mirror of
https://github.com/directus/directus.git
synced 2026-02-06 11:55:00 -05:00
Update system-filter interface to use v-field-list (#12320)
* update system filter to use v-field-list * remove unused code * use v-field-list in nodes * prevent node name wrapping * use prepend as the correct term Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<v-list :mandatory="false" @toggle="loadFieldRelations($event.value)">
|
||||
<slot name="prepend" />
|
||||
<v-list-item v-if="fieldsCount > 20">
|
||||
<v-list-item-content>
|
||||
<v-input v-model="search" autofocus small :placeholder="t('search')">
|
||||
|
||||
@@ -16,22 +16,15 @@
|
||||
<div v-if="filterInfo[index].isField" block class="node field">
|
||||
<div class="header" :class="{ inline }">
|
||||
<v-icon name="drag_indicator" class="drag-handle" small></v-icon>
|
||||
<v-select
|
||||
inline
|
||||
class="name"
|
||||
item-text="name"
|
||||
item-value="key"
|
||||
placement="bottom-start"
|
||||
:full-width="false"
|
||||
:model-value="filterInfo[index].field"
|
||||
:items="fieldOptions"
|
||||
:mandatory="false"
|
||||
:groups-clickable="true"
|
||||
@group-toggle="loadFieldRelations($event.value)"
|
||||
@update:modelValue="updateField(index, $event)"
|
||||
>
|
||||
<template #preview>{{ getFieldPreview(element) }}</template>
|
||||
</v-select>
|
||||
<v-menu placement="bottom-start" show-arrow>
|
||||
<template #activator="{ toggle }">
|
||||
<button class="name" @click="toggle">
|
||||
<span>{{ getFieldPreview(element) }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<v-field-list :collection="collectionName" @select-field="updateField(index, $event)" />
|
||||
</v-menu>
|
||||
<v-select
|
||||
inline
|
||||
class="comparator"
|
||||
@@ -98,7 +91,6 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { useFieldTree } from '@/composables/use-field-tree';
|
||||
import { computed, defineComponent, PropType, toRefs } from 'vue';
|
||||
import InputGroup from './input-group.vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
@@ -153,9 +145,8 @@ export default defineComponent({
|
||||
},
|
||||
emits: ['remove-node', 'update:filter', 'change'],
|
||||
setup(props, { emit }) {
|
||||
const { collection } = toRefs(props);
|
||||
const { collection: collectionName } = toRefs(props);
|
||||
const filterSync = useSync(props, 'filter', emit);
|
||||
const { treeList: fieldOptions, loadFieldRelations } = useFieldTree(collection);
|
||||
const fieldsStore = useFieldsStore();
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -186,14 +177,13 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
return {
|
||||
fieldOptions,
|
||||
collectionName,
|
||||
getCompareOptions,
|
||||
updateField,
|
||||
updateComparator,
|
||||
t,
|
||||
replaceNode,
|
||||
toggleLogic,
|
||||
loadFieldRelations,
|
||||
getNodeName,
|
||||
getField,
|
||||
getComparator,
|
||||
@@ -385,6 +375,10 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.name,
|
||||
.comparator {
|
||||
position: relative;
|
||||
|
||||
@@ -21,25 +21,26 @@
|
||||
/>
|
||||
</v-list>
|
||||
<div class="buttons">
|
||||
<v-select
|
||||
:inline="!inline"
|
||||
item-text="name"
|
||||
item-value="key"
|
||||
placement="bottom-start"
|
||||
class="add-filter"
|
||||
:placeholder="t('interfaces.filter.add_filter')"
|
||||
:full-width="inline"
|
||||
:model-value="null"
|
||||
:items="fieldOptions"
|
||||
:mandatory="false"
|
||||
:groups-clickable="true"
|
||||
@group-toggle="loadFieldRelations($event.value)"
|
||||
@update:modelValue="addNode($event)"
|
||||
>
|
||||
<template v-if="inline" #prepend>
|
||||
<v-icon name="add" small />
|
||||
<v-menu placement="bottom-start" show-arrow>
|
||||
<template #activator="{ toggle, active }">
|
||||
<button class="add-filter" :class="{ active }" @click="toggle">
|
||||
<v-icon v-if="inline" name="add" class="add" small />
|
||||
<span>{{ t('interfaces.filter.add_filter') }}</span>
|
||||
<v-icon name="expand_more" class="expand_more" />
|
||||
</button>
|
||||
</template>
|
||||
</v-select>
|
||||
|
||||
<v-field-list :collection="collectionName" @select-field="addNode($event)">
|
||||
<template #prepend>
|
||||
<v-list-item clickable @click="addNode('$group')">
|
||||
<v-list-item-content>
|
||||
<v-text-overflow :text="t('interfaces.filter.add_group')" />
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
<v-divider />
|
||||
</template>
|
||||
</v-field-list>
|
||||
</v-menu>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -51,7 +52,6 @@ import { useI18n } from 'vue-i18n';
|
||||
import { Filter } from '@directus/shared/types';
|
||||
import Nodes from './nodes.vue';
|
||||
import { getNodeName } from './utils';
|
||||
import { useFieldTree } from '@/composables/use-field-tree';
|
||||
import { getFilterOperatorsForType } from '@directus/shared/utils';
|
||||
import { useFieldsStore } from '@/stores';
|
||||
|
||||
@@ -96,8 +96,6 @@ export default defineComponent({
|
||||
|
||||
const fieldsStore = useFieldsStore();
|
||||
|
||||
const { treeList, loadFieldRelations } = useFieldTree(collection);
|
||||
|
||||
const innerValue = computed<Filter[]>({
|
||||
get() {
|
||||
if (!props.value || isEmpty(props.value)) return [];
|
||||
@@ -119,17 +117,11 @@ export default defineComponent({
|
||||
},
|
||||
});
|
||||
|
||||
const fieldOptions = computed(() => {
|
||||
return [{ key: '$group', name: t('interfaces.filter.add_group') }, { divider: true }, ...treeList.value];
|
||||
});
|
||||
|
||||
return {
|
||||
t,
|
||||
addNode,
|
||||
removeNode,
|
||||
innerValue,
|
||||
fieldOptions,
|
||||
loadFieldRelations,
|
||||
emitValue,
|
||||
collection,
|
||||
};
|
||||
@@ -163,7 +155,7 @@ export default defineComponent({
|
||||
|
||||
let list = get(innerValue.value, ids.join('.')) as Filter[];
|
||||
|
||||
list = list.filter((node, index) => index !== Number(id));
|
||||
list = list.filter((_node, index) => index !== Number(id));
|
||||
|
||||
innerValue.value = set(innerValue.value, ids.join('.'), list);
|
||||
}
|
||||
@@ -218,7 +210,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
.add-filter {
|
||||
--v-select-placeholder-color: var(--primary);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
&.inline {
|
||||
@@ -238,29 +230,38 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
.add-filter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding: 0;
|
||||
color: var(--foreground-subdued);
|
||||
background-color: var(--background-page);
|
||||
border: var(--border-width) solid var(--border-subdued);
|
||||
border-radius: 100px;
|
||||
transition: border-color var(--fast) var(--transition);
|
||||
|
||||
:deep(.v-input) {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
padding: 0;
|
||||
background-color: var(--background-page);
|
||||
border: var(--border-width) solid var(--border-subdued);
|
||||
border-radius: 100px;
|
||||
transition: border-color var(--fast) var(--transition);
|
||||
&:hover,
|
||||
&.active {
|
||||
border-color: var(--border-normal);
|
||||
}
|
||||
|
||||
.input {
|
||||
padding-right: 5px;
|
||||
padding-left: 6px;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
|
||||
.prepend {
|
||||
margin-right: 4px;
|
||||
}
|
||||
&.active {
|
||||
.expand_more {
|
||||
transform: scaleY(-1);
|
||||
transition-timing-function: var(--transition-in);
|
||||
}
|
||||
}
|
||||
|
||||
.add {
|
||||
margin-left: 6px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
.expand_more {
|
||||
margin-left: auto;
|
||||
margin-right: 6px;
|
||||
transition: transform var(--medium) var(--transition-out);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user