Compare commits

..

No commits in common. "bb33ff66b32b207a376df2a570deaa3e525e10b8" and "b383460f3b23077a50ee113e152fc5dd544f8251" have entirely different histories.

22 changed files with 243 additions and 861 deletions

View file

@ -4194,49 +4194,6 @@ declare namespace lib_plankton.zoo_widget {
load(target_element: HTMLElement): Promise<void>; 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 { declare namespace lib_plankton.zoo_page {
/** /**
*/ */

View file

@ -12754,230 +12754,6 @@ var lib_plankton;
})(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {})); })(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {})); })(lib_plankton || (lib_plankton = {}));
/* /*
This file is part of »bacterio-plankton:zoo-widget«.
Copyright 2016-2025 'kcf' <fenris@folksprak.org>
»bacterio-plankton:zoo-widget« 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.
»bacterio-plankton:zoo-widget« 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 »bacterio-plankton:zoo-widget«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var zoo_widget;
(function (zoo_widget) {
/**
*/
class class_slider {
/**
*/
constructor(content, { "threshold": threshold = 200, "acceleration_function": acceleration_function = (x => (x * 3)), "initial_index": initial_index = 1, } = {}) {
this.conf = {
"content": content,
"threshold": threshold,
"acceleration_function": acceleration_function,
};
this.state = {
"dom_context": null,
"index": initial_index,
"touch_start_position": null,
};
}
/**
*/
static cap(minimum, maximum, value) {
let result = value;
if (minimum !== null) {
result = Math.max(minimum, result);
}
if (maximum !== null) {
result = Math.min(maximum, result);
}
return result;
}
/**
*/
static position_subtract(position1, position2) {
return {
"x": (position1.x - position2.x),
"y": (position1.y - position2.y),
};
}
/**
*/
static touch_event_position(touch_event) {
return ((touch_event.changedTouches.length <= 0)
?
null
:
{
"x": touch_event.changedTouches[0].pageX,
"y": touch_event.changedTouches[0].pageY,
});
}
/**
*/
set_translation(position) {
const difference = (((this.state.touch_start_position === null) || (position === null))
?
null
:
class_slider.position_subtract(position, this.state.touch_start_position));
this.state.dom_context.querySelector(".slides").style.transform = (([
lib_plankton.string.coin("translateX({{value}}%)", {
"value": ((this.state.index - 1) * (-100)).toFixed(0)
})
]
.concat((difference === null)
?
[]
:
[
//
lib_plankton.string.coin("translateX({{value}}px)", {
"value": class_slider.cap(((this.state.index >= this.conf.content.length)
?
(-this.conf.threshold)
:
null), ((this.state.index <= 1)
?
this.conf.threshold
:
null), this.conf.acceleration_function(difference.x)).toFixed(0),
})
]))
.join(" "));
}
/**
*/
start(position) {
if (position === null) {
// do nothing
}
else {
if (this.state.touch_start_position === null) {
this.state.touch_start_position = position;
}
else {
// do nothing
}
}
}
/**
*/
update(position) {
if (position === null) {
// do nothing
}
else {
if (this.state.touch_start_position === null) {
// do nothing
}
else {
this.set_translation(position);
}
}
}
/**
*/
finish(position) {
if (position === null) {
this.state.touch_start_position = null;
// do nothing
}
else {
if (this.state.touch_start_position === null) {
// do nothing
}
else {
const difference = class_slider.position_subtract(position, this.state.touch_start_position);
const offset = this.conf.acceleration_function(difference.x);
const index_increment = (() => {
if (offset <= -this.conf.threshold) {
return ((this.state.index >= this.conf.content.length) ? 0 : (+1));
}
else if ((offset > -this.conf.threshold) && (offset < this.conf.threshold)) {
return 0;
}
else if (offset >= this.conf.threshold) {
return ((this.state.index <= 1) ? 0 : (-1));
}
else {
// not possible
}
})();
this.state.index += index_increment;
this.set_translation(null);
this.state.touch_start_position = null;
}
}
}
/**
*/
async load(target_element) {
this.state.dom_context = target_element;
// structure
{
const dom_container = document.createElement("div");
{
dom_container.style.overflow = "hidden";
dom_container.style.whiteSpace = "nowrap";
}
{
const dom_content = document.createElement("div");
{
dom_content.style.height = "100%";
dom_content.style.width = "100%";
dom_content.style.transition = "transform 0.25s ease-in-out";
}
dom_content.classList.add("slides");
for (const slide of this.conf.content) {
const dom_slide = document.createElement("div");
dom_slide.classList.add("slide");
{
dom_slide.style.display = "inline-block";
dom_slide.style.height = "100%";
dom_slide.style.width = "100%";
dom_slide.style.transition = "width 0.25s ease-in-out";
}
await slide.load(dom_slide);
dom_content.appendChild(dom_slide);
}
dom_container.appendChild(dom_content);
}
this.state.dom_context.appendChild(dom_container);
}
// listeners
{
this.state.dom_context.addEventListener("touchstart", (event) => {
this.start(class_slider.touch_event_position(event));
});
this.state.dom_context.addEventListener("touchmove", (event) => {
this.update(class_slider.touch_event_position(event));
});
this.state.dom_context.addEventListener("touchend", (event) => {
this.finish(class_slider.touch_event_position(event));
});
this.state.dom_context.addEventListener("touchcancel", (event) => {
this.finish(null);
});
}
this.set_translation(null);
}
}
zoo_widget.class_slider = class_slider;
})(zoo_widget = lib_plankton.zoo_widget || (lib_plankton.zoo_widget = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-page«. This file is part of »bacterio-plankton:zoo-page«.
Copyright 2016-2025 'kcf' <fenris@folksprak.org> Copyright 2016-2025 'kcf' <fenris@folksprak.org>

View file

@ -14,18 +14,6 @@
"common.weekday.friday": "Fr", "common.weekday.friday": "Fr",
"common.weekday.saturday": "Sa", "common.weekday.saturday": "Sa",
"common.weekday.sunday": "So", "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.open": "öffnen",
"common.edit": "bearbeiten", "common.edit": "bearbeiten",
"common.show": "zeigen", "common.show": "zeigen",

View file

@ -14,18 +14,6 @@
"common.weekday.friday": "Fri", "common.weekday.friday": "Fri",
"common.weekday.saturday": "Sat", "common.weekday.saturday": "Sat",
"common.weekday.sunday": "Sun", "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.open": "open",
"common.edit": "edit", "common.edit": "edit",
"common.show": "show", "common.show": "show",

View file

@ -23,23 +23,6 @@ along with »dali«. If not, see <http://www.gnu.org/licenses/>.
namespace _dali.helpers 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> = {}; var _template_cache : Record<string, string> = {};
@ -49,13 +32,12 @@ namespace _dali.helpers
*/ */
export function view_mode_determine( export function view_mode_determine(
mode_descriptor : string mode_descriptor : string
) ) : _dali.enum_view_mode
: _dali.enum_view_mode
{ {
if (mode_descriptor === "auto") if (mode_descriptor === "auto")
{ {
return ( return (
(window.innerWidth >= 1000) (window.innerWidth >= 800)
? ?
_dali.enum_view_mode.week _dali.enum_view_mode.week
: :
@ -69,30 +51,6 @@ 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( export async function template_coin(
@ -325,29 +283,4 @@ 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]);
}
} }

View file

@ -40,6 +40,21 @@ namespace _dali
} }
/**
* @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();
}
/** /**
*/ */
@ -181,7 +196,16 @@ namespace _dali
} }
); );
} }
await update();
await _dali.overlay.initialize(); await _dali.overlay.initialize();
/*
lib_plankton.call.loop(
() => {
update();
},
_dali.conf.get().misc.update_interval
);
*/
// check if logged_in // check if logged_in
{ {

View file

@ -28,9 +28,33 @@ namespace _dali.pages.overview
async (parameters, target_element) => { async (parameters, target_element) => {
// params // params
const view_mode : _dali.enum_view_mode = _dali.helpers.view_mode_determine(parameters["mode"] ?? "auto"); const view_mode : _dali.enum_view_mode = _dali.helpers.view_mode_determine(parameters["mode"] ?? "auto");
const view_kind : _dali.enum_view_kind = _dali.helpers.view_kind_determine(parameters["kind"] ?? "auto");
// exec // 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( async function get_available_calendars(
@ -101,7 +125,7 @@ namespace _dali.pages.overview
: Promise<void> : Promise<void>
{ {
await widget_sources.update({"priviliged": priviliged}); await widget_sources.update({"priviliged": priviliged});
await widget_multiview.update_entries(); await widget_weekview.update_entries();
} }
/** /**
@ -122,7 +146,7 @@ namespace _dali.pages.overview
) )
: Promise<void> : Promise<void>
{ {
await widget_multiview.update_entries(); await widget_weekview.update_entries();
} }
/** /**
@ -477,70 +501,6 @@ namespace _dali.pages.overview
await widget.load(_dali.overlay.get_content_element()); await widget.load(_dali.overlay.get_content_element());
} }
const widget_sources : _dali.widgets.sources.class_widget_sources = (
new _dali.widgets.sources.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_toggle": (entry, mode) => {
widget_multiview.toggle_calendar_visibilty(entry.id, {"mode": mode});
},
}
)
);
const widget_multiview : _dali.widgets.multiview.class_widget_multiview = (
new _dali.widgets.multiview.class_widget_multiview(
get_entries,
{
"initial_view_mode": view_mode,
"action_create_event": action_create_event,
"action_edit_event": action_edit_event,
}
)
);
target_element.innerHTML = await _dali.helpers.template_coin(
"overview",
"main",
{
}
);
switch (view_kind)
{
case _dali.enum_view_kind.regular:
{
target_element.querySelector("#overview-body").innerHTML = await _dali.helpers.template_coin(
"overview",
"body-regular",
{
}
);
await widget_sources.load(target_element.querySelector("#overview-pane-left"));
await widget_multiview.load(target_element.querySelector("#overview-pane-right"));
break;
}
case _dali.enum_view_kind.touch:
{
const widget_slider = new lib_plankton.zoo_widget.class_slider(
[
widget_sources,
widget_multiview,
],
{
"threshold": 100,
"initial_index": 2,
}
)
await widget_slider.load(target_element.querySelector("#overview-body"));
break;
}
}
// hint // hint
{ {
const dom_hint = target_element.querySelector("#overview-hint"); const dom_hint = target_element.querySelector("#overview-hint");
@ -550,8 +510,79 @@ namespace _dali.pages.overview
// mode switcher // mode switcher
{ {
// set_view_mode(view_mode); widget_mode_switcher = new _dali.widgets.mode_switcher.class_widget_mode_switcher(
// await widget_mode_switcher.load(target_element.querySelector("#overview-mode")); [
{
"mode": _dali.enum_view_mode.week,
"label": lib_plankton.translate.get("page.overview.mode.week"),
},
{
"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),
}
}
);
set_view_mode(view_mode);
}
}
);
set_view_mode(view_mode);
await widget_mode_switcher.load(target_element.querySelector("#overview-mode"));
}
// sources
{
widget_sources = new _dali.widgets.sources.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_toggle": (entry, mode) => {
widget_weekview.toggle_visibility(entry.id, {"mode": mode});
widget_listview.toggle_visibility(entry.id, {"mode": mode});
},
}
);
await widget_sources.load(target_element.querySelector("#overview-pane-left"));
}
// weekview
{
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}),
}
)
);
await widget_weekview.load(target_element.querySelector("#overview-pane-right-weekview"));
}
// listview
{
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"));
} }
_dali.model.listen_reset( _dali.model.listen_reset(

View file

@ -34,3 +34,13 @@
flex-grow: 1; flex-grow: 1;
flex-shrink: 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 {}

View file

@ -1,4 +0,0 @@
<div id="overview-pane-left">
</div>
<div id="overview-pane-right">
</div>

View file

@ -0,0 +1,18 @@
<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>

View file

@ -1,8 +0,0 @@
<div id="overview">
<div id="overview-head">
<div id="overview-hint">
</div>
</div>
<div id="overview-body">
</div>
</div>

View file

@ -73,15 +73,14 @@ namespace _dali.conf
"default": "http://localhost:8888/#oidc_finish,session_key={{session_key}}" "default": "http://localhost:8888/#oidc_finish,session_key={{session_key}}"
}, },
"use_central_europe_specific_datetime_inputs": { "use_central_europe_specific_datetime_inputs": {
"nullable": false, "nullable": true,
"type": "boolean", "type": "boolean",
"default": false "default": false
}, },
"weekview_cell_day_format": { "update_interval": {
"nullable": false, "nullable": false,
"type": "string", "type": "integer",
"default": "d.b", "default": 60
"description": "available placeholders: Y,m,b,d,W,w (as in UNIX command 'date')"
}, },
}, },
"required": [ "required": [
@ -99,25 +98,7 @@ namespace _dali.conf
/** /**
*/ */
type type_data = { var _data : (null | any) = null;
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;
/** /**
@ -132,7 +113,7 @@ namespace _dali.conf
/** /**
*/ */
export function get( export function get(
) : type_data ) : any
{ {
if (_data === null) if (_data === null)
{ {
@ -150,7 +131,10 @@ namespace _dali.conf
path : string path : string
) : Promise<void> ) : Promise<void>
{ {
_data = ((await lib_plankton.conf.load(_schema, path)) as type_data); _data = await lib_plankton.conf.load(
_schema,
path
);
return Promise.resolve<void>(undefined); return Promise.resolve<void>(undefined);
} }

View file

@ -25,8 +25,7 @@ namespace _dali
/** /**
*/ */
export enum enum_access_level export enum enum_access_level {
{
none, none,
view, view,
edit, edit,
@ -203,12 +202,20 @@ namespace _dali
}; };
/**
*/
export enum enum_view_mode
{
week,
list,
}
/** /**
*/ */
export function access_level_encode( export function access_level_encode(
access_level : _dali.enum_access_level access_level : _dali.enum_access_level
) ) : ("none" | "view" | "edit" | "admin")
: ("none" | "view" | "edit" | "admin")
{ {
switch (access_level) switch (access_level)
{ {
@ -224,8 +231,7 @@ namespace _dali
*/ */
export function access_level_decode( export function access_level_decode(
representation : /*("none" | "view" | "edit" | "admin")*/string representation : /*("none" | "view" | "edit" | "admin")*/string
) ) : _dali.enum_access_level
: _dali.enum_access_level
{ {
switch (representation) switch (representation)
{ {
@ -238,21 +244,11 @@ namespace _dali
} }
/**
*/
export enum enum_view_mode
{
week,
list,
}
/** /**
*/ */
export function view_mode_encode( export function view_mode_encode(
mode : _dali.enum_view_mode mode : _dali.enum_view_mode
) ) : string
: string
{ {
switch (mode) switch (mode)
{ {
@ -267,8 +263,7 @@ namespace _dali
*/ */
export function view_mode_decode( export function view_mode_decode(
view_mode_encoded : string view_mode_encoded : string
) ) : _dali.enum_view_mode
: _dali.enum_view_mode
{ {
const map : Record<string, _dali.enum_view_mode> = { const map : Record<string, _dali.enum_view_mode> = {
"week": _dali.enum_view_mode.week, "week": _dali.enum_view_mode.week,
@ -284,51 +279,4 @@ 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];
}
}
} }

View file

@ -66,7 +66,7 @@ namespace _dali.widgets.menu
entry_data_list : Array<type_entry_data>, entry_data_list : Array<type_entry_data>,
{ {
"initial_groups": initial_groups = [], "initial_groups": initial_groups = [],
"initial_label": initial_label = "", "initial_label": initial_label = "=",
} }
: :
{ {
@ -115,10 +115,10 @@ namespace _dali.widgets.menu
: void : void
{ {
this.label = label; this.label = label;
this.container.querySelector(".widget-menu-button").innerHTML = ( this.container.querySelector(".widget-menu-button").textContent = (
(this.label === null) (this.label === null)
? ?
("[" + "=" + "]") "[=]"
: :
("[" + this.label + "]") ("[" + this.label + "]")
); );

View file

@ -47,24 +47,6 @@
list-style-type: none; list-style-type: none;
} }
.widget-menu-entry
{
margin: 12px 8px;
text-transform: capitalize;
background-color: hsl(var(--hue), 0%, 25%);
color: hsl(var(--hue), 0%, 100%);
border-bottom: 2px solid hsl(0, 0%, 25%);
}
.widget-menu-entry:hover
{
color: hsl(var(--hue), 0%, 100%);
border-bottom: 2px solid hsl(0, 0%, 100%);
transition: 1s ease color;
}
/*
.widget-menu-entry .widget-menu-entry
{ {
margin: 8px; margin: 8px;
@ -76,7 +58,15 @@
background-color: hsl(var(--hue), 0%, 25%); background-color: hsl(var(--hue), 0%, 25%);
color: hsl(var(--hue), 0%, 100%); color: hsl(var(--hue), 0%, 100%);
} }
.widget-menu-entry:hover::before
{
content: "» ";
/*
background-color: hsl(var(--hue), 0%, 50%);
color: hsl(var(--hue), 0%, 100%);
*/ */
}
.widget-menu-entry.widget-menu-entry-hidden .widget-menu-entry.widget-menu-entry-hidden
{ {

View file

@ -1,269 +0,0 @@
/*
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.multiview
{
/**
*/
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 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.mode_switcher.class_widget_mode_switcher;
/**
*/
private widget_weekview : _dali.widgets.weekview.class_widget_weekview;
/**
*/
private widget_listview : _dali.widgets.listview.class_widget_listview;
/**
*/
public constructor(
get_entries : type_get_entries,
{
"initial_view_mode": initial_view_mode = _dali.enum_view_mode.week,
"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;
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.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 update_entries(
)
:
Promise<void>
{
return this.widget_weekview.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.mode_switcher.class_widget_mode_switcher(
[
{
"mode": _dali.enum_view_mode.week,
"label": lib_plankton.translate.get("page.overview.mode.week"),
},
{
"mode": _dali.enum_view_mode.list,
"label": lib_plankton.translate.get("page.overview.mode.list"),
},
],
{
"initial_selection": this.initial_view_mode,
"action_change": (view_mode) => {
console.warn("todo");
/*
lib_plankton.zoo_page.set(
{
"name": "overview",
"parameters": {
"mode": _dali.view_mode_encode(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.weekview.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}),
}
)
);
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.listview.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);
}
}
}

View file

@ -1,10 +0,0 @@
.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 {}

View file

@ -121,7 +121,7 @@ namespace _dali.widgets.weekview
"vertical": vertical = false, "vertical": vertical = false,
"initial_year": initial_year = null, "initial_year": initial_year = null,
"initial_week": initial_week = null, "initial_week": initial_week = null,
"initial_count": initial_count = 5, "initial_count": initial_count = 4,
} }
: :
{ {
@ -386,6 +386,13 @@ namespace _dali.widgets.weekview
"tableview-cell-entry", "tableview-cell-entry",
{ {
"color": _dali.helpers.event_color(entry.hue), "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, "name": entry.event_object.name,
"rel": entry.key, "rel": entry.key,
"additional_classes": lib_plankton.string.coin( "additional_classes": lib_plankton.string.coin(
@ -756,8 +763,6 @@ namespace _dali.widgets.weekview
today_begin_pit, today_begin_pit,
today_end_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( return _dali.helpers.template_coin(
"widget-weekview", "widget-weekview",
"tableview-cell", "tableview-cell",
@ -767,23 +772,48 @@ namespace _dali.widgets.weekview
.concat(is_today ? ["weekview-cell-today"] : []) .concat(is_today ? ["weekview-cell-today"] : [])
.join(" ") .join(" ")
), ),
"day": ( "title": lib_plankton.call.convey(
_dali.conf.get().misc.weekview_cell_day_format day_pit,
.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")) lib_plankton.pit.to_datetime_ce,
.replace(new RegExp("b", "g"), _dali.helpers.month_name(day_as_date.month)) (x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
.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}}-{{month}}-{{day}}",
{ {
"year": day_as_date.year.toFixed(0).padStart(4, "0"), "year": x.date.year.toFixed(0).padStart(4, "0"),
"month": day_as_date.month.toFixed(0).padStart(2, "0"), "month": x.date.month.toFixed(0).padStart(2, "0"),
"day": day_as_date.day.toFixed(0).padStart(2, "0"), "day": x.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(
"{{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"),
}
),
]
),
"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": "" "entries": ""
} }
); );
@ -805,11 +835,7 @@ namespace _dali.widgets.weekview
element.addEventListener( element.addEventListener(
"click", "click",
(event) => { (event) => {
if ( if (! (element === event.target))
(! (element === event.target))
&&
(! (event.target as HTMLElement).classList.contains("weekview-day"))
)
{ {
// do nothing // do nothing
} }

View file

@ -87,6 +87,7 @@
.weekview-day .weekview-day
{ {
font-size: 0.75em; font-size: 0.75em;
cursor: help;
} }
.weekview-events .weekview-events

View file

@ -1,3 +1,3 @@
<li class="weekview-event_entry{{additional_classes}}" style="background-color: {{color}};" rel="{{rel}}"> <li class="weekview-event_entry{{additional_classes}}" style="background-color: {{color}};" title="{{title}}" rel="{{rel}}">
{{name}} {{name}}
</li> </li>

View file

@ -1,5 +1,5 @@
<td class="weekview-cell weekview-cell-regular{{extra_classes}}" rel="{{rel}}"> <td class="weekview-cell weekview-cell-regular{{extra_classes}}" rel="{{rel}}">
<span class="weekview-day"> <span class="weekview-day" title="{{title}}">
{{day}} {{day}}
</span> </span>
<ul class="weekview-events"> <ul class="weekview-events">