@solidstarters/solid-core 1.2.133 → 1.2.135
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.
- package/dist/controllers/ai-interaction.controller.d.ts +45 -0
- package/dist/controllers/ai-interaction.controller.d.ts.map +1 -0
- package/dist/controllers/ai-interaction.controller.js +192 -0
- package/dist/controllers/ai-interaction.controller.js.map +1 -0
- package/dist/controllers/dashboard-variable.controller.d.ts +43 -0
- package/dist/controllers/dashboard-variable.controller.d.ts.map +1 -0
- package/dist/controllers/dashboard-variable.controller.js +179 -0
- package/dist/controllers/dashboard-variable.controller.js.map +1 -0
- package/dist/controllers/dashboard.controller.d.ts +45 -0
- package/dist/controllers/dashboard.controller.d.ts.map +1 -0
- package/dist/controllers/dashboard.controller.js +192 -0
- package/dist/controllers/dashboard.controller.js.map +1 -0
- package/dist/controllers/question-sql-dataset-config.controller.d.ts +43 -0
- package/dist/controllers/question-sql-dataset-config.controller.d.ts.map +1 -0
- package/dist/controllers/question-sql-dataset-config.controller.js +179 -0
- package/dist/controllers/question-sql-dataset-config.controller.js.map +1 -0
- package/dist/controllers/question.controller.d.ts +45 -0
- package/dist/controllers/question.controller.d.ts.map +1 -0
- package/dist/controllers/question.controller.js +194 -0
- package/dist/controllers/question.controller.js.map +1 -0
- package/dist/controllers/test.controller.d.ts.map +1 -1
- package/dist/controllers/test.controller.js.map +1 -1
- package/dist/decorators/dashboard-question-data-provider.decorator.d.ts +3 -0
- package/dist/decorators/dashboard-question-data-provider.decorator.d.ts.map +1 -0
- package/dist/decorators/dashboard-question-data-provider.decorator.js +11 -0
- package/dist/decorators/dashboard-question-data-provider.decorator.js.map +1 -0
- package/dist/decorators/dashboard-selection-provider.decorator.d.ts +3 -0
- package/dist/decorators/dashboard-selection-provider.decorator.d.ts.map +1 -0
- package/dist/decorators/dashboard-selection-provider.decorator.js +11 -0
- package/dist/decorators/dashboard-selection-provider.decorator.js.map +1 -0
- package/dist/dtos/create-ai-interaction.dto.d.ts +14 -0
- package/dist/dtos/create-ai-interaction.dto.d.ts.map +1 -0
- package/dist/dtos/create-ai-interaction.dto.js +90 -0
- package/dist/dtos/create-ai-interaction.dto.js.map +1 -0
- package/dist/dtos/create-dashboard-variable.dto.d.ts +18 -0
- package/dist/dtos/create-dashboard-variable.dto.d.ts.map +1 -0
- package/dist/dtos/create-dashboard-variable.dto.js +97 -0
- package/dist/dtos/create-dashboard-variable.dto.js.map +1 -0
- package/dist/dtos/create-dashboard.dto.d.ts +15 -0
- package/dist/dtos/create-dashboard.dto.d.ts.map +1 -0
- package/dist/dtos/create-dashboard.dto.js +90 -0
- package/dist/dtos/create-dashboard.dto.js.map +1 -0
- package/dist/dtos/create-question-sql-dataset-config.dto.d.ts +12 -0
- package/dist/dtos/create-question-sql-dataset-config.dto.d.ts.map +1 -0
- package/dist/dtos/create-question-sql-dataset-config.dto.js +77 -0
- package/dist/dtos/create-question-sql-dataset-config.dto.js.map +1 -0
- package/dist/dtos/create-question.dto.d.ts +16 -0
- package/dist/dtos/create-question.dto.d.ts.map +1 -0
- package/dist/dtos/create-question.dto.js +99 -0
- package/dist/dtos/create-question.dto.js.map +1 -0
- package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.d.ts +8 -0
- package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.d.ts.map +1 -0
- package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.js +52 -0
- package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.js.map +1 -0
- package/dist/dtos/invoke-ai-prompt.dto.d.ts +4 -0
- package/dist/dtos/invoke-ai-prompt.dto.d.ts.map +1 -0
- package/dist/dtos/invoke-ai-prompt.dto.js +25 -0
- package/dist/dtos/invoke-ai-prompt.dto.js.map +1 -0
- package/dist/dtos/update-ai-interaction.dto.d.ts +15 -0
- package/dist/dtos/update-ai-interaction.dto.d.ts.map +1 -0
- package/dist/dtos/update-ai-interaction.dto.js +96 -0
- package/dist/dtos/update-ai-interaction.dto.js.map +1 -0
- package/dist/dtos/update-dashboard-variable.dto.d.ts +15 -0
- package/dist/dtos/update-dashboard-variable.dto.d.ts.map +1 -0
- package/dist/dtos/update-dashboard-variable.dto.js +95 -0
- package/dist/dtos/update-dashboard-variable.dto.js.map +1 -0
- package/dist/dtos/update-dashboard.dto.d.ts +16 -0
- package/dist/dtos/update-dashboard.dto.d.ts.map +1 -0
- package/dist/dtos/update-dashboard.dto.js +96 -0
- package/dist/dtos/update-dashboard.dto.js.map +1 -0
- package/dist/dtos/update-question-sql-dataset-config.dto.d.ts +13 -0
- package/dist/dtos/update-question-sql-dataset-config.dto.d.ts.map +1 -0
- package/dist/dtos/update-question-sql-dataset-config.dto.js +86 -0
- package/dist/dtos/update-question-sql-dataset-config.dto.js.map +1 -0
- package/dist/dtos/update-question.dto.d.ts +17 -0
- package/dist/dtos/update-question.dto.d.ts.map +1 -0
- package/dist/dtos/update-question.dto.js +106 -0
- package/dist/dtos/update-question.dto.js.map +1 -0
- package/dist/entities/ai-interaction.entity.d.ts +15 -0
- package/dist/entities/ai-interaction.entity.d.ts.map +1 -0
- package/dist/entities/ai-interaction.entity.js +70 -0
- package/dist/entities/ai-interaction.entity.js.map +1 -0
- package/dist/entities/dashboard-variable.entity.d.ts +15 -0
- package/dist/entities/dashboard-variable.entity.d.ts.map +1 -0
- package/dist/entities/dashboard-variable.entity.js +73 -0
- package/dist/entities/dashboard-variable.entity.js.map +1 -0
- package/dist/entities/dashboard.entity.d.ts +12 -0
- package/dist/entities/dashboard.entity.d.ts.map +1 -0
- package/dist/entities/dashboard.entity.js +50 -0
- package/dist/entities/dashboard.entity.js.map +1 -0
- package/dist/entities/question-sql-dataset-config.entity.d.ts +13 -0
- package/dist/entities/question-sql-dataset-config.entity.d.ts.map +1 -0
- package/dist/entities/question-sql-dataset-config.entity.js +60 -0
- package/dist/entities/question-sql-dataset-config.entity.js.map +1 -0
- package/dist/entities/question.entity.d.ts +15 -0
- package/dist/entities/question.entity.d.ts.map +1 -0
- package/dist/entities/question.entity.js +67 -0
- package/dist/entities/question.entity.js.map +1 -0
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts +1 -0
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js +32 -7
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionStaticFieldCrudManager.d.ts +1 -0
- package/dist/helpers/field-crud-managers/SelectionStaticFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionStaticFieldCrudManager.js +32 -7
- package/dist/helpers/field-crud-managers/SelectionStaticFieldCrudManager.js.map +1 -1
- package/dist/helpers/solid-registry.d.ts +9 -1
- package/dist/helpers/solid-registry.d.ts.map +1 -1
- package/dist/helpers/solid-registry.js +32 -0
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +12 -1
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/mappers/dashboard-mapper.d.ts +6 -0
- package/dist/mappers/dashboard-mapper.d.ts.map +1 -0
- package/dist/mappers/dashboard-mapper.js +60 -0
- package/dist/mappers/dashboard-mapper.js.map +1 -0
- package/dist/repository/dashboard.repository.d.ts +11 -0
- package/dist/repository/dashboard.repository.d.ts.map +1 -0
- package/dist/repository/dashboard.repository.js +93 -0
- package/dist/repository/dashboard.repository.js.map +1 -0
- package/dist/seeders/module-metadata-seeder.service.d.ts +5 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +18 -2
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +4222 -2418
- package/dist/services/ai-interaction.service.d.ts +23 -0
- package/dist/services/ai-interaction.service.d.ts.map +1 -0
- package/dist/services/ai-interaction.service.js +147 -0
- package/dist/services/ai-interaction.service.js.map +1 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.d.ts +12 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.d.ts.map +1 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.js +55 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.js.map +1 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.d.ts +11 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.d.ts.map +1 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.js +45 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.js.map +1 -0
- package/dist/services/dashboard-variable.service.d.ts +23 -0
- package/dist/services/dashboard-variable.service.d.ts.map +1 -0
- package/dist/services/dashboard-variable.service.js +57 -0
- package/dist/services/dashboard-variable.service.js.map +1 -0
- package/dist/services/dashboard.service.d.ts +38 -0
- package/dist/services/dashboard.service.d.ts.map +1 -0
- package/dist/services/dashboard.service.js +179 -0
- package/dist/services/dashboard.service.js.map +1 -0
- package/dist/services/import-transaction.service.d.ts.map +1 -1
- package/dist/services/import-transaction.service.js +2 -1
- package/dist/services/import-transaction.service.js.map +1 -1
- package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
- package/dist/services/menu-item-metadata.service.js +1 -1
- package/dist/services/menu-item-metadata.service.js.map +1 -1
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts +36 -0
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts.map +1 -0
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js +85 -0
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js.map +1 -0
- package/dist/services/question-data-providers/helpers.d.ts +4 -0
- package/dist/services/question-data-providers/helpers.d.ts.map +1 -0
- package/dist/services/question-data-providers/helpers.js +10 -0
- package/dist/services/question-data-providers/helpers.js.map +1 -0
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts +17 -0
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts.map +1 -0
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js +64 -0
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js.map +1 -0
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts +19 -0
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts.map +1 -0
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js +84 -0
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js.map +1 -0
- package/dist/services/question-sql-dataset-config.service.d.ts +22 -0
- package/dist/services/question-sql-dataset-config.service.d.ts.map +1 -0
- package/dist/services/question-sql-dataset-config.service.js +56 -0
- package/dist/services/question-sql-dataset-config.service.js.map +1 -0
- package/dist/services/question.service.d.ts +29 -0
- package/dist/services/question.service.d.ts.map +1 -0
- package/dist/services/question.service.js +117 -0
- package/dist/services/question.service.js.map +1 -0
- package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.js +22 -11
- package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.d.ts +11 -0
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.d.ts.map +1 -0
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js +46 -0
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js.map +1 -0
- package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.d.ts +11 -0
- package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.d.ts.map +1 -0
- package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.js +47 -0
- package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.js.map +1 -0
- package/dist/services/solid-introspect.service.d.ts +2 -0
- package/dist/services/solid-introspect.service.d.ts.map +1 -1
- package/dist/services/solid-introspect.service.js +28 -0
- package/dist/services/solid-introspect.service.js.map +1 -1
- package/dist/services/sql-expression-resolver.service.d.ts +9 -0
- package/dist/services/sql-expression-resolver.service.d.ts.map +1 -0
- package/dist/services/sql-expression-resolver.service.js +105 -0
- package/dist/services/sql-expression-resolver.service.js.map +1 -0
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +61 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/dashboard-variable.subscriber.d.ts +16 -0
- package/dist/subscribers/dashboard-variable.subscriber.d.ts.map +1 -0
- package/dist/subscribers/dashboard-variable.subscriber.js +72 -0
- package/dist/subscribers/dashboard-variable.subscriber.js.map +1 -0
- package/dist/subscribers/dashboard.subscriber.d.ts +15 -0
- package/dist/subscribers/dashboard.subscriber.d.ts.map +1 -0
- package/dist/subscribers/dashboard.subscriber.js +56 -0
- package/dist/subscribers/dashboard.subscriber.js.map +1 -0
- package/dist/subscribers/question-sql-dataset-config.subscriber.d.ts +16 -0
- package/dist/subscribers/question-sql-dataset-config.subscriber.d.ts.map +1 -0
- package/dist/subscribers/question-sql-dataset-config.subscriber.js +72 -0
- package/dist/subscribers/question-sql-dataset-config.subscriber.js.map +1 -0
- package/dist/subscribers/question.subscriber.d.ts +16 -0
- package/dist/subscribers/question.subscriber.d.ts.map +1 -0
- package/dist/subscribers/question.subscriber.js +72 -0
- package/dist/subscribers/question.subscriber.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/controllers/ai-interaction.controller.ts +98 -0
- package/src/controllers/dashboard-variable.controller.ts +93 -0
- package/src/controllers/dashboard.controller.ts +99 -0
- package/src/controllers/question-sql-dataset-config.controller.ts +93 -0
- package/src/controllers/question.controller.ts +104 -0
- package/src/controllers/test.controller.ts +1 -2
- package/src/decorators/dashboard-question-data-provider.decorator.ts +7 -0
- package/src/decorators/dashboard-selection-provider.decorator.ts +7 -0
- package/src/dtos/create-ai-interaction.dto.ts +60 -0
- package/src/dtos/create-dashboard-variable.dto.ts +56 -0
- package/src/dtos/create-dashboard.dto.ts +53 -0
- package/src/dtos/create-question-sql-dataset-config.dto.ts +42 -0
- package/src/dtos/create-question.dto.ts +58 -0
- package/src/dtos/dashboard-variable-selection-dynamic-query.dto.ts +29 -0
- package/src/dtos/invoke-ai-prompt.dto.ts +6 -0
- package/src/dtos/update-ai-interaction.dto.ts +65 -0
- package/src/dtos/update-dashboard-variable.dto.ts +54 -0
- package/src/dtos/update-dashboard.dto.ts +57 -0
- package/src/dtos/update-question-sql-dataset-config.dto.ts +49 -0
- package/src/dtos/update-question.dto.ts +63 -0
- package/src/entities/ai-interaction.entity.ts +39 -0
- package/src/entities/dashboard-variable.entity.ts +30 -0
- package/src/entities/dashboard.entity.ts +21 -0
- package/src/entities/question-sql-dataset-config.entity.ts +25 -0
- package/src/entities/question.entity.ts +30 -0
- package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +44 -18
- package/src/helpers/field-crud-managers/SelectionStaticFieldCrudManager.ts +43 -15
- package/src/helpers/solid-registry.ts +44 -2
- package/src/index.ts +5 -0
- package/src/interfaces.ts +41 -29
- package/src/mappers/dashboard-mapper.ts +52 -0
- package/src/repository/dashboard.repository.ts +100 -0
- package/src/seeders/module-metadata-seeder.service.ts +21 -1
- package/src/seeders/seed-data/solid-core-metadata.json +4225 -2421
- package/src/services/1. Create a context menu option i.py +12 -0
- package/src/services/ai-interaction.service.ts +127 -0
- package/src/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.ts +56 -0
- package/src/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.ts +37 -0
- package/src/services/dashboard-variable.service.ts +36 -0
- package/src/services/dashboard.service.ts +147 -0
- package/src/services/import-transaction.service.ts +2 -1
- package/src/services/menu-item-metadata.service.ts +2 -1
- package/src/services/question-data-providers/chartjs-sql-data-provider.service.ts +121 -0
- package/src/services/question-data-providers/helpers.ts +11 -0
- package/src/services/question-data-providers/prime-react-datatable-sql-data-provider.service.ts +72 -0
- package/src/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.ts +110 -0
- package/src/services/question-sql-dataset-config.service.ts +34 -0
- package/src/services/question.service.ts +115 -0
- package/src/services/scheduled-jobs/scheduler.service.ts +32 -64
- package/src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts +41 -0
- package/src/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.ts +41 -0
- package/src/services/solid-introspect.service.ts +42 -0
- package/src/services/sql-expression-resolver.service.ts +125 -0
- package/src/solid-core.module.ts +61 -1
- package/src/subscribers/dashboard-variable.subscriber.ts +63 -0
- package/src/subscribers/dashboard.subscriber.ts +43 -0
- package/src/subscribers/question-sql-dataset-config.subscriber.ts +63 -0
- package/src/subscribers/question.subscriber.ts +65 -0
|
@@ -20,31 +20,57 @@ export class SelectionDynamicFieldCrudManager implements FieldCrudManager {
|
|
|
20
20
|
|
|
21
21
|
async validate(dto: any): Promise<ValidationError[]> {
|
|
22
22
|
const fieldValue: any = dto[this.options.fieldName];
|
|
23
|
+
// return this.applyValidations(fieldValue);
|
|
23
24
|
const isMultiSelect = this.options?.isMultiSelect;
|
|
25
|
+
if (isMultiSelect && fieldValue) {
|
|
26
|
+
const arrayCheck = this.parseAndValidateArray(fieldValue);
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
if (!arrayCheck.isValid) {
|
|
29
|
+
return [
|
|
30
|
+
{
|
|
31
|
+
field: this.options.fieldName,
|
|
32
|
+
error: `Field: ${this.options.fieldName} must be a valid array`,
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
}
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
// Try to parse the field value, which should be a JSON stringified array
|
|
32
|
-
values = JSON.parse(fieldValue);
|
|
33
|
-
} catch {
|
|
34
|
-
// If parsing fails, fallback to a single value
|
|
35
|
-
values = [fieldValue];
|
|
36
|
-
}
|
|
37
|
+
const values = arrayCheck.values;
|
|
37
38
|
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
if (this.isApplyRequiredValidation() && values.length === 0) {
|
|
40
|
+
return [
|
|
41
|
+
{
|
|
42
|
+
field: this.options.fieldName,
|
|
43
|
+
error: `Field: ${this.options.fieldName} is required`,
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
}
|
|
40
47
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
// Apply validations to each value
|
|
49
|
+
const allErrors = await Promise.all(values.map((val) => this.applyValidations(val)));
|
|
50
|
+
return allErrors.flat();
|
|
51
|
+
} else {
|
|
52
|
+
// For non-multi-select, apply validations to the single field value
|
|
53
|
+
return this.applyValidations(fieldValue);
|
|
54
|
+
}
|
|
46
55
|
}
|
|
56
|
+
|
|
57
|
+
private parseAndValidateArray(fieldValue: any): { isValid: boolean; values: any[] } {
|
|
58
|
+
if (Array.isArray(fieldValue)) {
|
|
59
|
+
return { isValid: true, values: fieldValue };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const parsed = typeof fieldValue === 'string' ? JSON.parse(fieldValue) : null;
|
|
64
|
+
if (Array.isArray(parsed)) {
|
|
65
|
+
return { isValid: true, values: parsed };
|
|
66
|
+
}
|
|
67
|
+
} catch {
|
|
68
|
+
// fall through
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { isValid: false, values: [] };
|
|
47
72
|
}
|
|
73
|
+
|
|
48
74
|
|
|
49
75
|
private async applyValidations(fieldValue: any): Promise<ValidationError[]> {
|
|
50
76
|
const errors: ValidationError[] = [];
|
|
@@ -16,24 +16,34 @@ export class SelectionStaticFieldCrudManager implements FieldCrudManager {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
async validate(dto: any): Promise<ValidationError[]> {
|
|
19
|
-
|
|
19
|
+
const fieldValue: any = dto[this.options.fieldName];
|
|
20
20
|
// return this.applyValidations(fieldValue);
|
|
21
21
|
const isMultiSelect = this.options?.isMultiSelect;
|
|
22
|
-
if (isMultiSelect) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
if (isMultiSelect && fieldValue) {
|
|
23
|
+
const arrayCheck = this.parseAndValidateArray(fieldValue);
|
|
24
|
+
|
|
25
|
+
if (!arrayCheck.isValid) {
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
field: this.options.fieldName,
|
|
29
|
+
error: `Field: ${this.options.fieldName} must be a valid array`,
|
|
30
|
+
},
|
|
31
|
+
];
|
|
31
32
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
|
|
34
|
+
const values = arrayCheck.values;
|
|
35
|
+
|
|
36
|
+
if (this.isApplyRequiredValidation() && values.length === 0) {
|
|
37
|
+
return [
|
|
38
|
+
{
|
|
39
|
+
field: this.options.fieldName,
|
|
40
|
+
error: `Field: ${this.options.fieldName} is required`,
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Apply validations to each value
|
|
46
|
+
const allErrors = await Promise.all(values.map((val) => this.applyValidations(val)));
|
|
37
47
|
return allErrors.flat();
|
|
38
48
|
} else {
|
|
39
49
|
// For non-multi-select, apply validations to the single field value
|
|
@@ -41,6 +51,24 @@ export class SelectionStaticFieldCrudManager implements FieldCrudManager {
|
|
|
41
51
|
}
|
|
42
52
|
}
|
|
43
53
|
|
|
54
|
+
private parseAndValidateArray(fieldValue: any): { isValid: boolean; values: any[] } {
|
|
55
|
+
if (Array.isArray(fieldValue)) {
|
|
56
|
+
return { isValid: true, values: fieldValue };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const parsed = typeof fieldValue === 'string' ? JSON.parse(fieldValue) : null;
|
|
61
|
+
if (Array.isArray(parsed)) {
|
|
62
|
+
return { isValid: true, values: parsed };
|
|
63
|
+
}
|
|
64
|
+
} catch {
|
|
65
|
+
// fall through
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return { isValid: false, values: [] };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
44
72
|
private applyValidations(fieldValue: any): ValidationError[] {
|
|
45
73
|
const errors: ValidationError[] = [];
|
|
46
74
|
this.isApplyRequiredValidation() && isEmpty(fieldValue) ? errors.push({ field: this.options.fieldName, error: `Field: ${this.options.fieldName} is required` }) : "no errors";
|
|
@@ -5,7 +5,7 @@ import { CommonEntity } from 'src/entities/common.entity';
|
|
|
5
5
|
import { Locale } from 'src/entities/locale.entity';
|
|
6
6
|
import { SecurityRule } from 'src/entities/security-rule.entity';
|
|
7
7
|
import { IScheduledJob } from 'src/services/scheduled-jobs/scheduled-job.interface';
|
|
8
|
-
import { ISelectionProvider, ISelectionProviderContext } from "../interfaces";
|
|
8
|
+
import { IDashboardQuestionDataProvider, IDashboardVariableSelectionProvider, ISelectionProvider, ISelectionProviderContext } from "../interfaces";
|
|
9
9
|
|
|
10
10
|
type ControllerMetadata = {
|
|
11
11
|
name: string;
|
|
@@ -63,6 +63,8 @@ export class SolidRegistry {
|
|
|
63
63
|
private securityRules: SecurityRule[] = [];
|
|
64
64
|
private locales: Locale[] = [];
|
|
65
65
|
private computedFieldMetadata: ComputedFieldMetadata[] = [];
|
|
66
|
+
private dashboardVariableSelectionProviders: Set<InstanceWrapper> = new Set();
|
|
67
|
+
private dashboardQuestionDataProviders: Set<InstanceWrapper> = new Set();
|
|
66
68
|
|
|
67
69
|
registerController(name: string, methodNames: string[]): void {
|
|
68
70
|
this.controllers.add({ name: name, methods: methodNames });
|
|
@@ -80,6 +82,14 @@ export class SolidRegistry {
|
|
|
80
82
|
this.selectionProviders.add(selectionProvider);
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
registerDashboardVariableSelectionProvider(dashboardSelectionProvider: InstanceWrapper): void {
|
|
86
|
+
this.dashboardVariableSelectionProviders.add(dashboardSelectionProvider);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
registerDashboardQuestionDataProvider(dashboardQuestionDataProvider: InstanceWrapper): void {
|
|
90
|
+
this.dashboardQuestionDataProviders.add(dashboardQuestionDataProvider);
|
|
91
|
+
}
|
|
92
|
+
|
|
83
93
|
registerComputedFieldProvider(computedFieldProvider: InstanceWrapper): void {
|
|
84
94
|
this.computedFieldProviders.add(computedFieldProvider);
|
|
85
95
|
}
|
|
@@ -119,6 +129,38 @@ export class SolidRegistry {
|
|
|
119
129
|
}
|
|
120
130
|
}
|
|
121
131
|
|
|
132
|
+
getDashboardVariableSelectionProviders(): Array<InstanceWrapper> {
|
|
133
|
+
return Array.from(this.dashboardVariableSelectionProviders);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
getDashboardVariableSelectionProviderInstance<T extends ISelectionProviderContext>(name: string): IDashboardVariableSelectionProvider<T> {
|
|
137
|
+
const dashboardSelectionProviders = this.getDashboardVariableSelectionProviders();
|
|
138
|
+
|
|
139
|
+
for (let i = 0; i < dashboardSelectionProviders.length; i++) {
|
|
140
|
+
const dashboardSelectionProvider = dashboardSelectionProviders[i];
|
|
141
|
+
if (dashboardSelectionProvider.instance.name() === name) {
|
|
142
|
+
return dashboardSelectionProvider.instance;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
getDashboardQuestionDataProviders(): Array<InstanceWrapper> {
|
|
148
|
+
return Array.from(this.dashboardQuestionDataProviders)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
getDashboardQuestionDataProviderInstance<TContext, TData>(name: string): IDashboardQuestionDataProvider<TContext, TData> {
|
|
152
|
+
const dashboardQuestionDataProviders = this.getDashboardQuestionDataProviders();
|
|
153
|
+
|
|
154
|
+
for (let i = 0; i < dashboardQuestionDataProviders.length; i++) {
|
|
155
|
+
const dasbhoardQuestionDataProvider = dashboardQuestionDataProviders[i];
|
|
156
|
+
if (dasbhoardQuestionDataProvider.instance.name() === name) {
|
|
157
|
+
return dasbhoardQuestionDataProvider.instance;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
122
164
|
getComputedFieldProviders(): Array<InstanceWrapper> {
|
|
123
165
|
return Array.from(this.computedFieldProviders);
|
|
124
166
|
}
|
|
@@ -137,7 +179,7 @@ export class SolidRegistry {
|
|
|
137
179
|
}
|
|
138
180
|
}
|
|
139
181
|
}
|
|
140
|
-
|
|
182
|
+
|
|
141
183
|
getComputedFieldProvider(name: string): InstanceWrapper {
|
|
142
184
|
const provider = this.getComputedFieldProviders().filter((provider) => provider.name === name).pop();
|
|
143
185
|
if (!provider) {
|
package/src/index.ts
CHANGED
|
@@ -125,6 +125,11 @@ export * from './entities/import-transaction.entity'
|
|
|
125
125
|
export * from './entities/import-transaction-error-log.entity'
|
|
126
126
|
export * from './entities/locale.entity'
|
|
127
127
|
export * from './entities/user-activity-history.entity'
|
|
128
|
+
export * from './entities/dashboard.entity'
|
|
129
|
+
export * from './entities/dashboard-variable.entity'
|
|
130
|
+
export * from './entities/question.entity'
|
|
131
|
+
export * from './entities/question-sql-dataset-config.entity'
|
|
132
|
+
export * from './entities/ai-interaction.entity'
|
|
128
133
|
|
|
129
134
|
export * from './enums/auth-type.enum'
|
|
130
135
|
|
package/src/interfaces.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { CreateEmailTemplateDto } from 'src/dtos/create-email-template.dto';
|
|
2
2
|
import { CreateSmsTemplateDto } from 'src/dtos/create-sms-template.dto';
|
|
3
3
|
import { SignUpDto } from 'src/dtos/sign-up.dto';
|
|
4
|
-
import {
|
|
4
|
+
import { Readable } from 'stream';
|
|
5
5
|
import { CreateMediaStorageProviderMetadataDto } from './dtos/create-media-storage-provider-metadata.dto';
|
|
6
|
-
import { CreateMenuItemMetadataDto } from './dtos/create-menu-item-metadata.dto';
|
|
7
6
|
import { DatasourceType } from './dtos/create-model-metadata.dto';
|
|
8
7
|
import { CreateModuleMetadataDto } from './dtos/create-module-metadata.dto';
|
|
9
8
|
import { CreateRoleMetadataDto } from './dtos/create-role-metadata.dto';
|
|
10
9
|
import { CreateSecurityRuleDto } from './dtos/create-security-rule.dto';
|
|
11
|
-
import { CreateViewMetadataDto } from './dtos/create-view-metadata.dto';
|
|
12
10
|
import { FieldMetadata } from './entities/field-metadata.entity';
|
|
13
11
|
import { Media } from './entities/media.entity';
|
|
14
|
-
import {
|
|
12
|
+
import { Question } from './entities/question.entity';
|
|
15
13
|
import { ComputedFieldMetadata } from './helpers/solid-registry';
|
|
14
|
+
import { SqlExpression } from './services/question-data-providers/chartjs-sql-data-provider.service';
|
|
15
|
+
import { CreateDashboardDto } from './dtos/create-dashboard.dto';
|
|
16
16
|
|
|
17
17
|
export interface FieldCrudManager {
|
|
18
18
|
// fieldMetadata: FieldMetadata;
|
|
@@ -27,39 +27,40 @@ export interface FieldCrudManager {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
export interface ValidationError {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
field: string;
|
|
31
|
+
error: string;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// export interface MediaStorage
|
|
35
35
|
export interface MediaStorageProvider<T> {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
store(files: Express.Multer.File[], entity: T, mediaFieldMetadata: FieldMetadata): Promise<Media[]>;
|
|
37
|
+
delete(entity: T, mediaFieldMetadata: FieldMetadata): Promise<void>;
|
|
38
|
+
retrieve(entity: T, mediaFieldMetadata: FieldMetadata): Promise<Media[]>;
|
|
39
|
+
storeStreams(streamPairs: [Readable, string][], entity: T, mediaFieldMetadata: FieldMetadata): Promise<Media[]>;
|
|
40
|
+
// delete(file: string): Promise<void>;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export interface ModuleMetadataConfiguration {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
44
|
+
moduleMetadata?: CreateModuleMetadataDto,
|
|
45
|
+
roles?: CreateRoleMetadataDto[],
|
|
46
|
+
users?: SignUpDto[],
|
|
47
|
+
actions?: any[],
|
|
48
|
+
menus?: any[],
|
|
49
|
+
views?: any[],
|
|
50
|
+
emailTemplates?: CreateEmailTemplateDto[],
|
|
51
|
+
smsTemplates?: CreateSmsTemplateDto[],
|
|
52
|
+
mediaStorageProviders?: CreateMediaStorageProviderMetadataDto[]
|
|
53
|
+
securityRules?: CreateSecurityRuleDto[],
|
|
54
|
+
dashboards?: CreateDashboardDto[],
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
export interface CodeGenerationOptions {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
moduleId?: number;
|
|
59
|
+
moduleUserKey?: string;
|
|
60
|
+
modelId?: number;
|
|
61
|
+
modelUserKey?: string;
|
|
62
|
+
fieldIdsForRemoval?: number[];
|
|
63
|
+
dryRun?: boolean;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
export interface ISelectionProviderContext {
|
|
@@ -81,6 +82,17 @@ export interface ISelectionProvider<T extends ISelectionProviderContext> {
|
|
|
81
82
|
values(query: any, ctxt: T): Promise<readonly ISelectionProviderValues[]>;
|
|
82
83
|
}
|
|
83
84
|
|
|
85
|
+
export interface IDashboardVariableSelectionProvider<T extends ISelectionProviderContext> extends ISelectionProvider<T> {
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface IDashboardQuestionDataProvider<TContext, TData> {
|
|
89
|
+
help(): string;
|
|
90
|
+
|
|
91
|
+
name(): string;
|
|
92
|
+
|
|
93
|
+
getData(question: Question, expressions?: SqlExpression[], ctxt?: TContext): Promise<TData[] | TData>;
|
|
94
|
+
}
|
|
95
|
+
|
|
84
96
|
/**
|
|
85
97
|
* @deprecated Use `IEntityComputedFieldProvider` instead.
|
|
86
98
|
*/
|
|
@@ -94,7 +106,7 @@ export interface IComputedFieldProvider<T> {
|
|
|
94
106
|
computeValue(dto: any, ctxt: T): Promise<string | number>; // FIXME : Improve the types to make it more specific using generics
|
|
95
107
|
}
|
|
96
108
|
|
|
97
|
-
export interface IEntityComputedFieldProvider {
|
|
109
|
+
export interface IEntityComputedFieldProvider {
|
|
98
110
|
help(): string;
|
|
99
111
|
|
|
100
112
|
name(): string;
|
|
@@ -122,7 +134,7 @@ export class EventDetails<T> {
|
|
|
122
134
|
constructor(
|
|
123
135
|
public type: any,
|
|
124
136
|
public payload: T,
|
|
125
|
-
) {}
|
|
137
|
+
) { }
|
|
126
138
|
}
|
|
127
139
|
|
|
128
140
|
export interface IMail {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Injectable } from "@nestjs/common";
|
|
2
|
+
import { SelectionDynamicSourceType } from "src/dtos/create-dashboard-variable.dto";
|
|
3
|
+
import { Dashboard } from "src/entities/dashboard.entity";
|
|
4
|
+
|
|
5
|
+
@Injectable()
|
|
6
|
+
export class DashboardMapper {
|
|
7
|
+
toDto(dashboard: Dashboard): any {
|
|
8
|
+
return {
|
|
9
|
+
name: dashboard.name,
|
|
10
|
+
layoutJson: this.safeParseJSON(dashboard.layoutJson, {}),
|
|
11
|
+
moduleUserKey: dashboard.module?.name ?? null, // safer fallback
|
|
12
|
+
|
|
13
|
+
dashboardVariables: (dashboard.dashboardVariables || []).map(variable => ({
|
|
14
|
+
variableName: variable.variableName,
|
|
15
|
+
variableType: variable.variableType,
|
|
16
|
+
selectionStaticValues: this.safeParseJSON(variable.selectionStaticValues, []),
|
|
17
|
+
selectionDynamicSourceType: variable.selectionDynamicSourceType as SelectionDynamicSourceType,
|
|
18
|
+
selectionDynamicSQL: variable.selectionDynamicSQL ?? null,
|
|
19
|
+
selectionDynamicProviderName: variable.selectionDynamicProviderName ?? null,
|
|
20
|
+
defaultValue: this.safeParseJSON(variable.defaultValue, []),
|
|
21
|
+
defaultOperator: variable.defaultOperator ?? null,
|
|
22
|
+
})),
|
|
23
|
+
questions: (dashboard.questions || []).map(question => ({
|
|
24
|
+
name: question.name,
|
|
25
|
+
sourceType: question.sourceType,
|
|
26
|
+
visualisedAs: question.visualisedAs,
|
|
27
|
+
providerName: question.providerName ?? null,
|
|
28
|
+
chartOptions: question.chartOptions ?? null,
|
|
29
|
+
labelSql: question.labelSql ?? null,
|
|
30
|
+
kpiSql: question.kpiSql ?? null,
|
|
31
|
+
|
|
32
|
+
questionSqlDatasetConfigs: (question.questionSqlDatasetConfigs || []).map(config => ({
|
|
33
|
+
sql: config.sql,
|
|
34
|
+
datasetName: config.datasetName,
|
|
35
|
+
datasetDisplayName: config.datasetDisplayName, // 🔧 fixed typo: `daataSetDisplayName`
|
|
36
|
+
description: config.description,
|
|
37
|
+
labelColumnName: config.labelColumnName,
|
|
38
|
+
valueColumnName: config.valueColumnName,
|
|
39
|
+
options: this.safeParseJSON(config.options, {}),
|
|
40
|
+
}))
|
|
41
|
+
}))
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private safeParseJSON(json: string | null | undefined, fallback: any): any {
|
|
46
|
+
try {
|
|
47
|
+
return json ? JSON.parse(json) : fallback;
|
|
48
|
+
} catch {
|
|
49
|
+
return fallback;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Injectable, Logger } from "@nestjs/common";
|
|
2
|
+
import { CreateDashboardDto } from "src/dtos/create-dashboard.dto";
|
|
3
|
+
import { DashboardVariable } from "src/entities/dashboard-variable.entity";
|
|
4
|
+
import { Dashboard } from "src/entities/dashboard.entity";
|
|
5
|
+
import { ModuleMetadata } from "src/entities/module-metadata.entity";
|
|
6
|
+
import { QuestionSqlDatasetConfig } from "src/entities/question-sql-dataset-config.entity";
|
|
7
|
+
import { Question } from "src/entities/question.entity";
|
|
8
|
+
import { DataSource, Repository } from "typeorm";
|
|
9
|
+
|
|
10
|
+
@Injectable()
|
|
11
|
+
export class DashboardRepository extends Repository<Dashboard> {
|
|
12
|
+
private readonly logger = new Logger(this.constructor.name);
|
|
13
|
+
constructor(
|
|
14
|
+
private dataSource: DataSource,
|
|
15
|
+
) {
|
|
16
|
+
super(Dashboard, dataSource.createEntityManager());
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async upsertWithDto(createDto: CreateDashboardDto) {
|
|
21
|
+
const moduleMetadataRepository = this.dataSource.getRepository(ModuleMetadata);
|
|
22
|
+
const module = await moduleMetadataRepository.findOneBy({ name: createDto.moduleUserKey });
|
|
23
|
+
|
|
24
|
+
if (!module) throw new Error(`Module with key ${createDto.moduleUserKey} not found`);
|
|
25
|
+
|
|
26
|
+
const existingDashboard = await this.findOne({
|
|
27
|
+
where: { name: createDto.name },
|
|
28
|
+
relations: ['dashboardVariables', 'questions', 'questions.questionSqlDatasetConfigs'],
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const dashboardData = {
|
|
32
|
+
...createDto,
|
|
33
|
+
module,
|
|
34
|
+
layoutJson: JSON.stringify(createDto.layoutJson ?? {}),
|
|
35
|
+
dashboardVariables: createDto.dashboardVariables?.map(variable => ({
|
|
36
|
+
...variable,
|
|
37
|
+
selectionStaticValues: JSON.stringify(variable.selectionStaticValues ?? []),
|
|
38
|
+
defaultValue: JSON.stringify(variable.defaultValue ?? []),
|
|
39
|
+
})),
|
|
40
|
+
questions: createDto.questions?.map(question => ({
|
|
41
|
+
...question,
|
|
42
|
+
questionSqlDatasetConfigs: question.questionSqlDatasetConfigs?.map(cfg => ({
|
|
43
|
+
...cfg,
|
|
44
|
+
options: JSON.stringify(cfg.options ?? {}),
|
|
45
|
+
})),
|
|
46
|
+
})),
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
if (existingDashboard) {
|
|
50
|
+
// Optionally clean up stale children
|
|
51
|
+
await this.cleanupRemovedRelations(existingDashboard, createDto);
|
|
52
|
+
|
|
53
|
+
this.merge(existingDashboard, dashboardData);
|
|
54
|
+
return this.save(existingDashboard);
|
|
55
|
+
} else {
|
|
56
|
+
const newDashboard = this.create(dashboardData);
|
|
57
|
+
return this.save(newDashboard);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private async cleanupRemovedRelations(existing: Dashboard, dto: CreateDashboardDto) {
|
|
62
|
+
const dashboardVariableRepo = this.dataSource.getRepository(DashboardVariable);
|
|
63
|
+
const questionRepo = this.dataSource.getRepository(Question);
|
|
64
|
+
const datasetConfigRepo = this.dataSource.getRepository(QuestionSqlDatasetConfig); // 👈 make sure this is imported
|
|
65
|
+
|
|
66
|
+
// === 1. Clean up removed dashboardVariables ===
|
|
67
|
+
const dtoVariableNames = new Set(dto.dashboardVariables.map(v => v.variableName));
|
|
68
|
+
const variablesToRemove = existing.dashboardVariables.filter(
|
|
69
|
+
v => !dtoVariableNames.has(v.variableName)
|
|
70
|
+
);
|
|
71
|
+
if (variablesToRemove.length > 0) {
|
|
72
|
+
await dashboardVariableRepo.remove(variablesToRemove);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// === 2. Clean up removed questions and gather removed question IDs ===
|
|
76
|
+
const dtoQuestionNames = new Set(dto.questions.map(q => q.name));
|
|
77
|
+
const questionsToRemove = existing.questions.filter(
|
|
78
|
+
q => !dtoQuestionNames.has(q.name)
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
if (questionsToRemove.length > 0) {
|
|
82
|
+
await questionRepo.remove(questionsToRemove);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// === 3. Clean up removed questionSqlDatasetConfigs from existing (retained) questions ===
|
|
86
|
+
for (const existingQuestion of existing.questions) {
|
|
87
|
+
const dtoQuestion = dto.questions.find(q => q.name === existingQuestion.name);
|
|
88
|
+
if (!dtoQuestion) continue;
|
|
89
|
+
|
|
90
|
+
const dtoDatasetNames = new Set(dtoQuestion.questionSqlDatasetConfigs?.map(cfg => cfg.datasetName));
|
|
91
|
+
const configsToRemove = existingQuestion.questionSqlDatasetConfigs.filter(
|
|
92
|
+
cfg => !dtoDatasetNames.has(cfg.datasetName)
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
if (configsToRemove.length > 0) {
|
|
96
|
+
await datasetConfigRepo.remove(configsToRemove);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -37,6 +37,8 @@ import { SecurityRuleRepository } from 'src/repository/security-rule.repository'
|
|
|
37
37
|
import { ListOfValuesService } from 'src/services/list-of-values.service';
|
|
38
38
|
import { CreateListOfValuesDto } from 'src/dtos/create-list-of-values.dto';
|
|
39
39
|
import { SystemFieldsSeederService } from './system-fields-seeder.service';
|
|
40
|
+
import { CreateDashboardDto } from 'src/dtos/create-dashboard.dto';
|
|
41
|
+
import { DashboardRepository } from 'src/repository/dashboard.repository';
|
|
40
42
|
|
|
41
43
|
@Injectable()
|
|
42
44
|
export class ModuleMetadataSeederService {
|
|
@@ -69,7 +71,8 @@ export class ModuleMetadataSeederService {
|
|
|
69
71
|
@InjectRepository(Setting, 'default')
|
|
70
72
|
readonly settingsRepo: Repository<Setting>,
|
|
71
73
|
readonly securityRuleRepo: SecurityRuleRepository,
|
|
72
|
-
readonly systemFieldsSeederService: SystemFieldsSeederService
|
|
74
|
+
readonly systemFieldsSeederService: SystemFieldsSeederService,
|
|
75
|
+
readonly dashboardRepo: DashboardRepository,
|
|
73
76
|
) { }
|
|
74
77
|
|
|
75
78
|
async seed() {
|
|
@@ -212,6 +215,13 @@ export class ModuleMetadataSeederService {
|
|
|
212
215
|
await this.seedListOfValues(listOfValues);
|
|
213
216
|
this.logger.debug(`[End] Processing List Of Values for ${moduleMetadata.name}`);
|
|
214
217
|
|
|
218
|
+
// Dashboards
|
|
219
|
+
this.logger.debug(`[Start] Processing dashboards for ${moduleMetadata.name}`);
|
|
220
|
+
const dashboards: CreateDashboardDto[] = overallMetadata.dashboards;
|
|
221
|
+
await this.seedDashboards(dashboards);
|
|
222
|
+
this.logger.debug(`[End] Processing dashboards for ${moduleMetadata.name}`);
|
|
223
|
+
|
|
224
|
+
|
|
215
225
|
this.logger.debug(`[End] module seed data: ${overallMetadata}`);
|
|
216
226
|
|
|
217
227
|
}
|
|
@@ -559,4 +569,14 @@ export class ModuleMetadataSeederService {
|
|
|
559
569
|
}
|
|
560
570
|
}
|
|
561
571
|
|
|
572
|
+
async seedDashboards(dashboardDtos: CreateDashboardDto[]) {
|
|
573
|
+
if (!dashboardDtos || dashboardDtos.length === 0) {
|
|
574
|
+
this.logger.debug(`No dashboards found to seed`);
|
|
575
|
+
return;
|
|
576
|
+
}
|
|
577
|
+
for (const dto of dashboardDtos) {
|
|
578
|
+
await this.dashboardRepo.upsertWithDto(dto);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
|
|
562
582
|
}
|