mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
migration(bvn): update modals and modal system
This commit is contained in:
parent
915023de1d
commit
622e5be061
19 changed files with 146 additions and 69 deletions
|
@ -53,6 +53,8 @@
|
|||
</main>
|
||||
</ViewLockOverlay>
|
||||
|
||||
<BModalOrchestrator />
|
||||
|
||||
<!-- HISTORY CONSOLE -->
|
||||
<HistoryConsole />
|
||||
|
||||
|
|
42
app/src/composables/useAutoModal.js
Normal file
42
app/src/composables/useAutoModal.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { h } from 'vue'
|
||||
import { useModalController, BModal } from 'bootstrap-vue-next'
|
||||
import { VueShowdown } from 'vue-showdown'
|
||||
|
||||
export function useAutoModal() {
|
||||
const { confirm, show } = useModalController()
|
||||
|
||||
return function (
|
||||
message,
|
||||
props_,
|
||||
{ markdown = false, cancelable = true } = {},
|
||||
) {
|
||||
const props = {
|
||||
okTitle: this.$t('ok'),
|
||||
cancelTitle: this.$t('cancel'),
|
||||
centered: true,
|
||||
okOnly: !cancelable,
|
||||
...(markdown
|
||||
? { headerBgVariant: 'warning', headerClass: 'text-black' }
|
||||
: {
|
||||
hideHeader: true,
|
||||
bodyBgVariant: 'warning',
|
||||
bodyClass: ['fw-bold', 'rounded-top', 'text-black'],
|
||||
}),
|
||||
...props_,
|
||||
}
|
||||
|
||||
const fn = cancelable ? confirm : show
|
||||
return fn?.({
|
||||
props,
|
||||
component: h(BModal, null, {
|
||||
default: () =>
|
||||
markdown
|
||||
? h(VueShowdown, {
|
||||
markdown: message,
|
||||
options: { headerLevelStart: 3 },
|
||||
})
|
||||
: message,
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
|
@ -29,41 +29,6 @@ app.use(VueShowdownPlugin, {
|
|||
},
|
||||
})
|
||||
|
||||
// Ugly wrapper for `$bvModal.msgBoxConfirm` to set default i18n button titles
|
||||
// FIXME find or wait for a better way
|
||||
app.config.globalProperties.$askConfirmation = function (message, props) {
|
||||
return this.$bvModal.msgBoxConfirm(message, {
|
||||
okTitle: this.$t('ok'),
|
||||
cancelTitle: this.$t('cancel'),
|
||||
bodyBgVariant: 'warning',
|
||||
centered: true,
|
||||
bodyClass: [
|
||||
'font-weight-bold',
|
||||
'rounded-top',
|
||||
store.state.dark ? 'text-white' : 'text-black',
|
||||
],
|
||||
...props,
|
||||
})
|
||||
}
|
||||
|
||||
app.config.globalProperties.$askMdConfirmation = function (
|
||||
markdown,
|
||||
props,
|
||||
ok = false,
|
||||
) {
|
||||
const content = this.$createElement('vue-showdown', {
|
||||
props: { markdown, flavor: 'github', options: { headerLevelStart: 4 } },
|
||||
})
|
||||
return this.$bvModal['msgBox' + (ok ? 'Ok' : 'Confirm')](content, {
|
||||
okTitle: this.$t('yes'),
|
||||
cancelTitle: this.$t('cancel'),
|
||||
headerBgVariant: 'warning',
|
||||
headerClass: store.state.dark ? 'text-white' : 'text-black',
|
||||
centered: true,
|
||||
...props,
|
||||
})
|
||||
}
|
||||
|
||||
// Register global components
|
||||
const globalComponentsModules = import.meta.glob(
|
||||
['@/components/globals/*.vue', '@/components/globals/*/*.vue'],
|
||||
|
|
|
@ -45,7 +45,9 @@
|
|||
// Utilities
|
||||
@import '~bootstrap/scss/utilities/api';
|
||||
|
||||
@import '~bootstrap-vue-next/src/styles/styles.scss';
|
||||
// @import '~bootstrap-vue-next/src/styles/styles.scss';
|
||||
// FIXME modals doesn't appears if we import the scss
|
||||
@import 'bootstrap-vue-next/dist/bootstrap-vue-next.css';
|
||||
|
||||
// Import fonts
|
||||
@import 'font';
|
||||
|
|
|
@ -92,6 +92,7 @@
|
|||
import { useVuelidate } from '@vuelidate/core'
|
||||
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { DomainForm } from '@/views/_partials'
|
||||
import LoginView from '@/views/LoginView.vue'
|
||||
import { formatFormData } from '@/helpers/yunohostArguments'
|
||||
|
@ -114,6 +115,7 @@ export default {
|
|||
setup() {
|
||||
return {
|
||||
v$: useVuelidate(),
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -179,7 +181,7 @@ export default {
|
|||
},
|
||||
|
||||
async setUser() {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_postinstall', { domain: this.domain }),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -223,6 +223,7 @@
|
|||
import { useVuelidate } from '@vuelidate/core'
|
||||
|
||||
import CardDeckFeed from '@/components/CardDeckFeed.vue'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { required, appRepoUrl } from '@/helpers/validators'
|
||||
import { randint } from '@/helpers/commons'
|
||||
|
||||
|
@ -243,6 +244,7 @@ export default {
|
|||
setup() {
|
||||
return {
|
||||
v$: useVuelidate(),
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -403,7 +405,7 @@ export default {
|
|||
async onInstallClick(appId) {
|
||||
const app = this.apps.find((app) => app.id === appId)
|
||||
if (!app.decent_quality) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_install_app_' + app.state),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
@ -413,7 +415,7 @@ export default {
|
|||
|
||||
// INSTALL CUSTOM APP
|
||||
async onCustomInstallClick() {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_install_custom_app'),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -343,8 +343,8 @@
|
|||
id="uninstall-modal"
|
||||
:title="$t('confirm_uninstall', { name: id })"
|
||||
header-bg-variant="warning"
|
||||
header-class="text-black"
|
||||
:body-class="{ 'd-none': !app.supports_purge }"
|
||||
body-bg-variant=""
|
||||
@ok="uninstall"
|
||||
>
|
||||
<BFormGroup v-if="app.supports_purge">
|
||||
|
@ -366,6 +366,7 @@ import { mapGetters } from 'vuex'
|
|||
import { useVuelidate } from '@vuelidate/core'
|
||||
|
||||
import api, { objectToParams } from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { humanPermissionName } from '@/helpers/filters/human'
|
||||
import { helpers, required } from '@/helpers/validators'
|
||||
import { isEmptyValue } from '@/helpers/commons'
|
||||
|
@ -390,6 +391,7 @@ export default {
|
|||
setup() {
|
||||
return {
|
||||
v$: useVuelidate(),
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -646,7 +648,7 @@ export default {
|
|||
},
|
||||
|
||||
async changeUrl() {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_app_change_url'),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
@ -662,9 +664,7 @@ export default {
|
|||
},
|
||||
|
||||
async setAsDefaultDomain(undo = false) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
this.$t('confirm_app_default'),
|
||||
)
|
||||
const confirmed = await this.modalConfirm(this.$t('confirm_app_default'))
|
||||
if (!confirmed) return
|
||||
|
||||
api
|
||||
|
|
|
@ -209,6 +209,7 @@
|
|||
import { useVuelidate } from '@vuelidate/core'
|
||||
|
||||
import api, { objectToParams } from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import {
|
||||
formatYunoHostArguments,
|
||||
formatI18nField,
|
||||
|
@ -230,6 +231,7 @@ export default {
|
|||
setup() {
|
||||
return {
|
||||
v$: useVuelidate(),
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -379,7 +381,7 @@ export default {
|
|||
|
||||
async performInstall() {
|
||||
if ('path' in this.form && this.form.path === '/') {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_install_domain_root', {
|
||||
domain: this.form.domain,
|
||||
}),
|
||||
|
@ -405,15 +407,14 @@ export default {
|
|||
if (postInstall) {
|
||||
const message =
|
||||
this.$t('app.install.notifs.post.alert') + '\n\n' + postInstall
|
||||
await this.$askMdConfirmation(
|
||||
await this.modalConfirm(
|
||||
message,
|
||||
{
|
||||
title: this.$t('app.install.notifs.post.title', {
|
||||
name: this.app.name,
|
||||
}),
|
||||
okTitle: this.$t('ok'),
|
||||
},
|
||||
true,
|
||||
{ markdown: true, cancelable: false },
|
||||
)
|
||||
}
|
||||
this.$router.push({ name: 'app-list' })
|
||||
|
|
|
@ -137,6 +137,7 @@
|
|||
|
||||
<script>
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { readableDate } from '@/helpers/filters/date'
|
||||
import { humanSize } from '@/helpers/filters/human'
|
||||
import { isEmptyValue } from '@/helpers/commons'
|
||||
|
@ -149,6 +150,12 @@ export default {
|
|||
name: { type: String, required: true },
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
queries: [['GET', `backups/${this.name}?with_details`]],
|
||||
|
@ -215,7 +222,7 @@ export default {
|
|||
},
|
||||
|
||||
async restoreBackup() {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_restore', { name: this.name }),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
@ -245,7 +252,7 @@ export default {
|
|||
},
|
||||
|
||||
async deleteBackup() {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_delete', { name: this.name }),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -145,6 +145,7 @@
|
|||
|
||||
<script>
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { isEmptyValue } from '@/helpers/commons'
|
||||
|
||||
export default {
|
||||
|
@ -154,6 +155,12 @@ export default {
|
|||
name: { type: String, required: true },
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
queries: [['GET', `domains/${this.name}/dns/suggest`]],
|
||||
|
@ -246,7 +253,7 @@ export default {
|
|||
|
||||
async pushDnsChanges() {
|
||||
if (this.force) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('domain.dns.push_force_confirm'),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -125,8 +125,8 @@
|
|||
:title="$t('confirm_delete', { name: this.name })"
|
||||
@ok="deleteDomain"
|
||||
header-bg-variant="warning"
|
||||
body-class=""
|
||||
body-bg-variant=""
|
||||
header-class="text-black"
|
||||
:body-class="{ 'd-none': !isMainDynDomain }"
|
||||
>
|
||||
<BFormGroup v-if="isMainDynDomain">
|
||||
<BFormCheckbox v-model="unsubscribeDomainFromDyndns">
|
||||
|
@ -141,6 +141,7 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
|
||||
import api, { objectToParams } from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import {
|
||||
formatFormData,
|
||||
formatYunoHostConfigPanels,
|
||||
|
@ -160,6 +161,12 @@ export default {
|
|||
name: { type: String, required: true },
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
queries: [
|
||||
|
@ -279,7 +286,7 @@ export default {
|
|||
},
|
||||
|
||||
async setAsDefaultDomain() {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_change_maindomain'),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -134,6 +134,7 @@
|
|||
|
||||
<script>
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { isEmptyValue } from '@/helpers/commons'
|
||||
import TagsSelectizeItem from '@/components/globals/formItems/TagsSelectizeItem.vue'
|
||||
|
||||
|
@ -146,6 +147,12 @@ export default {
|
|||
TagsSelectizeItem,
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
queries: [
|
||||
|
@ -264,7 +271,7 @@ export default {
|
|||
async onPermissionChanged({ option, groupName, action, applyMethod }) {
|
||||
const permId = this.permissions.find((perm) => perm.label === option).id
|
||||
if (action === 'add' && ['sftp.main', 'ssh.main'].includes(permId)) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_group_add_access_permission', {
|
||||
name: groupName,
|
||||
perm: option,
|
||||
|
@ -310,7 +317,7 @@ export default {
|
|||
},
|
||||
|
||||
async deleteGroup(groupName) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_delete', { name: groupName }),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
|
||||
<script>
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { distanceToNow } from '@/helpers/filters/date'
|
||||
|
||||
export default {
|
||||
|
@ -92,6 +93,12 @@ export default {
|
|||
name: { type: String, required: true },
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
queries: [
|
||||
|
@ -132,7 +139,7 @@ export default {
|
|||
},
|
||||
|
||||
async updateService(action) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_service_' + action, { name: this.name }),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -121,6 +121,7 @@
|
|||
import { useVuelidate } from '@vuelidate/core'
|
||||
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { required, integer, between } from '@/helpers/validators'
|
||||
|
||||
export default {
|
||||
|
@ -129,6 +130,7 @@ export default {
|
|||
setup() {
|
||||
return {
|
||||
v$: useVuelidate(),
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -214,7 +216,7 @@ export default {
|
|||
},
|
||||
|
||||
async togglePort({ action, port, protocol, connection }) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_firewall_' + action, {
|
||||
port,
|
||||
protocol,
|
||||
|
@ -244,7 +246,7 @@ export default {
|
|||
|
||||
async toggleUpnp(value) {
|
||||
const action = this.upnpEnabled ? 'disable' : 'enable'
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_upnp_' + action),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -88,11 +88,18 @@
|
|||
|
||||
<script>
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
|
||||
// FIXME not tested with pending migrations (disclaimer and stuff)
|
||||
export default {
|
||||
name: 'ToolMigrations',
|
||||
|
||||
setup() {
|
||||
return {
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
queries: [
|
||||
|
@ -136,7 +143,7 @@ export default {
|
|||
},
|
||||
|
||||
async skipMigration(id) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_migrations_skip'),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -35,13 +35,20 @@
|
|||
|
||||
<script>
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
|
||||
export default {
|
||||
name: 'ToolPower',
|
||||
|
||||
setup() {
|
||||
return {
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async triggerAction(action) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_reboot_action_' + action),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -88,10 +88,11 @@
|
|||
</YCard>
|
||||
|
||||
<BModal
|
||||
v-model="showPreUpgradeModal"
|
||||
id="apps-pre-upgrade"
|
||||
:title="$t('app.upgrade.confirm.title')"
|
||||
header-bg-variant="warning"
|
||||
:header-class="dark ? 'text-white' : 'text-black'"
|
||||
header-class="text-black"
|
||||
:ok-title="$t('system_upgrade_btn')"
|
||||
ok-variant="success"
|
||||
:cancel-title="$t('cancel')"
|
||||
|
@ -139,6 +140,7 @@
|
|||
|
||||
<script>
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
import CardCollapse from '@/components/CardCollapse.vue'
|
||||
|
@ -150,6 +152,12 @@ export default {
|
|||
CardCollapse,
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
queries: [['PUT', 'update/all', {}, 'update']],
|
||||
|
@ -158,6 +166,7 @@ export default {
|
|||
apps: undefined,
|
||||
importantYunohostUpgrade: undefined,
|
||||
pendingMigrations: undefined,
|
||||
showPreUpgradeModal: false,
|
||||
preUpgrade: {
|
||||
apps: [],
|
||||
notifs: [],
|
||||
|
@ -200,7 +209,7 @@ export default {
|
|||
: '',
|
||||
}))
|
||||
this.preUpgrade = { apps, hasNotifs: apps.some((app) => app.notif) }
|
||||
this.$bvModal.show('apps-pre-upgrade')
|
||||
this.showPreUpgradeModal = true
|
||||
},
|
||||
|
||||
async performAppsUpgrade(ids) {
|
||||
|
@ -224,7 +233,7 @@ export default {
|
|||
if (postMessage) {
|
||||
const message =
|
||||
this.$t('app.upgrade.notifs.post.alert') + '\n\n' + postMessage
|
||||
return this.$askMdConfirmation(
|
||||
return this.modalConfirm(
|
||||
message,
|
||||
{
|
||||
title: this.$t('app.upgrade.notifs.post.title', {
|
||||
|
@ -233,7 +242,7 @@ export default {
|
|||
okTitle: this.$t(isLast ? 'ok' : 'app.upgrade.continue'),
|
||||
cancelTitle: this.$t('app.upgrade.stop'),
|
||||
},
|
||||
isLast,
|
||||
{ markdown: true, cancelable: !isLast },
|
||||
)
|
||||
} else {
|
||||
return Promise.resolve(true)
|
||||
|
@ -248,7 +257,7 @@ export default {
|
|||
},
|
||||
|
||||
async performSystemUpgrade() {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('confirm_update_system'),
|
||||
)
|
||||
if (!confirmed) return
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
<script>
|
||||
import api from '@/api'
|
||||
import { useAutoModal } from '@/composables/useAutoModal'
|
||||
import { useVuelidate } from '@vuelidate/core'
|
||||
|
||||
import { formatFormData } from '@/helpers/yunohostArguments'
|
||||
|
@ -34,6 +35,7 @@ export default {
|
|||
setup() {
|
||||
return {
|
||||
v$: useVuelidate(),
|
||||
modalConfirm: useAutoModal(),
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -89,7 +91,7 @@ export default {
|
|||
methods: {
|
||||
async onSubmit() {
|
||||
if (this.form.delete) {
|
||||
const confirmed = await this.$askConfirmation(
|
||||
const confirmed = await this.modalConfirm(
|
||||
this.$t('users_import_confirm_destructive'),
|
||||
{ okTitle: this.$t('users_import_delete_others') },
|
||||
)
|
||||
|
|
|
@ -83,8 +83,7 @@
|
|||
:title="$t('confirm_delete', { name: user.username })"
|
||||
@ok="deleteUser"
|
||||
header-bg-variant="warning"
|
||||
body-class=""
|
||||
body-bg-variant=""
|
||||
header-class="text-black"
|
||||
>
|
||||
<BFormGroup>
|
||||
<BFormCheckbox v-model="purge">
|
||||
|
|
Loading…
Add table
Reference in a new issue