[task-193] [int]

This commit is contained in:
roydfalk 2025-07-03 08:53:22 +00:00
parent 1f91b8f9c8
commit a0c0e9eb22
8 changed files with 336 additions and 55 deletions

183
misc/model.ts Normal file
View file

@ -0,0 +1,183 @@
type type_group = {
name : boolean;
};
type type_property = {
name : string;
type : (
"boolean"
|
"int"
|
"string"
);
};
type type_member = {
name : string;
groups : Array<type_group>;
email_address : (null | string);
password_image : (null | string);
active : boolean;
};
type type_model = {
groups : Array<{id : int; data : type_group;}>;
properties : Array<{id : int; data : type_property;}>;
members : Array<{id : int; data : type_member;}>;
};
const model_linke_sx : type_model = {
"groups": [
{
"id": 1,
"data": {
"name": "lv-sachsen"
}
},
{
"id": 2,
"data": {
"name": "kv-zwickau"
}
},
{
"id": 3,
"data": {
"name": "ov-glauchau"
}
},
{
"id": 4,
"data": {
"name": "lag-netzpolitik_und_gaming"
}
},
{
"id": 5,
"data": {
"name": "kv-leipzig"
}
},
{
"id": 6,
"data": {
"name": "kv-dresden"
}
},
],
"properties": [
{
"id": 1,
"data": {
"name": "real_name",
"type": "string"
}
},
{
"id": 2,
"data": {
"name": "allow_email_sending",
"type": "boolean"
}
},
],
"members": [
{
"id": 1,
"data": {
"name": "m1973476",
"groups": [1, 2, 3, 4],
"email_address": "christian.frass@dielinke-glauchau.de",
"password_image": "____",
"active": true,
"properties": [
{
"id": 1,
"value": "Christian Fraß"
},
{
"id": 2,
"value": true
},
]
}
},
{
"id": 2,
"data": {
"name": "m2487647",
"groups": [1, 2, 4, 6],
"email_address": "paul.furkert@dielinke-dresden.de",
"password_image": "____",
"active": true,
"properties": [
{
"id": 1,
"value": "Paul Furkert"
},
{
"id": 2,
"value": true
},
]
}
},
],
};
const model_ramsch_sx : type_model = {
"groups": [
{
"id": 1,
"data": {
"name": "kulturknall"
}
},
{
"id": 2,
"data": {
"name": "lixer"
}
},
{
"id": 3,
"data": {
"name": "dill"
}
},
],
"properties": [
],
"members": [
{
"id": 1,
"data": {
"name": "fenris",
"groups": [1, 2, 3],
"email_address": "roydfalk@folksprak.org",
"password_image": "____",
"active": true,
"properties": [
]
}
},
{
"id": 2,
"data": {
"name": "magda",
"groups": [2],
"email_address": "magda@zschocher.com",
"password_image": "____",
"active": true,
"properties": [
]
}
},
]
};

View file

