mirror of
https://github.com/directus/directus.git
synced 2026-02-16 17:35:39 -05:00
Add new advanced filters experience (#8570)
* Remove advanced filter sidebar detail So long, and thanks for all the fish. * Remove filter conversion logic * Start replacing/removing old skool filters * Add inline mode for usages in search bar * Make filter work in header bar * Emit empty string as null in filter * Move shared filter types to shared * Upgrade use-items * Fix manual sort on tabular * Cleanup styling in search bar usage * Tweak styling * Fix filtering issues * Update cards * Remove activeFilterCount from tabular * Update maps to work with new filters * Update calendar to new filter/sort structure * Fix activity module nav/search * Fix no-results message * Update file library filtering * Finalize user search * Allow filtering in drawer-collection * Handle cancelled responses semi-gracefully * Add loading start state timeout * Replace sort type in api * Last commit before redoing a bunch * Finish new visual style * Remove unused rounded prop from v-menu * Tweak sizing * Enough size tweaking for now * Count all filter operators instead of top * Fix archive casting * Fix api build * Add merge filters util * Split filter in user vs system * Fix export sidebar detail * Show field label on permissions configuration * Add migration for filter/sort * Use filters in insights
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
v-slot="{ layoutState }"
|
||||
v-model:layout-options="layoutOptions"
|
||||
v-model:layout-query="layoutQuery"
|
||||
v-model:filters="layoutFilters"
|
||||
v-model:search-query="searchQuery"
|
||||
:filter="layoutFilter"
|
||||
:search="search"
|
||||
:collection="values.collection"
|
||||
readonly
|
||||
>
|
||||
@@ -66,7 +66,12 @@
|
||||
<v-form v-model="edits" :fields="fields" :loading="loading" :initial-values="initialValues" :primary-key="id" />
|
||||
|
||||
<div class="layout">
|
||||
<component :is="`layout-${values.layout}`" v-if="values.layout && values.collection" v-bind="layoutState">
|
||||
<component
|
||||
:is="`layout-${values.layout}`"
|
||||
v-if="values.layout && values.collection"
|
||||
v-bind="layoutState"
|
||||
:collection="values.collection"
|
||||
>
|
||||
<template #no-results>
|
||||
<v-info :title="t('no_results')" icon="search" center>
|
||||
{{ t('no_results_copy') }}
|
||||
@@ -93,7 +98,7 @@
|
||||
|
||||
<div class="layout-sidebar">
|
||||
<sidebar-detail icon="search" :title="t('search')">
|
||||
<v-input v-model="searchQuery" :placeholder="t('preset_search_placeholder')"></v-input>
|
||||
<v-input v-model="search" :placeholder="t('preset_search_placeholder')"></v-input>
|
||||
</sidebar-detail>
|
||||
|
||||
<component
|
||||
@@ -156,7 +161,7 @@ type FormattedPreset = {
|
||||
layout_query: Record<string, any> | null;
|
||||
|
||||
layout_options: Record<string, any> | null;
|
||||
filters: readonly Filter[] | null;
|
||||
filter: Filter | null;
|
||||
};
|
||||
|
||||
export default defineComponent({
|
||||
@@ -181,14 +186,13 @@ export default defineComponent({
|
||||
|
||||
const { loading, preset } = usePreset();
|
||||
const { fields } = useForm();
|
||||
const { edits, hasEdits, initialValues, values, layoutQuery, layoutOptions, updateFilters, searchQuery } =
|
||||
useValues();
|
||||
const { edits, hasEdits, initialValues, values, layoutQuery, layoutOptions, updateFilters, search } = useValues();
|
||||
const { save, saving } = useSave();
|
||||
const { deleting, deleteAndQuit, confirmDelete } = useDelete();
|
||||
|
||||
const layoutFilters = computed<any>({
|
||||
const layoutFilter = computed<any>({
|
||||
get() {
|
||||
return values.value.filters || [];
|
||||
return values.value.filter ?? null;
|
||||
},
|
||||
set(newFilters) {
|
||||
updateFilters(newFilters);
|
||||
@@ -237,13 +241,13 @@ export default defineComponent({
|
||||
layoutWrapper,
|
||||
layoutQuery,
|
||||
layoutOptions,
|
||||
layoutFilters,
|
||||
layoutFilter,
|
||||
hasEdits,
|
||||
deleting,
|
||||
deleteAndQuit,
|
||||
confirmDelete,
|
||||
updateFilters,
|
||||
searchQuery,
|
||||
search,
|
||||
isSavable,
|
||||
confirmLeave,
|
||||
leaveTo,
|
||||
@@ -266,7 +270,7 @@ export default defineComponent({
|
||||
if (edits.value.layout) editsParsed.layout = edits.value.layout;
|
||||
if (edits.value.layout_query) editsParsed.layout_query = edits.value.layout_query;
|
||||
if (edits.value.layout_options) editsParsed.layout_options = edits.value.layout_options;
|
||||
if (edits.value.filters) editsParsed.filters = edits.value.filters;
|
||||
if (edits.value.filter) editsParsed.filter = edits.value.filter;
|
||||
editsParsed.search = edits.value.search;
|
||||
|
||||
if (edits.value.scope) {
|
||||
@@ -334,7 +338,7 @@ export default defineComponent({
|
||||
scope: 'all',
|
||||
layout_query: null,
|
||||
layout_options: null,
|
||||
filters: null,
|
||||
filter: null,
|
||||
};
|
||||
if (isNew.value === true) return defaultValues;
|
||||
if (preset.value === null) return defaultValues;
|
||||
@@ -357,7 +361,7 @@ export default defineComponent({
|
||||
scope: scope,
|
||||
layout_query: preset.value.layout_query,
|
||||
layout_options: preset.value.layout_options,
|
||||
filters: preset.value.filters,
|
||||
filter: preset.value.filter,
|
||||
};
|
||||
|
||||
return value;
|
||||
@@ -406,7 +410,7 @@ export default defineComponent({
|
||||
},
|
||||
});
|
||||
|
||||
const searchQuery = computed<string | null>({
|
||||
const search = computed<string | null>({
|
||||
get() {
|
||||
return values.value.search;
|
||||
},
|
||||
@@ -418,12 +422,12 @@ export default defineComponent({
|
||||
},
|
||||
});
|
||||
|
||||
return { edits, initialValues, values, layoutQuery, layoutOptions, hasEdits, updateFilters, searchQuery };
|
||||
return { edits, initialValues, values, layoutQuery, layoutOptions, hasEdits, updateFilters, search };
|
||||
|
||||
function updateFilters(newFilters: Filter) {
|
||||
function updateFilters(newFilter: Filter) {
|
||||
edits.value = {
|
||||
...edits.value,
|
||||
filters: newFilters,
|
||||
filter: newFilter,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,11 +9,7 @@
|
||||
}}
|
||||
</v-notice>
|
||||
|
||||
<interface-system-filter
|
||||
:value="permissions"
|
||||
:collection-name="permission.collection"
|
||||
@input="permissions = $event"
|
||||
/>
|
||||
<v-form v-model="permissionSync" :fields="fields" />
|
||||
|
||||
<div v-if="appMinimal" class="app-minimal">
|
||||
<v-divider />
|
||||
@@ -48,21 +44,23 @@ export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
const { t } = useI18n();
|
||||
|
||||
const internalPermission = useSync(props, 'permission', emit);
|
||||
const permissionSync = useSync(props, 'permission', emit);
|
||||
|
||||
const permissions = computed({
|
||||
get() {
|
||||
return internalPermission.value.permissions;
|
||||
const fields = computed(() => [
|
||||
{
|
||||
field: 'permissions',
|
||||
name: t('rule'),
|
||||
type: 'json',
|
||||
meta: {
|
||||
interface: 'system-filter',
|
||||
options: {
|
||||
collectionName: permissionSync.value.collection,
|
||||
},
|
||||
},
|
||||
},
|
||||
set(newPermissions: Record<string, any> | null) {
|
||||
internalPermission.value = {
|
||||
...internalPermission.value,
|
||||
permissions: newPermissions,
|
||||
};
|
||||
},
|
||||
});
|
||||
]);
|
||||
|
||||
return { t, permissions };
|
||||
return { t, fields, permissionSync };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -9,11 +9,7 @@
|
||||
}}
|
||||
</v-notice>
|
||||
|
||||
<interface-system-filter
|
||||
:value="validation"
|
||||
:collection-name="permission.collection"
|
||||
@input="validation = $event"
|
||||
/>
|
||||
<v-form v-model="permissionSync" :fields="fields" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -38,21 +34,23 @@ export default defineComponent({
|
||||
setup(props, { emit }) {
|
||||
const { t } = useI18n();
|
||||
|
||||
const internalPermission = useSync(props, 'permission', emit);
|
||||
const permissionSync = useSync(props, 'permission', emit);
|
||||
|
||||
const validation = computed({
|
||||
get() {
|
||||
return internalPermission.value.validation;
|
||||
const fields = computed(() => [
|
||||
{
|
||||
field: 'permissions',
|
||||
name: t('rule'),
|
||||
type: 'json',
|
||||
meta: {
|
||||
interface: 'system-filter',
|
||||
options: {
|
||||
collectionName: permissionSync.value.collection,
|
||||
},
|
||||
},
|
||||
},
|
||||
set(newValidation: Record<string, any> | null) {
|
||||
internalPermission.value = {
|
||||
...internalPermission.value,
|
||||
validation: newValidation,
|
||||
};
|
||||
},
|
||||
});
|
||||
]);
|
||||
|
||||
return { t, validation };
|
||||
return { t, permissionSync, fields };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
v-model:selection="selection"
|
||||
v-model:layout-options="layoutOptions"
|
||||
v-model:layout-query="layoutQuery"
|
||||
v-model:filters="filters"
|
||||
v-model:search-query="searchQuery"
|
||||
:filter="filter"
|
||||
:search="search"
|
||||
collection="directus_webhooks"
|
||||
>
|
||||
<private-view :title="t('webhooks')">
|
||||
@@ -24,7 +24,7 @@
|
||||
</template>
|
||||
|
||||
<template #actions>
|
||||
<search-input v-model="searchQuery" />
|
||||
<search-input v-model="search" collection="directus_webhooks" />
|
||||
|
||||
<v-dialog v-if="selection.length > 0" v-model="confirmDelete" @esc="confirmDelete = false">
|
||||
<template #activator="{ on }">
|
||||
@@ -121,7 +121,7 @@ export default defineComponent({
|
||||
const layoutRef = ref();
|
||||
const selection = ref<Item[]>([]);
|
||||
|
||||
const { layout, layoutOptions, layoutQuery, filters, searchQuery } = usePreset(ref('directus_webhooks'));
|
||||
const { layout, layoutOptions, layoutQuery, filter, search } = usePreset(ref('directus_webhooks'));
|
||||
const { addNewLink, batchLink } = useLinks();
|
||||
const { confirmDelete, deleting, batchDelete } = useBatchDelete();
|
||||
|
||||
@@ -136,12 +136,12 @@ export default defineComponent({
|
||||
deleting,
|
||||
layoutRef,
|
||||
layoutWrapper,
|
||||
filters,
|
||||
filter,
|
||||
selection,
|
||||
layoutOptions,
|
||||
layoutQuery,
|
||||
layout,
|
||||
searchQuery,
|
||||
search,
|
||||
clearFilters,
|
||||
};
|
||||
|
||||
@@ -186,8 +186,8 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
function clearFilters() {
|
||||
filters.value = [];
|
||||
searchQuery.value = null;
|
||||
filter.value = null;
|
||||
search.value = null;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user