Compare commits

..

12 commits

Author SHA1 Message Date
Christian Fraß e5db07c192 [task-193] clean localizations 2025-08-25 12:21:21 +00:00
Christian Fraß 4b3c0beb93 [int] 2025-08-23 14:30:09 +02:00
Christian Fraß cfdfb96d7d [int] 2025-08-22 17:42:07 +02:00
Christian Fraß d5ff6ac576 invite -> invitation 2025-08-22 17:07:39 +02:00
Christian Fraß 9d1a0c856c [int] 2025-08-22 16:57:14 +02:00
Christian Fraß 17f432ab10 [int] 2025-08-22 10:53:20 +02:00
Christian Fraß b29730fffd [int] 2025-08-21 22:45:57 +00:00
Christian Fraß 9f0468ac0d [int] 2025-08-21 21:45:39 +00:00
Christian Fraß a0c0e9eb22 [task-193] [int] 2025-07-03 08:53:22 +00:00
Christian Fraß 1f91b8f9c8 [task-193] 2025-07-02 18:33:14 +02:00
Christian Fraß 76a2d7dff4 [task-193] [int] 2025-04-12 10:19:59 +00:00
Christian Fraß b2eeb3f1fe [task-193] [int] 2025-04-03 11:47:47 +00:00
32 changed files with 314 additions and 5362 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -4,8 +4,5 @@
"host": "localhost",
"port": 4916,
"path_base": ""
},
"settings": {
"title": "Lokaler Espe-Test"
}
}

View file

@ -1,8 +1,8 @@
# Espe | Frontend: Zackeneule
# Espe | Frontend
## Beschreibung
- Web-Anwendung für [Espe](/misc/espe-meta)
- Web-Anwendung für [Espe](https://gitlab.die-linke.cloud/espe/documentation)
## Erstellung

View file

@ -9,31 +9,19 @@
"common.timezone_shift": "Zeitzonen-Verschiebung",
"common.date": "Datum",
"common.time": "Uhzeit",
"common.loading": "laden …",
"common.checking": "prüfen …",
"domain.group.name.label": "Name",
"domain.group.label.label": "Beschriftung",
"domain.member.member": "Mitglied",
"domain.member.name.label": "Anmeldename",
"domain.member.name.help": "der Name für die Anmeldung bei den Netz-Diensten.\n\nkann später NICHT mehr geändert werden",
"domain.member.label.label": "Anzeigename",
"domain.member.label.help": "wie du angezeigt wirst\n\nkann später geändert werden",
"domain.member.name.label": "Name",
"domain.member.label.label": "Beschriftung",
"domain.member.groups.label": "Gruppen",
"domain.member.groups.help": "die Gruppen, denen du zugeordnet bist",
"domain.member.registered.label": "registriert",
"domain.member.enabled.label": "aktiviert",
"domain.member.email_address.label": "E-Mail-Adresse",
"domain.member.email_address.help": "für Benachrichtigungen von Diensten",
"domain.member.password_set.label": "Passwort gesetzt",
"domain.invitation.key.label": "Schlüssel",
"domain.invitation.expiry.label": "Ablaufzeitpunkt",
"domain.invitation.url.label": "URL",
"widget.password_policy.title": "Passwort-Richtlinien",
"widget.password_policy.minimum_length": "mindestens {{minimum_length}} Zeichen",
"widget.password_policy.maximum_length": "höchstens {{maximum_length}} Zeichen",
"widget.password_policy.must_contain_letter": "muss einen Buchstaben beinhalten",
"widget.password_policy.must_contain_number": "muss eine Zahl beinhalten",
"widget.password_policy.must_contain_special_character": "muss ein Sonderzeichen beinhalten",
"page.login.title": "Anmelden",
"page.login.name": "Name",
"page.login.password": "Passwort",
@ -42,7 +30,6 @@
"page.group_list.title": "Gruppen",
"page.group_create.title": "Gruppe anlegen",
"page.group_create.form.submit": "Abschicken",
"page.group_view.title": "Gruppe bearbeiten",
"page.member_create.title": "Mitglied anlegen",
"page.member_list.title": "Mitglieder",
"page.member_view.title": "Mitglied",
@ -71,18 +58,22 @@
"page.invitation_create.title": "Einladung anlegen",
"page.invitation_create.form.field.send_immediatly.label": "Link sofort versenden",
"page.invitation_create.form.action.submit": "anlegen",
"page.invitation_view.form.action.delete": "löschen",
"page.invitation_view.title": "Einladung",
"page.invitation_handle.title": "Einladung",
"page.invitation_handle.message.invalid": "ungültig",
"page.invitation_handle.message.successful": "erfolgreich; eine E-Mail mit Zugangsdaten wird an die angegebene Adresse geschickt",
"page.invitation_handle.message.successful": "erfolgreich",
"page.invitation_handle.form.action.submit": "annehmen",
"page.invitation_handle.form.field.password_value.label": "Passwort",
"page.invitation_handle.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.invitation_handle.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.invitation_handle.form.field.password_confirmation.label": "Passwort wiederholen",
"page.invitation_handle.form.field.password_confirmation.help": "",
"page.invitation_handle.flaw.already_registered": "bereits registriert",
"page.invitation_handle.flaw.password_invalid": "Passwort ungültig",
"page.invitation_handle.flaw.password_mismatch": "die Passwörter stimmen nicht überein",
"page.invitation_handle.flaw.password_too_short": "das Passwort muss mindestens {{minimum_length}} Zeichen haben",
"page.invitation_handle.flaw.password_too_long": "das Passwort darf höchstens {{maximum_length}} Zeichen haben",
"page.invitation_handle.flaw.password_lacks_letter": "das Passwort muss einen Buchstaben beinhalten",
"page.invitation_handle.flaw.password_lacks_number": "das Passwort muss eine Zahl beinhalten",
"page.invitation_handle.flaw.password_lacks_special_character": "das Passwort muss ein Sonderzeichen beinhalten",
"page.invitation_handle.flaw.unhandled_error": "da ist etwas schief gelaufen :/"
}
}

View file

