mirror of
https://github.com/directus/directus.git
synced 2026-04-03 03:00:39 -04:00
@@ -130,7 +130,7 @@ async function parseCurrentLevel(
|
||||
return { columnsToSelect, nestedCollectionNodes, primaryKeyField };
|
||||
}
|
||||
|
||||
async function getDBQuery(
|
||||
function getDBQuery(
|
||||
knex: Knex,
|
||||
table: string,
|
||||
columns: string[],
|
||||
@@ -138,7 +138,7 @@ async function getDBQuery(
|
||||
primaryKeyField: string,
|
||||
schema: SchemaOverview,
|
||||
nested?: boolean
|
||||
): Promise<QueryBuilder> {
|
||||
): QueryBuilder {
|
||||
let dbQuery = knex.select(columns.map((column) => `${table}.${column}`)).from(table);
|
||||
|
||||
const queryCopy = clone(query);
|
||||
@@ -154,7 +154,7 @@ async function getDBQuery(
|
||||
|
||||
query.sort = query.sort || [{ column: primaryKeyField, order: 'asc' }];
|
||||
|
||||
await applyQuery(table, dbQuery, queryCopy, schema);
|
||||
applyQuery(table, dbQuery, queryCopy, schema);
|
||||
|
||||
// Nested filters use joins to filter on the parent level, to prevent duplicate
|
||||
// parents, we group the query by the current tables primary key (which is unique)
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Query } from '../types/query';
|
||||
import database from '../database';
|
||||
import { AbstractServiceOptions, Accountability, SchemaOverview } from '../types';
|
||||
import Knex from 'knex';
|
||||
import { applyFilter } from '../utils/apply-query';
|
||||
import { applyFilter, applySearch } from '../utils/apply-query';
|
||||
|
||||
export class MetaService {
|
||||
knex: Knex;
|
||||
@@ -42,7 +42,11 @@ export class MetaService {
|
||||
const dbQuery = this.knex(collection).count('*', { as: 'count' });
|
||||
|
||||
if (query.filter) {
|
||||
await applyFilter(this.schema, dbQuery, query.filter, collection);
|
||||
applyFilter(this.schema, dbQuery, query.filter, collection);
|
||||
}
|
||||
|
||||
if (query.search) {
|
||||
applySearch(this.schema, dbQuery, query.search, collection);
|
||||
}
|
||||
|
||||
const records = await dbQuery;
|
||||
|
||||
@@ -6,16 +6,7 @@ import { nanoid } from 'nanoid';
|
||||
import getLocalType from './get-local-type';
|
||||
import validate from 'uuid-validate';
|
||||
|
||||
export default async function applyQuery(
|
||||
collection: string,
|
||||
dbQuery: QueryBuilder,
|
||||
query: Query,
|
||||
schema: SchemaOverview
|
||||
) {
|
||||
if (query.filter) {
|
||||
await applyFilter(schema, dbQuery, query.filter, collection);
|
||||
}
|
||||
|
||||
export default function applyQuery(collection: string, dbQuery: QueryBuilder, query: Query, schema: SchemaOverview) {
|
||||
if (query.sort) {
|
||||
dbQuery.orderBy(query.sort);
|
||||
}
|
||||
@@ -36,38 +27,16 @@ export default async function applyQuery(
|
||||
dbQuery.limit(1).first();
|
||||
}
|
||||
|
||||
if (query.search) {
|
||||
const columns = Object.values(schema.tables[collection].columns);
|
||||
if (query.filter) {
|
||||
applyFilter(schema, dbQuery, query.filter, collection);
|
||||
}
|
||||
|
||||
dbQuery.andWhere(function () {
|
||||
columns
|
||||
.map((column) => ({
|
||||
...column,
|
||||
localType: getLocalType(column),
|
||||
}))
|
||||
.forEach((column) => {
|
||||
if (['text', 'string'].includes(column.localType)) {
|
||||
this.orWhereRaw(`LOWER(??) LIKE ?`, [
|
||||
`${column.table_name}.${column.column_name}`,
|
||||
`%${query.search!.toLowerCase()}%`,
|
||||
]);
|
||||
} else if (['bigInteger', 'integer', 'decimal', 'float'].includes(column.localType)) {
|
||||
const number = Number(query.search!);
|
||||
if (!isNaN(number)) this.orWhere({ [`${column.table_name}.${column.column_name}`]: number });
|
||||
} else if (column.localType === 'uuid' && validate(query.search!)) {
|
||||
this.orWhere({ [`${column.table_name}.${column.column_name}`]: query.search! });
|
||||
}
|
||||
});
|
||||
});
|
||||
if (query.search) {
|
||||
applySearch(schema, dbQuery, query.search, collection);
|
||||
}
|
||||
}
|
||||
|
||||
export async function applyFilter(
|
||||
schema: SchemaOverview,
|
||||
rootQuery: QueryBuilder,
|
||||
rootFilter: Filter,
|
||||
collection: string
|
||||
) {
|
||||
export function applyFilter(schema: SchemaOverview, rootQuery: QueryBuilder, rootFilter: Filter, collection: string) {
|
||||
const relations: Relation[] = [...schema.relations, ...systemRelationRows];
|
||||
|
||||
const aliasMap: Record<string, string> = {};
|
||||
@@ -293,6 +262,36 @@ export async function applyFilter(
|
||||
}
|
||||
}
|
||||
|
||||
export async function applySearch(
|
||||
schema: SchemaOverview,
|
||||
dbQuery: QueryBuilder,
|
||||
searchQuery: string,
|
||||
collection: string
|
||||
) {
|
||||
const columns = Object.values(schema.tables[collection].columns);
|
||||
|
||||
dbQuery.andWhere(function () {
|
||||
columns
|
||||
.map((column) => ({
|
||||
...column,
|
||||
localType: getLocalType(column),
|
||||
}))
|
||||
.forEach((column) => {
|
||||
if (['text', 'string'].includes(column.localType)) {
|
||||
this.orWhereRaw(`LOWER(??) LIKE ?`, [
|
||||
`${column.table_name}.${column.column_name}`,
|
||||
`%${searchQuery.toLowerCase()}%`,
|
||||
]);
|
||||
} else if (['bigInteger', 'integer', 'decimal', 'float'].includes(column.localType)) {
|
||||
const number = Number(searchQuery);
|
||||
if (!isNaN(number)) this.orWhere({ [`${column.table_name}.${column.column_name}`]: number });
|
||||
} else if (column.localType === 'uuid' && validate(searchQuery)) {
|
||||
this.orWhere({ [`${column.table_name}.${column.column_name}`]: searchQuery });
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getFilterPath(key: string, value: Record<string, any>) {
|
||||
const path = [key];
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ import { userName } from '@/utils/user-name';
|
||||
import { usePermissions } from '@/composables/use-permissions';
|
||||
import { unexpectedError } from '@/utils/unexpected-error';
|
||||
import { addTokenToURL } from '@/api';
|
||||
import { useUserStore } from '@/stores';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'users-item',
|
||||
@@ -217,6 +218,7 @@ export default defineComponent({
|
||||
const form = ref<HTMLElement>();
|
||||
const fieldsStore = useFieldsStore();
|
||||
const collectionsStore = useCollectionsStore();
|
||||
const userStore = useUserStore();
|
||||
|
||||
const { primaryKey } = toRefs(props);
|
||||
const { breadcrumb } = useBreadcrumb();
|
||||
@@ -231,7 +233,6 @@ export default defineComponent({
|
||||
item,
|
||||
saving,
|
||||
loading,
|
||||
error,
|
||||
save,
|
||||
remove,
|
||||
deleting,
|
||||
|
||||
Reference in New Issue
Block a user