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:
Rijk van Zanten
2021-10-07 18:06:03 -04:00
committed by GitHub
parent 046cc8539c
commit f64a5bef7e
99 changed files with 1375 additions and 1760 deletions

View File

@@ -0,0 +1,141 @@
import { Filter, LogicalFilterAND } from '@directus/shared/types';
import { Knex } from 'knex';
import { nanoid } from 'nanoid';
type OldFilter = {
key: string;
field: string;
value: any;
operator: string;
};
export async function up(knex: Knex): Promise<void> {
await knex.schema.alterTable('directus_presets', (table) => {
table.json('filter');
});
const presets = await knex
.select<{ id: number; filters: string | OldFilter[]; layout_query: string | Record<string, any> }[]>(
'id',
'filters',
'layout_query'
)
.from('directus_presets');
for (const preset of presets) {
if (preset.filters) {
const oldFilters: OldFilter[] =
(typeof preset.filters === 'string' ? JSON.parse(preset.filters) : preset.filters) ?? [];
if (oldFilters.length === 0) continue;
const newFilter: Filter = {
_and: [],
};
for (const oldFilter of oldFilters) {
if (oldFilter.key === 'hide-archived') continue;
newFilter._and.push({
[oldFilter.field]: {
['_' + oldFilter.operator]: oldFilter.value,
},
});
}
if (newFilter._and.length > 0) {
await knex('directus_presets')
.update({ filter: JSON.stringify(newFilter) })
.where('id', '=', preset.id);
}
}
if (preset.layout_query) {
const layoutQuery: Record<string, any> =
typeof preset.layout_query === 'string' ? JSON.parse(preset.layout_query) : preset.layout_query;
for (const [layout, query] of Object.entries(layoutQuery)) {
if (query.sort) {
query.sort = [query.sort];
}
layoutQuery[layout] = query;
}
await knex('directus_presets')
.update({ layout_query: JSON.stringify(layoutQuery) })
.where('id', '=', preset.id);
}
}
await knex.schema.alterTable('directus_presets', (table) => {
table.dropColumn('filters');
});
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.alterTable('directus_presets', (table) => {
table.json('filters');
});
const presets = await knex
.select<{ id: number; filter: string | OldFilter[]; layout_query: string | Record<string, any> }[]>(
'id',
'filter',
'layout_query'
)
.from('directus_presets');
for (const preset of presets) {
if (preset.filter) {
const newFilter: LogicalFilterAND =
(typeof preset.filter === 'string' ? JSON.parse(preset.filter) : preset.filter) ?? {};
if (Object.keys(newFilter).length === 0) continue;
const oldFilters: OldFilter[] = [];
for (const filter of newFilter._and ?? []) {
const field = Object.keys(filter)?.[0];
const operator = Object.keys(Object.values(filter)?.[0] ?? {})?.[0];
const value = Object.values(Object.values(filter)?.[0] ?? {})?.[0];
if (!field || !operator || !value) continue;
oldFilters.push({
key: nanoid(),
field,
operator: operator.substring(1),
value,
});
}
if (oldFilters.length > 0) {
await knex('directus_presets')
.update({ filters: JSON.stringify(oldFilters) })
.where('id', '=', preset.id);
}
}
if (preset.layout_query) {
const layoutQuery: Record<string, any> =
typeof preset.layout_query === 'string' ? JSON.parse(preset.layout_query) : preset.layout_query;
for (const [layout, query] of Object.entries(layoutQuery)) {
if (query.sort && Array.isArray(query.sort)) {
query.sort = query.sort?.[0] ?? null;
}
layoutQuery[layout] = query;
}
await knex('directus_presets')
.update({ layout_query: JSON.stringify(layoutQuery) })
.where('id', '=', preset.id);
}
}
await knex.schema.alterTable('directus_presets', (table) => {
table.dropColumn('filter');
});
}