mirror of
https://code.lenaisten.de/Lenaisten/advent22.git
synced 2026-01-10 07:03:04 +00:00
🔧 ui: BulmaDrawer state machine rework
This commit is contained in:
parent
d5c935ade7
commit
eacd1da482
5 changed files with 54 additions and 80 deletions
|
|
@ -2,7 +2,7 @@
|
|||
<ConfigView />
|
||||
<CalendarAssistant />
|
||||
<DoorMapEditor />
|
||||
<BulmaDrawer header="Vorschau" @open="(ready) => ready()">
|
||||
<BulmaDrawer header="Vorschau">
|
||||
<UserView />
|
||||
</BulmaDrawer>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<MultiModal @handle="on_modal_handle" />
|
||||
|
||||
<BulmaDrawer header="Kalender-Assistent" @open="on_open" refreshable>
|
||||
<BulmaDrawer header="Kalender-Assistent" :opening="on_open" refreshable>
|
||||
<div class="card-content">
|
||||
<div class="content">
|
||||
<p>Hervorgehobenen Tagen wurde kein Buchstabe zugewiesen.</p>
|
||||
|
|
@ -63,33 +63,27 @@ function on_modal_handle(handle: HMultiModal) {
|
|||
modal = handle;
|
||||
}
|
||||
|
||||
async function on_open(ready: () => void, fail: () => void) {
|
||||
try {
|
||||
const [day_parts, day_image_names] = await Promise.all([
|
||||
API.request<NumStrDict>("admin/day_parts"),
|
||||
API.request<NumStrDict>("admin/day_image_names"),
|
||||
]);
|
||||
async function on_open() {
|
||||
const [day_parts, day_image_names] = await Promise.all([
|
||||
API.request<NumStrDict>("admin/day_parts"),
|
||||
API.request<NumStrDict>("admin/day_image_names"),
|
||||
]);
|
||||
|
||||
const _ensure_day_in_data = (day: number) => {
|
||||
if (!(day in day_data.value)) {
|
||||
day_data.value[day] = { part: "", image_name: "" };
|
||||
}
|
||||
};
|
||||
const _ensure_day_in_data = (day: number) => {
|
||||
if (!(day in day_data.value)) {
|
||||
day_data.value[day] = { part: "", image_name: "" };
|
||||
}
|
||||
};
|
||||
|
||||
objForEach(day_parts, (day, part) => {
|
||||
_ensure_day_in_data(day);
|
||||
day_data.value[day].part = part;
|
||||
});
|
||||
objForEach(day_parts, (day, part) => {
|
||||
_ensure_day_in_data(day);
|
||||
day_data.value[day].part = part;
|
||||
});
|
||||
|
||||
objForEach(day_image_names, (day, image_name) => {
|
||||
_ensure_day_in_data(day);
|
||||
day_data.value[day].image_name = image_name;
|
||||
});
|
||||
|
||||
ready();
|
||||
} catch {
|
||||
fail();
|
||||
}
|
||||
objForEach(day_image_names, (day, image_name) => {
|
||||
_ensure_day_in_data(day);
|
||||
day_data.value[day].image_name = image_name;
|
||||
});
|
||||
}
|
||||
|
||||
async function door_click(day: number) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<BulmaDrawer header="Konfiguration" @open="on_open" refreshable>
|
||||
<BulmaDrawer header="Konfiguration" :opening="on_open" refreshable>
|
||||
<div class="card-content">
|
||||
<div class="columns">
|
||||
<div class="column is-one-third">
|
||||
|
|
@ -247,24 +247,16 @@ function fmt_puzzle_date(name: keyof AdminConfigModel["puzzle"]): string {
|
|||
return DateTime.fromISO(iso_date).toLocaleString(DateTime.DATE_SHORT);
|
||||
}
|
||||
|
||||
async function on_open(ready: () => void, fail: () => void) {
|
||||
try {
|
||||
const [store_update, new_admin_config_model, new_doors] = await Promise.all(
|
||||
[
|
||||
store.update(),
|
||||
API.request<AdminConfigModel>("admin/config_model"),
|
||||
API.request<DoorSaved[]>("admin/doors"),
|
||||
],
|
||||
);
|
||||
async function on_open() {
|
||||
const [store_update, new_admin_config_model, new_doors] = await Promise.all([
|
||||
store.update(),
|
||||
API.request<AdminConfigModel>("admin/config_model"),
|
||||
API.request<DoorSaved[]>("admin/doors"),
|
||||
]);
|
||||
|
||||
void store_update;
|
||||
admin_config_model.value = new_admin_config_model;
|
||||
doors.value = new_doors;
|
||||
|
||||
ready();
|
||||
} catch {
|
||||
fail();
|
||||
}
|
||||
void store_update;
|
||||
admin_config_model.value = new_admin_config_model;
|
||||
doors.value = new_doors;
|
||||
}
|
||||
|
||||
async function load_dav_credentials() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<BulmaDrawer header="Türchen bearbeiten" @open="on_open">
|
||||
<BulmaDrawer header="Türchen bearbeiten" :opening="load_doors">
|
||||
<nav class="level is-mobile mb-0" style="overflow-x: auto">
|
||||
<BulmaButton
|
||||
:disabled="current_step === 0"
|
||||
|
|
@ -128,15 +128,6 @@ async function save_doors() {
|
|||
}
|
||||
}
|
||||
|
||||
async function on_open(ready: () => void, fail: () => void) {
|
||||
try {
|
||||
load_doors();
|
||||
ready();
|
||||
} catch {
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
async function on_download() {
|
||||
if (confirm("Aktuelle Änderungen verwerfen und Status vom Server laden?")) {
|
||||
loading_doors.value = true;
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@
|
|||
<header class="card-header is-unselectable" style="cursor: pointer">
|
||||
<p class="card-header-title" @click="toggle">{{ header }}</p>
|
||||
|
||||
<p v-if="refreshable" class="card-header-icon px-0">
|
||||
<BulmaButton class="is-small is-primary" @click="refresh">
|
||||
<p v-if="refreshable && is_open" class="card-header-icon px-0">
|
||||
<BulmaButton class="is-small is-primary" @click="load">
|
||||
<FontAwesomeIcon
|
||||
:icon="['fas', 'arrows-rotate']"
|
||||
:spin="is_open && state === 'loading'"
|
||||
:spin="state === 'loading'"
|
||||
/>
|
||||
</BulmaButton>
|
||||
</p>
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
<progress class="progress is-primary" />
|
||||
</div>
|
||||
<div
|
||||
v-else-if="state === 'failed'"
|
||||
v-else-if="state === 'err'"
|
||||
class="card-content has-text-danger has-text-centered"
|
||||
>
|
||||
<span class="icon is-large">
|
||||
|
|
@ -40,42 +40,39 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
|
||||
import BulmaButton from "./Button.vue";
|
||||
|
||||
withDefaults(
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
header: string;
|
||||
opening?: () => Promise<void>;
|
||||
refreshable?: boolean;
|
||||
}>(),
|
||||
{ refreshable: false },
|
||||
{ opening: async () => {}, refreshable: false },
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: "open", ready: () => void, fail: () => void): void;
|
||||
}>();
|
||||
|
||||
const is_open = ref(false);
|
||||
const state = ref<"loading" | "ready" | "failed">("loading");
|
||||
|
||||
function toggle() {
|
||||
is_open.value = !is_open.value;
|
||||
const state = ref<"closed" | "loading" | "ok" | "err">("closed");
|
||||
const is_open = computed(() => state.value !== "closed");
|
||||
|
||||
async function toggle() {
|
||||
if (is_open.value) {
|
||||
state.value = "loading";
|
||||
|
||||
emit(
|
||||
"open",
|
||||
() => (state.value = "ready"),
|
||||
() => (state.value = "failed"),
|
||||
);
|
||||
state.value = "closed";
|
||||
} else {
|
||||
await load();
|
||||
}
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
is_open.value = false;
|
||||
toggle();
|
||||
async function load() {
|
||||
state.value = "loading";
|
||||
|
||||
try {
|
||||
await props.opening();
|
||||
state.value = "ok";
|
||||
} catch {
|
||||
state.value = "err";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue