diff --git a/src/export.handler.ts b/src/export.handler.ts index 6dd42fa..8b10d28 100644 --- a/src/export.handler.ts +++ b/src/export.handler.ts @@ -1,18 +1,26 @@ import { Parsers } from './parsers'; import { getRecords } from './utils'; import { ActionHandler, ActionResponse } from 'adminjs'; +import { formatRecords } from './formater.handler'; +import { Column } from './formater.type'; -export const exportHandler: ActionHandler = async ( - request, - response, - context -) => { - const parser = Parsers[request.query?.type ?? 'json'].export; +export const exportHandlerFactory = (columns?: Column[]) => { + const exportHandler: ActionHandler = async ( + request, + response, + context + ) => { + const parser = Parsers[request.query?.type ?? 'json'].export; - const records = await getRecords(context); - const parsedData = parser(records); + const records = await getRecords(context); + const parsedData = parser( + columns ? formatRecords(records, columns) : records + ); - return { - exportedData: parsedData, + return { + exportedData: parsedData, + }; }; + + return exportHandler; }; diff --git a/src/formater.handler.ts b/src/formater.handler.ts new file mode 100644 index 0000000..20440c5 --- /dev/null +++ b/src/formater.handler.ts @@ -0,0 +1,45 @@ +import { BaseRecord } from 'adminjs'; +import { Column } from './formater.type'; + +const formatKey = (record: BaseRecord, column: Column) => { + if (!column.key) return null; + return column.callback + ? column.callback(record.params[column.key]) + : record.params[column.key]; +}; + +const formatConcatKeys = (record: BaseRecord, column: Column) => { + if (!column.concat?.keys) return null; + return column.concat.keys + .map(key => record.params[key]) + .join(column.concat.separator); +}; + +const formatConcatKey = (record: BaseRecord, column: Column) => { + if (!column.concat?.key) return null; + let index = 0; + const array: string[] = []; + while (!!record.params[`${column.concat.key}.${index}`]) { + array.push(record.params[`${column.concat.key}.${index}`]); + index++; + } + return array.join(column.concat.separator); +}; + +export const formatRecords = (records: BaseRecord[], columns: Column[]) => { + const formattedRecords = records.map(record => { + const formattedParams = {}; + columns.forEach(column => { + if (column.key) formattedParams[column.name] = formatKey(record, column); + if (column.value) formattedParams[column.name] = column.value; + if (column.concat?.keys) + formattedParams[column.name] = formatConcatKeys(record, column); + if (column.concat?.key) + formattedParams[column.name] = formatConcatKey(record, column); + }); + + return { params: formattedParams }; + }); + + return formattedRecords; +}; diff --git a/src/formater.type.ts b/src/formater.type.ts new file mode 100644 index 0000000..330d9cd --- /dev/null +++ b/src/formater.type.ts @@ -0,0 +1,11 @@ +export interface Column { + name: string; + key?: string; + callback?: (value: string) => string; + value?: string; + concat?: { + key?: string; + keys?: string[]; + separator: string; + }; +} diff --git a/src/importExportFeature.ts b/src/importExportFeature.ts index 0303148..696e971 100644 --- a/src/importExportFeature.ts +++ b/src/importExportFeature.ts @@ -1,25 +1,34 @@ +import * as _ from 'lodash'; import { buildFeature, FeatureType } from 'adminjs'; import { bundleComponents } from './components/bundleComponents'; import { postActionHandler } from './utils'; -import { exportHandler } from './export.handler'; +import { exportHandlerFactory } from './export.handler'; import { importHandler } from './import.handler'; +import { Options } from './options.type'; +import { defaultOptions } from './options.default'; const { EXPORT_COMPONENT, IMPORT_COMPONENT } = bundleComponents(); -const importExportFeature = (): FeatureType => { +const importExportFeature = (options: Options): FeatureType => { + const appOptions = _.merge({}, defaultOptions, options); + const actions = {}; + if (appOptions.export?.isVisible) + actions['export'] = { + handler: postActionHandler( + exportHandlerFactory(appOptions.export.columns) + ), + component: EXPORT_COMPONENT, + actionType: 'resource', + }; + if (appOptions.import?.isVisible) + actions['import'] = { + handler: postActionHandler(importHandler), + component: IMPORT_COMPONENT, + actionType: 'resource', + }; + return buildFeature({ - actions: { - export: { - handler: postActionHandler(exportHandler), - component: EXPORT_COMPONENT, - actionType: 'resource', - }, - import: { - handler: postActionHandler(importHandler), - component: IMPORT_COMPONENT, - actionType: 'resource', - }, - }, + actions, }); }; diff --git a/src/options.default.ts b/src/options.default.ts new file mode 100644 index 0000000..68e2a0e --- /dev/null +++ b/src/options.default.ts @@ -0,0 +1,10 @@ +import { Options } from './options.type'; + +export const defaultOptions: Options = { + export: { + isVisible: true, + }, + import: { + isVisible: true, + }, +}; diff --git a/src/options.type.ts b/src/options.type.ts new file mode 100644 index 0000000..7cf0063 --- /dev/null +++ b/src/options.type.ts @@ -0,0 +1,11 @@ +import { Column } from './formater.type'; + +export interface Options { + export?: { + isVisible?: boolean; + columns?: Column[]; + }; + import?: { + isVisible?: boolean; + }; +}