@solidstarters/solid-core 1.2.92 → 1.2.95

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.
Files changed (155) hide show
  1. package/# Password field.md +8 -0
  2. package/dist/controllers/import-transaction.controller.d.ts +2 -1
  3. package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
  4. package/dist/controllers/import-transaction.controller.js +16 -4
  5. package/dist/controllers/import-transaction.controller.js.map +1 -1
  6. package/dist/controllers/locale.controller.d.ts +41 -0
  7. package/dist/controllers/locale.controller.d.ts.map +1 -0
  8. package/dist/controllers/locale.controller.js +179 -0
  9. package/dist/controllers/locale.controller.js.map +1 -0
  10. package/dist/controllers/view-metadata.controller.d.ts +1 -0
  11. package/dist/controllers/view-metadata.controller.d.ts.map +1 -1
  12. package/dist/dtos/basic-filters.dto.d.ts +2 -0
  13. package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
  14. package/dist/dtos/basic-filters.dto.js +11 -1
  15. package/dist/dtos/basic-filters.dto.js.map +1 -1
  16. package/dist/dtos/create-locale.dto.d.ts +6 -0
  17. package/dist/dtos/create-locale.dto.d.ts.map +1 -0
  18. package/dist/dtos/create-locale.dto.js +43 -0
  19. package/dist/dtos/create-locale.dto.js.map +1 -0
  20. package/dist/dtos/create-menu-item-metadata.dto.d.ts +2 -1
  21. package/dist/dtos/create-menu-item-metadata.dto.d.ts.map +1 -1
  22. package/dist/dtos/create-menu-item-metadata.dto.js +22 -3
  23. package/dist/dtos/create-menu-item-metadata.dto.js.map +1 -1
  24. package/dist/dtos/create-model-metadata.dto.d.ts +1 -0
  25. package/dist/dtos/create-model-metadata.dto.d.ts.map +1 -1
  26. package/dist/dtos/create-model-metadata.dto.js +7 -2
  27. package/dist/dtos/create-model-metadata.dto.js.map +1 -1
  28. package/dist/dtos/create-role-metadata.dto.d.ts.map +1 -1
  29. package/dist/dtos/create-role-metadata.dto.js +11 -0
  30. package/dist/dtos/create-role-metadata.dto.js.map +1 -1
  31. package/dist/dtos/update-locale.dto.d.ts +7 -0
  32. package/dist/dtos/update-locale.dto.d.ts.map +1 -0
  33. package/dist/dtos/update-locale.dto.js +48 -0
  34. package/dist/dtos/update-locale.dto.js.map +1 -0
  35. package/dist/dtos/update-menu-item-metadata.dto.d.ts +2 -1
  36. package/dist/dtos/update-menu-item-metadata.dto.d.ts.map +1 -1
  37. package/dist/dtos/update-menu-item-metadata.dto.js +24 -5
  38. package/dist/dtos/update-menu-item-metadata.dto.js.map +1 -1
  39. package/dist/dtos/update-role-metadata.dto.d.ts.map +1 -1
  40. package/dist/dtos/update-role-metadata.dto.js +12 -1
  41. package/dist/dtos/update-role-metadata.dto.js.map +1 -1
  42. package/dist/entities/common.entity.d.ts +3 -0
  43. package/dist/entities/common.entity.d.ts.map +1 -1
  44. package/dist/entities/common.entity.js +13 -1
  45. package/dist/entities/common.entity.js.map +1 -1
  46. package/dist/entities/locale.entity.d.ts +7 -0
  47. package/dist/entities/locale.entity.d.ts.map +1 -0
  48. package/dist/entities/locale.entity.js +43 -0
  49. package/dist/entities/locale.entity.js.map +1 -0
  50. package/dist/entities/menu-item-metadata.entity.d.ts +2 -1
  51. package/dist/entities/menu-item-metadata.entity.d.ts.map +1 -1
  52. package/dist/entities/menu-item-metadata.entity.js +13 -8
  53. package/dist/entities/menu-item-metadata.entity.js.map +1 -1
  54. package/dist/entities/model-metadata.entity.d.ts +1 -0
  55. package/dist/entities/model-metadata.entity.d.ts.map +1 -1
  56. package/dist/entities/model-metadata.entity.js +5 -1
  57. package/dist/entities/model-metadata.entity.js.map +1 -1
  58. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.d.ts.map +1 -1
  59. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js.map +1 -1
  60. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.d.ts.map +1 -1
  61. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js.map +1 -1
  62. package/dist/helpers/module-metadata-helper.service.d.ts.map +1 -1
  63. package/dist/helpers/module-metadata-helper.service.js.map +1 -1
  64. package/dist/helpers/solid-registry.d.ts +2 -0
  65. package/dist/helpers/solid-registry.d.ts.map +1 -1
  66. package/dist/helpers/solid-registry.js +5 -0
  67. package/dist/helpers/solid-registry.js.map +1 -1
  68. package/dist/index.d.ts +5 -0
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +5 -0
  71. package/dist/index.js.map +1 -1
  72. package/dist/seeders/seed-data/solid-core-metadata.json +234 -0
  73. package/dist/services/authentication.service.d.ts.map +1 -1
  74. package/dist/services/authentication.service.js +8 -3
  75. package/dist/services/authentication.service.js.map +1 -1
  76. package/dist/services/crud-helper.service.d.ts +1 -1
  77. package/dist/services/crud-helper.service.d.ts.map +1 -1
  78. package/dist/services/crud-helper.service.js +17 -2
  79. package/dist/services/crud-helper.service.js.map +1 -1
  80. package/dist/services/crud.service.d.ts.map +1 -1
  81. package/dist/services/crud.service.js +19 -6
  82. package/dist/services/crud.service.js.map +1 -1
  83. package/dist/services/import-transaction.service.d.ts +19 -6
  84. package/dist/services/import-transaction.service.d.ts.map +1 -1
  85. package/dist/services/import-transaction.service.js +214 -87
  86. package/dist/services/import-transaction.service.js.map +1 -1
  87. package/dist/services/locale.service.d.ts +26 -0
  88. package/dist/services/locale.service.d.ts.map +1 -0
  89. package/dist/services/locale.service.js +64 -0
  90. package/dist/services/locale.service.js.map +1 -0
  91. package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
  92. package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
  93. package/dist/services/menu-item-metadata.service.js +1 -0
  94. package/dist/services/menu-item-metadata.service.js.map +1 -1
  95. package/dist/services/selection-providers/locale-list-selection-provider.service.d.ts +9 -0
  96. package/dist/services/selection-providers/locale-list-selection-provider.service.d.ts.map +1 -0
  97. package/dist/services/selection-providers/locale-list-selection-provider.service.js +87 -0
  98. package/dist/services/selection-providers/locale-list-selection-provider.service.js.map +1 -0
  99. package/dist/services/setting.service.d.ts.map +1 -1
  100. package/dist/services/setting.service.js +4 -2
  101. package/dist/services/setting.service.js.map +1 -1
  102. package/dist/services/view-metadata.service.d.ts +3 -0
  103. package/dist/services/view-metadata.service.d.ts.map +1 -1
  104. package/dist/services/view-metadata.service.js +73 -7
  105. package/dist/services/view-metadata.service.js.map +1 -1
  106. package/dist/solid-core.module.d.ts.map +1 -1
  107. package/dist/solid-core.module.js +8 -0
  108. package/dist/solid-core.module.js.map +1 -1
  109. package/dist/subscribers/model.subscriber.d.ts.map +1 -1
  110. package/dist/subscribers/model.subscriber.js +24 -0
  111. package/dist/subscribers/model.subscriber.js.map +1 -1
  112. package/dist/transformers/datetime-transformer.d.ts +4 -0
  113. package/dist/transformers/datetime-transformer.d.ts.map +1 -0
  114. package/dist/transformers/datetime-transformer.js +11 -0
  115. package/dist/transformers/datetime-transformer.js.map +1 -0
  116. package/dist/tsconfig.tsbuildinfo +1 -1
  117. package/package.json +2 -1
  118. package/src/controllers/import-transaction.controller.ts +9 -3
  119. package/src/controllers/locale.controller.ts +94 -0
  120. package/src/dtos/basic-filters.dto.ts +13 -1
  121. package/src/dtos/create-locale.dto.ts +17 -0
  122. package/src/dtos/create-menu-item-metadata.dto.ts +21 -13
  123. package/src/dtos/create-model-metadata.dto.ts +5 -1
  124. package/src/dtos/create-role-metadata.dto.ts +48 -45
  125. package/src/dtos/update-locale.dto.ts +23 -0
  126. package/src/dtos/update-menu-item-metadata.dto.ts +23 -16
  127. package/src/dtos/update-role-metadata.dto.ts +49 -47
  128. package/src/entities/common.entity.ts +11 -1
  129. package/src/entities/locale.entity.ts +14 -0
  130. package/src/entities/menu-item-metadata.entity.ts +14 -14
  131. package/src/entities/model-metadata.entity.ts +3 -0
  132. package/src/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.ts +2 -1
  133. package/src/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.ts +1 -0
  134. package/src/helpers/module-metadata-helper.service.ts +0 -1
  135. package/src/helpers/solid-registry.ts +11 -2
  136. package/src/index.ts +6 -3
  137. package/src/seeders/seed-data/email-templates/forgot-password.handlebars.html +134 -154
  138. package/src/seeders/seed-data/email-templates/on-force-password-change.handlebars.html +141 -195
  139. package/src/seeders/seed-data/email-templates/otp-on-login.handlebars.html +130 -144
  140. package/src/seeders/seed-data/email-templates/otp-on-register.handlebars.html +131 -145
  141. package/src/seeders/seed-data/solid-core-metadata.json +234 -0
  142. package/src/services/authentication.service.ts +8 -3
  143. package/src/services/crud-helper.service.ts +30 -12
  144. package/src/services/crud.service.ts +51 -35
  145. package/src/services/import-transaction.service.ts +313 -121
  146. package/src/services/locale.service.ts +37 -0
  147. package/src/services/mediaStorageProviders/file-storage-provider.ts +1 -1
  148. package/src/services/menu-item-metadata.service.ts +2 -0
  149. package/src/services/pending_import_issues +3 -0
  150. package/src/services/selection-providers/locale-list-selection-provider.service.ts +58 -0
  151. package/src/services/setting.service.ts +4 -2
  152. package/src/services/view-metadata.service.ts +179 -14
  153. package/src/solid-core.module.ts +8 -0
  154. package/src/subscribers/model.subscriber.ts +24 -0
  155. package/src/transformers/datetime-transformer.ts +12 -0
