Files
docuseal/app/javascript/template_builder/conditions_modal.vue
T

243 lines
7.6 KiB
Vue
Raw Normal View History

2024-03-01 23:29:37 +02:00
<template>
<div
class="modal modal-open items-start !animate-none overflow-y-auto"
>
<div
class="absolute top-0 bottom-0 right-0 left-0"
@click.prevent="$emit('close')"
/>
<div class="modal-box pt-4 pb-6 px-6 mt-20 max-h-none w-full max-w-xl">
<div class="flex justify-between items-center border-b pb-2 mb-2 font-medium">
2025-03-18 17:34:11 +02:00
<span class="modal-title">
2025-08-23 21:46:51 +03:00
{{ t('condition') }} - {{ (defaultField ? (defaultField.title || item.title || item.name) : item.name) || buildDefaultName(item, template.fields) }}
2024-03-01 23:29:37 +02:00
</span>
<a
href="#"
2025-03-18 17:34:11 +02:00
class="text-xl modal-close-button"
2024-03-01 23:29:37 +02:00
@click.prevent="$emit('close')"
>&times;</a>
</div>
<div>
<div
v-if="!withConditions"
class="bg-base-300 rounded-xl py-2 px-3 text-center"
>
<a
2024-10-31 14:25:37 +02:00
href="https://www.docuseal.com/pricing"
2024-03-01 23:29:37 +02:00
target="_blank"
class="link"
2024-09-18 19:47:47 +03:00
>{{ t('available_in_pro') }}</a>
2024-03-01 23:29:37 +02:00
</div>
<form @submit.prevent="validateSaveAndClose">
2024-11-27 21:47:53 +02:00
<div class="my-4">
2024-06-09 16:37:28 +03:00
<div
v-for="(condition, cindex) in conditions"
:key="cindex"
class="space-y-4 relative"
>
2024-11-27 21:47:53 +02:00
<div
v-if="cindex > 0"
class="divider -mb-2 mx-1"
>
<button
class="btn btn-xs btn-primary w-24"
@click.prevent="condition.operation === 'or' ? delete condition.operation : condition.operation = 'or'"
>
{{ condition.operation === 'or' ? t('or') : t('and') }}
</button>
</div>
2024-06-09 16:37:28 +03:00
<div
v-if="conditions.length > 1"
2024-11-27 21:47:53 +02:00
class="flex justify-between mx-1"
2024-06-09 16:37:28 +03:00
>
2025-03-18 17:34:11 +02:00
<label class="text-sm">
2024-06-09 16:37:28 +03:00
{{ t('condition') }} {{ cindex + 1 }}
2025-03-18 17:34:11 +02:00
</label>
2024-06-09 16:37:28 +03:00
<a
href="#"
class="link text-sm"
@click.prevent="conditions.splice(cindex, 1)"
> {{ t('remove') }}</a>
</div>
2024-03-01 23:29:37 +02:00
<select
class="select select-bordered select-sm w-full bg-white h-11 pl-4 text-base font-normal"
2024-10-10 19:49:31 +03:00
:class="{ 'text-gray-300': !condition.field_uuid }"
2024-03-01 23:29:37 +02:00
required
@change="[
2024-06-09 16:37:28 +03:00
condition.field_uuid = $event.target.value,
delete condition.value,
(conditionActions(condition).includes(condition.action) ? '' : condition.action = conditionActions(condition)[0])
2024-03-01 23:29:37 +02:00
]"
>
<option
value=""
disabled
2024-06-09 16:37:28 +03:00
:selected="!condition.field_uuid"
2024-03-01 23:29:37 +02:00
>
{{ t('select_field_') }}
</option>
<option
v-for="f in fields"
:key="f.uuid"
:value="f.uuid"
2024-10-10 19:49:31 +03:00
class="text-base-content"
2024-06-09 16:37:28 +03:00
:selected="condition.field_uuid === f.uuid"
2024-03-01 23:29:37 +02:00
>
{{ f.name || buildDefaultName(f, template.fields) }}
</option>
</select>
<select
2024-06-09 16:37:28 +03:00
v-model="condition.action"
2024-03-01 23:29:37 +02:00
class="select select-bordered select-sm w-full h-11 pl-4 text-base font-normal"
2024-06-09 16:37:28 +03:00
:class="{ 'bg-white': condition.field_uuid, 'bg-base-300': !condition.field_uuid }"
:required="condition.field_uuid"
2024-03-01 23:29:37 +02:00
>
<option
2024-06-09 16:37:28 +03:00
v-for="action in conditionActions(condition)"
2024-03-01 23:29:37 +02:00
:key="action"
:value="action"
>
{{ t(action) }}
</option>
</select>
<select
2024-10-24 12:08:10 +03:00
v-if="['radio', 'select', 'multiple'].includes(conditionField(condition)?.type) && conditionField(condition)?.options"
2024-03-01 23:29:37 +02:00
class="select select-bordered select-sm w-full bg-white h-11 pl-4 text-base font-normal"
2024-10-10 19:49:31 +03:00
:class="{ 'text-gray-300': !condition.value }"
2024-03-01 23:29:37 +02:00
required
2024-06-09 16:37:28 +03:00
@change="condition.value = $event.target.value"
2024-03-01 23:29:37 +02:00
>
<option
value=""
disabled
selected
>
{{ t('select_value_') }}
</option>
<option
2024-06-09 16:37:28 +03:00
v-for="(option, index) in conditionField(condition).options"
2024-03-01 23:29:37 +02:00
:key="option.uuid"
:value="option.uuid"
2024-06-09 16:37:28 +03:00
:selected="condition.value === option.uuid"
2024-10-10 19:49:31 +03:00
class="text-base-content"
2024-03-01 23:29:37 +02:00
>
{{ option.value || `${t('option')} ${index + 1}` }}
</option>
</select>
</div>
</div>
2024-06-09 16:37:28 +03:00
<a
href="#"
class="inline float-right link text-right mb-3 px-2"
@click.prevent="conditions.push({})"
> + {{ t('add_condition') }}</a>
2025-03-18 17:34:11 +02:00
<button class="base-button w-full mt-2 modal-save-button">
2024-03-01 23:29:37 +02:00
{{ t('save') }}
</button>
</form>
<div
2024-12-07 01:35:59 +02:00
v-if="item.conditions?.[0]?.field_uuid"
2024-03-01 23:29:37 +02:00
class="text-center w-full mt-4"
>
<button
class="link"
2024-12-07 01:35:59 +02:00
@click="[conditions = [], delete item.conditions, validateSaveAndClose()]"
2024-03-01 23:29:37 +02:00
>
{{ t('remove_condition') }}
</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'ConditionModal',
inject: ['t', 'save', 'template', 'withConditions'],
props: {
2024-12-07 01:35:59 +02:00
item: {
2024-03-01 23:29:37 +02:00
type: Object,
required: true
},
2025-08-23 21:46:51 +03:00
defaultField: {
type: Object,
required: false,
default: null
},
2024-03-01 23:29:37 +02:00
buildDefaultName: {
type: Function,
required: true
}
},
emits: ['close'],
data () {
return {
2024-12-07 01:35:59 +02:00
conditions: this.item.conditions?.[0] ? JSON.parse(JSON.stringify(this.item.conditions)) : [{}]
2024-03-01 23:29:37 +02:00
}
},
computed: {
2025-09-26 20:52:44 +03:00
excludeTypes () {
return ['heading', 'strikethrough']
},
2024-03-01 23:29:37 +02:00
fields () {
2024-12-07 01:35:59 +02:00
if (this.item.submitter_uuid) {
return this.template.fields.reduce((acc, f) => {
2025-09-26 20:52:44 +03:00
if (f !== this.item && !this.excludeTypes.includes(f.type) && (!f.conditions?.length || !f.conditions.find((c) => c.field_uuid === this.item.uuid))) {
2024-12-07 01:35:59 +02:00
acc.push(f)
}
2024-03-01 23:29:37 +02:00
2024-12-07 01:35:59 +02:00
return acc
}, [])
} else {
return this.template.fields
}
2024-03-01 23:29:37 +02:00
}
},
created () {
2024-12-07 01:35:59 +02:00
this.item.conditions ||= []
2024-03-01 23:29:37 +02:00
},
methods: {
2024-06-09 16:37:28 +03:00
conditionField (condition) {
return this.fields.find((f) => f.uuid === condition.field_uuid)
},
conditionActions (condition) {
return this.fieldActions(this.conditionField(condition))
},
2024-03-01 23:29:37 +02:00
fieldActions (field) {
const actions = []
if (!field) {
return actions
}
if (field.type === 'checkbox') {
actions.push('checked', 'unchecked')
} else if (['radio', 'select'].includes(field.type)) {
actions.push('equal', 'not_equal')
} else if (['multiple'].includes(field.type)) {
actions.push('contains', 'does_not_contain')
} else {
actions.push('not_empty', 'empty')
}
return actions
},
validateSaveAndClose () {
if (!this.withConditions) {
2024-09-23 15:22:07 +03:00
return alert(this.t('available_only_in_pro'))
2024-03-01 23:29:37 +02:00
}
2024-06-09 16:37:28 +03:00
if (this.conditions.find((f) => f.field_uuid)) {
2024-12-07 01:35:59 +02:00
this.item.conditions = this.conditions
2024-03-01 23:29:37 +02:00
} else {
2024-12-07 01:35:59 +02:00
delete this.item.conditions
2024-03-01 23:29:37 +02:00
}
this.save()
this.$emit('close')
}
}
}
</script>