/* This file is part of »dali«. Copyright 2025 'kcf' »dali« is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. »dali« is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with »dali«. If not, see . */ namespace _dali.widgets { /** */ type type_entry = { id : _dali.type_calendar_id; name : string; hue : float; access_level : _dali.enum_access_level; }; /** */ export class class_widget_sources implements lib_plankton.zoo_widget.interface_widget { /** * [dependency] */ private get_entries : (() => Promise>); /** * [hook] */ private action_toggle : ((entry : type_entry, mode : boolean) => void); /** * [hook] */ private action_select : ((entry : type_entry) => void); /** * [hook] */ private action_add : (() => void); /** * [state] */ private priviliged : boolean; /** * [state] */ private container : (null | Element); /** */ public constructor( get_entries : (() => Promise>), { "action_select": action_select = ((calendar_id) => {}), "action_toggle": action_toggle = ((calendar_id, mode) => {}), "action_add": action_add = (() => {}), "initial_priviliged": initial_priviliged = false, } : { action_select ?: ((entry : type_entry) => void); action_toggle ?: ((entry : type_entry, mode : boolean) => void); action_add ?: (() => void); initial_priviliged ?: boolean; } = { } ) { // dependencies this.get_entries = get_entries; // hooks this.action_select = action_select; this.action_toggle = action_toggle; this.action_add = action_add; // state this.priviliged = initial_priviliged; this.container = null; } /** */ private static id_encode( id : _dali.type_calendar_id ) : string { return id.toFixed(0); } /** */ private static id_decode( representation : string ) : _dali.type_calendar_id { return parseInt(representation); } /** */ public async update( { "priviliged": priviliged = null, } : { priviliged ?: boolean; } = { } ) : Promise { if (priviliged === null) { // do nothing } else { this.priviliged = priviliged; } const data : lib_plankton.map.type_map<_dali.type_calendar_id, type_entry> = lib_plankton.map.hashmap.implementation_map( lib_plankton.map.hashmap.make( calendar_id => class_widget_sources.id_encode(calendar_id), { "pairs": ( (await this.get_entries()) .map( entry => ( { "key": entry.id, "value": entry, } ) ) ), } ) ); // structure { this.container.innerHTML = await _dali.helpers.template_coin( "widget-sources", "main", { "label_create": lib_plankton.translate.get("widget.sources.create"), "entries": ( ( await _dali.helpers.promise_row( lib_plankton.map.dump(data) .map( (pair) => () => { return _dali.helpers.template_coin( "widget-sources", "entry", { "name": pair.value.name, // "access_level": entry.access_level, // TODO "color": _dali.helpers.event_color(pair.value.hue), "rel": class_widget_sources.id_encode(pair.key), } ); } ) ) ) .join("") ), } ); this.container.querySelector(".sources").classList.toggle("sources-priviliged", this.priviliged); } // listeners { this.container.querySelector(".sources-create").addEventListener( "click", (event) => { event.preventDefault(); this.action_add(); } ); this.container.querySelectorAll(".sources-entry-visibility").forEach( (element) => { element.addEventListener( "change", () => { const mode : boolean = (element as HTMLInputElement).checked; const key_encoded : string = element.parentElement.getAttribute("rel"); const calendar_id : _dali.type_calendar_id = class_widget_sources.id_decode(key_encoded); const entry : type_entry = data.get(calendar_id); element.parentElement.classList.toggle("sources-entry-hidden", (! mode)); this.action_toggle(entry, mode); } ); } ); this.container.querySelectorAll(".sources-entry").forEach( (element) => { element.addEventListener( "click", (event) => { if ((event.target as Element).classList.contains("sources-entry-visibility")) { // do nothing } else { const key_encoded : string = element.getAttribute("rel"); const calendar_id : _dali.type_calendar_id = class_widget_sources.id_decode(key_encoded); const entry : type_entry = data.get(calendar_id); this.action_select(entry); } } ); } ); } } /** * [implementation] */ public async load( target_element : Element ) : Promise { this.container = target_element; await this.update(); } } }