Compare commits
13 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
207ea459ae | ||
|
|
74e95dff54 | ||
|
|
b0bd963145 | ||
|
|
58fc2ea97f | ||
|
|
44c70a10bb | ||
|
|
63504f4e70 | ||
|
|
fae611bec4 | ||
|
|
b383460f3b | ||
|
|
9e24750d4d | ||
|
|
c0abe0a180 | ||
|
|
2b11b57818 | ||
|
|
004b9f3211 | ||
|
|
ccb408b1b0 |
146
lib/plankton/plankton.d.ts
vendored
146
lib/plankton/plankton.d.ts
vendored
|
|
@ -887,6 +887,35 @@ declare namespace lib_plankton.call {
|
|||
export function null_prop<type_value_from, type_value_to>(value_from: (null | type_value_from), function_: ((value: type_value_from) => type_value_to)): (null | type_value_to);
|
||||
export {};
|
||||
}
|
||||
declare namespace lib_plankton.call {
|
||||
/**
|
||||
*/
|
||||
type type_queue_item<type_data, type_result> = {
|
||||
data: type_data;
|
||||
resolve: ((result: type_result) => void);
|
||||
reject: ((reason: any) => void);
|
||||
};
|
||||
/**
|
||||
*/
|
||||
export type type_queue<type_data, type_result> = {
|
||||
handler: ((data: type_data) => Promise<type_result>);
|
||||
items: Array<type_queue_item<type_data, type_result>>;
|
||||
busy: boolean;
|
||||
paused: boolean;
|
||||
};
|
||||
/**
|
||||
*/
|
||||
export function queue_make<type_data, type_result>(handler: ((data: type_data) => Promise<type_result>)): type_queue<type_data, type_result>;
|
||||
/**
|
||||
*/
|
||||
export function queue_toggle_paused<type_data, type_result>(queue_subject: type_queue<type_data, type_result>, { "mode": mode, }?: {
|
||||
mode?: (null | boolean);
|
||||
}): void;
|
||||
/**
|
||||
*/
|
||||
export function queue_add<type_data, type_result>(queue_subject: type_queue<type_data, type_result>, data: type_data, resolve: ((result: type_result) => void), reject: ((reason: any) => void)): void;
|
||||
export {};
|
||||
}
|
||||
declare namespace lib_plankton.file {
|
||||
/**
|
||||
* @author fenris
|
||||
|
|
@ -4165,6 +4194,49 @@ declare namespace lib_plankton.zoo_widget {
|
|||
load(target_element: HTMLElement): Promise<void>;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_widget {
|
||||
/**
|
||||
*/
|
||||
class class_slider implements interface_widget {
|
||||
/**
|
||||
*/
|
||||
private conf;
|
||||
/**
|
||||
*/
|
||||
private state;
|
||||
/**
|
||||
*/
|
||||
constructor(content: Array<interface_widget>, { "threshold": threshold, "acceleration_function": acceleration_function, "initial_index": initial_index, }?: {
|
||||
threshold?: float;
|
||||
acceleration_function?: ((float: any) => float);
|
||||
initial_index?: int;
|
||||
});
|
||||
/**
|
||||
*/
|
||||
private static cap;
|
||||
/**
|
||||
*/
|
||||
private static position_subtract;
|
||||
/**
|
||||
*/
|
||||
private static touch_event_position;
|
||||
/**
|
||||
*/
|
||||
private set_translation;
|
||||
/**
|
||||
*/
|
||||
private start;
|
||||
/**
|
||||
*/
|
||||
private update;
|
||||
/**
|
||||
*/
|
||||
private finish;
|
||||
/**
|
||||
*/
|
||||
load(target_element: HTMLElement): Promise<void>;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_page {
|
||||
/**
|
||||
*/
|
||||
|
|
@ -4234,6 +4306,9 @@ declare namespace lib_plankton.zoo_input {
|
|||
/**
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4281,6 +4356,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4320,6 +4399,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4367,6 +4450,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4405,6 +4492,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4461,6 +4552,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4499,6 +4594,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4545,6 +4644,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4584,6 +4687,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4630,6 +4737,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4693,6 +4804,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
export {};
|
||||
}
|
||||
|
|
@ -4737,6 +4852,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4789,6 +4908,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4833,6 +4956,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4881,6 +5008,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4916,6 +5047,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4949,6 +5084,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -4982,6 +5121,10 @@ declare namespace lib_plankton.zoo_input {
|
|||
* [implementation]
|
||||
*/
|
||||
hook_change(action: (() => void)): Promise<void>;
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
focus(): void;
|
||||
}
|
||||
}
|
||||
declare namespace lib_plankton.zoo_input {
|
||||
|
|
@ -5094,6 +5237,9 @@ declare namespace lib_plankton.zoo_form {
|
|||
/**
|
||||
*/
|
||||
input_lock(mode: boolean): Promise<void>;
|
||||
/**
|
||||
*/
|
||||
input_focus(): void;
|
||||
}
|
||||
export {};
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -7,7 +7,7 @@
|
|||
"path": ""
|
||||
},
|
||||
"misc": {
|
||||
"oidc_redirect_uri_template": "http://localhost:8888/#oidc_finish,session_key={{session_key}}",
|
||||
"oidc_redirect_uri_template": "http://localhost:8888/?action=oidc_finish&session_key={{session_key}}",
|
||||
"use_central_europe_specific_datetime_inputs": true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali
|
||||
{
|
||||
|
||||
|
|
@ -86,9 +106,20 @@ namespace _dali
|
|||
{
|
||||
await _dali.backend.set_session_key(session_key);
|
||||
const status = await _dali.backend.status();
|
||||
if (! status.logged_in)
|
||||
{
|
||||
lib_plankton.log.error(
|
||||
"dali.oidc_login_failed"
|
||||
);
|
||||
await _dali.notify_logout();
|
||||
return Promise.reject<void>(new Error("oidc login failed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
await _dali.notify_login(status.name);
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -14,7 +14,20 @@
|
|||
"common.weekday.friday": "Fr",
|
||||
"common.weekday.saturday": "Sa",
|
||||
"common.weekday.sunday": "So",
|
||||
"common.monthname.january": "Jan",
|
||||
"common.monthname.february": "Feb",
|
||||
"common.monthname.march": "Mär",
|
||||
"common.monthname.april": "Apr",
|
||||
"common.monthname.may": "Mai",
|
||||
"common.monthname.june": "Jun",
|
||||
"common.monthname.july": "Jul",
|
||||
"common.monthname.august": "Aug",
|
||||
"common.monthname.september": "Sep",
|
||||
"common.monthname.october": "Okt",
|
||||
"common.monthname.november": "Nov",
|
||||
"common.monthname.december": "Dez",
|
||||
"common.open": "öffnen",
|
||||
"common.close": "schließen",
|
||||
"common.edit": "bearbeiten",
|
||||
"common.show": "zeigen",
|
||||
"common.hide": "ausblenden",
|
||||
|
|
@ -66,27 +79,20 @@
|
|||
"widget.login.internal.password": "Kennwort",
|
||||
"widget.login.internal.do": "Anmelden",
|
||||
"widget.login.oidc.via": "via {{title}}",
|
||||
"page.caldav.title": "CalDAV",
|
||||
"page.caldav.unavailable": "CalDAV nicht verfügbar",
|
||||
"page.caldav.conf.title": "Zugangsdaten",
|
||||
"page.caldav.conf.address": "Adresse (URL)",
|
||||
"page.caldav.conf.username": "Nutzername",
|
||||
"page.caldav.conf.password": "Kennwort",
|
||||
"page.caldav.conf.setup_hints": "Einrichtungs-Hinweise",
|
||||
"page.caldav.conf.token_unset": "es muss zunächst ein Token gesetzt werden",
|
||||
"page.caldav.set_token.title": "Token setzen",
|
||||
"page.caldav.set_token.action.set": "setzen",
|
||||
"page.caldav.set_token.action.overwrite": "überschreiben",
|
||||
"page.calendar_add.title": "Kalendar anlegen",
|
||||
"page.calendar_add.actions.do": "anlegen",
|
||||
"page.calendar_edit.title.regular": "Kalendar bearbeiten",
|
||||
"page.calendar_edit.title.read_only": "Kalendar-Details",
|
||||
"page.event_add.title": "Termin anlegen",
|
||||
"page.event_edit.title.regular": "Termin bearbeiten",
|
||||
"page.event_edit.title.read_only": "Termin-Details",
|
||||
"page.overview.title": "Übersicht",
|
||||
"page.overview.login_hint": "anmelden um nicht-öffentliche Termine zu sehen",
|
||||
"page.overview.mode.week": "Wochen-Ansicht",
|
||||
"page.overview.mode.list": "Listen-Ansicht"
|
||||
"widget.caldav.title": "CalDAV",
|
||||
"widget.caldav.unavailable": "CalDAV nicht verfügbar",
|
||||
"widget.caldav.conf.title": "Zugangsdaten",
|
||||
"widget.caldav.conf.address": "Adresse (URL)",
|
||||
"widget.caldav.conf.username": "Nutzername",
|
||||
"widget.caldav.conf.password": "Kennwort",
|
||||
"widget.caldav.conf.setup_hints": "Einrichtungs-Hinweise",
|
||||
"widget.caldav.conf.token_unset": "es muss zunächst ein Token gesetzt werden",
|
||||
"widget.caldav.set_token.title": "Token setzen",
|
||||
"widget.caldav.set_token.action.set": "setzen",
|
||||
"widget.caldav.set_token.action.overwrite": "überschreiben",
|
||||
"widget.overview.title": "Übersicht",
|
||||
"widget.overview.login_hint": "anmelden um nicht-öffentliche Termine zu sehen",
|
||||
"widget.overview.mode.week": "Wochen-Ansicht",
|
||||
"widget.overview.mode.list": "Listen-Ansicht"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,20 @@
|
|||
"common.weekday.friday": "Fri",
|
||||
"common.weekday.saturday": "Sat",
|
||||
"common.weekday.sunday": "Sun",
|
||||
"common.monthname.january": "jan",
|
||||
"common.monthname.february": "feb",
|
||||
"common.monthname.march": "mar",
|
||||
"common.monthname.april": "apr",
|
||||
"common.monthname.may": "may",
|
||||
"common.monthname.june": "jun",
|
||||
"common.monthname.july": "jul",
|
||||
"common.monthname.august": "aug",
|
||||
"common.monthname.september": "sep",
|
||||
"common.monthname.october": "oct",
|
||||
"common.monthname.november": "nov",
|
||||
"common.monthname.december": "dec",
|
||||
"common.open": "open",
|
||||
"common.close": "close",
|
||||
"common.edit": "edit",
|
||||
"common.show": "show",
|
||||
"common.hide": "hide",
|
||||
|
|
@ -66,27 +79,20 @@
|
|||
"widget.login.internal.password": "password",
|
||||
"widget.login.internal.do": "login",
|
||||
"widget.login.oidc.via": "via {{title}}",
|
||||
"page.caldav.title": "CalDAV",
|
||||
"page.caldav.unavailable": "CalDAV not available",
|
||||
"page.caldav.conf.title": "credentials",
|
||||
"page.caldav.conf.address": "address (URL)",
|
||||
"page.caldav.conf.username": "username",
|
||||
"page.caldav.conf.password": "password",
|
||||
"page.caldav.conf.setup_hints": "setup hints",
|
||||
"page.caldav.conf.token_unset": "a token has to be set",
|
||||
"page.caldav.set_token.title": "set token",
|
||||
"page.caldav.set_token.action.set": "set",
|
||||
"page.caldav.set_token.action.overwrite": "overwrite",
|
||||
"page.calendar_add.title": "Add calendar",
|
||||
"page.calendar_add.actions.do": "anlegen",
|
||||
"page.event_add.title": "Add event",
|
||||
"page.calendar_edit.title.regular": "Edit calendar",
|
||||
"page.calendar_edit.title.read_only": "Calendar details",
|
||||
"page.event_edit.title.regular": "Edit event",
|
||||
"page.event_edit.title.read_only": "Event details",
|
||||
"page.overview.title": "Overview",
|
||||
"page.overview.login_hint": "log in to view non-public events",
|
||||
"page.overview.mode.week": "week view",
|
||||
"page.overview.mode.list": "list view"
|
||||
"widget.caldav.title": "CalDAV",
|
||||
"widget.caldav.unavailable": "CalDAV not available",
|
||||
"widget.caldav.conf.title": "credentials",
|
||||
"widget.caldav.conf.address": "address (URL)",
|
||||
"widget.caldav.conf.username": "username",
|
||||
"widget.caldav.conf.password": "password",
|
||||
"widget.caldav.conf.setup_hints": "setup hints",
|
||||
"widget.caldav.conf.token_unset": "a token has to be set",
|
||||
"widget.caldav.set_token.title": "set token",
|
||||
"widget.caldav.set_token.action.set": "set",
|
||||
"widget.caldav.set_token.action.overwrite": "overwrite",
|
||||
"widget.overview.title": "Overview",
|
||||
"widget.overview.login_hint": "log in to view non-public events",
|
||||
"widget.overview.mode.week": "week view",
|
||||
"widget.overview.mode.list": "list view"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,45 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
namespace _dali.helpers
|
||||
{
|
||||
|
||||
/**
|
||||
* @todo outsource
|
||||
*/
|
||||
function is_touch_device(
|
||||
)
|
||||
: boolean
|
||||
{
|
||||
return (
|
||||
("ontouchstart" in window)
|
||||
||
|
||||
(navigator.maxTouchPoints > 0)
|
||||
||
|
||||
(navigator["msMaxTouchPoints"] > 0)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
var _template_cache : Record<string, string> = {};
|
||||
|
|
@ -13,12 +49,13 @@ namespace _dali.helpers
|
|||
*/
|
||||
export function view_mode_determine(
|
||||
mode_descriptor : string
|
||||
) : _dali.enum_view_mode
|
||||
)
|
||||
: _dali.enum_view_mode
|
||||
{
|
||||
if (mode_descriptor === "auto")
|
||||
{
|
||||
return (
|
||||
(window.innerWidth >= 800)
|
||||
(window.innerWidth >= 1000)
|
||||
?
|
||||
_dali.enum_view_mode.week
|
||||
:
|
||||
|
|
@ -32,6 +69,30 @@ namespace _dali.helpers
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function view_kind_determine(
|
||||
mode_descriptor : string
|
||||
)
|
||||
: _dali.enum_view_kind
|
||||
{
|
||||
if (mode_descriptor === "auto")
|
||||
{
|
||||
return (
|
||||
is_touch_device()
|
||||
?
|
||||
_dali.enum_view_kind.touch
|
||||
:
|
||||
_dali.enum_view_kind.regular
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return view_kind_decode(mode_descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function template_coin(
|
||||
|
|
@ -77,6 +138,25 @@ namespace _dali.helpers
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function element_from_template(
|
||||
group : string,
|
||||
name : string,
|
||||
data : Record<string, string>
|
||||
)
|
||||
: Promise<HTMLElement>
|
||||
{
|
||||
const dom_dummy = document.createElement("div");
|
||||
dom_dummy.innerHTML = await _dali.helpers.template_coin(
|
||||
group,
|
||||
name,
|
||||
data
|
||||
);
|
||||
return (dom_dummy.children[0] as HTMLElement);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo outsource
|
||||
*/
|
||||
|
|
@ -84,7 +164,8 @@ namespace _dali.helpers
|
|||
members : Array<
|
||||
() => Promise<type_result>
|
||||
>
|
||||
) : Promise<
|
||||
)
|
||||
: Promise<
|
||||
Array<
|
||||
type_result
|
||||
>
|
||||
|
|
@ -101,7 +182,8 @@ namespace _dali.helpers
|
|||
/**
|
||||
*/
|
||||
export function input_access_level(
|
||||
) : lib_plankton.zoo_input.interface_input<_dali.enum_access_level>
|
||||
)
|
||||
: lib_plankton.zoo_input.interface_input<_dali.enum_access_level>
|
||||
{
|
||||
return (
|
||||
new lib_plankton.zoo_input.class_input_wrapped<
|
||||
|
|
@ -222,7 +304,8 @@ namespace _dali.helpers
|
|||
/**
|
||||
*/
|
||||
export function datetime_input(
|
||||
) : lib_plankton.zoo_input.interface_input<lib_plankton.pit.type_datetime>
|
||||
)
|
||||
: lib_plankton.zoo_input.interface_input<lib_plankton.pit.type_datetime>
|
||||
{
|
||||
return (
|
||||
_dali.conf.get().misc.use_central_europe_specific_datetime_inputs
|
||||
|
|
@ -264,4 +347,48 @@ namespace _dali.helpers
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function month_name(
|
||||
month : int
|
||||
)
|
||||
: string
|
||||
{
|
||||
const keys : Array<string> = [
|
||||
"common.monthname.january",
|
||||
"common.monthname.february",
|
||||
"common.monthname.march",
|
||||
"common.monthname.april",
|
||||
"common.monthname.may",
|
||||
"common.monthname.june",
|
||||
"common.monthname.july",
|
||||
"common.monthname.august",
|
||||
"common.monthname.september",
|
||||
"common.monthname.october",
|
||||
"common.monthname.november",
|
||||
"common.monthname.december",
|
||||
];
|
||||
return lib_plankton.translate.get(keys[month-1]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function loading(
|
||||
mode : boolean
|
||||
)
|
||||
: void
|
||||
{
|
||||
if (! mode)
|
||||
{
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
}
|
||||
else
|
||||
{
|
||||
_dali.overlay.get_content_element().innerHTML = ". . .";
|
||||
_dali.overlay.toggle({"mode": true});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
189
source/main.ts
189
source/main.ts
|
|
@ -1,42 +1,28 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
namespace _dali
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
function nav_groups(
|
||||
logged_in : boolean
|
||||
)
|
||||
: Array<string>
|
||||
{
|
||||
return (
|
||||
logged_in
|
||||
?
|
||||
["logged_in"]
|
||||
:
|
||||
["logged_out"]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo reload page when switching to "logged_out"
|
||||
*/
|
||||
async function update(
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
lib_plankton.log.debug(
|
||||
"dali.update"
|
||||
);
|
||||
const logged_in : boolean = _dali.is_logged_in();
|
||||
lib_plankton.zoo_page.nav_set_groups(nav_groups(logged_in));
|
||||
// lib_plankton.zoo_page.reload();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export async function main(
|
||||
|
|
@ -48,12 +34,27 @@ namespace _dali
|
|||
"conf.json"
|
||||
);
|
||||
|
||||
// init
|
||||
// init:logger
|
||||
lib_plankton.log.set_main_logger(
|
||||
[
|
||||
{"kind": "console", "data": {"threshold": "info"}},
|
||||
{
|
||||
"kind": "minlevel",
|
||||
"data": {
|
||||
"core": {
|
||||
"kind": "console",
|
||||
"data": {
|
||||
}
|
||||
},
|
||||
"threshold": "info"
|
||||
}
|
||||
},
|
||||
]
|
||||
);
|
||||
// init:overlay
|
||||
{
|
||||
await _dali.overlay.initialize();
|
||||
_dali.helpers.loading(true);
|
||||
}
|
||||
// init:localization
|
||||
{
|
||||
const order : Array<string> = ["deu", "eng"];
|
||||
|
|
@ -62,10 +63,11 @@ namespace _dali
|
|||
"verbosity": 1,
|
||||
"packages": await Promise.all(
|
||||
order.map(
|
||||
async (code) => JSON.parse(
|
||||
await lib_plankton.file.read(
|
||||
"data/localization/" + code + ".loc.json"
|
||||
)
|
||||
code => (
|
||||
Promise.resolve(code)
|
||||
.then<string>(code => Promise.resolve(lib_plankton.string.coin("data/localization/{{code}}.loc.json", {"code": code})))
|
||||
.then<string>(lib_plankton.file.read)
|
||||
.then<any>(content => Promise.resolve(JSON.parse(content)))
|
||||
)
|
||||
)
|
||||
),
|
||||
|
|
@ -74,11 +76,14 @@ namespace _dali
|
|||
}
|
||||
);
|
||||
}
|
||||
// init:backend
|
||||
await _dali.backend.initialize(
|
||||
_dali.conf.get()["backend"]
|
||||
);
|
||||
// init:model
|
||||
await _dali.model.initialize(
|
||||
);
|
||||
// init:page
|
||||
lib_plankton.zoo_page.init(
|
||||
document.querySelector("main"),
|
||||
{
|
||||
|
|
@ -86,69 +91,55 @@ namespace _dali
|
|||
"name": "overview",
|
||||
"parameters": {}
|
||||
},
|
||||
/*
|
||||
"nav_entries": [
|
||||
],
|
||||
*/
|
||||
"nav_initial_groups": [],
|
||||
}
|
||||
);
|
||||
// menu widget
|
||||
// init:menu
|
||||
{
|
||||
const widget_menu : _dali.widgets.menu.class_widget_menu = new _dali.widgets.menu.class_widget_menu(
|
||||
const widget_menu : _dali.widgets.class_widget_menu = new _dali.widgets.class_widget_menu(
|
||||
[
|
||||
{
|
||||
"label": lib_plankton.translate.get("common.login"),
|
||||
"groups": ["logged_out"],
|
||||
"action": () => {
|
||||
const widget_login = new _dali.widgets.login.class_widget_login(
|
||||
"action": async () => {
|
||||
_dali.helpers.loading(true);
|
||||
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_login(
|
||||
{
|
||||
"action_cancel": () => {
|
||||
_dali.overlay.clear();
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
},
|
||||
"action_success": async () => {
|
||||
_dali.helpers.loading(true);
|
||||
const status = await _dali.backend.status();
|
||||
_dali.notify_login(status.name);
|
||||
_dali.overlay.clear();
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
// _dali.overlay.clear();
|
||||
_dali.helpers.loading(false);
|
||||
},
|
||||
}
|
||||
);
|
||||
_dali.overlay.clear();
|
||||
await widget.load(_dali.overlay.get_content_element());
|
||||
// _dali.helpers.loading(false);
|
||||
_dali.overlay.toggle({"mode": true});
|
||||
widget_login.load(_dali.overlay.get_content_element());
|
||||
},
|
||||
},
|
||||
{
|
||||
"label": lib_plankton.translate.get("page.overview.title"),
|
||||
"groups": ["logged_out", "logged_in"],
|
||||
"action": () => {
|
||||
lib_plankton.zoo_page.set(
|
||||
{
|
||||
"name": "overview",
|
||||
"parameters": {}
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
"label": lib_plankton.translate.get("page.caldav.title"),
|
||||
"label": lib_plankton.translate.get("widget.caldav.title"),
|
||||
"groups": ["logged_in"],
|
||||
"action": () => {
|
||||
lib_plankton.zoo_page.set(
|
||||
{
|
||||
"name": "caldav",
|
||||
"parameters": {}
|
||||
}
|
||||
);
|
||||
"action": async () => {
|
||||
_dali.helpers.loading(true);
|
||||
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_caldav();
|
||||
await widget.load(_dali.overlay.get_content_element());
|
||||
// _dali.helpers.loading(false);
|
||||
_dali.overlay.toggle({"mode": true});
|
||||
},
|
||||
},
|
||||
{
|
||||
"label": lib_plankton.translate.get("common.logout"),
|
||||
"groups": ["logged_in"],
|
||||
"action": () => {
|
||||
_dali.logout();
|
||||
"action": async () => {
|
||||
_dali.helpers.loading(true);
|
||||
await _dali.logout();
|
||||
_dali.helpers.loading(false);
|
||||
},
|
||||
},
|
||||
]
|
||||
|
|
@ -167,18 +158,36 @@ namespace _dali
|
|||
}
|
||||
);
|
||||
}
|
||||
await update();
|
||||
await _dali.overlay.initialize();
|
||||
/*
|
||||
lib_plankton.call.loop(
|
||||
() => {
|
||||
update();
|
||||
},
|
||||
_dali.conf.get().misc.update_interval
|
||||
);
|
||||
*/
|
||||
|
||||
// check if logged_in
|
||||
// process actions
|
||||
{
|
||||
let url_search_params : URLSearchParams = new URLSearchParams(window.location.search);
|
||||
const action : (null | string) = url_search_params.get("action");
|
||||
switch (action)
|
||||
{
|
||||
case "oidc_finish":
|
||||
{
|
||||
try
|
||||
{
|
||||
await _dali.oidc_finish(url_search_params.get("session_key"));
|
||||
}
|
||||
catch (error_)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
document.location = "/";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case null:
|
||||
{
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// process status
|
||||
{
|
||||
const status = await _dali.backend.status();
|
||||
lib_plankton.log.info(
|
||||
|
|
@ -195,7 +204,15 @@ namespace _dali
|
|||
}
|
||||
}
|
||||
|
||||
lib_plankton.zoo_page.start();
|
||||
// load overview
|
||||
{
|
||||
const widget : lib_plankton.zoo_widget.interface_widget = (
|
||||
new _dali.widgets.class_widget_overview(
|
||||
)
|
||||
);
|
||||
await widget.load(document.querySelector("main"));
|
||||
}
|
||||
_dali.helpers.loading(false);
|
||||
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.model
|
||||
{
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,31 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.overlay
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
function get_container_element(
|
||||
) : HTMLElement
|
||||
)
|
||||
: HTMLElement
|
||||
{
|
||||
return document.querySelector("#overlay");
|
||||
}
|
||||
|
|
@ -13,7 +34,8 @@ namespace _dali.overlay
|
|||
/**
|
||||
*/
|
||||
export function get_content_element(
|
||||
) : HTMLElement
|
||||
)
|
||||
: HTMLElement
|
||||
{
|
||||
return document.querySelector("#overlay_content");
|
||||
}
|
||||
|
|
@ -22,7 +44,8 @@ namespace _dali.overlay
|
|||
/**
|
||||
*/
|
||||
export function clear(
|
||||
) : void
|
||||
)
|
||||
: void
|
||||
{
|
||||
get_content_element().innerHTML = "";
|
||||
}
|
||||
|
|
@ -41,7 +64,8 @@ namespace _dali.overlay
|
|||
=
|
||||
{
|
||||
}
|
||||
) : void
|
||||
)
|
||||
: void
|
||||
{
|
||||
get_container_element().classList.toggle("overlay_active", mode ?? undefined);
|
||||
}
|
||||
|
|
@ -50,7 +74,8 @@ namespace _dali.overlay
|
|||
/**
|
||||
*/
|
||||
export function initialize(
|
||||
) : Promise<void>
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
clear();
|
||||
const container_element : HTMLElement = get_container_element();
|
||||
|
|
|
|||
|
|
@ -1,119 +0,0 @@
|
|||
namespace _dali.pages
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
lib_plankton.zoo_page.register(
|
||||
"caldav",
|
||||
async (parameters, target_element) => {
|
||||
target_element.innerHTML = "";
|
||||
const conf = await _dali.backend.user_dav_conf();
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"caldav",
|
||||
"main",
|
||||
{
|
||||
"label": lib_plankton.translate.get("page.caldav.title"),
|
||||
"content": (
|
||||
(conf === null)
|
||||
?
|
||||
await _dali.helpers.template_coin(
|
||||
"caldav",
|
||||
"unavailable",
|
||||
{
|
||||
"text": lib_plankton.translate.get("page.caldav.unavailable"),
|
||||
}
|
||||
)
|
||||
:
|
||||
await _dali.helpers.template_coin(
|
||||
"caldav",
|
||||
"available",
|
||||
{
|
||||
"conf_title": lib_plankton.translate.get("page.caldav.conf.title"),
|
||||
"conf_content": (
|
||||
(conf.password === null)
|
||||
?
|
||||
await _dali.helpers.template_coin(
|
||||
"caldav",
|
||||
"conf-token_unset",
|
||||
{
|
||||
"text": lib_plankton.translate.get("page.caldav.conf.token_unset")
|
||||
}
|
||||
)
|
||||
:
|
||||
await _dali.helpers.template_coin(
|
||||
"caldav",
|
||||
"conf-token_set",
|
||||
{
|
||||
"address_label": lib_plankton.translate.get("page.caldav.conf.address"),
|
||||
"address_value": conf.address,
|
||||
"username_label": lib_plankton.translate.get("page.caldav.conf.username"),
|
||||
"username_value": conf.username,
|
||||
"password_label": lib_plankton.translate.get("page.caldav.conf.password"),
|
||||
"password_value": conf.password,
|
||||
"setup_hints_label": lib_plankton.translate.get("page.caldav.conf.setup_hints"),
|
||||
"setup_hint_entries": (
|
||||
await lib_plankton.call.promise_condense<string, unknown>(
|
||||
conf.setup_hints
|
||||
.map(
|
||||
entry => () => _dali.helpers.template_coin(
|
||||
"caldav",
|
||||
"conf-setup_hint_entry",
|
||||
{
|
||||
"text": entry.label,
|
||||
"href": entry.link,
|
||||
"remark": (
|
||||
(entry.remark === null)
|
||||
?
|
||||
""
|
||||
:
|
||||
lib_plankton.string.coin(
|
||||
" — {{content}}",
|
||||
{
|
||||
"content": entry.remark,
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
).join("")
|
||||
}
|
||||
)
|
||||
),
|
||||
"set_token_title": lib_plankton.translate.get("page.caldav.set_token.title"),
|
||||
"set_token_action": (
|
||||
(conf.password === null)
|
||||
?
|
||||
lib_plankton.translate.get("page.caldav.set_token.action.set")
|
||||
:
|
||||
lib_plankton.translate.get("page.caldav.set_token.action.overwrite")
|
||||
),
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* logic: set token
|
||||
*/
|
||||
{
|
||||
if (conf !== null)
|
||||
{
|
||||
document.querySelector("#caldav-set_token > button").addEventListener(
|
||||
"click",
|
||||
async () => {
|
||||
await _dali.backend.user_dav_token();
|
||||
lib_plankton.zoo_page.reload();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<div class="caldav-conf-section" id="caldav-conf-address">
|
||||
<span class="caldav-conf-section-label">{{address_label}}</span>
|
||||
<span class="caldav-conf-section-value caldav-conf-section-value-regular">{{address_value}}</span>
|
||||
</div>
|
||||
<div class="caldav-conf-section" id="caldav-conf-username">
|
||||
<span class="caldav-conf-section-label">{{username_label}}</span>
|
||||
<span class="caldav-conf-section-value caldav-conf-section-value-regular">{{username_value}}</span>
|
||||
</div>
|
||||
<div class="caldav-conf-section" id="caldav-conf-password">
|
||||
<span class="caldav-conf-section-label">{{password_label}}</span>
|
||||
<span class="caldav-conf-section-value caldav-conf-section-value-regular">{{password_value}}</span>
|
||||
</div>
|
||||
<div class="caldav-conf-section" id="caldav-conf-setup_hints">
|
||||
<span class="caldav-conf-section-label">{{setup_hints_label}}</span>
|
||||
<ul>
|
||||
{{setup_hint_entries}}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
<div id="caldav-conf-info">
|
||||
({{text}})
|
||||
</div>
|
||||
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
<div id="caldav">
|
||||
<h2>{{label}}</h2>
|
||||
<div id="caldav-content">
|
||||
{{content}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
<div id="caldav-info">
|
||||
{{text}}
|
||||
</div>
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
namespace _dali.pages
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
lib_plankton.zoo_page.register(
|
||||
"oidc_finish",
|
||||
async (parameters, target_element) => {
|
||||
target_element.innerHTML = "";
|
||||
await _dali.oidc_finish(parameters["session_key"]);
|
||||
lib_plankton.zoo_page.set(
|
||||
{
|
||||
"name": "overview",
|
||||
"parameters": {}
|
||||
}
|
||||
);
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
#overview-head
|
||||
{
|
||||
padding-bottom: 12px;
|
||||
margin-bottom: 12px;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
#overview-hint
|
||||
{
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#overview-hint.overview-hint-hidden
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#overview-body
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
#overview-body #overview-pane-left
|
||||
{
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
#overview-body #overview-pane-right
|
||||
{
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
#overview.overview-compact #overview-pane-left {/*flex-basis: 25%;*/display: none;}
|
||||
#overview.overview-compact #overview-pane-right {flex-basis: 75%;}
|
||||
#overview.overview-compact #overview-pane-right-listview {}
|
||||
#overview.overview-compact #overview-pane-right-weekview {display: none;}
|
||||
|
||||
#overview:not(.overview-compact) #overview-pane-left {flex-basis: 12.5%;}
|
||||
#overview:not(.overview-compact) #overview-pane-right {flex-basis: 87.5%;}
|
||||
#overview:not(.overview-compact) #overview-pane-right-listview {display: none;}
|
||||
#overview:not(.overview-compact) #overview-pane-right-weekview {}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
<div id="overview">
|
||||
<div id="overview-head">
|
||||
<div id="overview-hint">
|
||||
</div>
|
||||
<div id="overview-mode">
|
||||
</div>
|
||||
</div>
|
||||
<div id="overview-body">
|
||||
<div id="overview-pane-left">
|
||||
</div>
|
||||
<div id="overview-pane-right">
|
||||
<div id="overview-pane-right-weekview">
|
||||
</div>
|
||||
<div id="overview-pane-right-listview">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,3 +1,23 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
namespace _dali.backend
|
||||
|
|
@ -107,16 +127,7 @@ namespace _dali.backend
|
|||
|
||||
/**
|
||||
*/
|
||||
var _queue : {
|
||||
items : Array<
|
||||
{
|
||||
request : type_request;
|
||||
resolve : ((result : any) => void);
|
||||
reject : ((reason : any) => void);
|
||||
}
|
||||
>;
|
||||
busy : boolean;
|
||||
};
|
||||
var _queue : lib_plankton.call.type_queue<type_request, any>;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -140,10 +151,9 @@ namespace _dali.backend
|
|||
)
|
||||
*/
|
||||
);
|
||||
_queue = {
|
||||
"items": [],
|
||||
"busy": false,
|
||||
};
|
||||
_queue = lib_plankton.call.queue_make<type_request, any>(
|
||||
call_real
|
||||
);
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
|
||||
|
|
@ -243,60 +253,18 @@ namespace _dali.backend
|
|||
&&
|
||||
(http_response.status_code < 300)
|
||||
)
|
||||
) {
|
||||
)
|
||||
{
|
||||
return Promise.reject<any>(http_response.body.toString());
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
const output : any = lib_plankton.json.decode(http_response.body.toString());
|
||||
return Promise.resolve<any>(output);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
async function process(
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
if (_queue.busy)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
_queue.busy = true;
|
||||
while (_queue.items.length > 0)
|
||||
{
|
||||
const entry = _queue.items.shift();
|
||||
let successful : boolean;
|
||||
let reason : any;
|
||||
let result : any;
|
||||
try
|
||||
{
|
||||
result = await call_real(entry.request);
|
||||
successful = true;
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
reason = error;
|
||||
successful = false;
|
||||
}
|
||||
if (successful)
|
||||
{
|
||||
entry.resolve(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.reject(reason);
|
||||
}
|
||||
}
|
||||
_queue.busy = false;
|
||||
// process();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
async function call(
|
||||
|
|
@ -311,19 +279,18 @@ namespace _dali.backend
|
|||
"action": action,
|
||||
"input": input,
|
||||
};
|
||||
const promise : Promise<any> = new Promise<any>(
|
||||
return (
|
||||
new Promise<any>(
|
||||
(resolve, reject) => {
|
||||
_queue.items.push(
|
||||
{
|
||||
"request": request,
|
||||
"resolve": resolve,
|
||||
"reject": reject,
|
||||
}
|
||||
lib_plankton.call.queue_add<type_request, any>(
|
||||
_queue,
|
||||
request,
|
||||
resolve,
|
||||
reject
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
process();
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
namespace _dali.conf
|
||||
{
|
||||
|
|
@ -53,14 +73,15 @@ namespace _dali.conf
|
|||
"default": "http://localhost:8888/#oidc_finish,session_key={{session_key}}"
|
||||
},
|
||||
"use_central_europe_specific_datetime_inputs": {
|
||||
"nullable": true,
|
||||
"nullable": false,
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"update_interval": {
|
||||
"weekview_cell_day_format": {
|
||||
"nullable": false,
|
||||
"type": "integer",
|
||||
"default": 60
|
||||
"type": "string",
|
||||
"default": "d.b",
|
||||
"description": "available placeholders: Y,m,b,d,W,w (as in UNIX command 'date')"
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
|
|
@ -78,7 +99,25 @@ namespace _dali.conf
|
|||
|
||||
/**
|
||||
*/
|
||||
var _data : (null | any) = null;
|
||||
type type_data = {
|
||||
version : string;
|
||||
backend : {
|
||||
scheme : string;
|
||||
host : string;
|
||||
port : int;
|
||||
path : string;
|
||||
};
|
||||
misc : {
|
||||
oidc_redirect_uri_template : string;
|
||||
use_central_europe_specific_datetime_inputs : string;
|
||||
weekview_cell_day_format : string;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
var _data : (null | type_data) = null;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -93,7 +132,7 @@ namespace _dali.conf
|
|||
/**
|
||||
*/
|
||||
export function get(
|
||||
) : any
|
||||
) : type_data
|
||||
{
|
||||
if (_data === null)
|
||||
{
|
||||
|
|
@ -111,10 +150,7 @@ namespace _dali.conf
|
|||
path : string
|
||||
) : Promise<void>
|
||||
{
|
||||
_data = await lib_plankton.conf.load(
|
||||
_schema,
|
||||
path
|
||||
);
|
||||
_data = ((await lib_plankton.conf.load(_schema, path)) as type_data);
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
.plankton_input_group_field[rel="resource"]
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.weekview-control-count
|
||||
{
|
||||
display: none !important;
|
||||
}
|
||||
|
|
@ -20,72 +20,6 @@ header
|
|||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
#overlay
|
||||
{
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: hsla(var(--hue), 0%, 0%, 0.75);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#overlay_content
|
||||
{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
|
||||
transform: translate(-50%,-50%);
|
||||
-ms-transform: translate(-50%,-50%);
|
||||
|
||||
padding: 32px;
|
||||
|
||||
background-color: hsl(0, 0%, 12.5%);
|
||||
color: hsl(0, 0%, 100%);
|
||||
}
|
||||
|
||||
#overlay:not(.overlay_active)
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
nav > ul
|
||||
{
|
||||
list-style-type: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
nav > ul > li
|
||||
{
|
||||
display: inline-block;
|
||||
margin: 8px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
nav > ul > li:not(.active)
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
nav a
|
||||
{
|
||||
padding: 8px;
|
||||
text-decoration: none;
|
||||
color: hsl(var(--hue), 0%, 87.5%);
|
||||
}
|
||||
|
||||
nav a:hover
|
||||
{
|
||||
color: hsl(var(--hue), 0%, 100%);
|
||||
border-bottom: 2px solid hsl(0, 0%, 100%);
|
||||
transition: 1s ease color;
|
||||
}
|
||||
|
||||
a
|
||||
{
|
||||
text-decoration: none;
|
||||
|
|
@ -101,7 +35,7 @@ a:hover
|
|||
|
||||
button
|
||||
{
|
||||
padding: 8px;
|
||||
padding: 8px 12px;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
|
||||
|
|
|
|||
33
source/style/overlay.css
Normal file
33
source/style/overlay.css
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#overlay
|
||||
{
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: hsla(var(--hue), 0%, 0%, 0.75);
|
||||
z-index: 2;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#overlay_content
|
||||
{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
|
||||
transform: translate(-50%,-50%);
|
||||
-ms-transform: translate(-50%,-50%);
|
||||
|
||||
padding: 32px;
|
||||
|
||||
background-color: hsl(0, 0%, 12.5%);
|
||||
color: hsl(0, 0%, 100%);
|
||||
}
|
||||
|
||||
#overlay:not(.overlay_active)
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
|
|
@ -6,7 +25,8 @@ namespace _dali
|
|||
|
||||
/**
|
||||
*/
|
||||
export enum enum_access_level {
|
||||
export enum enum_access_level
|
||||
{
|
||||
none,
|
||||
view,
|
||||
edit,
|
||||
|
|
@ -183,20 +203,12 @@ namespace _dali
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export enum enum_view_mode
|
||||
{
|
||||
week,
|
||||
list,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function access_level_encode(
|
||||
access_level : _dali.enum_access_level
|
||||
) : ("none" | "view" | "edit" | "admin")
|
||||
)
|
||||
: ("none" | "view" | "edit" | "admin")
|
||||
{
|
||||
switch (access_level)
|
||||
{
|
||||
|
|
@ -212,7 +224,8 @@ namespace _dali
|
|||
*/
|
||||
export function access_level_decode(
|
||||
representation : /*("none" | "view" | "edit" | "admin")*/string
|
||||
) : _dali.enum_access_level
|
||||
)
|
||||
: _dali.enum_access_level
|
||||
{
|
||||
switch (representation)
|
||||
{
|
||||
|
|
@ -225,11 +238,21 @@ namespace _dali
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export enum enum_view_mode
|
||||
{
|
||||
week,
|
||||
list,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function view_mode_encode(
|
||||
mode : _dali.enum_view_mode
|
||||
) : string
|
||||
)
|
||||
: string
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
|
|
@ -244,7 +267,8 @@ namespace _dali
|
|||
*/
|
||||
export function view_mode_decode(
|
||||
view_mode_encoded : string
|
||||
) : _dali.enum_view_mode
|
||||
)
|
||||
: _dali.enum_view_mode
|
||||
{
|
||||
const map : Record<string, _dali.enum_view_mode> = {
|
||||
"week": _dali.enum_view_mode.week,
|
||||
|
|
@ -260,4 +284,51 @@ namespace _dali
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export enum enum_view_kind
|
||||
{
|
||||
regular,
|
||||
touch,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function view_kind_encode(
|
||||
kind : _dali.enum_view_kind
|
||||
)
|
||||
: string
|
||||
{
|
||||
switch (kind)
|
||||
{
|
||||
case _dali.enum_view_kind.regular: {return "regular"; break;}
|
||||
case _dali.enum_view_kind.touch: {return "touch"; break;}
|
||||
default: {throw (new Error("invalid kind"));}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export function view_kind_decode(
|
||||
view_kind_encoded : string
|
||||
)
|
||||
: _dali.enum_view_kind
|
||||
{
|
||||
const map : Record<string, _dali.enum_view_kind> = {
|
||||
"regular": _dali.enum_view_kind.regular,
|
||||
"touch": _dali.enum_view_kind.touch,
|
||||
};
|
||||
if (! (view_kind_encoded in map))
|
||||
{
|
||||
throw (new Error("invalid kind: " + view_kind_encoded));
|
||||
}
|
||||
else
|
||||
{
|
||||
return map[view_kind_encoded];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
173
source/widgets/caldav/logic.ts
Normal file
173
source/widgets/caldav/logic.ts
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export class class_widget_caldav
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
public constructor(
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public async load(
|
||||
target_element : HTMLElement
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
target_element.innerHTML = "";
|
||||
const conf = await _dali.backend.user_dav_conf();
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"widget-caldav",
|
||||
"main",
|
||||
{
|
||||
"title": lib_plankton.translate.get("widget.caldav.title"),
|
||||
"content": (
|
||||
(conf === null)
|
||||
?
|
||||
await _dali.helpers.template_coin(
|
||||
"widget-caldav",
|
||||
"unavailable",
|
||||
{
|
||||
"text": lib_plankton.translate.get("widget.caldav.unavailable"),
|
||||
}
|
||||
)
|
||||
:
|
||||
await _dali.helpers.template_coin(
|
||||
"widget-caldav",
|
||||
"available",
|
||||
{
|
||||
"conf_title": lib_plankton.translate.get("widget.caldav.conf.title"),
|
||||
"conf_content": (
|
||||
(conf.password === null)
|
||||
?
|
||||
await _dali.helpers.template_coin(
|
||||
"widget-caldav",
|
||||
"conf-token_unset",
|
||||
{
|
||||
"text": lib_plankton.translate.get("widget.caldav.conf.token_unset")
|
||||
}
|
||||
)
|
||||
:
|
||||
await _dali.helpers.template_coin(
|
||||
"widget-caldav",
|
||||
"conf-token_set",
|
||||
{
|
||||
"address_label": lib_plankton.translate.get("widget.caldav.conf.address"),
|
||||
"address_value": conf.address,
|
||||
"username_label": lib_plankton.translate.get("widget.caldav.conf.username"),
|
||||
"username_value": conf.username,
|
||||
"password_label": lib_plankton.translate.get("widget.caldav.conf.password"),
|
||||
"password_value": conf.password,
|
||||
"setup_hints_label": lib_plankton.translate.get("widget.caldav.conf.setup_hints"),
|
||||
"setup_hint_entries": (
|
||||
await lib_plankton.call.promise_condense<string, unknown>(
|
||||
conf.setup_hints
|
||||
.map(
|
||||
entry => () => _dali.helpers.template_coin(
|
||||
"widget-caldav",
|
||||
"conf-setup_hint_entry",
|
||||
{
|
||||
"text": entry.label,
|
||||
"href": entry.link,
|
||||
"remark": (
|
||||
(entry.remark === null)
|
||||
?
|
||||
""
|
||||
:
|
||||
lib_plankton.string.coin(
|
||||
" — {{content}}",
|
||||
{
|
||||
"content": entry.remark,
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
).join("")
|
||||
}
|
||||
)
|
||||
),
|
||||
"set_token_title": lib_plankton.translate.get("widget.caldav.set_token.title"),
|
||||
"set_token_action": (
|
||||
(conf.password === null)
|
||||
?
|
||||
lib_plankton.translate.get("widget.caldav.set_token.action.set")
|
||||
:
|
||||
lib_plankton.translate.get("widget.caldav.set_token.action.overwrite")
|
||||
),
|
||||
}
|
||||
)
|
||||
),
|
||||
"close": lib_plankton.translate.get("common.close"),
|
||||
}
|
||||
);
|
||||
// logic
|
||||
{
|
||||
// set token
|
||||
{
|
||||
if (conf === null)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
target_element.querySelector(".widget-caldav-set_token > button").addEventListener(
|
||||
"click",
|
||||
async () => {
|
||||
await _dali.backend.user_dav_token();
|
||||
await this.load(target_element);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
// close
|
||||
{
|
||||
target_element.querySelector(".widget-caldav-close").addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
// init
|
||||
{
|
||||
(target_element.querySelector(".widget-caldav-close") as HTMLElement).focus();
|
||||
}
|
||||
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
.caldav-conf-section
|
||||
.widget-caldav-conf-section
|
||||
{
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.caldav-conf-section-label
|
||||
.widget-caldav-conf-section-label
|
||||
{
|
||||
margin-left: 16px;
|
||||
display: block;
|
||||
|
|
@ -11,12 +11,12 @@
|
|||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.caldav-conf-section-value
|
||||
.widget-caldav-conf-section-value
|
||||
{
|
||||
margin-left: 32px;
|
||||
}
|
||||
|
||||
.caldav-conf-section-value-regular
|
||||
.widget-caldav-conf-section-value-regular
|
||||
{
|
||||
font-family: monospace;
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<div id="caldav-conf">
|
||||
<div class="widget-caldav-conf">
|
||||
<h3>{{conf_title}}</h3>
|
||||
{{conf_content}}
|
||||
</div>
|
||||
<div id="caldav-set_token">
|
||||
<div class="widget-caldav-set_token">
|
||||
<h3>{{set_token_title}}</h3>
|
||||
<button>{{set_token_action}}</button>
|
||||
</div>
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
<li class="caldav-conf-setup_hints-entry">
|
||||
<li class="widget-caldav-conf-setup_hints-entry">
|
||||
<a target="_blank" href="{{href}}">{{text}}</a>{{remark}}
|
||||
</li>
|
||||
18
source/widgets/caldav/templates/conf-token_set.html.tpl
Normal file
18
source/widgets/caldav/templates/conf-token_set.html.tpl
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<div class="widget-caldav-conf-section" class="widget-caldav-conf-address">
|
||||
<span class="widget-caldav-conf-section-label">{{address_label}}</span>
|
||||
<span class="widget-caldav-conf-section-value widget-caldav-conf-section-value-regular">{{address_value}}</span>
|
||||
</div>
|
||||
<div class="widget-caldav-conf-section" class="widget-caldav-conf-username">
|
||||
<span class="widget-caldav-conf-section-label">{{username_label}}</span>
|
||||
<span class="widget-caldav-conf-section-value widget-caldav-conf-section-value-regular">{{username_value}}</span>
|
||||
</div>
|
||||
<div class="widget-caldav-conf-section" class="widget-caldav-conf-password">
|
||||
<span class="widget-caldav-conf-section-label">{{password_label}}</span>
|
||||
<span class="widget-caldav-conf-section-value widget-caldav-conf-section-value-regular">{{password_value}}</span>
|
||||
</div>
|
||||
<div class="widget-caldav-conf-section" class="widget-caldav-conf-setup_hints">
|
||||
<span class="widget-caldav-conf-section-label">{{setup_hints_label}}</span>
|
||||
<ul>
|
||||
{{setup_hint_entries}}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<div class="widget-caldav-conf-info">
|
||||
({{text}})
|
||||
</div>
|
||||
|
||||
8
source/widgets/caldav/templates/main.html.tpl
Normal file
8
source/widgets/caldav/templates/main.html.tpl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<div class="widget-caldav">
|
||||
<h2>{{title}}</h2>
|
||||
<div class="widget-caldav-content">
|
||||
{{content}}
|
||||
</div>
|
||||
<hr/>
|
||||
<button class="widget-caldav-close">{{close}}</button>
|
||||
</div>
|
||||
3
source/widgets/caldav/templates/unavailable.html.tpl
Normal file
3
source/widgets/caldav/templates/unavailable.html.tpl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<div class="widget-caldav-info">
|
||||
{{text}}
|
||||
</div>
|
||||
|
|
@ -1,4 +1,24 @@
|
|||
namespace _dali.widgets.calendar_edit
|
||||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
@ -91,6 +111,13 @@ namespace _dali.widgets.calendar_edit
|
|||
target_element : HTMLElement
|
||||
) : Promise<void>
|
||||
{
|
||||
const dom_root = await _dali.helpers.element_from_template(
|
||||
"widget-calendar_edit",
|
||||
"main",
|
||||
{
|
||||
}
|
||||
);
|
||||
|
||||
const form : lib_plankton.zoo_form.class_form<
|
||||
_dali.type_calendar_object,
|
||||
_dali.type_calendar_object
|
||||
|
|
@ -223,9 +250,12 @@ namespace _dali.widgets.calendar_edit
|
|||
)
|
||||
)
|
||||
);
|
||||
await form.setup(target_element);
|
||||
await form.setup(dom_root);
|
||||
await form.input_lock(this.read_only);
|
||||
await form.input_write(this.initial_value);
|
||||
|
||||
target_element.appendChild(dom_root);
|
||||
form.input_focus();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
4
source/widgets/calendar_edit/style.css
Normal file
4
source/widgets/calendar_edit/style.css
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
.widget-calendar_edit .plankton_input_group_field[rel="resource"]
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
2
source/widgets/calendar_edit/templates/main.html.tpl
Normal file
2
source/widgets/calendar_edit/templates/main.html.tpl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<div class="widget-calendar_edit">
|
||||
</div>
|
||||
|
|
@ -1,4 +1,24 @@
|
|||
namespace _dali.widgets.event_edit
|
||||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
@ -134,6 +154,13 @@ namespace _dali.widgets.event_edit
|
|||
target_element : HTMLElement
|
||||
) : Promise<void>
|
||||
{
|
||||
const dom_root = await _dali.helpers.element_from_template(
|
||||
"widget-event_edit",
|
||||
"main",
|
||||
{
|
||||
}
|
||||
);
|
||||
|
||||
const form : lib_plankton.zoo_form.class_form<
|
||||
type_value,
|
||||
type_representation
|
||||
|
|
@ -296,9 +323,12 @@ namespace _dali.widgets.event_edit
|
|||
)
|
||||
)
|
||||
);
|
||||
await form.setup(target_element);
|
||||
await form.setup(dom_root);
|
||||
await form.input_lock(this.read_only);
|
||||
await form.input_write(this.initial_value);
|
||||
|
||||
target_element.appendChild(dom_root);
|
||||
form.input_focus();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
2
source/widgets/event_edit/templates/main.html.tpl
Normal file
2
source/widgets/event_edit/templates/main.html.tpl
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
<div class="widget-event_edit">
|
||||
</div>
|
||||
|
|
@ -1,4 +1,24 @@
|
|||
namespace _dali.widgets.listview
|
||||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
@ -142,12 +162,12 @@ namespace _dali.widgets.listview
|
|||
|
||||
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
public async load(
|
||||
target_element : Element
|
||||
public async update_entries(
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
// structure
|
||||
{
|
||||
const now_pit : lib_plankton.pit.type_pit = lib_plankton.pit.now();
|
||||
const from_pit : lib_plankton.pit.type_pit = now_pit;
|
||||
|
|
@ -164,23 +184,8 @@ namespace _dali.widgets.listview
|
|||
lib_plankton.pit.from_datetime(y.event_object.begin)
|
||||
)
|
||||
);
|
||||
|
||||
// view
|
||||
{
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"widget-listview",
|
||||
"main",
|
||||
{
|
||||
"add_href": "",
|
||||
"add_label": lib_plankton.translate.get("widget.listview.add"),
|
||||
"add_extra_classes": (
|
||||
(! await _dali.is_logged_in())
|
||||
?
|
||||
" listview-add-hidden"
|
||||
:
|
||||
""
|
||||
),
|
||||
"entries": (
|
||||
const dom_list : HTMLElement = this.container.querySelector(".listview-entries");
|
||||
dom_list.innerHTML = (
|
||||
(
|
||||
await _dali.helpers.promise_row<string>(
|
||||
entries
|
||||
|
|
@ -267,21 +272,11 @@ namespace _dali.widgets.listview
|
|||
)
|
||||
)
|
||||
.join("")
|
||||
),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// control
|
||||
// listeners
|
||||
{
|
||||
target_element.querySelector(".listview-add").addEventListener(
|
||||
"click",
|
||||
(event) => {
|
||||
event.preventDefault();
|
||||
this.action_add();
|
||||
}
|
||||
);
|
||||
target_element.querySelectorAll(".listview-entry").forEach(
|
||||
this.container.querySelectorAll(".listview-entry").forEach(
|
||||
(element) => {
|
||||
element.addEventListener(
|
||||
"click",
|
||||
|
|
@ -300,8 +295,51 @@ namespace _dali.widgets.listview
|
|||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.container = target_element.querySelector(".listview");
|
||||
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
public async load(
|
||||
target_element : Element
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
this.container = target_element;
|
||||
|
||||
// view
|
||||
{
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"widget-listview",
|
||||
"main",
|
||||
{
|
||||
"add_href": "",
|
||||
"add_label": lib_plankton.translate.get("widget.listview.add"),
|
||||
"add_extra_classes": (
|
||||
(! await _dali.is_logged_in())
|
||||
?
|
||||
" listview-add-hidden"
|
||||
:
|
||||
""
|
||||
),
|
||||
"entries": "",
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// control
|
||||
{
|
||||
target_element.querySelector(".listview-add").addEventListener(
|
||||
"click",
|
||||
(event) => {
|
||||
event.preventDefault();
|
||||
this.action_add();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
await this.update_entries();
|
||||
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,24 @@
|
|||
namespace _dali.widgets.login
|
||||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
@ -53,7 +73,7 @@ namespace _dali.widgets.login
|
|||
* [implementation]
|
||||
*/
|
||||
public async load(
|
||||
target_element : Element
|
||||
target_element : HTMLElement
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
|
|
@ -66,125 +86,36 @@ namespace _dali.widgets.login
|
|||
{
|
||||
case "internal":
|
||||
{
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"widget-login",
|
||||
"default",
|
||||
const sub_widget : lib_plankton.zoo_widget.interface_widget = (
|
||||
new class_widget_login_internal(
|
||||
preparation.data,
|
||||
{
|
||||
"initial_name": this.initial_name,
|
||||
"action_cancel": this.action_cancel,
|
||||
"action_success": this.action_success,
|
||||
}
|
||||
);
|
||||
const form : lib_plankton.zoo_form.class_form<
|
||||
{name : string; password : string;},
|
||||
{name : string; password : string;}
|
||||
> = new lib_plankton.zoo_form.class_form<
|
||||
{name : string; password : string;},
|
||||
{name : string; password : string;}
|
||||
>(
|
||||
x => x,
|
||||
x => x,
|
||||
new lib_plankton.zoo_input.class_input_group<
|
||||
{name : string; password : string;}
|
||||
>(
|
||||
[
|
||||
{
|
||||
"name": "name",
|
||||
"input": new lib_plankton.zoo_input.class_input_text(),
|
||||
"label": lib_plankton.translate.get("widget.login.internal.name"),
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"input": new lib_plankton.zoo_input.class_input_password(),
|
||||
"label": lib_plankton.translate.get("widget.login.internal.password"),
|
||||
},
|
||||
]
|
||||
),
|
||||
(
|
||||
[]
|
||||
.concat(
|
||||
[
|
||||
{
|
||||
"label": lib_plankton.translate.get("widget.login.internal.do"),
|
||||
"procedure": async (get_value, get_representation) => {
|
||||
const value : any = await get_value();
|
||||
try
|
||||
{
|
||||
await _dali.backend.session_begin(
|
||||
value.name,
|
||||
value.password
|
||||
);
|
||||
if (this.action_success !== null) this.action_success();
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// todo
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
.concat(
|
||||
(this.action_cancel === null)
|
||||
?
|
||||
[]
|
||||
:
|
||||
[
|
||||
{
|
||||
"label": lib_plankton.translate.get("common.cancel"),
|
||||
"procedure": () => {
|
||||
this.action_cancel();
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
await form.setup(document.querySelector(".widget-login"));
|
||||
await form.input_write(
|
||||
{
|
||||
"name": this.initial_name,
|
||||
"password": "",
|
||||
}
|
||||
);
|
||||
await sub_widget.load(target_element);
|
||||
break;
|
||||
}
|
||||
case "oidc":
|
||||
{
|
||||
// link
|
||||
const sub_widget : lib_plankton.zoo_widget.interface_widget = (
|
||||
new class_widget_login_oidc(
|
||||
preparation.data,
|
||||
{
|
||||
let element_a : HTMLElement = document.createElement("a");;
|
||||
element_a.textContent = lib_plankton.string.coin(
|
||||
lib_plankton.translate.get("widget.login.oidc.via"),
|
||||
{
|
||||
"title": preparation.data.label,
|
||||
"action_cancel": this.action_cancel,
|
||||
"action_success": this.action_success,
|
||||
}
|
||||
)
|
||||
);
|
||||
element_a.setAttribute("href", preparation.data.url);
|
||||
target_element.appendChild(element_a);
|
||||
}
|
||||
{
|
||||
let dom_br : HTMLElement = document.createElement("br");
|
||||
target_element.appendChild(dom_br);
|
||||
}
|
||||
{
|
||||
let dom_br : HTMLElement = document.createElement("br");
|
||||
target_element.appendChild(dom_br);
|
||||
}
|
||||
// cancel
|
||||
{
|
||||
let dom_cancel : HTMLElement = document.createElement("button");
|
||||
dom_cancel.textContent = lib_plankton.translate.get("common.cancel");
|
||||
dom_cancel.addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
this.action_cancel();
|
||||
}
|
||||
);
|
||||
target_element.appendChild(dom_cancel);
|
||||
}
|
||||
await sub_widget.load(target_element);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// todo
|
||||
throw (new Error("unhandled login kind: " + preparation.kind));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
<div class="widget-login">
|
||||
</div>
|
||||
165
source/widgets/login_internal/logic.ts
Normal file
165
source/widgets/login_internal/logic.ts
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export class class_widget_login_internal
|
||||
implements lib_plankton.zoo_widget.interface_widget
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
private preparation_data : any;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private initial_name : (null | string);
|
||||
|
||||
|
||||
/**
|
||||
* [hook]
|
||||
*/
|
||||
private action_cancel : (null | (() => void));
|
||||
|
||||
|
||||
/**
|
||||
* [hook]
|
||||
*/
|
||||
private action_success : (null | (() => void));
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public constructor(
|
||||
preparation_data : any,
|
||||
{
|
||||
"initial_name": initial_name = null,
|
||||
"action_cancel": action_cancel = null,
|
||||
"action_success": action_success = null,
|
||||
}
|
||||
:
|
||||
{
|
||||
initial_name ?: (null | string);
|
||||
action_cancel ?: (null | (() => void));
|
||||
action_success ?: (null | (() => void));
|
||||
}
|
||||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
{
|
||||
this.preparation_data = preparation_data;
|
||||
this.initial_name = initial_name;
|
||||
this.action_cancel = action_cancel;
|
||||
this.action_success = action_success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
public async load(
|
||||
target_element : HTMLElement
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
const form : lib_plankton.zoo_form.class_form<
|
||||
{name : string; password : string;},
|
||||
{name : string; password : string;}
|
||||
> = new lib_plankton.zoo_form.class_form<
|
||||
{name : string; password : string;},
|
||||
{name : string; password : string;}
|
||||
>(
|
||||
x => x,
|
||||
x => x,
|
||||
new lib_plankton.zoo_input.class_input_group<
|
||||
{name : string; password : string;}
|
||||
>(
|
||||
[
|
||||
{
|
||||
"name": "name",
|
||||
"input": new lib_plankton.zoo_input.class_input_text(),
|
||||
"label": lib_plankton.translate.get("widget.login.internal.name"),
|
||||
},
|
||||
{
|
||||
"name": "password",
|
||||
"input": new lib_plankton.zoo_input.class_input_password(),
|
||||
"label": lib_plankton.translate.get("widget.login.internal.password"),
|
||||
},
|
||||
]
|
||||
),
|
||||
(
|
||||
[]
|
||||
.concat(
|
||||
[
|
||||
{
|
||||
"label": lib_plankton.translate.get("widget.login.internal.do"),
|
||||
"procedure": async (get_value, get_representation) => {
|
||||
const value : any = await get_value();
|
||||
try
|
||||
{
|
||||
await _dali.backend.session_begin(
|
||||
value.name,
|
||||
value.password
|
||||
);
|
||||
if (this.action_success !== null) this.action_success();
|
||||
}
|
||||
catch (error)
|
||||
{
|
||||
// todo
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
.concat(
|
||||
(this.action_cancel === null)
|
||||
?
|
||||
[]
|
||||
:
|
||||
[
|
||||
{
|
||||
"label": lib_plankton.translate.get("common.cancel"),
|
||||
"procedure": () => {
|
||||
this.action_cancel();
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
)
|
||||
);
|
||||
target_element.innerHTML = "";
|
||||
await form.setup(target_element);
|
||||
await form.input_write(
|
||||
{
|
||||
"name": this.initial_name,
|
||||
"password": "",
|
||||
}
|
||||
);
|
||||
form.input_focus();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
110
source/widgets/login_oidc/logic.ts
Normal file
110
source/widgets/login_oidc/logic.ts
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export class class_widget_login_oidc
|
||||
implements lib_plankton.zoo_widget.interface_widget
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
private preparation_data : any;
|
||||
|
||||
|
||||
/**
|
||||
* [hook]
|
||||
*/
|
||||
private action_cancel : (null | (() => void));
|
||||
|
||||
|
||||
/**
|
||||
* [hook]
|
||||
*/
|
||||
private action_success : (null | (() => void));
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public constructor(
|
||||
preparation_data : any,
|
||||
{
|
||||
"action_cancel": action_cancel = null,
|
||||
"action_success": action_success = null,
|
||||
}
|
||||
:
|
||||
{
|
||||
action_cancel ?: (null | (() => void));
|
||||
action_success ?: (null | (() => void));
|
||||
}
|
||||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
{
|
||||
this.preparation_data = preparation_data;
|
||||
this.action_cancel = action_cancel;
|
||||
this.action_success = action_success;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
public async load(
|
||||
target_element : HTMLElement
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
// structure
|
||||
{
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"widget-login_oidc",
|
||||
"main",
|
||||
{
|
||||
"label": lib_plankton.string.coin(
|
||||
lib_plankton.translate.get("widget.login.oidc.via"),
|
||||
{
|
||||
"title": this.preparation_data.label,
|
||||
}
|
||||
),
|
||||
"href": this.preparation_data.url,
|
||||
"cancel": lib_plankton.translate.get("common.cancel"),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// controls
|
||||
{
|
||||
target_element.querySelector(".widget-login_oidc-cancel").addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
this.action_cancel();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
5
source/widgets/login_oidc/style.css
Normal file
5
source/widgets/login_oidc/style.css
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.widget-login_oidc-cancel
|
||||
{
|
||||
display: block;
|
||||
margin-top: 32px;
|
||||
}
|
||||
4
source/widgets/login_oidc/templates/main.html.tpl
Normal file
4
source/widgets/login_oidc/templates/main.html.tpl
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<div class="widget-login_oidc">
|
||||
<a class="widget-login_oidc-link" href="{{href}}">{{label}}</a>
|
||||
<button class="widget-login_oidc-cancel">{{cancel}}</button>
|
||||
</div>
|
||||
|
|
@ -1,4 +1,24 @@
|
|||
namespace _dali.widgets.menu
|
||||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
@ -17,12 +37,7 @@ namespace _dali.widgets.menu
|
|||
|
||||
/**
|
||||
*/
|
||||
private entries : Array<
|
||||
{
|
||||
data : type_entry_data;
|
||||
element : (null | HTMLElement);
|
||||
}
|
||||
>;
|
||||
private entries : Array<type_entry_data>;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -43,10 +58,10 @@ namespace _dali.widgets.menu
|
|||
/**
|
||||
*/
|
||||
public constructor(
|
||||
entry_data_list : Array<type_entry_data>,
|
||||
entries : Array<type_entry_data>,
|
||||
{
|
||||
"initial_groups": initial_groups = [],
|
||||
"initial_label": initial_label = "=",
|
||||
"initial_label": initial_label = "",
|
||||
}
|
||||
:
|
||||
{
|
||||
|
|
@ -58,14 +73,7 @@ namespace _dali.widgets.menu
|
|||
}
|
||||
)
|
||||
{
|
||||
this.entries = entry_data_list.map(
|
||||
entry_data => (
|
||||
{
|
||||
"data": entry_data,
|
||||
"element": null,
|
||||
}
|
||||
)
|
||||
);
|
||||
this.entries = entries;
|
||||
this.initial_groups = initial_groups;
|
||||
this.label = initial_label;
|
||||
this.container = null;
|
||||
|
|
@ -80,25 +88,28 @@ namespace _dali.widgets.menu
|
|||
: void
|
||||
{
|
||||
this.entries.forEach(
|
||||
entry => {
|
||||
const active : boolean = groups.some(group => entry.data.groups.includes(group));
|
||||
entry.element.classList.toggle("widget-menu-entry-hidden", (! active));
|
||||
(entry, index) => {
|
||||
const active : boolean = groups.some(group => entry.groups.includes(group));
|
||||
const rel : string = index.toFixed(0);
|
||||
const dom_entry = this.container.querySelector(".widget-menu-entry[rel=\"" + rel + "\"]");
|
||||
dom_entry.classList.toggle("widget-menu-entry-hidden", (! active));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public set_label(
|
||||
label ?: string
|
||||
label : (null | string)
|
||||
)
|
||||
: void
|
||||
{
|
||||
this.label = label;
|
||||
this.container.querySelector(".widget-menu-button").textContent = (
|
||||
this.container.querySelector(".widget-menu-button").innerHTML = (
|
||||
(this.label === null)
|
||||
?
|
||||
"[=]"
|
||||
("[" + "=" + "]")
|
||||
:
|
||||
("[" + this.label + "]")
|
||||
);
|
||||
|
|
@ -133,56 +144,69 @@ namespace _dali.widgets.menu
|
|||
)
|
||||
: Promise<void>
|
||||
{
|
||||
// container
|
||||
// structure
|
||||
this.container = await _dali.helpers.element_from_template(
|
||||
"widget-menu",
|
||||
"main",
|
||||
{
|
||||
const dom_container : HTMLElement = document.createElement("div");
|
||||
dom_container.classList.add("widget-menu");
|
||||
// button
|
||||
"entries": (
|
||||
(
|
||||
await lib_plankton.call.promise_condense(
|
||||
this.entries.map(
|
||||
(entry, index) => () => _dali.helpers.template_coin(
|
||||
"widget-menu",
|
||||
"entry",
|
||||
{
|
||||
const dom_button : HTMLElement = document.createElement("button");
|
||||
dom_button.textContent = "[" + this.label + "]";
|
||||
dom_button.classList.add("widget-menu-button");
|
||||
dom_button.addEventListener(
|
||||
"label": entry.label,
|
||||
"rel": index.toFixed(0),
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.join("")
|
||||
),
|
||||
}
|
||||
);
|
||||
|
||||
// logic
|
||||
{
|
||||
// collapser
|
||||
{
|
||||
this.container.querySelector(".widget-menu-button").addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
this.toggle_collapsed();
|
||||
}
|
||||
);
|
||||
dom_container.classList.toggle("widget-menu-collapsed", true);
|
||||
dom_container.appendChild(dom_button);
|
||||
}
|
||||
// platform
|
||||
// entries
|
||||
{
|
||||
const dom_platform : HTMLElement = document.createElement("div");
|
||||
dom_platform.classList.add("widget-menu-platform");
|
||||
{
|
||||
const dom_list : HTMLElement = document.createElement("ul");
|
||||
dom_list.classList.add("widget-menu-entries");
|
||||
this.entries.forEach(
|
||||
entry => {
|
||||
const dom_entry : HTMLElement = document.createElement("li");
|
||||
dom_entry.classList.add("widget-menu-entry");
|
||||
dom_entry.textContent = entry.data.label;
|
||||
this.container.querySelectorAll(".widget-menu-entry").forEach(
|
||||
dom_entry => {
|
||||
dom_entry.addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
const index : int = parseInt(dom_entry.getAttribute("rel"));
|
||||
const entry : type_entry_data = this.entries[index];
|
||||
this.toggle_collapsed({"mode": true});
|
||||
entry.data.action();
|
||||
entry.action();
|
||||
}
|
||||
);
|
||||
dom_list.appendChild(dom_entry);
|
||||
entry.element = dom_entry;
|
||||
}
|
||||
);
|
||||
dom_platform.appendChild(dom_list);
|
||||
}
|
||||
dom_container.appendChild(dom_platform);
|
||||
}
|
||||
target_element.appendChild(dom_container);
|
||||
this.container = dom_container;
|
||||
}
|
||||
|
||||
// init
|
||||
{
|
||||
this.toggle_collapsed({"mode": true});
|
||||
this.set_groups(this.initial_groups);
|
||||
this.set_label(null);
|
||||
}
|
||||
|
||||
// finish
|
||||
target_element.appendChild(this.container);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@
|
|||
|
||||
padding: 8px;
|
||||
|
||||
/*
|
||||
min-width: 200px;
|
||||
*/
|
||||
}
|
||||
|
||||
.widget-menu-platform:not(.widget-menu-platform-collapsed)
|
||||
|
|
@ -49,23 +51,22 @@
|
|||
|
||||
.widget-menu-entry
|
||||
{
|
||||
margin: 8px;
|
||||
margin: 12px 8px;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.widget-menu-entry:not(:hover)
|
||||
{
|
||||
background-color: hsl(var(--hue), 0%, 25%);
|
||||
color: hsl(var(--hue), 0%, 100%);
|
||||
}
|
||||
|
||||
.widget-menu-entry:hover::before
|
||||
.widget-menu-entry:not(:hover) > span
|
||||
{
|
||||
content: "» ";
|
||||
/*
|
||||
background-color: hsl(var(--hue), 0%, 50%);
|
||||
color: hsl(var(--hue), 0%, 100%);
|
||||
*/
|
||||
border-bottom: 2px solid hsl(0, 0%, 25%);
|
||||
}
|
||||
|
||||
.widget-menu-entry:hover > span
|
||||
{
|
||||
border-bottom: 2px solid hsl(0, 0%, 100%);
|
||||
|
||||
transition: 1s ease color;
|
||||
}
|
||||
|
||||
.widget-menu-entry.widget-menu-entry-hidden
|
||||
|
|
|
|||
3
source/widgets/menu/templates/entry.html.tpl
Normal file
3
source/widgets/menu/templates/entry.html.tpl
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<li class="widget-menu-entry" rel="{{rel}}">
|
||||
<span>{{label}}</span>
|
||||
</li>
|
||||
8
source/widgets/menu/templates/main.html.tpl
Normal file
8
source/widgets/menu/templates/main.html.tpl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<div class="widget-menu">
|
||||
<button class="widget-menu-button"></button>
|
||||
<div class="widget-menu-platform">
|
||||
<ul class="widget-menu-entries">
|
||||
{{entries}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,4 +1,24 @@
|
|||
namespace _dali.widgets.mode_switcher
|
||||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
@ -58,7 +78,8 @@ namespace _dali.widgets.mode_switcher
|
|||
*/
|
||||
public async load(
|
||||
target_element : Element
|
||||
) : Promise<void>
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"widget-mode_switcher",
|
||||
|
|
|
|||
4
source/widgets/mode_switcher/style.css
Normal file
4
source/widgets/mode_switcher/style.css
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
.widget-mode_switcher-option
|
||||
{
|
||||
margin-left: 16px;
|
||||
}
|
||||
278
source/widgets/multiview/logic.ts
Normal file
278
source/widgets/multiview/logic.ts
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
type type_get_entries = (
|
||||
(
|
||||
from_pit : lib_plankton.pit.type_pit,
|
||||
to_pit : lib_plankton.pit.type_pit,
|
||||
calendar_ids : Array<_dali.type_calendar_id>
|
||||
)
|
||||
=>
|
||||
Promise<Array<_dali.type_event_object_extended>>
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
type type_create_event = (
|
||||
(
|
||||
stuff ?: {
|
||||
date ?: lib_plankton.pit.type_date;
|
||||
}
|
||||
)
|
||||
=>
|
||||
Promise<void>
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
type type_edit_event = (
|
||||
(
|
||||
event_key : _dali.type_event_key
|
||||
)
|
||||
=>
|
||||
Promise<void>
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export class class_widget_multiview
|
||||
implements lib_plankton.zoo_widget.interface_widget
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
private initial_view_mode : _dali.enum_view_mode;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private weekview_initial_vertical : boolean;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private get_entries : type_get_entries;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private action_create_event : type_create_event;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private action_edit_event : type_edit_event;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private dom_context : (null | HTMLElement);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private widget_mode_switcher : _dali.widgets.class_widget_mode_switcher;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private widget_weekview : _dali.widgets.class_widget_weekview;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private widget_listview : _dali.widgets.class_widget_listview;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public constructor(
|
||||
get_entries : type_get_entries,
|
||||
{
|
||||
"initial_view_mode": initial_view_mode = _dali.enum_view_mode.week,
|
||||
"weekview_initial_vertical": weekview_initial_vertical = false,
|
||||
"action_create_event": action_create_event = ((stuff) => Promise.resolve<void>(undefined)),
|
||||
"action_edit_event": action_edit_event = ((event_key) => Promise.resolve<void>(undefined)),
|
||||
}
|
||||
:
|
||||
{
|
||||
initial_view_mode ?: _dali.enum_view_mode;
|
||||
weekview_initial_vertical ?: boolean;
|
||||
action_create_event ?: type_create_event;
|
||||
action_edit_event ?: type_edit_event;
|
||||
}
|
||||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
{
|
||||
this.get_entries = get_entries;
|
||||
this.initial_view_mode = initial_view_mode;
|
||||
this.weekview_initial_vertical = weekview_initial_vertical;
|
||||
this.action_create_event = action_create_event;
|
||||
this.action_edit_event = action_edit_event;
|
||||
this.dom_context = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public toggle_calendar_visibilty(
|
||||
calendar_id : _dali.type_calendar_id,
|
||||
{
|
||||
"mode": mode = null,
|
||||
}
|
||||
:
|
||||
{
|
||||
mode ?: (null | boolean);
|
||||
}
|
||||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
: void
|
||||
{
|
||||
this.widget_weekview.toggle_visibility(calendar_id, {"mode": mode});
|
||||
this.widget_listview.toggle_visibility(calendar_id, {"mode": mode});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private set_view_mode
|
||||
(
|
||||
view_mode : _dali.enum_view_mode
|
||||
)
|
||||
: void
|
||||
{
|
||||
this.dom_context.setAttribute("rel", _dali.view_mode_encode(view_mode));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public async update_entries(
|
||||
)
|
||||
:
|
||||
Promise<void>
|
||||
{
|
||||
await Promise.all(
|
||||
[
|
||||
this.widget_weekview.update_entries(),
|
||||
this.widget_listview.update_entries(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
public async load(
|
||||
target_element : Element
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
this.dom_context = (target_element as HTMLElement);
|
||||
|
||||
this.dom_context.classList.add("widget-multiview");
|
||||
|
||||
// mode switcher
|
||||
{
|
||||
this.widget_mode_switcher = (
|
||||
new _dali.widgets.class_widget_mode_switcher(
|
||||
[
|
||||
{
|
||||
"mode": _dali.enum_view_mode.week,
|
||||
/**
|
||||
* @todo as dependency
|
||||
*/
|
||||
"label": lib_plankton.translate.get("widget.overview.mode.week"),
|
||||
},
|
||||
{
|
||||
"mode": _dali.enum_view_mode.list,
|
||||
/**
|
||||
* @todo as dependency
|
||||
*/
|
||||
"label": lib_plankton.translate.get("widget.overview.mode.list"),
|
||||
},
|
||||
],
|
||||
{
|
||||
"initial_selection": this.initial_view_mode,
|
||||
"action_change": (view_mode) => {
|
||||
this.set_view_mode(view_mode);
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
let dom_wrapper = document.createElement("div");
|
||||
dom_wrapper.classList.add("widget-multiview-mode_switcher");
|
||||
await this.widget_mode_switcher.load(dom_wrapper);
|
||||
this.dom_context.appendChild(dom_wrapper);
|
||||
}
|
||||
// weekview
|
||||
{
|
||||
this.widget_weekview = (
|
||||
new _dali.widgets.class_widget_weekview(
|
||||
this.get_entries,
|
||||
{
|
||||
"action_select_event": (event_key) => this.action_edit_event(event_key),
|
||||
"action_select_day": (date) => this.action_create_event({"date": date}),
|
||||
"vertical": this.weekview_initial_vertical,
|
||||
}
|
||||
)
|
||||
);
|
||||
let dom_wrapper = document.createElement("div");
|
||||
dom_wrapper.classList.add("widget-multiview-weekview");
|
||||
await this.widget_weekview.load(dom_wrapper);
|
||||
this.dom_context.appendChild(dom_wrapper);
|
||||
}
|
||||
// listview
|
||||
{
|
||||
this.widget_listview = (
|
||||
new _dali.widgets.class_widget_listview(
|
||||
this.get_entries,
|
||||
{
|
||||
"action_select": (event_key) => this.action_edit_event(event_key),
|
||||
"action_add": () => this.action_create_event(),
|
||||
}
|
||||
)
|
||||
);
|
||||
let dom_wrapper = document.createElement("div");
|
||||
dom_wrapper.classList.add("widget-multiview-listview");
|
||||
await this.widget_listview.load(dom_wrapper);
|
||||
this.dom_context.appendChild(dom_wrapper);
|
||||
}
|
||||
this.set_view_mode(this.initial_view_mode);
|
||||
|
||||
return Promise.resolve<void>(undefined);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
10
source/widgets/multiview/style.css
Normal file
10
source/widgets/multiview/style.css
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
.widget-multiview-mode_switcher
|
||||
{
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.widget-multiview[rel="week"] > .widget-multiview-weekview {}
|
||||
.widget-multiview[rel="week"] > .widget-multiview-listview {display: none;}
|
||||
|
||||
.widget-multiview[rel="list"] > .widget-multiview-weekview {display: none;}
|
||||
.widget-multiview[rel="list"] > .widget-multiview-listview {}
|
||||
|
|
@ -1,141 +1,115 @@
|
|||
namespace _dali.pages.overview
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
lib_plankton.zoo_page.register(
|
||||
"overview",
|
||||
async (parameters, target_element) => {
|
||||
// params
|
||||
const view_mode : _dali.enum_view_mode = _dali.helpers.view_mode_determine(parameters["mode"] ?? "auto");
|
||||
|
||||
// exec
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"overview",
|
||||
"default",
|
||||
{
|
||||
}
|
||||
);
|
||||
|
||||
let widget_mode_switcher : lib_plankton.zoo_widget.interface_widget;
|
||||
let widget_sources : _dali.widgets.sources.class_widget_sources;
|
||||
let widget_weekview : _dali.widgets.weekview.class_widget_weekview;
|
||||
let widget_listview : _dali.widgets.listview.class_widget_listview;
|
||||
|
||||
/**
|
||||
* @todo ordentlich machen (nicht nur week und list)
|
||||
*/
|
||||
function set_view_mode
|
||||
(
|
||||
view_mode : _dali.enum_view_mode
|
||||
)
|
||||
: void
|
||||
{
|
||||
const compact : boolean = (view_mode !== _dali.enum_view_mode.week);
|
||||
target_element.querySelector("#overview").classList.toggle("overview-compact", compact);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async function get_available_calendars(
|
||||
)
|
||||
: Promise<
|
||||
Array<
|
||||
_dali.type_calendar_object_reduced_with_id
|
||||
>
|
||||
>
|
||||
{
|
||||
return (
|
||||
(await _dali.model.calendar_list())
|
||||
/*
|
||||
.filter(
|
||||
(entry) => (
|
||||
(entry.access_level === _dali.enum_access_level.edit)
|
||||
||
|
||||
(entry.access_level === _dali.enum_access_level.admin)
|
||||
)
|
||||
)
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
type type_action_create_calendar = (
|
||||
(
|
||||
)
|
||||
=>
|
||||
Promise<void>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo add return type
|
||||
*/
|
||||
async function get_entries(
|
||||
from_pit : lib_plankton.pit.type_pit,
|
||||
to_pit : lib_plankton.pit.type_pit,
|
||||
calendar_ids : Array<_dali.type_calendar_id>
|
||||
type type_action_edit_calendar = (
|
||||
(
|
||||
type_calendar_object_reduced_with_id
|
||||
)
|
||||
: Promise<Array<_dali.type_event_object_extended>>
|
||||
{
|
||||
/**
|
||||
* @todo do NOT wait?
|
||||
*/
|
||||
await _dali.model.sync_events(
|
||||
{
|
||||
"from": from_pit,
|
||||
"to": to_pit,
|
||||
},
|
||||
{
|
||||
"calendar_ids": calendar_ids,
|
||||
}
|
||||
=>
|
||||
Promise<void>
|
||||
);
|
||||
/**
|
||||
* @todo filter
|
||||
*/
|
||||
return _dali.model.event_list();
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo update listview
|
||||
*/
|
||||
async function update_sources_and_entries(
|
||||
{
|
||||
"priviliged": priviliged = null,
|
||||
}
|
||||
:
|
||||
{
|
||||
priviliged ?: (null | boolean);
|
||||
}
|
||||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
await widget_sources.update({"priviliged": priviliged});
|
||||
await widget_weekview.update_entries();
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo use priviliged?
|
||||
* @todo update listview
|
||||
*/
|
||||
async function update_entries(
|
||||
{
|
||||
"priviliged": priviliged = null,
|
||||
}
|
||||
:
|
||||
{
|
||||
priviliged ?: (null | boolean);
|
||||
}
|
||||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
await widget_weekview.update_entries();
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async function action_create_calendar(
|
||||
type type_action_create_event = (
|
||||
(
|
||||
stuff ?: {
|
||||
date ?: lib_plankton.pit.type_date;
|
||||
}
|
||||
)
|
||||
: Promise<void>
|
||||
=>
|
||||
Promise<void>
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
type type_action_edit_event = (
|
||||
(
|
||||
event_key : _dali.type_event_key
|
||||
)
|
||||
=>
|
||||
Promise<void>
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
export class class_widget_overview
|
||||
implements lib_plankton.zoo_widget.interface_widget
|
||||
{
|
||||
const widget = new _dali.widgets.calendar_edit.class_widget_calendar_edit(
|
||||
|
||||
/**
|
||||
*/
|
||||
private widget_sources : _dali.widgets.class_widget_sources;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private widget_multiview : _dali.widgets.class_widget_multiview;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private action_create_calendar : type_action_create_calendar;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private action_edit_calendar : type_action_edit_calendar;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private action_create_event : type_action_create_event;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private action_edit_event : type_action_edit_event;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public constructor(
|
||||
)
|
||||
{
|
||||
this.action_create_calendar = async (
|
||||
) => {
|
||||
const widget = new _dali.widgets.class_widget_calendar_edit(
|
||||
await _dali.model.group_list(),
|
||||
await _dali.model.user_list(),
|
||||
{
|
||||
|
|
@ -143,7 +117,7 @@ namespace _dali.pages.overview
|
|||
"hue": lib_plankton.random.generate_unit(),
|
||||
"access": {
|
||||
"public": false,
|
||||
"default_level": _dali.enum_access_level.view,
|
||||
"default_level": _dali.enum_access_level.none,
|
||||
"attributed_group": lib_plankton.map.hashmap.implementation_map<
|
||||
_dali.type_group_id,
|
||||
_dali.enum_access_level
|
||||
|
|
@ -183,7 +157,7 @@ namespace _dali.pages.overview
|
|||
)
|
||||
.then(
|
||||
() => {
|
||||
update_sources_and_entries();
|
||||
this.update_sources_and_entries();
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
}
|
||||
)
|
||||
|
|
@ -201,15 +175,10 @@ namespace _dali.pages.overview
|
|||
_dali.overlay.clear();
|
||||
_dali.overlay.toggle({"mode": true});
|
||||
await widget.load(_dali.overlay.get_content_element());
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async function action_edit_calendar(
|
||||
calendar_object_reduced_with_id : type_calendar_object_reduced_with_id
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
};
|
||||
this.action_edit_calendar = async (
|
||||
calendar_object_reduced_with_id
|
||||
) => {
|
||||
const read_only : boolean = (() => {
|
||||
switch (calendar_object_reduced_with_id.access_level)
|
||||
{
|
||||
|
|
@ -246,7 +215,7 @@ namespace _dali.pages.overview
|
|||
const calendar_object : _dali.type_calendar_object = await _dali.model.calendar_get(
|
||||
calendar_id
|
||||
);
|
||||
const widget = new _dali.widgets.calendar_edit.class_widget_calendar_edit(
|
||||
const widget = new _dali.widgets.class_widget_calendar_edit(
|
||||
await _dali.model.group_list(),
|
||||
await _dali.model.user_list(),
|
||||
calendar_object,
|
||||
|
|
@ -262,7 +231,7 @@ namespace _dali.pages.overview
|
|||
)
|
||||
.then(
|
||||
() => {
|
||||
update_sources_and_entries();
|
||||
this.update_sources_and_entries();
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
}
|
||||
);
|
||||
|
|
@ -273,7 +242,7 @@ namespace _dali.pages.overview
|
|||
)
|
||||
.then(
|
||||
() => {
|
||||
update_sources_and_entries();
|
||||
this.update_sources_and_entries();
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
}
|
||||
);
|
||||
|
|
@ -285,11 +254,10 @@ namespace _dali.pages.overview
|
|||
await widget.load(_dali.overlay.get_content_element());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo unterschiedliches Verhalten bei Anmeldung?
|
||||
*/
|
||||
async function action_create_event(
|
||||
this.action_create_event = async (
|
||||
{
|
||||
"date": date = lib_plankton.pit.to_datetime(lib_plankton.pit.now()).date,
|
||||
}
|
||||
|
|
@ -300,17 +268,15 @@ namespace _dali.pages.overview
|
|||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
) => {
|
||||
if (! _dali.is_logged_in())
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
const widget = new _dali.widgets.event_edit.class_widget_event_edit(
|
||||
(await get_available_calendars()),
|
||||
const widget = new _dali.widgets.class_widget_event_edit(
|
||||
(await this.get_available_calendars()),
|
||||
{
|
||||
"calendar_id": null,
|
||||
"event_name": "",
|
||||
|
|
@ -363,7 +329,7 @@ namespace _dali.pages.overview
|
|||
)
|
||||
.then(
|
||||
() => {
|
||||
update_entries();
|
||||
this.update_entries();
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
}
|
||||
)
|
||||
|
|
@ -380,15 +346,11 @@ namespace _dali.pages.overview
|
|||
await widget.load(_dali.overlay.get_content_element());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
async function action_edit_event
|
||||
(
|
||||
event_key : _dali.type_event_key
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
this.action_edit_event = async (
|
||||
event_key
|
||||
) => {
|
||||
const event_object_extended : _dali.type_event_object_extended = await _dali.model.event_get(event_key);
|
||||
const read_only : boolean = (() => {
|
||||
switch (event_object_extended.access_level)
|
||||
|
|
@ -411,8 +373,8 @@ namespace _dali.pages.overview
|
|||
}
|
||||
}
|
||||
}) ();
|
||||
const widget = new _dali.widgets.event_edit.class_widget_event_edit(
|
||||
(await get_available_calendars()),
|
||||
const widget = new _dali.widgets.class_widget_event_edit(
|
||||
(await this.get_available_calendars()),
|
||||
{
|
||||
"calendar_id": event_object_extended.calendar_id,
|
||||
"event_name": event_object_extended.event_object.name,
|
||||
|
|
@ -441,7 +403,7 @@ namespace _dali.pages.overview
|
|||
)
|
||||
.then(
|
||||
() => {
|
||||
update_entries();
|
||||
this.update_entries();
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
}
|
||||
)
|
||||
|
|
@ -460,7 +422,7 @@ namespace _dali.pages.overview
|
|||
)
|
||||
.then(
|
||||
() => {
|
||||
update_entries();
|
||||
this.update_entries();
|
||||
_dali.overlay.toggle({"mode": false});
|
||||
}
|
||||
)
|
||||
|
|
@ -475,105 +437,212 @@ namespace _dali.pages.overview
|
|||
},
|
||||
}
|
||||
);
|
||||
|
||||
_dali.overlay.clear();
|
||||
_dali.overlay.toggle({"mode": true});
|
||||
await widget.load(_dali.overlay.get_content_element());
|
||||
}
|
||||
|
||||
// hint
|
||||
{
|
||||
const dom_hint = target_element.querySelector("#overview-hint");
|
||||
dom_hint.textContent = lib_plankton.translate.get("page.overview.login_hint");
|
||||
dom_hint.classList.toggle("overview-hint-hidden", _dali.is_logged_in());
|
||||
}
|
||||
|
||||
// mode switcher
|
||||
|
||||
/**
|
||||
*/
|
||||
private async get_available_calendars(
|
||||
)
|
||||
: Promise<
|
||||
Array<
|
||||
_dali.type_calendar_object_reduced_with_id
|
||||
>
|
||||
>
|
||||
{
|
||||
widget_mode_switcher = new _dali.widgets.mode_switcher.class_widget_mode_switcher(
|
||||
[
|
||||
return (
|
||||
(await _dali.model.calendar_list())
|
||||
/*
|
||||
.filter(
|
||||
(entry) => (
|
||||
(entry.access_level === _dali.enum_access_level.edit)
|
||||
||
|
||||
(entry.access_level === _dali.enum_access_level.admin)
|
||||
)
|
||||
)
|
||||
*/
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private async get_entries(
|
||||
from_pit : lib_plankton.pit.type_pit,
|
||||
to_pit : lib_plankton.pit.type_pit,
|
||||
calendar_ids : Array<_dali.type_calendar_id>
|
||||
)
|
||||
: Promise<Array<_dali.type_event_object_extended>>
|
||||
{
|
||||
"mode": _dali.enum_view_mode.week,
|
||||
"label": lib_plankton.translate.get("page.overview.mode.week"),
|
||||
/**
|
||||
* @todo do NOT wait?
|
||||
*/
|
||||
await _dali.model.sync_events(
|
||||
{
|
||||
"from": from_pit,
|
||||
"to": to_pit,
|
||||
},
|
||||
{
|
||||
"mode": _dali.enum_view_mode.list,
|
||||
"label": lib_plankton.translate.get("page.overview.mode.list"),
|
||||
},
|
||||
],
|
||||
{
|
||||
"initial_selection": view_mode,
|
||||
"action_change": (view_mode) => {
|
||||
lib_plankton.zoo_page.set(
|
||||
{
|
||||
"name": "overview",
|
||||
"parameters": {
|
||||
"mode": _dali.view_mode_encode(view_mode),
|
||||
}
|
||||
"calendar_ids": calendar_ids,
|
||||
}
|
||||
);
|
||||
set_view_mode(view_mode);
|
||||
}
|
||||
}
|
||||
);
|
||||
set_view_mode(view_mode);
|
||||
await widget_mode_switcher.load(target_element.querySelector("#overview-mode"));
|
||||
/**
|
||||
* @todo filter
|
||||
*/
|
||||
return _dali.model.event_list();
|
||||
}
|
||||
|
||||
// sources
|
||||
|
||||
/**
|
||||
*/
|
||||
private async update_sources_and_entries(
|
||||
{
|
||||
widget_sources = new _dali.widgets.sources.class_widget_sources(
|
||||
"priviliged": priviliged = null,
|
||||
}
|
||||
:
|
||||
{
|
||||
priviliged ?: (null | boolean);
|
||||
}
|
||||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
await this.widget_sources.update({"priviliged": priviliged});
|
||||
await this.widget_multiview.update_entries();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @todo use priviliged?
|
||||
*/
|
||||
private async update_entries(
|
||||
{
|
||||
"priviliged": priviliged = null,
|
||||
}
|
||||
:
|
||||
{
|
||||
priviliged ?: (null | boolean);
|
||||
}
|
||||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
await this.widget_multiview.update_entries();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
public async load(
|
||||
target_element : HTMLElement
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
const view_mode : _dali.enum_view_mode = _dali.helpers.view_mode_determine("auto");
|
||||
const view_kind : _dali.enum_view_kind = _dali.helpers.view_kind_determine("auto");
|
||||
|
||||
this.widget_sources = (
|
||||
new _dali.widgets.class_widget_sources(
|
||||
_dali.model.calendar_list,
|
||||
{
|
||||
"initial_priviliged": _dali.is_logged_in(),
|
||||
"action_add": action_create_calendar,
|
||||
"action_select": (entry) => action_edit_calendar(entry),
|
||||
"action_add": this.action_create_calendar,
|
||||
"action_select": this.action_edit_calendar,
|
||||
"action_toggle": (entry, mode) => {
|
||||
widget_weekview.toggle_visibility(entry.id, {"mode": mode});
|
||||
widget_listview.toggle_visibility(entry.id, {"mode": mode});
|
||||
this.widget_multiview.toggle_calendar_visibilty(entry.id, {"mode": mode});
|
||||
},
|
||||
}
|
||||
)
|
||||
);
|
||||
await widget_sources.load(target_element.querySelector("#overview-pane-left"));
|
||||
}
|
||||
|
||||
// weekview
|
||||
this.widget_multiview = (
|
||||
new _dali.widgets.class_widget_multiview(
|
||||
this.get_entries,
|
||||
{
|
||||
widget_weekview = (
|
||||
new _dali.widgets.weekview.class_widget_weekview(
|
||||
get_entries,
|
||||
{
|
||||
"action_select_event": (event_key) => action_edit_event(event_key),
|
||||
"action_select_day": (date) => action_create_event({"date": date}),
|
||||
"initial_view_mode": view_mode,
|
||||
"weekview_initial_vertical": (view_kind === _dali.enum_view_kind.touch),
|
||||
"action_create_event": this.action_create_event,
|
||||
"action_edit_event": this.action_edit_event,
|
||||
}
|
||||
)
|
||||
);
|
||||
await widget_weekview.load(target_element.querySelector("#overview-pane-right-weekview"));
|
||||
}
|
||||
|
||||
// listview
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"widget-overview",
|
||||
"main",
|
||||
{
|
||||
widget_listview = (
|
||||
new _dali.widgets.listview.class_widget_listview(
|
||||
get_entries,
|
||||
{
|
||||
"action_select": (event_key) => action_edit_event(event_key),
|
||||
"action_add": () => action_create_event(),
|
||||
}
|
||||
)
|
||||
);
|
||||
await widget_listview.load(target_element.querySelector("#overview-pane-right-listview"));
|
||||
|
||||
// head
|
||||
{
|
||||
// hint
|
||||
{
|
||||
const dom_hint = target_element.querySelector(".widget-overview-hint");
|
||||
dom_hint.textContent = lib_plankton.translate.get("widget.overview.login_hint");
|
||||
dom_hint.classList.toggle("widget-overview-hint-hidden", _dali.is_logged_in());
|
||||
}
|
||||
}
|
||||
// body
|
||||
{
|
||||
let widget_slider : lib_plankton.zoo_widget.interface_widget;
|
||||
switch (view_kind)
|
||||
{
|
||||
case _dali.enum_view_kind.regular:
|
||||
{
|
||||
widget_slider = new lib_plankton.zoo_widget.class_slider(
|
||||
[
|
||||
new lib_plankton.zoo_widget.class_bunch(
|
||||
[
|
||||
this.widget_sources,
|
||||
this.widget_multiview,
|
||||
]
|
||||
),
|
||||
],
|
||||
{
|
||||
"threshold": 100,
|
||||
"initial_index": 1,
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
case _dali.enum_view_kind.touch:
|
||||
{
|
||||
widget_slider = new lib_plankton.zoo_widget.class_slider(
|
||||
[
|
||||
this.widget_sources,
|
||||
this.widget_multiview,
|
||||
],
|
||||
{
|
||||
"threshold": 100,
|
||||
"initial_index": 2,
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
await widget_slider.load(target_element.querySelector(".widget-overview-body"));
|
||||
}
|
||||
|
||||
_dali.model.listen_reset(
|
||||
async (priviliged) => {
|
||||
update_sources_and_entries({"priviliged": priviliged});
|
||||
target_element.querySelector("#overview-hint").classList.toggle("overview-hint-hidden", priviliged);
|
||||
this.update_sources_and_entries({"priviliged": priviliged});
|
||||
target_element.querySelector(".widget-overview-hint").classList.toggle("widget-overview-hint-hidden", priviliged);
|
||||
}
|
||||
);
|
||||
|
||||
return Promise.resolve<void>(undefined);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
59
source/widgets/overview/style.css
Normal file
59
source/widgets/overview/style.css
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
.widget-overview-head
|
||||
{
|
||||
padding-bottom: 12px;
|
||||
margin-bottom: 12px;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.widget-overview-hint
|
||||
{
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.widget-overview-hint.widget-overview-hint-hidden
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.widget-overview-body
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.widget-overview-pane-left
|
||||
{
|
||||
flex-basis: 12.5%;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.widget-overview-pane-right
|
||||
{
|
||||
flex-basis: 87.5%;
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.widget-overview-body .widget-slider-slide .widget-bunch
|
||||
{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.widget-overview-body .widget-slider-slide .widget-bunch-element:nth-child(1)
|
||||
{
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 12.5%;
|
||||
}
|
||||
|
||||
.widget-overview-body .widget-slider-slide .widget-bunch-element:nth-child(2)
|
||||
{
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-basis: 87.5%;
|
||||
}
|
||||
8
source/widgets/overview/templates/main.html.tpl
Normal file
8
source/widgets/overview/templates/main.html.tpl
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<div class="widget-overview">
|
||||
<div class="widget-overview-head">
|
||||
<div class="widget-overview-hint">
|
||||
</div>
|
||||
</div>
|
||||
<div class="widget-overview-body">
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,4 +1,24 @@
|
|||
namespace _dali.widgets.sources
|
||||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
|
|||
167
source/widgets/special_number_input/logic.ts
Normal file
167
source/widgets/special_number_input/logic.ts
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
export class class_widget_special_number_input
|
||||
implements lib_plankton.zoo_widget.interface_widget
|
||||
{
|
||||
|
||||
/**
|
||||
*/
|
||||
private action_change : ((int) => Promise<void>);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private label : (null | string);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private minimum : (null | int);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private maximum : (null | int);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private value : int;
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
public constructor(
|
||||
{
|
||||
"label": label = null,
|
||||
"minimum": minimum = null,
|
||||
"maximum": maximum = null,
|
||||
"initial_value": initial_value = 0,
|
||||
"action_change": action_change = ((value) => Promise.resolve<void>(undefined)),
|
||||
}
|
||||
:
|
||||
{
|
||||
label ?: (null | string);
|
||||
minimum ?: (null | int);
|
||||
maximum ?: (null | int);
|
||||
initial_value ?: int;
|
||||
action_change ?: ((int) => Promise<void>);
|
||||
}
|
||||
=
|
||||
{
|
||||
}
|
||||
)
|
||||
{
|
||||
this.label = label;
|
||||
this.minimum = minimum;
|
||||
this.maximum = maximum;
|
||||
this.value = initial_value;
|
||||
this.action_change = action_change;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* [implementation]
|
||||
*/
|
||||
public async load(
|
||||
target_element : HTMLElement
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
const dom_root = await _dali.helpers.element_from_template(
|
||||
"widget-special_number_input",
|
||||
"main",
|
||||
{
|
||||
"label": this.label,
|
||||
}
|
||||
);
|
||||
|
||||
const dom_input : HTMLInputElement = (dom_root.querySelector(".widget-special_number_input-input") as HTMLInputElement);
|
||||
|
||||
// listeners
|
||||
{
|
||||
dom_input.addEventListener(
|
||||
"change",
|
||||
() => {
|
||||
const value : int = parseInt(dom_input.value);
|
||||
if (
|
||||
((this.minimum === null) || (value >= this.minimum))
|
||||
&&
|
||||
((this.maximum === null) || (value <= this.maximum))
|
||||
)
|
||||
{
|
||||
this.value = value;
|
||||
this.action_change(this.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
);
|
||||
dom_root.querySelector(".widget-special_number_input-prev").addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
if ((this.minimum === null) || (this.value > this.minimum))
|
||||
{
|
||||
this.value -= 1;
|
||||
dom_input.value = this.value.toFixed(0);
|
||||
this.action_change(this.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
);
|
||||
dom_root.querySelector(".widget-special_number_input-next").addEventListener(
|
||||
"click",
|
||||
() => {
|
||||
if ((this.maximum === null) || (this.value < this.maximum))
|
||||
{
|
||||
this.value += 1;
|
||||
dom_input.value = this.value.toFixed(0);
|
||||
this.action_change(this.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// content
|
||||
{
|
||||
dom_input.value = this.value.toFixed(0);
|
||||
}
|
||||
|
||||
target_element.appendChild(dom_root);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
34
source/widgets/special_number_input/style.css
Normal file
34
source/widgets/special_number_input/style.css
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
.widget-special_number_input-controls
|
||||
{
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.widget-special_number_input-controls > *
|
||||
{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.widget-special_number_input-button
|
||||
{
|
||||
padding: 4px 4px;
|
||||
margin: 0;
|
||||
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.widget-special_number_input-label
|
||||
{
|
||||
display: block;
|
||||
|
||||
font-size: 0.75em;
|
||||
/*
|
||||
text-transform: uppercase;
|
||||
*/
|
||||
}
|
||||
|
||||
.widget-special_number_input-input
|
||||
{
|
||||
max-width: 40px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<div class="widget-special_number_input">
|
||||
<label class="widget-special_number_input-label">{{label}}</label>
|
||||
<div class="widget-special_number_input-controls">
|
||||
<div class="widget-special_number_input-button widget-special_number_input-prev">◂</div>
|
||||
<input type="text" class="widget-special_number_input-input" pattern="-?[0-9]+"/>
|
||||
<div class="widget-special_number_input-button widget-special_number_input-next">▸</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,4 +1,24 @@
|
|||
namespace _dali.widgets.weekview
|
||||
/*
|
||||
This file is part of »dali«.
|
||||
|
||||
Copyright 2025 'kcf' <fenris@folksprak.org>
|
||||
|
||||
»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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
namespace _dali.widgets
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
@ -16,7 +36,8 @@ namespace _dali.widgets.weekview
|
|||
|
||||
/**
|
||||
*/
|
||||
export class class_widget_weekview implements lib_plankton.zoo_widget.interface_widget
|
||||
export class class_widget_weekview
|
||||
implements lib_plankton.zoo_widget.interface_widget
|
||||
{
|
||||
|
||||
/**
|
||||
|
|
@ -101,7 +122,7 @@ namespace _dali.widgets.weekview
|
|||
"vertical": vertical = false,
|
||||
"initial_year": initial_year = null,
|
||||
"initial_week": initial_week = null,
|
||||
"initial_count": initial_count = 4,
|
||||
"initial_count": initial_count = 5,
|
||||
}
|
||||
:
|
||||
{
|
||||
|
|
@ -171,7 +192,8 @@ namespace _dali.widgets.weekview
|
|||
*/
|
||||
private static entry_hash(
|
||||
entry : _dali.type_event_object_extended
|
||||
) : string
|
||||
)
|
||||
: string
|
||||
{
|
||||
return lib_plankton.call.convey(
|
||||
{
|
||||
|
|
@ -193,7 +215,8 @@ namespace _dali.widgets.weekview
|
|||
private static event_generate_tooltip(
|
||||
calendar_name : string,
|
||||
event_object : _dali.type_event_object
|
||||
) : string
|
||||
)
|
||||
: string
|
||||
{
|
||||
return (
|
||||
lib_plankton.string.coin(
|
||||
|
|
@ -339,7 +362,8 @@ namespace _dali.widgets.weekview
|
|||
*/
|
||||
private async entry_insert(
|
||||
entry : _dali.type_event_object_extended
|
||||
) : Promise<(null | HTMLElement)>
|
||||
)
|
||||
: Promise<(null | HTMLElement)>
|
||||
{
|
||||
const selector : string = lib_plankton.string.coin(
|
||||
".weekview-cell[rel=\"{{rel}}\"] > .weekview-events",
|
||||
|
|
@ -360,19 +384,11 @@ namespace _dali.widgets.weekview
|
|||
}
|
||||
else
|
||||
{
|
||||
let dom_dummy : HTMLElement = document.createElement("div");
|
||||
dom_dummy.innerHTML = await _dali.helpers.template_coin(
|
||||
const dom_entry = await _dali.helpers.element_from_template(
|
||||
"widget-weekview",
|
||||
"tableview-cell-entry",
|
||||
{
|
||||
"color": _dali.helpers.event_color(entry.hue),
|
||||
/*
|
||||
"title": class_widget_weekview.event_generate_tooltip(
|
||||
entry.calendar_name,
|
||||
entry.event_object
|
||||
),
|
||||
*/
|
||||
"title": "",
|
||||
"name": entry.event_object.name,
|
||||
"rel": entry.key,
|
||||
"additional_classes": lib_plankton.string.coin(
|
||||
|
|
@ -383,7 +399,6 @@ namespace _dali.widgets.weekview
|
|||
),
|
||||
}
|
||||
);
|
||||
const dom_entry : HTMLElement = dom_dummy.querySelector(".weekview-event_entry");
|
||||
|
||||
// listener
|
||||
dom_entry.addEventListener(
|
||||
|
|
@ -409,7 +424,8 @@ namespace _dali.widgets.weekview
|
|||
*/
|
||||
private async entry_add(
|
||||
entry : _dali.type_event_object_extended
|
||||
) : Promise<void>
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
const dom_entry : (null | HTMLElement) = await this.entry_insert(entry);
|
||||
if (dom_entry === null)
|
||||
|
|
@ -434,7 +450,8 @@ namespace _dali.widgets.weekview
|
|||
private async entry_update(
|
||||
key : _dali.type_event_key,
|
||||
entry : _dali.type_event_object_extended
|
||||
) : Promise<void>
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
if (! this.event_map.has(key))
|
||||
{
|
||||
|
|
@ -490,7 +507,8 @@ namespace _dali.widgets.weekview
|
|||
*/
|
||||
private async entry_remove(
|
||||
key : _dali.type_event_key
|
||||
) : Promise<void>
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
if (! this.event_map.has(key))
|
||||
{
|
||||
|
|
@ -519,7 +537,8 @@ namespace _dali.widgets.weekview
|
|||
/**
|
||||
*/
|
||||
public async update_entries(
|
||||
) : Promise<void>
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
const entries : Array<_dali.type_event_object_extended> = await this.get_entries_wrapped(
|
||||
);
|
||||
|
|
@ -557,23 +576,11 @@ namespace _dali.widgets.weekview
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private async update_controls(
|
||||
) : Promise<void>
|
||||
{
|
||||
const context : Element = this.container;
|
||||
(context.querySelector(".weekview-control-year input") as HTMLInputElement).value = this.year.toFixed(0);
|
||||
(context.querySelector(".weekview-control-week input") as HTMLInputElement).value = this.week.toFixed(0);
|
||||
(context.querySelector(".weekview-control-count input") as HTMLInputElement).value = this.count.toFixed(0);
|
||||
(context.querySelector(".weekview-control-vertical input") as HTMLInputElement).checked = this.vertical;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
private async update_table(
|
||||
) : Promise<void>
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
/**
|
||||
* @todo avoid?
|
||||
|
|
@ -743,6 +750,8 @@ namespace _dali.widgets.weekview
|
|||
today_begin_pit,
|
||||
today_end_pit
|
||||
);
|
||||
const day_as_date : lib_plankton.pit.type_date = lib_plankton.pit.to_datetime_ce(day_pit).date;
|
||||
const day_as_ywd : lib_plankton.pit.type_ywd = lib_plankton.pit.to_ywd(day_pit);
|
||||
return _dali.helpers.template_coin(
|
||||
"widget-weekview",
|
||||
"tableview-cell",
|
||||
|
|
@ -752,48 +761,23 @@ namespace _dali.widgets.weekview
|
|||
.concat(is_today ? ["weekview-cell-today"] : [])
|
||||
.join(" ")
|
||||
),
|
||||
"title": lib_plankton.call.convey(
|
||||
day_pit,
|
||||
[
|
||||
lib_plankton.pit.to_datetime_ce,
|
||||
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
|
||||
"day": (
|
||||
_dali.conf.get().misc.weekview_cell_day_format
|
||||
.replace(new RegExp("Y", "g"), day_as_date.year.toFixed(0).padStart(4, "0"))
|
||||
.replace(new RegExp("m", "g"), day_as_date.month.toFixed(0).padStart(2, "0"))
|
||||
.replace(new RegExp("b", "g"), _dali.helpers.month_name(day_as_date.month))
|
||||
.replace(new RegExp("d", "g"), day_as_date.day.toFixed(0).padStart(2, "0"))
|
||||
.replace(new RegExp("W", "g"), day_as_ywd.week.toFixed(0).padStart(2, "0"))
|
||||
.replace(new RegExp("w", "g"), day_as_ywd.day.toFixed(0).padStart(1, "0"))
|
||||
),
|
||||
"rel": 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"),
|
||||
"year": day_as_date.year.toFixed(0).padStart(4, "0"),
|
||||
"month": day_as_date.month.toFixed(0).padStart(2, "0"),
|
||||
"day": day_as_date.day.toFixed(0).padStart(2, "0"),
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
"day": lib_plankton.call.convey(
|
||||
day_pit,
|
||||
[
|
||||
lib_plankton.pit.to_datetime_ce,
|
||||
(x : lib_plankton.pit.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"),
|
||||
}
|
||||
),
|
||||
]
|
||||
),
|
||||
"rel": lib_plankton.call.convey(
|
||||
day_pit,
|
||||
[
|
||||
lib_plankton.pit.to_datetime_ce,
|
||||
(x : lib_plankton.pit.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"),
|
||||
}
|
||||
)
|
||||
]
|
||||
),
|
||||
"entries": ""
|
||||
}
|
||||
);
|
||||
|
|
@ -815,7 +799,11 @@ namespace _dali.widgets.weekview
|
|||
element.addEventListener(
|
||||
"click",
|
||||
(event) => {
|
||||
if (! (element === event.target))
|
||||
if (
|
||||
(! (element === event.target))
|
||||
&&
|
||||
(! (event.target as HTMLElement).classList.contains("weekview-day"))
|
||||
)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
|
@ -852,7 +840,8 @@ namespace _dali.widgets.weekview
|
|||
=
|
||||
{
|
||||
}
|
||||
) : void
|
||||
)
|
||||
: void
|
||||
{
|
||||
this.container.querySelectorAll(".weekview-event_entry").forEach(
|
||||
(element) => {
|
||||
|
|
@ -880,175 +869,97 @@ namespace _dali.widgets.weekview
|
|||
*/
|
||||
public async load(
|
||||
target_element : Element
|
||||
) : Promise<void>
|
||||
)
|
||||
: Promise<void>
|
||||
{
|
||||
target_element.innerHTML = await _dali.helpers.template_coin(
|
||||
"widget-weekview",
|
||||
"main",
|
||||
{
|
||||
"label_control_year": lib_plankton.translate.get("widget.weekview.controls.year"),
|
||||
"label_control_week": lib_plankton.translate.get("widget.weekview.controls.week"),
|
||||
"label_control_count": lib_plankton.translate.get("widget.weekview.controls.count"),
|
||||
"label_control_vertical": lib_plankton.translate.get("widget.weekview.controls.vertical"),
|
||||
"label_control_apply": lib_plankton.translate.get("widget.weekview.controls.apply"),
|
||||
}
|
||||
);
|
||||
this.container = target_element.querySelector(".weekview");
|
||||
// controls
|
||||
// control:year
|
||||
{
|
||||
// direct inputs
|
||||
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_special_number_input(
|
||||
{
|
||||
[
|
||||
{
|
||||
"name": "year",
|
||||
"selector": ".weekview-control-year input",
|
||||
"retrieve": element => parseInt(element.value),
|
||||
"write": x => {this.year = x;}
|
||||
"label": lib_plankton.translate.get("widget.weekview.controls.year"),
|
||||
"minimum": 1900,
|
||||
"maximum": 2500,
|
||||
"initial_value": this.year,
|
||||
"action_change": async (value) => {
|
||||
this.year = value;
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
},
|
||||
}
|
||||
);
|
||||
await widget.load(target_element.querySelector(".weekview-controls"));
|
||||
}
|
||||
// control:week
|
||||
{
|
||||
"name": "week",
|
||||
"selector": ".weekview-control-week input",
|
||||
"retrieve": element => parseInt(element.value),
|
||||
"write": x => {this.week = x;}
|
||||
},
|
||||
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_special_number_input(
|
||||
{
|
||||
"name": "count",
|
||||
"selector": ".weekview-control-count input",
|
||||
"retrieve": element => parseInt(element.value),
|
||||
"write": x => {this.count = x;}
|
||||
"label": lib_plankton.translate.get("widget.weekview.controls.week"),
|
||||
"minimum": 1,
|
||||
/**
|
||||
* @todo correct
|
||||
*/
|
||||
"maximum": 53,
|
||||
"initial_value": this.week,
|
||||
"action_change": async (value) => {
|
||||
this.week = value;
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
},
|
||||
}
|
||||
);
|
||||
await widget.load(target_element.querySelector(".weekview-controls"));
|
||||
}
|
||||
// control:count
|
||||
/*
|
||||
{
|
||||
"name": "vertical",
|
||||
"selector": ".weekview-control-vertical input",
|
||||
"retrieve": element => element.checked,
|
||||
"write": x => {this.vertical = x;}
|
||||
const widget : lib_plankton.zoo_widget.interface_widget = new _dali.widgets.class_widget_special_number_input(
|
||||
{
|
||||
"label": lib_plankton.translate.get("widget.weekview.controls.count"),
|
||||
"minimum": 2,
|
||||
"maximum": 6,
|
||||
"initial_value": this.count,
|
||||
"action_change": async (value) => {
|
||||
this.count = value;
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
},
|
||||
].forEach(
|
||||
(entry) => {
|
||||
const element : HTMLInputElement = (target_element.querySelector(entry.selector) as HTMLInputElement);
|
||||
element.addEventListener(
|
||||
}
|
||||
);
|
||||
await widget.load(target_element.querySelector(".weekview-controls"));
|
||||
}
|
||||
*/
|
||||
// control:vertical
|
||||
{
|
||||
const dom_control = await _dali.helpers.element_from_template(
|
||||
"widget-weekview",
|
||||
"control-vertical",
|
||||
{
|
||||
"label": lib_plankton.translate.get("widget.weekview.controls.vertical"),
|
||||
}
|
||||
);
|
||||
const dom_input : HTMLInputElement = (dom_control.querySelector("input") as HTMLInputElement);
|
||||
dom_input.addEventListener(
|
||||
"change",
|
||||
async (event) => {
|
||||
async () => {
|
||||
event.preventDefault();
|
||||
const value : unknown = entry.retrieve(element);
|
||||
entry.write(value);
|
||||
const value : boolean = dom_input.checked;
|
||||
this.vertical = value;
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
}
|
||||
);
|
||||
dom_input.checked = this.vertical;
|
||||
target_element.querySelector(".weekview-controls").appendChild(dom_control);
|
||||
}
|
||||
);
|
||||
}
|
||||
// buttons
|
||||
{
|
||||
// year
|
||||
{
|
||||
/**
|
||||
* @todo limit
|
||||
*/
|
||||
target_element.querySelector(".weekview-control-year-prev").addEventListener(
|
||||
"click",
|
||||
async () => {
|
||||
this.year -= 1;
|
||||
await this.update_controls();
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
}
|
||||
);
|
||||
/**
|
||||
* @todo limit
|
||||
*/
|
||||
target_element.querySelector(".weekview-control-year-next").addEventListener(
|
||||
"click",
|
||||
async () => {
|
||||
this.year += 1;
|
||||
await this.update_controls();
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
}
|
||||
);
|
||||
}
|
||||
// week
|
||||
{
|
||||
target_element.querySelector(".weekview-control-week-prev").addEventListener(
|
||||
"click",
|
||||
async () => {
|
||||
if (this.week >= 1)
|
||||
{
|
||||
this.week -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.year -= 1;
|
||||
/**
|
||||
* @todo get correct week
|
||||
*/
|
||||
this.week = 51;
|
||||
}
|
||||
await this.update_controls();
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
}
|
||||
);
|
||||
target_element.querySelector(".weekview-control-week-next").addEventListener(
|
||||
"click",
|
||||
async () => {
|
||||
/**
|
||||
* @todo correct limit
|
||||
*/
|
||||
if (this.week <= 51)
|
||||
{
|
||||
this.week += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.year += 1;
|
||||
this.week = 1;
|
||||
}
|
||||
await this.update_controls();
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
}
|
||||
);
|
||||
}
|
||||
// count
|
||||
{
|
||||
target_element.querySelector(".weekview-control-count-prev").addEventListener(
|
||||
"click",
|
||||
async () => {
|
||||
if (this.count >= 2)
|
||||
{
|
||||
this.count -= 1;
|
||||
await this.update_controls();
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
);
|
||||
target_element.querySelector(".weekview-control-count-next").addEventListener(
|
||||
"click",
|
||||
async () => {
|
||||
if (this.count <= 6)
|
||||
{
|
||||
this.count += 1;
|
||||
await this.update_controls();
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
}
|
||||
else
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.update_controls();
|
||||
|
||||
this.container = target_element.querySelector(".weekview");
|
||||
|
||||
await this.update_table();
|
||||
await this.update_entries();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: right;
|
||||
|
||||
margin-bottom: 12px;
|
||||
|
|
@ -10,14 +10,13 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.weekview-control
|
||||
.weekview-controls > *
|
||||
{
|
||||
flex-basis: 0;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
|
||||
min-width: 140px;
|
||||
margin: 0 12px;
|
||||
margin: 0 0 0 16px;
|
||||
}
|
||||
|
||||
.weekview-control-label
|
||||
|
|
@ -30,16 +29,6 @@
|
|||
*/
|
||||
}
|
||||
|
||||
.weekview-control-input > *
|
||||
{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.weekview-control input
|
||||
{
|
||||
max-width: 40px;
|
||||
}
|
||||
|
||||
.weekview-table table
|
||||
{
|
||||
width: 100%;
|
||||
|
|
@ -87,7 +76,6 @@
|
|||
.weekview-day
|
||||
{
|
||||
font-size: 0.75em;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.weekview-events
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<div class="weekview-control weekview-control-vertical">
|
||||
<label class="weekview-control-label">{{label}}</label>
|
||||
<div class="weekview-control-input">
|
||||
<input type="checkbox"/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1,35 +1,5 @@
|
|||
<div class="weekview">
|
||||
<div class="weekview-controls">
|
||||
<div class="weekview-control weekview-control-year">
|
||||
<label class="weekview-control-label">{{label_control_year}}</label>
|
||||
<div class="weekview-control-input">
|
||||
<button class="weekview-control-year-prev">◂</button>
|
||||
<input type="text"/>
|
||||
<button class="weekview-control-year-next">▸</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="weekview-control weekview-control-week">
|
||||
<label class="weekview-control-label">{{label_control_week}}</label>
|
||||
<div class="weekview-control-input">
|
||||
<button class="weekview-control-week-prev">◂</button>
|
||||
<input type="text"/>
|
||||
<button class="weekview-control-week-next">▸</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="weekview-control weekview-control-count">
|
||||
<label class="weekview-control-label">{{label_control_count}}</label>
|
||||
<div class="weekview-control-input">
|
||||
<button class="weekview-control-count-prev">◂</button>
|
||||
<input type="text"/>
|
||||
<button class="weekview-control-count-next">▸</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="weekview-control weekview-control-vertical">
|
||||
<label class="weekview-control-label">{{label_control_vertical}}</label>
|
||||
<div class="weekview-control-input">
|
||||
<input type="checkbox"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="weekview-table">
|
||||
<table>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
<li class="weekview-event_entry{{additional_classes}}" style="background-color: {{color}};" title="{{title}}" rel="{{rel}}">
|
||||
<li class="weekview-event_entry{{additional_classes}}" style="background-color: {{color}};" rel="{{rel}}">
|
||||
{{name}}
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<td class="weekview-cell weekview-cell-regular{{extra_classes}}" rel="{{rel}}">
|
||||
<span class="weekview-day" title="{{title}}">
|
||||
<span class="weekview-day">
|
||||
{{day}}
|
||||
</span>
|
||||
<ul class="weekview-events">
|
||||
|
|
|
|||
|
|
@ -30,20 +30,38 @@ ${dir_build}/index.html: \
|
|||
|
||||
.PHONY: templates
|
||||
templates: \
|
||||
templates-widgets-login \
|
||||
templates-widgets-special_number_input \
|
||||
templates-widgets-login_oidc \
|
||||
templates-widgets-menu \
|
||||
templates-widgets-sources \
|
||||
templates-widgets-calendar_edit \
|
||||
templates-widgets-event_edit \
|
||||
templates-widgets-caldav \
|
||||
templates-widgets-listview \
|
||||
templates-widgets-weekview \
|
||||
templates-widgets-mode_switcher \
|
||||
templates-pages-caldav \
|
||||
templates-pages-overview
|
||||
templates-widgets-overview \
|
||||
templates-widgets-mode_switcher
|
||||
|
||||
.PHONY: templates-widgets-login
|
||||
templates-widgets-login: \
|
||||
$(wildcard ${dir_source}/widgets/login/templates/*)
|
||||
@ ${cmd_log} "templates:widget:login …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/widget-login
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/login/templates/* ${dir_build}/templates/widget-login/
|
||||
.PHONY: templates-widgets-special_number_input
|
||||
templates-widgets-special_number_input: \
|
||||
$(wildcard ${dir_source}/widgets/special_number_input/templates/*)
|
||||
@ ${cmd_log} "templates:widget:special_number_input …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/widget-special_number_input
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/special_number_input/templates/* ${dir_build}/templates/widget-special_number_input/
|
||||
|
||||
.PHONY: templates-widgets-login_oidc
|
||||
templates-widgets-login_oidc: \
|
||||
$(wildcard ${dir_source}/widgets/login_oidc/templates/*)
|
||||
@ ${cmd_log} "templates:widget:login_oidc …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/widget-login_oidc
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/login_oidc/templates/* ${dir_build}/templates/widget-login_oidc/
|
||||
|
||||
.PHONY: templates-widgets-menu
|
||||
templates-widgets-menu: \
|
||||
$(wildcard ${dir_source}/widgets/menu/templates/*)
|
||||
@ ${cmd_log} "templates:widget:menu …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/widget-menu
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/menu/templates/* ${dir_build}/templates/widget-menu/
|
||||
|
||||
.PHONY: templates-widgets-sources
|
||||
templates-widgets-sources: \
|
||||
|
|
@ -52,6 +70,27 @@ templates-widgets-sources: \
|
|||
@ ${cmd_mkdir} ${dir_build}/templates/widget-sources
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/sources/templates/* ${dir_build}/templates/widget-sources/
|
||||
|
||||
.PHONY: templates-widgets-calendar_edit
|
||||
templates-widgets-calendar_edit: \
|
||||
$(wildcard ${dir_source}/widgets/calendar_edit/templates/*)
|
||||
@ ${cmd_log} "templates:widget:calendar_edit …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/widget-calendar_edit
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/calendar_edit/templates/* ${dir_build}/templates/widget-calendar_edit/
|
||||
|
||||
.PHONY: templates-widgets-event_edit
|
||||
templates-widgets-event_edit: \
|
||||
$(wildcard ${dir_source}/widgets/event_edit/templates/*)
|
||||
@ ${cmd_log} "templates:widget:event_edit …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/widget-event_edit
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/event_edit/templates/* ${dir_build}/templates/widget-event_edit/
|
||||
|
||||
.PHONY: templates-widgets-caldav
|
||||
templates-widgets-caldav: \
|
||||
$(wildcard ${dir_source}/widgets/caldav/templates/*)
|
||||
@ ${cmd_log} "templates:widget:caldav …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/widget-caldav
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/caldav/templates/* ${dir_build}/templates/widget-caldav/
|
||||
|
||||
.PHONY: templates-widgets-listview
|
||||
templates-widgets-listview: \
|
||||
$(wildcard ${dir_source}/widgets/listview/templates/*)
|
||||
|
|
@ -66,6 +105,13 @@ templates-widgets-weekview: \
|
|||
@ ${cmd_mkdir} ${dir_build}/templates/widget-weekview
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/weekview/templates/* ${dir_build}/templates/widget-weekview/
|
||||
|
||||
.PHONY: templates-widgets-overview
|
||||
templates-widgets-overview: \
|
||||
$(wildcard ${dir_source}/widgets/overview/templates/*)
|
||||
@ ${cmd_log} "templates:widget:overview …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/widget-overview
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/overview/templates/* ${dir_build}/templates/widget-overview/
|
||||
|
||||
.PHONY: templates-widgets-mode_switcher
|
||||
templates-widgets-mode_switcher: \
|
||||
$(wildcard ${dir_source}/widgets/mode_switcher/templates/*)
|
||||
|
|
@ -73,27 +119,12 @@ templates-widgets-mode_switcher: \
|
|||
@ ${cmd_mkdir} ${dir_build}/templates/widget-mode_switcher
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/mode_switcher/templates/* ${dir_build}/templates/widget-mode_switcher/
|
||||
|
||||
.PHONY: templates-pages-caldav
|
||||
templates-pages-caldav: \
|
||||
$(wildcard ${dir_source}/pages/caldav/templates/*)
|
||||
@ ${cmd_log} "templates:page:caldav …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/caldav
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/pages/caldav/templates/* ${dir_build}/templates/caldav/
|
||||
|
||||
.PHONY: templates-pages-overview
|
||||
templates-pages-overview: \
|
||||
$(wildcard ${dir_source}/pages/overview/templates/*)
|
||||
@ ${cmd_log} "templates:page:overview …"
|
||||
@ ${cmd_mkdir} ${dir_build}/templates/overview
|
||||
@ ${cmd_cp} -r -u -v ${dir_source}/pages/overview/templates/* ${dir_build}/templates/overview/
|
||||
|
||||
.PHONY: style
|
||||
style: ${dir_build}/style.css
|
||||
|
||||
${dir_build}/style.css: \
|
||||
$(wildcard ${dir_source}/style/*.css) \
|
||||
$(wildcard ${dir_source}/widgets/*/style.css) \
|
||||
$(wildcard ${dir_source}/pages/*/style.css)
|
||||
$(wildcard ${dir_source}/widgets/*/style.css)
|
||||
@ ${cmd_log} "style …"
|
||||
@ ${cmd_mkdir} ${dir_build}
|
||||
@ ${cmd_cat} $^ > $@
|
||||
|
|
@ -108,10 +139,9 @@ ${dir_temp}/logic-unlinked.js: \
|
|||
${dir_source}/base.ts \
|
||||
${dir_source}/types.ts \
|
||||
${dir_source}/model.ts \
|
||||
${dir_source}/helpers.ts \
|
||||
${dir_source}/overlay.ts \
|
||||
${dir_source}/helpers.ts \
|
||||
$(wildcard ${dir_source}/widgets/*/logic.ts) \
|
||||
$(wildcard ${dir_source}/pages/*/logic.ts) \
|
||||
${dir_source}/main.ts
|
||||
@ ${cmd_log} "logic | compile …"
|
||||
@ ${cmd_mkdir} $(dir $@)
|
||||
|
|
|
|||
Loading…
Reference in a new issue