[mod] pages

This commit is contained in:
Fenris Wolf 2024-09-26 16:47:01 +02:00
parent 8f3a4cb9db
commit fc0ee92094
19 changed files with 1112 additions and 1074 deletions

View file

@ -6,29 +6,6 @@ type int = number;
* @author fenris
*/
type float = number;
/**
* @author fenris
*/
type type_date = {
year: int;
month: int;
day: int;
};
/**
* @author fenris
*/
type type_time = {
hour: int;
minute: int;
second: int;
};
/**
* @author fenris
*/
type type_datetimeobject = {
date: type_date;
time: type_time;
};
declare class Buffer {
constructor(x: string, modifier?: string);
toString(modifier?: string): string;
@ -3141,6 +3118,94 @@ declare namespace lib_plankton.zoo_page {
export function start(): void;
export {};
}
declare namespace lib_plankton.pit {
/**
*/
type type_date = {
year: int;
month: int;
day: int;
};
/**
*/
type type_ywd = {
year: int;
week: int;
day: int;
};
/**
*/
type type_time = {
hour: int;
minute: int;
second: int;
};
/**
*/
type type_datetime = {
timezone_shift: int;
date: type_date;
time: (null | type_time);
};
/**
*/
type type_pit = int;
}
declare namespace lib_plankton.pit {
/**
*/
function date_object_get_week_of_year(date: Date): int;
/**
*/
function to_unix_timestamp(pit: type_pit): int;
/**
*/
function from_unix_timestamp(unix_timestamp: int): type_pit;
/**
*/
function to_date_object(pit: type_pit): Date;
/**
* @todo timezone
*/
function to_datetime(pit: type_pit, options?: {
timezone_shift?: int;
}): type_datetime;
/**
*/
function from_datetime(datetime: type_datetime): type_pit;
/**
*/
function is_before(pit: type_pit, reference: type_pit): boolean;
/**
*/
function is_between(pit: type_pit, reference_left: type_pit, reference_right: type_pit): boolean;
/**
*/
function shift_day(pit: type_pit, increment: int): type_pit;
/**
*/
function shift_week(pit: type_pit, increment: int): type_pit;
/**
*/
function trunc_week(pit: type_pit): type_pit;
/**
*/
function now(): type_pit;
/**
* @param year year according to specified timezone shift
* @param week week according to specified timezone shift
* @return the begin of the week (monday, 00:00)
*/
function from_ywd(ywd: type_ywd, options?: {
timezone_shift?: int;
}): type_pit;
/**
* @todo timezone
*/
function to_ywd(pit: type_pit, options?: {
timezone_shift?: int;
}): type_ywd;
}
declare namespace lib_plankton.zoo_input {
/**
* @author fenris
@ -3343,7 +3408,7 @@ declare namespace lib_plankton.zoo_input {
/**
* @author fenris
*/
class class_input_date implements interface_input<(null | type_date)> {
class class_input_date implements interface_input<(null | lib_plankton.pit.type_date)> {
/**
*/
private required;
@ -3362,11 +3427,11 @@ declare namespace lib_plankton.zoo_input {
/**
* [implementation]
*/
read(): Promise<(null | type_date)>;
read(): Promise<(null | lib_plankton.pit.type_date)>;
/**
* [implementation]
*/
write(value: (null | type_date)): Promise<void>;
write(value: (null | lib_plankton.pit.type_date)): Promise<void>;
}
}
declare namespace lib_plankton.zoo_input {
@ -3607,7 +3672,7 @@ declare namespace lib_plankton.zoo_input {
/**
* @author fenris
*/
class class_input_time implements interface_input<(null | type_time)> {
class class_input_time implements interface_input<(null | lib_plankton.pit.type_time)> {
/**
*/
private dom_input;
@ -3621,11 +3686,11 @@ declare namespace lib_plankton.zoo_input {
/**
* [implementation]
*/
read(): Promise<(null | type_time)>;
read(): Promise<(null | lib_plankton.pit.type_time)>;
/**
* [implementation]
*/
write(value: (null | type_time)): Promise<void>;
write(value: (null | lib_plankton.pit.type_time)): Promise<void>;
}
}
declare namespace lib_plankton.zoo_input {
@ -3658,6 +3723,31 @@ declare namespace lib_plankton.zoo_input {
write(value: type_record): 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_form {
/**
*/

View file

@ -8931,6 +8931,353 @@ var lib_plankton;
})(zoo_page = lib_plankton.zoo_page || (lib_plankton.zoo_page = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:pit«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:pit« 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:pit« 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:pit«. If not, see <http://www.gnu.org/licenses/>.
*/
/*
This file is part of »bacterio-plankton:pit«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
<info@greenscale.de>
»bacterio-plankton:pit« 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:pit« 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:pit«. If not, see <http://www.gnu.org/licenses/>.
*/
var lib_plankton;
(function (lib_plankton) {
var pit;
(function (pit_1) {
/**
*/
function date_object_get_week_of_year(date) {
let date_ = new Date(date.getTime());
date_.setHours(0, 0, 0, 0);
// Thursday in current week decides the year.
date_.setDate(date_.getDate() + 3 - (date_.getDay() + 6) % 7);
// January 4 is always in week 1.
let week1 = new Date(date_.getFullYear(), 0, 4);
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
return (1
+
Math.round((((date_.getTime() - week1.getTime()) / 86400000)
-
3
+
(week1.getDay() + 6) % 7)
/
7));
}
pit_1.date_object_get_week_of_year = date_object_get_week_of_year;
/**
*/
function to_unix_timestamp(pit) {
return pit;
}
pit_1.to_unix_timestamp = to_unix_timestamp;
/**
*/
function from_unix_timestamp(unix_timestamp) {
return unix_timestamp;
}
pit_1.from_unix_timestamp = from_unix_timestamp;
/**
*/
function to_date_object(pit) {
return (new Date(pit * 1000));
}
pit_1.to_date_object = to_date_object;
/**
*/
function from_date_object(date_object) {
return Math.round(date_object.getTime() / 1000);
}
/**
* @todo timezone
*/
function to_datetime(pit, options = {}) {
options = Object.assign({
"timezone_shift": 0,
}, options);
return lib_plankton.call.convey(pit, [
to_date_object,
(x) => x.getTime(),
(x) => (x + ((options.timezone_shift * (60 * 60)) * 1000)),
(x) => new Date(x),
x => x.toISOString(),
x => ({
"timezone_shift": options.timezone_shift,
"date": {
"year": parseInt(x.slice(0, 4)),
"month": parseInt(x.slice(5, 7)),
"day": parseInt(x.slice(8, 10)),
},
"time": {
"hour": parseInt(x.slice(11, 13)),
"minute": parseInt(x.slice(14, 16)),
"second": parseInt(x.slice(17, 19)),
},
})
]);
}
pit_1.to_datetime = to_datetime;
/**
*/
function from_datetime(datetime) {
return lib_plankton.call.convey(datetime, [
(x) => lib_plankton.string.coin("{{year}}-{{month}}-{{day}}T{{hour}}:{{minute}}:{{second}}.000+{{shift}}", {
"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"),
"hour": ((x.time !== null) ? x.time.hour : 0).toFixed(0).padStart(2, "0"),
"minute": ((x.time !== null) ? x.time.minute : 0).toFixed(0).padStart(2, "0"),
"second": ((x.time !== null) ? x.time.second : 0).toFixed(0).padStart(2, "0"),
"shift": (x.timezone_shift.toFixed(0).padStart(2, "0") + ":00"),
}),
x => (new Date(x)),
from_date_object,
]);
}
pit_1.from_datetime = from_datetime;
/**
*/
function is_before(pit, reference) {
return (pit < reference);
}
pit_1.is_before = is_before;
/**
*/
function is_after(pit, reference) {
return (pit > reference);
}
/**
*/
function is_between(pit, reference_left, reference_right) {
return (is_after(pit, reference_left)
&&
is_before(pit, reference_right));
}
pit_1.is_between = is_between;
/**
*/
function shift_hour(pit, increment) {
return (pit + (60 * 60 * increment));
}
/**
*/
function shift_day(pit, increment) {
return (pit + (60 * 60 * 24 * increment));
}
pit_1.shift_day = shift_day;
/**
*/
function shift_week(pit, increment) {
return (pit + (60 * 60 * 24 * 7 * increment));
}
pit_1.shift_week = shift_week;
/**
*/
function shift_year(pit, increment) {
return (pit + (60 * 60 * 24 * 365 * increment));
}
/**
*/
function trunc_minute(pit) {
const datetime_input = to_datetime(pit);
const datetime_output = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": datetime_input.date.month,
"day": datetime_input.date.day,
},
"time": {
"hour": ((datetime_input.time === null)
?
0
:
datetime_input.time.hour),
"minute": ((datetime_input.time === null)
?
0
:
datetime_input.time.minute),
"second": 0,
},
};
return from_datetime(datetime_output);
}
/**
*/
function trunc_hour(pit) {
const datetime_input = to_datetime(pit);
const datetime_output = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": datetime_input.date.month,
"day": datetime_input.date.day,
},
"time": {
"hour": ((datetime_input.time === null)
?
0
:
datetime_input.time.hour),
"minute": 0,
"second": 0,
},
};
return from_datetime(datetime_output);
}
/**
*/
function trunc_day(pit) {
const datetime_input = to_datetime(pit);
const datetime_output = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": datetime_input.date.month,
"day": datetime_input.date.day,
},
"time": {
"hour": 0,
"minute": 0,
"second": 0,
},
};
return from_datetime(datetime_output);
}
/**
*/
function trunc_week(pit) {
const date_object = to_date_object(pit);
return lib_plankton.call.convey(date_object.getDay(), [
(x) => ((x === 0) ? 7 : x),
(x) => (x - 1),
(x) => shift_day(pit, (-x)),
trunc_day
]);
}
pit_1.trunc_week = trunc_week;
/**
*/
function trunc_month(pit) {
const datetime_input = to_datetime(pit);
const datetime_output = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": datetime_input.date.month,
"day": 1,
},
"time": {
"hour": 0,
"minute": 0,
"second": 0,
},
};
return from_datetime(datetime_output);
}
/**
*/
function trunc_year(pit) {
const datetime_input = to_datetime(pit);
const datetime_output = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": 1,
"day": 1,
},
"time": {
"hour": 0,
"minute": 0,
"second": 0,
},
};
return from_datetime(datetime_output);
}
/**
*/
function now() {
return from_date_object(new Date(Date.now()));
}
pit_1.now = now;
/**
* @param year year according to specified timezone shift
* @param week week according to specified timezone shift
* @return the begin of the week (monday, 00:00)
*/
function from_ywd(ywd, options = {}) {
options = Object.assign({
"timezone_shift": 0,
}, options);
return lib_plankton.call.convey({
"timezone_shift": options.timezone_shift,
"date": {
"year": ywd.year,
"month": 1,
"day": 1,
},
"time": {
"hour": 0,
"minute": 0,
"second": 0
}
}, [
from_datetime,
(x) => shift_week(x, (ywd.week - 1)),
trunc_week,
(x) => shift_day(x, (ywd.day - 1)),
]);
}
pit_1.from_ywd = from_ywd;
/**
* @todo timezone
*/
function to_ywd(pit, options = {}) {
options = Object.assign({
"timezone_shift": 0,
}, options);
return lib_plankton.call.convey(pit, [
to_date_object,
x => ({
"year": x.getFullYear(),
"week": date_object_get_week_of_year(x),
"day": ((day => (day <= 0) ? 7 : day)(x.getDay())),
})
]);
}
pit_1.to_ywd = to_ywd;
})(pit = lib_plankton.pit || (lib_plankton.pit = {}));
})(lib_plankton || (lib_plankton = {}));
/*
This file is part of »bacterio-plankton:zoo-input«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
@ -10252,6 +10599,77 @@ var lib_plankton;
})(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) {
/**
*/
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-form«.
Copyright 2016-2024 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'