@ -46,7 +46,7 @@
"page.member_register.form.field.email_address.option.both": "pseudonymisiert und namentlich", "page.member_register.form.field.email_address.option.both": "pseudonymisiert und namentlich",
"page.member_register.form.field.email_redirect.label": "eingehende E-Mails an private Adresse leiten", "page.member_register.form.field.email_redirect.label": "eingehende E-Mails an private Adresse leiten",
"page.member_register.form.field.email_redirect.help": "", "page.member_register.form.field.email_redirect.help": "",
"page.member_register.form.field.password_value.label": "Passwort für Netz-Dienste", "page.member_register.form.field.password_value.label": "Passwort",
"page.member_register.form.field.password_value.help": "das Passwort für die Anmeldung bei den Netz-Diensten.\n\nDu solltest dir merken oder geeignet abspeichern, was du hier einträgst.\n\nSolltest du dieses Passwort mal vergessen oder verlieren, hast du die Möglichkeit ein neues zu setzen.", "page.member_register.form.field.password_value.help": "das Passwort für die Anmeldung bei den Netz-Diensten.\n\nDu solltest dir merken oder geeignet abspeichern, was du hier einträgst.\n\nSolltest du dieses Passwort mal vergessen oder verlieren, hast du die Möglichkeit ein neues zu setzen.",
"page.member_register.form.field.password_confirmation.label": "Passwort wiederholen", "page.member_register.form.field.password_confirmation.label": "Passwort wiederholen",
"page.member_register.form.field.password_confirmation.help": "", "page.member_register.form.field.password_confirmation.help": "",
@ -87,7 +87,7 @@
"page.invite_view.title": "Einladung", "page.invite_view.title": "Einladung",
"page.invite_handle.title": "Einladung", "page.invite_handle.title": "Einladung",
"page.invite_handle.message.invalid": "ungültig", "page.invite_handle.message.invalid": "ungültig",
"page.invite_handle.message.successfull": "erfolgreich", "page.invite_handle.message.successful": "erfolgreich",
"page.invite_handle.form.action.submit": "annehmen" "page.invite_handle.form.action.submit": "annehmen"
} }
} }

View file

@ -46,7 +46,7 @@
"page.member_register.form.field.email_address.option.both": "both, veiled and namely", "page.member_register.form.field.email_address.option.both": "both, veiled and namely",
"page.member_register.form.field.email_redirect.label": "redirect incoming e-mails to private address", "page.member_register.form.field.email_redirect.label": "redirect incoming e-mails to private address",
"page.member_register.form.field.email_redirect.help": "", "page.member_register.form.field.email_redirect.help": "",
"page.member_register.form.field.password_value.label": "password for online services", "page.member_register.form.field.password_value.label": "password",
"page.member_register.form.field.password_value.help": "the password for logging in to the online services\n\nYou should remember, denote or save properly, what you enter here.\n\nIn case you forget or lose the password some day, you can reset it.", "page.member_register.form.field.password_value.help": "the password for logging in to the online services\n\nYou should remember, denote or save properly, what you enter here.\n\nIn case you forget or lose the password some day, you can reset it.",
"page.member_register.form.field.password_confirmation.label": "confirm password", "page.member_register.form.field.password_confirmation.label": "confirm password",
"page.member_register.form.field.password_confirmation.help": "", "page.member_register.form.field.password_confirmation.help": "",
@ -87,7 +87,7 @@
"page.invite_view.title": "invitation", "page.invite_view.title": "invitation",
"page.invite_handle.title": "invitation", "page.invite_handle.title": "invitation",
"page.invite_handle.message.invalid": "invalid", "page.invite_handle.message.invalid": "invalid",
"page.invite_handle.message.successfull": "successful", "page.invite_handle.message.successful": "successful",
"page.invite_handle.form.action.submit": "accept" "page.invite_handle.form.action.submit": "accept"
} }
} }

View file

