mirror of
https://github.com/directus/directus.git
synced 2026-01-29 13:38:05 -05:00
Custom filter support for list-m2m, list-o2m, list-o2m-tree-view and select-dropdown-m2o interfaces (#9135)
This commit is contained in:
@@ -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'],
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -26,6 +26,17 @@ export default defineInterface({
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'filter',
|
||||
name: '$t:filter',
|
||||
type: 'json',
|
||||
meta: {
|
||||
interface: 'system-filter',
|
||||
options: {
|
||||
collectionName: collection,
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
recommendedDisplays: ['related-values'],
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user