2022-05-01 19:57:22 +00:00
|
|
|
<script setup lang="ts">
|
|
|
|
import SignupForm from '~/components/auth/SignupForm.vue'
|
|
|
|
import { useVModel } from '@vueuse/core'
|
|
|
|
import { computed, ref } from 'vue'
|
|
|
|
import { useGettext } from 'vue3-gettext'
|
|
|
|
import { Form } from '~/types'
|
|
|
|
import { arrayMove } from '~/utils'
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
modelValue: Form
|
|
|
|
signupApprovalEnabled?: boolean
|
|
|
|
}
|
|
|
|
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
|
|
signupApprovalEnabled: false
|
|
|
|
})
|
|
|
|
|
|
|
|
const emit = defineEmits(['update:modelValue'])
|
|
|
|
const value = useVModel(props, 'modelValue', emit, { deep: true })
|
|
|
|
|
|
|
|
const maxFields = ref(10)
|
|
|
|
const isPreviewing = ref(false)
|
|
|
|
|
|
|
|
const { $pgettext } = useGettext()
|
|
|
|
const labels = computed(() => ({
|
|
|
|
delete: $pgettext('*/*/*', 'Delete'),
|
|
|
|
up: $pgettext('*/*/*', 'Move up'),
|
|
|
|
down: $pgettext('*/*/*', 'Move down')
|
|
|
|
}))
|
|
|
|
|
|
|
|
if (!value.value?.fields) {
|
|
|
|
value.value = {
|
|
|
|
help_text: {
|
|
|
|
text: '',
|
|
|
|
content_type: 'text/markdown'
|
|
|
|
},
|
|
|
|
fields: []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const addField = () => {
|
|
|
|
value.value.fields.push({
|
|
|
|
label: $pgettext('*/*/Form-builder', 'Additional field') + ' ' + (value.value.fields.length + 1),
|
|
|
|
required: true,
|
|
|
|
input_type: 'short_text'
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
const remove = (idx: number) => {
|
|
|
|
value.value.fields.splice(idx, 1)
|
|
|
|
}
|
|
|
|
|
|
|
|
const move = (idx: number, increment: number) => {
|
|
|
|
if (idx + increment >= value.value.fields.length) return
|
|
|
|
if (idx === 0 && increment < 0) return
|
|
|
|
arrayMove(value.value.fields, idx, idx + increment)
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
2020-03-18 10:57:33 +00:00
|
|
|
<template>
|
|
|
|
<div>
|
|
|
|
<div class="ui top attached tabular menu">
|
2021-12-06 10:35:20 +00:00
|
|
|
<button
|
|
|
|
:class="[{active: !isPreviewing}, 'item']"
|
|
|
|
@click.stop.prevent="isPreviewing = false"
|
|
|
|
>
|
|
|
|
<translate translate-context="Content/*/Button.Label/Verb">
|
|
|
|
Edit form
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</button>
|
2021-12-06 10:35:20 +00:00
|
|
|
<button
|
|
|
|
:class="[{active: isPreviewing}, 'item']"
|
|
|
|
@click.stop.prevent="isPreviewing = true"
|
|
|
|
>
|
|
|
|
<translate translate-context="*/Form/Menu.item">
|
|
|
|
Preview form
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</button>
|
|
|
|
</div>
|
2021-12-06 10:35:20 +00:00
|
|
|
<div
|
|
|
|
v-if="isPreviewing"
|
|
|
|
class="ui bottom attached segment"
|
|
|
|
>
|
2020-03-18 10:57:33 +00:00
|
|
|
<signup-form
|
2022-05-01 19:57:22 +00:00
|
|
|
:customization="value"
|
2020-03-18 10:57:33 +00:00
|
|
|
:signup-approval-enabled="signupApprovalEnabled"
|
2021-12-06 10:35:20 +00:00
|
|
|
:fetch-description-html="true"
|
|
|
|
/>
|
|
|
|
<div class="ui clearing hidden divider" />
|
2020-03-18 10:57:33 +00:00
|
|
|
</div>
|
2021-12-06 10:35:20 +00:00
|
|
|
<div
|
|
|
|
v-else
|
|
|
|
class="ui bottom attached segment"
|
|
|
|
>
|
2020-03-18 10:57:33 +00:00
|
|
|
<div class="field">
|
|
|
|
<label for="help-text">
|
|
|
|
<translate translate-context="*/*/Label">Help text</translate>
|
|
|
|
</label>
|
|
|
|
<p>
|
2021-12-06 10:35:20 +00:00
|
|
|
<translate translate-context="*/*/Help">
|
|
|
|
An optional text to be displayed at the start of the sign-up form.
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</p>
|
|
|
|
<content-form
|
2022-05-01 19:57:22 +00:00
|
|
|
v-model="value.help_text.text"
|
2020-03-18 10:57:33 +00:00
|
|
|
field-id="help-text"
|
|
|
|
:permissive="true"
|
2021-12-06 10:35:20 +00:00
|
|
|
/>
|
2020-03-18 10:57:33 +00:00
|
|
|
</div>
|
|
|
|
<div class="field">
|
|
|
|
<label>
|
|
|
|
<translate translate-context="*/*/Label">Additional fields</translate>
|
|
|
|
</label>
|
|
|
|
<p>
|
2021-12-06 10:35:20 +00:00
|
|
|
<translate translate-context="*/*/Help">
|
|
|
|
Additional form fields to be displayed in the form. Only shown if manual sign-up validation is enabled.
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</p>
|
2022-05-01 19:57:22 +00:00
|
|
|
<table v-if="value.fields.length > 0">
|
2020-03-18 10:57:33 +00:00
|
|
|
<thead>
|
|
|
|
<tr>
|
|
|
|
<th>
|
2021-12-06 10:35:20 +00:00
|
|
|
<translate translate-context="*/*/Form-builder,Help">
|
|
|
|
Field label
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</th>
|
|
|
|
<th>
|
2021-12-06 10:35:20 +00:00
|
|
|
<translate translate-context="*/*/Form-builder,Help">
|
|
|
|
Field type
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</th>
|
|
|
|
<th>
|
2021-12-06 10:35:20 +00:00
|
|
|
<translate translate-context="*/*/Form-builder,Help">
|
|
|
|
Required
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</th>
|
2020-08-01 09:11:51 +00:00
|
|
|
<th><span class="visually-hidden"><translate translate-context="*/*/Form-builder,Help">Actions</translate></span></th>
|
2020-03-18 10:57:33 +00:00
|
|
|
</tr>
|
|
|
|
</thead>
|
|
|
|
<tbody>
|
2022-05-01 19:57:22 +00:00
|
|
|
<!-- TODO (wvffle): Add random _id as :key -->
|
2021-12-06 10:35:20 +00:00
|
|
|
<tr
|
2022-05-01 19:57:22 +00:00
|
|
|
v-for="(field, idx) in value.fields"
|
2021-12-06 10:35:20 +00:00
|
|
|
:key="idx"
|
|
|
|
>
|
2020-03-18 10:57:33 +00:00
|
|
|
<td>
|
2021-12-06 10:35:20 +00:00
|
|
|
<input
|
|
|
|
v-model="field.label"
|
|
|
|
type="text"
|
|
|
|
required
|
|
|
|
>
|
2020-03-18 10:57:33 +00:00
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
<select v-model="field.input_type">
|
|
|
|
<option value="short_text">
|
2021-12-06 10:35:20 +00:00
|
|
|
<translate translate-context="*/*/Form-builder">
|
|
|
|
Short text
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</option>
|
|
|
|
<option value="long_text">
|
2021-12-06 10:35:20 +00:00
|
|
|
<translate translate-context="*/*/Form-builder">
|
|
|
|
Long text
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
<select v-model="field.required">
|
|
|
|
<option :value="true">
|
2021-12-06 10:35:20 +00:00
|
|
|
<translate translate-context="*/*/*">
|
|
|
|
Yes
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</option>
|
|
|
|
<option :value="false">
|
2021-12-06 10:35:20 +00:00
|
|
|
<translate translate-context="*/*/*">
|
|
|
|
No
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</option>
|
|
|
|
</select>
|
|
|
|
</td>
|
|
|
|
<td>
|
|
|
|
<i
|
2022-05-01 15:36:36 +00:00
|
|
|
:disabled="idx === 0 || null"
|
2021-12-06 10:35:20 +00:00
|
|
|
role="button"
|
2020-03-18 10:57:33 +00:00
|
|
|
:title="labels.up"
|
2022-05-01 19:57:22 +00:00
|
|
|
:class="['up', 'arrow', { disabled: idx === 0 }, 'icon']"
|
2021-12-06 10:35:20 +00:00
|
|
|
@click="move(idx, -1)"
|
|
|
|
/>
|
2020-03-18 10:57:33 +00:00
|
|
|
<i
|
2022-05-01 19:57:22 +00:00
|
|
|
:disabled="idx >= value.fields.length - 1 || null"
|
2021-12-06 10:35:20 +00:00
|
|
|
role="button"
|
2020-08-01 09:11:51 +00:00
|
|
|
:title="labels.down"
|
2022-05-01 19:57:22 +00:00
|
|
|
:class="['down', 'arrow', { disabled: idx >= value.fields.length - 1 }, 'icon']"
|
2021-12-06 10:35:20 +00:00
|
|
|
@click="move(idx, 1)"
|
|
|
|
/>
|
|
|
|
<i
|
|
|
|
role="button"
|
|
|
|
:title="labels.delete"
|
|
|
|
class="x icon"
|
|
|
|
@click="remove(idx)"
|
|
|
|
/>
|
2020-03-18 10:57:33 +00:00
|
|
|
</td>
|
|
|
|
</tr>
|
|
|
|
</tbody>
|
|
|
|
</table>
|
2021-12-06 10:35:20 +00:00
|
|
|
<div class="ui hidden divider" />
|
|
|
|
<button
|
2022-05-01 19:57:22 +00:00
|
|
|
v-if="value.fields.length < maxFields"
|
2021-12-06 10:35:20 +00:00
|
|
|
class="ui basic button"
|
|
|
|
@click.stop.prevent="addField"
|
|
|
|
>
|
|
|
|
<translate translate-context="*/*/Form-builder">
|
|
|
|
Add a new field
|
|
|
|
</translate>
|
2020-03-18 10:57:33 +00:00
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
2021-12-06 10:35:20 +00:00
|
|
|
<div class="ui hidden divider" />
|
2020-03-18 10:57:33 +00:00
|
|
|
</div>
|
|
|
|
</template>
|