mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
149 lines
4.3 KiB
Vue
149 lines
4.3 KiB
Vue
<script setup lang="ts">
|
|
import { reactive, ref } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
import api from '@/api'
|
|
import type ViewBase from '@/components/globals/ViewBase.vue'
|
|
import { useAutoModal } from '@/composables/useAutoModal'
|
|
|
|
// FIXME not tested with pending migrations (disclaimer and stuff)
|
|
const { t } = useI18n()
|
|
const modalConfirm = useAutoModal()
|
|
|
|
const viewElem = ref<InstanceType<typeof ViewBase> | null>(null)
|
|
|
|
const queries = [
|
|
['GET', 'migrations?pending'],
|
|
['GET', 'migrations?done'],
|
|
]
|
|
const pending = ref()
|
|
const done = ref()
|
|
const checked = reactive({})
|
|
|
|
function onQueriesResponse({ migrations: pending_ }, { migrations: done_ }) {
|
|
done.value = done_.length ? done_.reverse() : null
|
|
pending_.forEach((migration) => {
|
|
if (migration.disclaimer) {
|
|
migration.disclaimer = migration.disclaimer.replaceAll('\n', '<br>')
|
|
checked[migration.id] = null
|
|
}
|
|
})
|
|
// FIXME change to pending
|
|
pending.value = pending_.length ? pending_.reverse() : null
|
|
}
|
|
|
|
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.
|
|
if (Object.values(checked).every((value) => value === true)) {
|
|
api
|
|
.put('migrations?accept_disclaimer', {}, 'migrations.run')
|
|
.then(() => viewElem.value!.fetchQueries())
|
|
}
|
|
}
|
|
|
|
async function skipMigration(id) {
|
|
const confirmed = await modalConfirm(t('confirm_migrations_skip'))
|
|
if (!confirmed) return
|
|
api
|
|
.put('/migrations/' + id, { skip: '', targets: id }, 'migration.skip')
|
|
.then(() => viewElem.value!.fetchQueries())
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<ViewBase
|
|
:queries="queries"
|
|
@queries-response="onQueriesResponse"
|
|
ref="viewElem"
|
|
>
|
|
<!-- PENDING MIGRATIONS -->
|
|
<YCard :title="$t('migrations_pending')" icon="cogs" no-body>
|
|
<template #header-buttons v-if="pending">
|
|
<BButton size="sm" variant="success" @click="runMigrations">
|
|
<YIcon iname="play" /> {{ $t('run') }}
|
|
</BButton>
|
|
</template>
|
|
|
|
<BCardBody v-if="pending === null">
|
|
<span class="text-success">
|
|
<YIcon iname="check-circle" /> {{ $t('migrations_no_pending') }}
|
|
</span>
|
|
</BCardBody>
|
|
|
|
<BListGroup v-else-if="pending" flush>
|
|
<BListGroupItem
|
|
v-for="{ number, description, id, disclaimer } in pending"
|
|
:key="number"
|
|
>
|
|
<div class="d-flex align-items-center">
|
|
{{ number }}. {{ description }}
|
|
|
|
<div class="ms-auto">
|
|
<BButton @click="skipMigration(id)" size="sm" variant="warning">
|
|
<YIcon iname="close" /> {{ $t('skip') }}
|
|
</BButton>
|
|
</div>
|
|
</div>
|
|
|
|
<template v-if="disclaimer">
|
|
<hr />
|
|
<p v-html="disclaimer" />
|
|
|
|
<BFormCheckbox
|
|
:id="'checkbox-' + number"
|
|
:name="'checkbox-' + number"
|
|
:aria-describedby="'checkbox-feedback-' + number"
|
|
v-model="checked[id]"
|
|
>
|
|
{{ $t('migrations_disclaimer_check_message') }}
|
|
</BFormCheckbox>
|
|
|
|
<BFormInvalidFeedback
|
|
v-if="checked[id] === false"
|
|
:state="false"
|
|
:id="'checkbox-feedback-' + number"
|
|
>
|
|
{{ $t('migrations_disclaimer_not_checked') }}
|
|
</BFormInvalidFeedback>
|
|
</template>
|
|
</BListGroupItem>
|
|
</BListGroup>
|
|
</YCard>
|
|
|
|
<!-- DONE MIGRATIONS -->
|
|
<YCard
|
|
:title="$t('migrations_done')"
|
|
icon="cogs"
|
|
collapsable
|
|
collapsed
|
|
no-body
|
|
>
|
|
<BCardBody v-if="done === null">
|
|
<span class="text-success">
|
|
<YIcon iname="check-circle" /> {{ $t('migrations_no_done') }}
|
|
</span>
|
|
</BCardBody>
|
|
|
|
<BListGroup flush v-else-if="done">
|
|
<BListGroupItem v-for="{ number, description } in done" :key="number">
|
|
{{ number }}. {{ description }}
|
|
</BListGroupItem>
|
|
</BListGroup>
|
|
</YCard>
|
|
|
|
<template #skeleton>
|
|
<CardListSkeleton :item-count="3" />
|
|
<BCard no-body>
|
|
<template #header>
|
|
<BSkeleton width="30%" height="36px" class="m-0" />
|
|
</template>
|
|
</BCard>
|
|
</template>
|
|
</ViewBase>
|
|
</template>
|