[mod] Kosmetik

This commit is contained in:
roydfalk 2024-05-01 09:53:59 +02:00
parent c42ee84034
commit bcd3e08192
11 changed files with 284 additions and 234 deletions

View file

@ -14,12 +14,13 @@
"page.view.form.field.email_address_veiled.label": "pseudonymisierte E-Mail-Adresse", "page.view.form.field.email_address_veiled.label": "pseudonymisierte E-Mail-Adresse",
"page.view.form.field.email_address_nominal.label": "namentliche E-Mail-Adresse", "page.view.form.field.email_address_nominal.label": "namentliche E-Mail-Adresse",
"page.view.form.field.email_redirect_to_private_address.label": "eingehende E-Mails zu privater Adresse umleiten", "page.view.form.field.email_redirect_to_private_address.label": "eingehende E-Mails zu privater Adresse umleiten",
"page.view.form.field.email_allow_sending.label": "Versenden von E-Mails erlaubt", "page.view.form.field.email_allow_sending.label": "Versenden von E-Mails erlauben",
"page.view.form.field.name_login.label": "Anmeldename", "page.view.form.field.name_login.label": "Anmeldename",
"page.view.form.field.password_set.label": "Passwort gesetzt", "page.view.form.field.password_set.label": "Passwort gesetzt",
"page.view.form.action.save": "Änderungen speichern", "page.view.form.action.save": "Änderungen speichern",
"page.view.form.action.summon": "Zur Registrierung auffordern", "page.view.form.action.summon": "Zur Registrierung auffordern",
"page.view.misc.summoned": "Benachrichtigung verschickt", "page.view.misc.summoned": "Benachrichtigung verschickt",
"page.view.misc.test_info": "Im Produktiv-Szenario würde an dieser Stelle eine E-Mail an die hinterlegte private E-Mail-Adresse des Mitglieds versendet werden mit einem Willkommens-Gruß und dem Aufruf folgenden Link zu öffnen:\n\n{{url}}",
"page.register.title": "Registrieren", "page.register.title": "Registrieren",
"page.register.form.field.email_address.label": "Partei-E-Mail-Adresse einrichten", "page.register.form.field.email_address.label": "Partei-E-Mail-Adresse einrichten",
"page.register.form.field.email_address.help": "Für Partei-Angelegenheiten möchten wir dir anbieten gesonderte E-Mail-Adressen zu verwenden.\n\nDeine namentliche E-Mail-Adresse würde lauten »{{email_address_nominal}}« und die pseudonymisierte »{{email_address_veiled}}«\n\nDie Partei-E-Mail-Adressen können zum Empfangen von E-Mails verwendet werden. Falls es nötig werden sollte, dass du auch E-Mails mit über die Partei-Adresse verschicken kannst, wende dich bitte an den/die Mitgliederbeauftragte:n!", "page.register.form.field.email_address.help": "Für Partei-Angelegenheiten möchten wir dir anbieten gesonderte E-Mail-Adressen zu verwenden.\n\nDeine namentliche E-Mail-Adresse würde lauten »{{email_address_nominal}}« und die pseudonymisierte »{{email_address_veiled}}«\n\nDie Partei-E-Mail-Adressen können zum Empfangen von E-Mails verwendet werden. Falls es nötig werden sollte, dass du auch E-Mails mit über die Partei-Adresse verschicken kannst, wende dich bitte an den/die Mitgliederbeauftragte:n!",
@ -33,6 +34,7 @@
"page.register.form.field.password_confirmation.label": "Passwort wiederholen", "page.register.form.field.password_confirmation.label": "Passwort wiederholen",
"page.register.form.field.password_confirmation.help": "", "page.register.form.field.password_confirmation.help": "",
"page.register.form.submit": "Abschicken", "page.register.form.submit": "Abschicken",
"page.register.flaw.already_registered": "bereits registriert",
"page.register.flaw.password_mismatch": "die Passwörter stimmen nicht überein", "page.register.flaw.password_mismatch": "die Passwörter stimmen nicht überein",
"page.register.flaw.password_too_short": "das Passwort muss mindestens {{minimum_length}} Zeichen haben", "page.register.flaw.password_too_short": "das Passwort muss mindestens {{minimum_length}} Zeichen haben",
"page.register.flaw.password_too_long": "das Passwort darf höchstens {{maximum_length}} Zeichen haben", "page.register.flaw.password_too_long": "das Passwort darf höchstens {{maximum_length}} Zeichen haben",

