advent22/ui/src/components/admin/DoorMapEditor.vue

175 lines
4.2 KiB
Vue
Raw Normal View History

2023-01-17 18:25:56 +00:00
<template>
<BulmaDrawer header="Türchen bearbeiten" :opening="load_doors">
2023-10-27 15:09:44 +00:00
<nav class="level is-mobile mb-0" style="overflow-x: auto">
2023-09-14 13:57:20 +00:00
<BulmaButton
:disabled="current_step === 0"
class="level-item is-link"
@click="current_step--"
:icon="['fas', 'fa-backward']"
2023-09-14 13:57:20 +00:00
/>
2023-09-14 13:54:23 +00:00
2023-09-14 13:57:20 +00:00
<BulmaBreadcrumbs
:steps="steps"
v-model="current_step"
class="level-item mb-0"
/>
2023-09-14 13:54:23 +00:00
2023-09-14 13:57:20 +00:00
<BulmaButton
:disabled="current_step === 2"
class="level-item is-link"
@click="current_step++"
:icon="['fas', 'fa-forward']"
2023-09-14 13:57:20 +00:00
/>
2023-09-14 13:54:23 +00:00
</nav>
2023-01-19 00:22:01 +00:00
2023-09-21 10:03:53 +00:00
<div class="card-content pb-0">
<div v-if="doors.length > 0" class="content">
<p>Für diese Tage ist ein Türchen vorhanden:</p>
<div class="tags">
<span
v-for="(door, index) in doors.toSorted((a, b) => a.day - b.day)"
:key="`door-${index}`"
class="tag is-primary"
>
{{ door.day }}
</span>
</div>
</div>
</div>
<DoorPlacer v-if="current_step === 0" v-model="doors" />
<DoorChooser v-if="current_step === 1" v-model="doors" />
2023-09-10 03:38:24 +00:00
<div v-if="current_step === 2" class="card-content">
<Calendar :doors="doors" />
2023-09-10 00:54:29 +00:00
</div>
2023-09-09 22:18:16 +00:00
2023-09-10 03:38:24 +00:00
<footer class="card-footer is-flex is-justify-content-space-around">
2023-09-10 00:54:29 +00:00
<BulmaButton
2023-09-10 03:38:24 +00:00
class="card-footer-item is-danger"
2023-09-10 00:54:29 +00:00
@click="on_download"
:icon="['fas', 'fa-cloud-arrow-down']"
:busy="loading_doors"
2023-09-10 00:54:29 +00:00
text="Laden"
/>
<BulmaButton
2023-09-10 03:38:24 +00:00
class="card-footer-item is-warning"
2023-09-10 00:54:29 +00:00
@click="on_discard"
:icon="['fas', 'fa-trash']"
2023-09-10 00:54:29 +00:00
text="Löschen"
/>
<BulmaButton
2023-09-10 03:38:24 +00:00
class="card-footer-item is-success"
2023-09-10 00:54:29 +00:00
@click="on_upload"
:icon="['fas', 'fa-cloud-arrow-up']"
:busy="saving_doors"
2023-09-10 00:54:29 +00:00
text="Speichern"
/>
2023-09-10 03:38:24 +00:00
</footer>
2023-09-09 22:18:16 +00:00
</BulmaDrawer>
2023-01-17 18:25:56 +00:00
</template>
<script setup lang="ts">
2024-08-27 00:25:42 +00:00
import { API } from "@/lib/api";
import { APIError } from "@/lib/api_error";
2024-08-23 16:38:04 +00:00
import { DoorSaved } from "@/lib/model";
import { Door } from "@/lib/rects/door";
2024-08-27 00:25:42 +00:00
import { toast } from "bulma-toast";
import { ref } from "vue";
import { BCStep } from "../bulma/Breadcrumbs.vue";
2023-01-17 18:25:56 +00:00
2023-09-13 16:08:05 +00:00
import Calendar from "../Calendar.vue";
import BulmaBreadcrumbs from "../bulma/Breadcrumbs.vue";
2023-09-13 16:08:05 +00:00
import BulmaButton from "../bulma/Button.vue";
2023-09-14 12:51:30 +00:00
import BulmaDrawer from "../bulma/Drawer.vue";
2023-09-13 16:08:05 +00:00
import DoorChooser from "../editor/DoorChooser.vue";
import DoorPlacer from "../editor/DoorPlacer.vue";
2023-01-24 00:14:50 +00:00
const steps: BCStep[] = [
{ label: "Platzieren", icon: ["fas", "fa-crosshairs"] },
{ label: "Ordnen", icon: ["fas", "fa-list-ol"] },
{ label: "Vorschau", icon: ["fas", "fa-magnifying-glass"] },
];
const doors = ref<Door[]>([]);
const current_step = ref(0);
const loading_doors = ref(false);
const saving_doors = ref(false);
async function load_doors() {
try {
const data = await API.request<DoorSaved[]>("admin/doors");
doors.value.length = 0;
for (const value of data) {
doors.value.push(Door.load(value));
}
} catch (error) {
APIError.alert(error);
throw null;
}
}
2023-09-07 16:44:44 +00:00
async function save_doors() {
try {
const data: DoorSaved[] = [];
2023-09-07 20:54:11 +00:00
for (const door of doors.value) {
data.push(door.save());
2023-09-09 22:18:16 +00:00
}
await API.request<void>({
endpoint: "admin/doors",
method: "PUT",
data: data,
});
} catch (error) {
APIError.alert(error);
throw null;
}
}
async function on_download() {
if (confirm("Aktuelle Änderungen verwerfen und Status vom Server laden?")) {
loading_doors.value = true;
try {
load_doors();
toast({
message: "Erfolgreich!",
type: "is-success",
duration: 2e3,
});
} finally {
loading_doors.value = false;
}
2023-09-09 22:18:16 +00:00
}
}
2023-09-09 22:18:16 +00:00
function on_discard() {
if (confirm("Alle Türchen löschen? (nur lokal)")) {
// empty `doors` array
doors.value.length = 0;
2023-09-09 22:18:16 +00:00
}
}
2023-09-09 22:18:16 +00:00
async function on_upload() {
if (confirm("Aktuelle Änderungen an den Server schicken?")) {
saving_doors.value = true;
try {
save_doors();
load_doors();
toast({
message: "Erfolgreich!",
type: "is-success",
duration: 2e3,
});
} finally {
saving_doors.value = false;
}
2023-09-09 22:18:16 +00:00
}
2023-09-07 20:54:11 +00:00
}
2023-09-09 22:18:16 +00:00
</script>