identity-admin 1.27.2 → 1.27.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,6 +41,8 @@ const ReportsGenerator_1 = __importDefault(require("../helpers/ReportsGenerator"
41
41
  const IUserActionsLog_1 = require("../models/userActionsLog/IUserActionsLog");
42
42
  const UserActionsLog_1 = __importDefault(require("../models/userActionsLog/UserActionsLog"));
43
43
  const PermissionResource_1 = require("../helpers/Permissions/PermissionResource");
44
+ const RecordsCounter_1 = require("../helpers/RecordsCounter");
45
+ const FilterQueryHelper_1 = require("../helpers/FilterQueryHelper");
44
46
  let DashboardController = DashboardController_1 = class DashboardController {
45
47
  constructor(resource, repository, resources, modelConfigurations) {
46
48
  this.resource = resource;
@@ -451,19 +453,23 @@ let DashboardController = DashboardController_1 = class DashboardController {
451
453
  populate: modifiedPopulatedObject,
452
454
  });
453
455
  var documents = [];
454
- var documents = [];
455
456
  for (var i = 0; i < records.length; i++) {
456
457
  const record = records[i];
457
458
  const recordFlatten = record.toObject();
458
459
  documents.push(recordFlatten);
459
460
  }
460
461
  if (crudOperations && crudOperations.index && crudOperations.index.after) {
461
- documents = yield crudOperations.index.after(req, documents, currentUser);
462
+ try {
463
+ documents = yield crudOperations.index.after(req, documents, currentUser);
464
+ }
465
+ catch (e) {
466
+ documents = yield crudOperations.index.after(req, records, currentUser);
467
+ }
462
468
  }
463
469
  const fields = req.query.fields.map((v) => JSON.parse(v));
464
470
  const fileType = req.query.fileType;
465
471
  if (fileType === 'xlsx') {
466
- const buffer = ReportsGenerator_1.default.CreateXlsxFile(fields, documents, modelName, language);
472
+ const buffer = ReportsGenerator_1.default.CreateXlsxFile(fields, documents, modelName, language, resource);
467
473
  res.writeHead(200, {
468
474
  'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
469
475
  'Content-disposition': 'attachment;filename=' + `${modelName}.xlsx`,
@@ -472,7 +478,7 @@ let DashboardController = DashboardController_1 = class DashboardController {
472
478
  res.end(buffer);
473
479
  }
474
480
  if (fileType === 'pdf') {
475
- const buffer = yield ReportsGenerator_1.default.CreatePdfFile(fields, documents, modelName, language);
481
+ const buffer = yield ReportsGenerator_1.default.CreatePdfFile(fields, documents, modelName, language, resource);
476
482
  res.writeHead(200, {
477
483
  'Content-Type': 'application/pdf',
478
484
  'Content-disposition': 'attachment;filename=' + `${modelName}.pdf`,
@@ -522,6 +528,7 @@ let DashboardController = DashboardController_1 = class DashboardController {
522
528
  if (!record) {
523
529
  return ResponseUtils_1.default.send(res, 404, 'record not found');
524
530
  }
531
+ const recordPageResult = yield RecordsCounter_1.RecordsCounter.count(req, resource, repository, record, this.modelConfigurations);
525
532
  record = record.toObject();
526
533
  //record = await this.getExtras(record._id.toString(), record, this.getExtraRepository())
527
534
  record = yield ResourceHelper_1.default.addExtraFields(modifiedResource.showProperties, modifiedResource.properties.model, record, StringUtils_1.default.lowerCaseFirstLetter(modifiedResource.properties.modelName), resource);
@@ -530,7 +537,7 @@ let DashboardController = DashboardController_1 = class DashboardController {
530
537
  if (afterMethod && record) {
531
538
  extras = yield afterMethod(req, record);
532
539
  }
533
- return ResponseUtils_1.default.ok(res, Object.assign(Object.assign({}, extras), { record: record ? record : null }));
540
+ return ResponseUtils_1.default.ok(res, Object.assign(Object.assign({}, extras), { record: record ? record : null, numberOfRecords: recordPageResult === null || recordPageResult === void 0 ? void 0 : recordPageResult.recordsCount, recordIndex: recordPageResult === null || recordPageResult === void 0 ? void 0 : recordPageResult.recordIndex }));
534
541
  });
535
542
  }
536
543
  deleteAll(req, res) {
@@ -673,11 +680,12 @@ let DashboardController = DashboardController_1 = class DashboardController {
673
680
  ? resource.properties.crudOperations.show.nextPreviousButtonHandler
674
681
  : undefined;
675
682
  var neighbor;
683
+ const filter = yield FilterQueryHelper_1.FilterQueryHelper.getFilter(req, resource, this.modelConfigurations);
676
684
  if (neighborRecordType === helpers_1.NeighborTypes.NEXT) {
677
- neighbor = yield (model === null || model === void 0 ? void 0 : model.findOne(handler ? yield handler(req, nextQuery, currentUser, neighborRecordType) : nextQuery).sort(nextSortQuery).limit(1));
685
+ neighbor = yield (model === null || model === void 0 ? void 0 : model.findOne(handler ? yield handler(req, nextQuery, currentUser, neighborRecordType) : Object.assign(Object.assign({}, nextQuery), filter)).sort(nextSortQuery).limit(1));
678
686
  }
679
687
  else {
680
- neighbor = yield (model === null || model === void 0 ? void 0 : model.findOne(handler ? yield handler(req, prevQuery, currentUser, neighborRecordType) : prevQuery).sort(previousSortQuery).limit(1));
688
+ neighbor = yield (model === null || model === void 0 ? void 0 : model.findOne(handler ? yield handler(req, prevQuery, currentUser, neighborRecordType) : Object.assign(Object.assign({}, prevQuery), filter)).sort(previousSortQuery).limit(1));
681
689
  }
682
690
  const hasNeighbor = record && neighbor && neighbor._id ? true : false;
683
691
  const neighborRecordId = hasNeighbor ? neighbor._id : undefined;
@@ -0,0 +1,9 @@
1
+ import { IRequest } from '../middlewares/isAuth';
2
+ import { IResourceFile } from '../types/IResourceFile';
3
+ import { IModelConfigurationDocument } from '../models/modelConfiguration/IModelConfigurations';
4
+ export declare class FilterQueryHelper {
5
+ static getFilter(req: IRequest, resource: IResourceFile, modelConfigurations?: Map<string, IModelConfigurationDocument> | undefined): Promise<{
6
+ [key: string]: any;
7
+ } | undefined>;
8
+ private static getSearchableSubStringFilter;
9
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.FilterQueryHelper = void 0;
16
+ const mongoose_1 = __importDefault(require("mongoose"));
17
+ const FiltersHelper_1 = __importDefault(require("./FiltersHelper"));
18
+ const LocalizedStringHelper_1 = __importDefault(require("./LocalizedStringHelper"));
19
+ const ResourceHelper_1 = __importDefault(require("./ResourceHelper"));
20
+ class FilterQueryHelper {
21
+ static getFilter(req, resource, modelConfigurations) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const searchableSubString = req.query.filter ? new RegExp(req.query.filter, 'i') : undefined;
24
+ const scope = req.query.scope;
25
+ const currentUser = req.user;
26
+ const filtersQuery = req.query.filters;
27
+ const filters = filtersQuery ? filtersQuery.split('^^') : undefined;
28
+ if (!resource) {
29
+ return;
30
+ }
31
+ if (!currentUser) {
32
+ return;
33
+ }
34
+ const sort = req.query.order;
35
+ const sortBy = req.query.orderBy;
36
+ const sortQuery = {};
37
+ sortQuery[sortBy] = sort;
38
+ if (sortBy !== '_id') {
39
+ sortQuery._id = 'asc';
40
+ }
41
+ var filter = {};
42
+ if (scope && resource.properties.filters && resource.properties.filters.scopes && resource.properties.filters.scopes.isAccessible) {
43
+ if (resource.properties.filters.scopes.manual) {
44
+ filter = yield resource.properties.filters.scopes.manual.handler(filter, scope, currentUser);
45
+ }
46
+ else if (resource.properties.filters.scopes.auto) {
47
+ const key = resource.properties.filters.scopes.auto.key;
48
+ if (key) {
49
+ filter[key] = scope;
50
+ }
51
+ }
52
+ }
53
+ if (searchableSubString) {
54
+ filter = this.getSearchableSubStringFilter(resource, filter, searchableSubString, modelConfigurations);
55
+ }
56
+ filter = yield FiltersHelper_1.default.appendFilters(filter, filters, resource);
57
+ const crudOperations = resource.properties.crudOperations;
58
+ if (crudOperations && crudOperations.index && crudOperations.index.before) {
59
+ filter = yield crudOperations.index.before(req, filter, currentUser);
60
+ }
61
+ return filter;
62
+ });
63
+ }
64
+ static getSearchableSubStringFilter(resource, filter, subString, modelConfigurations) {
65
+ const schema = resource.properties.resource.schema.paths;
66
+ const searchBy = ResourceHelper_1.default.getSchemaTitle(schema, resource, modelConfigurations === null || modelConfigurations === void 0 ? void 0 : modelConfigurations.get(resource.properties.modelName));
67
+ if (searchBy === '_id') {
68
+ if (!mongoose_1.default.isValidObjectId(subString.source)) {
69
+ return filter;
70
+ }
71
+ filter[searchBy] = subString.source;
72
+ return filter;
73
+ }
74
+ if (LocalizedStringHelper_1.default.checkLocalizedStringType(resource, searchBy)) {
75
+ filter.$or = [LocalizedStringHelper_1.default.getFilterObject(searchBy, '0', subString), LocalizedStringHelper_1.default.getFilterObject(searchBy, '1', subString)];
76
+ }
77
+ else {
78
+ filter[searchBy] = subString;
79
+ }
80
+ return filter;
81
+ }
82
+ }
83
+ exports.FilterQueryHelper = FilterQueryHelper;
@@ -0,0 +1,10 @@
1
+ import { IRequest } from '../middlewares/isAuth';
2
+ import Repository from '../repositories/Repository';
3
+ import { IResourceFile } from '../types/IResourceFile';
4
+ import { IModelConfigurationDocument } from '../models/modelConfiguration/IModelConfigurations';
5
+ export declare class RecordsCounter {
6
+ static count(req: IRequest, resource: IResourceFile, repository: Repository<any>, currentRecord: any, modelConfigurations?: Map<string, IModelConfigurationDocument> | undefined): Promise<{
7
+ recordsCount: number;
8
+ recordIndex: number;
9
+ }>;
10
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RecordsCounter = void 0;
13
+ const FilterQueryHelper_1 = require("./FilterQueryHelper");
14
+ class RecordsCounter {
15
+ static count(req, resource, repository, currentRecord, modelConfigurations) {
16
+ return __awaiter(this, void 0, void 0, function* () {
17
+ const sort = req.query.order;
18
+ const sortBy = req.query.orderBy;
19
+ const sortQuery = {};
20
+ sortQuery[sortBy] = sort;
21
+ if (sortBy !== '_id') {
22
+ sortQuery._id = 'asc';
23
+ }
24
+ const filter = yield FilterQueryHelper_1.FilterQueryHelper.getFilter(req, resource, modelConfigurations);
25
+ const comparisonQuery = { $or: [] };
26
+ comparisonQuery.$or.push({ [sortBy]: { [sort === 'asc' ? '$lt' : '$gt']: currentRecord[sortBy] } }, { [sortBy]: currentRecord[sortBy], _id: { $lt: currentRecord._id } });
27
+ const recordIndex = (yield repository.count(Object.assign(Object.assign({}, filter), comparisonQuery))) + 1;
28
+ const recordsCount = yield repository.count(filter);
29
+ return { recordsCount, recordIndex };
30
+ });
31
+ }
32
+ }
33
+ exports.RecordsCounter = RecordsCounter;
@@ -1,5 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { FieldTypes } from '../types/helpers';
3
+ import { IResourceFile } from '../types/IResourceFile';
3
4
  export interface Columns {
4
5
  label: string;
5
6
  value: string;
@@ -16,10 +17,10 @@ export interface ILanguage {
16
17
  value?: string;
17
18
  }
18
19
  export default class ReportsGenerator {
19
- static CreateXlsxFile(columns: Columns[], data: any[], name: string, language: Languages): Buffer;
20
- static CreatePdfFile(columns: Columns[], data: any[], name: string, language: Languages): Promise<Buffer>;
21
- static getRows(columns: Columns[], data: any[], language: Languages): any[][];
22
- static getFieldValue(field: Columns, row: any, language: Languages): any;
20
+ static CreateXlsxFile(columns: Columns[], data: any[], name: string, language: Languages, resource: IResourceFile): Buffer;
21
+ static CreatePdfFile(columns: Columns[], data: any[], name: string, language: Languages, resource: IResourceFile): Promise<Buffer>;
22
+ static getRows(columns: Columns[], data: any[], language: Languages, resource: IResourceFile): any[][];
23
+ static getFieldValue(field: Columns, row: any, language: Languages, resource: IResourceFile): any;
23
24
  static checkLocalizedStringExistence(columns: Columns[]): boolean;
24
25
  static getReferenceValueByTitleType(rowValue: any, language: Languages, titleType?: FieldTypes): any;
25
26
  }
@@ -42,15 +42,16 @@ const helpers_1 = require("../types/helpers");
42
42
  const pdfjs_1 = __importDefault(require("pdfjs"));
43
43
  const fs = __importStar(require("fs"));
44
44
  const LocalizedStringHelper_1 = __importDefault(require("./LocalizedStringHelper"));
45
+ const DateUtils_1 = require("../utils/DateUtils");
45
46
  var Languages;
46
47
  (function (Languages) {
47
48
  Languages["ARABIC"] = "ar";
48
49
  Languages["ENGLISH"] = "en";
49
50
  })(Languages = exports.Languages || (exports.Languages = {}));
50
51
  class ReportsGenerator {
51
- static CreateXlsxFile(columns, data, name, language) {
52
+ static CreateXlsxFile(columns, data, name, language, resource) {
52
53
  const header = columns.map((field) => field.label);
53
- const rows = this.getRows(columns, data, language);
54
+ const rows = this.getRows(columns, data, language, resource);
54
55
  const sheets = [
55
56
  {
56
57
  name,
@@ -61,9 +62,9 @@ class ReportsGenerator {
61
62
  const buffer = node_xlsx_1.default.build(sheets);
62
63
  return buffer;
63
64
  }
64
- static CreatePdfFile(columns, data, name, language) {
65
+ static CreatePdfFile(columns, data, name, language, resource) {
65
66
  return __awaiter(this, void 0, void 0, function* () {
66
- const rows = this.getRows(columns, data, language);
67
+ const rows = this.getRows(columns, data, language, resource);
67
68
  const ArabicFont = new pdfjs_1.default.Font(fs.readFileSync(__dirname + '/../assets/Amiri-Regular.ttf'));
68
69
  const localizedStringIsExisted = this.checkLocalizedStringExistence(columns);
69
70
  const doc = new pdfjs_1.default.Document({
@@ -75,28 +76,43 @@ class ReportsGenerator {
75
76
  borderWidth: 1,
76
77
  });
77
78
  const header = table.header({
78
- backgroundColor: 0x000,
79
- color: 0xffffff,
79
+ backgroundColor: 0xdddddd,
80
+ color: 0x333333,
81
+ paddingBottom: 5,
82
+ paddingTop: 5,
80
83
  });
81
- columns.map((field) => header.cell(field.label));
84
+ columns.map((field) => header.cell(field.label, {
85
+ textAlign: 'center',
86
+ alignment: 'center',
87
+ }));
82
88
  rows.forEach((row) => {
83
89
  const tableRow = table.row();
84
- row.map((cell) => tableRow.cell(`${cell !== null && cell !== void 0 ? cell : '---'}`));
90
+ row.map((cell) => tableRow.cell(`${cell !== null && cell !== void 0 ? cell : '---'}`, {
91
+ textAlign: 'center',
92
+ alignment: 'center',
93
+ paddingBottom: 5,
94
+ paddingTop: 5,
95
+ }));
85
96
  });
86
97
  return yield doc.asBuffer();
87
98
  });
88
99
  }
89
- static getRows(columns, data, language) {
90
- const rows = data.map((row) => columns.map((field) => this.getFieldValue(field, row, language)));
100
+ static getRows(columns, data, language, resource) {
101
+ const rows = data.map((row) => columns.map((field) => this.getFieldValue(field, row, language, resource)));
91
102
  return rows;
92
103
  }
93
- static getFieldValue(field, row, language) {
104
+ static getFieldValue(field, row, language, resource) {
94
105
  var _a, _b, _c;
106
+ const schema = resource.properties.model;
107
+ const fieldProps = schema ? schema[field.value] : undefined;
95
108
  switch (field.type) {
96
109
  case helpers_1.FieldTypes.OBJECTID:
97
110
  return (_b = (_a = (0, lodash_1.get)(row, field.value)) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '';
98
111
  case helpers_1.FieldTypes.LOCALIZEDSTRING:
99
112
  return LocalizedStringHelper_1.default.getLocalizedValue(row, field.value, language);
113
+ case helpers_1.FieldTypes.DATE:
114
+ const withTime = fieldProps && fieldProps.withTime ? true : false;
115
+ return DateUtils_1.DateUtils.getIsoDate((0, lodash_1.get)(row, field.value), withTime);
100
116
  case helpers_1.FieldTypes.REFERENCE:
101
117
  const valuePath = (_c = field.titlePath) !== null && _c !== void 0 ? _c : field.value;
102
118
  const rowValue = (0, lodash_1.get)(row, valuePath);
@@ -0,0 +1,7 @@
1
+ import { Languages } from '../helpers/ReportsGenerator';
2
+ export declare class DateUtils {
3
+ static addBegginingZero(value: number): string;
4
+ static localizingToArabicAMPM(amOrPm: string): "صباحاً" | "مساءاً";
5
+ static formatAMPM(date: Date, language: Languages): string;
6
+ static getIsoDate(date: Date | string, withTime: boolean): string;
7
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DateUtils = void 0;
4
+ const ReportsGenerator_1 = require("../helpers/ReportsGenerator");
5
+ class DateUtils {
6
+ static addBegginingZero(value) {
7
+ return value % 10 === value ? `0${value.toString()}` : value.toString();
8
+ }
9
+ static localizingToArabicAMPM(amOrPm) {
10
+ switch (amOrPm) {
11
+ case 'am':
12
+ return 'صباحاً';
13
+ case 'pm':
14
+ return 'مساءاً';
15
+ default:
16
+ return 'صباحاً';
17
+ }
18
+ }
19
+ static formatAMPM(date, language) {
20
+ var hours = date.getHours();
21
+ var minutes = date.getMinutes();
22
+ var ampm = hours >= 12 ? 'pm' : 'am';
23
+ if (language === ReportsGenerator_1.Languages.ARABIC) {
24
+ ampm = this.localizingToArabicAMPM(ampm);
25
+ }
26
+ hours = hours % 12;
27
+ hours = hours ? hours : 12;
28
+ minutes = minutes < 10 ? '0' + minutes : minutes;
29
+ var strTime = hours + ':' + minutes + ' ' + ampm;
30
+ return strTime;
31
+ }
32
+ static getIsoDate(date, withTime) {
33
+ date = new Date(date);
34
+ const month = date.getMonth() + 1;
35
+ const day = date.getDate();
36
+ const mappedMonth = this.addBegginingZero(month);
37
+ const mappedDay = this.addBegginingZero(day);
38
+ var isoDate = date.getFullYear() + '-' + mappedMonth + '-' + mappedDay;
39
+ if (withTime) {
40
+ isoDate = isoDate + ' ' + this.formatAMPM(date, ReportsGenerator_1.Languages.ENGLISH);
41
+ }
42
+ return isoDate;
43
+ }
44
+ }
45
+ exports.DateUtils = DateUtils;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "identity-admin",
3
- "version": "1.27.2",
3
+ "version": "1.27.4",
4
4
  "description": "",
5
5
  "main": "lib/Dashboard.js",
6
6
  "types": "lib/Dashbord.d.ts",