Compare commits

...
Sign in to create a new pull request.

16 commits

Author SHA1 Message Date
Fenris Wolf
530c0ce116 [mod] date formatting [mod] caldav resource integration 2024-11-01 13:35:49 +01:00
Fenris Wolf
431f1a1847 [mod] todo 2024-11-01 13:35:43 +01:00
Fenris Wolf
f4811a43bf [upd] plankton 2024-11-01 13:35:06 +01:00
Fenris Wolf
10e3862fc0 [mod] tools:default directories 2024-10-25 10:30:20 +02:00
Fenris Wolf
77f43372c9 [mod] overview:hide/show calendars 2024-10-21 23:18:08 +02:00
Fenris Wolf
ad322f7550 [mod] config switch for central europe datetime inputs 2024-10-21 23:17:53 +02:00
Fenris Wolf
5f6d72f67c [add] todo 2024-10-21 19:19:42 +02:00
Fenris Wolf
348f6da19c [mod] style 2024-10-21 19:19:33 +02:00
Fenris Wolf
6c92725d50 [upd] plankton 2024-10-21 19:19:11 +02:00
Fenris Wolf
61835bc533 [fix] widget:weekview 2024-10-21 07:01:13 +02:00
Fenris Wolf
fda85b38f9 [mod] widget:weekview [mod] page:overview:responsive 2024-10-20 18:26:05 +02:00
Fenris Wolf
18fcdd881e [mod] widget:listview:bessere Darstellung und Bedienung 2024-10-20 17:26:35 +02:00
Fenris Wolf
34ec6125c5 [mod] link für events berücksichtigen [mod] Wochentage übersetzen 2024-10-14 19:07:35 +02:00
Fenris Wolf
5736e1a5a2 [mod] loc:add keys 2024-10-14 19:07:03 +02:00
Fenris Wolf
93d35f5cc0 Merge branch 'dev-publicity_calendars' 2024-10-12 12:06:38 +02:00
Fenris Wolf
e505103228 [add] license 2024-10-12 12:05:31 +02:00
35 changed files with 1423 additions and 835 deletions

View file