@@ -1,3 +1,4 @@
1
+ import { Logger } from '@nestjs/common';
1
2
  import { BadRequestException, Injectable } from '@nestjs/common';
2
3
  import { ConfigService } from '@nestjs/config';
3
4
  import { DiscoveryService, ModuleRef } from "@nestjs/core";
@@ -18,6 +19,9 @@ import { ActionMetadataService } from './action-metadata.service';
18
19
  import { SolidIntrospectService } from './solid-introspect.service';
19
20
  import { BasicFilterDto } from 'src/dtos/basic-filters.dto';
20
21
  import { UserViewMetadataService } from './user-view-metadata.service';
22
+ import { Locale } from 'src/entities/locale.entity';
23
+ import { SolidRegistry } from 'src/helpers/solid-registry';
24
+ import { classify } from '@angular-devkit/core/src/utils/strings';
21
25
 
22
26
  @Injectable()
23
27
  export class ViewMetadataService extends CRUDService<ViewMetadata> {
@@ -40,18 +44,81 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
40
44
  @InjectRepository(ModelMetadata)
41
45
  private readonly modelMetadataRepo: Repository<ModelMetadata>,
42
46
  readonly moduleRef: ModuleRef
43
-
44
47
  ) {
45
48
  super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'viewMetadata', 'app-builder', moduleRef);