View file

@ -20,6 +20,7 @@
"page.view.form.action.save": "save changes", "page.view.form.action.save": "save changes",
"page.view.form.action.summon": "urge for registration", "page.view.form.action.summon": "urge for registration",
"page.view.misc.summoned": "notification sent", "page.view.misc.summoned": "notification sent",
"page.view.misc.test_info": "in a productive environment the system would now send an e-mail to the member's private address with a welcome note and a call to open the following link:\n\n{{url}}",
"page.register.title": "Register", "page.register.title": "Register",
"page.register.form.field.email_address.label": "Set up party e-mail address", "page.register.form.field.email_address.label": "Set up party e-mail address",
"page.register.form.field.email_address.help": "We offer you to use a special e-mail address for any party concerns.\n\nYour namely e-mail address would be »{{email_address_nominal}}« and the veiled one »{{email_address_veiled}}«\n\nThe party e-mail address may be used for the reception of e-mails. In case it becomes necessary for you to submit e-mails via a party address, please get in contact with your membership authority!", "page.register.form.field.email_address.help": "We offer you to use a special e-mail address for any party concerns.\n\nYour namely e-mail address would be »{{email_address_nominal}}« and the veiled one »{{email_address_veiled}}«\n\nThe party e-mail address may be used for the reception of e-mails. In case it becomes necessary for you to submit e-mails via a party address, please get in contact with your membership authority!",
@ -33,6 +34,7 @@
"page.register.form.field.password_confirmation.label": "confirm password", "page.register.form.field.password_confirmation.label": "confirm password",
"page.register.form.field.password_confirmation.help": "", "page.register.form.field.password_confirmation.help": "",
"page.register.form.submit": "submit", "page.register.form.submit": "submit",
"page.register.flaw.already_registered": "already registered",
"page.register.flaw.password_mismatch": "passwords do not match", "page.register.flaw.password_mismatch": "passwords do not match",
"page.register.flaw.password_too_short": "the password must have at least {{minimum_length}} characters", "page.register.flaw.password_too_short": "the password must have at least {{minimum_length}} characters",
"page.register.flaw.password_too_long": "the password must not have more than {{maximum_length}} characters", "page.register.flaw.password_too_long": "the password must not have more than {{maximum_length}} characters",

View file

@ -389,8 +389,8 @@ namespace _espe.backend
*/ */
export async function member_summon( export async function member_summon(
id : int, id : int,
url : string url_template : string
) : Promise<null> ) : Promise<string>
{ {
return ( return (
abstract_call( abstract_call(
@ -398,7 +398,7 @@ namespace _espe.backend
("/member/summon/" + id.toFixed(0)), ("/member/summon/" + id.toFixed(0)),
{ {
"data": { "data": {
"url_template": url, "url_template": url_template,
}, },
} }
) )

View file

@ -12,6 +12,7 @@ namespace _espe.conf
}; };
settings : { settings : {
title : string; title : string;
test_mode : boolean;
}; };
}; };
@ -46,6 +47,7 @@ namespace _espe.conf
"settings": ( "settings": (
(node_settings => ({ (node_settings => ({
"title": (node_settings["title"] ?? "Espe"), "title": (node_settings["title"] ?? "Espe"),
"test_mode": (node_settings["test_mode"] ?? false),
})) (data_raw["settings"] ?? {}) })) (data_raw["settings"] ?? {})
), ),
}; };

View file

@ -109,6 +109,7 @@ async function main(
// set title // set title
document.querySelector("header > h1").textContent = _espe.conf.get().settings.title; document.querySelector("header > h1").textContent = _espe.conf.get().settings.title;
document.querySelector("title").textContent = _espe.conf.get().settings.title;
setup_nav(); setup_nav();

View file

@ -9,7 +9,7 @@ lib_plankton.zoo_page.register(
name_real_index : int; name_real_index : int;
}; };
}; };
const term : (null | string) = (parameters["term"] ?? null); const term : (null | string) = (parameters["term"] ?? "");
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

