refactor: rework async ToolMigrations

This commit is contained in:
axolotle 2024-08-13 00:31:17 +02:00
parent 68e6c78c22
commit ab506a5727
2 changed files with 54 additions and 45 deletions

View file

@ -280,6 +280,22 @@ export type LogInfo = {
logs: string[] logs: string[]
} }
// MIGRATIONS
type MigrationInfo = {
id: string
number: number
name: string
mode: 'auto' | 'manual'
state: 'pending' | 'done' | 'skipped'
description: string
disclaimer: string | null
}
export type MigrationList = {
migrations: MigrationInfo[]
}
// DOMAINS // DOMAINS
export type DNSRecord = { export type DNSRecord = {

View file

@ -1,54 +1,52 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref } from 'vue' import { reactive } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import api from '@/api' import api from '@/api'
import { useAutoModal } from '@/composables/useAutoModal' import { useAutoModal } from '@/composables/useAutoModal'
import { useInitialQueries } from '@/composables/useInitialQueries' import type { Obj } from '@/types/commons'
import type { MigrationList } from '@/types/core/api'
// FIXME not tested with pending migrations (disclaimer and stuff) // FIXME not tested with pending migrations (disclaimer and stuff)
const { t } = useI18n() const { t } = useI18n()
const modalConfirm = useAutoModal() const modalConfirm = useAutoModal()
const { loading, refetch } = useInitialQueries(
[{ uri: 'migrations?pending' }, { uri: 'migrations?done' }],
{ onQueriesResponse },
)
const pending = ref() const { pending, done, checked } = await api
const done = ref() .fetchAll<
const checked = reactive({}) [MigrationList, MigrationList]
>([{ uri: 'migrations?pending' }, { uri: 'migrations?done' }])
function onQueriesResponse( .then(([{ migrations: pending }, { migrations: done }]) => {
{ migrations: pending_ }: any, const checked = {} as Obj<boolean | undefined>
{ migrations: done_ }: any, return {
) { pending: pending.length
done.value = done_.length ? done_.reverse() : null ? reactive(
pending_.forEach((migration) => { pending
if (migration.disclaimer) { .map((migration) => {
migration.disclaimer = migration.disclaimer.replaceAll('\n', '<br>') if (migration.disclaimer) {
checked[migration.id] = null migration.disclaimer =
migration.disclaimer.replaceAll('\n', '<br>') ?? null
checked[migration.id] = false
}
return migration
})
.reverse(),
)
: null,
done: done.length ? done.reverse() : null,
checked: reactive(checked),
} }
}) })
// FIXME change to pending
pending.value = pending_.length ? pending_.reverse() : null
}
function runMigrations() { function runMigrations() {
// Display an error on migration's disclaimer that aren't checked.
for (const [id, value] of Object.entries(checked)) {
if (value !== true) {
checked[id] = false
}
}
// Check that every migration's disclaimer has been checked. // Check that every migration's disclaimer has been checked.
if (Object.values(checked).every((value) => value === true)) { if (Object.values(checked).every((value) => value === true)) {
api api
.put({ uri: 'migrations?accept_disclaimer', humanKey: 'migrations.run' }) .put({ uri: 'migrations?accept_disclaimer', humanKey: 'migrations.run' })
.then(() => refetch(false)) .then(() => api.refetch())
} }
} }
async function skipMigration(id) { async function skipMigration(id: string) {
const confirmed = await modalConfirm(t('confirm_migrations_skip')) const confirmed = await modalConfirm(t('confirm_migrations_skip'))
if (!confirmed) return if (!confirmed) return
api api
@ -57,12 +55,12 @@ async function skipMigration(id) {
data: { skip: '', targets: id }, data: { skip: '', targets: id },
humanKey: 'migration.skip', humanKey: 'migration.skip',
}) })
.then(() => refetch(false)) .then(() => api.refetch())
} }
</script> </script>
<template> <template>
<ViewBase :loading="loading"> <div>
<!-- PENDING MIGRATIONS --> <!-- PENDING MIGRATIONS -->
<YCard :title="$t('migrations_pending')" icon="cogs" no-body> <YCard :title="$t('migrations_pending')" icon="cogs" no-body>
<template #header-buttons v-if="pending"> <template #header-buttons v-if="pending">
@ -86,7 +84,12 @@ async function skipMigration(id) {
{{ number }}. {{ description }} {{ number }}. {{ description }}
<div class="ms-auto"> <div class="ms-auto">
<BButton @click="skipMigration(id)" size="sm" variant="warning"> <BButton
size="sm"
variant="warning"
class="d-flex align-items-center ms-2"
@click="skipMigration(id)"
>
<YIcon iname="close" /> {{ $t('skip') }} <YIcon iname="close" /> {{ $t('skip') }}
</BButton> </BButton>
</div> </div>
@ -98,13 +101,12 @@ async function skipMigration(id) {
<BFormCheckbox <BFormCheckbox
:id="'checkbox-' + number" :id="'checkbox-' + number"
v-model="checked[id]"
:name="'checkbox-' + number" :name="'checkbox-' + number"
:aria-describedby="'checkbox-feedback-' + number" :aria-describedby="'checkbox-feedback-' + number"
v-model="checked[id]"
> >
{{ $t('migrations_disclaimer_check_message') }} {{ $t('migrations_disclaimer_check_message') }}
</BFormCheckbox> </BFormCheckbox>
<BFormInvalidFeedback <BFormInvalidFeedback
v-if="checked[id] === false" v-if="checked[id] === false"
:state="false" :state="false"
@ -137,14 +139,5 @@ async function skipMigration(id) {
</BListGroupItem> </BListGroupItem>
</BListGroup> </BListGroup>
</YCard> </YCard>
</div>
<template #skeleton>
<CardListSkeleton :item-count="3" />
<BCard no-body>
<template #header>
<BSkeleton width="30%" height="36px" class="m-0" />
</template>
</BCard>
</template>
</ViewBase>
</template> </template>