@ -1,11 +1,11 @@
/** /**
* @author fenris * @author fenris
*/ */
type int = number; declare type int = number;
/** /**
* @author fenris * @author fenris
*/ */
type float = number; declare type float = number;
declare class Buffer { declare class Buffer {
constructor(x: string, modifier?: string); constructor(x: string, modifier?: string);
toString(modifier?: string): string; toString(modifier?: string): string;
@ -19,7 +19,7 @@ declare namespace lib_plankton.base {
/** /**
* @author fenris * @author fenris
*/ */
type type_pseudopointer<type_value> = { declare type type_pseudopointer<type_value> = {
value: type_value; value: type_value;
}; };
/** /**
@ -868,33 +868,11 @@ declare namespace lib_plankton.call {
fallback?: (null | ((coproduct?: type_coproduct) => type_output)); fallback?: (null | ((coproduct?: type_coproduct) => type_output));
}): type_output; }): type_output;
/** /**
* for rate_limit_check
*
* @author fenris
*/ */
type type_mana_snapshot = { function try_catch_wrap<type_value>(get_value: (() => type_value)): {
timestamp: float; value: (null | type_value);
value: float; error: (null | any);
}; };
/**
* rate limiting algorithm, based on the idea of mana (magic power) in video games:
* - an actor has a fixed mana capacity, i.e. the maximum amount of available power
* - an actor has a fixed rate of mana regeneration, i.e. how fast the power is filled up (linear growth)
* - an action has a defined mana heft, i.e. how much power is required and deducted in order to execute it
* - mana states are represented by snapshots, i.e. the amount of power at a certain point in time
*
* @author fenris
*/
function rate_limit_check(setup: {
capacity: float;
regeneration_rate: float;
get_snapshot: (() => Promise<(null | type_mana_snapshot)>);
set_snapshot: ((snapshot: type_mana_snapshot) => Promise<void>);
update_snapshot: ((timestamp: float, value_increment: float) => Promise<void>);
}, heft: float): Promise<{
granted: boolean;
seconds: (null | float);
}>;
} }
declare namespace lib_plankton.file { declare namespace lib_plankton.file {
/** /**
@ -1825,7 +1803,7 @@ declare namespace lib_plankton.storage.memory {
clear(): Promise<void>; clear(): Promise<void>;
write(key: any, value: any): Promise<boolean>; write(key: any, value: any): Promise<boolean>;
delete(key: any): Promise<void>; delete(key: any): Promise<void>;
read(key: any): Promise<Awaited<type_item>>; read(key: any): Promise<type_item>;
search(term: any): Promise<{ search(term: any): Promise<{
key: string; key: string;
preview: string; preview: string;
@ -2995,6 +2973,10 @@ declare namespace lib_plankton.pit {
type type_pit = int; type type_pit = int;
} }
declare namespace lib_plankton.pit { declare namespace lib_plankton.pit {
/**
* @todo complete
*/
function timezone_name_to_timezone_shift(timezone_name: string): int;
/** /**
*/ */
function date_object_get_week_of_year(date: Date): int; function date_object_get_week_of_year(date: Date): int;
@ -3008,9 +2990,9 @@ declare namespace lib_plankton.pit {
*/ */
function to_date_object(pit: type_pit): Date; function to_date_object(pit: type_pit): Date;
/** /**
* @todo timezone * @todo test
*/ */
function to_datetime(pit: type_pit, options?: { function to_datetime(pit: type_pit, { timezone_shift, }?: {
timezone_shift?: int; timezone_shift?: int;
}): type_datetime; }): type_datetime;
/** /**
@ -3048,6 +3030,60 @@ declare namespace lib_plankton.pit {
function to_ywd(pit: type_pit, options?: { function to_ywd(pit: type_pit, options?: {
timezone_shift?: int; timezone_shift?: int;
}): type_ywd; }): type_ywd;
/**
* computes the point in time for switching to central european summer time
*
* @todo write tests
*/
function cest_switch_on(year: int): type_pit;
/**
* computes the point in time for switching away from central european summer time
*
* @todo write tests
*/
function cest_switch_off(year: int): type_pit;
/**
*/
function timezone_shift_ce(pit: type_pit): int;
/**
* [convenience]
*/
function to_datetime_ce(pit: type_pit): type_datetime;
/**
*/
function datetime_translate(datetime: type_datetime, timezone_shift: int): type_datetime;
/**
* [convenience]
*/
function datetime_translate_ce(datetime: type_datetime): type_datetime;
/**
*/
function timezone_shift_format(timezone_shift: int): string;
/**
*/
function date_format(date: type_date): string;
/**
*/
function time_format(time: type_time, { show_seconds, }?: {
show_seconds?: boolean;
}): string;
/**
* @todo show timezone
*/
function datetime_format(datetime: (null | type_datetime), { timezone_indicator, show_timezone, adjust_to_ce, omit_date, }?: {
timezone_indicator?: string;
show_timezone?: boolean;
adjust_to_ce?: boolean;
omit_date?: boolean;
}): string;
/**
*/
function timespan_format(from: type_datetime, to: (null | type_datetime), { timezone_indicator, show_timezone, adjust_to_ce, omit_date, }?: {
timezone_indicator?: string;
show_timezone?: boolean;
adjust_to_ce?: boolean;
omit_date?: boolean;
}): string;
} }
declare namespace lib_plankton.www_form { declare namespace lib_plankton.www_form {
/** /**
@ -3566,6 +3602,55 @@ declare namespace lib_plankton.zoo_input {
write(value: string): Promise<void>; write(value: string): Promise<void>;
} }
} }
declare namespace lib_plankton.zoo_input {
/**
*/
type type_translations = {
add?: string;
remove?: string;
};
/**
* @author fenris
*/
export class class_input_list<type_element> implements interface_input<Array<type_element>> {
/**
*/
private element_input_factory;
/**
*/
private elements_container_dom;
/**
*/
private elements;
/**
*/
private translations;
/**
*/
constructor(element_input_factory: (() => interface_input<type_element>), options?: {
translations?: type_translations;
});
/**
*/
private clear;
/**
*/
private add;
/**
* [implementation]
*/
setup(parent: HTMLElement): Promise<void>;
/**
* [implementation]
*/
read(): Promise<Array<type_element>>;
/**
* [implementation]
*/
write(value: Array<type_element>): Promise<void>;
}
export {};
}
declare namespace lib_plankton.zoo_input { declare namespace lib_plankton.zoo_input {
/** /**
* @author fenris * @author fenris
@ -3644,31 +3729,6 @@ declare namespace lib_plankton.zoo_input {
write(value: (null | lib_plankton.pit.type_time)): Promise<void>; write(value: (null | lib_plankton.pit.type_time)): Promise<void>;
} }
} }
declare namespace lib_plankton.zoo_input {
/**
*/
class class_input_datetime implements interface_input<lib_plankton.pit.type_datetime> {
/**
*/
private core;
/**
*/
constructor(options?: {
label_timezone_shift?: string;
label_date?: string;
label_time?: string;
});
/**
*/
setup(parent: HTMLElement): Promise<void>;
/**
*/
read(): Promise<lib_plankton.pit.type_datetime>;
/**
*/
write(value: lib_plankton.pit.type_datetime): Promise<void>;
}
}
declare namespace lib_plankton.zoo_input { declare namespace lib_plankton.zoo_input {
/** /**
* @author fenris * @author fenris
@ -3699,55 +3759,6 @@ declare namespace lib_plankton.zoo_input {
write(value: type_record): Promise<void>; write(value: type_record): Promise<void>;
} }
} }
declare namespace lib_plankton.zoo_input {
/**
*/
type type_translations = {
add?: string;
remove?: string;
};
/**
* @author fenris
*/
export class class_input_list<type_element> implements interface_input<Array<type_element>> {
/**
*/
private element_input_factory;
/**
*/
private elements_container_dom;
/**
*/
private elements;
/**
*/
private translations;
/**
*/
constructor(element_input_factory: (() => interface_input<type_element>), options?: {
translations?: type_translations;
});
/**
*/
private clear;
/**
*/
private add;
/**
* [implementation]
*/
setup(parent: HTMLElement): Promise<void>;
/**
* [implementation]
*/
read(): Promise<Array<type_element>>;
/**
* [implementation]
*/
write(value: Array<type_element>): Promise<void>;
}
export {};
}
declare namespace lib_plankton.zoo_input { declare namespace lib_plankton.zoo_input {
/** /**
*/ */
@ -3775,6 +3786,56 @@ declare namespace lib_plankton.zoo_input {
write(map: lib_plankton.map.type_map<type_key, type_value>): Promise<void>; write(map: lib_plankton.map.type_map<type_key, type_value>): Promise<void>;
} }
} }
declare namespace lib_plankton.zoo_input {
/**
*/
class class_input_datetime implements interface_input<lib_plankton.pit.type_datetime> {
/**
*/
private core;
/**
*/
constructor(options?: {
label_timezone_shift?: string;
label_date?: string;
label_time?: string;
});
/**
*/
setup(parent: HTMLElement): Promise<void>;
/**
*/
read(): Promise<lib_plankton.pit.type_datetime>;
/**
*/
write(value: lib_plankton.pit.type_datetime): Promise<void>;
}
}
declare namespace lib_plankton.zoo_input {
/**
* for central europe with daylight saving time feature
*/
class class_input_datetime_central_europe implements interface_input<lib_plankton.pit.type_datetime> {
/**
*/
private core;
/**
*/
constructor(options?: {
label_date?: string;
label_time?: string;
});
/**
*/
setup(parent: HTMLElement): Promise<void>;
/**
*/
read(): Promise<lib_plankton.pit.type_datetime>;
/**
*/
write(value: lib_plankton.pit.type_datetime): Promise<void>;
}
}
declare namespace lib_plankton.zoo_form { declare namespace lib_plankton.zoo_form {
/** /**
*/ */

View file

@ -2046,63 +2046,22 @@ var lib_plankton;
} }
call.distinguish = distinguish; call.distinguish = distinguish;
/** /**
* rate limiting algorithm, based on the idea of mana (magic power) in video games:
* - an actor has a fixed mana capacity, i.e. the maximum amount of available power
* - an actor has a fixed rate of mana regeneration, i.e. how fast the power is filled up (linear growth)
* - an action has a defined mana heft, i.e. how much power is required and deducted in order to execute it
* - mana states are represented by snapshots, i.e. the amount of power at a certain point in time
*
* @author fenris
*/ */
async function rate_limit_check(setup, heft) { function try_catch_wrap(get_value) {
if (heft > setup.capacity) { try {
return Promise.resolve({ return {
"granted": false, "value": get_value(),
"seconds": null, "error": null,
}); };
} }
else { catch (error) {
// get current value return {
const current_timestamp = (Date.now() / 1000); "value": null,
const old_snapshot_raw = (await setup.get_snapshot()); "error": error,
const old_snapshot = (old_snapshot_raw };
??
{ "timestamp": current_timestamp, "value": setup.capacity });
const seconds_passed = (current_timestamp - old_snapshot.timestamp);
const current_value = Math.min(setup.capacity, (old_snapshot.value
+
(setup.regeneration_rate
*
seconds_passed)));
// analyze
if (current_value < heft) {
// too less
const seconds_needed = ((setup.regeneration_rate <= 0)
? null
: ((heft - old_snapshot.value) / setup.regeneration_rate));
return Promise.resolve({
"granted": false,
"seconds": ((seconds_needed === null) ? null : (seconds_needed - seconds_passed)),
});
}
else {
// enough -> update snapshot
const new_value = (current_value - heft);
// set_snapshot
if (old_snapshot_raw === null) {
await setup.set_snapshot({ "timestamp": current_timestamp, "value": new_value });
}
else {
await setup.update_snapshot(current_timestamp, (new_value - old_snapshot.value));
}
return Promise.resolve({
"granted": true,
"seconds": 0,
});
} }
} }
} call.try_catch_wrap = try_catch_wrap;
call.rate_limit_check = rate_limit_check;
})(call = lib_plankton.call || (lib_plankton.call = {})); })(call = lib_plankton.call || (lib_plankton.call = {}));
})(lib_plankton || (lib_plankton = {})); })(lib_plankton || (lib_plankton = {}));
/* /*
@ -2225,7 +2184,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
function verb(n) { return function (v) { return step([n, v]); }; } function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) { function step(op) {
if (f) throw new TypeError("Generator is already executing."); if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try { while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value]; if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) { switch (op[0]) {
@ -3824,7 +3783,7 @@ var lib_plankton;
return { return {
"reports": [ "reports": [
{ {
"incident": "no valid apaptions", "incident": "no valid adaptions",
"details": { "details": {
"sub_adaptions": sub_adaptions, "sub_adaptions": sub_adaptions,
} }
@ -4634,11 +4593,16 @@ var lib_plankton;
if (options.legacy) { if (options.legacy) {
const value = args[key]; const value = args[key];
const regexp_argument = new RegExp("\\${" + key + "}", "g"); const regexp_argument = new RegExp("\\${" + key + "}", "g");
lib_plankton.log.debug("lib_plankton.string.coin", { /*
lib_plankton.log.debug(
"lib_plankton.string.coin",
{
"key": key, "key": key,
"regex": regexp_argument.toString(), "regex": regexp_argument.toString(),
"value": value, "value": value,
}); }
);
*/
str = str.replace(regexp_argument, value); str = str.replace(regexp_argument, value);
} }
} }
@ -4646,11 +4610,16 @@ var lib_plankton;
{ {
const value = args[key]; const value = args[key];
const regexp_argument = new RegExp(options.open + key + options.close, "g"); const regexp_argument = new RegExp(options.open + key + options.close, "g");
lib_plankton.log.debug("lib_plankton.string.coin", { /*
lib_plankton.log.debug(
"lib_plankton.string.coin",
{
"key": key, "key": key,
"regex": regexp_argument.toString(), "regex": regexp_argument.toString(),
"value": value, "value": value,
}); }
);
*/
str = str.replace(regexp_argument, value); str = str.replace(regexp_argument, value);
} }
}); });
@ -6735,12 +6704,6 @@ var lib_plankton;
* @author fenris * @author fenris
*/ */
class class_relation { class class_relation {
/**
* @author fenris
*/
check(value, reference) {
return this.predicate(value, reference);
}
/** /**
* @author fenris * @author fenris
*/ */
@ -6750,6 +6713,12 @@ var lib_plankton;
this.name = name; this.name = name;
this.predicate = predicate; this.predicate = predicate;
} }
/**
* @author fenris
*/
check(value, reference) {
return this.predicate(value, reference);
}
/** /**
* @author fenris * @author fenris
*/ */
@ -8357,6 +8326,23 @@ var lib_plankton;
(function (lib_plankton) { (function (lib_plankton) {
var pit; var pit;
(function (pit_1) { (function (pit_1) {
/**
* @todo complete
*/
function timezone_name_to_timezone_shift(timezone_name) {
const map = {
"UTC": 0,
"CET": +1,
"CEST": +2,
};
if (!(timezone_name in map)) {
throw (new Error("unhandled timezone: " + timezone_name));
}
else {
return map[timezone_name];
}
}
pit_1.timezone_name_to_timezone_shift = timezone_name_to_timezone_shift;
/** /**
*/ */
function date_object_get_week_of_year(date) { function date_object_get_week_of_year(date) {
@ -8402,20 +8388,17 @@ var lib_plankton;
return Math.round(date_object.getTime() / 1000); return Math.round(date_object.getTime() / 1000);
} }
/** /**
* @todo timezone * @todo test
*/ */
function to_datetime(pit, options = {}) { function to_datetime(pit, { timezone_shift = 0, } = {}) {
options = Object.assign({
"timezone_shift": 0,
}, options);
return lib_plankton.call.convey(pit, [ return lib_plankton.call.convey(pit, [
to_date_object, to_date_object,
(x) => x.getTime(), (x) => x.getTime(),
(x) => (x + ((options.timezone_shift * (60 * 60)) * 1000)), (x) => (x + ((timezone_shift * (60 * 60)) * 1000)),
(x) => new Date(x), (x) => new Date(x),
x => x.toISOString(), x => x.toISOString(),
x => ({ x => ({
"timezone_shift": options.timezone_shift, "timezone_shift": timezone_shift,
"date": { "date": {
"year": parseInt(x.slice(0, 4)), "year": parseInt(x.slice(0, 4)),
"month": parseInt(x.slice(5, 7)), "month": parseInt(x.slice(5, 7)),
@ -8660,6 +8643,234 @@ var lib_plankton;
]); ]);
} }
pit_1.to_ywd = to_ywd; pit_1.to_ywd = to_ywd;
/**
* computes the point in time for switching to central european summer time
*
* @todo write tests
*/
function cest_switch_on(year) {
return lib_plankton.call.convey(year, [
(x) => ({
"timezone_shift": 0,
"date": {
"year": x,
"month": 4,
"day": 1,
},
"time": {
"hour": 2,
"minute": 0,
"second": 0
},
}),
from_datetime,
trunc_week,
x => shift_day(x, -1),
]);
}
pit_1.cest_switch_on = cest_switch_on;
/**
* computes the point in time for switching away from central european summer time
*
* @todo write tests
*/
function cest_switch_off(year) {
return lib_plankton.call.convey(year, [
(x) => ({
"timezone_shift": 0,
"date": {
"year": x,
"month": 11,
"day": 1,
},
"time": {
"hour": 1,
"minute": 0,
"second": 0
},
}),
from_datetime,
trunc_week,
x => shift_day(x, -1),
]);
}
pit_1.cest_switch_off = cest_switch_off;
/**
*/
function timezone_shift_ce(pit) {
const year = to_datetime(pit).date.year;
return (is_between(pit, cest_switch_on(year), cest_switch_off(year))
? +2
: +1);
}
pit_1.timezone_shift_ce = timezone_shift_ce;
/**
* [convenience]
*/
function to_datetime_ce(pit) {
return to_datetime(pit, {
"timezone_shift": timezone_shift_ce(pit),
});
}
pit_1.to_datetime_ce = to_datetime_ce;
/**
*/
function datetime_translate(datetime, timezone_shift) {
if (datetime.timezone_shift === timezone_shift) {
return datetime;
}
else {
const pit = from_datetime(datetime);
const pit_shifted = shift_hour(pit, (timezone_shift - datetime.timezone_shift));
const datetime_shifted = to_datetime(pit_shifted);
return {
"timezone_shift": timezone_shift,
"date": datetime_shifted.date,
"time": ((datetime.time === null)
?
null
: datetime_shifted.time)
};
}
}
pit_1.datetime_translate = datetime_translate;
/**
* [convenience]
*/
function datetime_translate_ce(datetime) {
return datetime_translate(datetime, timezone_shift_ce(from_datetime(datetime)));
}
pit_1.datetime_translate_ce = datetime_translate_ce;
/**
*/
function timezone_shift_format(timezone_shift) {
return lib_plankton.string.coin("{{sign}}{{value}}", {
"sign": ((timezone_shift === 0)
?
" "
:
((timezone_shift > 0)
?
"+"
:
"-")),
"value": Math.abs(timezone_shift).toFixed(0),
});
}
pit_1.timezone_shift_format = timezone_shift_format;
/**
*/
function date_format(date) {
return lib_plankton.string.coin("{{year}}-{{month}}-{{day}}", {
"year": date.year.toFixed(0).padStart(4, "0"),
"month": date.month.toFixed(0).padStart(2, "0"),
"day": date.day.toFixed(0).padStart(2, "0"),
});
}
pit_1.date_format = date_format;
/**
*/
function time_format(time, { show_seconds = false, } = {}) {
return lib_plankton.string.coin((show_seconds
?
"{{hour}}:{{minute}}:{{seconds}}"
:
"{{hour}}:{{minute}}"), {
"hour": time.hour.toFixed(0).padStart(2, "0"),
"minute": time.minute.toFixed(0).padStart(2, "0"),
"second": time.second.toFixed(0).padStart(2, "0"),
});
}
pit_1.time_format = time_format;
/**
* @todo show timezone
*/
function datetime_format(datetime, { timezone_indicator = "", show_timezone = false, adjust_to_ce = false, omit_date = false, } = {}) {
if (datetime === null) {
return "-";
}
else {
const datetime_adjusted = (adjust_to_ce
?
to_datetime_ce(from_datetime(datetime))
:
datetime);
return lib_plankton.string.coin("{{macro_date_and_time}}{{macro_timezone}}", {
"macro_date_and_time": ([
// date
(omit_date
?
null
:
date_format(datetime_adjusted.date)),
// time
((datetime_adjusted.time === null)
?
null
:
time_format(datetime_adjusted.time)),
]
.filter(x => (x !== null))
.join(", ")),
"macro_timezone": (show_timezone
?
lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", {
"timezone_indicator": timezone_indicator,
"timezone_value": timezone_shift_format(datetime_adjusted.timezone_shift),
})
:
""),
});
}
}
pit_1.datetime_format = datetime_format;
/**
*/
function timespan_format(from, to, { timezone_indicator = "", show_timezone = false, adjust_to_ce = false, omit_date = false, } = {}) {
const from_adjusted = (adjust_to_ce
?
datetime_translate_ce(from)
:
from);
const to_adjusted = ((to === null)
?
null
:
(adjust_to_ce
?
datetime_translate_ce(to)
:
to));
return lib_plankton.string.coin("{{from}}{{to_macro}}{{macro_timezone}}", {
"from": datetime_format(from_adjusted, {
"show_timezone": false,
"adjust_to_ce": false,
"omit_date": omit_date,
}),
"to_macro": ((to_adjusted === null)
?
""
:
lib_plankton.string.coin(" - {{to}}", {
"to": datetime_format(to_adjusted, {
"omit_date": ((from_adjusted.date.year === to_adjusted.date.year)
&&
(from_adjusted.date.month === to_adjusted.date.month)
&&
(from_adjusted.date.day === to_adjusted.date.day))
}),
})),
"macro_timezone": (show_timezone
?
lib_plankton.string.coin(" [{{timezone_indicator}}{{timezone_value}}]", {
"timezone_indicator": timezone_indicator,
"timezone_value": timezone_shift_format(from_adjusted.timezone_shift),
})
:
""),
});
}
pit_1.timespan_format = timespan_format;
})(pit = lib_plankton.pit || (lib_plankton.pit = {})); })(pit = lib_plankton.pit || (lib_plankton.pit = {}));
})(lib_plankton || (lib_plankton = {})); })(lib_plankton || (lib_plankton = {}));
/* /*
@ -10153,6 +10364,153 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. 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-input«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var zoo_input;
(function (zoo_input) {
/**
* @author fenris
*/
class class_input_list {
/**
*/
constructor(element_input_factory, options = {}) {
options = Object.assign({
"translations": {
"add": "add",
"remove": "remove",
},
}, options);
this.element_input_factory = element_input_factory;
this.elements = [];
this.elements_container_dom = null;
this.translations = options.translations;
}
/**
*/
clear() {
this.elements_container_dom.innerHTML = "";
this.elements = [];
return Promise.resolve(undefined);
}
/**
*/
async add() {
// model
let element_dom = document.createElement("div");
const input = this.element_input_factory();
this.elements.push({ "dom": element_dom, "input": input });
// view & control
{
element_dom.classList.add("plankton_input_list_element");
// remover
{
let remover_dom = document.createElement("button");
remover_dom.classList.add("plankton_input_list_button");
remover_dom.classList.add("plankton_input_list_element_remover");
remover_dom.setAttribute("title", this.translations.remove);
remover_dom.textContent = "x";
remover_dom.addEventListener("click", (event) => {
event.preventDefault();
const index = this.elements.findIndex(element => (element.input === input));
const element = this.elements[index];
this.elements_container_dom.removeChild(element.dom);
this.elements.splice(index, 1);
});
element_dom.appendChild(remover_dom);
}
// input
{
let input_dom = document.createElement("div");
input_dom.classList.add("plankton_input_list_element_input");
await input.setup(input_dom);
element_dom.appendChild(input_dom);
}
this.elements_container_dom.appendChild(element_dom);
}
return Promise.resolve(input);
}
/**
* [implementation]
*/
setup(parent) {
let container_dom = document.createElement("div");
container_dom.classList.add("plankton_input_list");
// elements
{
this.elements_container_dom = document.createElement("div");
this.elements_container_dom.classList.add("plankton_input_list_elements");
container_dom.appendChild(this.elements_container_dom);
}
// foot
{
let footer_dom = document.createElement("div");
footer_dom.classList.add("plankton_input_list_foot");
// adder
{
let adder_dom = document.createElement("button");
adder_dom.classList.add("plankton_input_list_button");
adder_dom.classList.add("plankton_input_list_adder");
adder_dom.setAttribute("title", this.translations.add);
adder_dom.textContent = "+";
adder_dom.addEventListener("click", (event) => {
event.preventDefault();
this.add();
});
footer_dom.appendChild(adder_dom);
}
container_dom.appendChild(footer_dom);
}
parent.appendChild(container_dom);
return Promise.resolve(undefined);
}
/**
* [implementation]
*/
read() {
return (Promise.all(this.elements
.map((element, index) => (element.input.read()
.then((element_value) => Promise.resolve({
"index": index,
"value": element_value,
})))))
.then((elements) => Promise.resolve(elements
.sort((x, y) => ((x.index <= y.index) ? 0 : 1))
.map(element => element.value))));
}
/**
* [implementation]
*/
write(value) {
return (this.clear()
.then(() => Promise.all(value
.map((element_value) => (this.add()
.then(element_input => element_input.write(element_value))))))
.then(() => Promise.resolve(undefined)));
}
}
zoo_input.class_input_list = class_input_list;
})(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:zoo-input« 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-input« 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 You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>. along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -10360,77 +10718,6 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. 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-input«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var zoo_input;
(function (zoo_input) {
/**
*/
class class_input_datetime {
/**
*/
constructor(options = {}) {
options = Object.assign({
"label_timezone_shift": "",
"label_date": "",
"label_time": "",
}, options);
this.core = new zoo_input.class_input_group([
{
"name": "timezone_shift",
"input": new zoo_input.class_input_number(),
"label": options.label_timezone_shift,
},
{
"name": "date",
"input": new zoo_input.class_input_date(),
"label": options.label_date,
},
{
"name": "time",
"input": new zoo_input.class_input_soft(new zoo_input.class_input_time()),
"label": options.label_time,
},
]);
}
/**
*/
async setup(parent) {
return this.core.setup(parent);
}
/**
*/
async read() {
return this.core.read();
}
/**
*/
async write(value) {
return this.core.write(value);
}
}
zoo_input.class_input_datetime = class_input_datetime;
})(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:zoo-input« 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-input« 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 You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>. along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -10538,153 +10825,6 @@ but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. 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-input«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var zoo_input;
(function (zoo_input) {
/**
* @author fenris
*/
class class_input_list {
/**
*/
constructor(element_input_factory, options = {}) {
options = Object.assign({
"translations": {
"add": "add",
"remove": "remove",
},
}, options);
this.element_input_factory = element_input_factory;
this.elements = [];
this.elements_container_dom = null;
this.translations = options.translations;
}
/**
*/
clear() {
this.elements_container_dom.innerHTML = "";
this.elements = [];
return Promise.resolve(undefined);
}
/**
*/
async add() {
// model
let element_dom = document.createElement("div");
const input = this.element_input_factory();
this.elements.push({ "dom": element_dom, "input": input });
// view & control
{
element_dom.classList.add("plankton_input_list_element");
// remover
{
let remover_dom = document.createElement("button");
remover_dom.classList.add("plankton_input_list_button");
remover_dom.classList.add("plankton_input_list_element_remover");
remover_dom.setAttribute("title", this.translations.remove);
remover_dom.textContent = "x";
remover_dom.addEventListener("click", (event) => {
event.preventDefault();
const index = this.elements.findIndex(element => (element.input === input));
const element = this.elements[index];
this.elements_container_dom.removeChild(element.dom);
this.elements.splice(index, 1);
});
element_dom.appendChild(remover_dom);
}
// input
{
let input_dom = document.createElement("div");
input_dom.classList.add("plankton_input_list_element_input");
await input.setup(input_dom);
element_dom.appendChild(input_dom);
}
this.elements_container_dom.appendChild(element_dom);
}
return Promise.resolve(input);
}
/**
* [implementation]
*/
setup(parent) {
let container_dom = document.createElement("div");
container_dom.classList.add("plankton_input_list");
// elements
{
this.elements_container_dom = document.createElement("div");
this.elements_container_dom.classList.add("plankton_input_list_elements");
container_dom.appendChild(this.elements_container_dom);
}
// foot
{
let footer_dom = document.createElement("div");
footer_dom.classList.add("plankton_input_list_foot");
// adder
{
let adder_dom = document.createElement("button");
adder_dom.classList.add("plankton_input_list_button");
adder_dom.classList.add("plankton_input_list_adder");
adder_dom.setAttribute("title", this.translations.add);
adder_dom.textContent = "+";
adder_dom.addEventListener("click", (event) => {
event.preventDefault();
this.add();
});
footer_dom.appendChild(adder_dom);
}
container_dom.appendChild(footer_dom);
}
parent.appendChild(container_dom);
return Promise.resolve(undefined);
}
/**
* [implementation]
*/
read() {
return (Promise.all(this.elements
.map((element, index) => (element.input.read()
.then((element_value) => Promise.resolve({
"index": index,
"value": element_value,
})))))
.then((elements) => Promise.resolve(elements
.sort((x, y) => ((x.index <= y.index) ? 0 : 1))
.map(element => element.value))));
}
/**
* [implementation]
*/
write(value) {
return (this.clear()
.then(() => Promise.all(value
.map((element_value) => (this.add()
.then(element_input => element_input.write(element_value))))))
.then(() => Promise.resolve(undefined)));
}
}
zoo_input.class_input_list = class_input_list;
})(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:zoo-input« 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-input« 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 You should have received a copy of the GNU Lesser General Public License
along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>. along with »bacterio-plankton:zoo-input«. If not, see <http://www.gnu.org/licenses/>.
*/ */
@ -10739,6 +10879,180 @@ var lib_plankton;
})(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {})); })(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {})); })(lib_plankton || (lib_plankton = {}));
/* /*
This file is part of »bacterio-plankton:zoo-input«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:zoo-input« 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-input« 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-input«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var zoo_input;
(function (zoo_input) {
/**
*/
class class_input_datetime {
/**
*/
constructor(options = {}) {
options = Object.assign({
"label_timezone_shift": "",
"label_date": "",
"label_time": "",
}, options);
this.core = new zoo_input.class_input_group([
{
"name": "timezone_shift",
"input": new zoo_input.class_input_number(),
"label": options.label_timezone_shift,
},
{
"name": "date",
"input": new zoo_input.class_input_date(),
"label": options.label_date,
},
{
"name": "time",
"input": new zoo_input.class_input_soft(new zoo_input.class_input_time()),
"label": options.label_time,
},
]);
}
/**
*/
setup(parent) {
return this.core.setup(parent);
}
/**
*/
read() {
return this.core.read();
}
/**
*/
write(value) {
return this.core.write(value);
}
}
zoo_input.class_input_datetime = class_input_datetime;
})(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:zoo-input« 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-input« 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-input«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var zoo_input;
(function (zoo_input) {
/**
* for central europe with daylight saving time feature
*/
class class_input_datetime_central_europe {
/**
*/
constructor(options = {}) {
options = Object.assign({
"label_date": "",
"label_time": "",
}, options);
this.core = new zoo_input.class_input_group([
{
"name": "date",
"input": new zoo_input.class_input_date(),
"label": options.label_date,
},
{
"name": "time",
"input": new zoo_input.class_input_soft(new zoo_input.class_input_time()),
"label": options.label_time,
},
]);
}
/**
*/
setup(parent) {
return this.core.setup(parent);
}
/**
*/
async read() {
const datetime_easy = await this.core.read();
const datetime_cet = {
"timezone_shift": 1,
"date": datetime_easy.date,
"time": datetime_easy.time,
};
const datetime_cest = {
"timezone_shift": 2,
"date": datetime_easy.date,
"time": datetime_easy.time,
};
const datetime = (lib_plankton.pit.is_between(lib_plankton.pit.from_datetime(datetime_cet), lib_plankton.pit.cest_switch_on(datetime_easy.date.year), lib_plankton.pit.cest_switch_off(datetime_easy.date.year))
?
datetime_cest
:
datetime_cet);
if (datetime_easy.time === null) {
datetime.time = null;
}
else {
// do nothing
}
return Promise.resolve(datetime);
}
/**
*/
async write(value) {
const pit = lib_plankton.pit.from_datetime(value);
const datetime_utc = lib_plankton.pit.to_datetime(pit, {
"timezone_shift": 0,
});
const datetime_relative = lib_plankton.pit.to_datetime(pit, {
"timezone_shift": (lib_plankton.pit.is_between(lib_plankton.pit.from_datetime(datetime_utc), lib_plankton.pit.cest_switch_on(datetime_utc.date.year), lib_plankton.pit.cest_switch_off(datetime_utc.date.year))
?
2
:
1)
});
const datetime_easy = {
"date": datetime_relative.date,
"time": ((value.time === null) ? null : datetime_relative.time),
};
return this.core.write(datetime_easy);
}
}
zoo_input.class_input_datetime_central_europe = class_input_datetime_central_europe;
})(zoo_input = lib_plankton.zoo_input || (lib_plankton.zoo_input = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-form«. This file is part of »bacterio-plankton:zoo-form«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR' Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'

View file

@ -4,17 +4,31 @@
}, },
"tree": { "tree": {
"common.timezone_shift": "Zeitzonen-Verschiebung", "common.timezone_shift": "Zeitzonen-Verschiebung",
"common.timezone_indicator": "ZZ:",
"common.date": "Datum", "common.date": "Datum",
"common.time": "Uhrzeit", "common.time": "Uhrzeit",
"common.weekday.monday": "Mo",
"common.weekday.tuesday": "Di",
"common.weekday.wednesday": "Mi",
"common.weekday.thursday": "Do",
"common.weekday.friday": "Fr",
"common.weekday.saturday": "Sa",
"common.weekday.sunday": "So",
"common.open": "öffnen",
"common.edit": "bearbeiten",
"common.show": "zeigen",
"common.hide": "ausblenden",
"access_level.none": "nichts", "access_level.none": "nichts",
"access_level.view": "nur lesen", "access_level.view": "nur lesen",
"access_level.edit": "lesen und bearbeiten", "access_level.edit": "lesen und bearbeiten",
"access_level.admin": "voll", "access_level.admin": "voll",
"event.event": "Termin", "event.event": "Termin",
"event.name": "Name", "event.name": "Name",
"event.when": "Zeit",
"event.begin": "Anfang", "event.begin": "Anfang",
"event.end": "Ende", "event.end": "Ende",
"event.location": "Ort", "event.location": "Ort",
"event.link": "Netz-Verweis",
"event.description": "Beschreibung", "event.description": "Beschreibung",
"resource.kind": "Art", "resource.kind": "Art",
"resource.kinds.local.title": "lokal", "resource.kinds.local.title": "lokal",
@ -29,6 +43,7 @@
"calendar.access.public": "öffentlich", "calendar.access.public": "öffentlich",
"calendar.access.default_level": "Standard", "calendar.access.default_level": "Standard",
"calendar.access.attributed": "Zuweisungen", "calendar.access.attributed": "Zuweisungen",
"widget.listview.add": "Termin anlegen",
"widget.weekview.controls.year": "Jahr", "widget.weekview.controls.year": "Jahr",
"widget.weekview.controls.week": "Woche", "widget.weekview.controls.week": "Woche",
"widget.weekview.controls.count": "Anzahl", "widget.weekview.controls.count": "Anzahl",

View file

@ -4,17 +4,31 @@
}, },
"tree": { "tree": {
"common.timezone_shift": "Timezone shift", "common.timezone_shift": "Timezone shift",
"common.timezone_indicator": "TZ:",
"common.date": "date", "common.date": "date",
"common.time": "time", "common.time": "time",
"common.weekday.monday": "Mon",
"common.weekday.tuesday": "Tue",
"common.weekday.wednesday": "Wed",
"common.weekday.thursday": "Thu",
"common.weekday.friday": "Fri",
"common.weekday.saturday": "Sat",
"common.weekday.sunday": "Sun",
"common.open": "open",
"common.edit": "edit",
"common.show": "show",
"common.hide": "hide",
"access_level.none": "none", "access_level.none": "none",
"access_level.view": "read only", "access_level.view": "read only",
"access_level.edit": "read and write", "access_level.edit": "read and write",
"access_level.admin": "full", "access_level.admin": "full",
"event.event": "event", "event.event": "event",
"event.name": "name", "event.name": "name",
"event.when": "time",
"event.begin": "begin", "event.begin": "begin",
"event.end": "end", "event.end": "end",
"event.location": "location", "event.location": "location",
"event.link": "link",
"event.description": "description", "event.description": "description",
"resource.kind": "kind", "resource.kind": "kind",
"resource.kinds.local.title": "local", "resource.kinds.local.title": "local",
@ -29,6 +43,7 @@
"calendar.access.public": "public", "calendar.access.public": "public",
"calendar.access.default_level": "default", "calendar.access.default_level": "default",
"calendar.access.attributed": "attributed", "calendar.access.attributed": "attributed",
"widget.listview.add": "add event",
"widget.weekview.controls.year": "Year", "widget.weekview.controls.year": "Year",
"widget.weekview.controls.week": "Week", "widget.weekview.controls.week": "Week",
"widget.weekview.controls.count": "Count", "widget.weekview.controls.count": "Count",

View file

@ -52,6 +52,11 @@ namespace _zeitbild.frontend_web.conf
"type": "string", "type": "string",
"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": {
"nullable": true,
"type": "boolean",
"default": false
},
}, },
"required": [ "required": [
], ],

View file

@ -75,106 +75,6 @@ namespace _zeitbild.frontend_web.helpers
} }
/**
* @todo timezone
*/
export function date_format(
date : lib_plankton.pit.type_date
) : string
{
return lib_plankton.string.coin(
"{{year}}-{{month}}-{{day}}",
{
"year": date.year.toFixed(0).padStart(4, "0"),
"month": date.month.toFixed(0).padStart(2, "0"),
"day": date.day.toFixed(0).padStart(2, "0"),
}
);
}
/**
* @todo timezone
*/
export function time_format(
time : lib_plankton.pit.type_time
) : string
{
return lib_plankton.string.coin(
"{{hour}}:{{minute}}",
{
"hour": time.hour.toFixed(0).padStart(2, "0"),
"minute": time.minute.toFixed(0).padStart(2, "0"),
"second": time.second.toFixed(0).padStart(2, "0"),
}
);
}
/**
* @todo timezone
*/
export function datetime_format(
datetime : (null | lib_plankton.pit.type_datetime)
) : string
{
if (datetime === null) {
return "-";
}
else {
return lib_plankton.string.coin(
"{{date}}{{macro_time}}",
{
"date": date_format(datetime.date),
"macro_time": (
(datetime.time === null)
?
""
:
lib_plankton.string.coin(
",{{time}}",
{
"time": time_format(datetime.time),
}
)
),
}
);
}
}
/**
*/
export function timespan_format(
from : lib_plankton.pit.type_datetime,
to : (null | lib_plankton.pit.type_datetime)
) : string
{
let result : string = "";
result += datetime_format(from);
if (to === null) {
// do nothing
}
else {
result += " - ";
if (
(from.date.year === to.date.year)
&&
(from.date.month === to.date.month)
&&
(from.date.day === to.date.day)
) {
// only time
result += time_format(to.time);
}
else {
result += datetime_format(to);
}
}
return result;
}
/** /**
*/ */
export function input_access_level( export function input_access_level(
@ -257,4 +157,30 @@ namespace _zeitbild.frontend_web.helpers
); );
} }
/**
*/
export function datetime_input(
) : lib_plankton.zoo_input.interface_input<lib_plankton.pit.type_datetime>
{
return (
_zeitbild.frontend_web.conf.get().misc.use_central_europe_specific_datetime_inputs
?
new lib_plankton.zoo_input.class_input_datetime_central_europe(
{
"label_date": lib_plankton.translate.get("common.date"),
"label_time": lib_plankton.translate.get("common.time"),
}
)
:
new lib_plankton.zoo_input.class_input_datetime(
{
"label_timezone_shift": lib_plankton.translate.get("common.timezone_shift"),
"label_date": lib_plankton.translate.get("common.date"),
"label_time": lib_plankton.translate.get("common.time"),
}
)
);
}
} }

View file

@ -46,6 +46,11 @@ namespace _zeitbild.frontend_web.type
| |
string string
); );
link : (
null
|
string
);
description : ( description : (
null null
| |

View file

@ -70,6 +70,7 @@ namespace _zeitbild.frontend_web.pages
begin : lib_plankton.pit.type_datetime; begin : lib_plankton.pit.type_datetime;
end : (null | lib_plankton.pit.type_datetime); end : (null | lib_plankton.pit.type_datetime);
location : (null | string); location : (null | string);
link : (null | string);
description : (null | string); description : (null | string);
} }
> = new lib_plankton.zoo_form.class_form< > = new lib_plankton.zoo_form.class_form<
@ -83,6 +84,7 @@ namespace _zeitbild.frontend_web.pages
begin : lib_plankton.pit.type_datetime; begin : lib_plankton.pit.type_datetime;
end : (null | lib_plankton.pit.type_datetime); end : (null | lib_plankton.pit.type_datetime);
location : (null | string); location : (null | string);
link : (null | string);
description : (null | string); description : (null | string);
} }
>( >(
@ -92,6 +94,7 @@ namespace _zeitbild.frontend_web.pages
"begin": value.event_object.begin, "begin": value.event_object.begin,
"end": value.event_object.end, "end": value.event_object.end,
"location": value.event_object.location, "location": value.event_object.location,
"link": value.event_object.link,
"description": value.event_object.description, "description": value.event_object.description,
}), }),
(representation) => ({ (representation) => ({
@ -101,6 +104,7 @@ namespace _zeitbild.frontend_web.pages
"begin": representation.begin, "begin": representation.begin,
"end": representation.end, "end": representation.end,
"location": representation.location, "location": representation.location,
"link": representation.link,
"description": representation.description, "description": representation.description,
} }
}), }),
@ -136,25 +140,13 @@ namespace _zeitbild.frontend_web.pages
}, },
{ {
"name": "begin", "name": "begin",
"input": new lib_plankton.zoo_input.class_input_datetime( "input": _zeitbild.frontend_web.helpers.datetime_input(),
{
"label_timezone_shift": lib_plankton.translate.get("common.timezone_shift"),
"label_date": lib_plankton.translate.get("common.date"),
"label_time": lib_plankton.translate.get("common.time"),
}
),
"label": lib_plankton.translate.get("event.begin") "label": lib_plankton.translate.get("event.begin")
}, },
{ {
"name": "end", "name": "end",
"input": new lib_plankton.zoo_input.class_input_soft<lib_plankton.pit.type_datetime>( "input": new lib_plankton.zoo_input.class_input_soft<lib_plankton.pit.type_datetime>(
new lib_plankton.zoo_input.class_input_datetime( _zeitbild.frontend_web.helpers.datetime_input()
{
"label_timezone_shift": lib_plankton.translate.get("common.timezone_shift"),
"label_date": lib_plankton.translate.get("common.date"),
"label_time": lib_plankton.translate.get("common.time"),
}
)
), ),
"label": lib_plankton.translate.get("event.end") "label": lib_plankton.translate.get("event.end")
}, },
@ -166,6 +158,14 @@ namespace _zeitbild.frontend_web.pages
), ),
"label": lib_plankton.translate.get("event.location") "label": lib_plankton.translate.get("event.location")
}, },
{
"name": "link",
"input": new lib_plankton.zoo_input.class_input_soft<string>(
new lib_plankton.zoo_input.class_input_text(
)
),
"label": lib_plankton.translate.get("event.link")
},
{ {
"name": "description", "name": "description",
"input": new lib_plankton.zoo_input.class_input_soft<string>( "input": new lib_plankton.zoo_input.class_input_soft<string>(
@ -223,6 +223,7 @@ namespace _zeitbild.frontend_web.pages
}, },
"end": null, "end": null,
"location": null, "location": null,
"link": null,
"description": null, "description": null,
} }
} }