46
49
  }
47
50
 
51
+ private readonly logger = new Logger(ViewMetadataService.name);
52
+
53
+ //for locales
54
+ private async getEntityRecordsInAllLocales(
55
+ modelName: string,
56
+ id: string,
57
+ defaultEntityLocaleIdFromQuery?: string
58
+ ): Promise<{ records: any[], defaultEntityLocaleId: string | null }> {
59
+ const solidRegistry = await this.moduleRef.get(SolidRegistry, { strict: false });
60
+ const currentEntityTarget = solidRegistry.getEntityTarget(this.entityManager, classify(modelName));
61
+ const currentEntityRepository = this.entityManager.getRepository(currentEntityTarget);
62
+
63
+ // Case 1: Creating a new record with no defaultEntityLocaleId to clone
64
+ if (id === 'new' && !defaultEntityLocaleIdFromQuery) {
65
+ this.logger.debug(`Creating new record without cloning from any defaultEntityLocaleId.`);
66
+ return { records: [], defaultEntityLocaleId: null };
67
+ }
68
+
69
+ // Case 2: Creating a new record and cloning from an existing defaultEntityLocaleId
70
+ if (id === 'new' && defaultEntityLocaleIdFromQuery) {
71
+ this.logger.debug(`Creating new record by cloning translations from defaultEntityLocaleId: ${defaultEntityLocaleIdFromQuery}`);
72
+
73
+ const records = await currentEntityRepository.find({
74
+ where: [
75
+ { defaultEntityLocaleId: defaultEntityLocaleIdFromQuery },
76
+ { id: defaultEntityLocaleIdFromQuery }
77
+ ]
78
+ });
79
+
80
+ this.logger.debug(`Found ${records.length} cloned records for new entity.`);
81
+ return { records, defaultEntityLocaleId: defaultEntityLocaleIdFromQuery };
82
+ }
83
+
84
+ // Case 3: Editing an existing entity
85
+ const entityRecord = await currentEntityRepository.findOne({ where: { id } });
86
+
87
+ if (!entityRecord) {
88
+ this.logger.warn(`No entity found for id ${id}`);
89
+ return { records: [], defaultEntityLocaleId: null };
90
+ }
91
+
92
+ const defaultLocale = await this.entityManager.getRepository(Locale).findOne({ where: { isDefault: true } });
93
+
94
+ let defaultEntityLocaleId: string;
95
+ if (entityRecord.localeName === defaultLocale?.locale) {
96
+ defaultEntityLocaleId = entityRecord.id;
97
+ this.logger.debug(`Editing default locale record with id ${defaultEntityLocaleId}`);
98
+ } else {
99
+ defaultEntityLocaleId = entityRecord.defaultEntityLocaleId;
100
+ this.logger.debug(`Editing non-default locale record. DefaultEntityLocaleId: ${defaultEntityLocaleId}`);
101
+ }
102
+
103
+ const records = await currentEntityRepository.find({
104
+ where: [
105
+ { defaultEntityLocaleId: defaultEntityLocaleId },
106
+ { id: defaultEntityLocaleId }
107
+ ]
108
+ });
109
+
110
+ this.logger.debug(`Found ${records.length} records in all locales for existing entity.`);
111
+
112
+ return { records, defaultEntityLocaleId };
113
+ }
114
+
48
115
  // START: Custom Service Methods