@ -9,80 +9,71 @@
"common.timezone_shift": "timezone shift",
"common.date": "date",
"common.time": "time",
"common.loading": "loading …",
"common.checking": "checking …",
"domain.group.name.label": "name",
"domain.group.label.label": "label",
"domain.member.member": "member",
"domain.member.name.label": "login name",
"domain.member.name.help": "the name for logging in to the online services\n\ncan NOT be changed later on",
"domain.member.label.label": "display name",
"domain.member.label.help": "how you are displayed\n\ncan be changed later on",
"domain.member.name.label": "name",
"domain.member.label.label": "label",
"domain.member.groups.label": "groups",
"domain.member.groups.help": "groups, which you belong to",
"domain.member.registered.label": "registered",
"domain.member.enabled.label": "enabled",
"domain.member.email_address.label": "e-mail address",
"domain.member.email_address.help": "for notifications from services",
"domain.member.password_set.label": "password set",
"domain.invitation.key.label": "key",
"domain.invitation.expiry.label": "expiration",
"domain.invitation.url.url": "URL",
"widget.password_policy.title": "password policy",
"widget.password_policy.minimum_length": "at least {{minimum_length}} characters",
"widget.password_policy.maximum_length": "at most {{maximum_length}} characters",
"widget.password_policy.must_contain_letter": "must contain a letter",
"widget.password_policy.must_contain_number": "must contain a number",
"widget.password_policy.must_contain_special_character": "must contain a special character",
"page.login.title": "login",
"page.login.name": "name",
"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.title": "Create group",
"page.group_create.form.submit": "submit",
"page.group_view.title": "edit group",
"page.member_create.title": "Create member",
"page.member_list.title": "members",
"page.member_view.title": "member",
"page.member_list.title": "Members",
"page.member_view.title": "Member",
"page.member_view.form.action.save": "save changes",
"page.password_change_init.title": "change Password",
"page.password_change_init.info": "in case your member account can be found, an e-mail with further instructions will be sent to your private e-mail address.",
"page.password_change_init.identifier": "login name or private e-mail address",
"page.password_change_init.submit": "procede",
"page.password_change_init.title": "Change Password",
"page.password_change_init.info": "In case your member account can be found, an e-mail with further instructions will be sent to your private e-mail address.",
"page.password_change_init.identifier": "Login name or private e-mail address",
"page.password_change_init.submit": "Procede",
"page.password_change_init.status.wait": "just a second …",
"page.password_change_init.status.success": "Done. Take a look into your e-mail inbox",
"page.password_change_init.status.fail": "something went wrong :/",
"page.password_change_exec.title": "change password",
"page.password_change_init.status.fail": "Something went wrong :/",
"page.password_change_exec.title": "Change Password",
"page.password_change_exec.form.field.password_value.label": "password",
"page.password_change_exec.form.field.password_confirmation.label": "confirm password",
"page.password_change_exec.form.submit": "change",
"page.password_change_exec.form.submit": "Change",
"page.password_change_exec.flaw.token_invalid": "permission expired",
"page.password_change_exec.flaw.password_mismatch": "the passwords do not match",
"page.password_change_exec.flaw.password_too_short": "the password must have at least {{minimum_length}} characters",
"page.password_change_exec.flaw.password_too_long": "the password must have at most {{maximum_length}} characters",
"page.password_change_exec.flaw.password_lacks_letter": "the password must contain a letter",
"page.password_change_exec.flaw.password_lacks_number": "the password must contain a number",
"page.password_change_exec.flaw.password_lacks_special_character": "the password must contain a special character",
"page.password_change_exec.flaw.unhandled_error": "something went wrong :/",
"page.password_change_exec.flaw.password_mismatch": "die Passwörter stimmen nicht überein",
"page.password_change_exec.flaw.password_too_short": "das Passwort muss mindestens {{minimum_length}} Zeichen haben",
"page.password_change_exec.flaw.password_too_long": "das Passwort darf höchstens {{maximum_length}} Zeichen haben",
"page.password_change_exec.flaw.password_lacks_letter": "das Passwort muss einen Buchstaben beinhalten",
"page.password_change_exec.flaw.password_lacks_number": "das Passwort muss ein Zahl beinhalten",
"page.password_change_exec.flaw.password_lacks_special_character": "das Passwort muss ein Sonderzeichen beinhalten",
"page.password_change_exec.flaw.unhandled_error": "da ist etwas schief gelaufen :/",
"page.password_change_exec.status.success": "done",
"page.invitation_list.title": "invitations",
"page.invitation_create.title": "create invitation",
"page.invitation_create.form.field.send_immediatly.label": "send link immediatly",
"page.invitation_create.form.action.submit": "create",
"page.invitation_view.form.action.delete": "delete",
"page.invitation_view.title": "invitation",
"page.invitation_handle.title": "invitation",
"page.invitation_handle.message.invalid": "invalid",
"page.invitation_handle.message.successful": "successful; an e-mail, containing the credentials, is sent to the provided address",
"page.invitation_handle.message.successful": "successful",
"page.invitation_handle.form.action.submit": "accept",
"page.invitation_handle.form.field.password_value.label": "password",
"page.invitation_handle.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.invitation_handle.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.invitation_handle.form.field.password_confirmation.label": "confirm password",
"page.invitation_handle.form.field.password_confirmation.help": "",
"page.invitation_handle.flaw.already_registered": "already registered",
"page.invitation_handle.flaw.password_invalid": "invalid password",
"page.invitation_handle.flaw.password_mismatch": "passwords do not match",
"page.invitation_handle.flaw.password_too_short": "the password must have at least {{minimum_length}} characters",
"page.invitation_handle.flaw.password_too_long": "the password must not have more than {{maximum_length}} characters",
"page.invitation_handle.flaw.password_lacks_letter": "the password must contain a letter",
"page.invitation_handle.flaw.password_lacks_number": "the password must contain a number",
"page.invitation_handle.flaw.password_lacks_special_character": "the password must contain a special character",
"page.invitation_handle.flaw.unhandled_error": "something went wrong :/"
}
}

View file