@ -24,165 +24,184 @@ lib_plankton.zoo_page.register(
// const verification : string = (new URLSearchParams(location.search)).get("verification"); // const verification : string = (new URLSearchParams(location.search)).get("verification");
update_nav({"mode": null}); update_nav({"mode": null});
const member_data : {
name_real_value : string;
name_real_index : int;
name_login : string;
email_address_veiled : string;
email_address_nominal : string;
} = await _espe.backend.member_info(id, verification);
target_element.appendChild(template_request("register")); target_element.appendChild(template_request("register"));
set_state( set_state(
"load", "load",
[ [
] ]
); );
// title let member_data : (
{ null
target_element.querySelector(".register-title").textContent = lib_plankton.translate.get("page.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_real_value : string;
[ name_real_index : int;
{ name_login : string;
"name": "email_address", email_address_veiled : string;
"input": new lib_plankton.zoo_input.class_input_enumeration( email_address_nominal : string;
[
{
"value": "none",
"label": lib_plankton.translate.get("page.register.form.field.email_address.option.none"),
},
{
"value": "only_veiled",
"label": lib_plankton.translate.get("page.register.form.field.email_address.option.only_veiled"),
},
{
"value": "both",
"label": lib_plankton.translate.get("page.register.form.field.email_address.option.both"),
},
]
),
"label": lib_plankton.translate.get("page.register.form.field.email_address.label"),
"help": lib_plankton.translate.get(
"page.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.register.form.field.email_redirect.label"),
},
{
"name": "password_value",
"input": new lib_plankton.zoo_input.class_input_password(
),
"label": lib_plankton.translate.get("page.register.form.field.password_value.label"),
"help": lib_plankton.translate.get("page.register.form.field.password_value.help"),
},
{
"name": "password_confirmation",
"input": new lib_plankton.zoo_input.class_input_password(
),
"label": lib_plankton.translate.get("page.register.form.field.password_confirmation.label"),
},
]
);
await input.setup(target_element.querySelector(".register-form-input") as HTMLElement);
await input.write(
{
"email_address": "both",
"email_redirect": true,
"password_value": "",
"password_confirmation": "",
}
);
} }
// actions );
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.register.flaw.already_registered"),
]
);
}
else {
// title
{ {
target_element.querySelector(".register-form-action-send").textContent = lib_plankton.translate.get("page.register.form.submit"); target_element.querySelector(".register-title").textContent = lib_plankton.translate.get("page.register.title");
target_element.querySelector(".register-form-action-send").addEventListener( }
"click", // info
async (event) => { {
const value : { }
email_address : ("none" | "only_veiled" | "both"); // form
email_redirect : boolean; {
password_value : string; let input : lib_plankton.zoo_input.interface_input<
password_confirmation : string; {
} = await input.read(); email_address : ("none" | "only_veiled" | "both");
let flaws : Array<{incident : string; details : Record<string, any>;}>; email_redirect : boolean;
if (value.password_value !== value.password_confirmation) { password_value : string;
flaws = [ password_confirmation : string;
{"incident": "password_mismatch", "details": {}}, }
]; >;
} // input
else { {
set_state( input = new lib_plankton.zoo_input.class_input_group(
"wait", [
[ {
] "name": "email_address",
); "input": new lib_plankton.zoo_input.class_input_enumeration(
try { [
flaws = await _espe.backend.member_register( {
id, "value": "none",
verification, "label": lib_plankton.translate.get("page.register.form.field.email_address.option.none"),
},
{
"value": "only_veiled",
"label": lib_plankton.translate.get("page.register.form.field.email_address.option.only_veiled"),
},
{
"value": "both",
"label": lib_plankton.translate.get("page.register.form.field.email_address.option.both"),
},
]
),
"label": lib_plankton.translate.get("page.register.form.field.email_address.label"),
"help": lib_plankton.translate.get(
"page.register.form.field.email_address.help",
{ {
"email_use_veiled_address": (value.email_address !== "none"), "email_address_veiled": member_data.email_address_veiled,
"email_use_nominal_address": (value.email_address === "both"), "email_address_nominal": member_data.email_address_nominal,
"email_redirect_to_private_address": value.email_redirect,
"password": value.password_value,
} }
); ),
} },
catch (error) { {
"name": "email_redirect",
"input": new lib_plankton.zoo_input.class_input_checkbox(
),
"label": lib_plankton.translate.get("page.register.form.field.email_redirect.label"),
},
{
"name": "password_value",
"input": new lib_plankton.zoo_input.class_input_password(
),
"label": lib_plankton.translate.get("page.register.form.field.password_value.label"),
"help": lib_plankton.translate.get("page.register.form.field.password_value.help"),
},
{
"name": "password_confirmation",
"input": new lib_plankton.zoo_input.class_input_password(
),
"label": lib_plankton.translate.get("page.register.form.field.password_confirmation.label"),
},
]
);
await input.setup(target_element.querySelector(".register-form-input") as HTMLElement);
await input.write(
{
"email_address": "both",
"email_redirect": true,
"password_value": "",
"password_confirmation": "",
}
);
}
// actions
{
target_element.querySelector(".register-form-action-send").textContent = lib_plankton.translate.get("page.register.form.submit");
target_element.querySelector(".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>;}>;
if (value.password_value !== value.password_confirmation) {
flaws = [ flaws = [
{"incident": "unhandled_error", "details": {}}, {"incident": "password_mismatch", "details": {}},
]; ];
} }
} else {
if (flaws.length > 0) { set_state(
set_state( "wait",
"fill", [
flaws.map( ]
flaw => lib_plankton.string.coin( );
lib_plankton.translate.get("page.register.flaw." + flaw.incident), try {
flaw.details 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,
}
);
}
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.register.flaw." + flaw.incident),
flaw.details
)
) )
) );
); }
else {
set_state(
"done",
[
lib_plankton.translate.get("page.register.success")
]
);
}
} }
else { );
set_state( }
"done",
[
lib_plankton.translate.get("page.register.success")
]
);
}
}
);
} }
} }
}, },