49
116
  async getLayout(query, activeUser) {
50
- let { modelName, moduleName, viewType, populate } = query;
117
+ let { modelName, moduleName, viewType, id, populate } = query;
51
118
 
52
119
  // modelName = camelize(modelName);
53
120
 
54
- // Fetch the view based on module, model & view name.
121
+ // 1. Fetch the view based on module, model & view name.
55
122
  const entity = await this.repo.findOne({
56
123
  where: {
57
124
  model: { singularName: modelName },
@@ -60,7 +127,7 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
60
127
  },
61
128
  relations: {
62
129
  model: {
63
- userKeyField: true, // Nested population of 'someOtherEntity' within 'model'
130
+ userKeyField: true,
64
131
  },
65
132
  module: true,
66
133
  }
@@ -69,19 +136,18 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
69
136
  if (!entity) {
70
137
  throw new BadRequestException(`Unable to identify view for module: ${moduleName}, model: ${modelName} and viewType: ${viewType}`);
71
138
  }
72
-
73
139
  if (!activeUser?.sub) {
74
140
  throw new BadRequestException(`Unable to identify user for module: ${moduleName}, model: ${modelName} and viewType: ${viewType}`);
75
141
  }
76
142
 
143
+ // 2. See if we have a user specific layout for this view.
77
144
  const userLayout = await this.userViewMetadataService.repo.findOne({
78
145
  where: {
79
146
  user: { id: activeUser?.sub },
80
147
  viewMetadata: { id: entity.id },
81
148
  },
82
149
  });
83
-
84
-
150
+ // Based on where we found the layout we are converting it from string to json.
85
151
  if (userLayout) {
86
152
  entity.layout = JSON.parse(userLayout.layout);
87
153
  } else {
@@ -89,8 +155,7 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
89
155
  }
90
156
 
91
157
 
92
- // If view entity found then convert layout from "string" to "json".
93
- //pass user id
158
+ // 3. We are resolving the create & edit actions if specified in the layout.
94
159
  if (entity?.layout?.attrs?.createAction) {
95
160
  const actionName: string = entity.layout.attrs.createAction;
96
161
  entity.layout.attrs.createAction = await this.actionMetadataService.findOneByUserKey(actionName)
@@ -100,14 +165,14 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
100
165
  entity.layout.attrs.editAction = await this.actionMetadataService.findOneByUserKey(actionName)
101
166
  }
102
167
 
103
- // for form views, we need to check if "workflow" field is configured, if configured then return an extra metadata "solidFormViewWorkflowData"
168
+ // 4. For form views we need to fetch the workflow field metadata if specified.
104
169
  let workflowFieldName = null;
105
170
  let workflowField = null;
106
171
  if (viewType === 'form') {
107
172
  workflowFieldName = entity.layout?.attrs?.workflowField;
108
173
  }
109
174
 
110
- // We also need to fetch a map of fields.
175
+ // 5. Create an easy to use map of field metadata, rather than sending an array of fields it becomes easier to use in the frontend.
111
176
  const fields = await this.loadFieldHierarchy(modelName);
112
177
  const fieldsMap = new Map<string, FieldMetadata>();
113
178
  for (let i = 0; i < fields.length; i++) {
@@ -139,6 +204,7 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
139
204
  }
140
205
  }
141
206
 
207
+ // 6. Use the resolved workflowField to populate workflow specific metadata.
142
208
  // Check if we were able to resolve an actual workflowField.
143
209
  let solidFormViewWorkflowData = [];
144
210
  if (viewType === 'form' && workflowField) {
@@ -146,7 +212,7 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
146
212
  // for workflowFields of type selectionStatic we simply return the key/values from field metadata AS-IS
147
213
  if (workflowField.type === 'selectionStatic') {
148
214
  solidFormViewWorkflowData = workflowField.selectionStaticValues.map(item => {
149
- const [value,label] = item.split(":");
215
+ const [value, label] = item.split(":");
150
216
  return { label, value };
151
217
  });
152
218
  }
@@ -161,13 +227,112 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
161
227
  // iterate over the comodel records extracting the label & value.
162
228
  solidFormViewWorkflowData = records.map(item => ({ 'label': item[workflowFielUserkey], 'value': item['id'] }))
163
229
  }
230
+ }
164
231
 
232
+ // 7. If this model supports internationalisation, we need to load the locales applicable with the id of an actual record for each locale if present.
233
+ // This is the shape of locales that will be returned
234
+ /**
235
+ * [
236
+ * {locale: 'en', displayName: 'English', isDefault: 'yes', defaultEntityLocaleId: '', entityId: '1'},
237
+ * {locale: 'en-IN', displayName: 'English (India)', isDefault: 'no', defaultEntityLocaleId: '1', entityId: '2'},
238
+ * {locale: 'en-SG', displayName: 'English (Singapore)', isDefault: 'no', defaultEntityLocaleId: '', entityId: '3'},
239
+ * {locale: 'fr', displayName: 'French', isDefault: 'no', defaultEntityLocaleId: '', entityId: ''}
240
+ * ]
241
+ */
242
+
243
+ const applicableLocales: any = []
244
+ // if (entity.model.internationalisation) {
245
+ // const allLocales = await this.entityManager.getRepository(Locale).find({});
246
+
247
+ // if (id === 'new') {
248
+ // allLocales.forEach(locale => {
249
+ // applicableLocales.push({
250
+ // locale: locale.locale,
251
+ // displayName: locale.displayName,
252
+ // isDefault: locale.isDefault ? 'yes' : 'no',
253
+ // defaultEntityLocaleId: null,
254
+ // entityId: null
255
+ // });
256
+ // });
257
+ // }
258
+ // else {
259
+ // const defaultLocale = allLocales.find(locale => locale.isDefault);
260
+ // this.logger.debug(`Default locale is: ${defaultLocale.locale}`);
261
+
262
+ // // Get hold of the repository for the current model
263
+ // const solidRegistry = await this.moduleRef.get(SolidRegistry, { strict: false });
264
+ // const currentEntityTarget = solidRegistry.getEntityTarget(this.entityManager, classify(modelName));
265
+ // const currentEntityRepository = this.entityManager.getRepository(currentEntityTarget);
266
+
267
+ // // We are in edit mode, the id that is being edited could be a record tagged with the default locale or it could be tagged with a non-default locale.
268
+ // const entityRecord = await currentEntityRepository.findOne({
269
+ // where: {
270
+ // id: id,
271
+ // }
272
+ // });
273
+ // if(entityRecord){
274
+ // // Resolve the default entity locale id....
275
+ // let defaultEntityLocaleId = null;
276
+ // if (entityRecord.localeName === defaultLocale.locale) {
277
+ // defaultEntityLocaleId = entityRecord.id;
278
+ // this.logger.debug(`You are editing a record tagged with the default locale: ${entityRecord.localeName}.`);
279
+ // }
280
+ // else {
281
+ // defaultEntityLocaleId = entityRecord.defaultEntityLocaleId;
282
+ // this.logger.debug(`You are editing a record tagged with the non-default locale: ${entityRecord.localeName}. `);
283
+ // }
284
+ // this.logger.debug(`Identified default Entity Locale Id: ${defaultEntityLocaleId}`);
285
+
286
+ // // Now we query for all records in the same model matching the defaultEntityLocaleId
287
+ // // Get all records mathcing the defaultEntityLocaleId or where the id is same as the defaultEntityLocaleId
288
+ // const entityRecordsInAllLocales = await currentEntityRepository.find({
289
+ // where: [
290
+ // { defaultEntityLocaleId: defaultEntityLocaleId },
291
+ // { id: defaultEntityLocaleId }
292
+ // ],
293
+ // });
294
+ // this.logger.debug(`Found ${entityRecordsInAllLocales.length} records in all locales for the defaultEntityLocaleId: ${defaultEntityLocaleId}`);
295
+
296
+ // // Loop over all locales and populate the applicableLocales array
297
+ // for (const locale of allLocales) {
298
+ // // Find the record in the entityRecordsInAllLocales that matches the current locale
299
+ // const matchingRecord = entityRecordsInAllLocales.find(record => record.localeName === locale.locale);
300
+
301
+ // applicableLocales.push({
302
+ // locale: locale.locale,
303
+ // displayName: locale.displayName,
304
+ // isDefault: locale.isDefault ? 'yes' : 'no',
305
+ // defaultEntityLocaleId: defaultEntityLocaleId,
306
+ // entityId: (matchingRecord ? matchingRecord.id : null)
307
+ // });
308
+ // }
309
+ // }else{
310
+ // this.logger.warn(`No record found for id: ${id} in model: ${modelName}. Cannot determine applicable locales.`);
311
+ // }
312
+ // }
313
+ // }
314
+ if(entity.model.internationalisation){
315
+ const defaultEntityLocaleIdFromQuery = query?.defaultEntityLocaleId;
316
+ const { records: entityRecordsInAllLocales, defaultEntityLocaleId } =
317
+ await this.getEntityRecordsInAllLocales(modelName, id, defaultEntityLocaleIdFromQuery);
318
+ const allLocales = await this.entityManager.getRepository(Locale).find({});
319
+ for (const locale of allLocales) {
320
+ const matchingRecord = entityRecordsInAllLocales.find(record => record.localeName === locale.locale);
321
+ applicableLocales.push({
322
+ locale: locale.locale,
323
+ displayName: locale.displayName,
324
+ isDefault: locale.isDefault ? 'yes' : 'no',
325
+ defaultEntityLocaleId: defaultEntityLocaleId,
326
+ entityId: matchingRecord ? matchingRecord.id : null
327
+ });
328
+ }
165
329
  }
166
330
 
167
331
  const r = {
168
332
  'solidView': entity,
169
333
  'solidFieldsMetadata': Object.fromEntries(fieldsMap),
170
- 'solidFormViewWorkflowData': solidFormViewWorkflowData
334
+ 'solidFormViewWorkflowData': solidFormViewWorkflowData,
335
+ 'applicableLocales': applicableLocales
171
336
  }
172
337
 
173
338
  return r;
@@ -195,7 +360,7 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
195
360
  fields.push(...model.parentModel.fields);
196
361
  }
