Custom filter support for list-m2m, list-o2m, list-o2m-tree-view and select-dropdown-m2o interfaces (#9135)

This commit is contained in:
Tien Tran
2021-12-17 09:19:51 +11:00
committed by GitHub
parent 42c1dafc2d
commit 5e7fa633b0
8 changed files with 174 additions and 4 deletions

View File

@@ -52,6 +52,27 @@ export default defineInterface({
width: 'half',
},
},
{
field: 'filter',
name: '$t:filter',
type: 'json',
meta: {
interface: 'system-filter',
options: {
collectionName: relations.m2o?.related_collection ?? null,
},
conditions: [
{
rule: {
enableSelect: {
_eq: false,
},
},
hidden: true,
},
],
},
},
];
},
recommendedDisplays: ['related-values'],

View File

@@ -70,6 +70,7 @@
v-model:active="selectModalActive"
:collection="relationCollection.collection"
:selection="selectedPrimaryKeys"
:filter="customFilter"
multiple
@input="stageSelection"
/>
@@ -78,11 +79,15 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, computed, PropType, toRefs } from 'vue';
import { defineComponent, computed, PropType, toRefs, inject, ref } from 'vue';
import DrawerItem from '@/views/private/components/drawer-item';
import DrawerCollection from '@/views/private/components/drawer-collection';
import { get } from 'lodash';
import Draggable from 'vuedraggable';
import { Filter } from '@directus/shared/types';
import { parseFilter } from '@/utils/parse-filter';
import { render } from 'micromustache';
import { deepMap } from '@directus/shared/utils';
import useActions from './use-actions';
import useRelation from '@/composables/use-m2m';
@@ -129,11 +134,29 @@ export default defineComponent({
type: Boolean,
default: true,
},
filter: {
type: Object as PropType<Filter>,
default: null,
},
},
emits: ['input'],
setup(props, { emit }) {
const { t } = useI18n();
const values = inject('values', ref<Record<string, any>>({}));
const customFilter = computed(() => {
return parseFilter(
deepMap(props.filter, (val: any) => {
if (val && typeof val === 'string') {
return render(val, values.value);
}
return val;
})
);
});
const { value, collection, field } = toRefs(props);
const { junction, junctionCollection, relation, relationCollection, relationInfo } = useRelation(collection, field);
@@ -223,6 +246,7 @@ export default defineComponent({
templateWithDefaults,
createAllowed,
selectAllowed,
customFilter,
};
function emitter(newVal: any[] | null) {

View File

@@ -54,6 +54,27 @@ export default defineInterface({
width: 'half',
},
},
{
field: 'filter',
name: '$t:filter',
type: 'json',
meta: {
interface: 'system-filter',
options: {
collectionName: collection,
},
conditions: [
{
rule: {
enableSelect: {
_eq: false,
},
},
hidden: true,
},
],
},
},
];
},
});

View File

