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 { computed } from 'vue'
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
|
import type {
|
||||||
|
AnyWritableComponents,
|
||||||
|
FormField,
|
||||||
|
FormFieldDict,
|
||||||
|
} from '@/types/form'
|
||||||
|
|
||||||
export function useStoreGetters() {
|
export function useStoreGetters() {
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
return Object.fromEntries(
|
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">
|
<script setup lang="ts">
|
||||||
import { computed } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
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 { 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: {
|
locale: {
|
||||||
label: t('tools_webadmin.language'),
|
|
||||||
component: 'SelectItem',
|
component: 'SelectItem',
|
||||||
props: { id: 'locale', choices: [] },
|
label: t('tools_webadmin.language'),
|
||||||
|
props: { id: 'locale', choices: asUnreffed(availableLocales) },
|
||||||
},
|
},
|
||||||
|
|
||||||
fallbackLocale: {
|
fallbackLocale: {
|
||||||
|
component: 'SelectItem',
|
||||||
label: t('tools_webadmin.fallback_language'),
|
label: t('tools_webadmin.fallback_language'),
|
||||||
description: t('tools_webadmin.fallback_language_description'),
|
description: t('tools_webadmin.fallback_language_description'),
|
||||||
component: 'SelectItem',
|
props: { id: 'fallback-locale', choices: asUnreffed(availableLocales) },
|
||||||
props: { id: 'fallback-locale', choices: [] },
|
|
||||||
},
|
},
|
||||||
|
|
||||||
cache: {
|
cache: {
|
||||||
|
component: 'CheckboxItem',
|
||||||
id: 'cache',
|
id: 'cache',
|
||||||
label: t('tools_webadmin.cache'),
|
label: t('tools_webadmin.cache'),
|
||||||
description: t('tools_webadmin.cache_description'),
|
description: t('tools_webadmin.cache_description'),
|
||||||
component: 'CheckboxItem',
|
|
||||||
props: { labels: { true: 'enabled', false: 'disabled' } },
|
props: { labels: { true: 'enabled', false: 'disabled' } },
|
||||||
},
|
},
|
||||||
|
|
||||||
transitions: {
|
transitions: {
|
||||||
|
component: 'CheckboxItem',
|
||||||
id: 'transitions',
|
id: 'transitions',
|
||||||
label: t('tools_webadmin.transitions'),
|
label: t('tools_webadmin.transitions'),
|
||||||
component: 'CheckboxItem',
|
|
||||||
props: { labels: { true: 'enabled', false: 'disabled' } },
|
props: { labels: { true: 'enabled', false: 'disabled' } },
|
||||||
},
|
},
|
||||||
|
|
||||||
dark: {
|
dark: {
|
||||||
|
component: 'CheckboxItem',
|
||||||
id: 'theme',
|
id: 'theme',
|
||||||
label: t('tools_webadmin.theme'),
|
label: t('tools_webadmin.theme'),
|
||||||
component: 'CheckboxItem',
|
|
||||||
props: { labels: { true: '🌙', false: '☀️' } },
|
props: { labels: { true: '🌙', false: '☀️' } },
|
||||||
},
|
},
|
||||||
|
|
||||||
// experimental: added in `created()`
|
experimental: {
|
||||||
}
|
component: 'CheckboxItem',
|
||||||
|
|
||||||
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 = {
|
|
||||||
id: 'experimental',
|
id: 'experimental',
|
||||||
label: t('tools_webadmin.experimental'),
|
label: t('tools_webadmin.experimental'),
|
||||||
description: t('tools_webadmin.experimental_description'),
|
description: t('tools_webadmin.experimental_description'),
|
||||||
component: 'CheckboxItem',
|
// Available in dev mode only
|
||||||
|
visible: import.meta.env.DEV,
|
||||||
props: { labels: { true: 'enabled', false: 'disabled' } },
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<CardForm :title="$t('tools_webadmin_settings')" icon="cog" no-footer>
|
<CardForm
|
||||||
<template v-for="(field, fname) in fields" :key="fname">
|
v-model="form"
|
||||||
<FormField v-bind="field" v-model="form[fname]" />
|
:fields="fields"
|
||||||
<hr />
|
:title="$t('tools_webadmin_settings')"
|
||||||
</template>
|
icon="cog"
|
||||||
</CardForm>
|
no-footer
|
||||||
|
hr
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Add table
Reference in a new issue