Add reporting features with new report engine and bookmark management
- Introduced a comprehensive report engine for generating and managing reports, including sales and logistics reports. - Added new API endpoints for retrieving report configurations, data, and metadata, ensuring secure access with privilege checks. - Implemented a report bookmarks system to allow users to save and manage report filters and configurations. - Created database migrations for the `report_bookmarks` table and updated the schema to support new report functionalities. - Developed services and controllers for handling report queries and bookmarks, including CRUD operations for bookmarks. - Enhanced API documentation to reflect the new reporting features and endpoints. - Added unit and integration tests to validate the new functionalities and ensure data integrity across report operations.
This commit is contained in:
@@ -0,0 +1,570 @@
|
||||
import {
|
||||
DATA_FORMAT,
|
||||
DATA_TYPE,
|
||||
FILTER_FIELD_TYPE,
|
||||
FILTER_TYPE,
|
||||
REPORT_GROUP,
|
||||
} from '../constants';
|
||||
import type { ReportConfigEntity } from '../entities';
|
||||
|
||||
const SALES_PREFIX = `${REPORT_GROUP.SALES_REPORT}__`;
|
||||
const LOGISTICS_PREFIX = `${REPORT_GROUP.LOGISTICS_REPORT}__`;
|
||||
|
||||
export const salesOrderReport: ReportConfigEntity = {
|
||||
groupName: REPORT_GROUP.SALES_REPORT,
|
||||
uniqueName: `${SALES_PREFIX}sales_order`,
|
||||
privilegeKey: 'SALES.REPORT',
|
||||
label: 'Report Sales Order',
|
||||
tableSchema: `sales_orders main
|
||||
JOIN customers cust ON cust.id = main.customer_id
|
||||
JOIN branches br ON br.id = main.branch_id
|
||||
JOIN divisions dv ON dv.id = main.division_id
|
||||
JOIN employees emp ON emp.id = main.sales_person_id
|
||||
LEFT JOIN (
|
||||
SELECT sales_order_id, SUM(quantity * price) AS amount
|
||||
FROM sales_order_products
|
||||
GROUP BY sales_order_id
|
||||
) sop ON sop.sales_order_id = main.id`,
|
||||
mainTableAlias: 'main',
|
||||
whereDefaultConditions: [],
|
||||
defaultOrderBy: ['main.created_at DESC'],
|
||||
lowLevelOrderBy: ['main.id DESC'],
|
||||
filterPeriodConfig: { hidden: true },
|
||||
columnConfigs: [
|
||||
{
|
||||
column: 'main__date',
|
||||
query: 'main.date',
|
||||
label: 'Date',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.DATE_EPOCH,
|
||||
},
|
||||
{
|
||||
column: 'br__name',
|
||||
query: 'br.name',
|
||||
label: 'Branch',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'dv__name',
|
||||
query: 'dv.name',
|
||||
label: 'Division',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'main__code',
|
||||
query: 'main.code',
|
||||
label: 'No. Sales Order',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'cust__name',
|
||||
query: 'cust.name',
|
||||
label: 'Customer',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'main__amount',
|
||||
query: 'COALESCE(sop.amount, 0)',
|
||||
label: 'Invoice Amount',
|
||||
type: DATA_TYPE.MEASURE,
|
||||
format: DATA_FORMAT.CURRENCY,
|
||||
},
|
||||
{
|
||||
column: 'emp__name',
|
||||
query: 'emp.name',
|
||||
label: 'Sales Rep.',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'main__status',
|
||||
query: 'main.status',
|
||||
label: 'Last Status Order',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.STATUS,
|
||||
},
|
||||
],
|
||||
filterConfigs: [
|
||||
{
|
||||
fieldLabel: 'Date',
|
||||
filterColumn: 'main__date',
|
||||
fieldType: FILTER_FIELD_TYPE.DATE_RANGE_PICKER,
|
||||
filterType: FILTER_TYPE.TEXT_IN_DATE_RANGE_EPOCH,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Branch',
|
||||
filterColumn: 'br__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Division',
|
||||
filterColumn: 'dv__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Customer',
|
||||
filterColumn: 'cust__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Sales Rep.',
|
||||
filterColumn: 'emp__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Status',
|
||||
filterColumn: 'main__status',
|
||||
fieldType: FILTER_FIELD_TYPE.SELECT,
|
||||
filterType: FILTER_TYPE.TEXT_IN_MEMBER_TEXT,
|
||||
selectCustomOptions: ['draft', 'active', 'archived'],
|
||||
},
|
||||
],
|
||||
customQueryColumn: (column) => {
|
||||
if (column === 'main__date') {
|
||||
return 'main.date';
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
};
|
||||
|
||||
export const salesRequestReport: ReportConfigEntity = {
|
||||
groupName: REPORT_GROUP.SALES_REPORT,
|
||||
uniqueName: `${SALES_PREFIX}sales_request`,
|
||||
privilegeKey: 'SALES.REPORT',
|
||||
label: 'Report Request Order',
|
||||
tableSchema: `sales_requests main
|
||||
JOIN customers cust ON cust.id = main.customer_id
|
||||
JOIN branches br ON br.id = main.branch_id
|
||||
JOIN divisions dv ON dv.id = main.division_id
|
||||
JOIN employees emp ON emp.id = main.sales_person_id`,
|
||||
mainTableAlias: 'main',
|
||||
defaultOrderBy: ['main.created_at DESC'],
|
||||
lowLevelOrderBy: ['main.id DESC'],
|
||||
filterPeriodConfig: { hidden: true },
|
||||
columnConfigs: [
|
||||
{
|
||||
column: 'main__date',
|
||||
query: 'main.date',
|
||||
label: 'Date',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.DATE_EPOCH,
|
||||
},
|
||||
{
|
||||
column: 'br__name',
|
||||
query: 'br.name',
|
||||
label: 'Branch',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'dv__name',
|
||||
query: 'dv.name',
|
||||
label: 'Division',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'main__code',
|
||||
query: 'main.code',
|
||||
label: 'No. Request Order',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'cust__name',
|
||||
query: 'cust.name',
|
||||
label: 'Customer',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'emp__name',
|
||||
query: 'emp.name',
|
||||
label: 'Sales Rep.',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'main__status',
|
||||
query: 'main.status',
|
||||
label: 'Status',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.STATUS,
|
||||
},
|
||||
],
|
||||
filterConfigs: [
|
||||
{
|
||||
fieldLabel: 'Date',
|
||||
filterColumn: 'main__date',
|
||||
fieldType: FILTER_FIELD_TYPE.DATE_RANGE_PICKER,
|
||||
filterType: FILTER_TYPE.TEXT_IN_DATE_RANGE_EPOCH,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Branch',
|
||||
filterColumn: 'br__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Division',
|
||||
filterColumn: 'dv__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Customer',
|
||||
filterColumn: 'cust__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Sales Rep.',
|
||||
filterColumn: 'emp__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Status',
|
||||
filterColumn: 'main__status',
|
||||
fieldType: FILTER_FIELD_TYPE.SELECT,
|
||||
filterType: FILTER_TYPE.TEXT_IN_MEMBER_TEXT,
|
||||
selectCustomOptions: ['draft', 'active', 'archived'],
|
||||
},
|
||||
],
|
||||
customQueryColumn: (column) => {
|
||||
if (column === 'main__date') {
|
||||
return 'main.date';
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
};
|
||||
|
||||
export const salesInvoiceReport: ReportConfigEntity = {
|
||||
groupName: REPORT_GROUP.SALES_REPORT,
|
||||
uniqueName: `${SALES_PREFIX}sales_invoice`,
|
||||
privilegeKey: 'SALES.REPORT',
|
||||
label: 'Report Invoice',
|
||||
tableSchema: `sales_invoices main
|
||||
JOIN customers cust ON cust.id = main.customer_id
|
||||
JOIN branches br ON br.id = main.branch_id
|
||||
JOIN divisions dv ON dv.id = main.division_id
|
||||
JOIN employees emp ON emp.id = main.sales_person_id`,
|
||||
mainTableAlias: 'main',
|
||||
defaultOrderBy: ['main.created_at DESC'],
|
||||
lowLevelOrderBy: ['main.id DESC'],
|
||||
filterPeriodConfig: { hidden: true },
|
||||
columnConfigs: [
|
||||
{
|
||||
column: 'main__date',
|
||||
query: 'main.date',
|
||||
label: 'Date',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.DATE_EPOCH,
|
||||
},
|
||||
{
|
||||
column: 'br__name',
|
||||
query: 'br.name',
|
||||
label: 'Branch',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'dv__name',
|
||||
query: 'dv.name',
|
||||
label: 'Division',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'cust__name',
|
||||
query: 'cust.name',
|
||||
label: 'Customer',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'cust__code',
|
||||
query: 'cust.code',
|
||||
label: 'Customer code',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'main__sales_order_code',
|
||||
query: 'main.sales_order_code',
|
||||
label: 'Sales Order No.',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'main__code',
|
||||
query: 'main.code',
|
||||
label: 'Invoice No.',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'main__status',
|
||||
query: 'main.status',
|
||||
label: 'Status',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.STATUS,
|
||||
},
|
||||
{
|
||||
column: 'emp__name',
|
||||
query: 'emp.name',
|
||||
label: 'Sales Rep.',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'main__balance',
|
||||
query: 'main.balance',
|
||||
label: 'Balance',
|
||||
type: DATA_TYPE.MEASURE,
|
||||
format: DATA_FORMAT.CURRENCY,
|
||||
},
|
||||
],
|
||||
filterConfigs: [
|
||||
{
|
||||
fieldLabel: 'Date',
|
||||
filterColumn: 'main__date',
|
||||
fieldType: FILTER_FIELD_TYPE.DATE_RANGE_PICKER,
|
||||
filterType: FILTER_TYPE.TEXT_IN_DATE_RANGE_EPOCH,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Branch',
|
||||
filterColumn: 'br__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Status',
|
||||
filterColumn: 'main__status',
|
||||
fieldType: FILTER_FIELD_TYPE.SELECT,
|
||||
filterType: FILTER_TYPE.TEXT_IN_MEMBER_TEXT,
|
||||
selectCustomOptions: ['draft', 'active', 'archived'],
|
||||
},
|
||||
],
|
||||
customQueryColumn: (column) => {
|
||||
if (column === 'main__date') {
|
||||
return 'main.date';
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
};
|
||||
|
||||
export const salesPaymentReport: ReportConfigEntity = {
|
||||
groupName: REPORT_GROUP.SALES_REPORT,
|
||||
uniqueName: `${SALES_PREFIX}sales_payment`,
|
||||
privilegeKey: 'SALES.REPORT',
|
||||
label: 'Report Payment',
|
||||
tableSchema: `sales_payments main
|
||||
JOIN sales_payment_invoices spi ON spi.sales_payment_id = main.id
|
||||
JOIN sales_invoices inv ON inv.id = spi.sales_invoice_id
|
||||
JOIN customers cust ON cust.id = inv.customer_id
|
||||
JOIN branches br ON br.id = inv.branch_id
|
||||
JOIN divisions dv ON dv.id = inv.division_id
|
||||
JOIN employees emp ON emp.id = inv.sales_person_id`,
|
||||
mainTableAlias: 'main',
|
||||
defaultOrderBy: ['main.created_at DESC'],
|
||||
lowLevelOrderBy: ['main.id DESC'],
|
||||
filterPeriodConfig: { hidden: true },
|
||||
columnConfigs: [
|
||||
{
|
||||
column: 'main__date',
|
||||
query: 'main.date',
|
||||
label: 'Date',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.DATE_EPOCH,
|
||||
},
|
||||
{
|
||||
column: 'main__code',
|
||||
query: 'main.code',
|
||||
label: 'Payment No.',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'cust__code',
|
||||
query: 'cust.code',
|
||||
label: 'Customer code',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'br__name',
|
||||
query: 'br.name',
|
||||
label: 'Branch',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'dv__name',
|
||||
query: 'dv.name',
|
||||
label: 'Division',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'emp__name',
|
||||
query: 'emp.name',
|
||||
label: 'Sales Rep',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'inv__code',
|
||||
query: 'inv.code',
|
||||
label: 'Invoice ID',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'inv__balance',
|
||||
query: 'inv.balance',
|
||||
label: 'Invoice Amount',
|
||||
type: DATA_TYPE.MEASURE,
|
||||
format: DATA_FORMAT.CURRENCY,
|
||||
},
|
||||
{
|
||||
column: 'spi__amount',
|
||||
query: 'spi.amount',
|
||||
label: 'Payment Amount',
|
||||
type: DATA_TYPE.MEASURE,
|
||||
format: DATA_FORMAT.CURRENCY,
|
||||
},
|
||||
{
|
||||
column: 'main__status',
|
||||
query: 'main.status',
|
||||
label: 'Status',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.STATUS,
|
||||
},
|
||||
],
|
||||
filterConfigs: [
|
||||
{
|
||||
fieldLabel: 'Date',
|
||||
filterColumn: 'main__date',
|
||||
fieldType: FILTER_FIELD_TYPE.DATE_RANGE_PICKER,
|
||||
filterType: FILTER_TYPE.TEXT_IN_DATE_RANGE_EPOCH,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Status',
|
||||
filterColumn: 'main__status',
|
||||
fieldType: FILTER_FIELD_TYPE.SELECT,
|
||||
filterType: FILTER_TYPE.TEXT_IN_MEMBER_TEXT,
|
||||
selectCustomOptions: ['draft', 'active', 'archived'],
|
||||
},
|
||||
],
|
||||
customQueryColumn: (column) => {
|
||||
if (column === 'main__date') {
|
||||
return 'main.date';
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
};
|
||||
|
||||
export const visitPlanReport: ReportConfigEntity = {
|
||||
groupName: REPORT_GROUP.SALES_REPORT,
|
||||
uniqueName: `${SALES_PREFIX}visit_plan`,
|
||||
privilegeKey: 'SALES.REPORT',
|
||||
label: 'Report Visit Plan',
|
||||
tableSchema: `plans main
|
||||
JOIN employees emp ON emp.id = main.employee_id
|
||||
JOIN branches start_br ON start_br.id = main.start_branch_id
|
||||
LEFT JOIN (
|
||||
SELECT plan_id, COUNT(*) AS destination_count
|
||||
FROM plan_destinations
|
||||
GROUP BY plan_id
|
||||
) pd ON pd.plan_id = main.id
|
||||
LEFT JOIN (
|
||||
SELECT plan_id, COUNT(*) AS invoice_count
|
||||
FROM plan_invoices
|
||||
GROUP BY plan_id
|
||||
) pi ON pi.plan_id = main.id`,
|
||||
mainTableAlias: 'main',
|
||||
whereDefaultConditions: ["main.purpose = 'sales'"],
|
||||
defaultOrderBy: ['main.date DESC'],
|
||||
lowLevelOrderBy: ['main.id DESC'],
|
||||
filterPeriodConfig: { hidden: true },
|
||||
columnConfigs: [
|
||||
{
|
||||
column: 'main__date',
|
||||
query: 'main.date',
|
||||
label: 'Date',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.DATE_EPOCH,
|
||||
},
|
||||
{
|
||||
column: 'emp__name',
|
||||
query: 'emp.name',
|
||||
label: 'Sales Rep',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'start_br__name',
|
||||
query: 'start_br.name',
|
||||
label: 'Branch',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.TEXT,
|
||||
},
|
||||
{
|
||||
column: 'pd__destination_count',
|
||||
query: 'COALESCE(pd.destination_count, 0)',
|
||||
label: 'Plan',
|
||||
type: DATA_TYPE.MEASURE,
|
||||
format: DATA_FORMAT.NUMBER,
|
||||
},
|
||||
{
|
||||
column: 'pi__invoice_count',
|
||||
query: 'COALESCE(pi.invoice_count, 0)',
|
||||
label: 'Invoice',
|
||||
type: DATA_TYPE.MEASURE,
|
||||
format: DATA_FORMAT.NUMBER,
|
||||
},
|
||||
{
|
||||
column: 'main__status',
|
||||
query: 'main.status',
|
||||
label: 'Status',
|
||||
type: DATA_TYPE.DIMENSION,
|
||||
format: DATA_FORMAT.STATUS,
|
||||
},
|
||||
],
|
||||
filterConfigs: [
|
||||
{
|
||||
fieldLabel: 'Date',
|
||||
filterColumn: 'main__date',
|
||||
fieldType: FILTER_FIELD_TYPE.DATE_RANGE_PICKER,
|
||||
filterType: FILTER_TYPE.TEXT_IN_DATE_RANGE_EPOCH,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Sales Rep',
|
||||
filterColumn: 'emp__name',
|
||||
fieldType: FILTER_FIELD_TYPE.INPUT_TAG,
|
||||
filterType: FILTER_TYPE.TEXT_MULTIPLE_CONTAINS,
|
||||
},
|
||||
{
|
||||
fieldLabel: 'Status',
|
||||
filterColumn: 'main__status',
|
||||
fieldType: FILTER_FIELD_TYPE.SELECT,
|
||||
filterType: FILTER_TYPE.TEXT_IN_MEMBER_TEXT,
|
||||
selectCustomOptions: ['draft', 'active', 'archived'],
|
||||
},
|
||||
],
|
||||
customQueryColumn: (column) => {
|
||||
if (column === 'main__date') {
|
||||
return 'main.date';
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user