@@ -40,6 +40,7 @@
v-model:active="selectDrawer"
:collection="collection"
:selection="[]"
:filter="customFilter"
multiple
@input="stageSelection"
/>
@@ -48,7 +49,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, ref, computed, PropType, onMounted, watch } from 'vue';
import { defineComponent, ref, computed, PropType, onMounted, watch, inject } from 'vue';
import { useCollection } from '@directus/shared/composables';
import { useRelationsStore } from '@/stores';
import api from '@/api';
@@ -58,6 +59,10 @@ import NestedDraggable from './nested-draggable.vue';
import { Relation } from '@directus/shared/types';
import DrawerCollection from '@/views/private/components/drawer-collection';
import DrawerItem from '@/views/private/components/drawer-item';
import { Filter } from '@directus/shared/types';
import { parseFilter } from '@/utils/parse-filter';
import { render } from 'micromustache';
import { deepMap } from '@directus/shared/utils';
export default defineComponent({
components: { NestedDraggable, DrawerCollection, DrawerItem },
@@ -94,11 +99,29 @@ export default defineComponent({
type: Boolean,
default: true,
},
filter: {
type: Object as PropType<Filter>,
default: null,
},
},
emits: ['input'],
setup(props, { emit }) {
const { t } = useI18n();
const values = inject('values', ref<Record<string, any>>({}));
const customFilter = computed(() => {
return parseFilter(
deepMap(props.filter, (val: any) => {
if (val && typeof val === 'string') {
return render(val, values.value);
}
return val;
})
);
});
const relationsStore = useRelationsStore();
const openItems = ref([]);
@@ -136,6 +159,7 @@ export default defineComponent({
selectDrawer,
addNewActive,
addNew,
customFilter,
};
function useValues() {

View File

@@ -55,6 +55,27 @@ export default defineInterface({
width: 'half',
},
},
{
field: 'filter',
name: '$t:filter',
type: 'json',
meta: {
interface: 'system-filter',
options: {
collectionName: collection,
},
conditions: [
{
rule: {
enableSelect: {
_eq: false,
},
},
hidden: true,
},
],
},
},
];
},
recommendedDisplays: ['related-values'],

View File

@@ -72,6 +72,7 @@
v-model:active="selectModalActive"
:collection="relatedCollection.collection"
:selection="selectedPrimaryKeys"
:filter="customFilter"
multiple
@input="$emit('input', $event.length > 0 ? $event : null)"
/>
@@ -80,7 +81,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, ref, computed, watch, PropType } from 'vue';
import { defineComponent, ref, computed, watch, PropType, inject } from 'vue';
import api from '@/api';
import { useCollection } from '@directus/shared/composables';
import { useCollectionsStore, useRelationsStore, useFieldsStore, usePermissionsStore, useUserStore } from '@/stores/';
@@ -93,6 +94,10 @@ import { getFieldsFromTemplate } from '@directus/shared/utils';
import { addRelatedPrimaryKeyToFields } from '@/utils/add-related-primary-key-to-fields';
import Draggable from 'vuedraggable';
import adjustFieldsForDisplays from '@/utils/adjust-fields-for-displays';
import { Filter } from '@directus/shared/types';
import { parseFilter } from '@/utils/parse-filter';
import { render } from 'micromustache';
import { deepMap } from '@directus/shared/utils';
export default defineComponent({
components: { DrawerItem, DrawerCollection, Draggable },
@@ -129,11 +134,29 @@ export default defineComponent({
type: Boolean,
default: true,
},
filter: {
type: Object as PropType<Filter>,
default: null,
},
},
emits: ['input'],
setup(props, { emit }) {
const { t } = useI18n();
const values = inject('values', ref<Record<string, any>>({}));
const customFilter = computed(() => {
return parseFilter(
deepMap(props.filter, (val: any) => {
if (val && typeof val === 'string') {
return render(val, values.value);
}
return val;
})
);
});
const relationsStore = useRelationsStore();
const collectionsStore = useCollectionsStore();
const fieldsStore = useFieldsStore();
@@ -182,6 +205,7 @@ export default defineComponent({
templateWithDefaults,
createAllowed,
updateAllowed,
customFilter,
};
function getItemFromIndex(index: number) {

View File

@@ -26,6 +26,17 @@ export default defineInterface({
},
},
},
{
field: 'filter',
name: '$t:filter',
type: 'json',
meta: {
interface: 'system-filter',
options: {
collectionName: collection,
},
},
},
];
},
recommendedDisplays: ['related-values'],

View File

@@ -80,6 +80,7 @@
v-model:active="selectModalActive"
:collection="relatedCollection.collection"
:selection="selection"
:filter="customFilter"
@input="stageSelection"
/>
</div>
@@ -87,7 +88,7 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, computed, ref, toRefs, watch, PropType } from 'vue';
import { defineComponent, computed, ref, toRefs, watch, PropType, inject } from 'vue';
import { useCollectionsStore, useRelationsStore } from '@/stores/';
import { useCollection } from '@directus/shared/composables';
import { getFieldsFromTemplate } from '@directus/shared/utils';
@@ -96,6 +97,10 @@ import DrawerItem from '@/views/private/components/drawer-item';
import DrawerCollection from '@/views/private/components/drawer-collection';
import { unexpectedError } from '@/utils/unexpected-error';
import adjustFieldsForDisplays from '@/utils/adjust-fields-for-displays';
import { Filter } from '@directus/shared/types';
import { parseFilter } from '@/utils/parse-filter';
import { render } from 'micromustache';
import { deepMap } from '@directus/shared/utils';
/**
* @NOTE
@@ -132,11 +137,29 @@ export default defineComponent({
type: Boolean,
default: false,
},
filter: {
type: Object as PropType<Filter>,
default: null,
},
},
emits: ['input'],
setup(props, { emit }) {
const { t } = useI18n();
const values = inject('values', ref<Record<string, any>>({}));
const customFilter = computed(() => {
return parseFilter(
deepMap(props.filter, (val: any) => {
if (val && typeof val === 'string') {
return render(val, values.value);
}
return val;
})
);
});
const { collection } = toRefs(props);
const relationsStore = useRelationsStore();
@@ -178,6 +201,7 @@ export default defineComponent({
stageEdits,
editModalActive,
relatedPrimaryKeyField,
customFilter,
};
function useCurrent() {