chore(front): use section and heading in settings page
This commit is contained in:
parent
02dbb7990d
commit
3584e67851
|
@ -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>
|
||||||
|
|
|
@ -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"
|
||||||
|
|
Loading…
Reference in New Issue