This commit is contained in:
roydfalk 2025-08-21 22:45:57 +00:00
parent 9f0468ac0d
commit b29730fffd
14 changed files with 158 additions and 570 deletions

View file

@ -360,34 +360,6 @@ namespace _espe.backend
} }
/**
*/
export async function member_project(
data : {
membership_number : string;
name_real_value : string;
email_address_private : (null | string);
groups : Array<string>;
},
notification_target_url_template : string
) : Promise<int>
{
return abstract_call(
"POST",
"/member/project",
{
"data": {
"membership_number": data.membership_number,
"name_real_value": data.name_real_value,
"email_address_private": data.email_address_private,
"groups": data.groups,
"notification_target_url_template": notification_target_url_template,
}
}
);
}
/** /**
*/ */
export async function member_info( export async function member_info(
@ -591,14 +563,12 @@ namespace _espe.backend
{ {
key : string; key : string;
expiry : (null | int); expiry : (null | int);
membership_number_changeable : boolean;
membership_number_value : (null | string);
name_changeable : boolean; name_changeable : boolean;
name_value : string; name_value : string;
email_address_changeable : boolean; email_address_changeable : boolean;
email_address_value : (null | string); email_address_value : (null | string);
groups_changeable : boolean; groups_changeable : boolean;
groups_value : Array<string>; groups_value : Array<int>;
} }
> >
{ {
@ -618,14 +588,12 @@ namespace _espe.backend
*/ */
export async function invite_create( export async function invite_create(
data : { data : {
membership_number_changeable : boolean;
membership_number_value : (null | string);
name_changeable : boolean; name_changeable : boolean;
name_value : string; name_value : string;
email_address_changeable : boolean; email_address_changeable : boolean;
email_address_value : (null | string); email_address_value : (null | string);
groups_changeable : boolean; groups_changeable : boolean;
groups_value : Array<string>; groups_value : Array<int>;
expiry : (null | int); expiry : (null | int);
}, },
send_immediatly : boolean, send_immediatly : boolean,
@ -657,14 +625,12 @@ namespace _espe.backend
key : string key : string
) : Promise< ) : Promise<
{ {
membership_number_changeable : boolean;
membership_number_value : (null | string);
name_changeable : boolean; name_changeable : boolean;
name_value : string; name_value : string;
email_address_changeable : boolean; email_address_changeable : boolean;
email_address_value : (null | string); email_address_value : (null | string);
groups_changeable : boolean; groups_changeable : boolean;
groups_value : Array<string>; groups_value : Array<int>;
} }
> >
{ {
@ -685,9 +651,8 @@ namespace _espe.backend
export async function invite_accept( export async function invite_accept(
key : string, key : string,
data : { data : {
membership_number : string;
groups : Array<string>;
name : string; name : string;
groups : Array<int>;
email_address : (null | string); email_address : (null | string);
password : string; password : string;
} }
@ -707,9 +672,8 @@ namespace _espe.backend
"data": { "data": {
"key": key, "key": key,
"data": { "data": {
"membership_number": data.membership_number,
"groups": data.groups,
"name": data.name, "name": data.name,
"groups": data.groups,
"email_address": data.email_address, "email_address": data.email_address,
"password": data.password, "password": data.password,
}, },

View file

@ -79,6 +79,7 @@ namespace _espe
{ {
const element_checkbox : HTMLInputElement = document.createElement("input"); const element_checkbox : HTMLInputElement = document.createElement("input");
element_checkbox.setAttribute("type", "checkbox"); element_checkbox.setAttribute("type", "checkbox");
(this.read_only && element_checkbox.setAttribute("disabled", "disabled"));
element_container.appendChild(element_checkbox); element_container.appendChild(element_checkbox);
this.checkboxes.set(option, element_checkbox); this.checkboxes.set(option, element_checkbox);
} }

View file

@ -27,26 +27,30 @@ lib_plankton.zoo_page.register(
*/ */
const null_when_empty = (str) => (((str === null) || (str === "")) ? null : str); const null_when_empty = (str) => (((str === null) || (str === "")) ? null : str);
/**
* @todo cache
*/
const groups_as_array : Array<{id : int; name : string;}> = await _espe.backend.group_list();
const groups_as_map : Map<int, {name : string;}> = new Map<int, {name : string;}>();
for (const group_thingy of groups_as_array)
{
groups_as_map.set(group_thingy.id, {"name": group_thingy.name});
}
const form = new lib_plankton.zoo_form.class_form< const form = new lib_plankton.zoo_form.class_form<
{ {
data : { data : {
membership_number_changeable : boolean;
membership_number_value : (null | string);
name_changeable : boolean; name_changeable : boolean;
name_value : (null | string); name_value : (null | string);
email_address_changeable : boolean; email_address_changeable : boolean;
email_address_value : (null | string); email_address_value : (null | string);
groups_changeable : boolean; groups_changeable : boolean;
groups_value : Array<string>; groups_value : Array<int>;
expiry : (null | int); expiry : (null | int);
}; };
send_immediatly : boolean; send_immediatly : boolean;
}, },
{ {
membership_number : {
changeable : boolean;
value : string;
};
name : { name : {
changeable : boolean; changeable : boolean;
value : string; value : string;
@ -57,17 +61,13 @@ lib_plankton.zoo_page.register(
}; };
groups : { groups : {
changeable : boolean; changeable : boolean;
value : Array<string>; value : Array<int>;
}; };
expiry : (null | lib_plankton.pit.type_datetime); expiry : (null | lib_plankton.pit.type_datetime);
send_immediatly : boolean; send_immediatly : boolean;
} }
>( >(
value => ({ value => ({
"membership_number": {
"changeable": value.data.membership_number_changeable,
"value": (value.data.membership_number_value ?? ""),
},
"name": { "name": {
"changeable": value.data.name_changeable, "changeable": value.data.name_changeable,
"value": value.data.name_value, "value": value.data.name_value,
@ -91,8 +91,6 @@ lib_plankton.zoo_page.register(
}), }),
representation => ({ representation => ({
"data": { "data": {
"membership_number_changeable": representation.membership_number.changeable,
"membership_number_value": null_when_empty(representation.membership_number.value),
"name_changeable": representation.name.changeable, "name_changeable": representation.name.changeable,
"name_value": null_when_empty(representation.name.value), "name_value": null_when_empty(representation.name.value),
"email_address_changeable": representation.email_address.changeable, "email_address_changeable": representation.email_address.changeable,
@ -129,26 +127,6 @@ lib_plankton.zoo_page.register(
), ),
"label": lib_plankton.translate.get("domain.member.name.label"), "label": lib_plankton.translate.get("domain.member.name.label"),
}, },
{
"name": "groups",
"input": new lib_plankton.zoo_input.class_input_group(
[
{
"name": "value",
"input": new lib_plankton.zoo_input.class_input_list(
() => 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.groups.label"),
},
{ {
"name": "email_address", "name": "email_address",
"input": new lib_plankton.zoo_input.class_input_group( "input": new lib_plankton.zoo_input.class_input_group(
@ -167,6 +145,45 @@ lib_plankton.zoo_page.register(
), ),
"label": lib_plankton.translate.get("domain.member.email_address.label"), "label": lib_plankton.translate.get("domain.member.email_address.label"),
}, },
{
"name": "groups",
"input": new lib_plankton.zoo_input.class_input_group(
[
{
"name": "value",
/*
"input": new lib_plankton.zoo_input.class_input_list(
() => new lib_plankton.zoo_input.class_input_text()
),
*/
"input": new lib_plankton.zoo_input.class_input_wrapped<Set<string>, Array<int>>(
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
),
(value_inner) => {
const array : Array<int> = [];
for (const group_id_encoded of value_inner)
{
array.push(parseInt(group_id_encoded));
}
return array;
},
(value_outer) => new Set<string>(value_outer.map(group_id => group_id.toFixed(0)))
),
"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.groups.label"),
},
{ {
"name": "expiry", "name": "expiry",
"input": new lib_plankton.zoo_input.class_input_soft( "input": new lib_plankton.zoo_input.class_input_soft(
@ -225,8 +242,6 @@ lib_plankton.zoo_page.register(
form.input_write( form.input_write(
{ {
"data": { "data": {
"membership_number_changeable": false,
"membership_number_value": null,
"name_changeable": false, "name_changeable": false,
"name_value": "", "name_value": "",
"email_address_changeable": true, "email_address_changeable": true,

View file

@ -51,14 +51,12 @@ lib_plankton.zoo_page.register(
null null
| |
{ {
membership_number_changeable : boolean;
membership_number_value : (null | string);
name_changeable : boolean; name_changeable : boolean;
name_value : (null | string); name_value : (null | string);
email_address_changeable : boolean; email_address_changeable : boolean;
email_address_value : (null | string); email_address_value : (null | string);
groups_changeable : boolean; groups_changeable : boolean;
groups_value : Array<string>; groups_value : Array<int>;
} }
); );
try try
@ -81,26 +79,33 @@ lib_plankton.zoo_page.register(
} }
else else
{ {
/**
* @todo cache
*/
const groups_as_array : Array<{id : int; name : string;}> = await _espe.backend.group_list();
const groups_as_map : Map<int, {name : string;}> = new Map<int, {name : string;}>();
for (const group_thingy of groups_as_array)
{
groups_as_map.set(group_thingy.id, {"name": group_thingy.name});
}
const form = new lib_plankton.zoo_form.class_form< const form = new lib_plankton.zoo_form.class_form<
{ {
membership_number : (null | string);
name : string; name : string;
email_address : (null | string); email_address : (null | string);
groups : Array<string>; groups : Array<int>;
password_value : string; password_value : string;
password_confirmation : string; password_confirmation : string;
}, },
{ {
membership_number : string;
name : string; name : string;
email_address : string; email_address : string;
groups : Array<string>; groups : Array<int>;
password_value : string; password_value : string;
password_confirmation : string; password_confirmation : string;
} }
>( >(
value => ({ value => ({
"membership_number": (value.membership_number ?? ""),
"name": value.name, "name": value.name,
"email_address": (value.email_address ?? ""), "email_address": (value.email_address ?? ""),
"groups": value.groups, "groups": value.groups,
@ -108,7 +113,6 @@ lib_plankton.zoo_page.register(
"password_confirmation": value.password_confirmation, "password_confirmation": value.password_confirmation,
}), }),
representation => ({ representation => ({
"membership_number": representation.membership_number,
"name": representation.name, "name": representation.name,
"email_address": representation.email_address, "email_address": representation.email_address,
"groups": representation.groups, "groups": representation.groups,
@ -118,16 +122,17 @@ lib_plankton.zoo_page.register(
new lib_plankton.zoo_input.class_input_group( new lib_plankton.zoo_input.class_input_group(
[ [
{ {
"name": "membership_number", "name": "name",
"input": new lib_plankton.zoo_input.class_input_text( "input": new lib_plankton.zoo_input.class_input_text(
{ {
"read_only": (! data.membership_number_changeable), "read_only": (! data.name_changeable),
} }
), ),
"label": lib_plankton.translate.get("domain.member.membership_number.label"), "label": lib_plankton.translate.get("domain.member.name.label"),
}, },
{ {
"name": "groups", "name": "groups",
/*
"input": new lib_plankton.zoo_input.class_input_list( "input": new lib_plankton.zoo_input.class_input_list(
() => new lib_plankton.zoo_input.class_input_text( () => new lib_plankton.zoo_input.class_input_text(
{ {
@ -138,16 +143,28 @@ lib_plankton.zoo_page.register(
"read_only": (! data.groups_changeable), "read_only": (! data.groups_changeable),
} }
), ),
"label": lib_plankton.translate.get("domain.member.groups.label"), */
}, "input": new lib_plankton.zoo_input.class_input_wrapped<Set<string>, Array<int>>(
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,
{ {
"name": "name", "read_only": (! data.groups_changeable),
"input": new lib_plankton.zoo_input.class_input_text(
{
"read_only": (! data.name_changeable),
} }
), ),
"label": lib_plankton.translate.get("domain.member.name_real_value.label"), (value_inner) => {
const array : Array<int> = [];
for (const group_id_encoded of value_inner)
{
array.push(parseInt(group_id_encoded));
}
return array;
},
(value_outer) => new Set<string>(value_outer.map(group_id => group_id.toFixed(0)))
),
"label": lib_plankton.translate.get("domain.member.groups.label"),
}, },
{ {
"name": "email_address", "name": "email_address",
@ -197,7 +214,6 @@ lib_plankton.zoo_page.register(
flaws = await _espe.backend.invite_accept( flaws = await _espe.backend.invite_accept(
key, key,
{ {
"membership_number": value.membership_number,
"groups": value.groups, "groups": value.groups,
"name": value.name, "name": value.name,
"email_address": value.email_address, "email_address": value.email_address,
@ -241,7 +257,6 @@ lib_plankton.zoo_page.register(
await form.setup(target_element.querySelector(".invite_handle-form") as HTMLElement); await form.setup(target_element.querySelector(".invite_handle-form") as HTMLElement);
form.input_write( form.input_write(
{ {
"membership_number": data.membership_number_value,
"name": data.name_value, "name": data.name_value,
"email_address": data.email_address_value, "email_address": data.email_address_value,
"groups": data.groups_value, "groups": data.groups_value,

View file

@ -42,26 +42,30 @@ lib_plankton.zoo_page.register(
*/ */
const null_when_empty = (str) => (((str === null) || (str === "")) ? null : str); const null_when_empty = (str) => (((str === null) || (str === "")) ? null : str);
/**
* @todo cache
*/
const groups_as_array : Array<{id : int; name : string;}> = await _espe.backend.group_list();
const groups_as_map : Map<int, {name : string;}> = new Map<int, {name : string;}>();
for (const group_thingy of groups_as_array)
{
groups_as_map.set(group_thingy.id, {"name": group_thingy.name});
}
const form = new lib_plankton.zoo_form.class_form< const form = new lib_plankton.zoo_form.class_form<
{ {
key : string; key : string;
expiry : (null | int); expiry : (null | int);
membership_number_changeable : boolean;
membership_number_value : (null | string);
name_changeable : boolean; name_changeable : boolean;
name_value : string; name_value : string;
email_address_changeable : boolean; email_address_changeable : boolean;
email_address_value : (null | string); email_address_value : (null | string);
groups_changeable : boolean; groups_changeable : boolean;
groups_value : Array<string>; groups_value : Array<int>;
}, },
{ {
key : string; key : string;
expiry : (null | lib_plankton.pit.type_datetime); expiry : (null | lib_plankton.pit.type_datetime);
membership_number : {
changeable : boolean;
value : string;
};
name : { name : {
changeable : boolean; changeable : boolean;
value : string; value : string;
@ -72,7 +76,7 @@ lib_plankton.zoo_page.register(
}; };
groups : { groups : {
changeable : boolean; changeable : boolean;
value : Array<string>; value : Array<int>;
}; };
url : string; url : string;
} }
@ -86,10 +90,6 @@ lib_plankton.zoo_page.register(
lib_plankton.pit.to_datetime(lib_plankton.pit.from_unix_timestamp(value.expiry)) lib_plankton.pit.to_datetime(lib_plankton.pit.from_unix_timestamp(value.expiry))
), ),
"key": value.key, "key": value.key,
"membership_number": {
"changeable": value.membership_number_changeable,
"value": (value.membership_number_value ?? ""),
},
"name": { "name": {
"changeable": value.name_changeable, "changeable": value.name_changeable,
"value": value.name_value, "value": value.name_value,
@ -113,8 +113,6 @@ lib_plankton.zoo_page.register(
lib_plankton.pit.to_unix_timestamp(lib_plankton.pit.from_datetime(representation.expiry)) lib_plankton.pit.to_unix_timestamp(lib_plankton.pit.from_datetime(representation.expiry))
), ),
"key": representation.key, "key": representation.key,
"membership_number_changeable": representation.membership_number.changeable,
"membership_number_value": null_when_empty(representation.membership_number.value),
"name_changeable": representation.name.changeable, "name_changeable": representation.name.changeable,
"name_value": representation.name.value, "name_value": representation.name.value,
"email_address_changeable": representation.email_address.changeable, "email_address_changeable": representation.email_address.changeable,
@ -159,9 +157,28 @@ lib_plankton.zoo_page.register(
[ [
{ {
"name": "value", "name": "value",
/*
"input": new lib_plankton.zoo_input.class_input_list( "input": new lib_plankton.zoo_input.class_input_list(
() => new lib_plankton.zoo_input.class_input_text(), () => new lib_plankton.zoo_input.class_input_text(),
{"read_only": true} {"read_only": true}
),
*/
"input": new lib_plankton.zoo_input.class_input_wrapped<Set<string>, Array<int>>(
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
),
(value_inner) => {
const array : Array<int> = [];
for (const group_id_encoded of value_inner)
{
array.push(parseInt(group_id_encoded));
}
return array;
},
(value_outer) => new Set<string>(value_outer.map(group_id => group_id.toFixed(0)))
), ),
"label": indent(lib_plankton.translate.get("common.initial_value")), "label": indent(lib_plankton.translate.get("common.initial_value")),
}, },
@ -216,14 +233,12 @@ lib_plankton.zoo_page.register(
const data : { const data : {
key: string; key: string;
expiry : (null | int); expiry : (null | int);
membership_number_changeable : boolean;
membership_number_value : (null | string);
name_changeable : boolean; name_changeable : boolean;
name_value : string; name_value : string;
email_address_changeable : boolean; email_address_changeable : boolean;
email_address_value : (null | string); email_address_value : (null | string);
groups_changeable : boolean; groups_changeable : boolean;
groups_value : Array<string>; groups_value : Array<int>;
} = await _espe.backend.invite_read(id); } = await _espe.backend.invite_read(id);
form.input_write(data); form.input_write(data);

View file

@ -1,98 +0,0 @@
/*
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
<https://www.gnu.org/licenses/>.
*/
lib_plankton.zoo_page.register(
"member_create",
(parameters, target_element) => {
target_element.appendChild(template_request("member_create"));
target_element.querySelector(".member_create-title").textContent = lib_plankton.translate.get("page.member_create.title");
const form = new lib_plankton.zoo_form.class_form<
{
membership_number : string;
name_real_value : string;
email_address_private : (null | string);
groups : Array<string>;
},
{
membership_number : string;
name_real_value : string;
email_address_private : string;
groups : Array<string>;
}
>(
value => ({
"membership_number": value.membership_number,
"name_real_value": value.name_real_value,
"email_address_private": (value.email_address_private ?? ""),
"groups": value.groups,
}),
representation => ({
"membership_number": representation.membership_number,
"name_real_value": representation.name_real_value,
"email_address_private": representation.email_address_private,
"groups": representation.groups,
}),
new lib_plankton.zoo_input.class_input_group(
[
{
"name": "name_real_value",
"input": new lib_plankton.zoo_input.class_input_text(),
"label": lib_plankton.translate.get("domain.member.name_real_value.label"),
},
{
"name": "membership_number",
"input": new lib_plankton.zoo_input.class_input_text(),
"label": lib_plankton.translate.get("domain.member.membership_number.label"),
},
{
"name": "email_address_private",
"input": new lib_plankton.zoo_input.class_input_text(),
"label": lib_plankton.translate.get("domain.member.email_address_private.label")
},
{
"name": "groups",
"input": new lib_plankton.zoo_input.class_input_list(
() => new lib_plankton.zoo_input.class_input_text()
),
"label": lib_plankton.translate.get("domain.member.groups.label"),
},
]
),
[
{
"label": lib_plankton.translate.get("page.member_register.form.submit"),
"procedure": async (get_value, get_representation) => {
const value = await get_value();
const id : int = await _espe.backend.member_project(
value,
lib_plankton.zoo_page.encode(
{
"name": "member_view",
"parameters": {
"id": "{{id}}",
}
}
)
);
lib_plankton.zoo_page.set({"name": "member_view", "parameters": {"id": id}});
},
}
]
);
form.setup(target_element.querySelector(".member_create-form") as HTMLElement);
}
);

View file

@ -1,19 +0,0 @@
<!--
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
<https://www.gnu.org/licenses/>.
-->
<template id="member_create">
<h2 class="member_create-title"></h2>
<div class="member_create-form"></div>
</template>

View file

@ -1,15 +0,0 @@
/*
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
<https://www.gnu.org/licenses/>.
*/

View file

@ -29,6 +29,7 @@ lib_plankton.zoo_page.register(
target_element.querySelector(".member_list-title").textContent = lib_plankton.translate.get("page.member_list.title"); target_element.querySelector(".member_list-title").textContent = lib_plankton.translate.get("page.member_list.title");
// create link // create link
/*
{ {
const element : HTMLElement = target_element.querySelector(".member_list-create"); const element : HTMLElement = target_element.querySelector(".member_list-create");
element.setAttribute( element.setAttribute(
@ -43,6 +44,7 @@ lib_plankton.zoo_page.register(
); );
element.textContent = lib_plankton.translate.get("page.member_create.title"); element.textContent = lib_plankton.translate.get("page.member_create.title");
} }
*/
const search : lib_plankton.zoo_search.type_search<type_item> = lib_plankton.zoo_search.make<type_item>( const search : lib_plankton.zoo_search.type_search<type_item> = lib_plankton.zoo_search.make<type_item>(
(term) => _espe.backend.member_list(term), (term) => _espe.backend.member_list(term),

View file

@ -1,232 +0,0 @@
/*
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
<https://www.gnu.org/licenses/>.
*/
lib_plankton.zoo_page.register(
"member_register",
async (parameters, target_element) => {
function set_state(
state : ("load" | "fill" | "wait" | "done"),
messages : Array<string> = []
) : void
{
target_element.querySelector(".member_register").setAttribute("rel", state);
target_element.querySelector(".member_register-message").textContent = "";
let dom_list = document.createElement("ul");
messages.forEach(
message => {
let dom_message = document.createElement("li");
dom_message.textContent = message;
dom_list.appendChild(dom_message);
}
);
target_element.querySelector(".member_register-message").appendChild(dom_list);
}
// parameters
const id : int = parseInt(parameters["id"]);
const verification : string = parameters["verification"];
// const verification : string = (new URLSearchParams(location.search)).get("verification");
update_nav({"mode": null});
target_element.appendChild(template_request("member_register"));
set_state(
"load",
[
]
);
let member_data : (
null
|
{
name_real_value : string;
name_real_index : int;
name_login : string;
email_address_veiled : string;
email_address_nominal : string;
}
);
try {
member_data = await _espe.backend.member_info(id, verification);
}
catch (error) {
member_data = null;
}
if (member_data === null) {
set_state(
"fill",
[
lib_plankton.translate.get("page.member_register.flaw.already_registered"),
]
);
}
else {
// title
{
target_element.querySelector(".member_register-title").textContent = lib_plankton.translate.get("page.member_register.title");
}
// info
{
}
// form
{
let input : lib_plankton.zoo_input.interface_input<
{
email_address : ("none" | "only_veiled" | "both");
email_redirect : boolean;
password_value : string;
password_confirmation : string;
}
>;
// input
{
input = new lib_plankton.zoo_input.class_input_group(
[
{
"name": "email_address",
"input": new lib_plankton.zoo_input.class_input_enumeration(
[
{
"value": "none",
"label": lib_plankton.translate.get("page.member_register.form.field.email_address.option.none"),
},
{
"value": "only_veiled",
"label": lib_plankton.translate.get("page.member_register.form.field.email_address.option.only_veiled"),
},
{
"value": "both",
"label": lib_plankton.translate.get("page.member_register.form.field.email_address.option.both"),
},
]
),
"label": lib_plankton.translate.get("page.member_register.form.field.email_address.label"),
"help": lib_plankton.translate.get(
"page.member_register.form.field.email_address.help",
{
"email_address_veiled": member_data.email_address_veiled,
"email_address_nominal": member_data.email_address_nominal,
}
),
},
{
"name": "email_redirect",
"input": new lib_plankton.zoo_input.class_input_checkbox(
),
"label": lib_plankton.translate.get("page.member_register.form.field.email_redirect.label"),
},
{
"name": "password_value",
"input": new lib_plankton.zoo_input.class_input_password(
),
"label": lib_plankton.translate.get("page.member_register.form.field.password_value.label"),
"help": lib_plankton.translate.get("page.member_register.form.field.password_value.help"),
},
{
"name": "password_confirmation",
"input": new lib_plankton.zoo_input.class_input_password(
),
"label": lib_plankton.translate.get("page.member_register.form.field.password_confirmation.label"),
},
]
);
await input.setup(target_element.querySelector(".member_register-form-input") as HTMLElement);
await input.write(
{
"email_address": _espe.conf.get().settings.registration_defaults.email_address,
"email_redirect": _espe.conf.get().settings.registration_defaults.email_redirect,
"password_value": "",
"password_confirmation": "",
}
);
}
// actions
{
target_element.querySelector(".member_register-form-action-send").textContent = lib_plankton.translate.get("page.member_register.form.submit");
target_element.querySelector(".member_register-form-action-send").addEventListener(
"click",
async (event) => {
const value : {
email_address : ("none" | "only_veiled" | "both");
email_redirect : boolean;
password_value : string;
password_confirmation : string;
} = await input.read();
let flaws : Array<{incident : string; details : Record<string, any>;}>;
set_state(
"wait",
[
]
);
if (value.password_value !== value.password_confirmation) {
flaws = [
{"incident": "password_mismatch", "details": {}},
];
}
else {
try {
flaws = await _espe.backend.member_register(
id,
verification,
{
"email_use_veiled_address": (value.email_address !== "none"),
"email_use_nominal_address": (value.email_address === "both"),
"email_redirect_to_private_address": value.email_redirect,
"password": value.password_value,
},
lib_plankton.zoo_page.encode(
{
"name": "member_view",
"parameters": {
"id": "{{id}}",
}
}
)
);
}
catch (error) {
flaws = [
{"incident": "unhandled_error", "details": {}},
];
}
}
if (flaws.length > 0) {
set_state(
"fill",
flaws.map(
flaw => lib_plankton.string.coin(
lib_plankton.translate.get("page.member_register.flaw." + flaw.incident),
flaw.details
)
)
);
}
else {
set_state(
"done",
[
lib_plankton.translate.get("page.member_register.success")
]
);
}
}
);
}
}
}
},
);

View file

@ -1,31 +0,0 @@
<!--
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
<https://www.gnu.org/licenses/>.
-->
<template id="member_register">
<section class="member_register">
<h2 class="member_register-title"></h2>
<div class="member_register-info">
</div>
<div class="member_register-message">
</div>
<div class="member_register-form">
<div class="member_register-form-input">
</div>
<div class="member_register-form-actions">
<button class="member_register-form-action-send"></button>
</div>
</div>
</section>
</template>

View file

@ -1,27 +0,0 @@
/*
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
<https://www.gnu.org/licenses/>.
*/
.member_register:not([rel]) .member_register-message {display: none;}
.member_register:not([rel]) .member_register-form {display: none;}
.member_register[rel="fill"] .member_register-message {}
.member_register[rel="fill"] .member_register-form {}
.member_register[rel="wait"] .member_register-message {}
.member_register[rel="wait"] .member_register-form {display: none;}
.member_register[rel="done"] .member_register-message {}
.member_register[rel="done"] .member_register-form {display: none;}

View file

@ -44,7 +44,7 @@ lib_plankton.zoo_page.register(
}, },
{ {
name : string; name : string;
groups : Set<string>; groups : Array<int>;
enabled : boolean; enabled : boolean;
email_address : (null | string); email_address : (null | string);
password_set : boolean; password_set : boolean;
@ -52,21 +52,14 @@ lib_plankton.zoo_page.register(
>( >(
value => ({ value => ({
"name": value.name, "name": value.name,
"groups": new Set<string>(value.groups.map(group_id => group_id.toFixed(0))), "groups": value.groups,
"enabled": value.enabled, "enabled": value.enabled,
"email_address": value.email_address, "email_address": value.email_address,
"password_set": value.password_set, "password_set": value.password_set,
}), }),
representation => ({ representation => ({
"name": representation.name, "name": representation.name,
"groups": (() => { "groups": representation.groups,
const array : Array<int> = [];
for (const group_id_encoded of representation.groups)
{
array.push(parseInt(group_id_encoded));
}
return array;
}) (),
"enabled": representation.enabled, "enabled": representation.enabled,
"email_address": representation.email_address, "email_address": representation.email_address,
"password_set": representation.password_set, "password_set": representation.password_set,
@ -78,21 +71,6 @@ lib_plankton.zoo_page.register(
"input": new lib_plankton.zoo_input.class_input_text({"read_only": true}), "input": new lib_plankton.zoo_input.class_input_text({"read_only": true}),
"label": lib_plankton.translate.get("domain.member.name.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_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"),
},
{ {
"name": "enabled", "name": "enabled",
"input": new lib_plankton.zoo_input.class_input_checkbox(), "input": new lib_plankton.zoo_input.class_input_checkbox(),
@ -108,6 +86,32 @@ lib_plankton.zoo_page.register(
"input": new lib_plankton.zoo_input.class_input_text(), "input": new lib_plankton.zoo_input.class_input_text(),
"label": lib_plankton.translate.get("domain.member.email_address.label"), "label": lib_plankton.translate.get("domain.member.email_address.label"),
}, },
{
"name": "groups",
/*
"input": new lib_plankton.zoo_input.class_input_list(
() => new lib_plankton.zoo_input.class_input_number()
),
*/
"input": new lib_plankton.zoo_input.class_input_wrapped<Set<string>, Array<int>>(
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
),
(value_inner) => {
const array : Array<int> = [];
for (const group_id_encoded of value_inner)
{
array.push(parseInt(group_id_encoded));
}
return array;
},
(value_outer) => new Set<string>(value_outer.map(group_id => group_id.toFixed(0)))
),
"label": lib_plankton.translate.get("domain.member.groups.label"),
},
] ]
), ),
( (

View file

@ -45,10 +45,8 @@ ${dir_temp}/logic-unlinked.js: \
${dir_source}/pages/group_list/logic.ts \ ${dir_source}/pages/group_list/logic.ts \
${dir_source}/pages/group_view/logic.ts \ ${dir_source}/pages/group_view/logic.ts \
${dir_source}/pages/group_create/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_list/logic.ts \
${dir_source}/pages/member_view/logic.ts \ ${dir_source}/pages/member_view/logic.ts \
${dir_source}/pages/member_register/logic.ts \
${dir_source}/pages/password_change_init/logic.ts \ ${dir_source}/pages/password_change_init/logic.ts \
${dir_source}/pages/password_change_exec/logic.ts \ ${dir_source}/pages/password_change_exec/logic.ts \
${dir_source}/pages/invite_list/logic.ts \ ${dir_source}/pages/invite_list/logic.ts \
@ -73,10 +71,8 @@ ${dir_build}/style.css: \
${dir_source}/pages/group_list/style.css \ ${dir_source}/pages/group_list/style.css \
${dir_source}/pages/group_view/style.css \ ${dir_source}/pages/group_view/style.css \
${dir_source}/pages/group_create/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_list/style.css \
${dir_source}/pages/member_view/style.css \ ${dir_source}/pages/member_view/style.css \
${dir_source}/pages/member_register/style.css \
${dir_source}/pages/password_change_init/style.css \ ${dir_source}/pages/password_change_init/style.css \
${dir_source}/pages/password_change_exec/style.css \ ${dir_source}/pages/password_change_exec/style.css \
${dir_source}/pages/invite_list/style.css \ ${dir_source}/pages/invite_list/style.css \
@ -95,10 +91,8 @@ ${dir_build}/index.html: \
${dir_source}/pages/group_list/structure.html \ ${dir_source}/pages/group_list/structure.html \
${dir_source}/pages/group_view/structure.html \ ${dir_source}/pages/group_view/structure.html \
${dir_source}/pages/group_create/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_list/structure.html \
${dir_source}/pages/member_view/structure.html \ ${dir_source}/pages/member_view/structure.html \
${dir_source}/pages/member_register/structure.html \
${dir_source}/pages/password_change_init/structure.html \ ${dir_source}/pages/password_change_init/structure.html \
${dir_source}/pages/password_change_exec/structure.html \ ${dir_source}/pages/password_change_exec/structure.html \
${dir_source}/pages/invite_list/structure.html \ ${dir_source}/pages/invite_list/structure.html \