mirror of
https://github.com/directus/directus.git
synced 2026-02-04 08:05:35 -05:00
Add support for Conditional Fields (#6864)
* Add conditions field to directus_fields * Add conditions configuration * Apply conditional overrides * Handle conditions in nested groups * Fix reverse mutating conditions * Start on filter setup interface * Move field types/constants to shared * [WIP] Updated client side filter validation * Support logical operators in client validation step * Use new validation util in conditions check * Add nesting in filter seutp * Add filter rule setup configurator * Fixes that should've been done in the merge * Strip out filter-settings interface TBD in a new PR * Move browser to index
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { defineModule } from '@directus/shared/utils/browser';
|
||||
import { defineModule } from '@directus/shared/utils';
|
||||
import ActivityCollection from './routes/collection.vue';
|
||||
import ActivityItem from './routes/item.vue';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineModule } from '@directus/shared/utils/browser';
|
||||
import { defineModule } from '@directus/shared/utils';
|
||||
import { addQueryToPath } from '@/utils/add-query-to-path';
|
||||
import RouterPass from '@/utils/router-passthrough';
|
||||
import { NavigationGuard } from 'vue-router';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineModule } from '@directus/shared/utils/browser';
|
||||
import { defineModule } from '@directus/shared/utils';
|
||||
import docs, { DocsRoutes } from '@directus/docs';
|
||||
import { RouteRecordRaw } from 'vue-router';
|
||||
import NotFound from './routes/not-found.vue';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineModule } from '@directus/shared/utils/browser';
|
||||
import { defineModule } from '@directus/shared/utils';
|
||||
import AddNew from './routes/add-new.vue';
|
||||
import Collection from './routes/collection.vue';
|
||||
import Item from './routes/item.vue';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import api from '@/api';
|
||||
import { useCollection } from '@/composables/use-collection';
|
||||
import { defineModule } from '@directus/shared/utils/browser';
|
||||
import { defineModule } from '@directus/shared/utils';
|
||||
import { useCollectionsStore, useFieldsStore } from '@/stores';
|
||||
import RouterPass from '@/utils/router-passthrough';
|
||||
import { ref } from 'vue';
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<div>
|
||||
<interface-list :fields="repeaterFields" template="{{ name }}" :value="value" @input="value = $event" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, computed } from 'vue';
|
||||
import { Field, Condition, DeepPartial } from '@directus/shared/types';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { state } from '../store';
|
||||
import { get, set } from 'lodash';
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
collection: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
|
||||
const value = computed({
|
||||
get() {
|
||||
return get(state, 'fieldData.meta.conditions', []);
|
||||
},
|
||||
set(value: Condition[]) {
|
||||
set(state, 'fieldData.meta.conditions', value);
|
||||
},
|
||||
});
|
||||
|
||||
const repeaterFields = computed<DeepPartial<Field>[]>(() => [
|
||||
{
|
||||
field: 'name',
|
||||
name: t('name'),
|
||||
type: 'string',
|
||||
meta: {
|
||||
interface: 'input',
|
||||
options: {
|
||||
iconLeft: 'label',
|
||||
placeholder: t('enter_a_value'),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'rule',
|
||||
name: t('rule'),
|
||||
type: 'json',
|
||||
meta: {
|
||||
interface: 'input-code',
|
||||
options: {
|
||||
language: 'json',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'readonly',
|
||||
name: t('readonly'),
|
||||
type: 'boolean',
|
||||
meta: {
|
||||
interface: 'boolean',
|
||||
options: {
|
||||
label: t('disabled_editing_value'),
|
||||
},
|
||||
width: 'half',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'hidden',
|
||||
name: t('hidden'),
|
||||
type: 'boolean',
|
||||
meta: {
|
||||
interface: 'boolean',
|
||||
options: {
|
||||
label: t('hidden_on_detail'),
|
||||
},
|
||||
width: 'half',
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'options',
|
||||
name: t('interface_options'),
|
||||
type: 'json',
|
||||
meta: {
|
||||
interface: 'system-interface-options',
|
||||
options: {
|
||||
interface: state?.fieldData.meta?.interface,
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
return { repeaterFields, value, state };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@@ -83,6 +83,8 @@
|
||||
:collection="collection"
|
||||
:type="localType"
|
||||
/>
|
||||
|
||||
<setup-conditions v-if="currentTab[0] === 'conditions'" :collection="collection" :type="localType" />
|
||||
</div>
|
||||
|
||||
<template #actions>
|
||||
@@ -125,6 +127,7 @@ import SetupRelationship from './components/relationship.vue';
|
||||
import SetupTranslations from './components/translations.vue';
|
||||
import SetupInterface from './components/interface.vue';
|
||||
import SetupDisplay from './components/display.vue';
|
||||
import SetupConditions from './components/conditions.vue';
|
||||
import { isEmpty, cloneDeep } from 'lodash';
|
||||
import api from '@/api';
|
||||
import { useFieldsStore, useRelationsStore, useCollectionsStore } from '@/stores/';
|
||||
@@ -149,6 +152,7 @@ export default defineComponent({
|
||||
SetupTranslations,
|
||||
SetupInterface,
|
||||
SetupDisplay,
|
||||
SetupConditions,
|
||||
},
|
||||
props: {
|
||||
collection: {
|
||||
@@ -284,6 +288,12 @@ export default defineComponent({
|
||||
);
|
||||
}
|
||||
|
||||
tabs.push({
|
||||
text: t('conditions'),
|
||||
value: 'conditions',
|
||||
disabled: interfaceDisplayDisabled(),
|
||||
});
|
||||
|
||||
return tabs;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineModule } from '@directus/shared/utils/browser';
|
||||
import { defineModule } from '@directus/shared/utils';
|
||||
import Collection from './routes/collection.vue';
|
||||
import Item from './routes/item.vue';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user