mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
refactor: use useForm + rework mapStoreGetSet of ToolWebadmin
This commit is contained in:
parent
0262aaaefb
commit
317bf7fbb6
2 changed files with 87 additions and 51 deletions
|
@ -1,6 +1,13 @@
|
|||
import type { WritableComputedRef } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
import type {
|
||||
AnyWritableComponents,
|
||||
FormField,
|
||||
FormFieldDict,
|
||||
} from '@/types/form'
|
||||
|
||||
export function useStoreGetters() {
|
||||
const store = useStore()
|
||||
return Object.fromEntries(
|
||||
|
@ -10,3 +17,41 @@ export function useStoreGetters() {
|
|||
]),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamicly generate computed properties from store with get/set and automatic commit/dispatch
|
||||
*/
|
||||
export function useMapStoreGetSet<FFD extends FormFieldDict>({
|
||||
commit = [],
|
||||
dispatch = [],
|
||||
}: {
|
||||
commit: Extract<keyof FFD, string>[]
|
||||
dispatch: Extract<keyof FFD, string>[]
|
||||
}) {
|
||||
const store = useStore()
|
||||
type Types = {
|
||||
[k in keyof FFD]: FFD[k] extends
|
||||
| FormField<AnyWritableComponents, infer MV>
|
||||
| undefined
|
||||
? MV
|
||||
: any
|
||||
}
|
||||
return [...commit, ...dispatch].reduce(
|
||||
(obj, prop) => {
|
||||
obj[prop] = computed<Types[typeof prop]>({
|
||||
get() {
|
||||
return store.getters[prop]
|
||||
},
|
||||
set(value) {
|
||||
const isCommit = commit.includes(prop)
|
||||
const key = (isCommit ? 'SET_' : 'UPDATE_') + prop.toUpperCase()
|
||||
store[isCommit ? 'commit' : 'dispatch'](key, value)
|
||||
},
|
||||
})
|
||||
return obj
|
||||
},
|
||||
{} as { [k in keyof FFD]: WritableComputedRef<any> },
|
||||
) as {
|
||||
[k in keyof FFD]: WritableComputedRef<Types[k]>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,93 +1,84 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useStore } from 'vuex'
|
||||
|
||||
import { asUnreffed } from '@/helpers/commons'
|
||||
import { useMapStoreGetSet, useStoreGetters } from '@/store/utils'
|
||||
import type { FormField } from '@/types/form'
|
||||
|
||||
const { t } = useI18n()
|
||||
const store = useStore()
|
||||
const { availableLocales } = useStoreGetters()
|
||||
|
||||
const fields = {
|
||||
const form = ref({
|
||||
...useMapStoreGetSet<Fields>({
|
||||
commit: ['cache', 'transitions', 'experimental'],
|
||||
dispatch: ['locale', 'fallbackLocale', 'dark'],
|
||||
}),
|
||||
})
|
||||
|
||||
type Fields = {
|
||||
locale: FormField<'SelectItem', string>
|
||||
fallbackLocale: FormField<'SelectItem', string>
|
||||
cache: FormField<'CheckboxItem', boolean>
|
||||
transitions: FormField<'CheckboxItem', boolean>
|
||||
dark: FormField<'CheckboxItem', boolean>
|
||||
experimental: FormField<'CheckboxItem', boolean>
|
||||
}
|
||||
const fields: Fields = {
|
||||
locale: {
|
||||
label: t('tools_webadmin.language'),
|
||||
component: 'SelectItem',
|
||||
props: { id: 'locale', choices: [] },
|
||||
label: t('tools_webadmin.language'),
|
||||
props: { id: 'locale', choices: asUnreffed(availableLocales) },
|
||||
},
|
||||
|
||||
fallbackLocale: {
|
||||
component: 'SelectItem',
|
||||
label: t('tools_webadmin.fallback_language'),
|
||||
description: t('tools_webadmin.fallback_language_description'),
|
||||
component: 'SelectItem',
|
||||
props: { id: 'fallback-locale', choices: [] },
|
||||
props: { id: 'fallback-locale', choices: asUnreffed(availableLocales) },
|
||||
},
|
||||
|
||||
cache: {
|
||||
component: 'CheckboxItem',
|
||||
id: 'cache',
|
||||
label: t('tools_webadmin.cache'),
|
||||
description: t('tools_webadmin.cache_description'),
|
||||
component: 'CheckboxItem',
|
||||
props: { labels: { true: 'enabled', false: 'disabled' } },
|
||||
},
|
||||
|
||||
transitions: {
|
||||
component: 'CheckboxItem',
|
||||
id: 'transitions',
|
||||
label: t('tools_webadmin.transitions'),
|
||||
component: 'CheckboxItem',
|
||||
props: { labels: { true: 'enabled', false: 'disabled' } },
|
||||
},
|
||||
|
||||
dark: {
|
||||
component: 'CheckboxItem',
|
||||
id: 'theme',
|
||||
label: t('tools_webadmin.theme'),
|
||||
component: 'CheckboxItem',
|
||||
props: { labels: { true: '🌙', false: '☀️' } },
|
||||
},
|
||||
|
||||
// experimental: added in `created()`
|
||||
}
|
||||
|
||||
const form = {
|
||||
...mapStoreGetSet(['locale', 'fallbackLocale', 'dark'], 'dispatch'),
|
||||
...mapStoreGetSet(['cache', 'transitions', 'experimental']),
|
||||
}
|
||||
|
||||
const availableLocales = store.getters.availableLocales
|
||||
fields.locale.props.choices = availableLocales
|
||||
fields.fallbackLocale.props.choices = availableLocales
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
fields.experimental = {
|
||||
experimental: {
|
||||
component: 'CheckboxItem',
|
||||
id: 'experimental',
|
||||
label: t('tools_webadmin.experimental'),
|
||||
description: t('tools_webadmin.experimental_description'),
|
||||
component: 'CheckboxItem',
|
||||
// Available in dev mode only
|
||||
visible: import.meta.env.DEV,
|
||||
props: { labels: { true: 'enabled', false: 'disabled' } },
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME move into helpers ?
|
||||
// Dynamicly generate computed properties from store with get/set and automatic commit/dispatch
|
||||
function mapStoreGetSet(props = [], action = 'commit') {
|
||||
return props.reduce((obj, prop) => {
|
||||
obj[prop] = computed({
|
||||
get() {
|
||||
return store.getters[prop]
|
||||
},
|
||||
set(value) {
|
||||
const key =
|
||||
(action === 'commit' ? 'SET_' : 'UPDATE_') + prop.toUpperCase()
|
||||
store[action](key, value)
|
||||
},
|
||||
})
|
||||
return obj
|
||||
}, {})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<CardForm :title="$t('tools_webadmin_settings')" icon="cog" no-footer>
|
||||
<template v-for="(field, fname) in fields" :key="fname">
|
||||
<FormField v-bind="field" v-model="form[fname]" />
|
||||
<hr />
|
||||
</template>
|
||||
</CardForm>
|
||||
<CardForm
|
||||
v-model="form"
|
||||
:fields="fields"
|
||||
:title="$t('tools_webadmin_settings')"
|
||||
icon="cog"
|
||||
no-footer
|
||||
hr
|
||||
/>
|
||||
</template>
|
||||
|
|
Loading…
Add table
Reference in a new issue