197
362
  }
198
- return fields;
363
+ return fields;
199
364
  }
200
365
 
201
366
  async findOneByUserKey(name: string, relations = {}) {
@@ -160,6 +160,9 @@ import { ChatterMessageController } from './controllers/chatter-message.controll
160
160
  import { ChatterMessageDetails } from './entities/chatter-message-details.entity';
161
161
  import { ChatterMessageDetailsService } from './services/chatter-message-details.service';
162
162
  import { ChatterMessageDetailsController } from './controllers/chatter-message-details.controller';
163
+ import { Locale } from './entities/locale.entity';
164
+ import { LocaleService } from './services/locale.service';
165
+ import { LocaleController } from './controllers/locale.controller';
163
166
  import { AuditSubscriber } from './subscribers/audit.subscriber';
164
167
  import { ExportTemplate } from './entities/export-template.entity';
165
168
  import { ExportTemplateService } from './services/export-template.service';
@@ -177,6 +180,7 @@ import { ImportTransactionController } from './controllers/import-transaction.co
177
180
  import { ImportTransactionErrorLog } from './entities/import-transaction-error-log.entity';
178
181
  import { ImportTransactionErrorLogService } from './services/import-transaction-error-log.service';
179
182
  import { ImportTransactionErrorLogController } from './controllers/import-transaction-error-log.controller';
183
+ import { LocaleListSelectionProvider } from './services/selection-providers/locale-list-selection-provider.service';
180
184
 
181
185
 
182
186
  @Global()
@@ -228,6 +232,7 @@ import { ImportTransactionErrorLogController } from './controllers/import-transa
228
232
  TypeOrmModule.forFeature([ListOfValues]),
229
233
  TypeOrmModule.forFeature([ChatterMessage]),
230
234
  TypeOrmModule.forFeature([ChatterMessageDetails]),
235
+ TypeOrmModule.forFeature([Locale]),
231
236
  TypeOrmModule.forFeature([ExportTemplate]),
232
237
  TypeOrmModule.forFeature([ExportTransaction]),
233
238
  // TypeOrmModule.forFeature([User]),
@@ -268,6 +273,7 @@ import { ImportTransactionErrorLogController } from './controllers/import-transa
268
273
  ListOfValuesController,
269
274
  ChatterMessageController,
270
275
  ChatterMessageDetailsController,
276
+ LocaleController,
271
277
  ExportTemplateController,
272
278
  ExportTransactionController,
273
279
  ImportTransactionController,
@@ -343,6 +349,7 @@ import { ImportTransactionErrorLogController } from './controllers/import-transa
343
349
  PdfService,
344
350
  UuidExternalIdComputedFieldProvider,
345
351
  ListOfModelsSelectionProvider,
352
+ LocaleListSelectionProvider,
346
353
  SoftDeleteAwareEventSubscriber,
347
354
  AccessTokenGuard,
348
355
  AuthenticationService,
@@ -375,6 +382,7 @@ import { ImportTransactionErrorLogController } from './controllers/import-transa
375
382
  SavedFiltersService,
376
383
  ChatterMessageService,
377
384
  ChatterMessageDetailsService,
385
+ LocaleService,
378
386
  AuditSubscriber,
379
387
  ExportTemplateService,
380
388
  ExportTransactionService,
@@ -66,6 +66,30 @@ export class ModelSubscriber implements EntitySubscriberInterface<ModelMetadata>
66
66
  isSystem: true,
67
67
  model: event.entity,
68
68
  },
