mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 05:40:31 +00:00
refactor: dynamic list to nestjs
This commit is contained in:
@@ -1,17 +1,15 @@
|
||||
import { forEach } from 'lodash';
|
||||
import { DynamicFilterAbstractor } from './DynamicFilterAbstractor';
|
||||
import { IDynamicFilter, IFilterRole, IModel } from '@/interfaces';
|
||||
import { IDynamicFilter, IFilterRole } from './DynamicFilter.types';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { DynamicFilterRoleAbstractor } from './DynamicFilterRoleAbstractor';
|
||||
|
||||
export class DynamicFilter extends DynamicFilterAbstractor {
|
||||
private model: BaseModel;
|
||||
private dynamicFilters: IDynamicFilter[];
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param {String} tableName -
|
||||
*/
|
||||
constructor(model: BaseModel) {
|
||||
constructor(model: typeof BaseModel) {
|
||||
super();
|
||||
|
||||
this.model = model;
|
||||
@@ -22,7 +20,7 @@ export class DynamicFilter extends DynamicFilterAbstractor {
|
||||
* Registers the given dynamic filter.
|
||||
* @param {IDynamicFilter} filterRole - Filter role.
|
||||
*/
|
||||
public setFilter = (dynamicFilter: IDynamicFilter) => {
|
||||
public setFilter = (dynamicFilter: DynamicFilterRoleAbstractor) => {
|
||||
dynamicFilter.setModel(this.model);
|
||||
dynamicFilter.onInitialize();
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { BaseModel } from '@/models/Model';
|
||||
// import { IModel, ISortOrder } from "./Model";
|
||||
|
||||
export type ISortOrder = 'DESC' | 'ASC';
|
||||
|
||||
export interface IDynamicFilter {
|
||||
setModel(model: BaseModel): void;
|
||||
setModel(model: typeof BaseModel): void;
|
||||
onInitialize(): void;
|
||||
buildQuery(): void;
|
||||
getResponseMeta();
|
||||
}
|
||||
@@ -20,7 +20,7 @@ export interface IDynamicListFilter {
|
||||
filterRoles?: IFilterRole[];
|
||||
columnSortBy: ISortOrder;
|
||||
sortOrder: string;
|
||||
stringifiedFilterRoles: string;
|
||||
stringifiedFilterRoles?: string;
|
||||
searchKeyword?: string;
|
||||
viewSlug?: string;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ import { BaseModel } from '@/models/Model';
|
||||
import { IDynamicFilter } from './DynamicFilter.types';
|
||||
|
||||
export class DynamicFilterAbstractor {
|
||||
model: BaseModel;
|
||||
dynamicFilters: IDynamicFilter[];
|
||||
public model: typeof BaseModel;
|
||||
public dynamicFilters: IDynamicFilter[];
|
||||
|
||||
/**
|
||||
* Extract relation table name from relation.
|
||||
|
||||
@@ -2,8 +2,6 @@ import { IFilterRole } from './DynamicFilter.types';
|
||||
import { DynamicFilterFilterRoles } from './DynamicFilterFilterRoles';
|
||||
|
||||
export class DynamicFilterAdvancedFilter extends DynamicFilterFilterRoles {
|
||||
private filterRoles: IFilterRole[];
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {Array} filterRoles -
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { DynamicFilterAbstractor } from './DynamicFilterRoleAbstractor';
|
||||
import { IFilterRole } from '@/interfaces';
|
||||
import { DynamicFilterRoleAbstractor } from './DynamicFilterRoleAbstractor';
|
||||
|
||||
export class DynamicFilterFilterRoles extends DynamicFilterAbstractor {
|
||||
private filterRoles: IFilterRole[];
|
||||
export class DynamicFilterFilterRoles extends DynamicFilterRoleAbstractor {
|
||||
/**
|
||||
* On initialize filter roles.
|
||||
*/
|
||||
@@ -28,14 +26,14 @@ export class DynamicFilterFilterRoles extends DynamicFilterAbstractor {
|
||||
/**
|
||||
* Builds database query of view roles.
|
||||
*/
|
||||
protected buildQuery() {
|
||||
public buildQuery() {
|
||||
const logicExpression = this.buildLogicExpression();
|
||||
|
||||
return (builder) => {
|
||||
this.buildFilterQuery(
|
||||
this.model,
|
||||
this.filterRoles,
|
||||
logicExpression
|
||||
logicExpression,
|
||||
)(builder);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import moment from 'moment';
|
||||
import * as R from 'ramda';
|
||||
import { IFilterRole, IDynamicFilter, } from './DynamicFilter.types';
|
||||
import { IFilterRole, IDynamicFilter } from './DynamicFilter.types';
|
||||
import Parser from '@/libs/logic-evaluation/Parser';
|
||||
import { Lexer } from '@/libs/logic-evaluation/Lexer';
|
||||
import DynamicFilterQueryParser from './DynamicFilterQueryParser';
|
||||
import { COMPARATOR_TYPE, FIELD_TYPE } from './constants';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { IMetadataModel } from '../models/MetadataModel';
|
||||
|
||||
export abstract class DynamicFilterAbstractor
|
||||
implements IDynamicFilter
|
||||
{
|
||||
type MetadataModel = typeof BaseModel & IMetadataModel;
|
||||
|
||||
export abstract class DynamicFilterRoleAbstractor implements IDynamicFilter {
|
||||
protected filterRoles: IFilterRole[] = [];
|
||||
protected tableName: string;
|
||||
protected model: BaseModel;
|
||||
protected model: MetadataModel;
|
||||
protected responseMeta: { [key: string]: any } = {};
|
||||
public relationFields = [];
|
||||
|
||||
@@ -20,7 +21,7 @@ export abstract class DynamicFilterAbstractor
|
||||
* Sets model the dynamic filter service.
|
||||
* @param {IModel} model
|
||||
*/
|
||||
public setModel(model: BaseModel) {
|
||||
public setModel(model: MetadataModel) {
|
||||
this.model = model;
|
||||
this.tableName = model.tableName;
|
||||
}
|
||||
@@ -46,9 +47,9 @@ export abstract class DynamicFilterAbstractor
|
||||
* @return {Function}
|
||||
*/
|
||||
protected buildFilterRolesQuery = (
|
||||
model: IModel,
|
||||
model: typeof BaseModel,
|
||||
roles: IFilterRole[],
|
||||
logicExpression: string = ''
|
||||
logicExpression: string = '',
|
||||
) => {
|
||||
const rolesIndexSet = this.convertRolesMapByIndex(model, roles);
|
||||
|
||||
@@ -67,7 +68,7 @@ export abstract class DynamicFilterAbstractor
|
||||
|
||||
/**
|
||||
* Parses the logic expression to base expression.
|
||||
* @param {string} logicExpression -
|
||||
* @param {string} logicExpression -
|
||||
* @return {string}
|
||||
*/
|
||||
private parseLogicExpression(logicExpression: string): string {
|
||||
@@ -84,9 +85,9 @@ export abstract class DynamicFilterAbstractor
|
||||
* @param {String} logicExpression - Logic expression.
|
||||
*/
|
||||
protected buildFilterQuery = (
|
||||
model: IModel,
|
||||
model: typeof BaseModel,
|
||||
roles: IFilterRole[],
|
||||
logicExpression: string
|
||||
logicExpression: string,
|
||||
) => {
|
||||
const basicExpression = this.parseLogicExpression(logicExpression);
|
||||
|
||||
@@ -98,7 +99,7 @@ export abstract class DynamicFilterAbstractor
|
||||
/**
|
||||
* Retrieve relation column of comparator fieldز
|
||||
*/
|
||||
private getFieldComparatorRelationColumn(field) {
|
||||
protected getFieldComparatorRelationColumn(field: any): string {
|
||||
const relation = this.model.relationMappings[field.relationKey];
|
||||
|
||||
if (relation) {
|
||||
@@ -128,7 +129,7 @@ export abstract class DynamicFilterAbstractor
|
||||
* @param {IModel} model -
|
||||
* @param {Object} role -
|
||||
*/
|
||||
protected buildRoleQuery = (model: BaseModel, role: IFilterRole) => {
|
||||
protected buildRoleQuery = (model: MetadataModel, role: IFilterRole) => {
|
||||
const field = model.getField(role.fieldKey);
|
||||
const comparatorColumn = this.getFieldComparatorColumn(field);
|
||||
|
||||
@@ -160,7 +161,7 @@ export abstract class DynamicFilterAbstractor
|
||||
*/
|
||||
protected booleanRoleQueryBuilder = (
|
||||
role: IFilterRole,
|
||||
comparatorColumn: string
|
||||
comparatorColumn: string,
|
||||
) => {
|
||||
switch (role.comparator) {
|
||||
case COMPARATOR_TYPE.EQUALS:
|
||||
@@ -187,7 +188,7 @@ export abstract class DynamicFilterAbstractor
|
||||
*/
|
||||
protected numberRoleQueryBuilder = (
|
||||
role: IFilterRole,
|
||||
comparatorColumn: string
|
||||
comparatorColumn: string,
|
||||
) => {
|
||||
switch (role.comparator) {
|
||||
case COMPARATOR_TYPE.EQUALS:
|
||||
@@ -230,7 +231,7 @@ export abstract class DynamicFilterAbstractor
|
||||
*/
|
||||
protected textRoleQueryBuilder = (
|
||||
role: IFilterRole,
|
||||
comparatorColumn: string
|
||||
comparatorColumn: string,
|
||||
) => {
|
||||
switch (role.comparator) {
|
||||
case COMPARATOR_TYPE.EQUAL:
|
||||
@@ -266,7 +267,6 @@ export abstract class DynamicFilterAbstractor
|
||||
return (builder) => {
|
||||
builder.where(comparatorColumn, 'LIKE', `%${role.value}`);
|
||||
};
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
@@ -278,7 +278,7 @@ export abstract class DynamicFilterAbstractor
|
||||
*/
|
||||
protected dateQueryBuilder = (
|
||||
role: IFilterRole,
|
||||
comparatorColumn: string
|
||||
comparatorColumn: string,
|
||||
) => {
|
||||
switch (role.comparator) {
|
||||
case COMPARATOR_TYPE.AFTER:
|
||||
@@ -302,12 +302,12 @@ export abstract class DynamicFilterAbstractor
|
||||
protected dateQueryInComparator = (
|
||||
role: IFilterRole,
|
||||
comparatorColumn: string,
|
||||
builder
|
||||
builder,
|
||||
) => {
|
||||
const hasTimeFormat = moment(
|
||||
role.value,
|
||||
'YYYY-MM-DD HH:MM',
|
||||
true
|
||||
true,
|
||||
).isValid();
|
||||
const dateFormat = 'YYYY-MM-DD HH:MM:SS';
|
||||
|
||||
@@ -332,13 +332,13 @@ export abstract class DynamicFilterAbstractor
|
||||
protected dateQueryAfterBeforeComparator = (
|
||||
role: IFilterRole,
|
||||
comparatorColumn: string,
|
||||
builder
|
||||
builder,
|
||||
) => {
|
||||
const comparator = role.comparator === COMPARATOR_TYPE.BEFORE ? '<' : '>';
|
||||
const hasTimeFormat = moment(
|
||||
role.value,
|
||||
'YYYY-MM-DD HH:MM',
|
||||
true
|
||||
true,
|
||||
).isValid();
|
||||
const targetDate = moment(role.value);
|
||||
const dateFormat = 'YYYY-MM-DD HH:MM:SS';
|
||||
@@ -355,16 +355,14 @@ export abstract class DynamicFilterAbstractor
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers relation field if the given field was relation type
|
||||
* and not registered.
|
||||
* Registers relation field if the given field was relation type and not registered.
|
||||
* @param {string} fieldKey - Field key.
|
||||
*/
|
||||
protected setRelationIfRelationField = (fieldKey: string): void => {
|
||||
const field = this.model.getField(fieldKey);
|
||||
const isAlreadyRegistered = this.relationFields.some(
|
||||
(field) => field === fieldKey
|
||||
(field) => field === fieldKey,
|
||||
);
|
||||
|
||||
if (
|
||||
!isAlreadyRegistered &&
|
||||
field &&
|
||||
@@ -385,4 +383,11 @@ export abstract class DynamicFilterAbstractor
|
||||
* On initialize the registered dynamic filter.
|
||||
*/
|
||||
onInitialize() {}
|
||||
|
||||
buildQuery(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getResponseMeta() {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import { DynamicFilterFilterRoles } from './DynamicFilterFilterRoles';
|
||||
|
||||
export class DynamicFilterSearch extends DynamicFilterFilterRoles {
|
||||
private searchKeyword: string;
|
||||
private filterRoles: IFilterRole[];
|
||||
|
||||
/**
|
||||
* Constructor method.
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { FIELD_TYPE } from './constants';
|
||||
import { DynamicFilterAbstractor } from './DynamicFilterAbstractor';
|
||||
import { DynamicFilterRoleAbstractor } from './DynamicFilterRoleAbstractor';
|
||||
|
||||
interface ISortRole {
|
||||
fieldKey: string;
|
||||
order: string;
|
||||
}
|
||||
|
||||
export class DynamicFilterSortBy extends DynamicFilterAbstractor {
|
||||
export class DynamicFilterSortBy extends DynamicFilterRoleAbstractor {
|
||||
private sortRole: ISortRole = {};
|
||||
|
||||
/**
|
||||
@@ -36,7 +37,7 @@ export class DynamicFilterSortBy extends DynamicFilterAbstractor {
|
||||
* @param field
|
||||
* @returns {string}
|
||||
*/
|
||||
private getFieldComparatorRelationColumn = (field): string => {
|
||||
protected getFieldComparatorRelationColumn(field: any): string {
|
||||
const relation = this.model.relationMappings[field.relationKey];
|
||||
|
||||
if (relation) {
|
||||
@@ -46,7 +47,7 @@ export class DynamicFilterSortBy extends DynamicFilterAbstractor {
|
||||
return `${relationModel.tableName}.${relationField.column}`;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the comparator field column.
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import { omit } from 'lodash';
|
||||
import { IView, IViewRole } from '@/interfaces';
|
||||
import { DynamicFilterAbstractor } from './DynamicFilterAbstractor';
|
||||
import { DynamicFilterRoleAbstractor } from './DynamicFilterRoleAbstractor';
|
||||
|
||||
export class DynamicFilterViews extends DynamicFilterAbstractor {
|
||||
export class DynamicFilterViews extends DynamicFilterRoleAbstractor {
|
||||
private viewSlug: string;
|
||||
private logicExpression: string;
|
||||
private filterRoles: IViewRole[];
|
||||
private viewColumns = [];
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { DynamicListService } from './DynamicList.service';
|
||||
import { DynamicListCustomView } from './DynamicListCustomView.service';
|
||||
import { DynamicListSortBy } from './DynamicListSortBy.service';
|
||||
import { DynamicListSearch } from './DynamicListSearch.service';
|
||||
import { DynamicListFilterRoles } from './DynamicListFilterRoles.service';
|
||||
|
||||
@Module({
|
||||
providers: [
|
||||
DynamicListService,
|
||||
DynamicListCustomView,
|
||||
DynamicListSortBy,
|
||||
DynamicListSearch,
|
||||
DynamicListFilterRoles,
|
||||
],
|
||||
exports: [DynamicListService],
|
||||
})
|
||||
export class DynamicListModule {}
|
||||
@@ -1,18 +1,15 @@
|
||||
import { castArray, isEmpty } from 'lodash';
|
||||
import {
|
||||
IDynamicListFilter,
|
||||
IDynamicListService,
|
||||
} from './DynamicFilter/DynamicFilter.types';
|
||||
import { DynamicListSortBy } from './DynamicListSortBy';
|
||||
import { DynamicListSearch } from './DynamicListSearch';
|
||||
import { DynamicListCustomView } from './DynamicListCustomView';
|
||||
import { IDynamicListFilter } from './DynamicFilter/DynamicFilter.types';
|
||||
import { DynamicListSortBy } from './DynamicListSortBy.service';
|
||||
import { DynamicListSearch } from './DynamicListSearch.service';
|
||||
import { DynamicListCustomView } from './DynamicListCustomView.service';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DynamicListFilterRoles } from './DynamicListFilterRoles';
|
||||
import { DynamicListFilterRoles } from './DynamicListFilterRoles.service';
|
||||
import { DynamicFilter } from './DynamicFilter';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
|
||||
@Injectable()
|
||||
export class DynamicListService implements IDynamicListService {
|
||||
export class DynamicListService {
|
||||
constructor(
|
||||
private dynamicListFilterRoles: DynamicListFilterRoles,
|
||||
private dynamicListSearch: DynamicListSearch,
|
||||
@@ -44,7 +41,10 @@ export class DynamicListService implements IDynamicListService {
|
||||
* @param {IModel} model - Model.
|
||||
* @param {IDynamicListFilter} filter - Dynamic filter DTO.
|
||||
*/
|
||||
public dynamicList = async (model: BaseModel, filter: IDynamicListFilter) => {
|
||||
public dynamicList = async (
|
||||
model: typeof BaseModel,
|
||||
filter: IDynamicListFilter,
|
||||
) => {
|
||||
const dynamicFilter = new DynamicFilter(model);
|
||||
|
||||
// Parses the filter object.
|
||||
@@ -90,7 +90,9 @@ export class DynamicListService implements IDynamicListService {
|
||||
* Parses stringified filter roles.
|
||||
* @param {string} stringifiedFilterRoles - Stringified filter roles.
|
||||
*/
|
||||
public parseStringifiedFilter = (filterRoles: IDynamicListFilter) => {
|
||||
public parseStringifiedFilter<T extends IDynamicListFilter>(
|
||||
filterRoles: T,
|
||||
): T {
|
||||
return {
|
||||
...filterRoles,
|
||||
filterRoles: filterRoles.stringifiedFilterRoles
|
||||
@@ -1 +0,0 @@
|
||||
export class DynamicListAbstract {}
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DynamicListAbstract } from './DynamicListAbstract';
|
||||
import { ERRORS } from './constants';
|
||||
import { DynamicFilterViews } from './DynamicFilter';
|
||||
import { ServiceError } from '../Items/ServiceError';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { DynamicListServiceAbstract } from './DynamicListServiceAbstract';
|
||||
|
||||
@Injectable()
|
||||
export class DynamicListCustomView extends DynamicListAbstract {
|
||||
export class DynamicListCustomView extends DynamicListServiceAbstract {
|
||||
/**
|
||||
* Retreive custom view or throws error not found.
|
||||
* @param {number} tenantId
|
||||
@@ -30,7 +30,7 @@ export class DynamicListCustomView extends DynamicListAbstract {
|
||||
* Dynamic list custom view.
|
||||
* @param {IModel} model
|
||||
* @param {number} customViewId
|
||||
* @returns
|
||||
* @returns {DynamicFilterRoleAbstractor}
|
||||
*/
|
||||
public dynamicListCustomView = async (
|
||||
dynamicFilter: any,
|
||||
@@ -40,6 +40,7 @@ export class DynamicListCustomView extends DynamicListAbstract {
|
||||
|
||||
// Retrieve the custom view or throw not found.
|
||||
const view = await this.getCustomViewOrThrowError(customViewSlug, model);
|
||||
|
||||
return new DynamicFilterViews(view);
|
||||
};
|
||||
}
|
||||
@@ -2,14 +2,14 @@ import * as R from 'ramda';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import validator from 'is-my-json-valid';
|
||||
import { IFilterRole } from './DynamicFilter/DynamicFilter.types';
|
||||
import { DynamicListAbstract } from './DynamicListAbstract';
|
||||
import { DynamicFilterAdvancedFilter } from './DynamicFilter/DynamicFilterAdvancedFilter';
|
||||
import { ERRORS } from './constants';
|
||||
import { ServiceError } from '../Items/ServiceError';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { DynamicFilterRoleAbstractor } from './DynamicFilter/DynamicFilterRoleAbstractor';
|
||||
|
||||
@Injectable()
|
||||
export class DynamicListFilterRoles extends DynamicListAbstract {
|
||||
export class DynamicListFilterRoles extends DynamicFilterRoleAbstractor {
|
||||
/**
|
||||
* Validates filter roles schema.
|
||||
* @param {IFilterRole[]} filterRoles - Filter roles.
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DynamicListAbstract } from './DynamicListAbstract';
|
||||
import { DynamicFilterSearch } from './DynamicFilter/DynamicFilterSearch';
|
||||
import { DynamicListServiceAbstract } from './DynamicListServiceAbstract';
|
||||
|
||||
@Injectable()
|
||||
export class DynamicListSearch extends DynamicListAbstract {
|
||||
export class DynamicListSearch extends DynamicListServiceAbstract {
|
||||
/**
|
||||
* Dynamic list filter roles.
|
||||
* @param {string} searchKeyword - Search keyword.
|
||||
@@ -0,0 +1 @@
|
||||
export class DynamicListServiceAbstract {}
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { DynamicListAbstract } from './DynamicListAbstract';
|
||||
import { ISortOrder } from './DynamicFilter/DynamicFilter.types';
|
||||
import { ERRORS } from './constants';
|
||||
import { DynamicFilterSortBy } from './DynamicFilter';
|
||||
import { ServiceError } from '../Items/ServiceError';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { DynamicFilterRoleAbstractor } from './DynamicFilter/DynamicFilterRoleAbstractor';
|
||||
|
||||
@Injectable()
|
||||
export class DynamicListSortBy extends DynamicListAbstract {
|
||||
export class DynamicListSortBy extends DynamicFilterRoleAbstractor {
|
||||
/**
|
||||
* Dynamic list sort by.
|
||||
* @param {BaseModel} model
|
||||
@@ -0,0 +1,26 @@
|
||||
import { BaseModel } from '@/models/Model';
|
||||
|
||||
export const CustomViewBaseModel = (Model: typeof BaseModel) =>
|
||||
class extends Model {
|
||||
/**
|
||||
* Retrieve the default custom views, roles and columns.
|
||||
*/
|
||||
static get defaultViews() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the default view by the given slug.
|
||||
*/
|
||||
static getDefaultViewBySlug(viewSlug) {
|
||||
return this.defaultViews.find((view) => view.slug === viewSlug) || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the default views.
|
||||
* @returns {IView[]}
|
||||
*/
|
||||
static getDefaultViews() {
|
||||
return this.defaultViews;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,93 @@
|
||||
import { get } from 'lodash';
|
||||
import {
|
||||
IModelMeta,
|
||||
IModelMetaField,
|
||||
IModelMetaDefaultSort,
|
||||
} from '@/interfaces/Model';
|
||||
import { BaseModel } from '@/models/Model';
|
||||
|
||||
const defaultModelMeta = {
|
||||
fields: {},
|
||||
fields2: {},
|
||||
};
|
||||
|
||||
export interface IMetadataModel extends BaseModel {
|
||||
meta: IModelMeta;
|
||||
parsedMeta: IModelMeta;
|
||||
fields: { [key: string]: IModelMetaField };
|
||||
defaultSort: IModelMetaDefaultSort;
|
||||
defaultFilterField: string;
|
||||
|
||||
getField(key: string, attribute?: string): IModelMetaField;
|
||||
getMeta(key?: string): IModelMeta;
|
||||
}
|
||||
|
||||
type GConstructor<T = {}> = new (...args: any[]) => T;
|
||||
|
||||
export const MetadataModelMixin = <T extends GConstructor<BaseModel>>(
|
||||
Model: T,
|
||||
) =>
|
||||
class ModelSettings extends Model {
|
||||
/**
|
||||
* Retrieve the model meta.
|
||||
* @returns {IModelMeta}
|
||||
*/
|
||||
static get meta(): IModelMeta {
|
||||
throw new Error('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parsed meta merged with default emta.
|
||||
* @returns {IModelMeta}
|
||||
*/
|
||||
static get parsedMeta(): IModelMeta {
|
||||
return {
|
||||
...defaultModelMeta,
|
||||
...this.meta,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve specific model field meta of the given field key.
|
||||
* @param {string} key
|
||||
* @returns {IModelMetaField}
|
||||
*/
|
||||
public static getField(key: string, attribute?: string): IModelMetaField {
|
||||
const field = get(this.meta.fields, key);
|
||||
|
||||
return attribute ? get(field, attribute) : field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the specific model meta.
|
||||
* @param {string} key
|
||||
* @returns
|
||||
*/
|
||||
public static getMeta(key?: string) {
|
||||
return key ? get(this.parsedMeta, key) : this.parsedMeta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the model meta fields.
|
||||
* @return {{ [key: string]: IModelMetaField }}
|
||||
*/
|
||||
public static get fields(): { [key: string]: IModelMetaField } {
|
||||
return this.getMeta('fields');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the model default sort settings.
|
||||
* @return {IModelMetaDefaultSort}
|
||||
*/
|
||||
public static get defaultSort(): IModelMetaDefaultSort {
|
||||
return this.getMeta('defaultSort');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the default filter field key.
|
||||
* @return {string}
|
||||
*/
|
||||
public static get defaultFilterField(): string {
|
||||
return this.getMeta('defaultFilterField');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
import { BaseModel } from '@/models/Model';
|
||||
import { IModelMeta } from '@/interfaces/Model';
|
||||
import { ISearchRole } from '../DynamicFilter.types';
|
||||
|
||||
type GConstructor<T = {}> = new (...args: any[]) => T;
|
||||
|
||||
export const SearchableBaseModelMixin = <T extends GConstructor<BaseModel>>(
|
||||
Model: T,
|
||||
) =>
|
||||
class SearchableBaseModel extends Model {
|
||||
/**
|
||||
* Searchable model.
|
||||
*/
|
||||
static get searchable(): IModelMeta {
|
||||
throw true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search roles.
|
||||
*/
|
||||
static get searchRoles(): ISearchRole[] {
|
||||
return [];
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
import { ISortOrder } from '@/interfaces/Model';
|
||||
import { IFilterRole } from '../DynamicFilter/DynamicFilter.types';
|
||||
|
||||
export interface IDynamicListFilter {
|
||||
customViewId?: number;
|
||||
filterRoles?: IFilterRole[];
|
||||
columnSortBy: ISortOrder;
|
||||
sortOrder: string;
|
||||
stringifiedFilterRoles: string;
|
||||
searchKeyword?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user