forked from swablab/website
207 lines
6 KiB
Text
207 lines
6 KiB
Text
---
|
|
import Base from "../layouts/Base.astro"
|
|
|
|
const statuses = [
|
|
{ id: "not_started", title: "Nicht gestartet" },
|
|
{ id: "in_progress", title: "In Arbeit" },
|
|
{ id: "hold", title: "Wartend" },
|
|
{ id: "done", title: "Abgeschlossen" },
|
|
]
|
|
const priorities = [
|
|
{ id: "low", title: "Niedrig" },
|
|
{ id: "normal", title: "Normal" },
|
|
{ id: "high", title: "Hoch" },
|
|
]
|
|
---
|
|
|
|
<Base title="Todo">
|
|
<div x-data="task" x-cloak>
|
|
<div class="navbar glass">
|
|
<div class="navbar-start">
|
|
<a class="btn btn-ghost text-xl">todo</a>
|
|
</div>
|
|
<div class="navbar-end space-x-2">
|
|
<a class="btn btn-success btn-square" x-on:click="submit()">
|
|
<span class="icon-[ph--floppy-disk] w-6 h-6"></span>
|
|
</a>
|
|
<a class="btn btn-error btn-square" href="/todo">
|
|
<span class="icon-[ph--x] w-6 h-6"></span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div x-show="error" class="p-4 flex flex-col space-y-4">
|
|
<div
|
|
x-show="!error.includes('permission to access collection')"
|
|
class="alert alert-error"
|
|
>
|
|
<span x-text="error"></span>
|
|
</div>
|
|
<a
|
|
x-show="error.includes('permission to access collection')"
|
|
class="btn btn-primary"
|
|
href="https://directus.swablab.de/auth/login/zitadel?redirect=https://swablab.de/todo"
|
|
>
|
|
Klicke hier, um dich anzumelden
|
|
</a>
|
|
</div>
|
|
|
|
<div class="drawer">
|
|
<input id="drawer" type="checkbox" class="drawer-toggle" />
|
|
|
|
<div class="drawer-content">
|
|
<div class="p-4 grid md:grid-cols-3 gap-4">
|
|
<input x-model="title" class="input input-bordered md:col-span-3" />
|
|
|
|
<label class="form-control">
|
|
<div class="label">Status</div>
|
|
<select x-model="status" class="select select-bordered">
|
|
{
|
|
statuses.map((status) => (
|
|
<option value={status.id}>{status.title}</option>
|
|
))
|
|
}
|
|
</select>
|
|
</label>
|
|
|
|
<label class="form-control">
|
|
<div class="label">Priorität</div>
|
|
<select x-model="priority" class="select select-bordered">
|
|
{
|
|
priorities.map((prio) => (
|
|
<option value={prio.id}>{prio.title}</option>
|
|
))
|
|
}
|
|
</select>
|
|
</label>
|
|
|
|
<label class="form-control">
|
|
<div class="label">Fälligkeitdatum</div>
|
|
<input
|
|
x-model="date_due"
|
|
class="input input-bordered"
|
|
type="date"
|
|
/>
|
|
</label>
|
|
|
|
<div class="form-control md:col-span-3">
|
|
<div class="label space-x-2 justify-start">
|
|
<span>Verantwortliche</span>
|
|
<label for="drawer" class="btn btn-sm btn-primary btn-square">
|
|
+
|
|
</label>
|
|
</div>
|
|
<div class="flex space-x-2">
|
|
<template x-for="res in responsibles">
|
|
<button
|
|
class="btn"
|
|
x-on:click="responsibles = responsibles.filter(x => x != res)"
|
|
x-text="users.find(u => u.id == res)?.first_name ?? res"
|
|
>
|
|
</button>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
|
|
<label class="form-control md:col-span-3 h-64">
|
|
<div class="label">Beschreibung</div>
|
|
<textarea
|
|
x-model="description"
|
|
class="textarea textarea-bordered md:col-span-3 h-64"
|
|
>
|
|
</textarea>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="drawer-side">
|
|
<label for="drawer" class="drawer-overlay"></label>
|
|
<ul class="menu p-4 w-80 min-h-full bg-base-200 text-base-content">
|
|
<template x-for="user in users">
|
|
<li>
|
|
<a
|
|
x-on:click="responsibles.indexOf(user.id) == -1 && responsibles.push(user.id)"
|
|
x-text="user.first_name"
|
|
>
|
|
</a>
|
|
</li>
|
|
</template>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Base>
|
|
|
|
<script>
|
|
import Alpine from "alpinejs"
|
|
import { directus, Task } from "../helper"
|
|
|
|
Alpine.data("task", () => ({
|
|
id: globalThis.location.search.replace("?", ""),
|
|
title: "",
|
|
status: "not_started",
|
|
date_due: "",
|
|
priority: "normal",
|
|
description: "",
|
|
responsibles: [],
|
|
|
|
users: [],
|
|
error: "",
|
|
|
|
init() {
|
|
directus<{ id: string; first_name: string }[]>(
|
|
`users?fields=id,first_name&filter[provider][_neq]=default`,
|
|
).then(
|
|
(res) =>
|
|
(this.users = res.sort((a, b) =>
|
|
a.first_name.localeCompare(b.first_name),
|
|
)),
|
|
)
|
|
|
|
if (this.id != "") {
|
|
directus<Task>(
|
|
`items/tasks_general/${this.id}?fields=*,responsibles.directus_users_id.id`,
|
|
)
|
|
.then((res) => {
|
|
this.title = res.title
|
|
this.status = res.status
|
|
this.date_due = res.date_due?.substring(0, 10) ?? ""
|
|
this.priority = res.priority
|
|
this.description = res.description
|
|
this.responsibles = res.responsibles.map(
|
|
(x) => x.directus_users_id.id,
|
|
)
|
|
})
|
|
.catch((err) => (this.error = err))
|
|
}
|
|
},
|
|
submit() {
|
|
const task = {
|
|
id: this.id,
|
|
title: this.title,
|
|
status: this.status,
|
|
date_due: this.date_due != "" ? this.date_due : null,
|
|
priority: this.priority,
|
|
description: this.description,
|
|
responsibles: this.responsibles.map(
|
|
(r: { directus_users_id: string }) => ({
|
|
directus_users_id: r,
|
|
}),
|
|
),
|
|
}
|
|
if (this.id != "") {
|
|
directus(
|
|
`items/tasks_general/${this.id}`,
|
|
"PATCH",
|
|
JSON.stringify(task),
|
|
).then((_) => (document.location.href = "/todo"))
|
|
} else {
|
|
directus(`items/tasks_general`, "POST", JSON.stringify(task)).then(
|
|
(_) => (document.location.href = "/todo"),
|
|
)
|
|
}
|
|
},
|
|
}))
|
|
|
|
Alpine.start()
|
|
</script>
|