View file

@ -327,8 +327,8 @@ namespace _zeitbild.frontend_web.backend
* @todo prevent loops
*/
export async function events(
from_pit : _zeitbild.frontend_web.helpers.type_pit,
to_pit : _zeitbild.frontend_web.helpers.type_pit,
from_pit : lib_plankton.pit.type_pit,
to_pit : lib_plankton.pit.type_pit,
options : {
calendar_ids ?: (null | Array<_zeitbild.frontend_web.type.calendar_id>);
} = {}

View file

@ -65,472 +65,5 @@ namespace _zeitbild.frontend_web.helpers
}
return Promise.resolve<Array<type_result>>(results);
}
/**
*/
export function date_object_get_week_of_year(
date : Date
) : int
{
let date_ : Date = new Date(date.getTime());
date_.setHours(0, 0, 0, 0);
// Thursday in current week decides the year.
date_.setDate(date_.getDate() + 3 - (date_.getDay() + 6) % 7);
// January 4 is always in week 1.
let week1 : Date = new Date(date_.getFullYear(), 0, 4);
// Adjust to Thursday in week 1 and count number of weeks from date to week1.
return (
1
+
Math.round(
(
((date_.getTime() - week1.getTime()) / 86400000)
-
3
+
(week1.getDay() + 6) % 7
)
/
7
)
);
}
/**
* @todo unite with type_datetimeobject?
*/
export type type_datetime = {
timezone_shift : int;
date : type_date;
time : (
null
|
type_time
);
};
/**
* @todo timezone_shift
*/
function datetime_from_date_object(
date : Date,
options : {
timezone_shift ?: int;
} = {}
) : type_datetime
{
options = Object.assign(
{
"timezone_shift": 0,
},
options
);
const date_ : Date = lib_plankton.call.convey(
date,
[
(x : Date) => x.getTime(),
(x : int) => (x + (((options.timezone_shift as int) * (60 * 60)) * 1000)),
(x : int) => new Date(x),
]
);
const iso_string : string = date_.toISOString();
return {
"timezone_shift": (options.timezone_shift as int),
"date": {
"year": parseInt(iso_string.slice(0, 4)),
"month": parseInt(iso_string.slice(5, 7)),
"day": parseInt(iso_string.slice(8, 10)),
},
"time": {
"hour": parseInt(iso_string.slice(11, 13)),
"minute": parseInt(iso_string.slice(14, 16)),
"second": parseInt(iso_string.slice(17, 19)),
},
};
}
/**
* @todo negative shift?
*/
function datetime_to_date_object(
datetime : type_datetime
) : Date
{
const iso_string : string = lib_plankton.string.coin(
"{{year}}-{{month}}-{{day}}T{{hour}}:{{minute}}:{{second}}.000+{{shift}}",
{
"year": datetime.date.year.toFixed(0).padStart(4, "0"),
"month": datetime.date.month.toFixed(0).padStart(2, "0"),
"day": datetime.date.day.toFixed(0).padStart(2, "0"),
"hour": ((datetime.time !== null) ? datetime.time.hour : 0).toFixed(0).padStart(2, "0"),
"minute": ((datetime.time !== null) ? datetime.time.minute : 0).toFixed(0).padStart(2, "0"),
"second": ((datetime.time !== null) ? datetime.time.second : 0).toFixed(0).padStart(2, "0"),
"shift": (datetime.timezone_shift.toFixed(0).padStart(2, "0") + ":00"),
}
);
return (new Date(iso_string));
}
/**
*/
export type type_pit = int;
/**
*/
export function pit_to_date_object(
pit : type_pit
) : Date
{
return (new Date(pit * 1000));
}
/**
*/
function pit_from_date_object(
date_object : Date
) : type_pit
{
return Math.round(date_object.getTime() / 1000);
}
/**
*/
export function pit_now(
) : type_pit
{
return pit_from_date_object(new Date(Date.now()));
}
/**
* @todo timezone
*/
export function pit_to_datetime(
pit : type_pit,
options : {
timezone_shift ?: int
} = {}
) : type_datetime
{
options = Object.assign(
{
"timezone_shift": 0,
},
options
);
const date_object : Date = pit_to_date_object(pit);
return datetime_from_date_object(
date_object,
{
"timezone_shift": (options.timezone_shift as int),
}
);
}
/**
*/
export function pit_from_datetime(
datetime : type_datetime
) : type_pit
{
return lib_plankton.call.convey(
datetime,
[
datetime_to_date_object,
pit_from_date_object,
]
);
}
/**
*/
export function pit_is_before(
pit : type_pit,
reference : type_pit
) : boolean
{
return (pit < reference);
}
/**
*/
function pit_is_after(
pit : type_pit,
reference : type_pit
) : boolean
{
return (pit > reference);
}
/**
*/
export function pit_is_between(
pit : type_pit,
reference_left : type_pit,
reference_right : type_pit
) : boolean
{
return (
pit_is_after(pit, reference_left)
&&
pit_is_before(pit, reference_right)
);
}
/**
*/
function pit_shift_hour(
pit : type_pit,
increment : int
) : type_pit
{
return (pit + (60 * 60 * increment));
}
/**
*/
export function pit_shift_day(
pit : type_pit,
increment : int
) : type_pit
{
return (pit + (60 * 60 * 24 * increment));
}
/**
*/
export function pit_shift_week(
pit : type_pit,
increment : int
) : type_pit
{
return (pit + (60 * 60 * 24 * 7 * increment));
}
/**
*/
function pit_shift_year(
pit : type_pit,
increment : int
) : type_pit
{
return (pit + (60 * 60 * 24 * 365 * increment));
}
/**
*/
function pit_trunc_minute(
pit : type_pit
) : type_pit
{
const datetime_input : type_datetime = pit_to_datetime(pit);
const datetime_output : type_datetime = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": datetime_input.date.month,
"day": datetime_input.date.day,
},
"time": {
"hour": (
(datetime_input.time === null)
?
0
:
datetime_input.time.hour
),
"minute": (
(datetime_input.time === null)
?
0
:
datetime_input.time.minute
),
"second": 0,
},
};
return pit_from_datetime(datetime_output);
}
/**
*/
function pit_trunc_hour(
pit : type_pit
) : type_pit
{
const datetime_input : type_datetime = pit_to_datetime(pit);
const datetime_output : type_datetime = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": datetime_input.date.month,
"day": datetime_input.date.day,
},
"time": {
"hour": (
(datetime_input.time === null)
?
0
:
datetime_input.time.hour
),
"minute": 0,
"second": 0,
},
};
return pit_from_datetime(datetime_output);
}
/**
*/
function pit_trunc_day(
pit : type_pit
) : type_pit
{
const datetime_input : type_datetime = pit_to_datetime(pit);
const datetime_output : type_datetime = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": datetime_input.date.month,
"day": datetime_input.date.day,
},
"time": {
"hour": 0,
"minute": 0,
"second": 0,
},
};
return pit_from_datetime(datetime_output);
}
/**
*/
export function pit_trunc_week(
pit : type_pit
) : type_pit
{
const date_object : Date = pit_to_date_object(pit);
return lib_plankton.call.convey(
date_object.getDay(),
[
(x : int) => ((x === 0) ? 7 : x),
(x : int) => (x - 1),
(x : int) => pit_shift_day(pit, (-x)),
pit_trunc_day
]
);
}
/**
*/
function pit_trunc_month(
pit : type_pit
) : type_pit
{
const datetime_input : type_datetime = pit_to_datetime(pit);
const datetime_output : type_datetime = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": datetime_input.date.month,
"day": 1,
},
"time": {
"hour": 0,
"minute": 0,
"second": 0,
},
};
return pit_from_datetime(datetime_output);
}
/**
*/
function pit_trunc_year(
pit : type_pit
) : type_pit
{
const datetime_input : type_datetime = pit_to_datetime(pit);
const datetime_output : type_datetime = {
"timezone_shift": 0,
"date": {
"year": datetime_input.date.year,
"month": 1,
"day": 1,
},
"time": {
"hour": 0,
"minute": 0,
"second": 0,
},
};
return pit_from_datetime(datetime_output);
}
/**
* @param year year according to specified timezone shift
* @param week week according to specified timezone shift
* @return the begin of the week (monday, 00:00)
*/
export function pit_from_year_and_week(
year : int,
week : int,
options : {
timezone_shift ?: int;
} = {}
) : type_pit
{
options = Object.assign(
{
"timezone_shift": 0,
},
options
);
return lib_plankton.call.convey(
{
"timezone_shift": (options.timezone_shift as int),
"date": {
"year": year,
"month": 1,
"day": 1,
},
"time": {
"hour": 0,
"minute": 0,
"second": 0
}
},
[
pit_from_datetime,
(x : type_pit) => pit_shift_week(x, (week - 1)),
pit_trunc_week,
]
);
}
}

