game version re-ordering

This commit is contained in:
DecDuck
2024-10-14 20:34:23 +11:00
parent 8674ac7211
commit 329c74d3ce
18 changed files with 354 additions and 50 deletions

View File

@ -74,7 +74,7 @@
</div>
</Listbox>
<div class="flex flex-col gap-4 max-w-md" v-if="versionSettings">
<div class="flex flex-col gap-8 max-w-md" v-if="versionSettings">
<div>
<label
for="startup"
@ -130,7 +130,41 @@
<PlatformSelector v-model="versionSettings.platform">
Version platform
</PlatformSelector>
<LoadingButton @click="startImport_wrapper" class="w-fit" :loading="importLoading">
<SwitchGroup as="div" class="flex items-center justify-between">
<span class="flex flex-grow flex-col">
<SwitchLabel
as="span"
class="text-sm font-medium leading-6 text-zinc-100"
passive
>Update mode</SwitchLabel
>
<SwitchDescription as="span" class="text-sm text-zinc-400"
>When enabled, these files will be installed on top of (overwriting)
the previous version's. If multiple "update modes" are chained
together, they are applied in order.</SwitchDescription
>
</span>
<Switch
v-model="delta"
:class="[
delta ? 'bg-blue-600' : 'bg-zinc-800',
'relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-blue-600 focus:ring-offset-2',
]"
>
<span
aria-hidden="true"
:class="[
delta ? 'translate-x-5' : 'translate-x-0',
'pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out',
]"
/>
</Switch>
</SwitchGroup>
<LoadingButton
@click="startImport_wrapper"
class="w-fit"
:loading="importLoading"
>
Import
</LoadingButton>
<div v-if="importError" class="mt-4 w-fit rounded-md bg-red-600/10 p-4">
@ -180,6 +214,10 @@ import {
ListboxLabel,
ListboxOption,
ListboxOptions,
Switch,
SwitchDescription,
SwitchGroup,
SwitchLabel,
} from "@headlessui/vue";
import { XCircleIcon } from "@heroicons/vue/16/solid";
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/vue/20/solid";
@ -203,6 +241,7 @@ const currentlySelectedVersion = ref(-1);
const versionSettings = ref<
{ platform: string; startup: string; setup: string } | undefined
>();
const delta = ref(false);
const importLoading = ref(false);
const importError = ref<string | undefined>();
@ -233,6 +272,7 @@ async function startImport() {
platform: versionSettings.value.platform,
startup: versionSettings.value.startup,
setup: versionSettings.value.setup,
delta: delta.value
},
});
router.push(`/admin/task/${taskId.taskId}`);

View File

@ -11,20 +11,18 @@
class="mt-5 pt-5 border-t border-zinc-700 prose prose-invert prose-blue"
></div>
</div>
<div>
<div class="space-y-8">
<div class="px-4 py-3 bg-gray-950 rounded">
<div class="border-b border-zinc-800 pb-3">
<div
class="-ml-4 -mt-2 flex flex-wrap items-center justify-between sm:flex-nowrap"
class="flex flex-wrap items-center justify-between sm:flex-nowrap"
>
<div class="ml-4 mt-2">
<h3
class="text-base font-semibold font-display leading-6 text-zinc-100"
>
Images
</h3>
</div>
<div class="ml-4 mt-2 flex-shrink-0">
<h3
class="text-base font-semibold font-display leading-6 text-zinc-100"
>
Images
</h3>
<div class="flex-shrink-0">
<button
@click="() => (showUploadModal = true)"
type="button"
@ -90,6 +88,39 @@
</div>
</div>
</div>
<div class="py-5 px-6 bg-gray-950 rounded">
<h1 class="text-2xl font-semibold font-display text-zinc-100">
Manage version order
</h1>
<div class="text-center w-full text-sm text-zinc-600">lowest</div>
<draggable
@update="() => updateVersionOrder()"
:list="game.versions"
handle=".handle"
class="mt-2 space-y-4"
>
<template #item="{ element: item }: { element: GameVersion }">
<div
class="w-full inline-flex items-center px-4 py-2 bg-zinc-900 rounded justify-between"
>
<div class="text-zinc-100 font-semibold">
{{ item.versionName }}
</div>
<div class="text-zinc-400">
{{ item.delta ? "Upgrade mode" : "" }}
</div>
<div class="inline-flex gap-x-2">
<Bars3Icon class="cursor-move w-6 h-6 text-zinc-400 handle" />
<button @click="() => deleteVersion(item.versionName)">
<TrashIcon class="w-5 h-5 text-red-600" />
</button>
</div>
</div>
</template>
</draggable>
<div class="mt-2 text-center w-full text-sm text-zinc-600">highest</div>
<span class="text-zinc-100">{{ game.versions }}</span>
</div>
</div>
</div>
<UploadFileDialog
@ -102,7 +133,8 @@
</template>
<script setup lang="ts">
import type { Game } from "@prisma/client";
import { Bars3Icon, TrashIcon } from "@heroicons/vue/16/solid";
import type { Game, GameVersion } from "@prisma/client";
import markdownit from "markdown-it";
import UploadFileDialog from "~/components/UploadFileDialog.vue";
@ -116,9 +148,12 @@ const route = useRoute();
const gameId = route.params.id.toString();
const headers = useRequestHeaders(["cookie"]);
const game = ref(
await $fetch<Game>(`/api/v1/admin/game?id=${encodeURIComponent(gameId)}`, {
headers,
})
await $fetch(
`/api/v1/admin/game?id=${encodeURIComponent(gameId)}`,
{
headers,
}
)
);
const md = markdownit();
@ -167,4 +202,29 @@ async function uploadAfterImageUpload(result: Game) {
if (!game.value) return;
game.value.mImageLibrary = result.mImageLibrary;
}
async function deleteVersion(versionName: string) {
await $fetch("/api/v1/admin/game/version", {
method: "DELETE",
body: {
id: gameId,
versionName: versionName,
},
});
game.value.versions.splice(
game.value.versions.findIndex((e) => e.versionName === versionName),
1
);
}
async function updateVersionOrder() {
const newVersions = await $fetch("/api/v1/admin/game/version", {
method: "POST",
body: {
id: gameId,
versions: game.value.versions.map((e) => e.versionName),
},
});
game.value.versions = newVersions;
}
</script>