View file

@ -30,6 +30,7 @@ namespace _zeitbild.frontend_web.pages
begin : lib_plankton.pit.type_datetime; begin : lib_plankton.pit.type_datetime;
end : (null | lib_plankton.pit.type_datetime); end : (null | lib_plankton.pit.type_datetime);
location : (null | string); location : (null | string);
link : (null | string);
description : (null | string); description : (null | string);
} }
> = new lib_plankton.zoo_form.class_form< > = new lib_plankton.zoo_form.class_form<
@ -39,6 +40,7 @@ namespace _zeitbild.frontend_web.pages
begin : lib_plankton.pit.type_datetime; begin : lib_plankton.pit.type_datetime;
end : (null | lib_plankton.pit.type_datetime); end : (null | lib_plankton.pit.type_datetime);
location : (null | string); location : (null | string);
link : (null | string);
description : (null | string); description : (null | string);
} }
>( >(
@ -47,6 +49,7 @@ namespace _zeitbild.frontend_web.pages
"begin": value.begin, "begin": value.begin,
"end": value.end, "end": value.end,
"location": value.location, "location": value.location,
"link": value.link,
"description": value.description, "description": value.description,
}), }),
(representation) => ({ (representation) => ({
@ -54,6 +57,7 @@ namespace _zeitbild.frontend_web.pages
"begin": representation.begin, "begin": representation.begin,
"end": representation.end, "end": representation.end,
"location": representation.location, "location": representation.location,
"link": representation.link,
"description": representation.description, "description": representation.description,
}), }),
new lib_plankton.zoo_input.class_input_group<any>( new lib_plankton.zoo_input.class_input_group<any>(
@ -66,25 +70,13 @@ namespace _zeitbild.frontend_web.pages
}, },
{ {
"name": "begin", "name": "begin",
"input": new lib_plankton.zoo_input.class_input_datetime( "input": _zeitbild.frontend_web.helpers.datetime_input(),
{
"label_timezone_shift": lib_plankton.translate.get("common.timezone_shift"),
"label_date": lib_plankton.translate.get("common.date"),
"label_time": lib_plankton.translate.get("common.time"),
}
),
"label": lib_plankton.translate.get("event.begin") "label": lib_plankton.translate.get("event.begin")
}, },
{ {
"name": "end", "name": "end",
"input": new lib_plankton.zoo_input.class_input_soft<lib_plankton.pit.type_datetime>( "input": new lib_plankton.zoo_input.class_input_soft<lib_plankton.pit.type_datetime>(
new lib_plankton.zoo_input.class_input_datetime( _zeitbild.frontend_web.helpers.datetime_input()
{
"label_timezone_shift": lib_plankton.translate.get("common.timezone_shift"),
"label_date": lib_plankton.translate.get("common.date"),
"label_time": lib_plankton.translate.get("common.time"),
}
)
), ),
"label": lib_plankton.translate.get("event.end") "label": lib_plankton.translate.get("event.end")
}, },
@ -96,6 +88,14 @@ namespace _zeitbild.frontend_web.pages
), ),
"label": lib_plankton.translate.get("event.location") "label": lib_plankton.translate.get("event.location")
}, },
{
"name": "link",
"input": new lib_plankton.zoo_input.class_input_soft<string>(
new lib_plankton.zoo_input.class_input_text(
)
),
"label": lib_plankton.translate.get("event.link")
},
{ {
"name": "description", "name": "description",
"input": new lib_plankton.zoo_input.class_input_soft<string>( "input": new lib_plankton.zoo_input.class_input_soft<string>(

View file

@ -30,7 +30,9 @@ namespace _zeitbild.frontend_web.pages.overview
{ {
} }
); );
target_element.querySelector("#overview").classList.toggle("compact", compact); target_element.querySelector("#overview").classList.toggle("overview-compact", compact);
let widget_weekview : _zeitbild.frontend_web.widgets.weekview.class_widget_weekview;
let widget_listview : _zeitbild.frontend_web.widgets.listview.class_widget_listview;
// hint // hint
{ {
if (! await _zeitbild.frontend_web.backend.is_logged_in()) { if (! await _zeitbild.frontend_web.backend.is_logged_in()) {
@ -53,7 +55,7 @@ namespace _zeitbild.frontend_web.pages.overview
const widget_sources = new _zeitbild.frontend_web.widgets.sources.class_widget_sources( const widget_sources = new _zeitbild.frontend_web.widgets.sources.class_widget_sources(
data, data,
{ {
"action_select": (entry) => { "action_open": (entry) => {
switch (entry.access_level) { switch (entry.access_level) {
case _zeitbild.frontend_web.type.enum_access_level.none: { case _zeitbild.frontend_web.type.enum_access_level.none: {
throw (new Error("this event should not be visible")); throw (new Error("this event should not be visible"));
@ -86,16 +88,14 @@ namespace _zeitbild.frontend_web.pages.overview
} }
} }
}, },
"action_toggle_visibility": (entry) => {
widget_weekview.toggle_visibility(entry.id);
},
} }
); );
if (compact) {
// do nothing
}
else {
await widget_sources.load(target_element.querySelector("#overview-pane-left")); await widget_sources.load(target_element.querySelector("#overview-pane-left"));
} }
} // events
// view
{ {
const get_entries = (from_pit, to_pit, calendar_ids) => _zeitbild.frontend_web.backend.events( const get_entries = (from_pit, to_pit, calendar_ids) => _zeitbild.frontend_web.backend.events(
from_pit, from_pit,
@ -139,10 +139,9 @@ namespace _zeitbild.frontend_web.pages.overview
} }
} }
}; };
const widget = ( // listview
compact {
? widget_listview = (
(
new _zeitbild.frontend_web.widgets.listview.class_widget_listview( new _zeitbild.frontend_web.widgets.listview.class_widget_listview(
get_entries, get_entries,
{ {
@ -162,9 +161,12 @@ namespace _zeitbild.frontend_web.pages.overview
}, },
} }
) )
) );
: await widget_listview.load(target_element.querySelector("#overview-pane-right-listview"));
( }
// weekview
{
widget_weekview = (
new _zeitbild.frontend_web.widgets.weekview.class_widget_weekview( new _zeitbild.frontend_web.widgets.weekview.class_widget_weekview(
get_entries, get_entries,
{ {
@ -184,9 +186,9 @@ namespace _zeitbild.frontend_web.pages.overview
}, },
} }
) )
)
); );
await widget.load(target_element.querySelector("#overview-pane-right")); await widget_weekview.load(target_element.querySelector("#overview-pane-right-weekview"));
}
} }
return Promise.resolve<void>(undefined); return Promise.resolve<void>(undefined);
}, },