View file

@ -1,78 +1,4 @@
/**
*/
class class_input_datetime implements lib_plankton.zoo_input.interface_input<_zeitbild.frontend_web.helpers.type_datetime>
{
/**
*/
private core : lib_plankton.zoo_input.class_input_group<_zeitbild.frontend_web.helpers.type_datetime>;
/**
*/
public constructor(
prefix : string
)
{
this.core = new lib_plankton.zoo_input.class_input_group<_zeitbild.frontend_web.helpers.type_datetime>(
[
{
"name": "timezone_shift",
"input": new lib_plankton.zoo_input.class_input_number(
),
"label": (prefix + lib_plankton.translate.get("common.timezone_shift")),
},
{
"name": "date",
"input": new lib_plankton.zoo_input.class_input_date(
),
"label": (prefix + lib_plankton.translate.get("common.date")),
},
{
"name": "time",
"input": new lib_plankton.zoo_input.class_input_soft<type_time>(
new lib_plankton.zoo_input.class_input_time(
)
),
"label": (prefix + lib_plankton.translate.get("common.time")),
},
]
);
}
/**
*/
public async setup(
parent : HTMLElement
) : Promise<void>
{
return this.core.setup(parent);
}
/**
*/
public async read(
) : Promise<_zeitbild.frontend_web.helpers.type_datetime>
{
return this.core.read();
}
/**
*/
public async write(
value : _zeitbild.frontend_web.helpers.type_datetime
) : Promise<void>
{
return this.core.write(value);
}
}
/**
*/
namespace _zeitbild.frontend_web
@ -103,464 +29,6 @@ namespace _zeitbild.frontend_web
lib_plankton.zoo_page.init(
document.querySelector("main"),
{
"pool": {
"login": async (parameters, target_element) => {
const preparation : {kind : string; data : any;} = await _zeitbild.frontend_web.backend.session_prepare(
);
switch (preparation.kind) {
case "internal": {
target_element.innerHTML = await _zeitbild.frontend_web.helpers.template_coin(
"login",
{
}
);
const form : lib_plankton.zoo_form.class_form<
{name : string; password : string;},
{name : string; password : string;}
> = new lib_plankton.zoo_form.class_form<
{name : string; password : string;},
{name : string; password : string;}
>(
x => x,
x => x,
new lib_plankton.zoo_input.class_input_group<
{name : string; password : string;}
>(
[
{
"name": "name",
"input": new lib_plankton.zoo_input.class_input_text(),
"label": lib_plankton.translate.get("page.login.internal.name"),
},
{
"name": "password",
"input": new lib_plankton.zoo_input.class_input_password(),
"label": lib_plankton.translate.get("page.login.internal.password"),
},
]
),
[
{
"label": lib_plankton.translate.get("page.login.internal.do"),
"target": "submit",
"procedure": async (get_value, get_representation) => {
const value : any = await get_value();
try {
await _zeitbild.frontend_web.backend.session_begin(
value.name,
value.password
);
lib_plankton.zoo_page.set(
{
"name": "events",
"parameters": {}
}
);
}
catch (error) {
lib_plankton.zoo_page.set(
{
"name": "login",
"parameters": {
"name": value.name,
}
}
);
}
}
},
]
);
await form.setup(document.querySelector("#login"));
await form.input_write(
{
"name": (parameters.name ?? ""),
"password": "",
}
);
break;
}
case "oidc": {
let element_a : HTMLElement = document.createElement("a");;
element_a.textContent = lib_plankton.string.coin(
lib_plankton.translate.get("page.login.oidc.via"),
{
"title": preparation.data.label,
}
);
element_a.setAttribute("href", preparation.data.url);
target_element.innerHTML = "";
target_element.appendChild(element_a);
break;
}
default: {
break;
}
}
},
"oidc_finish": async (parameters, target_element) => {
await _zeitbild.frontend_web.backend.set_session_key(parameters["session_key"]);
lib_plankton.zoo_page.set(
{
"name": "events",
"parameters": {}
}
);
},
"logout": async (parameters, target_element) => {
await _zeitbild.frontend_web.backend.session_end(
);
lib_plankton.zoo_page.set(
{
"name": "login",
"parameters": {
}
}
);
},
"calendar_add": async (parameters, target_element) => {
target_element.innerHTML = await _zeitbild.frontend_web.helpers.template_coin(
"calendar_add",
{
"label": lib_plankton.translate.get("page.calendar_add.title")
}
);
const form : lib_plankton.zoo_form.class_form<
_zeitbild.frontend_web.type.calendar_object,
{
name : string;
access_default_level : string;
resource_kind : string;
}
> = new lib_plankton.zoo_form.class_form<
_zeitbild.frontend_web.type.calendar_object,
{
name : string;
access_default_level : string;
resource_kind : string;
}
>(
(calendar_object) => ({
"name": calendar_object.name,
"access_default_level": (() => {
switch (calendar_object.access.default_level) {
case _zeitbild.frontend_web.type.enum_access_level.none: return "none";
case _zeitbild.frontend_web.type.enum_access_level.view: return "view";
case _zeitbild.frontend_web.type.enum_access_level.edit: return "edit";
case _zeitbild.frontend_web.type.enum_access_level.admin: return "admin";
}
}) (),
"resource_kind": calendar_object.resource.kind,
}),
(raw) => ({
"name": raw.name,
"access": {
"default_level": (() => {
switch (raw.access_default_level) {
case "none": return _zeitbild.frontend_web.type.enum_access_level.none;
case "view": return _zeitbild.frontend_web.type.enum_access_level.view;
case "edit": return _zeitbild.frontend_web.type.enum_access_level.edit;
case "admin": return _zeitbild.frontend_web.type.enum_access_level.admin;
}
}) (),
"attributed": lib_plankton.map.hashmap.implementation_map(
lib_plankton.map.hashmap.make(
x => x.toFixed(0)
)
),
},
"resource": (() => {
switch (raw.resource_kind) {
case "local": {
return {
"kind": "local",
"data": {
"events": [],
}
};
break;
}
case "caldav": {
return {
"kind": "caldav",
"data": {
"url": "", // TODO
"read_only": true, // TODO
}
};
break;
}
default: {
throw (new Error("invalid resource kind: " + raw.resource_kind));
break;
}
}
}) (),
}),
new lib_plankton.zoo_input.class_input_group<any>(
[
{
"name": "name",
"input": new lib_plankton.zoo_input.class_input_text(),
"label": lib_plankton.translate.get("calendar.name")
},
{
"name": "access_default_level",
"input": new lib_plankton.zoo_input.class_input_selection(
[
{
"value": "none",
"label": lib_plankton.translate.get("access_level.none"),
},
{
"value": "view",
"label": lib_plankton.translate.get("access_level.view")
},
{
"value": "edit",
"label": lib_plankton.translate.get("access_level.edit")
},
{
"value": "admin",
"label": lib_plankton.translate.get("access_level.admin")
},
]
),
"label": lib_plankton.string.coin(
"{{default_level}}",
{
"head": lib_plankton.translate.get("calendar.access.access"),
"default_level": lib_plankton.translate.get("calendar.access.default_level"),
}
)
},
{
"name": "resource_kind",
"input": new lib_plankton.zoo_input.class_input_selection(
[
{
"value": "local",
"label": lib_plankton.translate.get("resource.kinds.local.title")
},
{
"value": "caldav",
"label": lib_plankton.translate.get("resource.kinds.caldav.title")
},
]
),
"label": lib_plankton.translate.get("resource.kind")
},
]
),
[
{
"label": lib_plankton.translate.get("page.calendar_add.actions.do"),
"target": "submit",
"procedure": async (get_value, get_representation) => {
const value : any = await get_value();
try {
await _zeitbild.frontend_web.backend.calendar_add(
value
);
lib_plankton.zoo_page.set(
{
"name": "events",
"parameters": {}
}
);
}
catch (error) {
// do nothing
/*
lib_plankton.zoo_page.set(
{
"name": "event_add",
"parameters": {
}
}
);
*/
}
}
},
]
);
await form.setup(document.querySelector("#calendar_add_form"));
},
"event_add": async (parameters, target_element) => {
const calendar_id : int = parseInt(parameters["calendar_id"]);
target_element.innerHTML = await _zeitbild.frontend_web.helpers.template_coin(
"event_add",
{
"label": lib_plankton.translate.get("page.event_add.title")
}
);
const form : lib_plankton.zoo_form.class_form<
{
calendar_id : _zeitbild.frontend_web.type.calendar_id;
event_object : _zeitbild.frontend_web.type.event_object;
},
{
calendar_id : string;
name : string;
begin : _zeitbild.frontend_web.helpers.type_datetime;
end : (null | _zeitbild.frontend_web.helpers.type_datetime);
location : (null | string);
description : (null | string);
}
> = new lib_plankton.zoo_form.class_form<
{
calendar_id : _zeitbild.frontend_web.type.calendar_id;
event_object : _zeitbild.frontend_web.type.event_object;
},
{
calendar_id : string;
name : string;
begin : _zeitbild.frontend_web.helpers.type_datetime;
end : (null | _zeitbild.frontend_web.helpers.type_datetime);
location : (null | string);
description : (null | string);
}
>(
(value) => ({
"calendar_id": value.calendar_id.toFixed(0),
"name": value.event_object.name,
"begin": value.event_object.begin,
"end": value.event_object.end,
"location": value.event_object.location,
"description": value.event_object.description,
}),
(representation) => ({
"calendar_id": parseInt(representation.calendar_id),
"event_object": {
"name": representation.name,
"begin": representation.begin,
"end": representation.end,
"location": representation.location,
"description": representation.description,
}
}),
new lib_plankton.zoo_input.class_input_group<any>(
[
{
"name": "calendar_id",
"input": new lib_plankton.zoo_input.class_input_selection(
(await _zeitbild.frontend_web.backend.calendar_list())
.filter(
(entry) => (["edit","admin"].includes(entry.access_level))
)
.map(
(entry) => ({
"value": entry.id.toFixed(0),
"label": entry.name,
})
)
),
"label": lib_plankton.translate.get("calendar.calendar")
},
{
"name": "name",
"input": new lib_plankton.zoo_input.class_input_text(
),
"label": lib_plankton.translate.get("event.name")
},
{
"name": "begin",
"input": new class_input_datetime(
""
),
"label": lib_plankton.translate.get("event.begin")
},
{
"name": "end",
"input": new lib_plankton.zoo_input.class_input_soft<_zeitbild.frontend_web.helpers.type_datetime>(
new class_input_datetime(
""
)
),
"label": lib_plankton.translate.get("event.end")
},
{
"name": "location",
"input": new lib_plankton.zoo_input.class_input_soft<string>(
new lib_plankton.zoo_input.class_input_text(
)
),
"label": lib_plankton.translate.get("event.location")
},
{
"name": "description",
"input": new lib_plankton.zoo_input.class_input_soft<string>(
new lib_plankton.zoo_input.class_input_text(
)
),
"label": lib_plankton.translate.get("event.description")
},
]
),
[
{
"label": lib_plankton.translate.get("page.event_add.actions.do"),
"target": "submit",
"procedure": async (get_value, get_representation) => {
const value : any = await get_value();
try {
await _zeitbild.frontend_web.backend.calendar_event_add(
value.calendar_id,
value.event_object
);
lib_plankton.zoo_page.set(
{
"name": "events",
"parameters": {}
}
);
}
catch (error) {
// do nothing
/*
lib_plankton.zoo_page.set(
{
"name": "event_add",
"parameters": {
}
}
);
*/
}
}
},
]
);
/*
await form.write(
{
"calendar_id": parameters["calendar_id"],
}
);
*/
await form.setup(document.querySelector("#event_add_form"));
},
"events": async (parameters, target_element) => {
const content = await _zeitbild.frontend_web.view.calendar_view_table_html(
{
"calendar_ids": null,
// TODO
"from": {
"year": 2024,
"week": 37
},
// TODO
"to": {
"year": 2024,
"week": 43
},
"timezone_shift": /*conf.timezone_shift*/0,
}
);
target_element.innerHTML = content;
},
},
"fallback": {
"name": "login",
"parameters": {}

View file

@ -35,11 +35,11 @@ namespace _zeitbild.frontend_web.type
*/
export type event_object = {
name : string;
begin : _zeitbild.frontend_web.helpers.type_datetime;
begin : lib_plankton.pit.type_datetime;
end : (
null
|
_zeitbild.frontend_web.helpers.type_datetime
lib_plankton.pit.type_datetime
);
location : (
null

View file

@ -161,7 +161,7 @@ namespace _zeitbild.frontend_web.view
week : int;
data : Array<
{
pit : _zeitbild.frontend_web.helpers.type_pit;
pit : lib_plankton.pit.type_pit;
entries : Array<
{
calendar_id : _zeitbild.frontend_web.type.calendar_id;
@ -176,17 +176,23 @@ namespace _zeitbild.frontend_web.view
}
>
{
const now_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_now();
const from_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_from_year_and_week(
(from as {year : int; week : int}).year,
(from as {year : int; week : int}).week,
const now_pit : lib_plankton.pit.type_pit = lib_plankton.pit.now();
const from_pit : lib_plankton.pit.type_pit = lib_plankton.pit.from_ywd(
{
"year": (from as {year : int; week : int}).year,
"week": (from as {year : int; week : int}).week,
"day": 1,
},
{
"timezone_shift": (timezone_shift as int),
}
);
const to_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_from_year_and_week(
(to as {year : int; week : int}).year,
(to as {year : int; week : int}).week,
const to_pit : lib_plankton.pit.type_pit = lib_plankton.pit.from_ywd(
{
"year": (to as {year : int; week : int}).year,
"week": (to as {year : int; week : int}).week,
"day": 1,
},
{
"timezone_shift": (timezone_shift as int),
}
@ -218,7 +224,7 @@ namespace _zeitbild.frontend_web.view
week : int;
data : Array<
{
pit : _zeitbild.frontend_web.helpers.type_pit;
pit : lib_plankton.pit.type_pit;
entries : Array<
{
calendar_id : _zeitbild.frontend_web.type.calendar_id;
@ -255,7 +261,7 @@ namespace _zeitbild.frontend_web.view
};
let row : Array<
{
pit : _zeitbild.frontend_web.helpers.type_pit;
pit : lib_plankton.pit.type_pit;
entries : Array<
{
calendar_id : _zeitbild.frontend_web.type.calendar_id;
@ -267,12 +273,12 @@ namespace _zeitbild.frontend_web.view
> = [];
let day : int = 0;
while (true) {
const pit_current : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_shift_day(
const pit_current : lib_plankton.pit.type_pit = lib_plankton.pit.shift_day(
from_pit,
day
);
if (
_zeitbild.frontend_web.helpers.pit_is_before(
lib_plankton.pit.is_before(
pit_current,
to_pit
)
@ -317,7 +323,7 @@ namespace _zeitbild.frontend_web.view
.forEach(
(entry) => {
const distance_seconds : int = (
_zeitbild.frontend_web.helpers.pit_from_datetime(entry.event.begin)
lib_plankton.pit.from_datetime(entry.event.begin)
-
from_pit
);
@ -381,30 +387,24 @@ namespace _zeitbild.frontend_web.view
} = {}
) : Promise<string>
{
const now_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_now();
const now_pit : lib_plankton.pit.type_pit = lib_plankton.pit.now();
options = Object.assign(
{
"calendar_ids": null,
"from": lib_plankton.call.convey(
now_pit,
[
(x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_week(x, -1),
_zeitbild.frontend_web.helpers.pit_to_date_object,
(x : Date) => ({
"year": x.getFullYear(),
"week": _zeitbild.frontend_web.helpers.date_object_get_week_of_year(x),
})
(x : lib_plankton.pit.type_pit) => lib_plankton.pit.shift_week(x, -1),
lib_plankton.pit.to_ywd,
x => ({"year": x.year, "week": x.week}),
]
),
"to": lib_plankton.call.convey(
now_pit,
[
(x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_week(x, +4),
_zeitbild.frontend_web.helpers.pit_to_date_object,
(x : Date) => ({
"year": x.getFullYear(),
"week": _zeitbild.frontend_web.helpers.date_object_get_week_of_year(x),
})
(x : lib_plankton.pit.type_pit) => lib_plankton.pit.shift_week(x, +4),
lib_plankton.pit.to_ywd,
x => ({"year": x.year, "week": x.week}),
]
),
"timezone_shift": 0,
@ -423,7 +423,7 @@ namespace _zeitbild.frontend_web.view
week : int;
data : Array<
{
pit : _zeitbild.frontend_web.helpers.type_pit;
pit : lib_plankton.pit.type_pit;
entries : Array<
{
calendar_id : _zeitbild.frontend_web.type.calendar_id;
@ -515,8 +515,8 @@ namespace _zeitbild.frontend_web.view
"title": lib_plankton.call.convey(
cell.pit,
[
_zeitbild.frontend_web.helpers.pit_to_datetime,
(x : _zeitbild.frontend_web.helpers.type_datetime) => lib_plankton.string.coin(
lib_plankton.pit.to_datetime,
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
"{{year}}-{{month}}-{{day}}",
{
"year": x.date.year.toFixed(0).padStart(4, "0"),
@ -529,8 +529,8 @@ namespace _zeitbild.frontend_web.view
"day": lib_plankton.call.convey(
cell.pit,
[
_zeitbild.frontend_web.helpers.pit_to_datetime,
(x : _zeitbild.frontend_web.helpers.type_datetime) => lib_plankton.string.coin(
lib_plankton.pit.to_datetime,
(x : lib_plankton.pit.type_datetime) => lib_plankton.string.coin(
"{{day}}",
{
"year": x.date.year.toFixed(0).padStart(4, "0"),
@ -584,8 +584,8 @@ namespace _zeitbild.frontend_web.view
async function calendar_view_list_data(
calendar_ids : Array<_zeitbild.frontend_web.type.calendar_id>,
options : {
from ?: _zeitbild.frontend_web.helpers.type_pit;
to ?: _zeitbild.frontend_web.helpers.type_pit;
from ?: lib_plankton.pit.type_pit;
to ?: lib_plankton.pit.type_pit;
timezone_shift ?: int;
} = {}
) : Promise<
@ -597,19 +597,19 @@ namespace _zeitbild.frontend_web.view
>
>
{
const now_pit : _zeitbild.frontend_web.helpers.type_pit = _zeitbild.frontend_web.helpers.pit_now();
const now_pit : lib_plankton.pit.type_pit = lib_plankton.pit.now();
options = Object.assign(
{
"from": lib_plankton.call.convey(
now_pit,
[
(x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_day(x, -1),
(x : lib_plankton.pit.type_pit) => lib_plankton.pit.shift_day(x, -1),
]
),
"to": lib_plankton.call.convey(
now_pit,
[
(x : _zeitbild.frontend_web.helpers.type_pit) => _zeitbild.frontend_web.helpers.pit_shift_week(x, +4),
(x : lib_plankton.pit.type_pit) => lib_plankton.pit.shift_week(x, +4),
]
),
"timezone_shift": 0,
@ -623,8 +623,8 @@ namespace _zeitbild.frontend_web.view
event : _zeitbild.frontend_web.type.event_object;
}
> = await _zeitbild.frontend_web.backend.events(
(options.from as _zeitbild.frontend_web.helpers.type_pit),
(options.to as _zeitbild.frontend_web.helpers.type_pit),
(options.from as lib_plankton.pit.type_pit),
(options.to as lib_plankton.pit.type_pit),
{
"calendar_ids": calendar_ids,
}
@ -632,9 +632,9 @@ namespace _zeitbild.frontend_web.view
// TODO: optimize
entries.sort(
(entry_1, entry_2) => (
_zeitbild.frontend_web.helpers.pit_from_datetime(entry_1.event.begin)
lib_plankton.pit.from_datetime(entry_1.event.begin)
-
_zeitbild.frontend_web.helpers.pit_from_datetime(entry_2.event.begin)
lib_plankton.pit.from_datetime(entry_2.event.begin)
)
);
@ -647,8 +647,8 @@ namespace _zeitbild.frontend_web.view
export async function calendar_view_list_html(
calendar_ids : Array<_zeitbild.frontend_web.type.calendar_id>,
options : {
from ?: _zeitbild.frontend_web.helpers.type_pit;
to ?: _zeitbild.frontend_web.helpers.type_pit;
from ?: lib_plankton.pit.type_pit;
to ?: lib_plankton.pit.type_pit;
timezone_shift ?: int;
} = {}
) : Promise<string>

View file

@ -0,0 +1,180 @@
namespace _zeitbild.frontend_web.pages
{
/**
*/
lib_plankton.zoo_page.register(
"calendar_add",
async (parameters, target_element) => {
target_element.innerHTML = await _zeitbild.frontend_web.helpers.template_coin(
"calendar_add",
{
"label": lib_plankton.translate.get("page.calendar_add.title")
}
);
const form : lib_plankton.zoo_form.class_form<
_zeitbild.frontend_web.type.calendar_object,
{
name : string;
access_default_level : string;
resource_kind : string;
}
> = new lib_plankton.zoo_form.class_form<
_zeitbild.frontend_web.type.calendar_object,
{
name : string;
access_default_level : string;
resource_kind : string;
}
>(
(calendar_object) => ({
"name": calendar_object.name,
"access_default_level": (() => {
switch (calendar_object.access.default_level) {
case _zeitbild.frontend_web.type.enum_access_level.none: return "none";
case _zeitbild.frontend_web.type.enum_access_level.view: return "view";
case _zeitbild.frontend_web.type.enum_access_level.edit: return "edit";
case _zeitbild.frontend_web.type.enum_access_level.admin: return "admin";
}
}) (),
"resource_kind": calendar_object.resource.kind,
}),
(raw) => ({
"name": raw.name,
"access": {
"default_level": (() => {
switch (raw.access_default_level) {
case "none": return _zeitbild.frontend_web.type.enum_access_level.none;
case "view": return _zeitbild.frontend_web.type.enum_access_level.view;
case "edit": return _zeitbild.frontend_web.type.enum_access_level.edit;
case "admin": return _zeitbild.frontend_web.type.enum_access_level.admin;
}
}) (),
"attributed": lib_plankton.map.hashmap.implementation_map(
lib_plankton.map.hashmap.make(
x => x.toFixed(0)
)
),
},
"resource": (() => {
switch (raw.resource_kind) {
case "local": {
return {
"kind": "local",
"data": {
"events": [],
}
};
break;
}
case "caldav": {
return {
"kind": "caldav",
"data": {
"url": "", // TODO
"read_only": true, // TODO
}
};
break;
}
default: {
throw (new Error("invalid resource kind: " + raw.resource_kind));
break;
}
}
}) (),
}),
new lib_plankton.zoo_input.class_input_group<any>(
[
{
"name": "name",
"input": new lib_plankton.zoo_input.class_input_text(),
"label": lib_plankton.translate.get("calendar.name")
},
{
"name": "access_default_level",
"input": new lib_plankton.zoo_input.class_input_selection(
[
{
"value": "none",
"label": lib_plankton.translate.get("access_level.none"),
},
{
"value": "view",
"label": lib_plankton.translate.get("access_level.view")
},
{
"value": "edit",
"label": lib_plankton.translate.get("access_level.edit")
},
{
"value": "admin",
"label": lib_plankton.translate.get("access_level.admin")
},
]
),
"label": lib_plankton.string.coin(
"{{default_level}}",
{
"head": lib_plankton.translate.get("calendar.access.access"),
"default_level": lib_plankton.translate.get("calendar.access.default_level"),
}
)
},
{
"name": "resource_kind",
"input": new lib_plankton.zoo_input.class_input_selection(
[
{
"value": "local",
"label": lib_plankton.translate.get("resource.kinds.local.title")
},
{
"value": "caldav",
"label": lib_plankton.translate.get("resource.kinds.caldav.title")
},
]
),
"label": lib_plankton.translate.get("resource.kind")
},
]
),
[
{
"label": lib_plankton.translate.get("page.calendar_add.actions.do"),
"target": "submit",
"procedure": async (get_value, get_representation) => {
const value : any = await get_value();
try {
await _zeitbild.frontend_web.backend.calendar_add(
value
);
lib_plankton.zoo_page.set(
{
"name": "events",
"parameters": {}
}
);
}
catch (error) {
// do nothing
/*
lib_plankton.zoo_page.set(
{
"name": "event_add",
"parameters": {
}
}
);
*/
}
}
},
]
);
await form.setup(document.querySelector("#calendar_add_form"));
return Promise.resolve<void>(undefined);
}
);
}

View file

@ -0,0 +1 @@

View file

@ -0,0 +1,163 @@
namespace _zeitbild.frontend_web.pages
{
/**
*/
lib_plankton.zoo_page.register(
"event_add",
async (parameters, target_element) => {
const calendar_id : int = parseInt(parameters["calendar_id"]);
target_element.innerHTML = await _zeitbild.frontend_web.helpers.template_coin(
"event_add",
{
"label": lib_plankton.translate.get("page.event_add.title")
}
);
const form : lib_plankton.zoo_form.class_form<
{
calendar_id : _zeitbild.frontend_web.type.calendar_id;
event_object : _zeitbild.frontend_web.type.event_object;
},
{
calendar_id : string;
name : string;
begin : lib_plankton.pit.type_datetime;
end : (null | lib_plankton.pit.type_datetime);
location : (null | string);
description : (null | string);
}
> = new lib_plankton.zoo_form.class_form<
{
calendar_id : _zeitbild.frontend_web.type.calendar_id;
event_object : _zeitbild.frontend_web.type.event_object;
},
{
calendar_id : string;
name : string;
begin : lib_plankton.pit.type_datetime;
end : (null | lib_plankton.pit.type_datetime);
location : (null | string);
description : (null | string);
}
>(
(value) => ({
"calendar_id": value.calendar_id.toFixed(0),
"name": value.event_object.name,
"begin": value.event_object.begin,
"end": value.event_object.end,
"location": value.event_object.location,
"description": value.event_object.description,
}),
(representation) => ({
"calendar_id": parseInt(representation.calendar_id),
"event_object": {
"name": representation.name,
"begin": representation.begin,
"end": representation.end,
"location": representation.location,
"description": representation.description,
}
}),
new lib_plankton.zoo_input.class_input_group<any>(
[
{
"name": "calendar_id",
"input": new lib_plankton.zoo_input.class_input_selection(
(await _zeitbild.frontend_web.backend.calendar_list())
.filter(
(entry) => (["edit","admin"].includes(entry.access_level))
)
.map(
(entry) => ({
"value": entry.id.toFixed(0),
"label": entry.name,
})
)
),
"label": lib_plankton.translate.get("calendar.calendar")
},
{
"name": "name",
"input": new lib_plankton.zoo_input.class_input_text(
),
"label": lib_plankton.translate.get("event.name")
},
{
"name": "begin",
"input": new lib_plankton.zoo_input.class_input_datetime(
),
"label": lib_plankton.translate.get("event.begin")
},
{
"name": "end",
"input": new lib_plankton.zoo_input.class_input_soft<lib_plankton.pit.type_datetime>(
new lib_plankton.zoo_input.class_input_datetime(
)
),
"label": lib_plankton.translate.get("event.end")
},
{
"name": "location",
"input": new lib_plankton.zoo_input.class_input_soft<string>(
new lib_plankton.zoo_input.class_input_text(
)
),
"label": lib_plankton.translate.get("event.location")
},
{
"name": "description",
"input": new lib_plankton.zoo_input.class_input_soft<string>(
new lib_plankton.zoo_input.class_input_text(
)
),
"label": lib_plankton.translate.get("event.description")
},
]
),
[
{
"label": lib_plankton.translate.get("page.event_add.actions.do"),
"target": "submit",
"procedure": async (get_value, get_representation) => {
const value : any = await get_value();
try {
await _zeitbild.frontend_web.backend.calendar_event_add(
value.calendar_id,
value.event_object
);
lib_plankton.zoo_page.set(
{
"name": "events",
"parameters": {}
}
);
}
catch (error) {
// do nothing
/*
lib_plankton.zoo_page.set(
{
"name": "event_add",
"parameters": {
}
}
);
*/
}
}
},
]
);
/*
await form.write(
{
"calendar_id": parameters["calendar_id"],
}
);
*/
await form.setup(document.querySelector("#event_add_form"));
return Promise.resolve<void>(undefined);
}
);
}

View file

@ -0,0 +1,30 @@
namespace _zeitbild.frontend_web.pages
{
/**
*/
lib_plankton.zoo_page.register(
"events",
async (parameters, target_element) => {
const content = await _zeitbild.frontend_web.view.calendar_view_table_html(
{
"calendar_ids": null,
// TODO
"from": {
"year": 2024,
"week": 37
},
// TODO
"to": {
"year": 2024,
"week": 43
},
"timezone_shift": /*conf.timezone_shift*/0,
}
);
target_element.innerHTML = content;
return Promise.resolve<void>(undefined);
},
);
}

View file

106
source/pages/login/logic.ts Normal file
View file

@ -0,0 +1,106 @@
namespace _zeitbild.frontend_web.pages
{
/**
*/
lib_plankton.zoo_page.register(
"login",
async (parameters, target_element) => {
const preparation : {kind : string; data : any;} = await _zeitbild.frontend_web.backend.session_prepare(
);
switch (preparation.kind) {
case "internal": {
target_element.innerHTML = await _zeitbild.frontend_web.helpers.template_coin(
"login",
{
}
);
const form : lib_plankton.zoo_form.class_form<
{name : string; password : string;},
{name : string; password : string;}
> = new lib_plankton.zoo_form.class_form<
{name : string; password : string;},
{name : string; password : string;}
>(
x => x,
x => x,
new lib_plankton.zoo_input.class_input_group<
{name : string; password : string;}
>(
[
{
"name": "name",
"input": new lib_plankton.zoo_input.class_input_text(),
"label": lib_plankton.translate.get("page.login.internal.name"),
},
{
"name": "password",
"input": new lib_plankton.zoo_input.class_input_password(),
"label": lib_plankton.translate.get("page.login.internal.password"),
},
]
),
[
{
"label": lib_plankton.translate.get("page.login.internal.do"),
"target": "submit",
"procedure": async (get_value, get_representation) => {
const value : any = await get_value();
try {
await _zeitbild.frontend_web.backend.session_begin(
value.name,
value.password
);
lib_plankton.zoo_page.set(
{
"name": "events",
"parameters": {}
}
);
}
catch (error) {
lib_plankton.zoo_page.set(
{
"name": "login",
"parameters": {
"name": value.name,
}
}
);
}
}
},
]
);
await form.setup(document.querySelector("#login"));
await form.input_write(
{
"name": (parameters.name ?? ""),
"password": "",
}
);
break;
}
case "oidc": {
let element_a : HTMLElement = document.createElement("a");;
element_a.textContent = lib_plankton.string.coin(
lib_plankton.translate.get("page.login.oidc.via"),
{
"title": preparation.data.label,
}
);
element_a.setAttribute("href", preparation.data.url);
target_element.innerHTML = "";
target_element.appendChild(element_a);
break;
}
default: {
break;
}
}
return Promise.resolve<void>(undefined);
}
);
}

View file

View file

@ -0,0 +1,22 @@
namespace _zeitbild.frontend_web.pages
{
/**
*/
lib_plankton.zoo_page.register(
"logout",
async (parameters, target_element) => {
await _zeitbild.frontend_web.backend.session_end(
);
lib_plankton.zoo_page.set(
{
"name": "login",
"parameters": {
}
}
);
return Promise.resolve<void>(undefined);
}
);
}

View file

@ -0,0 +1,20 @@
namespace _zeitbild.frontend_web.pages
{
/**
*/
lib_plankton.zoo_page.register(
"oidc_finish",
async (parameters, target_element) => {
await _zeitbild.frontend_web.backend.set_session_key(parameters["session_key"]);
lib_plankton.zoo_page.set(
{
"name": "events",
"parameters": {}
}
);
return Promise.resolve<void>(undefined);
}
);
}

View file

@ -52,6 +52,12 @@ ${dir_temp}/logic-unlinked.js: \
${dir_source}/logic/types.ts \
${dir_source}/logic/backend.ts \
${dir_source}/logic/view.ts \
${dir_source}/pages/login/logic.ts \
${dir_source}/pages/logout/logic.ts \
${dir_source}/pages/oidc_finish/logic.ts \
${dir_source}/pages/calendar_add/logic.ts \
${dir_source}/pages/event_add/logic.ts \
${dir_source}/pages/events/logic.ts \
${dir_source}/logic/main.ts
@ ${cmd_log} "logic | compile …"
@ ${cmd_mkdir} $(dir $@)

View file

@ -19,6 +19,7 @@ modules="${modules} map"
modules="${modules} http"
modules="${modules} log"
modules="${modules} url"
modules="${modules} pit"
modules="${modules} www_form"
modules="${modules} translate"
modules="${modules} zoo-page"