@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with thi
*/
namespace _zackeneule.helpers
namespace _espe.helpers
{
/**

View file

@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with thi
*/
namespace _zackeneule.logic
namespace _espe.logic
{
/**
@ -78,7 +78,7 @@ namespace _zackeneule.logic
label : string;
};
}
> = await _zackeneule.backend.group_list();
> = await _espe.backend.group_list();
const pool : Map<int, {name : string; label : string;}> = new Map<int, {name : string; label : string;}>();
const order : Array<int> = new Array<int>();
for (const entry of array)

View file

@ -25,7 +25,7 @@ async function update_nav(
options = Object.assign(
{
"mode": (
(await _zackeneule.backend.logged_in())
(await _espe.backend.logged_in())
? "logged_in"
: "logged_out"
),
@ -104,9 +104,9 @@ function setup_nav(
async function main(
) : Promise<void>
{
await _zackeneule.conf.load();
await _espe.conf.load();
await _zackeneule.backend.init();
await _espe.backend.init();
await lib_plankton.translate.initialize(
{
@ -120,7 +120,7 @@ async function main(
}
);
await _zackeneule.logic.init();
await _espe.logic.init();
await lib_plankton.zoo_page.init(
document.querySelector("main"),
@ -130,16 +130,8 @@ async function main(
);
// set title
{
const title : string = lib_plankton.string.coin(
"Espe | {{conf_title}}",
{
"conf_title": _zackeneule.conf.get().settings.title,
}
);
document.querySelector("header > h1").textContent = title;
document.querySelector("title").textContent = title;
}
document.querySelector("header > h1").textContent = _espe.conf.get().settings.title;
document.querySelector("title").textContent = _espe.conf.get().settings.title;
setup_nav();

View file

@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with thi
lib_plankton.zoo_page.register(
"group_create",
(parameters, target_element) => {
target_element.appendChild(_zackeneule.helpers.template_request("group_create"));
target_element.appendChild(_espe.helpers.template_request("group_create"));
target_element.querySelector(".group_create-title").textContent = lib_plankton.translate.get("page.group_create.title");
@ -51,9 +51,8 @@ lib_plankton.zoo_page.register(
"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 _zackeneule.backend.group_add(value);
// lib_plankton.zoo_page.set({"name": "group_view", "parameters": {"id": id}});
lib_plankton.zoo_page.set({"name": "group_list", "parameters": {}});
const id : int = await _espe.backend.group_add(value);
lib_plankton.zoo_page.set({"name": "group_view", "parameters": {"id": id}});
},
}
]

View file

@ -25,7 +25,7 @@ lib_plankton.zoo_page.register(
};
const term : (null | string) = (parameters["term"] ?? "");
target_element.appendChild(_zackeneule.helpers.template_request("group_list"));
target_element.appendChild(_espe.helpers.template_request("group_list"));
target_element.querySelector(".group_list-title").textContent = lib_plankton.translate.get("page.group_list.title");
@ -46,7 +46,7 @@ lib_plankton.zoo_page.register(
}
const search : lib_plankton.zoo_search.type_search<type_item> = lib_plankton.zoo_search.make<type_item>(
(term) => _zackeneule.backend.group_list(),
(term) => _espe.backend.group_list(),
{
"encode_item": (item) => lib_plankton.string.coin(
"{{label}}",

View file

@ -18,11 +18,11 @@ lib_plankton.zoo_page.register(
async (parameters, target_element) => {
const id : int = parseInt(parameters["id"]);
let dom_fragment : DocumentFragment = _zackeneule.helpers.template_request("group_view");
let dom_fragment : DocumentFragment = _espe.helpers.template_request("group_view");
dom_fragment.querySelector(".group_view-title").textContent = lib_plankton.translate.get("page.group_view.title");
const group_object = await _zackeneule.backend.group_get(id);
const group_object = await _espe.backend.group_get(id);
const form = new lib_plankton.zoo_form.class_form<
{
@ -55,7 +55,7 @@ lib_plankton.zoo_page.register(
"label": lib_plankton.translate.get("page.group_create.form.submit"),
"procedure": async (get_value, get_representation) => {
const value = await get_value();
await _zackeneule.backend.group_modify(id, value);
await _espe.backend.group_modify(id, value);
lib_plankton.zoo_page.set({"name": "group_list", "parameters": {}});
},
}

View file

@ -16,13 +16,13 @@ You should have received a copy of the GNU General Public License along with thi
lib_plankton.zoo_page.register(
"invitation_create",
async (parameters, target_element) => {
target_element.appendChild(_zackeneule.helpers.template_request("invitation_create"));
target_element.appendChild(_espe.helpers.template_request("invitation_create"));
target_element.querySelector(".invitation_create-title").textContent = lib_plankton.translate.get("page.invitation_create.title");
const indent = str => (/*"... " + */str);
const group_data = await _zackeneule.logic.group_data();
const group_data = await _espe.logic.group_data();
/**
* @todo unify with form of "invitation_view"
@ -92,11 +92,11 @@ lib_plankton.zoo_page.register(
representation => ({
"data": {
"name_changeable": representation.name.changeable,
"name_value": _zackeneule.helpers.null_when_empty(representation.name.value),
"name_value": _espe.helpers.null_when_empty(representation.name.value),
"label_changeable": representation.label.changeable,
"label_value": _zackeneule.helpers.null_when_empty(representation.label.value),
"label_value": _espe.helpers.null_when_empty(representation.label.value),
"email_address_changeable": representation.email_address.changeable,
"email_address_value": _zackeneule.helpers.null_when_empty(representation.email_address.value),
"email_address_value": _espe.helpers.null_when_empty(representation.email_address.value),
"groups_changeable": representation.groups.changeable,
"groups_value": representation.groups.value,
"expiry": (
@ -171,6 +171,11 @@ lib_plankton.zoo_page.register(
[
{
"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 lib_plankton.zoo_input.class_input_set(
group_data.order.map(
@ -224,9 +229,17 @@ lib_plankton.zoo_page.register(
"label": lib_plankton.translate.get("page.invitation_create.form.action.submit"),
"procedure": async (get_value, get_representation) => {
const value = await get_value();
const result : {id : int; key : string;} = await _zackeneule.backend.invitation_create(
const result : {id : int; key : string;} = await _espe.backend.invitation_create(
value.data,
value.send_immediatly
value.send_immediatly,
lib_plankton.zoo_page.encode(
{
"name": "invitation_handle",
"parameters": {
"key": "{{key}}",
}
}
)
);
lib_plankton.zoo_page.set(
false

View file

@ -16,57 +16,32 @@ You should have received a copy of the GNU General Public License along with thi
lib_plankton.zoo_page.register(
"invitation_handle",
async (parameters, target_element) => {
async function set_state(
state : ("load" | "fill" | "wait" | "error" | "success"),
function set_state(
state : ("load" | "fill" | "wait" | "done"),
messages : Array<string> = []
) : Promise<void>
) : void
{
target_element.querySelector(".invitation_handle").setAttribute("rel", state);
target_element.querySelector(".invitation_handle-message").textContent = "";
const class_ = (() => {
switch (state)
{
case "load": return lib_plankton.zoo_widget.class_panel_info;
case "wait": return lib_plankton.zoo_widget.class_panel_info;
case "error": return lib_plankton.zoo_widget.class_panel_error;
case "success": return lib_plankton.zoo_widget.class_panel_success;
default: return lib_plankton.zoo_widget.class_panel;
let dom_list = document.createElement("ul");
messages.forEach(
message => {
let dom_message = document.createElement("li");
dom_message.textContent = message;
dom_list.appendChild(dom_message);
}
}) ();
const widget : lib_plankton.zoo_widget.interface_widget = (
(messages.length <= 0)
?
new lib_plankton.zoo_widget.class_empty()
:
new class_(
(
(messages.length === 1)
?
new lib_plankton.zoo_widget.class_string(messages[0])
:
new lib_plankton.zoo_widget.class_list(
messages
.map(x => new lib_plankton.zoo_widget.class_string(x))
)
),
{
"collapseable": false,
"collapsed_initial_value": false,
}
)
);
await widget.load(target_element.querySelector(".invitation_handle-message"));
target_element.querySelector(".invitation_handle-message").appendChild(dom_list);
}
// parameters
const key : string = parameters["key"];
update_nav({"mode": null});
target_element.appendChild(_zackeneule.helpers.template_request("invitation_handle"));
await set_state(
target_element.appendChild(_espe.helpers.template_request("invitation_handle"));
set_state(
"load",
[
lib_plankton.translate.get("common.loading"),
]
);
@ -88,7 +63,7 @@ lib_plankton.zoo_page.register(
);
try
{
data = await _zackeneule.backend.invitation_examine(key);
data = await _espe.backend.invitation_examine(key);
}
catch (error)
{
@ -97,8 +72,8 @@ lib_plankton.zoo_page.register(
if (data === null)
{
await set_state(
"error",
set_state(
"done",
[
lib_plankton.translate.get("page.invitation_handle.message.invalid"),
]
@ -106,8 +81,7 @@ lib_plankton.zoo_page.register(
}
else
{
const password_policy : lib_plankton.password.type_policy = await _zackeneule.backend.password_policy();
const group_data = await _zackeneule.logic.group_data();
const group_data = await _espe.logic.group_data();
const form = new lib_plankton.zoo_form.class_form<
{
@ -150,21 +124,9 @@ lib_plankton.zoo_page.register(
"input": new lib_plankton.zoo_input.class_input_text(
{
"read_only": (! data.name_changeable),
"pattern": "^[a-z0-9_\.]+$",
}
),
"label": lib_plankton.translate.get("domain.member.name.label"),
"help": new lib_plankton.zoo_widget.class_panel_info(
new lib_plankton.zoo_widget.class_list(
lib_plankton.translate.get("domain.member.name.help")
.split("\n\n")
.map(x => new lib_plankton.zoo_widget.class_string(x))
),
{
"collapseable": true,
"collapsed_initial_value": true,
}
),
},
{
"name": "label",
@ -174,17 +136,6 @@ lib_plankton.zoo_page.register(
}
),
"label": lib_plankton.translate.get("domain.member.label.label"),
"help": new lib_plankton.zoo_widget.class_panel_info(
new lib_plankton.zoo_widget.class_list(
lib_plankton.translate.get("domain.member.label.help")
.split("\n\n")
.map(x => new lib_plankton.zoo_widget.class_string(x))
),
{
"collapseable": true,
"collapsed_initial_value": true,
}
),
},
{
"name": "email_address",
@ -194,29 +145,27 @@ lib_plankton.zoo_page.register(
}
),
"label": lib_plankton.translate.get("domain.member.email_address.label"),
"help": new lib_plankton.zoo_widget.class_panel_info(
new lib_plankton.zoo_widget.class_list(
lib_plankton.translate.get("domain.member.email_address.help")
.split("\n\n")
.map(x => new lib_plankton.zoo_widget.class_string(x))
),
{
"collapseable": true,
"collapsed_initial_value": true,
}
),
},
{
"name": "groups",
/*
"input": new lib_plankton.zoo_input.class_input_list(
() => new lib_plankton.zoo_input.class_input_text(
{
"read_only": (! data.groups_changeable),
}
),
{
"read_only": (! data.groups_changeable),
}
),
*/
"input": new lib_plankton.zoo_input.class_input_wrapped<Set<string>, Array<int>>(
new lib_plankton.zoo_input.class_input_set(
group_data.order.map(
group_id => group_id.toFixed(0)
),
group_id_encoded => group_data.pool.get(parseInt(group_id_encoded)).label,
{
"read_only": (! data.groups_changeable),
}
group_id_encoded => group_data.pool.get(parseInt(group_id_encoded)).label
),
(value_inner) => {
const array : Array<int> = [];
@ -229,68 +178,20 @@ lib_plankton.zoo_page.register(
(value_outer) => new Set<string>(value_outer.map(group_id => group_id.toFixed(0)))
),
"label": lib_plankton.translate.get("domain.member.groups.label"),
"help": new lib_plankton.zoo_widget.class_panel_info(
new lib_plankton.zoo_widget.class_list(
(
lib_plankton.translate.get("domain.member.groups.help")
.split("\n\n")
.map(x => new lib_plankton.zoo_widget.class_string(x))
)
),
{
"collapseable": true,
"collapsed_initial_value": true,
}
),
},
{
"name": "password_value",
"input": new lib_plankton.zoo_input.class_input_password(
{
"exhibit_initial_value": true,
}
),
"label": lib_plankton.translate.get("page.invitation_handle.form.field.password_value.label"),
"help": new lib_plankton.zoo_widget.class_panel_info(
new lib_plankton.zoo_widget.class_list(
(
lib_plankton.translate.get("page.invitation_handle.form.field.password_value.help")
.split("\n\n")
.map<lib_plankton.zoo_widget.interface_widget>(x => new lib_plankton.zoo_widget.class_string(x))
)
.concat(
[
new _zackeneule.widget.password_policy.class_password_policy(
password_policy,
{
"title": "Richtlinien",
}
),
]
)
),
{
"collapseable": true,
"collapsed_initial_value": true,
}
),
"help": lib_plankton.translate.get("page.invitation_handle.form.field.password_value.help"),
},
{
"name": "password_confirmation",
"input": new lib_plankton.zoo_input.class_input_password(
),
"label": lib_plankton.translate.get("page.invitation_handle.form.field.password_confirmation.label"),
/*
"help": new lib_plankton.zoo_widget.class_panel_info(
new lib_plankton.zoo_widget.class_string(
lib_plankton.translate.get("page.invitation_handle.form.field.password_confirmation.help")
),
{
"collapseable": true,
"collapsed_initial_value": true,
}
),
*/
// "help": lib_plankton.translate.get("page.invitation_handle.form.field.password_confirmation.help"),
},
]
),
@ -300,10 +201,9 @@ lib_plankton.zoo_page.register(
"procedure": async (get_value, get_representation) => {
const value = await get_value();
let flaws : Array<{incident : string; details : Record<string, any>;}>;
await set_state(
set_state(
"wait",
[
lib_plankton.translate.get("common.checking"),
]
);
if (value.password_value !== value.password_confirmation)
@ -316,7 +216,7 @@ lib_plankton.zoo_page.register(
{
try
{
const flaws_ = await _zackeneule.backend.invitation_accept(
flaws = await _espe.backend.invitation_accept(
key,
{
"label": value.label,
@ -326,21 +226,6 @@ lib_plankton.zoo_page.register(
"password": value.password_value,
}
);
flaws = (
(
flaws_
.filter(
flaw => (! flaw.incident.startsWith("password_"))
)
)
.concat(
(flaws_.find(flaw => flaw.incident.startsWith("password_")) !== undefined)
?
[{"incident": "password_invalid", "details": {}}]
:
[]
)
);
}
catch (error)
{
@ -351,8 +236,8 @@ lib_plankton.zoo_page.register(
}
if (flaws.length > 0)
{
await set_state(
"error",
set_state(
"fill",
flaws.map(
flaw => lib_plankton.string.coin(
lib_plankton.translate.get("page.invitation_handle.flaw." + flaw.incident),
@ -363,8 +248,8 @@ lib_plankton.zoo_page.register(
}
else
{
await set_state(
"success",
set_state(
"done",
[
lib_plankton.translate.get("page.invitation_handle.message.successful"),
]
@ -381,7 +266,7 @@ lib_plankton.zoo_page.register(
"label": data.label_value,
"email_address": data.email_address_value,
"groups": data.groups_value,
"password_value": lib_plankton.password.generate(password_policy),
"password_value": "",
"password_confirmation": "",
}
);

View file

@ -14,25 +14,14 @@ You should have received a copy of the GNU General Public License along with thi
*/
.invitation_handle-message
{
margin-bottom: 16px;
}
.invitation_handle:not([rel]) .invitation_handle-message {display: none;}
.invitation_handle:not([rel]) .invitation_handle-form {display: none;}
.invitation_handle[rel="load"] .invitation_handle-message {}
.invitation_handle[rel="load"] .invitation_handle-form {display: none;}
.invitation_handle[rel="fill"] .invitation_handle-message {}
.invitation_handle[rel="fill"] .invitation_handle-form {}
.invitation_handle[rel="wait"] .invitation_handle-message {}
.invitation_handle[rel="wait"] .invitation_handle-form {display: none;}
.invitation_handle[rel="error"] .invitation_handle-message {}
.invitation_handle[rel="error"] .invitation_handle-form {}
.invitation_handle[rel="success"] .invitation_handle-message {}
.invitation_handle[rel="success"] .invitation_handle-form {display: none;}
.invitation_handle[rel="done"] .invitation_handle-message {}
.invitation_handle[rel="done"] .invitation_handle-form {display: none;}

View file

@ -31,7 +31,7 @@ lib_plankton.zoo_page.register(
const term : (null | string) = (parameters["term"] ?? "");
// exec
target_element.appendChild(_zackeneule.helpers.template_request("invitation_list"));
target_element.appendChild(_espe.helpers.template_request("invitation_list"));
target_element.querySelector(".invitation_list-title").textContent = lib_plankton.translate.get("page.invitation_list.title");
@ -52,14 +52,13 @@ lib_plankton.zoo_page.register(
}
const search : lib_plankton.zoo_search.type_search<type_item> = lib_plankton.zoo_search.make<type_item>(
(term) => _zackeneule.backend.invitation_list(),
(term) => _espe.backend.invitation_list(),
{
"encode_item": (item) => (
item.preview.label_value
??
item.preview.name_value
??
lib_plankton.string.coin("[{{id}}]", {"id": item.id.toFixed(0)})
"encode_item": (item) => lib_plankton.string.coin(
"{{label}}",
{
"label": item.preview.label_value,
}
),
"hooks_begin": [
(term) => {
@ -98,7 +97,7 @@ lib_plankton.zoo_page.register(
);
/*
const data = await _zackeneule.backend.invitation_list();
const data = await _espe.backend.invitation_list();
(target_element.querySelector(".invitation_list-data") as HTMLElement).textContent = JSON.stringify(
data,
undefined,

View file

@ -31,7 +31,7 @@ lib_plankton.zoo_page.register(
// parameters
const id : int = parseInt(parameters["id"]);
target_element.appendChild(_zackeneule.helpers.template_request("invitation_view"));
target_element.appendChild(_espe.helpers.template_request("invitation_view"));
target_element.querySelector(".invitation_view-title").textContent = lib_plankton.translate.get("page.invitation_view.title");
@ -48,7 +48,7 @@ lib_plankton.zoo_page.register(
label : string;
};
}
> = await _zackeneule.backend.group_list();
> = await _espe.backend.group_list();
const groups_as_map : Map<
int,
{
@ -152,7 +152,7 @@ lib_plankton.zoo_page.register(
"label_changeable": representation.label.changeable,
"label_value": representation.label.value,
"email_address_changeable": representation.email_address.changeable,
"email_address_value": _zackeneule.helpers.null_when_empty(representation.email_address.value),
"email_address_value": _espe.helpers.null_when_empty(representation.email_address.value),
"groups_changeable": representation.groups.changeable,
"groups_value": representation.groups.value,
"url": "",
@ -161,7 +161,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.invitation.url.label"),
},
{
@ -193,7 +193,7 @@ lib_plankton.zoo_page.register(
[
{
"name": "value",
"input": new lib_plankton.zoo_input.class_input_text({"read_only": true}),
"input": new lib_plankton.zoo_input.class_input_text(),
"label": indent(lib_plankton.translate.get("common.initial_value")),
},
{
@ -229,13 +229,18 @@ lib_plankton.zoo_page.register(
[
{
"name": "value",
/*
"input": new lib_plankton.zoo_input.class_input_list(
() => new lib_plankton.zoo_input.class_input_text(),
{"read_only": true}
),
*/
"input": new lib_plankton.zoo_input.class_input_wrapped<Set<string>, Array<int>>(
new lib_plankton.zoo_input.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)).label,
{"read_only": true}
group_id_encoded => groups_as_map.get(parseInt(group_id_encoded)).label
),
(value_inner) => {
const array : Array<int> = [];
@ -275,19 +280,6 @@ lib_plankton.zoo_page.register(
]
),
[
{
"label": lib_plankton.translate.get("page.invitation_view.form.action.delete"),
"procedure": async () => {
await _zackeneule.backend.invitation_delete(id);
lib_plankton.zoo_page.set(
{
"name": "invitation_list",
"parameters": {
}
}
);
},
},
]
);
await form.setup(target_element.querySelector(".invitation_view-form") as HTMLElement);
@ -303,7 +295,7 @@ lib_plankton.zoo_page.register(
email_address_value : (null | string);
groups_changeable : boolean;
groups_value : Array<int>;
} = await _zackeneule.backend.invitation_read(id);
} = await _espe.backend.invitation_read(id);
form.input_write(data);
}

View file

@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with thi
lib_plankton.zoo_page.register(
"login",
(parameters, target_element) => {
target_element.appendChild(_zackeneule.helpers.template_request("login"));
target_element.appendChild(_espe.helpers.template_request("login"));
target_element.querySelector(".login-title").textContent = lib_plankton.translate.get("page.login.title");
@ -52,7 +52,7 @@ lib_plankton.zoo_page.register(
"procedure": async (get_value, get_representation) => {
const value = await get_value();
(
_zackeneule.backend.login(value.name, value.password)
_espe.backend.login(value.name, value.password)
.then(
() => {
lib_plankton.zoo_page.set({"name": "member_list", "parameters": {}});

View file

@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with thi
lib_plankton.zoo_page.register(
"logout",
async (parameters, target_element) => {
await _zackeneule.backend.logout();
await _espe.backend.logout();
lib_plankton.zoo_page.set({"name": "index", "parameters": {}});
update_nav({"mode": "logged_out"});
}

View file

@ -25,7 +25,7 @@ lib_plankton.zoo_page.register(
};
const term : (null | string) = (parameters["term"] ?? "");
target_element.appendChild(_zackeneule.helpers.template_request("member_list"));
target_element.appendChild(_espe.helpers.template_request("member_list"));
target_element.querySelector(".member_list-title").textContent = lib_plankton.translate.get("page.member_list.title");
@ -48,7 +48,7 @@ lib_plankton.zoo_page.register(
*/
const search : lib_plankton.zoo_search.type_search<type_item> = lib_plankton.zoo_search.make<type_item>(
(term) => _zackeneule.backend.member_list(term),
(term) => _espe.backend.member_list(term),
{
"encode_item": (item) => lib_plankton.string.coin(
"{{label}}",

View file

@ -18,13 +18,13 @@ lib_plankton.zoo_page.register(
async (parameters, target_element) => {
const id : int = parseInt(parameters["id"]);
let dom_fragment : DocumentFragment = _zackeneule.helpers.template_request("member_view");
let dom_fragment : DocumentFragment = _espe.helpers.template_request("member_view");
dom_fragment.querySelector(".member_view-title").textContent = lib_plankton.translate.get("page.member_view.title");
const group_data = await _zackeneule.logic.group_data();
const group_data = await _espe.logic.group_data();
const member_data = await _zackeneule.backend.member_get(id);
const member_data = await _espe.backend.member_get(id);
const form = new lib_plankton.zoo_form.class_form<
{
@ -89,6 +89,11 @@ lib_plankton.zoo_page.register(
},
{
"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 lib_plankton.zoo_input.class_input_set(
group_data.order.map(
@ -116,7 +121,7 @@ lib_plankton.zoo_page.register(
"label": lib_plankton.translate.get("page.member_view.form.action.save"),
"procedure": async (get_value, get_representation) => {
const value = await get_value();
await _zackeneule.backend.member_modify(
await _espe.backend.member_modify(
id,
{
"label": value.label,

View file

@ -38,7 +38,7 @@ lib_plankton.zoo_page.register(
const token : string = parameters.token;
update_nav({"mode": null});
target_element.appendChild(_zackeneule.helpers.template_request("password_change_exec"));
target_element.appendChild(_espe.helpers.template_request("password_change_exec"));
target_element.querySelector(".password_change_exec-title").textContent = lib_plankton.translate.get("page.password_change_exec.title");
set_state(
"load",
@ -90,7 +90,7 @@ lib_plankton.zoo_page.register(
}
else {
try {
flaws = await _zackeneule.backend.member_password_change_execute(
flaws = await _espe.backend.member_password_change_execute(
id,
token,
value.password_value

View file

@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along with thi
lib_plankton.zoo_page.register(
"password_change_init",
(parameters, target_element) => {
target_element.appendChild(_zackeneule.helpers.template_request("password_change_init"));
target_element.appendChild(_espe.helpers.template_request("password_change_init"));
target_element.querySelector(".password_change_init-title").textContent = lib_plankton.translate.get("page.password_change_init.title");
target_element.querySelector(".password_change_init-info").textContent = lib_plankton.translate.get("page.password_change_init.info");
@ -49,8 +49,17 @@ lib_plankton.zoo_page.register(
target_element.querySelector(".password_change_init-stat").textContent = lib_plankton.translate.get("page.password_change_init.status.wait");
const value = await get_value();
(
_zackeneule.backend.member_password_change_initialize(
value.identifier
_espe.backend.member_password_change_initialize(
value.identifier,
lib_plankton.zoo_page.encode(
{
"name": "password_change_exec",
"parameters": {
"id": "{{id}}",
"token": "{{token}}",
}
}
)
)
.then(
() => {

View file

@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with thi
<https://www.gnu.org/licenses/>.
*/
namespace _zackeneule.backend
namespace _espe.backend
{
/**
@ -85,10 +85,10 @@ namespace _zackeneule.backend
lib_plankton.string.coin(
("{{scheme}}://{{host}}:{{port}}{{path_base}}{{path_action}}"),
{
"scheme": _zackeneule.conf.get().backend.scheme,
"host": _zackeneule.conf.get().backend.host,
"port": _zackeneule.conf.get().backend.port.toFixed(0),
"path_base": _zackeneule.conf.get().backend.path_base,
"scheme": _espe.conf.get().backend.scheme,
"host": _espe.conf.get().backend.host,
"port": _espe.conf.get().backend.port.toFixed(0),
"path_base": _espe.conf.get().backend.path_base,
"path_action": path,
}
),
@ -166,21 +166,65 @@ namespace _zackeneule.backend
/**
*/
export async function password_policy(
) : Promise<
{
minimum_length : (null | int);
maximum_length : (null | int);
must_contain_letter : boolean;
must_contain_number : boolean;
must_contain_special_character : boolean;
}
>
export async function email(
receivers : Array<string>,
subject : string,
content : string
) : Promise<void>
{
return (
abstract_call(
"GET",
"/password_policy"
"POST",
"/email",
{
"data": {
"receivers": receivers,
"subject": subject,
"content": content,
},
}
)
);
}
/**
*/
export async function verification_get(
data : any
) : Promise<string>
{
return (
abstract_call(
"POST",
"/verification/get",
{
"data": {
"data": data,
},
}
)
);
}
/**
*/
export async function verification_check(
data : any,
verification : string
) : Promise<boolean>
{
return (
abstract_call(
"POST",
"/verification/check",
{
"data": {
"data": data,
"verification": verification,
}
}
)
);
}
@ -224,7 +268,7 @@ namespace _zackeneule.backend
return (
abstract_call(
"GET",
lib_plankton.string.coin("/group/read/{{id}}", {"id": group_id.toFixed(0)})
("/group/read/" + group_id.toFixed(0))
)
);
}
@ -267,7 +311,7 @@ namespace _zackeneule.backend
return (
abstract_call(
"PATCH",
lib_plankton.string.coin("/group/modify/{{id}}", {"id": group_id.toFixed(0)}),
("/group/modify/" + group_id.toFixed(0)),
{
"data": group_object_data
}
@ -318,7 +362,7 @@ namespace _zackeneule.backend
{
return abstract_call(
"GET",
lib_plankton.string.coin("/member/read/{{id}}", {"id": id.toFixed(0)})
("/member/read/" + id.toFixed(0))
);
}
@ -337,7 +381,7 @@ namespace _zackeneule.backend
{
return abstract_call(
"PATCH",
lib_plankton.string.coin("/member/modify/{{id}}", {"id": id.toFixed(0)}),
("/member/modify/" + id.toFixed(0)),
{
"data": data
}
@ -348,7 +392,8 @@ namespace _zackeneule.backend
/**
*/
export async function member_password_change_initialize(
identifier : string
identifier : string,
url_template : string
) : Promise<string>
{
return (
@ -357,7 +402,8 @@ namespace _zackeneule.backend
"/member/password_change/initialize",
{
"data": {
"identifier": identifier
"identifier": identifier,
"url_template": url_template,
},
}
)
@ -383,7 +429,7 @@ namespace _zackeneule.backend
return (
abstract_call(
"PATCH",
lib_plankton.string.coin("/member/password_change/execute/{{id}}", {"id": id.toFixed(0)}),
("/member/password_change/execute/" + id.toFixed(0)),
{
"data": {
"token": token,
@ -447,7 +493,12 @@ namespace _zackeneule.backend
{
return abstract_call(
"GET",
lib_plankton.string.coin("/invitation/read/{{id}}", {"id": id.toFixed(0)})
lib_plankton.string.coin(
"/invitation/read?id={{id}}",
{
"id": id.toFixed(0),
}
)
);
}
@ -467,6 +518,7 @@ namespace _zackeneule.backend
expiry : (null | int);
},
send_immediatly : boolean,
notification_target_url_template : (null | string)
) : Promise<
{
id : int;
@ -480,6 +532,7 @@ namespace _zackeneule.backend
{
"data": {
"data": data,
"notification_target_url_template": notification_target_url_template,
"send_immediatly": send_immediatly,
}
}
@ -487,19 +540,6 @@ namespace _zackeneule.backend
}
/**
*/
export async function invitation_delete(
id : int
) : Promise<void>
{
return abstract_call(
"DELETE",
lib_plankton.string.coin("/invitation/delete/{{id}}", {"id": id.toFixed(0)}),
);
}
/**
*/
export async function invitation_examine(
@ -519,7 +559,12 @@ namespace _zackeneule.backend
{
return abstract_call(
"GET",
lib_plankton.string.coin("/invitation/examine?key={{key}}", {"key": key})
lib_plankton.string.coin(
"/invitation/examine?key={{key}}",
{
"key": key
}
)
);
}

View file

@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with thi
<https://www.gnu.org/licenses/>.
*/
namespace _zackeneule.conf
namespace _espe.conf
{
/**

View file

@ -157,78 +157,6 @@ nav > ul > li:hover::after
}
*/
.widget-panel
{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
.widget-panel-rule
{
flex-basis: 2%;
min-height: 8px;
cursor: pointer;
}
.widget-panel-content
{
flex-basis: 98%;
}
.widget-panel:not(.widget-panel-collapsed)
{
padding: 8px;
border-radius: 4px;
}
.widget-panel:not(.widget-panel-collapsed) > .widget-panel-rule
{
border-left: 4px solid hsl(var(--hue), 0%, 75%);
}
.widget-panel.widget-panel-collapsed > .widget-panel-rule::after
{
content: "(?)";
}
.widget-panel.widget-panel-collapsed > .widget-panel-content
{
display: none;
}
.widget-list
{
margin: 0;
padding: 0;
}
.widget-panel_info:not(.widget-panel-collapsed)
{
background-color: hsl(240, 25%, 25%);
color: hsl(240, 50%, 75%);
}
.widget-panel_warning:not(.widget-panel-collapsed)
{
background-color: hsl(60, 25%, 25%);
color: hsl(60, 50%, 75%);
}
.widget-panel_error:not(.widget-panel-collapsed)
{
background-color: hsl(0, 25%, 25%);
color: hsl(0, 50%, 75%);
}
.widget-panel_success:not(.widget-panel-collapsed)
{
background-color: hsl(120, 25%, 25%);
color: hsl(120, 50%, 75%);
}
.plankton_form_field
{
margin-bottom: 16px;
@ -246,7 +174,6 @@ nav > ul > li:hover::after
{
display: block;
margin: 8px;
text-transform: capitalize;
}
.plankton_search_item
@ -254,55 +181,9 @@ nav > ul > li:hover::after
cursor: pointer;
}
.plankton_input_password_input
{
display: inline-block;
}
.plankton_input_password_exhibit
{
margin: 8px;
padding: 8px;
background-color: hsla(var(--hue), 0%, 0%, 50%);
cursor: pointer;
display: inline-block;
font-weight: bold;
border-radius: 2px;
}
.plankton_input_password_exhibit::before
{
"content": "[";
}
.plankton_input_password_exhibit::after
{
"content": "[";
}
.plankton_input_group_field_help_content
{
display: block;
font-size: 0.75em;
margin-top: 4px;
margin-bottom: 4px;
margin-left: 8px;
}
/*
.plankton_input_group_field.plankton_input_group_field_help_active > .plankton_input_group_field_help_content
{
}
.plankton_input_group_field:not(.plankton_input_group_field_help_active) > .plankton_input_group_field_help_content
{
display: none;
}
*/
.plankton_input_group_field
{
margin-bottom: 32px;
margin-bottom: 16px;
}
.plankton_input_group_field_label

View file

@ -1,152 +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/>.
*/
namespace _zackeneule.widget.password_policy
{
/**
*/
export class class_password_policy implements lib_plankton.zoo_widget.interface_widget
{
/**
*/
private data : lib_plankton.password.type_policy;
/**
*/
private title : (null | string);
/**
*/
public constructor(
data : lib_plankton.password.type_policy,
{
"title": title = lib_plankton.translate.get("widget.password_policy.title"),
}
:
{
title ?: (null | string);
}
=
{
}
)
{
this.data = data;
this.title = title;
}
/**
*/
public load(
target_element : Element
) : Promise<void>
{
const entries : Array<string> = (
[]
// minimum_length
.concat(
(this.data.minimum_length === null)
?
[]
:
lib_plankton.translate.get(
"widget.password_policy.minimum_length",
{
"minimum_length": this.data.minimum_length.toFixed(0),
}
)
)
// maximum_length
.concat(
(this.data.minimum_length === null)
?
[]
:
lib_plankton.translate.get(
"widget.password_policy.maximum_length",
{
"maximum_length": this.data.maximum_length.toFixed(0),
}
)
)
// must_contain_letter
.concat(
(! this.data.must_contain_letter)
?
[]
:
lib_plankton.translate.get(
"widget.password_policy.must_contain_letter",
{
}
)
)
// must_contain_number
.concat(
(! this.data.must_contain_number)
?
[]
:
lib_plankton.translate.get(
"widget.password_policy.must_contain_number",
{
}
)
)
// must_contain_special_character
.concat(
(! this.data.must_contain_special_character)
?
[]
:
lib_plankton.translate.get(
"widget.password_policy.must_contain_special_character",
{
}
)
)
);
target_element.appendChild(_zackeneule.helpers.template_request("widget-password_policy"));
target_element.querySelector(".widget-password_policy").classList.toggle(
"widget-password_policy-without_title",
(this.title === null)
);
target_element.querySelector(".widget-password_policy-title").textContent = (this.title ?? "");
const element_ul : HTMLElement = target_element.querySelector(".widget-password_policy-entries");
entries.forEach(
entry => {
const element_li : HTMLElement = document.createElement("li");
element_li.textContent = entry;
element_ul.appendChild(element_li);
}
);
return Promise.resolve<void>(undefined);
}
}
}

View file

@ -1,6 +0,0 @@
<template id="widget-password_policy">
<div class="widget-password_policy">
<span class="widget-password_policy-title"></span>
<ul class="widget-password_policy-entries"></ul>
</div>
</template>

View file

@ -1,13 +0,0 @@
.widget-password_policy-title
{
display: block;
/*
font-weight: bold;
*/
}
.widget-password_policy-without_title .widget-password_policy-title
{
display: none;
}

View file

@ -19,7 +19,7 @@ def main():
"--target-directory",
type = str,
dest = "target_directory",
default = "/opt/zackeneule",
default = "/opt/espe",
metavar = "<target-directory>",
help = "directory on the target system, where the files shall be put; default: /opt/espe",
)

View file

@ -39,7 +39,6 @@ ${dir_temp}/logic-unlinked.js: \
${dir_source}/resources/backend.ts \
${dir_source}/resources/conf.ts \
${dir_source}/logic.ts \
${dir_source}/widgets/password_policy/logic.ts \
${dir_source}/pages/index/logic.ts \
${dir_source}/pages/login/logic.ts \
${dir_source}/pages/logout/logic.ts \
@ -66,7 +65,6 @@ ${dir_build}/logic.js: ${dir_lib}/plankton/plankton.js ${dir_temp}/logic-unlinke
${dir_build}/style.css: \
${dir_source}/style/main.css \
${dir_source}/widgets/password_policy/style.css \
${dir_source}/pages/index/style.css \
${dir_source}/pages/login/style.css \
${dir_source}/pages/logout/style.css \
@ -87,7 +85,6 @@ ${dir_build}/style.css: \
${dir_build}/index.html: \
${dir_source}/index.html.tpl \
${dir_source}/widgets/password_policy/structure.html \
${dir_source}/pages/index/structure.html \
${dir_source}/pages/login/structure.html \
${dir_source}/pages/logout/structure.html \

View file

@ -2,7 +2,7 @@
## consts
dir=$(pwd)/lib/plankton
dir=lib/plankton
modules=""
modules="${modules} base"
@ -10,11 +10,9 @@ modules="${modules} file"
modules="${modules} json"
modules="${modules} base64"
modules="${modules} string"
modules="${modules} password"
modules="${modules} translate"
modules="${modules} storage"
modules="${modules} cache"
modules="${modules} zoo-widget"
modules="${modules} zoo-input"
modules="${modules} zoo-form"
modules="${modules} zoo-search"
@ -24,17 +22,7 @@ modules="${modules} zoo-page"
## exec
if false
then
mkdir -p ${dir}
cd ${dir}
ptk bundle web ${modules}
cd - > /dev/null
else
mkdir -p ${dir}
mkdir /tmp/sandbox -p
cd /tmp/sandbox
ptk fetch web ${modules}
schwamm --include=/tmp/sandbox/plankton.swm.json --output=dump:logic-decl > ${dir}/plankton.d.ts
schwamm --include=/tmp/sandbox/plankton.swm.json --output=dump:logic-impl > ${dir}/plankton.js
fi
mkdir -p ${dir}
cd ${dir}
ptk bundle web ${modules}
cd - > /dev/null