69
+ {
70
+ name: "publishedAt",
71
+ displayName: "Published At",
72
+ type: "datetime",
73
+ ormType: "timestamp",
74
+ isSystem: true,
75
+ model: event.entity,
76
+ },
77
+ {
78
+ name: "localeName",
79
+ displayName: "Locale",
80
+ type: "shortText",
81
+ ormType: "varchar",
82
+ isSystem: true,
83
+ model: event.entity,
84
+ },
85
+ {
86
+ name: "defaultEntityLocaleId",
87
+ displayName: "Default Entity Locale Id",
88
+ type: "int",
89
+ ormType: "integer",
90
+ isSystem: true,
91
+ model: event.entity,
92
+ }
69
93
  ];
70
94
  await transactionManager.save(FieldMetadata, systemFieldsMetadata);
71
95
  // Save to the database.
@@ -0,0 +1,12 @@
1
+ import { TransformFnParams } from 'class-transformer';
2
+
3
+ const datetimeTransformer = ({ value }: TransformFnParams): Date | null => {
4
+ console.log("date time transformer debug", value);
5
+
6
+ if (value === '' || value === undefined || value === null) return null;
7
+
8
+ const parsed = new Date(value);
9
+ return isNaN(parsed.getTime()) ? null : parsed;
10
+ };
11
+
12
+ export default datetimeTransformer;