@ -613,12 +613,20 @@ namespace _espe.backend
export async function invite_accept( export async function invite_accept(
key : string, key : string,
data : { data : {
membership_number_value : string; membership_number : string;
name_value : string; groups : Array<string>;
email_address_value : (null | string); name : string;
groups_value : Array<string>; email_address : (null | string);
password : string;
} }
) : Promise<void> ) : Promise<
Array<
{
incident : string;
details : Record<string, any>;
}
>
>
{ {
return abstract_call( return abstract_call(
"POST", "POST",
@ -626,10 +634,13 @@ namespace _espe.backend
{ {
"data": { "data": {
"key": key, "key": key,
"membership_number_value": data.membership_number_value, "data": {
"name_value": data.name_value, "membership_number": data.membership_number,
"email_address_value": data.email_address_value, "groups": data.groups,
"groups_value": data.groups_value, "name": data.name,
"email_address": data.email_address,
"password": data.password,
},
} }
} }
); );

View file

@ -33,7 +33,7 @@ lib_plankton.zoo_page.register(
membership_number_changeable : boolean; membership_number_changeable : boolean;
membership_number_value : (null | string); membership_number_value : (null | string);
name_changeable : boolean; name_changeable : boolean;
name_value : 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;
@ -94,7 +94,7 @@ lib_plankton.zoo_page.register(
"membership_number_changeable": representation.membership_number.changeable, "membership_number_changeable": representation.membership_number.changeable,
"membership_number_value": null_when_empty(representation.membership_number.value), "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": null_when_empty(representation.name.value),
"email_address_changeable": representation.email_address.changeable, "email_address_changeable": representation.email_address.changeable,
"email_address_value": null_when_empty(representation.email_address.value), "email_address_value": null_when_empty(representation.email_address.value),
"groups_changeable": representation.groups.changeable, "groups_changeable": representation.groups.changeable,
@ -223,7 +223,7 @@ lib_plankton.zoo_page.register(
) )
); );
lib_plankton.zoo_page.set( lib_plankton.zoo_page.set(
true false
? ?
{ {
"name": "invite_view", "name": "invite_view",

View file

@ -37,6 +37,7 @@ lib_plankton.zoo_page.register(
// parameters // parameters
const key : string = parameters["key"]; const key : string = parameters["key"];
update_nav({"mode": null});
target_element.appendChild(template_request("invite_handle")); target_element.appendChild(template_request("invite_handle"));
set_state( set_state(
"load", "load",
@ -53,7 +54,7 @@ lib_plankton.zoo_page.register(
membership_number_changeable : boolean; membership_number_changeable : boolean;
membership_number_value : (null | string); membership_number_value : (null | string);
name_changeable : boolean; name_changeable : boolean;
name_value : 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;
@ -82,34 +83,42 @@ lib_plankton.zoo_page.register(
{ {
const form = new lib_plankton.zoo_form.class_form< const form = new lib_plankton.zoo_form.class_form<
{ {
membership_number_value : (null | string); membership_number : (null | string);
name_value : string; name : string;
email_address_value : (null | string); email_address : (null | string);
groups_value : Array<string>; groups : Array<string>;
password_value : string;
password_confirmation : string;
}, },
{ {
membership_number_value : string; membership_number : string;
name_value : string; name : string;
email_address_value : string; email_address : string;
groups_value : Array<string>; groups : Array<string>;
password_value : string;
password_confirmation : string;
} }
>( >(
value => ({ value => ({
"membership_number_value": (value.membership_number_value ?? ""), "membership_number": (value.membership_number ?? ""),
"name_value": value.name_value, "name": value.name,
"email_address_value": (value.email_address_value ?? ""), "email_address": (value.email_address ?? ""),
"groups_value": value.groups_value, "groups": value.groups,
"password_value": value.password_value,
"password_confirmation": value.password_confirmation,
}), }),
representation => ({ representation => ({
"membership_number_value": representation.membership_number_value, "membership_number": representation.membership_number,
"name_value": representation.name_value, "name": representation.name,
"email_address_value": representation.email_address_value, "email_address": representation.email_address,
"groups_value": representation.groups_value, "groups": representation.groups,
"password_value": representation.password_value,
"password_confirmation": representation.password_confirmation,
}), }),
new lib_plankton.zoo_input.class_input_group( new lib_plankton.zoo_input.class_input_group(
[ [
{ {
"name": "membership_number_value", "name": "membership_number",
"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.membership_number_changeable),
@ -118,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.membership_number.label"),
}, },
{ {
"name": "groups_value", "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(
{ {
@ -132,7 +141,7 @@ lib_plankton.zoo_page.register(
"label": lib_plankton.translate.get("domain.member.groups.label"), "label": lib_plankton.translate.get("domain.member.groups.label"),
}, },
{ {
"name": "name_value", "name": "name",
"input": new lib_plankton.zoo_input.class_input_text( "input": new lib_plankton.zoo_input.class_input_text(
{ {
"read_only": (! data.name_changeable), "read_only": (! data.name_changeable),
@ -141,7 +150,7 @@ lib_plankton.zoo_page.register(
"label": lib_plankton.translate.get("domain.member.name_real_value.label"), "label": lib_plankton.translate.get("domain.member.name_real_value.label"),
}, },
{ {
"name": "email_address_value", "name": "email_address",
"input": new lib_plankton.zoo_input.class_input_text( "input": new lib_plankton.zoo_input.class_input_text(
{ {
"read_only": (! data.email_address_changeable), "read_only": (! data.email_address_changeable),
@ -149,6 +158,19 @@ 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_private.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"),
},
] ]
), ),
[ [
@ -156,26 +178,62 @@ lib_plankton.zoo_page.register(
"label": lib_plankton.translate.get("page.invite_handle.form.action.submit"), "label": lib_plankton.translate.get("page.invite_handle.form.action.submit"),
"procedure": async (get_value, get_representation) => { "procedure": async (get_value, get_representation) => {
const value = await get_value(); const value = await get_value();
let flaws : Array<{incident : string; details : Record<string, any>;}>;
set_state( set_state(
"wait", "wait",
[ [
] ]
); );
await _espe.backend.invite_accept( if (value.password_value !== value.password_confirmation)
key, {
flaws = [
{"incident": "password_mismatch", "details": {}},
];
}
else
{
try
{ {
"membership_number_value": value.membership_number_value, flaws = await _espe.backend.invite_accept(
"name_value": value.name_value, key,
"email_address_value": value.email_address_value, {
"groups_value": value.groups_value, "membership_number": value.membership_number,
"groups": value.groups,
"name": value.name,
"email_address": value.email_address,
"password": value.password_value,
}
);
} }
); catch (error)
set_state( {
"done", flaws = [
[ {"incident": "unhandled_error", "details": {}},
lib_plankton.translate.get("page.invite_handle.message.successful"), ];
] }
); }
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")
lib_plankton.translate.get("page.invite_handle.message.successful"),
]
);
}
}, },
} }
] ]
@ -183,10 +241,12 @@ 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_value": data.membership_number_value, "membership_number": data.membership_number_value,
"name_value": data.name_value, "name": data.name_value,
"email_address_value": data.email_address_value, "email_address": data.email_address_value,
"groups_value": data.groups_value, "groups": data.groups_value,
"password_value": "",
"password_confirmation": "",
} }
); );
set_state( set_state(

View file

@ -158,7 +158,7 @@ lib_plankton.zoo_page.register(
id, id,
lib_plankton.zoo_page.encode( lib_plankton.zoo_page.encode(
{ {
"name": "register", "name": "member_register",
"parameters": { "parameters": {
"id": id, "id": id,
"verification": "{{verification}}", "verification": "{{verification}}",

View file

@ -1,7 +1,21 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# 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/>.
import sys as _sys import sys as _sys
import os as _os import os as _os
import shutil as _shutil
import argparse as _argparse import argparse as _argparse
@ -16,6 +30,14 @@ def main():
metavar = "<output-directory>", metavar = "<output-directory>",
help = "output directory", help = "output directory",
) )
argument_parser.add_argument(
"-c",
"--conf-path",
type = str,
default = "",
metavar = "<conf-path>",
help = "path to conf file to be put",
)
args = argument_parser.parse_args() args = argument_parser.parse_args()
## exec ## exec
@ -28,6 +50,11 @@ def main():
" ".join(targets), " ".join(targets),
) )
) )
if (args.conf_path != ""):
_shutil.copyfile(
args.conf_path,
_os.path.join(args.output_directory, "conf.json")
)
_sys.stdout.write("%s\n" % args.output_directory) _sys.stdout.write("%s\n" % args.output_directory)