chore(front): use section and heading in settings page

This commit is contained in:
ArneBo 2025-03-20 09:58:07 +01:00
parent 02dbb7990d
commit 3584e67851
2 changed files with 154 additions and 158 deletions

View File

@ -8,7 +8,7 @@ import { useStore } from '~/store'
import useLogger from '~/composables/useLogger' import useLogger from '~/composables/useLogger'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import Layout from '~/components/ui/Layout.vue' import Section from '~/components/ui/Section.vue'
import Toggle from '~/components/ui/Toggle.vue' import Toggle from '~/components/ui/Toggle.vue'
import Input from '~/components/ui/Input.vue' import Input from '~/components/ui/Input.vue'
import Alert from '~/components/ui/Alert.vue' import Alert from '~/components/ui/Alert.vue'
@ -106,157 +106,164 @@ const save = async () => {
</script> </script>
<template> <template>
<Layout <Section
:id="group.id" align-left
form no-items
class="ui form component-settings-group" :h2="group.label"
@submit.prevent="save"
> >
<h2> <form
{{ group.label }} :id="group.id"
</h2> class="ui form component-settings-group"
<Alert style="grid-column: 1 / -1;"
v-if="errors.length > 0" @submit.prevent="save"
red
> >
<h4 class="header"> <Alert
{{ t('components.admin.SettingsGroup.header.error') }} v-if="errors.length > 0"
</h4> red
<ul class="list">
<li
v-for="(error, key) in errors"
:key="key"
>
{{ error }}
</li>
</ul>
</Alert>
<Alert
v-if="result"
green
>
{{ t('components.admin.SettingsGroup.message.success') }}
</Alert>
<div
v-for="(setting, key) in settings"
:key="key"
class="ui field"
>
<template v-if="setting.field.widget.class !== 'CheckboxInput'">
<label :for="setting.identifier">{{ setting.verbose_name }}</label>
<p v-if="setting.help_text">
{{ setting.help_text }}
</p>
</template>
<content-form
v-if="setting.fieldType === 'markdown'"
v-bind="setting.fieldParams"
v-model="values[setting.identifier]"
/>
<!-- eslint-disable vue/valid-v-model -->
<signup-form-builder
v-else-if="setting.fieldType === 'formBuilder'"
v-model="values[setting.identifier] as Form"
:signup-approval-enabled="!!values.moderation__signup_approval_enabled"
/>
<!-- eslint-enable vue/valid-v-model -->
<Input
v-else-if="setting.field.widget.class === 'PasswordInput'"
v-model="values[setting.identifier]"
password
type="password"
class="ui input"
/>
<Input
v-else-if="setting.field.widget.class === 'TextInput'"
v-model="values[setting.identifier]"
type="text"
class="ui input"
/>
<Input
v-else-if="setting.field.class === 'IntegerField'"
v-model.number="values[setting.identifier]"
type="number"
class="ui input"
/>
<!-- eslint-disable vue/valid-v-model -->
<textarea
v-else-if="setting.field.widget.class === 'Textarea'"
v-model="values[setting.identifier] as string"
type="text"
class="ui input"
/>
<!-- eslint-enable vue/valid-v-model -->
<div
v-else-if="setting.field.widget.class === 'CheckboxInput'"
> >
<h4 class="header">
{{ t('components.admin.SettingsGroup.header.error') }}
</h4>
<ul class="list">
<li
v-for="(error, key) in errors"
:key="key"
>
{{ error }}
</li>
</ul>
</Alert>
<Alert
v-if="result"
green
>
{{ t('components.admin.SettingsGroup.message.success') }}
</Alert>
<Spacer :size="16" />
<div
v-for="(setting, key) in settings"
:key="key"
class="ui field"
>
<template v-if="setting.field.widget.class !== 'CheckboxInput'">
<label :for="setting.identifier">{{ setting.verbose_name }}</label>
<p v-if="setting.help_text">
{{ setting.help_text }}
</p>
</template>
<content-form
v-if="setting.fieldType === 'markdown'"
v-bind="setting.fieldParams"
v-model="values[setting.identifier]"
/>
<!-- eslint-disable vue/valid-v-model --> <!-- eslint-disable vue/valid-v-model -->
<Toggle <signup-form-builder
v-model="values[setting.identifier] as boolean" v-else-if="setting.fieldType === 'formBuilder'"
big v-model="values[setting.identifier] as Form"
:label="setting.verbose_name" :signup-approval-enabled="!!values.moderation__signup_approval_enabled"
/> />
<!-- eslint-enable vue/valid-v-model --> <!-- eslint-enable vue/valid-v-model -->
<p v-if="setting.help_text">
{{ setting.help_text }}
</p>
</div>
<select
v-else-if="setting.field.class === 'MultipleChoiceField'"
:id="setting.identifier"
v-model="values[setting.identifier]"
multiple
class="ui search selection dropdown"
style="height: 150px;"
>
<option
v-for="v in setting.additional_data?.choices"
:key="v[0]"
:value="v[0]"
>
{{ v[1] }}
</option>
</select>
<select
v-else-if="setting.field.class === 'ChoiceField'"
:id="setting.identifier"
v-model="values[setting.identifier]"
class="ui search selection dropdown"
>
<option
v-for="v in setting.additional_data?.choices"
:key="v[0]"
:value="v[0]"
>
{{ v[1] }}
</option>
</select>
<div v-else-if="setting.field.widget.class === 'ImageWidget'">
<Input <Input
:id="setting.identifier" v-else-if="setting.field.widget.class === 'PasswordInput'"
:ref="setFileRef(setting.identifier)" v-model="values[setting.identifier]"
type="file" password
type="password"
class="ui input"
/> />
<div v-if="values[setting.identifier]"> <Input
<h3 class="ui header"> v-else-if="setting.field.widget.class === 'TextInput'"
{{ t('components.admin.SettingsGroup.header.image') }} v-model="values[setting.identifier]"
</h3> type="text"
<img class="ui input"
v-if="values[setting.identifier]" />
class="ui image" <Input
alt="" v-else-if="setting.field.class === 'IntegerField'"
:src="store.getters['instance/absoluteUrl'](values[setting.identifier])" v-model.number="values[setting.identifier]"
> type="number"
class="ui input"
/>
<!-- eslint-disable vue/valid-v-model -->
<textarea
v-else-if="setting.field.widget.class === 'Textarea'"
v-model="values[setting.identifier] as string"
type="text"
class="ui input"
/>
<!-- eslint-enable vue/valid-v-model -->
<div
v-else-if="setting.field.widget.class === 'CheckboxInput'"
>
<!-- eslint-disable vue/valid-v-model -->
<Toggle
v-model="values[setting.identifier] as boolean"
big
:label="setting.verbose_name"
/>
<!-- eslint-enable vue/valid-v-model -->
<Spacer :size="8" />
<p v-if="setting.help_text">
{{ setting.help_text }}
</p>
</div> </div>
<select
v-else-if="setting.field.class === 'MultipleChoiceField'"
:id="setting.identifier"
v-model="values[setting.identifier]"
multiple
class="ui search selection dropdown"
style="height: 150px;"
>
<option
v-for="v in setting.additional_data?.choices"
:key="v[0]"
:value="v[0]"
>
{{ v[1] }}
</option>
</select>
<select
v-else-if="setting.field.class === 'ChoiceField'"
:id="setting.identifier"
v-model="values[setting.identifier]"
class="ui search selection dropdown"
>
<option
v-for="v in setting.additional_data?.choices"
:key="v[0]"
:value="v[0]"
>
{{ v[1] }}
</option>
</select>
<div v-else-if="setting.field.widget.class === 'ImageWidget'">
<Input
:id="setting.identifier"
:ref="setFileRef(setting.identifier)"
type="file"
/>
<div v-if="values[setting.identifier]">
<h3 class="ui header">
{{ t('components.admin.SettingsGroup.header.image') }}
</h3>
<img
v-if="values[setting.identifier]"
class="ui image"
alt=""
:src="store.getters['instance/absoluteUrl'](values[setting.identifier])"
>
</div>
</div>
<Spacer />
</div> </div>
</div> <Button
<Button type="submit"
type="submit" :class="['ui', {'loading': isLoading}, 'right', 'floated', 'success', 'button']"
:class="['ui', {'loading': isLoading}, 'right', 'floated', 'success', 'button']" primary
primary >
> {{ t('components.admin.SettingsGroup.button.save') }}
{{ t('components.admin.SettingsGroup.button.save') }} </Button>
</Button> </form>
<Spacer :size="32" /> </Section>
</Layout> <Spacer />
<Spacer />
</template> </template>

View File

@ -2,10 +2,8 @@
import type { SettingsGroup as SettingsGroupType } from '~/types' import type { SettingsGroup as SettingsGroupType } from '~/types'
import axios from 'axios' import axios from 'axios'
import $ from 'jquery'
import { ref, nextTick, onMounted, computed, watch } from 'vue' import { ref, nextTick, computed } from 'vue'
import { useCurrentElement } from '@vueuse/core'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
@ -13,6 +11,7 @@ import SettingsGroup from '~/components/admin/SettingsGroup.vue'
import Layout from '~/components/ui/Layout.vue' import Layout from '~/components/ui/Layout.vue'
import Loader from '~/components/ui/Loader.vue' import Loader from '~/components/ui/Loader.vue'
import Header from '~/components/ui/Header.vue'
import Toc from '~/components/ui/Toc.vue' import Toc from '~/components/ui/Toc.vue'
import useErrorHandler from '~/composables/useErrorHandler' import useErrorHandler from '~/composables/useErrorHandler'
@ -156,17 +155,6 @@ if (route.hash) {
scrollTo(route.hash.slice(1)) scrollTo(route.hash.slice(1))
} }
const el = useCurrentElement()
onMounted(async () => {
await nextTick()
$(el.value).find('select.dropdown').dropdown()
})
watch(settingsData, async () => {
await nextTick()
$(el.value).find('.sticky').sticky({ context: '#settings-grid' })
})
const isLoading = ref(false) const isLoading = ref(false)
const fetchSettings = async () => { const fetchSettings = async () => {
isLoading.value = true isLoading.value = true
@ -192,6 +180,7 @@ await nextTick()
:class="['ui', {'loading': isLoading}]" :class="['ui', {'loading': isLoading}]"
> >
<Loader v-if="isLoading" /> <Loader v-if="isLoading" />
<Header :h1="labels.settings" />
<div <div
v-if="settingsData" v-if="settingsData"
id="settings-grid" id="settings-grid"