/** */ namespace _zeitbild.frontend_web.view { /** */ function event_generate_tooltip( calendar_name : string, event : type_event ) : string { return ( lib_plankton.string.coin( "[{{calendar_name}}] {{event_name}}\n", { "calendar_name": calendar_name, "event_name": event.name, } ) + "--\n" + ( (event.begin.time !== null) ? lib_plankton.string.coin( "{{label}}: {{value}}\n", { "label": "Anfang", // TODO: translate "value": lib_plankton.string.coin( "{{hour}}:{{minute}}", { "hour": event.begin.time.hour.toFixed(0).padStart(2, "0"), "minute": event.begin.time.minute.toFixed(0).padStart(2, "0"), } ), // TODO: outsource } ) : "" ) + ( (event.end !== null) ? lib_plankton.string.coin( "{{label}}: {{value}}\n", { "label": "Ende", // TODO: translate "value": ( [ ( ( (event.end.date.year !== event.begin.date.year) || (event.end.date.month !== event.begin.date.month) || (event.end.date.day !== event.begin.date.day) ) ? lib_plankton.string.coin( "{{year}}-{{month}}-{{day}}", { "year": event.end.date.year.toFixed(0).padStart(4, "0"), "month": event.end.date.month.toFixed(0).padStart(2, "0"), "day": event.end.date.day.toFixed(0).padStart(2, "0"), } ) : null ), ( (event.end.time !== null) ? lib_plankton.string.coin( "{{hour}}:{{minute}}", { "hour": event.end.time.hour.toFixed(0).padStart(2, "0"), "minute": event.end.time.minute.toFixed(0).padStart(2, "0"), } ) : null ), ] .filter(x => (x !== null)) .join(",") ), } ) : "" ) + ( (event.location !== null) ? ( lib_plankton.string.coin( "{{label}}: {{value}}\n", { "label": "Ort", // TODO "value": event.location, } ) ) : "" ) + ( (event.description !== null) ? ( "--\n" + lib_plankton.string.coin( "{{description}}\n", { "description": event.description, } ) ) : "" ) ); } /** * @todo kein "while" */ async function calendar_view_table_data( calendar_ids : ( null | Array ), from : { year : int; week : int; }, to : { year : int; week : int; }, timezone_shift : int, ) : Promise< { sources : lib_plankton.map.type_map< type_calendar_id, { name : string; } >; rows : Array< { week : int; data : Array< { pit : _zeitbild.frontend_web.helpers.type_pit; entries : Array< { calendar_id : type_calendar_id; event : type_event; } >; today : boolean; } >; } > } > { const now_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_now(); /* const calendar_object : type_calendar_object = calendar_read( data, calendar_id ); */ const from_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_from_year_and_week( (from as {year : int; week : int}).year, (from as {year : int; week : int}).week, { "timezone_shift": (timezone_shift as int), } ); const to_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_from_year_and_week( (to as {year : int; week : int}).year, (to as {year : int; week : int}).week, { "timezone_shift": (timezone_shift as int), } ); // prepare const entries : Array< { calendar_id : type_calendar_id; calendar_name : string; event : type_event; } > = await _zeitbild.frontend_web.backend.events( from_pit, to_pit, { "calendar_ids": calendar_ids, } ); let result : { sources : lib_plankton.map.type_map< type_calendar_id, { name : string; } >; rows : Array< { week : int; data : Array< { pit : _zeitbild.frontend_web.helpers.type_pit; entries : Array< { calendar_id : type_calendar_id; event : type_event; } >; today : boolean; } >; } >; } = { "sources": lib_plankton.map.hashmap.implementation_map( lib_plankton.map.hashmap.make( x => x.toFixed(0), { "pairs": ( entries .map( (entry) => ( { "key": entry.calendar_id, "value": { "name": entry.calendar_name, } } ) ) ) } ) ), "rows": [], }; let row : Array< { pit : _zeitbild.frontend_web.helpers.type_pit; entries : Array< { calendar_id : type_calendar_id; event : type_event; } >; today : boolean; } > = []; let day : int = 0; while (true) { const pit_current : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_shift_day( from_pit, day ); if ( _zeitbild.frontend_web.helpers.pit_is_before( pit_current, to_pit ) ) { day += 1; row.push( { "pit": pit_current, "entries": [], "today": false, // TODO } ); if (day % 7 === 0) { result.rows.push( { "week": ( (from as {year : int; week : int}).week + Math.floor(day / 7) - 1 // TODO ), "data": row } ); row = []; } else { // do nothing } } else { break; } } // fill { // events ( entries .forEach( (entry) => { const distance_seconds : int = ( _zeitbild.frontend_web.helpers.pit_from_datetime(entry.event.begin) - from_pit ); const distance_days : int = (distance_seconds / (60 * 60 * 24)); const week : int = Math.floor(Math.floor(distance_days) / 7); const day : int = (Math.floor(distance_days) % 7); if ((week >= 0) && (week < result.rows.length)) { result.rows[week].data[day].entries.push(entry); } else { // do nothing } } ) ); // today { const distance_seconds : int = ( now_pit - from_pit ); const distance_days : int = (distance_seconds / (60 * 60 * 24)); const week : int = Math.floor(Math.floor(distance_days) / 7); const day : int = (Math.floor(distance_days) % 7); if ((week >= 0) && (week < result.rows.length)) { result.rows[week].data[day].today = true; } else { // do nothing } } } return Promise.resolve(result); } /** */ export async function calendar_view_table_html( options : { calendar_ids ?: ( null | Array ); from ?: { year : int; week : int; }; to ?: { year : int; week : int; }; timezone_shift ?: int; } = {} ) : Promise { const now_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_now(); options = Object.assign( { "calendar_ids": null, "from": lib_plankton.call.convey( now_pit, [ (x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_week(x, -1), _zeitbild.frontend_web.helpers.pit_to_date_object, (x : Date) => ({ "year": x.getFullYear(), "week": _zeitbild.frontend_web.helpers.date_object_get_week_of_year(x), }) ] ), "to": lib_plankton.call.convey( now_pit, [ (x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_week(x, +4), _zeitbild.frontend_web.helpers.pit_to_date_object, (x : Date) => ({ "year": x.getFullYear(), "week": _zeitbild.frontend_web.helpers.date_object_get_week_of_year(x), }) ] ), "timezone_shift": 0, }, options ); const stuff : { sources : lib_plankton.map.type_map< type_calendar_id, { name : string; } >; rows : Array< { week : int; data : Array< { pit : _zeitbild.frontend_web.helpers.type_pit; entries : Array< { calendar_id : type_calendar_id; event : type_event; } >; today : boolean; } >; } >; } = await calendar_view_table_data( options.calendar_ids, options.from, options.to, options.timezone_shift ); const sources : lib_plankton.map.type_map< type_calendar_id, { name : string; color : lib_plankton.color.type_color; } > = lib_plankton.map.hashmap.implementation_map( lib_plankton.map.hashmap.make( (x => x.toFixed(0)), { "pairs": ( lib_plankton.map.dump( stuff.sources ) .map( (pair) => ({ "key": pair.key, "value": { "name": pair.value.name, "color": lib_plankton.color.give_generic( (pair.key - 1), { "saturation": 0.375, "value": 0.375, } ), } }) ) ) } ) ); return _zeitbild.frontend_web.helpers.template_coin( "tableview", { "sources": ( await _zeitbild.frontend_web.helpers.promise_row( lib_plankton.map.dump(sources) .map( ({"key": calendar_id, "value": data}) => async () => _zeitbild.frontend_web.helpers.template_coin( "tableview-sources-entry", { "name": data.name, "color": lib_plankton.color.output_hex(data.color), "rel": calendar_id.toFixed(0), } ) ) ) ).join(""), "rows": ( await _zeitbild.frontend_web.helpers.promise_row( stuff.rows .map( (row) => async () => _zeitbild.frontend_web.helpers.template_coin( "tableview-row", { "week": row.week.toFixed(0).padStart(2, "0"), "cells": ( await _zeitbild.frontend_web.helpers.promise_row( row.data .map( (cell) => async () => _zeitbild.frontend_web.helpers.template_coin( "tableview-cell", { "extra_classes": ( [""] .concat(cell.today ? ["calendar-cell-today"] : []) .join(" ") ), "title": lib_plankton.call.convey( cell.pit, [ _zeitbild.frontend_web.helpers.pit_to_datetime, (x : _zeitbild.frontend_web.helpers.type_datetime) => lib_plankton.string.coin( "{{year}}-{{month}}-{{day}}", { "year": x.date.year.toFixed(0).padStart(4, "0"), "month": x.date.month.toFixed(0).padStart(2, "0"), "day": x.date.day.toFixed(0).padStart(2, "0"), } ), ] ), "day": lib_plankton.call.convey( cell.pit, [ _zeitbild.frontend_web.helpers.pit_to_datetime, (x : _zeitbild.frontend_web.helpers.type_datetime) => lib_plankton.string.coin( "{{day}}", { "year": x.date.year.toFixed(0).padStart(4, "0"), "month": x.date.month.toFixed(0).padStart(2, "0"), "day": x.date.day.toFixed(0).padStart(2, "0"), } ), ] ), "entries": ( await _zeitbild.frontend_web.helpers.promise_row( cell.entries .map( (entry) => () => _zeitbild.frontend_web.helpers.template_coin( "tableview-cell-entry", { "color": lib_plankton.color.output_hex( sources.get( entry.calendar_id ).color ), "title": event_generate_tooltip( sources.get( entry.calendar_id ).name, entry.event ), "name": entry.event.name, } ) ) ) ).join(""), } ) ) ) ).join(""), } ) ) ) ).join(""), } ); } /** */ async function calendar_view_list_data( calendar_ids : Array, options : { from ?: _zeitbild.frontend_web.helpers.type_pit; to ?: _zeitbild.frontend_web.helpers.type_pit; timezone_shift ?: int; } = {} ) : Promise< Array< { calendar_id : type_calendar_id; event : type_event; } > > { const now_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_now(); options = Object.assign( { "from": lib_plankton.call.convey( now_pit, [ (x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_day(x, -1), ] ), "to": lib_plankton.call.convey( now_pit, [ (x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_week(x, +4), ] ), "timezone_shift": 0, }, options ); const entries : Array< { calendar_id : type_calendar_id; event : type_event; } > = await _zeitbild.frontend_web.backend.events( (options.from as _zeitbild.frontend_web.helpers.type_pit), (options.to as _zeitbild.frontend_web.helpers.type_pit), { "calendar_ids": calendar_ids, } ); // TODO: optimize entries.sort( (entry_1, entry_2) => ( _zeitbild.frontend_web.helpers.pit_from_datetime(entry_1.event.begin) - _zeitbild.frontend_web.helpers.pit_from_datetime(entry_2.event.begin) ) ); return Promise.resolve(entries); } /** */ export async function calendar_view_list_html( calendar_ids : Array, options : { from ?: _zeitbild.frontend_web.helpers.type_pit; to ?: _zeitbild.frontend_web.helpers.type_pit; timezone_shift ?: int; } = {} ) : Promise { const stuff : Array< { calendar_id : type_calendar_id; event : type_event; } > = await calendar_view_list_data( calendar_ids, options ); return Promise.resolve( new lib_plankton.xml.class_node_complex( "div", { "class": "list", }, [ new lib_plankton.xml.class_node_complex( "style", {}, [ new lib_plankton.xml.class_node_text( "html {background-color: #111; color: #FFF; font-family: sans-serif;}\n" + "table {width: 100%; border-collapse: collapse;}\n" ) ] ), new lib_plankton.xml.class_node_complex( "ul", { "class": "list-events", }, ( stuff .map( (entry) => ( new lib_plankton.xml.class_node_complex( "li", { "class": "list-event_entry", }, [ new lib_plankton.xml.class_node_text( JSON.stringify(entry) ), ] ) ) ) ) ), ] ).compile() ); } }