View file

@ -5,6 +5,10 @@
<div id="overview-pane-left"> <div id="overview-pane-left">
</div> </div>
<div id="overview-pane-right"> <div id="overview-pane-right">
<div id="overview-pane-right-weekview">
</div>
<div id="overview-pane-right-listview">
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,73 +0,0 @@
.tableview-sources-entry:not(.tableview-sources-entry-active)
{
filter: saturate(0);
}
.calendar-cell
{
border: 1px solid hsl(0,0%,37.5%);
padding: 8px;
vertical-align: top;
}
.calendar-cell-day
{
width: 13.5%;
}
.calendar-cell-week
{
width: 5.5%;
}
.calendar-cell-regular
{
width: 13.5%;
height: 120px;
cursor: copy;
}
.calendar-cell-today
{
outline: 2px solid hsl(0, 0%, 100%);
}
.calendar-day
{
font-size: 0.75em;
cursor: help;
}
.calendar-events
{
margin: 0; padding: 0;
list-style-type: none;
}
.calendar-event_entry
{
margin: 4px;
padding: 4px;
border-radius: 2px;
font-size: 0.75em;
color: #FFF;
font-weight: bold;
}
.calendar-event_entry.access_level-none
,
.calendar-event_entry.access_level-view
{
/*
cursor: default;
*/
cursor: pointer;
}
.calendar-event_entry.access_level-edit
,
.calendar-event_entry.access_level-admin
{
cursor: pointer;
}

