identity-admin 1.25.17 → 1.25.19

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.
@@ -34,6 +34,7 @@ export default class DashboardController {
34
34
  index(req: IRequest, res: Response): Promise<void | Response<any, Record<string, any>>>;
35
35
  create(req: IRequest, res: Response): Promise<void>;
36
36
  update(req: IRequest, res: Response): Promise<void | Response<any, Record<string, any>>>;
37
+ report(req: IRequest, res: Response): Promise<void>;
37
38
  show(req: IRequest, res: Response): Promise<void | Response<any, Record<string, any>>>;
38
39
  deleteAll(req: IRequest, res: Response): Promise<void | Response<any, Record<string, any>>>;
39
40
  delete(req: IRequest, res: Response): Promise<void | Response<any, Record<string, any>>>;
@@ -37,6 +37,7 @@ const LocalizedStringHelper_1 = __importDefault(require("../helpers/LocalizedStr
37
37
  const ActionsGenerator_1 = __importDefault(require("../helpers/ActionsGenerator"));
38
38
  const helpers_1 = require("../types/helpers");
39
39
  const PopulationHelper_1 = require("../helpers/PopulationHelper");
40
+ const ReportsGenerator_1 = __importDefault(require("../helpers/ReportsGenerator"));
40
41
  let DashboardController = DashboardController_1 = class DashboardController {
41
42
  constructor(resource, repository, resources, modelConfigurations) {
42
43
  this.resource = resource;
@@ -355,6 +356,108 @@ let DashboardController = DashboardController_1 = class DashboardController {
355
356
  });
356
357
  });
357
358
  }
359
+ report(req, res) {
360
+ var _a, _b, _c;
361
+ return __awaiter(this, void 0, void 0, function* () {
362
+ if (!this.validateRequest(req, res)) {
363
+ return;
364
+ }
365
+ const searchableSubString = req.query.filter
366
+ ? new RegExp(req.query.filter, "i")
367
+ : undefined;
368
+ const scope = req.query.scope;
369
+ const currentUser = req.user;
370
+ const modelName = req.params.resource;
371
+ const filtersQuery = req.query.filters;
372
+ const filters = filtersQuery
373
+ ? filtersQuery.split("^^")
374
+ : undefined;
375
+ const resource = (_a = this.resource) !== null && _a !== void 0 ? _a : (0, ResourceUtils_1.getResource)(modelName, (_b = this.resources) !== null && _b !== void 0 ? _b : []);
376
+ if (!resource) {
377
+ return ResponseUtils_1.default.notFound(res, "Resource not found", []);
378
+ }
379
+ if (!currentUser) {
380
+ return ResponseUtils_1.default.unauthorized(res);
381
+ }
382
+ const permissionCheck = resource.properties.isAllowed
383
+ ? yield resource.properties.isAllowed(currentUser)
384
+ : true;
385
+ if (!permissionCheck) {
386
+ return ResponseUtils_1.default.forbidden(res);
387
+ }
388
+ const repository = (_c = this.repository) !== null && _c !== void 0 ? _c : new Repository_1.default(resource.properties.resource);
389
+ const modifiedResource = ResourceGenerator_1.default.generate(resource, currentUser, undefined, this.modelConfigurations);
390
+ const sort = req.query.order;
391
+ const sortBy = req.query.orderBy;
392
+ const sortQuery = {};
393
+ sortQuery[sortBy] = sort;
394
+ if (sortBy !== "_id") {
395
+ sortQuery._id = "asc";
396
+ }
397
+ var filter = {};
398
+ if (scope &&
399
+ resource.properties.filters &&
400
+ resource.properties.filters.scopes &&
401
+ resource.properties.filters.scopes.isAccessible) {
402
+ if (resource.properties.filters.scopes.manual) {
403
+ filter = yield resource.properties.filters.scopes.manual.handler(filter, scope, currentUser);
404
+ }
405
+ else if (resource.properties.filters.scopes.auto) {
406
+ const key = resource.properties.filters.scopes.auto.key;
407
+ if (key) {
408
+ filter[key] = scope;
409
+ }
410
+ }
411
+ }
412
+ if (searchableSubString) {
413
+ filter = this.getSearchableSubStringFilter(resource, filter, searchableSubString);
414
+ }
415
+ filter = yield FiltersHelper_1.default.appendFilters(filter, filters, resource);
416
+ const crudOperations = resource.properties.crudOperations;
417
+ if (crudOperations && crudOperations.index && crudOperations.index.before) {
418
+ filter = yield crudOperations.index.before(req, filter, currentUser);
419
+ }
420
+ var records = [];
421
+ const populatedString = modifiedResource.properties.populatedString;
422
+ const populationHelper = new PopulationHelper_1.PopulationHelper(resource, PopulationHelper_1.PopulationType.LIST, populatedString);
423
+ const modifiedPopulatedObject = yield populationHelper.get();
424
+ records = yield repository.findMany({
425
+ sort: sortQuery,
426
+ filter,
427
+ populate: modifiedPopulatedObject,
428
+ });
429
+ var documents = [];
430
+ var documents = [];
431
+ for (var i = 0; i < records.length; i++) {
432
+ const record = records[i];
433
+ const recordFlatten = record.toObject();
434
+ documents.push(recordFlatten);
435
+ }
436
+ if (crudOperations && crudOperations.index && crudOperations.index.after) {
437
+ documents = yield crudOperations.index.after(req, documents, currentUser);
438
+ }
439
+ const fields = req.query.fields.map(v => JSON.parse(v));
440
+ const fileType = req.query.fileType;
441
+ if (fileType === 'xlsx') {
442
+ const buffer = ReportsGenerator_1.default.CreateXlsxFile(fields, documents, modelName);
443
+ res.writeHead(200, {
444
+ 'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
445
+ 'Content-disposition': 'attachment;filename=' + `${modelName}.xlsx`,
446
+ 'Content-Length': buffer.length,
447
+ });
448
+ res.end(buffer);
449
+ }
450
+ if (fileType === 'pdf') {
451
+ const buffer = yield ReportsGenerator_1.default.CreatePdfFile(fields, documents, modelName);
452
+ res.writeHead(200, {
453
+ 'Content-Type': 'application/pdf',
454
+ 'Content-disposition': 'attachment;filename=' + `${modelName}.pdf`,
455
+ 'Content-Length': buffer.length,
456
+ });
457
+ res.end(buffer);
458
+ }
459
+ });
460
+ }
358
461
  show(req, res) {
359
462
  var _a, _b, _c, _d, _e;
360
463
  return __awaiter(this, void 0, void 0, function* () {
@@ -572,6 +675,11 @@ __decorate([
572
675
  __param(0, (0, inversify_express_utils_1.request)()),
573
676
  __param(1, (0, inversify_express_utils_1.response)())
574
677
  ], DashboardController.prototype, "update", null);
678
+ __decorate([
679
+ (0, inversify_express_utils_1.httpGet)("/report"),
680
+ __param(0, (0, inversify_express_utils_1.request)()),
681
+ __param(1, (0, inversify_express_utils_1.response)())
682
+ ], DashboardController.prototype, "report", null);
575
683
  __decorate([
576
684
  (0, inversify_express_utils_1.httpGet)("/:id"),
577
685
  __param(0, (0, inversify_express_utils_1.request)()),
@@ -58,12 +58,14 @@ let ResourceController = class ResourceController {
58
58
  this.PermissionModel = PermissionModel;
59
59
  }
60
60
  index(req, res) {
61
+ var _a;
61
62
  return __awaiter(this, void 0, void 0, function* () {
62
63
  var modifiedResource = {};
63
64
  modifiedResource.modelParents = {};
64
65
  const currentUser = req.user;
65
66
  if (this.configurations) {
66
67
  modifiedResource.appConfigurations = this.configurations;
68
+ modifiedResource.appConfigurations.showMainActions = (_a = modifiedResource.appConfigurations.showMainActions) !== null && _a !== void 0 ? _a : true;
67
69
  }
68
70
  for (var i = 0; i < this.resourceFiles.length; i++) {
69
71
  const resource = this.resourceFiles[i];
@@ -72,16 +72,18 @@ class ActionsGenerator {
72
72
  return extraActionsObject;
73
73
  }
74
74
  static getActions(actions, currentUser, configuration) {
75
- var _a, _b, _c, _d, _e, _f;
75
+ var _a, _b, _c, _d, _e, _f, _g;
76
76
  var actionObject = {
77
77
  show: {
78
78
  isAccessible: ((_a = configuration === null || configuration === void 0 ? void 0 : configuration.actions) === null || _a === void 0 ? void 0 : _a.show) === false ? false : true,
79
+ isMainAction: true
79
80
  },
80
81
  new: {
81
82
  isAccessible: ((_b = configuration === null || configuration === void 0 ? void 0 : configuration.actions) === null || _b === void 0 ? void 0 : _b.new) === false ? false : true,
82
83
  },
83
84
  edit: {
84
85
  isAccessible: ((_c = configuration === null || configuration === void 0 ? void 0 : configuration.actions) === null || _c === void 0 ? void 0 : _c.edit) === false ? false : true,
86
+ isMainAction: true
85
87
  },
86
88
  delete: {
87
89
  isAccessible: ((_d = configuration === null || configuration === void 0 ? void 0 : configuration.actions) === null || _d === void 0 ? void 0 : _d.delete) === false ? false : true,
@@ -106,6 +108,8 @@ class ActionsGenerator {
106
108
  actionObject[key] = actions[key];
107
109
  }
108
110
  actionObject[key].reloadAfterAction = (_f = actions[key]) === null || _f === void 0 ? void 0 : _f.reloadAfterAction;
111
+ actionObject[key].isMainAction =
112
+ (_g = actions[key].isMainAction) !== null && _g !== void 0 ? _g : (key === "edit" || key === "show");
109
113
  }
110
114
  return actionObject;
111
115
  }
@@ -0,0 +1,11 @@
1
+ /// <reference types="node" />
2
+ import { FieldTypes } from '../types/helpers';
3
+ export interface Columns {
4
+ label: string;
5
+ value: string;
6
+ type: FieldTypes;
7
+ }
8
+ export default class ReportsGenerator {
9
+ static CreateXlsxFile(columns: Columns[], data: any[], name: string): Buffer;
10
+ static CreatePdfFile(columns: Columns[], data: any[], name: string): Promise<Buffer>;
11
+ }
@@ -0,0 +1,43 @@
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
+ const node_xlsx_1 = __importDefault(require("node-xlsx"));
16
+ const lodash_1 = require("lodash");
17
+ const helpers_1 = require("../types/helpers");
18
+ const renderer_1 = require("@react-pdf/renderer");
19
+ const ReportTemplate_1 = __importDefault(require("../pdf/ReportTemplate"));
20
+ class ReportsGenerator {
21
+ static CreateXlsxFile(columns, data, name) {
22
+ const header = columns.map((field) => field.label);
23
+ const rows = data.map((row) => columns.map((field) => (field.type === helpers_1.FieldTypes.OBJECTID ? (0, lodash_1.get)(row, field.value).toString() : (0, lodash_1.get)(row, field.value))));
24
+ const sheets = [
25
+ {
26
+ name,
27
+ data: [header, ...rows],
28
+ options: {},
29
+ },
30
+ ];
31
+ const buffer = node_xlsx_1.default.build(sheets);
32
+ return buffer;
33
+ }
34
+ static CreatePdfFile(columns, data, name) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ const header = columns.map((field) => field.label);
37
+ const rows = data.map((row) => columns.map((field) => (field.type === helpers_1.FieldTypes.OBJECTID ? (0, lodash_1.get)(row, field.value).toString() : (0, lodash_1.get)(row, field.value))));
38
+ const pdf = yield (0, renderer_1.renderToBuffer)((0, ReportTemplate_1.default)({ columns: header, rows }));
39
+ return pdf;
40
+ });
41
+ }
42
+ }
43
+ exports.default = ReportsGenerator;
@@ -0,0 +1,10 @@
1
+ import { FieldTypes } from "../types/helpers";
2
+ interface Columns {
3
+ label: string;
4
+ value: string;
5
+ type: FieldTypes;
6
+ }
7
+ export default class ReportsGenerator {
8
+ static CreateXlsxFile(columns: Columns[], data: any[], name: string): void;
9
+ }
10
+ export {};
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_xlsx_1 = __importDefault(require("node-xlsx"));
7
+ const lodash_1 = require("lodash");
8
+ const helpers_1 = require("../types/helpers");
9
+ class ReportsGenerator {
10
+ static CreateXlsxFile(columns, data, name) {
11
+ const header = columns.map(field => field.label);
12
+ const rows = data.map(row => columns.map(field => field.type === helpers_1.FieldTypes.OBJECTID ? (0, lodash_1.get)(row, field.value).toString() : (0, lodash_1.get)(row, field.value)));
13
+ const sheets = [{
14
+ name,
15
+ data: [header, ...rows],
16
+ options: {}
17
+ }];
18
+ const buffer = node_xlsx_1.default.build(sheets);
19
+ }
20
+ }
21
+ exports.default = ReportsGenerator;
@@ -0,0 +1,71 @@
1
+ import React from 'react';
2
+ export declare const styles: {
3
+ table: {
4
+ display: "flex";
5
+ width: string;
6
+ borderStyle: "solid";
7
+ borderWidth: number;
8
+ borderRightWidth: number;
9
+ borderBottomWidth: number;
10
+ };
11
+ tableRow: {
12
+ width: string;
13
+ margin: string;
14
+ flexDirection: "row";
15
+ };
16
+ tableCol: {
17
+ width: string;
18
+ borderStyle: "solid";
19
+ borderWidth: number;
20
+ borderLeftWidth: number;
21
+ borderTopWidth: number;
22
+ };
23
+ tableCell: {
24
+ width: string;
25
+ margin: string;
26
+ marginTop: number;
27
+ fontSize: number;
28
+ overflow: "hidden";
29
+ };
30
+ flexRow: {
31
+ display: "flex";
32
+ flexDirection: "row";
33
+ alignItems: "flex-start";
34
+ alignContent: "flex-start";
35
+ justifyContent: "flex-start";
36
+ marginTop: string;
37
+ };
38
+ detailsTitle: {
39
+ fontSize: string;
40
+ textAlign: "left";
41
+ color: string;
42
+ fontWeight: number;
43
+ marginBottom: string;
44
+ };
45
+ detailsBody: {
46
+ fontSize: string;
47
+ textAlign: "left";
48
+ color: string;
49
+ fontWeight: number;
50
+ marginBottom: string;
51
+ };
52
+ flexColumn: {
53
+ display: "flex";
54
+ flexDirection: "column";
55
+ alignItems: "flex-start";
56
+ alignContent: "flex-start";
57
+ justifyContent: "flex-start";
58
+ };
59
+ flexWrap: {
60
+ flexWrap: "wrap";
61
+ };
62
+ borderTopBottom: {
63
+ borderTop: string;
64
+ borderBottom: string;
65
+ padding: string;
66
+ };
67
+ };
68
+ export default function ReportTemplate({ columns, rows }: {
69
+ columns: string[];
70
+ rows: any[][];
71
+ }): React.JSX.Element;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.styles = void 0;
7
+ const react_1 = __importDefault(require("react"));
8
+ const renderer_1 = require("@react-pdf/renderer");
9
+ exports.styles = renderer_1.StyleSheet.create({
10
+ table: {
11
+ display: 'flex',
12
+ width: 'auto',
13
+ borderStyle: 'solid',
14
+ borderWidth: 1,
15
+ borderRightWidth: 0,
16
+ borderBottomWidth: 0,
17
+ },
18
+ tableRow: {
19
+ width: '100%',
20
+ margin: 'auto',
21
+ flexDirection: 'row',
22
+ },
23
+ tableCol: {
24
+ width: '100%',
25
+ borderStyle: 'solid',
26
+ borderWidth: 1,
27
+ borderLeftWidth: 0,
28
+ borderTopWidth: 0,
29
+ },
30
+ tableCell: {
31
+ width: '100%',
32
+ margin: 'auto',
33
+ marginTop: 5,
34
+ fontSize: 18,
35
+ overflow: 'hidden'
36
+ },
37
+ flexRow: {
38
+ display: 'flex',
39
+ flexDirection: 'row',
40
+ alignItems: 'flex-start',
41
+ alignContent: 'flex-start',
42
+ justifyContent: 'flex-start',
43
+ marginTop: '24t',
44
+ },
45
+ detailsTitle: {
46
+ fontSize: '18',
47
+ textAlign: 'left',
48
+ color: '#637381',
49
+ fontWeight: 500,
50
+ marginBottom: '8',
51
+ },
52
+ detailsBody: {
53
+ fontSize: '18',
54
+ textAlign: 'left',
55
+ color: '#000',
56
+ fontWeight: 500,
57
+ marginBottom: '8',
58
+ },
59
+ flexColumn: {
60
+ display: 'flex',
61
+ flexDirection: 'column',
62
+ alignItems: 'flex-start',
63
+ alignContent: 'flex-start',
64
+ justifyContent: 'flex-start',
65
+ },
66
+ flexWrap: {
67
+ flexWrap: 'wrap',
68
+ },
69
+ borderTopBottom: {
70
+ borderTop: '2px solid #000',
71
+ borderBottom: '2px solid #000',
72
+ padding: '10px',
73
+ },
74
+ });
75
+ function ReportTemplate({ columns, rows }) {
76
+ return (react_1.default.createElement(renderer_1.Document, null,
77
+ react_1.default.createElement(renderer_1.Page, { size: "A2", orientation: "landscape", style: {
78
+ padding: '4pt',
79
+ paddingTop: '8pt',
80
+ } },
81
+ react_1.default.createElement(renderer_1.View, { style: [exports.styles.flexRow, { marginTop: '8pt', marginBottom: '16pt', marginLeft: '48pt', marginRight: '64pt', justifyContent: 'space-between', alignItems: 'center' }] },
82
+ react_1.default.createElement(renderer_1.Image, { style: {
83
+ width: 'auto',
84
+ height: '32px',
85
+ }, src: `public/logo.png` })),
86
+ react_1.default.createElement(renderer_1.View, { style: exports.styles.table },
87
+ react_1.default.createElement(renderer_1.View, { style: Object.assign(Object.assign({}, exports.styles.tableRow), { backgroundColor: 'black', color: 'white' }) }, columns.map((column) => (react_1.default.createElement(renderer_1.View, { style: exports.styles.tableCol, key: column },
88
+ react_1.default.createElement(renderer_1.Text, { style: exports.styles.tableCell }, column))))),
89
+ rows.map((row, index) => {
90
+ return (react_1.default.createElement(renderer_1.View, { style: exports.styles.tableRow, key: index }, row.map((cell) => (react_1.default.createElement(renderer_1.View, { style: exports.styles.tableCol, key: index * 10 },
91
+ react_1.default.createElement(renderer_1.Text, { style: [exports.styles.tableCell] }, `${cell}`))))));
92
+ })))));
93
+ }
94
+ exports.default = ReportTemplate;
@@ -2,5 +2,8 @@ declare type sizeTypes = 'small' | 'medium';
2
2
  export interface IConfiguartionFile {
3
3
  textFieldSize?: sizeTypes;
4
4
  defaultRowsPerPage?: number;
5
+ themeLayout?: 'mini' | 'vertical' | 'horizontal';
6
+ themeStretch?: boolean;
7
+ showMainActions?: boolean;
5
8
  }
6
9
  export {};
@@ -55,6 +55,11 @@ interface Action {
55
55
  * @default 'Same as isAccessible'
56
56
  */
57
57
  isAllowed?: (currentUser: Document) => boolean;
58
+ /**
59
+ * The property that manages which action will be extracted from action menu in list.
60
+ * @default true for edit and show false for others
61
+ */
62
+ isMainAction?: boolean;
58
63
  }
59
64
  interface ICrudOperations {
60
65
  index?: {
@@ -421,6 +426,11 @@ export interface ExtraAction {
421
426
  * {@link https://mui.com/material-ui/material-icons/}
422
427
  */
423
428
  handlerStrategy?: HandlerStrategy;
429
+ /**
430
+ * The property that manages which action will be extracted from action menu in list.
431
+ * @default true for edit and show false for others
432
+ */
433
+ isMainAction?: boolean;
424
434
  }
425
435
  export interface IActionHandlerResponse {
426
436
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "identity-admin",
3
- "version": "1.25.17",
3
+ "version": "1.25.19",
4
4
  "description": "",
5
5
  "main": "lib/Dashboard.js",
6
6
  "types": "lib/Dashbord.d.ts",
@@ -26,8 +26,10 @@
26
26
  "devDependencies": {
27
27
  "@types/express": "^4.17.14",
28
28
  "@types/i18n": "^0.13.4",
29
+ "@types/lodash": "^4.14.202",
29
30
  "@types/mongoose": "^5.11.97",
30
31
  "@types/passport-local-mongoose": "^6.1.1",
32
+ "@types/react": "^18.2.45",
31
33
  "express": "^4.18.1",
32
34
  "express-validator": "^6.14.2",
33
35
  "i18n": "^0.15.0",
@@ -39,13 +41,17 @@
39
41
  "reflect-metadata": "^0.1.13"
40
42
  },
41
43
  "dependencies": {
44
+ "@react-pdf/renderer": "^3.1.14",
42
45
  "@types/express-session": "^1.17.5",
43
46
  "bcryptjs": "^2.4.3",
44
47
  "connect-mongo": "^4.6.0",
45
48
  "cookie-parser": "^1.4.6",
46
49
  "express-session": "^1.17.3",
50
+ "lodash": "^4.17.21",
51
+ "node-xlsx": "^0.21.0",
47
52
  "passport": "^0.6.0",
48
53
  "passport-local": "^1.0.0",
49
- "pluralize": "^8.0.0"
54
+ "pluralize": "^8.0.0",
55
+ "typescript": "^4.7.4"
50
56
  }
51
57
  }