From 9f0468ac0d41ca5ee7062845fce7196af5ba3bf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Fra=C3=9F?= Date: Thu, 21 Aug 2025 21:45:39 +0000 Subject: [PATCH] [int] --- source/data/localization/deu.loc.json | 6 + source/data/localization/eng.loc.json | 6 + source/logic/backend.ts | 120 +++++++++++++++---- source/logic/input_set.ts | 132 +++++++++++++++++++++ source/logic/main.ts | 5 + source/pages/group_create/logic.ts | 51 ++++++++ source/pages/group_create/structure.html | 19 +++ source/pages/group_create/style.css | 15 +++ source/pages/group_list/logic.ts | 90 ++++++++++++++ source/pages/group_list/structure.html | 22 ++++ source/pages/group_list/style.css | 19 +++ source/pages/group_view/logic.ts | 58 +++++++++ source/pages/group_view/structure.html | 22 ++++ source/pages/group_view/style.css | 21 ++++ source/pages/invite_create/logic.ts | 24 +--- source/pages/invite_view/logic.ts | 26 +--- source/pages/member_list/logic.ts | 18 +-- source/pages/member_view/logic.ts | 144 +++++++++-------------- source/style/style.css | 5 + tools/makefile | 13 +- 20 files changed, 643 insertions(+), 173 deletions(-) create mode 100644 source/logic/input_set.ts create mode 100644 source/pages/group_create/logic.ts create mode 100644 source/pages/group_create/structure.html create mode 100644 source/pages/group_create/style.css create mode 100644 source/pages/group_list/logic.ts create mode 100644 source/pages/group_list/structure.html create mode 100644 source/pages/group_list/style.css create mode 100644 source/pages/group_view/logic.ts create mode 100644 source/pages/group_view/structure.html create mode 100644 source/pages/group_view/style.css diff --git a/source/data/localization/deu.loc.json b/source/data/localization/deu.loc.json index cc35975..aa8b758 100644 --- a/source/data/localization/deu.loc.json +++ b/source/data/localization/deu.loc.json @@ -9,13 +9,16 @@ "common.timezone_shift": "Zeitzonen-Verschiebung", "common.date": "Datum", "common.time": "Uhzeit", + "domain.group.name.label": "Name", "domain.member.member": "Mitglied", "domain.member.membership_number.label": "Mitgliedsnummer", + "domain.member.name.label": "Name", "domain.member.name_real_value.label": "Echter Name", "domain.member.name_real_index.label": "Namens-Index", "domain.member.groups.label": "Gruppen", "domain.member.registered.label": "registriert", "domain.member.enabled.label": "aktiviert", + "domain.member.email_address.label": "E-Mail-Adresse", "domain.member.email_address_private.label": "private E-Mail-Adresse", "domain.member.email_address_veiled.label": "pseudonymisierte E-Mail-Adresse", "domain.member.email_address_nominal.label": "namentliche E-Mail-Adresse", @@ -31,6 +34,9 @@ "page.login.password": "Passwort", "page.login.submit": "Anmelden", "page.logout.title": "Abmelden", + "page.group_list.title": "Gruppen", + "page.group_create.title": "Gruppe anlegen", + "page.group_create.form.submit": "Abschicken", "page.member_create.title": "Mitglied anlegen", "page.member_list.title": "Mitglieder", "page.member_view.title": "Mitglied", diff --git a/source/data/localization/eng.loc.json b/source/data/localization/eng.loc.json index cc7075f..2cc1fa1 100644 --- a/source/data/localization/eng.loc.json +++ b/source/data/localization/eng.loc.json @@ -9,13 +9,16 @@ "common.timezone_shift": "timezone shift", "common.date": "date", "common.time": "time", + "domain.group.name.label": "name", "domain.member.member": "member", "domain.member.membership_number.label": "membership number", + "domain.member.name.label": "name", "domain.member.name_real_value.label": "real name", "domain.member.name_real_index.label": "name index", "domain.member.groups.label": "groups", "domain.member.registered.label": "registered", "domain.member.enabled.label": "enabled", + "domain.member.email_address.label": "e-mail address", "domain.member.email_address_private.label": "private e-mail address", "domain.member.email_address_veiled.label": "veiled e-mail address", "domain.member.email_address_nominal.label": "nominal e-mail address", @@ -31,6 +34,9 @@ "page.login.password": "password", "page.login.submit": "login", "page.logout.title": "logout", + "page.group_list.title": "groups", + "page.group_create.title": "Create group", + "page.group_create.form.submit": "submit", "page.member_create.title": "Create member", "page.member_list.title": "Members", "page.member_view.title": "Member", diff --git a/source/logic/backend.ts b/source/logic/backend.ts index 93faffa..31bed3a 100644 --- a/source/logic/backend.ts +++ b/source/logic/backend.ts @@ -230,6 +230,91 @@ namespace _espe.backend } + /** + */ + export async function group_list( + ) : Promise< + Array< + { + id : int; + name : string; + } + > + > + { + return ( + abstract_call( + "GET", + "/group/list" + ) + ); + } + + + /** + */ + export async function group_get( + group_id : int + ) : Promise< + { + name : string; + } + > + { + return ( + abstract_call( + "GET", + ("/group/read/" + group_id.toFixed(0)) + ) + ); + } + + + /** + */ + export async function group_add( + group_object : { + name : string; + } + ) : Promise< + int + > + { + return ( + abstract_call( + "POST", + "/group/add", + { + "data": group_object, + } + ) + ); + } + + + /** + */ + export async function group_modify( + group_id : int, + group_object : { + name : string; + } + ) : Promise< + void + > + { + return ( + abstract_call( + "PATCH", + ("/group/modify/" + group_id.toFixed(0)), + { + "data": group_object, + } + ) + ); + } + + /** */ export async function member_list( @@ -239,9 +324,7 @@ namespace _espe.backend { id : int; preview : { - membership_number : string; - name_real_value : string; - name_real_index : int; + name : string; }; } > @@ -262,21 +345,11 @@ namespace _espe.backend id : int ) : Promise< { - membership_number : string; - name_real_value : string; - name_real_index : int; - email_address_private : (null | string); - groups : Array; - registered : boolean; + name : string; + email_address : (null | string); + groups : Array; enabled : boolean; - email_use_veiled_address : boolean; - email_use_nominal_address : boolean; - email_redirect_to_private_address : boolean; - email_allow_sending : boolean; password_set : boolean; - email_address_veiled : string; - email_address_nominal : string; - name_login : string; } > { @@ -393,9 +466,8 @@ namespace _espe.backend export async function member_modify( id : int, data : { - email_address_private : (null | string); - groups : Array; - registered : boolean; + email_address : (null | string); + groups : Array; enabled : boolean; } ) : Promise @@ -503,7 +575,7 @@ namespace _espe.backend return abstract_call( "GET", lib_plankton.string.coin( - "/invite/list", + "/invitation/list", { } ) @@ -533,7 +605,7 @@ namespace _espe.backend return abstract_call( "GET", lib_plankton.string.coin( - "/invite/read?id={{id}}", + "/invitation/read?id={{id}}", { "id": id.toFixed(0), } @@ -567,7 +639,7 @@ namespace _espe.backend { return abstract_call( "POST", - "/invite/create", + "/invitation/create", { "data": { "data": data, @@ -599,7 +671,7 @@ namespace _espe.backend return abstract_call( "GET", lib_plankton.string.coin( - "/invite/examine?key={{key}}", + "/invitation/examine?key={{key}}", { "key": key } @@ -630,7 +702,7 @@ namespace _espe.backend { return abstract_call( "POST", - "/invite/accept", + "/invitation/accept", { "data": { "key": key, diff --git a/source/logic/input_set.ts b/source/logic/input_set.ts new file mode 100644 index 0000000..acd684d --- /dev/null +++ b/source/logic/input_set.ts @@ -0,0 +1,132 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + +namespace _espe +{ + + /** + * @todo outsource to plankton + */ + export class class_input_set implements lib_plankton.zoo_input.interface_input> + { + + /** + */ + private options : Array; + + + /** + */ + private show_element : ((element : string) => string); + + + /** + */ + private read_only : boolean; + + + /** + */ + private checkboxes : Map; + + + /** + */ + public constructor( + options : Array, + show_element : ((element : string) => string), + { + "read_only": read_only = false, + } : { + read_only ?: boolean; + } = { + } + ) + { + this.show_element = show_element; + this.options = options; + this.read_only = read_only; + this.checkboxes = new Map(); + } + + + /** + * [implementation] + */ + public setup( + parent : HTMLElement + ) : Promise + { + for (const option of this.options) + { + // label + const element_container : HTMLElement = document.createElement("label"); + element_container.classList.add("plankton_input_set_option"); + element_container.setAttribute("rel", option); + // checkbox + { + const element_checkbox : HTMLInputElement = document.createElement("input"); + element_checkbox.setAttribute("type", "checkbox"); + element_container.appendChild(element_checkbox); + this.checkboxes.set(option, element_checkbox); + } + // text + { + const element_text : HTMLElement = document.createElement("span"); + element_text.textContent = this.show_element(option); + element_container.appendChild(element_text); + } + parent.appendChild(element_container); + } + return Promise.resolve(undefined); + } + + + /** + * [implementation] + */ + public read( + ) : Promise> + { + const result : Set = new Set(); + for (const option of this.options) + { + const element_checkbox : HTMLInputElement = this.checkboxes.get(option); + if (element_checkbox.checked) { + result.add(option); + } + } + return Promise.resolve>(result); + } + + + /** + * [implementation] + */ + public write( + value : Set + ) : Promise + { + for (const option of this.options) + { + const element_checkbox : HTMLInputElement = this.checkboxes.get(option); + element_checkbox.checked = value.has(option); + } + return Promise.resolve(undefined); + } + + } + +} diff --git a/source/logic/main.ts b/source/logic/main.ts index 94e0fee..8ad3d6f 100644 --- a/source/logic/main.ts +++ b/source/logic/main.ts @@ -59,6 +59,11 @@ function setup_nav( "label": lib_plankton.translate.get("page.login.title"), "classes": ["logged_out"], }, + { + "location": {"name": "group_list", "parameters": {}}, + "label": lib_plankton.translate.get("page.group_list.title"), + "classes": ["logged_in"], + }, { "location": {"name": "member_list", "parameters": {}}, "label": lib_plankton.translate.get("page.member_list.title"), diff --git a/source/pages/group_create/logic.ts b/source/pages/group_create/logic.ts new file mode 100644 index 0000000..22a9969 --- /dev/null +++ b/source/pages/group_create/logic.ts @@ -0,0 +1,51 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + +lib_plankton.zoo_page.register( + "group_create", + (parameters, target_element) => { + target_element.appendChild(template_request("group_create")); + + target_element.querySelector(".group_create-title").textContent = lib_plankton.translate.get("page.group_create.title"); + + const form = new lib_plankton.zoo_form.class_form< + {name : string}, + {name : string} + >( + value => value, + representation => representation, + new lib_plankton.zoo_input.class_input_group( + [ + { + "name": "name", + "input": new lib_plankton.zoo_input.class_input_text(), + "label": lib_plankton.translate.get("domain.group.name.label"), + }, + ] + ), + [ + { + "label": lib_plankton.translate.get("page.group_create.form.submit"), + "procedure": async (get_value, get_representation) => { + const value = await get_value(); + const id : int = await _espe.backend.group_add(value); + lib_plankton.zoo_page.set({"name": "group_view", "parameters": {"id": id}}); + }, + } + ] + ); + form.setup(target_element.querySelector(".group_create-form") as HTMLElement); + } +); diff --git a/source/pages/group_create/structure.html b/source/pages/group_create/structure.html new file mode 100644 index 0000000..c6a1c8d --- /dev/null +++ b/source/pages/group_create/structure.html @@ -0,0 +1,19 @@ + + + diff --git a/source/pages/group_create/style.css b/source/pages/group_create/style.css new file mode 100644 index 0000000..791713b --- /dev/null +++ b/source/pages/group_create/style.css @@ -0,0 +1,15 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + diff --git a/source/pages/group_list/logic.ts b/source/pages/group_list/logic.ts new file mode 100644 index 0000000..4e64b05 --- /dev/null +++ b/source/pages/group_list/logic.ts @@ -0,0 +1,90 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + +lib_plankton.zoo_page.register( + "group_list", + (parameters, target_element) => { + type type_item = { + id : int; + name : string; + }; + const term : (null | string) = (parameters["term"] ?? ""); + + target_element.appendChild(template_request("group_list")); + + target_element.querySelector(".group_list-title").textContent = lib_plankton.translate.get("page.group_list.title"); + + // create link + { + const element : HTMLElement = target_element.querySelector(".group_list-create"); + element.setAttribute( + "href", + lib_plankton.zoo_page.encode( + { + "name": "group_create", + "parameters": { + } + } + ) + ); + element.textContent = lib_plankton.translate.get("page.group_create.title"); + } + + const search : lib_plankton.zoo_search.type_search = lib_plankton.zoo_search.make( + (term) => _espe.backend.group_list(), + { + "encode_item": (item) => lib_plankton.string.coin( + "{{name}}", + { + "name": item.name, + } + ), + "hooks_begin": [ + (term) => { + lib_plankton.zoo_page.set( + { + "name": "group_list", + "parameters": { + "term": term, + } + } + ); + } + ], + "hooks_select": [ + (item) => { + lib_plankton.zoo_page.set( + { + "name": "group_view", + "parameters": { + "id": item.id.toFixed(0), + } + } + ); + } + ] + } + ); + lib_plankton.zoo_search.render( + search, + target_element.querySelector(".group_list-search"), + { + "state": { + "term": term, + } + } + ); + } +); diff --git a/source/pages/group_list/structure.html b/source/pages/group_list/structure.html new file mode 100644 index 0000000..926f380 --- /dev/null +++ b/source/pages/group_list/structure.html @@ -0,0 +1,22 @@ + + + diff --git a/source/pages/group_list/style.css b/source/pages/group_list/style.css new file mode 100644 index 0000000..8fd3ec8 --- /dev/null +++ b/source/pages/group_list/style.css @@ -0,0 +1,19 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + +.group_list-links +{ + margin-bottom: 16px; +} diff --git a/source/pages/group_view/logic.ts b/source/pages/group_view/logic.ts new file mode 100644 index 0000000..fef4aa5 --- /dev/null +++ b/source/pages/group_view/logic.ts @@ -0,0 +1,58 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + +lib_plankton.zoo_page.register( + "group_view", + async (parameters, target_element) => { + const id : int = parseInt(parameters["id"]); + + let dom_fragment : DocumentFragment = template_request("group_view"); + + dom_fragment.querySelector(".group_view-title").textContent = lib_plankton.translate.get("page.group_view.title"); + + const group_object = await _espe.backend.group_get(id); + + const form = new lib_plankton.zoo_form.class_form< + {name : string}, + {name : string} + >( + value => value, + representation => representation, + new lib_plankton.zoo_input.class_input_group( + [ + { + "name": "name", + "input": new lib_plankton.zoo_input.class_input_text(), + "label": lib_plankton.translate.get("domain.group.name.label"), + }, + ] + ), + [ + { + "label": lib_plankton.translate.get("page.group_create.form.submit"), + "procedure": async (get_value, get_representation) => { + const value = await get_value(); + await _espe.backend.group_modify(id, value); + lib_plankton.zoo_page.set({"name": "group_list", "parameters": {}}); + }, + } + ] + ); + await form.setup(dom_fragment.querySelector(".group_view-form") as HTMLElement); + await form.input_write(group_object); + + target_element.appendChild(dom_fragment); + }, +); diff --git a/source/pages/group_view/structure.html b/source/pages/group_view/structure.html new file mode 100644 index 0000000..ad0d2f6 --- /dev/null +++ b/source/pages/group_view/structure.html @@ -0,0 +1,22 @@ + + + diff --git a/source/pages/group_view/style.css b/source/pages/group_view/style.css new file mode 100644 index 0000000..a9889b6 --- /dev/null +++ b/source/pages/group_view/style.css @@ -0,0 +1,21 @@ +/* +Espe | Ein schlichtes Werkzeug zur Mitglieder-Verwaltung | Frontend +Copyright (C) 2024 Christian Fraß + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public +License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later +version. + +This program 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 General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see +. + */ + + +.group_view-title +{ + display: none; +} + diff --git a/source/pages/invite_create/logic.ts b/source/pages/invite_create/logic.ts index 4669350..0115192 100644 --- a/source/pages/invite_create/logic.ts +++ b/source/pages/invite_create/logic.ts @@ -112,7 +112,7 @@ lib_plankton.zoo_page.register( new lib_plankton.zoo_input.class_input_group( [ { - "name": "membership_number", + "name": "name", "input": new lib_plankton.zoo_input.class_input_group( [ { @@ -127,7 +127,7 @@ lib_plankton.zoo_page.register( }, ] ), - "label": lib_plankton.translate.get("domain.member.membership_number.label"), + "label": lib_plankton.translate.get("domain.member.name.label"), }, { "name": "groups", @@ -149,24 +149,6 @@ lib_plankton.zoo_page.register( ), "label": lib_plankton.translate.get("domain.member.groups.label"), }, - { - "name": "name", - "input": new lib_plankton.zoo_input.class_input_group( - [ - { - "name": "value", - "input": new lib_plankton.zoo_input.class_input_text(), - "label": indent(lib_plankton.translate.get("common.initial_value")), - }, - { - "name": "changeable", - "input": new lib_plankton.zoo_input.class_input_checkbox(), - "label": indent(lib_plankton.translate.get("common.changeable")), - }, - ] - ), - "label": lib_plankton.translate.get("domain.member.name_real_value.label"), - }, { "name": "email_address", "input": new lib_plankton.zoo_input.class_input_group( @@ -183,7 +165,7 @@ lib_plankton.zoo_page.register( }, ] ), - "label": lib_plankton.translate.get("domain.member.email_address_private.label"), + "label": lib_plankton.translate.get("domain.member.email_address.label"), }, { "name": "expiry", diff --git a/source/pages/invite_view/logic.ts b/source/pages/invite_view/logic.ts index 6118129..ae83d49 100644 --- a/source/pages/invite_view/logic.ts +++ b/source/pages/invite_view/logic.ts @@ -127,7 +127,7 @@ lib_plankton.zoo_page.register( [ { "name": "url", - "input": new lib_plankton.zoo_input.class_input_text({"read_only": false}), + "input": new lib_plankton.zoo_input.class_input_text({"read_only": true}), "label": lib_plankton.translate.get("domain.invite.url.label"), }, { @@ -136,7 +136,7 @@ lib_plankton.zoo_page.register( "label": lib_plankton.translate.get("domain.invite.key.label"), }, { - "name": "membership_number", + "name": "name", "input": new lib_plankton.zoo_input.class_input_group( [ { @@ -151,7 +151,7 @@ lib_plankton.zoo_page.register( }, ] ), - "label": lib_plankton.translate.get("domain.member.membership_number.label"), + "label": lib_plankton.translate.get("domain.member.name.label"), }, { "name": "groups", @@ -174,24 +174,6 @@ lib_plankton.zoo_page.register( ), "label": lib_plankton.translate.get("domain.member.groups.label"), }, - { - "name": "name", - "input": new lib_plankton.zoo_input.class_input_group( - [ - { - "name": "value", - "input": new lib_plankton.zoo_input.class_input_text({"read_only": true}), - "label": indent(lib_plankton.translate.get("common.initial_value")), - }, - { - "name": "changeable", - "input": new lib_plankton.zoo_input.class_input_checkbox({"read_only": true}), - "label": indent(lib_plankton.translate.get("common.changeable")), - }, - ] - ), - "label": lib_plankton.translate.get("domain.member.name_real_value.label"), - }, { "name": "email_address", "input": new lib_plankton.zoo_input.class_input_group( @@ -208,7 +190,7 @@ lib_plankton.zoo_page.register( }, ] ), - "label": lib_plankton.translate.get("domain.member.email_address_private.label"), + "label": lib_plankton.translate.get("domain.member.email_address.label"), }, { "name": "expiry", diff --git a/source/pages/member_list/logic.ts b/source/pages/member_list/logic.ts index d8d7494..a70b653 100644 --- a/source/pages/member_list/logic.ts +++ b/source/pages/member_list/logic.ts @@ -19,9 +19,7 @@ lib_plankton.zoo_page.register( type type_item = { id : int; preview : { - membership_number : string; - name_real_value : string; - name_real_index : int; + name : string; }; }; const term : (null | string) = (parameters["term"] ?? ""); @@ -50,19 +48,9 @@ lib_plankton.zoo_page.register( (term) => _espe.backend.member_list(term), { "encode_item": (item) => lib_plankton.string.coin( - "{{membership_number}} | {{name}}{{addition}}", + "{{name}}", { - "membership_number": item.preview.membership_number, - "name": item.preview.name_real_value, - "addition": ( - ( - (item.preview.name_real_index === null) - || - (item.preview.name_real_index <= 1) - ) - ? "" - : (" (" + item.preview.name_real_index.toFixed(0) + ")") - ), + "name": item.preview.name, } ), "hooks_begin": [ diff --git a/source/pages/member_view/logic.ts b/source/pages/member_view/logic.ts index 241a387..b02ab29 100644 --- a/source/pages/member_view/logic.ts +++ b/source/pages/member_view/logic.ts @@ -22,63 +22,74 @@ lib_plankton.zoo_page.register( dom_fragment.querySelector(".member_view-title").textContent = lib_plankton.translate.get("page.member_view.title"); + /** + * @todo cache + */ + const groups_as_array : Array<{id : int; name : string;}> = await _espe.backend.group_list(); + const groups_as_map : Map = new Map(); + for (const group_thingy of groups_as_array) + { + groups_as_map.set(group_thingy.id, {"name": group_thingy.name}); + } + const member_data = await _espe.backend.member_get(id); const form = new lib_plankton.zoo_form.class_form< { - membership_number : string; - name_real_value : string; - name_real_index : int; - groups : Array; - registered : boolean; + name : string; + groups : Array; enabled : boolean; - email_address_private : (null | string); - email_address_veiled : (null | string); - email_address_nominal : (null | string); - email_redirect_to_private_address : boolean; - email_allow_sending : boolean; - name_login : string; + email_address : (null | string); password_set : boolean; }, { - membership_number : string; - name_real_value : string; - name_real_index : int; - groups : Array; - registered : boolean; + name : string; + groups : Set; enabled : boolean; - email_address_private : (null | string); - email_address_veiled : (null | string); - email_address_nominal : (null | string); - email_redirect_to_private_address : boolean; - email_allow_sending : boolean; - name_login : string; + email_address : (null | string); password_set : boolean; } >( - value => value, - representation => representation, + value => ({ + "name": value.name, + "groups": new Set(value.groups.map(group_id => group_id.toFixed(0))), + "enabled": value.enabled, + "email_address": value.email_address, + "password_set": value.password_set, + }), + representation => ({ + "name": representation.name, + "groups": (() => { + const array : Array = []; + for (const group_id_encoded of representation.groups) + { + array.push(parseInt(group_id_encoded)); + } + return array; + }) (), + "enabled": representation.enabled, + "email_address": representation.email_address, + "password_set": representation.password_set, + }), new lib_plankton.zoo_input.class_input_group( [ { - "name": "name_real_value", + "name": "name", "input": new lib_plankton.zoo_input.class_input_text({"read_only": true}), - "label": lib_plankton.translate.get("domain.member.name_real_value.label"), - }, - { - "name": "name_real_index", - "input": new lib_plankton.zoo_input.class_input_number({"read_only": true}), - "label": lib_plankton.translate.get("domain.member.name_real_index.label"), - }, - { - "name": "membership_number", - "input": new lib_plankton.zoo_input.class_input_text({"read_only": true}), - "label": lib_plankton.translate.get("domain.member.membership_number.label"), + "label": lib_plankton.translate.get("domain.member.name.label"), }, { "name": "groups", + /* "input": new lib_plankton.zoo_input.class_input_list( - () => new lib_plankton.zoo_input.class_input_text() + () => new lib_plankton.zoo_input.class_input_number() + ), + */ + "input": new _espe.class_input_set( + groups_as_array.map( + group_thingy => group_thingy.id.toFixed(0) + ), + group_id_encoded => groups_as_map.get(parseInt(group_id_encoded)).name ), "label": lib_plankton.translate.get("domain.member.groups.label"), }, @@ -87,45 +98,15 @@ lib_plankton.zoo_page.register( "input": new lib_plankton.zoo_input.class_input_checkbox(), "label": lib_plankton.translate.get("domain.member.enabled.label"), }, - { - "name": "registered", - "input": new lib_plankton.zoo_input.class_input_checkbox({"read_only": true}), - "label": lib_plankton.translate.get("domain.member.registered.label"), - }, - { - "name": "name_login", - "input": new lib_plankton.zoo_input.class_input_text({"read_only": true}), - "label": lib_plankton.translate.get("domain.member.name_login.label"), - }, { "name": "password_set", "input": new lib_plankton.zoo_input.class_input_checkbox({"read_only": true}), "label": lib_plankton.translate.get("domain.member.password_set.label"), }, { - "name": "email_address_private", + "name": "email_address", "input": new lib_plankton.zoo_input.class_input_text(), - "label": lib_plankton.translate.get("domain.member.email_address_private.label"), - }, - { - "name": "email_address_veiled", - "input": new lib_plankton.zoo_input.class_input_text({"read_only": true}), - "label": lib_plankton.translate.get("domain.member.email_address_veiled.label"), - }, - { - "name": "email_address_nominal", - "input": new lib_plankton.zoo_input.class_input_text({"read_only": true}), - "label": lib_plankton.translate.get("domain.member.email_address_nominal.label"), - }, - { - "name": "email_redirect_to_private_address", - "input": new lib_plankton.zoo_input.class_input_checkbox({"read_only": true}), - "label": lib_plankton.translate.get("domain.member.email_redirect_to_private_address.label"), - }, - { - "name": "email_allow_sending", - "input": new lib_plankton.zoo_input.class_input_checkbox(), - "label": lib_plankton.translate.get("domain.member.email_allow_sending.label"), + "label": lib_plankton.translate.get("domain.member.email_address.label"), }, ] ), @@ -138,15 +119,15 @@ lib_plankton.zoo_page.register( await _espe.backend.member_modify( id, { - "email_address_private": value.email_address_private, + "email_address": value.email_address, "groups": value.groups, "enabled": value.enabled, - "registered": value.registered, } ); }, }, ] + /* .concat( member_data.registered ? [] @@ -176,31 +157,16 @@ lib_plankton.zoo_page.register( }, ] ) + */ ) ); await form.setup(dom_fragment.querySelector(".member_view-form") as HTMLElement); await form.input_write( { - "membership_number": member_data.membership_number, - "name_real_value": member_data.name_real_value, - "name_real_index": member_data.name_real_index, + "name": member_data.name, "groups": member_data.groups, - "registered": member_data.registered, "enabled": member_data.enabled, - "email_address_private": member_data.email_address_private, - "email_address_veiled": ( - member_data.email_use_veiled_address - ? member_data.email_address_veiled - : ("(" + lib_plankton.translate.get("common.not_used") + ")") - ), - "email_address_nominal": ( - member_data.email_use_nominal_address - ? member_data.email_address_nominal - : ("(" + lib_plankton.translate.get("common.not_used") + ")") - ), - "email_redirect_to_private_address": member_data.email_redirect_to_private_address, - "email_allow_sending": member_data.email_allow_sending, - "name_login": member_data.name_login, + "email_address": member_data.email_address, "password_set": member_data.password_set, } ); diff --git a/source/style/style.css b/source/style/style.css index a4c4260..27d8676 100644 --- a/source/style/style.css +++ b/source/style/style.css @@ -251,3 +251,8 @@ nav > ul > li:hover::after { display: none!important; } + +.plankton_input_set_option +{ + display: block; +} diff --git a/tools/makefile b/tools/makefile index c276c6b..af102ae 100644 --- a/tools/makefile +++ b/tools/makefile @@ -36,11 +36,15 @@ _default: ${dir_build}/logic.js ${dir_build}/style.css ${dir_build}/index.html d ${dir_temp}/logic-unlinked.js: \ ${dir_lib}/plankton/plankton.d.ts \ ${dir_source}/logic/helpers.ts \ + ${dir_source}/logic/input_set.ts \ ${dir_source}/logic/backend.ts \ ${dir_source}/logic/conf.ts \ ${dir_source}/pages/index/logic.ts \ ${dir_source}/pages/login/logic.ts \ ${dir_source}/pages/logout/logic.ts \ + ${dir_source}/pages/group_list/logic.ts \ + ${dir_source}/pages/group_view/logic.ts \ + ${dir_source}/pages/group_create/logic.ts \ ${dir_source}/pages/member_create/logic.ts \ ${dir_source}/pages/member_list/logic.ts \ ${dir_source}/pages/member_view/logic.ts \ @@ -54,19 +58,21 @@ ${dir_temp}/logic-unlinked.js: \ ${dir_source}/logic/main.ts @ ${cmd_log} "logic | compile …" @ ${cmd_mkdir} $(dir $@) - @ ${cmd_tsc} --lib es2020,dom $^ --outFile $@ + @ ${cmd_tsc} --lib es2020,dom --target es2015 $^ --outFile $@ ${dir_build}/logic.js: ${dir_lib}/plankton/plankton.js ${dir_temp}/logic-unlinked.js @ ${cmd_log} "logic | link …" @ ${cmd_mkdir} $(dir $@) @ ${cmd_cat} $^ > $@ - @ ${cmd_chmod} +x $@ ${dir_build}/style.css: \ ${dir_source}/style/style.css \ ${dir_source}/pages/index/style.css \ ${dir_source}/pages/login/style.css \ ${dir_source}/pages/logout/style.css \ + ${dir_source}/pages/group_list/style.css \ + ${dir_source}/pages/group_view/style.css \ + ${dir_source}/pages/group_create/style.css \ ${dir_source}/pages/member_create/style.css \ ${dir_source}/pages/member_list/style.css \ ${dir_source}/pages/member_view/style.css \ @@ -86,6 +92,9 @@ ${dir_build}/index.html: \ ${dir_source}/pages/index/structure.html \ ${dir_source}/pages/login/structure.html \ ${dir_source}/pages/logout/structure.html \ + ${dir_source}/pages/group_list/structure.html \ + ${dir_source}/pages/group_view/structure.html \ + ${dir_source}/pages/group_create/structure.html \ ${dir_source}/pages/member_create/structure.html \ ${dir_source}/pages/member_list/structure.html \ ${dir_source}/pages/member_view/structure.html \