🚧 wip on ui: rework for vue 3 composition API
This commit is contained in:
parent
4f603d3cb1
commit
f482fd4ec1
10 changed files with 140 additions and 171 deletions
|
|
@ -45,14 +45,13 @@
|
||||||
</figure>
|
</figure>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { API } from "@/lib/api";
|
import { API } from "@/lib/api";
|
||||||
import { APIError } from "@/lib/api_error";
|
import { APIError } from "@/lib/api_error";
|
||||||
import { ensure_loaded, Loading, name_door } from "@/lib/helpers";
|
import { ensure_loaded, Loading, name_door } from "@/lib/helpers";
|
||||||
import { ImageData } from "@/lib/model";
|
import { ImageData } from "@/lib/model";
|
||||||
import { Door } from "@/lib/rects/door";
|
import { Door } from "@/lib/rects/door";
|
||||||
import { advent22Store } from "@/lib/store";
|
import { advent22Store } from "@/lib/store";
|
||||||
import { Options, Vue } from "vue-class-component";
|
|
||||||
|
|
||||||
import MultiModal from "./MultiModal.vue";
|
import MultiModal from "./MultiModal.vue";
|
||||||
import BulmaButton from "./bulma/Button.vue";
|
import BulmaButton from "./bulma/Button.vue";
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,8 @@
|
||||||
<DoorMapEditor />
|
<DoorMapEditor />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { Options, Vue } from "vue-class-component";
|
|
||||||
|
|
||||||
import CalendarAssistant from "./CalendarAssistant.vue";
|
import CalendarAssistant from "./CalendarAssistant.vue";
|
||||||
import ConfigView from "./ConfigView.vue";
|
import ConfigView from "./ConfigView.vue";
|
||||||
import DoorMapEditor from "./DoorMapEditor.vue";
|
import DoorMapEditor from "./DoorMapEditor.vue";
|
||||||
|
|
||||||
@Options({
|
|
||||||
components: {
|
|
||||||
ConfigView,
|
|
||||||
CalendarAssistant,
|
|
||||||
DoorMapEditor,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
export default class extends Vue {}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
:key="`btn-${day}`"
|
:key="`btn-${day}`"
|
||||||
:class="'tag is-' + (data.part === '' ? 'warning' : 'info')"
|
:class="'tag is-' + (data.part === '' ? 'warning' : 'info')"
|
||||||
icon="fa-solid fa-door-open"
|
icon="fa-solid fa-door-open"
|
||||||
:text="day"
|
:text="day.toString()"
|
||||||
@click.left="door_click(day)"
|
@click.left="door_click(day)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -45,74 +45,64 @@
|
||||||
</BulmaDrawer>
|
</BulmaDrawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { API } from "@/lib/api";
|
import { API } from "@/lib/api";
|
||||||
import { name_door, objForEach } from "@/lib/helpers";
|
import { name_door, objForEach } from "@/lib/helpers";
|
||||||
import { ImageData, NumStrDict } from "@/lib/model";
|
import { ImageData, NumStrDict } from "@/lib/model";
|
||||||
import { Options, Vue } from "vue-class-component";
|
|
||||||
|
|
||||||
import MultiModal from "../MultiModal.vue";
|
import MultiModal from "../MultiModal.vue";
|
||||||
import BulmaButton from "../bulma/Button.vue";
|
import BulmaButton from "../bulma/Button.vue";
|
||||||
import BulmaDrawer from "../bulma/Drawer.vue";
|
import BulmaDrawer from "../bulma/Drawer.vue";
|
||||||
|
|
||||||
@Options({
|
const day_data: {
|
||||||
components: {
|
|
||||||
BulmaButton,
|
|
||||||
BulmaDrawer,
|
|
||||||
MultiModal,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
export default class extends Vue {
|
|
||||||
public day_data: {
|
|
||||||
[day: number]: {
|
[day: number]: {
|
||||||
part: string;
|
part: string;
|
||||||
image_name: string;
|
image_name: string;
|
||||||
};
|
};
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
private multi_modal?: MultiModal;
|
let multi_modal: MultiModal | undefined;
|
||||||
|
|
||||||
public modal_handle(modal: MultiModal) {
|
function modal_handle(modal: MultiModal) {
|
||||||
this.multi_modal = modal;
|
multi_modal = modal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public on_open(ready: () => void, fail: () => void): void {
|
function on_open(ready: () => void, fail: () => void) {
|
||||||
Promise.all([
|
Promise.all([
|
||||||
API.request<NumStrDict>("admin/day_parts"),
|
API.request<NumStrDict>("admin/day_parts"),
|
||||||
API.request<NumStrDict>("admin/day_image_names"),
|
API.request<NumStrDict>("admin/day_image_names"),
|
||||||
])
|
])
|
||||||
.then(([day_parts, day_image_names]) => {
|
.then(([day_parts, day_image_names]) => {
|
||||||
const _ensure_day_in_data = (day: number) => {
|
const _ensure_day_in_data = (day: number) => {
|
||||||
if (!(day in this.day_data)) {
|
if (!(day in day_data)) {
|
||||||
this.day_data[day] = { part: "", image_name: "" };
|
day_data[day] = { part: "", image_name: "" };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
objForEach(day_parts, (day, part) => {
|
objForEach(day_parts, (day, part) => {
|
||||||
_ensure_day_in_data(day);
|
_ensure_day_in_data(day);
|
||||||
this.day_data[day].part = part;
|
day_data[day].part = part;
|
||||||
});
|
});
|
||||||
|
|
||||||
objForEach(day_image_names, (day, image_name) => {
|
objForEach(day_image_names, (day, image_name) => {
|
||||||
_ensure_day_in_data(day);
|
_ensure_day_in_data(day);
|
||||||
this.day_data[day].image_name = image_name;
|
day_data[day].image_name = image_name;
|
||||||
});
|
});
|
||||||
|
|
||||||
ready();
|
ready();
|
||||||
})
|
})
|
||||||
.catch(fail);
|
.catch(fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async door_click(day: number) {
|
async function door_click(day: number) {
|
||||||
if (this.multi_modal === undefined) return;
|
if (multi_modal === undefined) return;
|
||||||
this.multi_modal.show_progress();
|
multi_modal.show_progress();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const day_image = await API.request<ImageData>(`user/image_${day}`);
|
const day_image = await API.request<ImageData>(`user/image_${day}`);
|
||||||
this.multi_modal!.show_image(day_image.data_url, name_door(day));
|
multi_modal!.show_image(day_image.data_url, name_door(day));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.multi_modal!.hide();
|
multi_modal!.hide();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -183,28 +183,19 @@
|
||||||
</BulmaDrawer>
|
</BulmaDrawer>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import { API } from "@/lib/api";
|
import { API } from "@/lib/api";
|
||||||
import { AdminConfigModel, Credentials, DoorSaved } from "@/lib/model";
|
import { AdminConfigModel, Credentials, DoorSaved } from "@/lib/model";
|
||||||
import { advent22Store } from "@/lib/store";
|
import { advent22Store } from "@/lib/store";
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
import { Options, Vue } from "vue-class-component";
|
|
||||||
|
|
||||||
import BulmaDrawer from "../bulma/Drawer.vue";
|
import BulmaDrawer from "../bulma/Drawer.vue";
|
||||||
import BulmaSecret from "../bulma/Secret.vue";
|
import BulmaSecret from "../bulma/Secret.vue";
|
||||||
import CountDown from "../CountDown.vue";
|
import CountDown from "../CountDown.vue";
|
||||||
|
|
||||||
@Options({
|
const store = advent22Store();
|
||||||
components: {
|
|
||||||
BulmaDrawer,
|
|
||||||
BulmaSecret,
|
|
||||||
CountDown,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
export default class extends Vue {
|
|
||||||
public readonly store = advent22Store();
|
|
||||||
|
|
||||||
public admin_config_model: AdminConfigModel = {
|
let admin_config_model: AdminConfigModel = {
|
||||||
solution: {
|
solution: {
|
||||||
value: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
value: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||||
whitespace: "KEEP",
|
whitespace: "KEEP",
|
||||||
|
|
@ -242,46 +233,46 @@ export default class extends Vue {
|
||||||
cache_ttl: 0,
|
cache_ttl: 0,
|
||||||
config_file: "sed diam nonumy",
|
config_file: "sed diam nonumy",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
public doors: DoorSaved[] = [];
|
|
||||||
public dav_credentials: Credentials = ["", ""];
|
|
||||||
public ui_credentials: Credentials = ["", ""];
|
|
||||||
|
|
||||||
public fmt_puzzle_date(name: keyof AdminConfigModel["puzzle"]): string {
|
let doors: DoorSaved[] = [];
|
||||||
const iso_date = this.admin_config_model.puzzle[name];
|
let dav_credentials: Credentials = ["", ""];
|
||||||
|
let ui_credentials: Credentials = ["", ""];
|
||||||
|
|
||||||
|
function fmt_puzzle_date(name: keyof AdminConfigModel["puzzle"]): string {
|
||||||
|
const iso_date = admin_config_model.puzzle[name];
|
||||||
if (!(typeof iso_date == "string")) return "-";
|
if (!(typeof iso_date == "string")) return "-";
|
||||||
|
|
||||||
return DateTime.fromISO(iso_date).toLocaleString(DateTime.DATE_SHORT);
|
return DateTime.fromISO(iso_date).toLocaleString(DateTime.DATE_SHORT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public on_open(ready: () => void, fail: () => void): void {
|
function on_open(ready: () => void, fail: () => void): void {
|
||||||
Promise.all([
|
Promise.all([
|
||||||
this.store.update(),
|
store.update(),
|
||||||
API.request<AdminConfigModel>("admin/config_model"),
|
API.request<AdminConfigModel>("admin/config_model"),
|
||||||
API.request<DoorSaved[]>("admin/doors"),
|
API.request<DoorSaved[]>("admin/doors"),
|
||||||
])
|
])
|
||||||
.then(([store_update, admin_config_model, doors]) => {
|
.then(([store_update, new_admin_config_model, new_doors]) => {
|
||||||
store_update; // discard value
|
store_update; // discard value
|
||||||
|
|
||||||
this.admin_config_model = admin_config_model;
|
admin_config_model = new_admin_config_model;
|
||||||
this.doors = doors;
|
doors = new_doors;
|
||||||
|
|
||||||
ready();
|
ready();
|
||||||
})
|
})
|
||||||
.catch(fail);
|
.catch(fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
public load_dav_credentials(): void {
|
function load_dav_credentials(): void {
|
||||||
API.request<Credentials>("admin/dav_credentials")
|
API.request<Credentials>("admin/dav_credentials")
|
||||||
.then((creds) => (this.dav_credentials = creds))
|
.then((creds) => (dav_credentials = creds))
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
public load_ui_credentials(): void {
|
function load_ui_credentials(): void {
|
||||||
API.request<Credentials>("admin/ui_credentials")
|
API.request<Credentials>("admin/ui_credentials")
|
||||||
.then((creds) => (this.ui_credentials = creds))
|
.then((creds) => (ui_credentials = creds))
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const props = defineProps<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
"update:modelValue": [number];
|
(event: "update:modelValue", value: number): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
function change_step(next_step: number) {
|
function change_step(next_step: number) {
|
||||||
|
|
|
||||||
|
|
@ -53,12 +53,7 @@ withDefaults(
|
||||||
);
|
);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
open: [
|
(event: "open", ready: () => void, fail: () => void): void;
|
||||||
{
|
|
||||||
ready(): void;
|
|
||||||
fail(): void;
|
|
||||||
},
|
|
||||||
];
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const is_open = ref(false);
|
const is_open = ref(false);
|
||||||
|
|
@ -70,10 +65,11 @@ function toggle() {
|
||||||
if (is_open.value) {
|
if (is_open.value) {
|
||||||
state.value = "loading";
|
state.value = "loading";
|
||||||
|
|
||||||
emit("open", {
|
emit(
|
||||||
ready: () => (state.value = "ready"),
|
"open",
|
||||||
fail: () => (state.value = "failed"),
|
() => (state.value = "ready"),
|
||||||
});
|
() => (state.value = "failed"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import { ref } from "vue";
|
||||||
import BulmaButton from "./Button.vue";
|
import BulmaButton from "./Button.vue";
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
load: [];
|
(event: "load"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const state = ref<"start" | "click" | "show">("start");
|
const state = ref<"start" | "click" | "show">("start");
|
||||||
|
|
|
||||||
|
|
@ -12,19 +12,19 @@ import * as bulmaToast from "bulma-toast";
|
||||||
import { onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
handle: [
|
(
|
||||||
{
|
event: "handle",
|
||||||
show(options: bulmaToast.Options): void;
|
show: (options: bulmaToast.Options) => void,
|
||||||
hide(): void;
|
hide: () => void,
|
||||||
},
|
): void;
|
||||||
];
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const message = ref<HTMLDivElement | null>(null);
|
const message = ref<HTMLDivElement | null>(null);
|
||||||
|
|
||||||
onMounted(() =>
|
onMounted(() =>
|
||||||
emit("handle", {
|
emit(
|
||||||
show(options: bulmaToast.Options = {}) {
|
"handle",
|
||||||
|
(options: bulmaToast.Options = {}) => {
|
||||||
if (!(message.value instanceof HTMLElement)) return;
|
if (!(message.value instanceof HTMLElement)) return;
|
||||||
|
|
||||||
bulmaToast.toast({
|
bulmaToast.toast({
|
||||||
|
|
@ -33,7 +33,7 @@ onMounted(() =>
|
||||||
message: message.value,
|
message: message.value,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
hide() {
|
() => {
|
||||||
if (!(message.value instanceof HTMLElement)) return;
|
if (!(message.value instanceof HTMLElement)) return;
|
||||||
|
|
||||||
const toast_div = message.value.parentElement;
|
const toast_div = message.value.parentElement;
|
||||||
|
|
@ -44,6 +44,6 @@ onMounted(() =>
|
||||||
|
|
||||||
dbutton.click();
|
dbutton.click();
|
||||||
},
|
},
|
||||||
}),
|
),
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,9 @@ function get_bg_aspect_ratio(): number {
|
||||||
if (!loading_success(store.background_image)) return 1;
|
if (!loading_success(store.background_image)) return 1;
|
||||||
|
|
||||||
return store.background_image.height / store.background_image.width;
|
return store.background_image.height / store.background_image.width;
|
||||||
|
|
||||||
|
// aspect_ratio is width/height!
|
||||||
|
// return store.background_image.aspect_ratio;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,8 +58,9 @@ export interface DoorSaved {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ImageData {
|
export interface ImageData {
|
||||||
height: number;
|
|
||||||
width: number;
|
width: number;
|
||||||
|
height: number;
|
||||||
|
aspect_ratio: number;
|
||||||
data_url: string;
|
data_url: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue