74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
import { Knex } from "knex";
|
|
import { db } from "@db/db";
|
|
|
|
export interface RequestQuery {
|
|
length: string;
|
|
start: string;
|
|
order: { column: string; dir: string }[];
|
|
columns: { [key: string]: { data: string; searchable: string } };
|
|
search: { value: string };
|
|
filters: { [key: string]: any };
|
|
}
|
|
|
|
export interface ResponseQuery {
|
|
query: Knex.QueryBuilder;
|
|
recordsTotal: number | string;
|
|
recordsFiltered: number | string;
|
|
}
|
|
|
|
type FilterConfig = {
|
|
[key: string]: (value: any) => Knex.QueryBuilder;
|
|
};
|
|
|
|
export const buildDatatableQuery = async (request: { query: RequestQuery }, query: Knex.QueryBuilder, tableName: string): Promise<ResponseQuery> => {
|
|
const size: number = parseInt(request.query.length) || 10;
|
|
const start: number = parseInt(request.query.start);
|
|
const order: string = (
|
|
request.query.order && request.query.columns
|
|
[request.query.order[0].column].data
|
|
) || 'id'
|
|
const direction: string = (request.query.order && request.query.order[0].dir) || "asc";
|
|
const search: string = request.query.search.value;
|
|
|
|
const recordsTotalResult = await query.clone().count("* as count").first();
|
|
const recordsTotal = recordsTotalResult ? recordsTotalResult.count : 0;
|
|
|
|
const filterConfig: FilterConfig = {
|
|
active: (value: string) => query.where('active', '=', value),
|
|
};
|
|
|
|
if (request.query.filters) {
|
|
Object.keys(request.query.filters).forEach((filterName: any) => {
|
|
const filterValue = request.query.filters[filterName];
|
|
if (filterConfig[filterName] && filterValue) {
|
|
query = filterConfig[filterName](filterValue);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (search) {
|
|
console.log("applying search: " + search)
|
|
console.log("columns: " + JSON.stringify(request.query.columns, null, 4));
|
|
query = query.where(builder => {
|
|
Object.values(request.query.columns)
|
|
.filter(column => column.searchable === "true")
|
|
.forEach((col, index) =>
|
|
index === 0
|
|
? builder.where(`${tableName}.${col.data}`, "like", `%${search}%`)
|
|
: builder.orWhere(`${tableName}.${col.data}`, "like", `%${search}%`)
|
|
);
|
|
});
|
|
}
|
|
|
|
const recordsFilteredResult = await query.clone().count("* as count").first();
|
|
const recordsFiltered = recordsFilteredResult ? recordsFilteredResult.count : 0;
|
|
|
|
query = query.orderBy(`${tableName}.${order}`, direction).limit(size).offset(start);
|
|
|
|
return {
|
|
query,
|
|
recordsTotal,
|
|
recordsFiltered
|
|
};
|
|
}
|