View file

@ -3,6 +3,12 @@ lib_plankton.zoo_page.register(
async (parameters, target_element) => { async (parameters, target_element) => {
const id : int = parseInt(parameters["id"]); const id : int = parseInt(parameters["id"]);
let dom_fragment : DocumentFragment = template_request("view");
dom_fragment.querySelector(".view-title").textContent = lib_plankton.translate.get("page.view.title");
const member_data = await _espe.backend.member_get(id);
const form = new lib_plankton.zoo_form.class_form< const form = new lib_plankton.zoo_form.class_form<
{ {
membership_number : string; membership_number : string;
@ -52,16 +58,16 @@ lib_plankton.zoo_page.register(
"input": new lib_plankton.zoo_input.class_input_number({"read_only": true}), "input": new lib_plankton.zoo_input.class_input_number({"read_only": true}),
"label": lib_plankton.translate.get("page.view.form.field.name_real_index.label"), "label": lib_plankton.translate.get("page.view.form.field.name_real_index.label"),
}, },
{
"name": "registered",
"input": new lib_plankton.zoo_input.class_input_checkbox({"read_only": true}),
"label": lib_plankton.translate.get("page.view.form.field.registered.label"),
},
{ {
"name": "enabled", "name": "enabled",
"input": new lib_plankton.zoo_input.class_input_checkbox(), "input": new lib_plankton.zoo_input.class_input_checkbox(),
"label": lib_plankton.translate.get("page.view.form.field.enabled.label"), "label": lib_plankton.translate.get("page.view.form.field.enabled.label"),
}, },
{
"name": "registered",
"input": new lib_plankton.zoo_input.class_input_checkbox({"read_only": true}),
"label": lib_plankton.translate.get("page.view.form.field.registered.label"),
},
{ {
"name": "email_address_private", "name": "email_address_private",
"input": new lib_plankton.zoo_input.class_input_text(), "input": new lib_plankton.zoo_input.class_input_text(),
@ -99,92 +105,83 @@ lib_plankton.zoo_page.register(
}, },
] ]
), ),
[ (
{
"label": lib_plankton.translate.get("page.view.form.action.save"),
"procedure": async (get_value, get_representation) => {
const value = await get_value();
await _espe.backend.member_modify(
id,
{
"email_address_private": value.email_address_private,
"enabled": value.enabled,
"registered": value.registered,
}
);
},
},
{
"label": lib_plankton.translate.get("page.view.form.action.summon"),
"procedure": async (get_value, get_representation) => {
const url : string = (
window.location.href.split("#")[0]
+
lib_plankton.zoo_page.encode(
{
"name": "register",
"parameters": {
"id": id,
"verification": "{{verification}}",
}
}
)
);
await _espe.backend.member_summon(id, url);
/*
lib_plankton.zoo_page.set(
{
"name": "index",
"parameters": {},
}
);
*/
alert(lib_plankton.translate.get("page.view.misc.summoned"));
},
},
]
);
let dom_fragment : DocumentFragment = template_request("view");
dom_fragment.querySelector(".view-title").textContent = lib_plankton.translate.get("page.view.title");
(
Promise.all(
[ [
form.setup(dom_fragment.querySelector(".view-form") as HTMLElement), {
_espe.backend.member_get(id), "label": lib_plankton.translate.get("page.view.form.action.save"),
"procedure": async (get_value, get_representation) => {
const value = await get_value();
await _espe.backend.member_modify(
id,
{
"email_address_private": value.email_address_private,
"enabled": value.enabled,
"registered": value.registered,
}
);
},
},
] ]
) .concat(
.then( member_data.registered
([_, member_data]) => { ? []
form.input_write( : [
{ {
"membership_number": member_data.membership_number, "label": lib_plankton.translate.get("page.view.form.action.summon"),
"name_real_value": member_data.name_real_value, "procedure": async (get_value, get_representation) => {
"name_real_index": member_data.name_real_index, const url_template : string = (
"registered": member_data.registered, window.location.href.split("#")[0]
"enabled": member_data.enabled, +
"email_address_private": member_data.email_address_private, lib_plankton.zoo_page.encode(
"email_address_veiled": ( {
member_data.email_use_veiled_address "name": "register",
? member_data.email_address_veiled "parameters": {
: ("(" + lib_plankton.translate.get("common.not_used") + ")") "id": id,
), "verification": "{{verification}}",
"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, const url : string = await _espe.backend.member_summon(id, url_template);
"email_allow_sending": member_data.email_allow_sending,
"name_login": member_data.name_login, if (_espe.conf.get().settings.test_mode) {
"password_set": member_data.password_set, alert(lib_plankton.translate.get("page.view.misc.test_info", {"url": url}));
} }
); else {
} alert(lib_plankton.translate.get("page.view.misc.summoned"));
}
},
},
]
)
) )
); );
await form.setup(dom_fragment.querySelector(".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,
"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,
"password_set": member_data.password_set,
}
);
target_element.appendChild(dom_fragment); target_element.appendChild(dom_fragment);
}, },

View file

@ -1,3 +1,8 @@
.view-title
{
display: none;
}
/* /*
.view-form > .plankton_form .view-form > .plankton_form
{ {

View file

@ -6,11 +6,12 @@
<link rel="stylesheet" type="text/css" href="style.css"/> <link rel="stylesheet" type="text/css" href="style.css"/>
<script type="text/javascript" src="logic.js"></script> <script type="text/javascript" src="logic.js"></script>
<script type="text/javascript">document.addEventListener("DOMContentLoaded", () => {main();});</script> <script type="text/javascript">document.addEventListener("DOMContentLoaded", () => {main();});</script>
<title></title>
{{templates}} {{templates}}
</head> </head>
<body> <body>
<header> <header>
<h1>Espe</h1> <h1></h1>
</header> </header>
<hr/> <hr/>
<nav> <nav>

View file

@ -55,17 +55,23 @@ input[type="text"]
, ,
input[type="number"] input[type="number"]
, ,
input[type="search"]
,
input[type="password"] input[type="password"]
{ {
padding: 8px; padding: 8px;
border: 1px solid hsl(var(--hue), 0%, 50%); border: 1px solid hsl(var(--hue), 0%, 50%);
min-width: 320px;
} }
input[type="text"]:not([disabled="disabled"]) input[type="text"]:not([disabled="disabled"])
, ,
input[type="number"]:not([disabled="disabled"]) input[type="number"]:not([disabled="disabled"])
, ,
input[type="search"]:not([disabled="disabled"])
,
input[type="password"]:not([disabled="disabled"]) input[type="password"]:not([disabled="disabled"])
{ {
/* /*
@ -80,6 +86,8 @@ input[type="text"][disabled="disabled"]
, ,
input[type="number"][disabled="disabled"] input[type="number"][disabled="disabled"]
, ,
input[type="search"][disabled="disabled"]
,
input[type="password"][disabled="disabled"] input[type="password"][disabled="disabled"]
{ {
background-color: hsl(var(--hue), 0%, 12.5%); background-color: hsl(var(--hue), 0%, 12.5%);
@ -110,6 +118,14 @@ nav > ul > li
*/ */
} }
input[type="submit"]
,
button
{
font-size: 1.25em;
cursor: pointer;
}
/* /*
nav > ul > li:hover::before nav > ul > li:hover::before
{ {
@ -190,3 +206,8 @@ nav > ul > li:hover::after
text-transform: uppercase; text-transform: uppercase;
margin: 8px; margin: 8px;
} }
.plankton_search_submit
{
margin-left: 16px;
}