0351d front end linting (#377)
* feat: disable custom script for trial users * after lint fix * frontend linting --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
@@ -1,47 +1,64 @@
|
||||
<template>
|
||||
<div v-if="content" class="flex flex-wrap">
|
||||
<div
|
||||
v-if="content"
|
||||
class="flex flex-wrap"
|
||||
>
|
||||
<div class="w-full font-semibold text-gray-700 dark:text-gray-300 mb-2">
|
||||
{{ property.name }}
|
||||
</div>
|
||||
<SelectInput v-model="content.operator" class="w-full" :options="operators" :name="'operator_' + property.id"
|
||||
placeholder="Comparison operator" @update:model-value="operatorChanged()" />
|
||||
<SelectInput
|
||||
v-model="content.operator"
|
||||
class="w-full"
|
||||
:options="operators"
|
||||
:name="'operator_' + property.id"
|
||||
placeholder="Comparison operator"
|
||||
@update:model-value="operatorChanged()"
|
||||
/>
|
||||
|
||||
<template v-if="needsInput">
|
||||
<component v-bind="inputComponentData" :is="inputComponentData.component" v-model="content.value" class="w-full"
|
||||
:name="'value_' + property.id" placeholder="Filter Value" @update:model-value="emitInput()" />
|
||||
<component
|
||||
v-bind="inputComponentData"
|
||||
:is="inputComponentData.component"
|
||||
v-model="content.value"
|
||||
class="w-full"
|
||||
:name="'value_' + property.id"
|
||||
placeholder="Filter Value"
|
||||
@update:model-value="emitInput()"
|
||||
/>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import OpenFilters from '../../../../../data/open_filters.json'
|
||||
import OpenFilters from "../../../../../data/open_filters.json"
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
props: {
|
||||
modelValue: { required: true }
|
||||
modelValue: { type: Object, required: true },
|
||||
},
|
||||
|
||||
emits: ['update:modelValue'],
|
||||
data() {
|
||||
return {
|
||||
content: { ...this.modelValue },
|
||||
available_filters: OpenFilters,
|
||||
hasInput: false,
|
||||
inputComponent: {
|
||||
text: 'TextInput',
|
||||
number: 'TextInput',
|
||||
rating: 'TextInput',
|
||||
scale: 'TextInput',
|
||||
slider: 'TextInput',
|
||||
select: 'SelectInput',
|
||||
multi_select: 'SelectInput',
|
||||
date: 'DateInput',
|
||||
files: 'FileInput',
|
||||
checkbox: 'CheckboxInput',
|
||||
url: 'TextInput',
|
||||
email: 'TextInput',
|
||||
phone_number: 'TextInput'
|
||||
}
|
||||
text: "TextInput",
|
||||
number: "TextInput",
|
||||
rating: "TextInput",
|
||||
scale: "TextInput",
|
||||
slider: "TextInput",
|
||||
select: "SelectInput",
|
||||
multi_select: "SelectInput",
|
||||
date: "DateInput",
|
||||
files: "FileInput",
|
||||
checkbox: "CheckboxInput",
|
||||
url: "TextInput",
|
||||
email: "TextInput",
|
||||
phone_number: "TextInput",
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
@@ -51,34 +68,41 @@ export default {
|
||||
const componentData = {
|
||||
component: this.inputComponent[this.property.type],
|
||||
name: this.property.id,
|
||||
required: true
|
||||
required: true,
|
||||
}
|
||||
|
||||
if (this.property.type === 'phone_number' && !this.property.use_simple_text_input) {
|
||||
componentData.component = 'PhoneInput'
|
||||
if (
|
||||
this.property.type === "phone_number" &&
|
||||
!this.property.use_simple_text_input
|
||||
) {
|
||||
componentData.component = "PhoneInput"
|
||||
}
|
||||
|
||||
if (['select', 'multi_select'].includes(this.property.type)) {
|
||||
if (["select", "multi_select"].includes(this.property.type)) {
|
||||
componentData.multiple = false
|
||||
componentData.options = this.property[this.property.type].options.map(option => {
|
||||
return {
|
||||
name: option.name,
|
||||
value: option.name
|
||||
}
|
||||
})
|
||||
} else if (this.property.type === 'date') {
|
||||
componentData.options = this.property[this.property.type].options.map(
|
||||
(option) => {
|
||||
return {
|
||||
name: option.name,
|
||||
value: option.name,
|
||||
}
|
||||
},
|
||||
)
|
||||
} else if (this.property.type === "date") {
|
||||
// componentData.withTime = true
|
||||
} else if (this.property.type === 'checkbox') {
|
||||
} else if (this.property.type === "checkbox") {
|
||||
componentData.label = this.property.name
|
||||
}
|
||||
|
||||
return componentData
|
||||
},
|
||||
operators() {
|
||||
return Object.keys(this.available_filters[this.property.type].comparators).map(key => {
|
||||
return Object.keys(
|
||||
this.available_filters[this.property.type].comparators,
|
||||
).map((key) => {
|
||||
return {
|
||||
value: key,
|
||||
name: this.optionFilterNames(key, this.property.type)
|
||||
name: this.optionFilterNames(key, this.property.type),
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -90,9 +114,17 @@ export default {
|
||||
const operatorFormat = operator.format
|
||||
if (!operatorFormat) return true
|
||||
|
||||
if (operator.expected_type === 'boolean' && operatorFormat.type === 'enum' && operatorFormat.values.length === 1) {
|
||||
if (
|
||||
operator.expected_type === "boolean" &&
|
||||
operatorFormat.type === "enum" &&
|
||||
operatorFormat.values.length === 1
|
||||
) {
|
||||
return false
|
||||
} else if (operator.expected_type === 'object' && operatorFormat.type === 'empty' && operatorFormat.values === '{}') {
|
||||
} else if (
|
||||
operator.expected_type === "object" &&
|
||||
operatorFormat.type === "empty" &&
|
||||
operatorFormat.values === "{}"
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -104,21 +136,28 @@ export default {
|
||||
modelValue() {
|
||||
this.refreshContent()
|
||||
},
|
||||
'content.operator': function (val) {
|
||||
"content.operator": function (val) {
|
||||
if (val) {
|
||||
this.operatorChanged()
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.refreshContent()
|
||||
},
|
||||
|
||||
methods: {
|
||||
castContent(content) {
|
||||
if (['number', 'rating', 'scale', 'slider'].includes(this.property.type) && content.value) {
|
||||
if (
|
||||
["number", "rating", "scale", "slider"].includes(this.property.type) &&
|
||||
content.value
|
||||
) {
|
||||
content.value = Number(content.value)
|
||||
}
|
||||
|
||||
const operator = this.selectedOperator()
|
||||
if (operator.expected_type === 'boolean') {
|
||||
if (operator.expected_type === "boolean") {
|
||||
content.value = Boolean(content.value)
|
||||
}
|
||||
|
||||
@@ -132,11 +171,22 @@ export default {
|
||||
const operator = this.selectedOperator()
|
||||
const operatorFormat = operator.format
|
||||
|
||||
if (operator.expected_type === 'boolean' && operatorFormat.type === 'enum' && operatorFormat.values.length === 1) {
|
||||
if (
|
||||
operator.expected_type === "boolean" &&
|
||||
operatorFormat.type === "enum" &&
|
||||
operatorFormat.values.length === 1
|
||||
) {
|
||||
this.content.value = operator.format.values[0]
|
||||
} else if (operator.expected_type === 'object' && operatorFormat.type === 'empty' && operatorFormat.values === '{}') {
|
||||
} else if (
|
||||
operator.expected_type === "object" &&
|
||||
operatorFormat.type === "empty" &&
|
||||
operatorFormat.values === "{}"
|
||||
) {
|
||||
this.content.value = {}
|
||||
} else if (typeof this.content.value === 'boolean' || typeof this.content.value === 'object') {
|
||||
} else if (
|
||||
typeof this.content.value === "boolean" ||
|
||||
typeof this.content.value === "object"
|
||||
) {
|
||||
this.content.value = null
|
||||
}
|
||||
this.emitInput()
|
||||
@@ -145,21 +195,26 @@ export default {
|
||||
if (!this.content.operator) {
|
||||
return null
|
||||
}
|
||||
return this.available_filters[this.property.type].comparators[this.content.operator]
|
||||
return this.available_filters[this.property.type].comparators[
|
||||
this.content.operator
|
||||
]
|
||||
},
|
||||
optionFilterNames(key, propertyType) {
|
||||
if (propertyType === 'checkbox') {
|
||||
if (propertyType === "checkbox") {
|
||||
return {
|
||||
equals: 'Is checked',
|
||||
does_not_equal: 'Is not checked'
|
||||
equals: "Is checked",
|
||||
does_not_equal: "Is not checked",
|
||||
}[key]
|
||||
}
|
||||
return key.split('_').map(function (item) {
|
||||
return item.charAt(0).toUpperCase() + item.substring(1)
|
||||
}).join(' ')
|
||||
return key
|
||||
.split("_")
|
||||
.map(function (item) {
|
||||
return item.charAt(0).toUpperCase() + item.substring(1)
|
||||
})
|
||||
.join(" ")
|
||||
},
|
||||
emitInput() {
|
||||
this.$emit('update:modelValue', this.castContent(this.content))
|
||||
this.$emit("update:modelValue", this.castContent(this.content))
|
||||
},
|
||||
refreshContent() {
|
||||
this.content = {
|
||||
@@ -167,14 +222,10 @@ export default {
|
||||
...this.modelValue,
|
||||
property_meta: {
|
||||
id: this.property.id,
|
||||
type: this.property.type
|
||||
}
|
||||
type: this.property.type,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.refreshContent()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
<template>
|
||||
<query-builder v-model="query" :rules="rules" :config="config" @update:model-value="onChange">
|
||||
<query-builder
|
||||
v-model="query"
|
||||
:rules="rules"
|
||||
:config="config"
|
||||
@update:model-value="onChange"
|
||||
>
|
||||
<template #groupOperator="props">
|
||||
<div class="query-builder-group-slot__group-selection flex items-center px-5 border-b py-1 mb-1 flex">
|
||||
<div
|
||||
class="query-builder-group-slot__group-selection flex items-center px-5 border-b py-1 mb-1 flex"
|
||||
>
|
||||
<p class="mr-2 font-semibold">
|
||||
Operator
|
||||
</p>
|
||||
@@ -30,91 +37,100 @@
|
||||
</query-builder>
|
||||
</template>
|
||||
|
||||
<style src="query-builder-vue-3/dist/style.css" />
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import QueryBuilder from 'query-builder-vue-3'
|
||||
import ColumnCondition from './ColumnCondition.vue'
|
||||
import GroupControlSlot from './GroupControlSlot.vue'
|
||||
/* eslint-disable vue/one-component-per-file */
|
||||
import { defineComponent } from "vue"
|
||||
import QueryBuilder from "query-builder-vue-3"
|
||||
import ColumnCondition from "./ColumnCondition.vue"
|
||||
import GroupControlSlot from "./GroupControlSlot.vue"
|
||||
|
||||
export default {
|
||||
|
||||
components: {
|
||||
GroupControlSlot,
|
||||
QueryBuilder,
|
||||
ColumnCondition
|
||||
ColumnCondition,
|
||||
},
|
||||
|
||||
props: {
|
||||
form: { type: Object, required: true },
|
||||
modelValue: { required: false }
|
||||
modelValue: { type: Object, required: false },
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
query: this.modelValue
|
||||
query: this.modelValue,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
rules () {
|
||||
return this.form.properties.filter((property) => {
|
||||
return !property.type.startsWith('nf-')
|
||||
}).map((property) => {
|
||||
const workspaceId = this.form.workspace_id
|
||||
const formSlug = this.form.slug
|
||||
return {
|
||||
identifier: property.id,
|
||||
name: property.name,
|
||||
component: (function () {
|
||||
return defineComponent({
|
||||
extends: ColumnCondition,
|
||||
computed: {
|
||||
property () {
|
||||
return property
|
||||
rules() {
|
||||
return this.form.properties
|
||||
.filter((property) => {
|
||||
return !property.type.startsWith("nf-")
|
||||
})
|
||||
.map((property) => {
|
||||
const workspaceId = this.form.workspace_id
|
||||
const formSlug = this.form.slug
|
||||
return {
|
||||
identifier: property.id,
|
||||
name: property.name,
|
||||
component: (function () {
|
||||
return defineComponent({
|
||||
extends: ColumnCondition,
|
||||
computed: {
|
||||
property() {
|
||||
return property
|
||||
},
|
||||
viewContext() {
|
||||
return {
|
||||
form_slug: formSlug,
|
||||
workspace_id: workspaceId,
|
||||
}
|
||||
},
|
||||
},
|
||||
viewContext () {
|
||||
return {
|
||||
form_slug: formSlug,
|
||||
workspace_id: workspaceId
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})()
|
||||
}
|
||||
})
|
||||
})
|
||||
})(),
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
config () {
|
||||
config() {
|
||||
return {
|
||||
operators: [
|
||||
{
|
||||
name: 'And',
|
||||
identifier: 'and'
|
||||
name: "And",
|
||||
identifier: "and",
|
||||
},
|
||||
{
|
||||
name: 'Or',
|
||||
identifier: 'or'
|
||||
}
|
||||
name: "Or",
|
||||
identifier: "or",
|
||||
},
|
||||
],
|
||||
rules: this.rules,
|
||||
colors: ['#ef4444', '#22c55e', '#f97316', '#0ea5e9', '#8b5cf6', '#ec4899']
|
||||
colors: [
|
||||
"#ef4444",
|
||||
"#22c55e",
|
||||
"#f97316",
|
||||
"#0ea5e9",
|
||||
"#8b5cf6",
|
||||
"#ec4899",
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
modelValue () {
|
||||
modelValue() {
|
||||
this.query = this.modelValue
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange () {
|
||||
this.$emit('update:modelValue', this.query)
|
||||
}
|
||||
}
|
||||
onChange() {
|
||||
this.$emit("update:modelValue", this.query)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style src="query-builder-vue-3/dist/style.css" />
|
||||
|
||||
@@ -1,24 +1,60 @@
|
||||
<template>
|
||||
<div v-if="logic" :key="resetKey">
|
||||
<div
|
||||
v-if="logic"
|
||||
:key="resetKey"
|
||||
>
|
||||
<h3 class="font-semibold block text-lg">
|
||||
Logic
|
||||
</h3>
|
||||
<p class="text-gray-400 text-xs mb-3">
|
||||
Add some logic to this block. Start by adding some conditions, and then add some actions.
|
||||
Add some logic to this block. Start by adding some conditions, and then
|
||||
add some actions.
|
||||
</p>
|
||||
<div class="relative flex">
|
||||
<div>
|
||||
<v-button color="light-gray" size="small" @click="showCopyFormModal=true">
|
||||
<svg class="h-4 w-4 text-blue-600 inline mr-1 -mt-1" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5 15H4C3.46957 15 2.96086 14.7893 2.58579 14.4142C2.21071 14.0391 2 13.5304 2 13V4C2 3.46957 2.21071 2.96086 2.58579 2.58579C2.96086 2.21071 3.46957 2 4 2H13C13.5304 2 14.0391 2.21071 14.4142 2.58579C14.7893 2.96086 15 3.46957 15 4V5M11 9H20C21.1046 9 22 9.89543 22 11V20C22 21.1046 21.1046 22 20 22H11C9.89543 22 9 21.1046 9 20V11C9 9.89543 9.89543 9 11 9Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<v-button
|
||||
color="light-gray"
|
||||
size="small"
|
||||
@click="showCopyFormModal = true"
|
||||
>
|
||||
<svg
|
||||
class="h-4 w-4 text-blue-600 inline mr-1 -mt-1"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M5 15H4C3.46957 15 2.96086 14.7893 2.58579 14.4142C2.21071 14.0391 2 13.5304 2 13V4C2 3.46957 2.21071 2.96086 2.58579 2.58579C2.96086 2.21071 3.46957 2 4 2H13C13.5304 2 14.0391 2.21071 14.4142 2.58579C14.7893 2.96086 15 3.46957 15 4V5M11 9H20C21.1046 9 22 9.89543 22 11V20C22 21.1046 21.1046 22 20 22H11C9.89543 22 9 21.1046 9 20V11C9 9.89543 9.89543 9 11 9Z"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
Copy from
|
||||
</v-button>
|
||||
</div>
|
||||
<div>
|
||||
<v-button color="light-gray" shade="light" size="small" class="ml-1" @click="clearAll">
|
||||
<svg class="text-red-600 h-4 w-4 inline -mt-1 mr-1" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 9L12 15M12 9L18 15M21 4H8L1 12L8 20H21C21.5304 20 22.0391 19.7893 22.4142 19.4142C22.7893 19.0391 23 18.5304 23 18V6C23 5.46957 22.7893 4.96086 22.4142 4.58579C22.0391 4.21071 21.5304 4 21 4Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<v-button
|
||||
color="light-gray"
|
||||
shade="light"
|
||||
size="small"
|
||||
class="ml-1"
|
||||
@click="clearAll"
|
||||
>
|
||||
<svg
|
||||
class="text-red-600 h-4 w-4 inline -mt-1 mr-1"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M18 9L12 15M12 9L18 15M21 4H8L1 12L8 20H21C21.5304 20 22.0391 19.7893 22.4142 19.4142C22.7893 19.0391 23 18.5304 23 18V6C23 5.46957 22.7893 4.96086 22.4142 4.58579C22.0391 4.21071 21.5304 4 21 4Z"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
Clear All
|
||||
@@ -29,35 +65,64 @@
|
||||
<h5 class="font-semibold mt-3">
|
||||
1. Conditions
|
||||
</h5>
|
||||
<condition-editor ref="filter-editor" v-model="logic.conditions" class="mt-1 border-t border rounded-md" :form="form" />
|
||||
<condition-editor
|
||||
ref="filter-editor"
|
||||
v-model="logic.conditions"
|
||||
class="mt-1 border-t border rounded-md"
|
||||
:form="form"
|
||||
/>
|
||||
|
||||
<h5 class="font-semibold mt-3">
|
||||
2. Actions
|
||||
</h5>
|
||||
<select-input :key="resetKey" v-model="logic.actions" name="actions"
|
||||
:multiple="true" class="mt-1" placeholder="Actions..."
|
||||
help="Action(s) triggered when above conditions are true"
|
||||
:options="actionOptions"
|
||||
@update:model-value="onActionInput"
|
||||
<select-input
|
||||
:key="resetKey"
|
||||
v-model="logic.actions"
|
||||
name="actions"
|
||||
:multiple="true"
|
||||
class="mt-1"
|
||||
placeholder="Actions..."
|
||||
help="Action(s) triggered when above conditions are true"
|
||||
:options="actionOptions"
|
||||
@update:model-value="onActionInput"
|
||||
/>
|
||||
|
||||
<modal :show="showCopyFormModal" @close="showCopyFormModal = false">
|
||||
<modal
|
||||
:show="showCopyFormModal"
|
||||
@close="showCopyFormModal = false"
|
||||
>
|
||||
<div class="min-h-[450px]">
|
||||
<h3 class="font-semibold block text-lg">
|
||||
Copy logic from another field
|
||||
</h3>
|
||||
<p class="text-gray-400 text-xs mb-5">
|
||||
Select another field/block to copy its logic and apply it to "{{ field.name }}".
|
||||
Select another field/block to copy its logic and apply it to "{{
|
||||
field.name
|
||||
}}".
|
||||
</p>
|
||||
<select-input v-model="copyFrom" name="copy_from" emit-key="value"
|
||||
label="Copy logic from" placeholder="Choose a field/block..."
|
||||
:options="copyFromOptions" :searchable="copyFromOptions && copyFromOptions.options > 5"
|
||||
<select-input
|
||||
v-model="copyFrom"
|
||||
name="copy_from"
|
||||
emit-key="value"
|
||||
label="Copy logic from"
|
||||
placeholder="Choose a field/block..."
|
||||
:options="copyFromOptions"
|
||||
:searchable="copyFromOptions && copyFromOptions.options > 5"
|
||||
/>
|
||||
<div class="flex justify-between mb-6">
|
||||
<v-button color="blue" shade="light" @click="copyLogic">
|
||||
<v-button
|
||||
color="blue"
|
||||
shade="light"
|
||||
@click="copyLogic"
|
||||
>
|
||||
Confirm & Copy
|
||||
</v-button>
|
||||
<v-button color="gray" shade="light" class="ml-1" @click="showCopyFormModal=false">
|
||||
<v-button
|
||||
color="gray"
|
||||
shade="light"
|
||||
class="ml-1"
|
||||
@click="showCopyFormModal = false"
|
||||
>
|
||||
Close
|
||||
</v-button>
|
||||
</div>
|
||||
@@ -67,136 +132,161 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ConditionEditor from './ConditionEditor.client.vue'
|
||||
import Modal from '../../../../global/Modal.vue'
|
||||
import clonedeep from 'clone-deep'
|
||||
import { default as _has } from 'lodash/has'
|
||||
import ConditionEditor from "./ConditionEditor.client.vue"
|
||||
import Modal from "../../../../global/Modal.vue"
|
||||
import clonedeep from "clone-deep"
|
||||
import { default as _has } from "lodash/has"
|
||||
|
||||
export default {
|
||||
name: 'FormBlockLogicEditor',
|
||||
name: "FormBlockLogicEditor",
|
||||
components: { Modal, ConditionEditor },
|
||||
props: {
|
||||
field: {
|
||||
type: Object,
|
||||
required: false
|
||||
required: false,
|
||||
},
|
||||
form: {
|
||||
type: Object,
|
||||
required: false
|
||||
}
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
resetKey: 0,
|
||||
logic: this.field.logic || {
|
||||
conditions: null,
|
||||
actions: []
|
||||
actions: [],
|
||||
},
|
||||
showCopyFormModal: false,
|
||||
copyFrom: null
|
||||
copyFrom: null,
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
copyFromOptions () {
|
||||
return this.form.properties.filter((field) => {
|
||||
return field.id !== this.field.id && _has(field, 'logic') && field.logic !== null && field.logic !== {}
|
||||
}).map((field) => {
|
||||
return { name: field.name, value: field.id }
|
||||
})
|
||||
copyFromOptions() {
|
||||
return this.form.properties
|
||||
.filter((field) => {
|
||||
return (
|
||||
field.id !== this.field.id &&
|
||||
_has(field, "logic") &&
|
||||
field.logic !== null &&
|
||||
field.logic !== {}
|
||||
)
|
||||
})
|
||||
.map((field) => {
|
||||
return { name: field.name, value: field.id }
|
||||
})
|
||||
},
|
||||
actionOptions () {
|
||||
if (['nf-text', 'nf-code', 'nf-page-break', 'nf-divider', 'nf-image'].includes(this.field.type)) {
|
||||
actionOptions() {
|
||||
if (
|
||||
[
|
||||
"nf-text",
|
||||
"nf-code",
|
||||
"nf-page-break",
|
||||
"nf-divider",
|
||||
"nf-image",
|
||||
].includes(this.field.type)
|
||||
) {
|
||||
if (this.field.hidden) {
|
||||
return [{ name: 'Show Block', value: 'show-block' }]
|
||||
return [{ name: "Show Block", value: "show-block" }]
|
||||
} else {
|
||||
return [{ name: 'Hide Block', value: 'hide-block' }]
|
||||
return [{ name: "Hide Block", value: "hide-block" }]
|
||||
}
|
||||
}
|
||||
|
||||
if (this.field.hidden) {
|
||||
return [
|
||||
{ name: 'Show Block', value: 'show-block' },
|
||||
{ name: 'Require answer', value: 'require-answer' }
|
||||
{ name: "Show Block", value: "show-block" },
|
||||
{ name: "Require answer", value: "require-answer" },
|
||||
]
|
||||
} else if (this.field.disabled) {
|
||||
return [
|
||||
{ name: 'Enable Block', value: 'enable-block' },
|
||||
(this.field.required
|
||||
? { name: 'Make it optional', value: 'make-it-optional' }
|
||||
{ name: "Enable Block", value: "enable-block" },
|
||||
this.field.required
|
||||
? { name: "Make it optional", value: "make-it-optional" }
|
||||
: {
|
||||
name: 'Require answer',
|
||||
value: 'require-answer'
|
||||
})
|
||||
name: "Require answer",
|
||||
value: "require-answer",
|
||||
},
|
||||
]
|
||||
} else {
|
||||
return [
|
||||
{ name: 'Hide Block', value: 'hide-block' },
|
||||
{ name: 'Disable Block', value: 'disable-block' },
|
||||
(this.field.required
|
||||
? { name: 'Make it optional', value: 'make-it-optional' }
|
||||
{ name: "Hide Block", value: "hide-block" },
|
||||
{ name: "Disable Block", value: "disable-block" },
|
||||
this.field.required
|
||||
? { name: "Make it optional", value: "make-it-optional" }
|
||||
: {
|
||||
name: 'Require answer',
|
||||
value: 'require-answer'
|
||||
})
|
||||
name: "Require answer",
|
||||
value: "require-answer",
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
logic: {
|
||||
handler () {
|
||||
handler() {
|
||||
this.field.logic = this.logic
|
||||
},
|
||||
deep: true
|
||||
deep: true,
|
||||
},
|
||||
'field.id': {
|
||||
handler (field, oldField) {
|
||||
"field.id": {
|
||||
handler() {
|
||||
// On field change, reset logic
|
||||
this.logic = this.field.logic || {
|
||||
conditions: null,
|
||||
actions: []
|
||||
actions: [],
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
'field.required': 'cleanConditions',
|
||||
'field.disabled': 'cleanConditions',
|
||||
'field.hidden': 'cleanConditions'
|
||||
"field.required": "cleanConditions",
|
||||
"field.disabled": "cleanConditions",
|
||||
"field.hidden": "cleanConditions",
|
||||
},
|
||||
|
||||
mounted () {
|
||||
if (!_has(this.field, 'logic')) {
|
||||
mounted() {
|
||||
if (!_has(this.field, "logic")) {
|
||||
this.field.logic = this.logic
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
clearAll () {
|
||||
clearAll() {
|
||||
this.logic.conditions = null
|
||||
this.logic.actions = []
|
||||
this.refreshActions()
|
||||
},
|
||||
onActionInput () {
|
||||
onActionInput() {
|
||||
if (this.logic.actions.length >= 2) {
|
||||
if (this.logic.actions[1] === 'require-answer' && this.logic.actions[0] === 'hide-block') {
|
||||
this.logic.actions = ['require-answer']
|
||||
} else if (this.logic.actions[1] === 'hide-block' && this.logic.actions[0] === 'require-answer') {
|
||||
this.logic.actions = ['hide-block']
|
||||
if (
|
||||
this.logic.actions[1] === "require-answer" &&
|
||||
this.logic.actions[0] === "hide-block"
|
||||
) {
|
||||
this.logic.actions = ["require-answer"]
|
||||
} else if (
|
||||
this.logic.actions[1] === "hide-block" &&
|
||||
this.logic.actions[0] === "require-answer"
|
||||
) {
|
||||
this.logic.actions = ["hide-block"]
|
||||
}
|
||||
this.refreshActions()
|
||||
}
|
||||
},
|
||||
cleanConditions () {
|
||||
const availableActions = this.actionOptions.map(function (op) { return op.value })
|
||||
this.logic.actions = availableActions.filter(value => this.logic.actions.includes(value))
|
||||
cleanConditions() {
|
||||
const availableActions = this.actionOptions.map(function (op) {
|
||||
return op.value
|
||||
})
|
||||
this.logic.actions = availableActions.filter((value) =>
|
||||
this.logic.actions.includes(value),
|
||||
)
|
||||
this.refreshActions()
|
||||
},
|
||||
refreshActions () {
|
||||
refreshActions() {
|
||||
this.resetKey++
|
||||
},
|
||||
copyLogic () {
|
||||
copyLogic() {
|
||||
if (this.copyFrom) {
|
||||
const property = this.form.properties.find((property) => {
|
||||
return property.id === this.copyFrom
|
||||
@@ -207,7 +297,7 @@ export default {
|
||||
}
|
||||
}
|
||||
this.showCopyFormModal = false
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
<template>
|
||||
<div class="flex flex-wrap px-4 py-1 -ml-1 -mt-1">
|
||||
<select-input ref="ruleSelect" v-model="selectedRule" class="flex-grow ml-1 mr-1 mt-1"
|
||||
wrapper-class="relative" placeholder="Add condition on input field"
|
||||
:options="groupCtrl.rules" margin-bottom="" :searchable="groupCtrl.rules.length > 5"
|
||||
emit-key="identifier"
|
||||
option-key="identifier"
|
||||
name="group-control-slot-rule"
|
||||
<select-input
|
||||
ref="ruleSelect"
|
||||
v-model="selectedRule"
|
||||
class="flex-grow ml-1 mr-1 mt-1"
|
||||
wrapper-class="relative"
|
||||
placeholder="Add condition on input field"
|
||||
:options="groupCtrl.rules"
|
||||
margin-bottom=""
|
||||
:searchable="groupCtrl.rules.length > 5"
|
||||
emit-key="identifier"
|
||||
option-key="identifier"
|
||||
name="group-control-slot-rule"
|
||||
/>
|
||||
<v-button class="ml-1 mt-1" color="blue" size="small" :disabled="(selectedRule === '')?true:null" @click="addRule">
|
||||
<v-button
|
||||
class="ml-1 mt-1"
|
||||
color="blue"
|
||||
size="small"
|
||||
:disabled="selectedRule === '' ? true : null"
|
||||
@click="addRule"
|
||||
>
|
||||
Add Condition
|
||||
</v-button>
|
||||
<v-button class="ml-1 mt-1" color="outline-blue" size="small" @click="groupCtrl.newGroup">
|
||||
<v-button
|
||||
class="ml-1 mt-1"
|
||||
color="outline-blue"
|
||||
size="small"
|
||||
@click="groupCtrl.newGroup"
|
||||
>
|
||||
Add Group
|
||||
</v-button>
|
||||
</div>
|
||||
@@ -20,20 +37,19 @@
|
||||
export default {
|
||||
components: {},
|
||||
props: { groupCtrl: { type: Object, required: true } },
|
||||
data () {
|
||||
data() {
|
||||
return {
|
||||
selectedRule: null
|
||||
selectedRule: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addRule () {
|
||||
addRule() {
|
||||
if (this.selectedRule) {
|
||||
this.groupCtrl.addRule(this.selectedRule)
|
||||
this.$refs.ruleSelect.content = null
|
||||
this.selectedRule = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user