[task-192]

## Tasks

- [192](https://vikunja.ramsch.sx/tasks/192)

## Zugehörige MRs

- [datamodel](misc/zeitbild-datamodel#1)
- [backend](misc/zeitbild-backend#1)

Reviewed-on: misc/zeitbild-frontend-dali#1
Co-authored-by: Fenris Wolf <fenris@folksprak.org>
Co-committed-by: Fenris Wolf <fenris@folksprak.org>
This commit is contained in:
fenris 2025-09-25 17:08:18 +02:00 committed by fenris
parent 3df888ced3
commit 5e932f63fc
14 changed files with 285 additions and 8 deletions

View file

@ -54,6 +54,17 @@
"page.login.internal.do": "Anmelden", "page.login.internal.do": "Anmelden",
"page.login.oidc.via": "via {{title}}", "page.login.oidc.via": "via {{title}}",
"page.logout.title": "Abmelden", "page.logout.title": "Abmelden",
"page.caldav.title": "CalDAV",
"page.caldav.unavailable": "CalDAV nicht verfügbar",
"page.caldav.conf.title": "Zugangsdaten",
"page.caldav.conf.address": "Adresse (URL)",
"page.caldav.conf.username": "Nutzername",
"page.caldav.conf.password": "Kennwort",
"page.caldav.conf.setup_hints": "Einrichtungs-Hinweise",
"page.caldav.conf.token_unset": "es muss zunächst ein Token gesetzt werden",
"page.caldav.set_token.title": "Token setzen",
"page.caldav.set_token.action.set": "setzen",
"page.caldav.set_token.action.overwrite": "überschreiben",
"page.calendar_add.title": "Kalendar anlegen", "page.calendar_add.title": "Kalendar anlegen",
"page.calendar_add.actions.do": "anlegen", "page.calendar_add.actions.do": "anlegen",
"page.calendar_edit.title.regular": "Kalendar bearbeiten", "page.calendar_edit.title.regular": "Kalendar bearbeiten",

View file

@ -54,6 +54,17 @@
"page.login.internal.do": "login", "page.login.internal.do": "login",
"page.login.oidc.via": "via {{title}}", "page.login.oidc.via": "via {{title}}",
"page.logout.title": "Logout", "page.logout.title": "Logout",
"page.caldav.title": "CalDAV",
"page.caldav.unavailable": "CalDAV not available",
"page.caldav.conf.title": "credentials",
"page.caldav.conf.address": "address (URL)",
"page.caldav.conf.username": "username",
"page.caldav.conf.password": "password",
"page.caldav.conf.setup_hints": "setup hints",
"page.caldav.conf.token_unset": "a token has to be set",
"page.caldav.set_token.title": "set token",
"page.caldav.set_token.action.set": "set",
"page.caldav.set_token.action.overwrite": "overwrite",
"page.calendar_add.title": "Add calendar", "page.calendar_add.title": "Add calendar",
"page.calendar_add.actions.do": "anlegen", "page.calendar_add.actions.do": "anlegen",
"page.event_add.title": "Add event", "page.event_add.title": "Add event",

View file

@ -231,7 +231,7 @@ namespace _zeitbild.frontend_web.backend
/** /**
*/ */
export async function user_list( export function user_list(
) : Promise< ) : Promise<
Array< Array<
{ {
@ -249,6 +249,49 @@ namespace _zeitbild.frontend_web.backend
} }
/**
*/
export function user_dav_conf(
) : Promise<
(
null
|
{
address : string;
username : string;
password : string;
setup_hints : Array<
{
label : string;
link : string;
remark : (null | string);
}
>;
}
)
>
{
return call(
lib_plankton.http.enum_method.get,
"/user_dav_conf",
null
);
}
/**
*/
export function user_dav_token(
) : Promise<void>
{
return call(
lib_plankton.http.enum_method.patch,
"/user_dav_token",
null
);
}
/** /**
*/ */
export async function calendar_list( export async function calendar_list(

View file

@ -15,9 +15,9 @@ namespace _zeitbild.frontend_web
); );
// init // init
lib_plankton.log.conf_push( lib_plankton.log.set_main_logger(
[ [
lib_plankton.log.channel_make({"kind": "console", "data": {"threshold": "info"}}), {"kind": "console", "data": {"threshold": "info"}},
] ]
); );
await _zeitbild.frontend_web.backend.init( await _zeitbild.frontend_web.backend.init(
@ -54,6 +54,10 @@ namespace _zeitbild.frontend_web
{"name": "calendar_add", "parameters": {}}, {"name": "calendar_add", "parameters": {}},
{"label": lib_plankton.translate.get("page.calendar_add.title")} {"label": lib_plankton.translate.get("page.calendar_add.title")}
); );
lib_plankton.zoo_page.add_nav_entry(
{"name": "caldav", "parameters": {}},
{"label": lib_plankton.translate.get("page.caldav.title")}
);
/* /*
lib_plankton.zoo_page.add_nav_entry( lib_plankton.zoo_page.add_nav_entry(
{"name": "event_add", "parameters": {}}, {"name": "event_add", "parameters": {}},

View file

@ -0,0 +1,119 @@
namespace _zeitbild.frontend_web.pages
{
/**
*/
lib_plankton.zoo_page.register(
"caldav",
async (parameters, target_element) => {
target_element.innerHTML = "";
const conf = await _zeitbild.frontend_web.backend.user_dav_conf();
target_element.innerHTML = await _zeitbild.frontend_web.helpers.template_coin(
"caldav",
"main",
{
"label": lib_plankton.translate.get("page.caldav.title"),
"content": (
(conf === null)
?
await _zeitbild.frontend_web.helpers.template_coin(
"caldav",
"unavailable",
{
"text": lib_plankton.translate.get("page.caldav.unavailable"),
}
)
:
await _zeitbild.frontend_web.helpers.template_coin(
"caldav",
"available",
{
"conf_title": lib_plankton.translate.get("page.caldav.conf.title"),
"conf_content": (
(conf.password === null)
?
await _zeitbild.frontend_web.helpers.template_coin(
"caldav",
"conf-token_unset",
{
"text": lib_plankton.translate.get("page.caldav.conf.token_unset")
}
)
:
await _zeitbild.frontend_web.helpers.template_coin(
"caldav",
"conf-token_set",
{
"address_label": lib_plankton.translate.get("page.caldav.conf.address"),
"address_value": conf.address,
"username_label": lib_plankton.translate.get("page.caldav.conf.username"),
"username_value": conf.username,
"password_label": lib_plankton.translate.get("page.caldav.conf.password"),
"password_value": conf.password,
"setup_hints_label": lib_plankton.translate.get("page.caldav.conf.setup_hints"),
"setup_hint_entries": (
await lib_plankton.call.promise_condense<string, unknown>(
conf.setup_hints
.map(
entry => () => _zeitbild.frontend_web.helpers.template_coin(
"caldav",
"conf-setup_hint_entry",
{
"text": entry.label,
"href": entry.link,
"remark": (
(entry.remark === null)
?
""
:
lib_plankton.string.coin(
" — {{content}}",
{
"content": entry.remark,
}
)
)
}
)
)
)
).join("")
}
)
),
"set_token_title": lib_plankton.translate.get("page.caldav.set_token.title"),
"set_token_action": (
(conf.password === null)
?
lib_plankton.translate.get("page.caldav.set_token.action.set")
:
lib_plankton.translate.get("page.caldav.set_token.action.overwrite")
),
}
)
)
}
);
/**
* logic: set token
*/
{
if (conf !== null)
{
document.querySelector("#caldav-set_token > button").addEventListener(
"click",
async () => {
await _zeitbild.frontend_web.backend.user_dav_token();
lib_plankton.zoo_page.reload();
}
);
}
}
return Promise.resolve<void>(undefined);
}
);
}

View file

@ -0,0 +1,8 @@
<div id="caldav-conf">
<h3>{{conf_title}}</h3>
{{conf_content}}
</div>
<div id="caldav-set_token">
<h3>{{set_token_title}}</h3>
<button>{{set_token_action}}</button>
</div>

View file

@ -0,0 +1,3 @@
<li class="caldav-conf-setup_hints-entry">
<a target="_blank" href="{{href}}">{{text}}</a>{{remark}}
</li>

View file

@ -0,0 +1,18 @@
<div class="caldav-conf-section" id="caldav-conf-address">
<span class="caldav-conf-section-label">{{address_label}}</span>
<span class="caldav-conf-section-value caldav-conf-section-value-regular">{{address_value}}</span>
</div>
<div class="caldav-conf-section" id="caldav-conf-username">
<span class="caldav-conf-section-label">{{username_label}}</span>
<span class="caldav-conf-section-value caldav-conf-section-value-regular">{{username_value}}</span>
</div>
<div class="caldav-conf-section" id="caldav-conf-password">
<span class="caldav-conf-section-label">{{password_label}}</span>
<span class="caldav-conf-section-value caldav-conf-section-value-regular">{{password_value}}</span>
</div>
<div class="caldav-conf-section" id="caldav-conf-setup_hints">
<span class="caldav-conf-section-label">{{setup_hints_label}}</span>
<ul>
{{setup_hint_entries}}
</ul>
</div>

View file

@ -0,0 +1,4 @@
<div id="caldav-conf-info">
({{text}})
</div>

View file

@ -0,0 +1,6 @@
<div id="caldav">
<h2>{{label}}</h2>
<div id="caldav-content">
{{content}}
</div>
</div>

View file

@ -0,0 +1,3 @@
<div id="caldav-info">
{{text}}
</div>

View file

@ -1,3 +1,8 @@
:root
{
--hue: 150;
}
html html
{ {
background-color: hsl(0, 0%, 12.5%); background-color: hsl(0, 0%, 12.5%);
@ -29,18 +34,29 @@ nav > ul > li
padding: 8px; padding: 8px;
} }
a nav a
{ {
padding: 8px; padding: 8px;
text-decoration: none; text-decoration: none;
color: hsl(0, 0%, 87.5%); color: hsl(var(--hue), 0%, 87.5%);
}
nav a:hover
{
color: hsl(var(--hue), 0%, 100%);
border-bottom: 2px solid hsl(0, 0%, 100%);
transition: 1s ease color;
}
a
{
text-decoration: none;
color: hsl(var(--hue), 50%, 50%);
} }
a:hover a:hover
{ {
color: hsl(0, 0%, 100%); color: hsl(var(--hue), 50%, 75%);
border-bottom: 2px solid hsl(0, 0%, 100%);
transition: 1s ease color;
} }
input,select,textarea input,select,textarea

View file

@ -0,0 +1,22 @@
.caldav-conf-section
{
margin-bottom: 16px;
}
.caldav-conf-section-label
{
margin-left: 16px;
display: block;
font-weight: bold;
text-transform: capitalize;
}
.caldav-conf-section-value
{
margin-left: 32px;
}
.caldav-conf-section-value-regular
{
font-family: monospace;
}

View file

@ -35,6 +35,7 @@ templates: \
templates-widgets-sources \ templates-widgets-sources \
templates-widgets-listview \ templates-widgets-listview \
templates-widgets-weekview \ templates-widgets-weekview \
templates-pages-caldav \
templates-pages-calendar_add \ templates-pages-calendar_add \
templates-pages-calendar_edit \ templates-pages-calendar_edit \
templates-pages-event_add \ templates-pages-event_add \
@ -63,6 +64,13 @@ templates-widgets-weekview: \
@ ${cmd_mkdir} ${dir_build}/templates/widget-weekview @ ${cmd_mkdir} ${dir_build}/templates/widget-weekview
@ ${cmd_cp} -r -u -v ${dir_source}/widgets/weekview/templates/* ${dir_build}/templates/widget-weekview/ @ ${cmd_cp} -r -u -v ${dir_source}/widgets/weekview/templates/* ${dir_build}/templates/widget-weekview/
.PHONY: templates-pages-caldav
templates-pages-caldav: \
$(wildcard ${dir_source}/pages/caldav/templates/*)
@ ${cmd_log} "templates:caldav …"
@ ${cmd_mkdir} ${dir_build}/templates/caldav
@ ${cmd_cp} -r -u -v ${dir_source}/pages/caldav/templates/* ${dir_build}/templates/caldav/
.PHONY: templates-pages-calendar_add .PHONY: templates-pages-calendar_add
templates-pages-calendar_add: \ templates-pages-calendar_add: \
$(wildcard ${dir_source}/pages/calendar_add/templates/*) $(wildcard ${dir_source}/pages/calendar_add/templates/*)
@ -127,6 +135,7 @@ ${dir_temp}/logic-unlinked.js: \
${dir_source}/widgets/weekview/logic.ts \ ${dir_source}/widgets/weekview/logic.ts \
${dir_source}/pages/login/logic.ts \ ${dir_source}/pages/login/logic.ts \
${dir_source}/pages/logout/logic.ts \ ${dir_source}/pages/logout/logic.ts \
${dir_source}/pages/caldav/logic.ts \
${dir_source}/pages/oidc_finish/logic.ts \ ${dir_source}/pages/oidc_finish/logic.ts \
${dir_source}/pages/calendar_add/logic.ts \ ${dir_source}/pages/calendar_add/logic.ts \
${dir_source}/pages/calendar_edit/logic.ts \ ${dir_source}/pages/calendar_edit/logic.ts \