View file

@ -43,7 +43,7 @@ a:hover
transition: 1s ease color; transition: 1s ease color;
} }
input,select input,select,textarea
{ {
padding: 4px; padding: 4px;
} }
@ -55,7 +55,7 @@ button
cursor: pointer; cursor: pointer;
} }
input,select,button input,select,textarea,button
{ {
background-color: hsl(0, 0%, 0%); background-color: hsl(0, 0%, 0%);
color: hsl(0, 0%, 100%); color: hsl(0, 0%, 100%);

View file

@ -0,0 +1,13 @@
#calendar_add .plankton_input_group_field[rel="attributed"] > .plankton_input_list > .plankton_input_list_elements > .plankton_input_list_element
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#calendar_add .plankton_input_group_field[rel="attributed"] > .plankton_input_list > .plankton_input_list_elements > .plankton_input_list_element > .plankton_input_list_element_input > .plankton_input_group
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}

View file

@ -0,0 +1,8 @@
#event_add .plankton_input_group_field[rel="begin"] > .plankton_input_group
,
#event_add .plankton_input_group_field[rel="end"] > .plankton_input_soft_container > .plankton_input_soft_core_wrapper > .plankton_input_group
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}

View file

@ -0,0 +1,8 @@
#event_edit .plankton_input_group_field[rel="begin"] > .plankton_input_group
,
#event_edit .plankton_input_group_field[rel="end"] > .plankton_input_soft_container > .plankton_input_soft_core_wrapper > .plankton_input_group
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}

View file

@ -0,0 +1,63 @@
#overview-head
{
text-align: center;
font-weight: bold;
margin-bottom: 12px;
}
#overview-body
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#overview-body #overview-pane-left
{
flex-grow: 0;
flex-shrink: 1;
}
#overview-body #overview-pane-right
{
flex-grow: 1;
flex-shrink: 1;
}
@media all and (max-width: 950px)
{
#overview #overview-pane-left
{
flex-basis: 0%;
}
#overview #overview-pane-left > *
{
display: none;
}
#overview #overview-pane-right
{
flex-basis: 100%;
}
#overview #overview-pane-right-listview {}
#overview #overview-pane-right-weekview {display: none;}
}
@media not all and (max-width: 950px)
{
#overview #overview-pane-left
{
flex-basis: 12.5%;
}
#overview #overview-pane-right
{
flex-basis: 87.5%;
}
#overview #overview-pane-right-listview {display: none;}
#overview #overview-pane-right-weekview {}
}

View file

@ -1,60 +0,0 @@
#calendar_add .plankton_input_group_field[rel="attributed"] > .plankton_input_list > .plankton_input_list_elements > .plankton_input_list_element
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#calendar_add .plankton_input_group_field[rel="attributed"] > .plankton_input_list > .plankton_input_list_elements > .plankton_input_list_element > .plankton_input_list_element_input > .plankton_input_group
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#event_add .plankton_input_group_field[rel="begin"] > .plankton_input_group
,
#event_add .plankton_input_group_field[rel="end"] > .plankton_input_soft_container > .plankton_input_soft_core_wrapper > .plankton_input_group
,
#event_edit .plankton_input_group_field[rel="begin"] > .plankton_input_group
,
#event_edit .plankton_input_group_field[rel="end"] > .plankton_input_soft_container > .plankton_input_soft_core_wrapper > .plankton_input_group
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#overview-head
{
text-align: center;
font-weight: bold;
margin-bottom: 12px;
}
#overview-body
{
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
#overview-body:not(.compact) #overview-pane-left
{
flex-basis: 12.5%;
}
#overview-body:not(.compact) #overview-pane-right
{
flex-basis: 87.5%;
}
#overview-body.compact #overview-pane-left
{
flex-basis: 0%;
}
#overview-body.compact #overview-pane-right
{
flex-basis: 100%;
}

View file

@ -33,3 +33,14 @@
{ {
display: inline-block; display: inline-block;
} }
.plankton_input_group_field textarea
{
min-width: 350px;
min-height: 200px;
}
.plankton_input_soft_setter
{
vertical-align: top;
}

View file

@ -1,33 +1,13 @@
.sources .listview-add
{ {
margin: 0; /*
padding: 0; text-transform: capitalize;
list-style-type: none; */
font-size: 0.75em;
} }
.sources-entry .listview-add-hidden
{ {
margin: 8px; display: none;
padding: 4px;
cursor: pointer;
}
.weekview-controls
{
margin-bottom: 12px;
text-align: center;
}
.weekview-control
{
margin: 0 12px;
}
.weekview-table table
{
width: 100%;
border-collapse: collapse;
} }
.listview-entries .listview-entries
@ -67,6 +47,10 @@
content: "] "; content: "] ";
} }
.listview-entry-field-empty {
display: none;
}
.listview-entry-field:not(:last-child) .listview-entry-field:not(:last-child)
{ {
margin-bottom: 16px; margin-bottom: 16px;

View file

@ -0,0 +1,52 @@
.sources
{
margin: 0;
padding: 0;
list-style-type: none;
font-size: 0.75em;
}
.sources-entry
{
margin: 8px;
padding: 4px;
}
.sources-entry-head
{
cursor: pointer;
}
.sources-entry-body
{
display: block;
transition: max-height ease 0.5s;
}
.sources-entry-body > ul
{
list-style-type: none;
padding: 0;
margin-left: 8px;
margin-bottom: 8px;
}
.sources-entry-body > ul > li
{
/*
display: block;
*/
margin-top: 8px;
cursor: pointer;
}
.sources-entry:not(.sources-entry-open) > .sources-entry-head {}
.sources-entry:not(.sources-entry-open) > .sources-entry-body {max-height: 0; overflow: hidden;}
.sources-entry.sources-entry-open > .sources-entry-head {}
.sources-entry.sources-entry-open > .sources-entry-body {max-height: 240px; overflow: auto;}
.sources-entry-hidden
{
filter: saturate(0);
}

View file

@ -0,0 +1,96 @@
.weekview-controls
{
margin-bottom: 12px;
text-align: center;
}
.weekview-control
{
margin: 0 12px;
}
.weekview-table table
{
width: 100%;
border-collapse: collapse;
}
.weekview-cell
{
border: 1px solid hsl(0,0%,37.5%);
padding: 8px;
vertical-align: top;
}
.weekview-cell-day
{
width: 13.5%;
}
.weekview-cell-week
{
width: 5.5%;
}
.weekview-cell-regular
{
width: 13.5%;
height: 120px;
cursor: copy;
}
.weekview-cell-today
{
outline: 2px solid hsl(0, 0%, 100%);
}
.weekview-cell-hidden
{
display: none;
}
.weekview-day
{
font-size: 0.75em;
cursor: help;
}
.weekview-events
{
margin: 0; padding: 0;
list-style-type: none;
}
.weekview-event_entry
{
margin: 4px;
padding: 4px;
border-radius: 2px;
font-size: 0.75em;
color: #FFF;
font-weight: bold;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
min-width: 75px;
word-wrap: anywhere;
}
.weekview-event_entry.access_level-none
,
.weekview-event_entry.access_level-view
{
/*
cursor: default;
*/
cursor: pointer;
}
.weekview-event_entry.access_level-edit
,
.weekview-event_entry.access_level-admin
{
cursor: pointer;
}

View file

@ -124,6 +124,15 @@ namespace _zeitbild.frontend_web.widgets.listview
"widget-listview", "widget-listview",
"main", "main",
{ {
"add_href": "",
"add_label": lib_plankton.translate.get("widget.listview.add"),
"add_extra_classes": (
(! await _zeitbild.frontend_web.backend.is_logged_in())
?
" listview-add-hidden"
:
""
),
"entries": ( "entries": (
( (
await _zeitbild.frontend_web.helpers.promise_row<string>( await _zeitbild.frontend_web.helpers.promise_row<string>(
@ -133,19 +142,57 @@ namespace _zeitbild.frontend_web.widgets.listview
"widget-listview", "widget-listview",
"entry", "entry",
{ {
"name": entry.event_object.name, "name_value": entry.event_object.name,
"calendar": entry.calendar_name, "calendar_value": entry.calendar_name,
"when": _zeitbild.frontend_web.helpers.timespan_format(entry.event_object.begin, entry.event_object.end), "when_value": lib_plankton.pit.timespan_format(
"label_location": lib_plankton.translate.get("event.location"), entry.event_object.begin,
"location": ( entry.event_object.end,
{
"timezone_indicator": lib_plankton.translate.get("common.timezone_indicator"),
"adjust_to_ce": true,
"show_timezone": false,
}
),
"location_label": lib_plankton.translate.get("event.location"),
"location_extra_classes": (
(entry.event_object.location === null)
?
" listview-entry-field-empty"
:
""
),
"location_value": (
(entry.event_object.location === null) (entry.event_object.location === null)
? ?
"?" "?"
: :
entry.event_object.location entry.event_object.location
), ),
"label_description": lib_plankton.translate.get("event.description"), "link_label": lib_plankton.translate.get("event.link"),
"description": ( "link_extra_classes": (
(entry.event_object.link === null)
?
" listview-entry-field-empty"
:
""
),
"link_value": (
(entry.event_object.link === null)
?
"?"
:
entry.event_object.link
),
"link_action": lib_plankton.translate.get("common.open"),
"description_label": lib_plankton.translate.get("event.description"),
"description_extra_classes": (
(entry.event_object.description === null)
?
" listview-entry-field-empty"
:
""
),
"description_value": (
(entry.event_object.description === null) (entry.event_object.description === null)
? ?
"?" "?"
@ -196,11 +243,22 @@ namespace _zeitbild.frontend_web.widgets.listview
// control // control
{ {
target_element.querySelector(".listview-add").addEventListener(
"click",
(event) => {
event.preventDefault();
this.action_add();
}
);
target_element.querySelectorAll(".listview-entry").forEach( target_element.querySelectorAll(".listview-entry").forEach(
(element) => { (element) => {
element.addEventListener( element.addEventListener(
"click", "click",
() => { (event) => {
if ((event.target as Element).nodeName === "A") {
// do nothing
}
else {
const rel : string = element.getAttribute("rel"); const rel : string = element.getAttribute("rel");
const parts : Array<string> = rel.split("/"); const parts : Array<string> = rel.split("/");
const calendar_id : _zeitbild.frontend_web.type.calendar_id = parseInt(parts[0]); const calendar_id : _zeitbild.frontend_web.type.calendar_id = parseInt(parts[0]);
@ -225,6 +283,7 @@ namespace _zeitbild.frontend_web.widgets.listview
event_id, event_id,
); );
} }
}
); );
} }
); );

View file

@ -1,16 +1,20 @@
<li class="listview-entry" style="background-color: {{color}}" rel="{{rel}}"> <li class="listview-entry" style="background-color: {{color}}" rel="{{rel}}">
<span class="listview-entry-name">{{name}}</span> (<span class="listview-entry-calendar">{{calendar}}</span>) <span class="listview-entry-name">{{name_value}}</span> (<span class="listview-entry-calendar">{{calendar_value}}</span>)
<div class="listview-entry-field listview-entry-when"> <div class="listview-entry-field listview-entry-when">
<span class="listview-entry-value">{{when}}</span> <span class="listview-entry-value">{{when_value}}</span>
</div> </div>
<div class="listview-entry-field listview-entry-location"> <div class="listview-entry-field listview-entry-location{{location_extra_classes}}">
<span class="listview-entry-label">{{label_location}}</span> <span class="listview-entry-label">{{location_label}}</span>
<span class="listview-entry-value">{{location}}</span> <span class="listview-entry-value">{{location_value}}</span>
</div>
<div class="listview-entry-field listview-entry-link{{link_extra_classes}}">
<span class="listview-entry-label">{{link_label}}</span>
<a class="listview-entry-value" href="{{link_value}}" target="_blank">{{link_action}}</a>
</div> </div>
<!-- <!--
<div class="listview-entry-field listview-entry-description"> <div class="listview-entry-field listview-entry-description{{description_extra_classes}}">
<span class="listview-entry-label">{{label_description}}</span> <span class="listview-entry-label">{{description_label}}</span>
<span class="listview-entry-value">{{description}}</span> <span class="listview-entry-value">{{description_value}}</span>
</div> </div>
<div class="listview-entry-raw">{{raw}}</div> <div class="listview-entry-raw">{{raw}}</div>
--> -->

View file

@ -1,4 +1,5 @@
<div class="listview"> <div class="listview">
<a class="listview-add{{add_extra_classes}}" href="{{add_href}}">{{add_label}}</a>
<ul class="listview-entries"> <ul class="listview-entries">
{{entries}} {{entries}}
</ul> </ul>

View file

@ -27,7 +27,12 @@ namespace _zeitbild.frontend_web.widgets.sources
/** /**
*/ */
private action_select : ((entry : type_entry) => void); private action_open : ((entry : type_entry) => void);
/**
*/
private action_toggle_visibility : ((entry : type_entry) => void);
/** /**
@ -35,13 +40,15 @@ namespace _zeitbild.frontend_web.widgets.sources
public constructor( public constructor(
entries : Array<type_entry>, entries : Array<type_entry>,
options : { options : {
action_select ?: ((entry : type_entry) => void); action_open ?: ((entry : type_entry) => void);
action_toggle_visibility ?: ((entry : type_entry) => void);
} = {} } = {}
) )
{ {
options = Object.assign( options = Object.assign(
{ {
"action_select": (calendar_id) => {}, "action_open": (calendar_id) => {},
"action_toggle_visibility": (calendar_id) => {},
}, },
options options
); );
@ -55,7 +62,8 @@ namespace _zeitbild.frontend_web.widgets.sources
this.data[key] = entry; this.data[key] = entry;
} }
); );
this.action_select = options.action_select; this.action_open = options.action_open;
this.action_toggle_visibility = options.action_toggle_visibility;
} }
@ -82,9 +90,17 @@ namespace _zeitbild.frontend_web.widgets.sources
"entry", "entry",
{ {
"name": entry.name, "name": entry.name,
"label_toggle": lib_plankton.string.coin(
"{{show}}/{{hide}}",
{
"show": lib_plankton.translate.get("common.show"),
"hide": lib_plankton.translate.get("common.hide"),
}
),
"label_edit": lib_plankton.translate.get("common.edit"),
// "access_level": entry.access_level, // TODO // "access_level": entry.access_level, // TODO
// TODO centralize // TODO centralize
"color": lib_plankton.color.output_hex( "color_head": lib_plankton.color.output_hex(
lib_plankton.color.give_generic( lib_plankton.color.give_generic(
(entry.id - 1), (entry.id - 1),
{ {
@ -93,6 +109,15 @@ namespace _zeitbild.frontend_web.widgets.sources
} }
), ),
), ),
"color_body": lib_plankton.color.output_hex(
lib_plankton.color.give_generic(
(entry.id - 1),
{
"saturation": 0.375,
"value": 0.25,
}
),
),
"rel": key, "rel": key,
} }
); );
@ -104,14 +129,38 @@ namespace _zeitbild.frontend_web.widgets.sources
), ),
} }
); );
target_element.querySelectorAll(".sources-entry").forEach( target_element.querySelectorAll(".sources-entry-head").forEach(
(element) => { (element) => {
element.addEventListener( element.addEventListener(
"click", "click",
(event) => { (event) => {
const key : string = element.getAttribute("rel"); element.parentElement.classList.toggle("sources-entry-open");
}
);
}
);
target_element.querySelectorAll(".sources-entry-toggle").forEach(
(element) => {
element.addEventListener(
"click",
() => {
const key : string = element.parentElement.parentElement.parentElement.getAttribute("rel");
const entry : type_entry = this.data[key]; const entry : type_entry = this.data[key];
this.action_select(entry); element.parentElement.parentElement.parentElement.classList.toggle("sources-entry-hidden");
element.parentElement.parentElement.parentElement.classList.toggle("sources-entry-open", false);
this.action_toggle_visibility(entry);
}
);
}
);
target_element.querySelectorAll(".sources-entry-edit").forEach(
(element) => {
element.addEventListener(
"click",
(event) => {
const key : string = element.parentElement.parentElement.parentElement.getAttribute("rel");
const entry : type_entry = this.data[key];
this.action_open(entry);
} }
); );
} }

View file

@ -1 +1,11 @@
<li class="sources-entry" style="background-color: {{color}}" rel="{{rel}}">{{name}}</li> <li class="sources-entry" style="background-color: {{color_head}}" rel="{{rel}}">
<div class="sources-entry-head">
<span>{{name}}</span>
</div>
<div class="sources-entry-body" style="background-color: {{color_body}}">
<ul>
<li class="sources-entry-action sources-entry-toggle">{{label_toggle}}</li>
<li class="sources-entry-action sources-entry-edit">{{label_edit}}</li>
</ul>
</div>
</li>

View file

@ -127,65 +127,16 @@ namespace _zeitbild.frontend_web.widgets.weekview
lib_plankton.string.coin( lib_plankton.string.coin(
"{{label}}: {{value}}\n", "{{label}}: {{value}}\n",
{ {
"label": lib_plankton.translate.get("event.begin"), "label": lib_plankton.translate.get("event.when"),
"value": lib_plankton.string.coin( "value": lib_plankton.pit.timespan_format(
"{{hour}}:{{minute}}", event_object.begin,
event_object.end,
{ {
"hour": event_object.begin.time.hour.toFixed(0).padStart(2, "0"), "timezone_indicator": lib_plankton.translate.get("common.timezone_indicator"),
"minute": event_object.begin.time.minute.toFixed(0).padStart(2, "0"), "adjust_to_ce": true,
"show_timezone": true,
"omit_date": true,
} }
), // TODO: outsource
}
)
:
""
)
+
(
(event_object.end !== null)
?
lib_plankton.string.coin(
"{{label}}: {{value}}\n",
{
"label": lib_plankton.translate.get("event.end"),
"value": (
[
(
(
(event_object.end.date.year !== event_object.begin.date.year)
||
(event_object.end.date.month !== event_object.begin.date.month)
||
(event_object.end.date.day !== event_object.begin.date.day)
)
?
lib_plankton.string.coin(
"{{year}}-{{month}}-{{day}}",
{
"year": event_object.end.date.year.toFixed(0).padStart(4, "0"),
"month": event_object.end.date.month.toFixed(0).padStart(2, "0"),
"day": event_object.end.date.day.toFixed(0).padStart(2, "0"),
}
)
:
null
),
(
(event_object.end.time !== null)
?
lib_plankton.string.coin(
"{{hour}}:{{minute}}",
{
"hour": event_object.end.time.hour.toFixed(0).padStart(2, "0"),
"minute": event_object.end.time.minute.toFixed(0).padStart(2, "0"),
}
)
:
null
),
]
.filter(x => (x !== null))
.join(",")
), ),
} }
) )
@ -208,6 +159,22 @@ namespace _zeitbild.frontend_web.widgets.weekview
: :
"" ""
) )
+
(
(event_object.link !== null)
?
(
lib_plankton.string.coin(
"{{label}}: {{value}}\n",
{
"label": lib_plankton.translate.get("event.link"),
"value": event_object.link,
}
)
)
:
""
)
/* /*
+ +
( (
@ -422,7 +389,24 @@ namespace _zeitbild.frontend_web.widgets.weekview
.forEach( .forEach(
(entry) => { (entry) => {
const distance_seconds : int = ( const distance_seconds : int = (
lib_plankton.pit.from_datetime(entry.event_object.begin) lib_plankton.pit.from_datetime(
/**
* so that events without a start time will be put in the correct box
*/
{
"timezone_shift": entry.event_object.begin.timezone_shift,
"date": entry.event_object.begin.date,
"time": (
entry.event_object.begin.time
??
{
"hour": 12,
"minute": 0,
"second": 0
}
),
}
)
- -
from_pit from_pit
); );
@ -604,13 +588,13 @@ namespace _zeitbild.frontend_web.widgets.weekview
{ {
"extra_classes": ( "extra_classes": (
[""] [""]
.concat(cell.today ? ["calendar-cell-today"] : []) .concat(cell.today ? ["weekview-cell-today"] : [])
.join(" ") .join(" ")
), ),
"title": lib_plankton.call.convey( "title": lib_plankton.call.convey(
cell.pit, cell.pit,
[ [
lib_plankton.pit.to_datetime, lib_plankton.pit.to_datetime_ce,
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin( (x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
"{{year}}-{{month}}-{{day}}", "{{year}}-{{month}}-{{day}}",
{ {
@ -624,7 +608,7 @@ namespace _zeitbild.frontend_web.widgets.weekview
"day": lib_plankton.call.convey( "day": lib_plankton.call.convey(
cell.pit, cell.pit,
[ [
lib_plankton.pit.to_datetime, lib_plankton.pit.to_datetime_ce,
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin( (x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
"{{day}}", "{{day}}",
{ {
@ -638,7 +622,7 @@ namespace _zeitbild.frontend_web.widgets.weekview
"rel": lib_plankton.call.convey( "rel": lib_plankton.call.convey(
cell.pit, cell.pit,
[ [
lib_plankton.pit.to_datetime, lib_plankton.pit.to_datetime_ce,
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin( (x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
"{{year}}-{{month}}-{{day}}", "{{year}}-{{month}}-{{day}}",
{ {
@ -776,7 +760,7 @@ namespace _zeitbild.frontend_web.widgets.weekview
// do nothing // do nothing
} }
else { else {
context.querySelectorAll(".calendar-cell-regular").forEach( context.querySelectorAll(".weekview-cell-regular").forEach(
(element) => { (element) => {
element.addEventListener( element.addEventListener(
"click", "click",
@ -806,7 +790,7 @@ namespace _zeitbild.frontend_web.widgets.weekview
// do nothing // do nothing
} }
else { else {
context.querySelectorAll(".calendar-event_entry").forEach( context.querySelectorAll(".weekview-event_entry").forEach(
(element) => { (element) => {
element.addEventListener( element.addEventListener(
"click", "click",
@ -845,6 +829,28 @@ namespace _zeitbild.frontend_web.widgets.weekview
} }
/**
*/
public toggle_visibility(
calendar_id: _zeitbild.frontend_web.type.calendar_id
) : void
{
this.container.querySelectorAll(".weekview-event_entry").forEach(
(element) => {
const rel : string = element.getAttribute("rel");
const parts : Array<string> = rel.split("/");
const calendar_id_ : _zeitbild.frontend_web.type.calendar_id = parseInt(parts[0]);
if (! (calendar_id === calendar_id_)) {
// do nothing
}
else {
element.classList.toggle("weekview-cell-hidden");
}
}
);
}
/** /**
* [implementation] * [implementation]
*/ */
@ -860,6 +866,13 @@ namespace _zeitbild.frontend_web.widgets.weekview
"label_control_week": lib_plankton.translate.get("widget.weekview.controls.week"), "label_control_week": lib_plankton.translate.get("widget.weekview.controls.week"),
"label_control_count": lib_plankton.translate.get("widget.weekview.controls.count"), "label_control_count": lib_plankton.translate.get("widget.weekview.controls.count"),
"label_control_apply": lib_plankton.translate.get("widget.weekview.controls.apply"), "label_control_apply": lib_plankton.translate.get("widget.weekview.controls.apply"),
"label_weekday_monday": lib_plankton.translate.get("common.weekday.monday"),
"label_weekday_tuesday": lib_plankton.translate.get("common.weekday.tuesday"),
"label_weekday_wednesday": lib_plankton.translate.get("common.weekday.wednesday"),
"label_weekday_thursday": lib_plankton.translate.get("common.weekday.thursday"),
"label_weekday_friday": lib_plankton.translate.get("common.weekday.friday"),
"label_weekday_saturday": lib_plankton.translate.get("common.weekday.saturday"),
"label_weekday_sunday": lib_plankton.translate.get("common.weekday.sunday"),
} }
); );
this.container = target_element.querySelector(".weekview"); this.container = target_element.querySelector(".weekview");

View file

@ -19,13 +19,13 @@
<thead> <thead>
<tr> <tr>
<th class="calendar-cell"></th> <th class="calendar-cell"></th>
<th class="calendar-cell calendar-cell-day">Mo</th> <th class="calendar-cell calendar-cell-day">{{label_weekday_monday}}</th>
<th class="calendar-cell calendar-cell-day">Di</th> <th class="calendar-cell calendar-cell-day">{{label_weekday_tuesday}}</th>
<th class="calendar-cell calendar-cell-day">Mi</th> <th class="calendar-cell calendar-cell-day">{{label_weekday_wednesday}}</th>
<th class="calendar-cell calendar-cell-day">Do</th> <th class="calendar-cell calendar-cell-day">{{label_weekday_thursday}}</th>
<th class="calendar-cell calendar-cell-day">Fr</th> <th class="calendar-cell calendar-cell-day">{{label_weekday_friday}}</th>
<th class="calendar-cell calendar-cell-day">Sa</th> <th class="calendar-cell calendar-cell-day">{{label_weekday_saturday}}</th>
<th class="calendar-cell calendar-cell-day">So</th> <th class="calendar-cell calendar-cell-day">{{label_weekday_sunday}}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>

View file

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

View file

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

View file

@ -1,5 +1,5 @@
<tr> <tr>
<th class="calendar-cell calendar-cell-week"> <th class="weekview-cell weekview-cell-week">
{{week}} {{week}}
</th> </th>
{{cells}} {{cells}}

2
todo.md Normal file
View file

@ -0,0 +1,2 @@
- unterschiedliche Ansichten für Betrachten und Bearbeiten von Terminen und Kalendern
- zu verwendende Zeitzone nicht fest auf mitteleuropäische setzen

View file

@ -12,7 +12,7 @@ def main():
"-o", "-o",
"--output-directory", "--output-directory",
type = str, type = str,
default = "/tmp/zeitbild-frontend-web", default = "/tmp/dali",
metavar = "<output-directory>", metavar = "<output-directory>",
help = "output directory", help = "output directory",
) )

View file

@ -28,7 +28,7 @@ def main():
"--build-directory", "--build-directory",
type = str, type = str,
dest = "build_directory", dest = "build_directory",
default = "build", default = "/tmp/dali",
metavar = "<build-directory>", metavar = "<build-directory>",
help = "directory to where the build was put", help = "directory to where the build was put",
) )