@acorex/platform-generator 19.2.12 → 19.2.16

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 (46) hide show
  1. package/generators.json +10 -0
  2. package/package.json +4 -1
  3. package/src/bin/interactive-entity-creator.js +448 -0
  4. package/src/bin/test-entity-creator.js +48 -0
  5. package/src/generators/app-module/files/src/app/app.module.ts.template +0 -3
  6. package/src/generators/app-module/files/src/app/modules/root/sample/sample.service.ts.template +1 -1
  7. package/src/generators/app-module/files/src/app/modules/root/sample/sample.types.ts.template +1 -1
  8. package/src/generators/create-app-module/files/__fileName__/src/index.ts__tmpl__ +9 -0
  9. package/src/generators/create-app-module/files/__fileName__/src/lib/__fileName__.module.ts__tmpl__ +44 -0
  10. package/src/generators/create-app-module/files/__fileName__/src/lib/const.ts__tmpl__ +19 -0
  11. package/src/generators/create-app-module/files/__fileName__/src/lib/entity.provider.ts__tmpl__ +33 -0
  12. package/src/generators/create-app-module/files/__fileName__/src/lib/menu.provider.ts__tmpl__ +29 -0
  13. package/src/generators/create-app-module/files/__fileName__/src/lib/permission.provider.ts__tmpl__ +13 -0
  14. package/src/generators/create-app-module/files/__fileName__/src/lib/search-command.provider.ts__tmpl__ +17 -0
  15. package/src/generators/create-app-module/files/__fileName__/src/lib/setting.provider.ts__tmpl__ +29 -0
  16. package/src/generators/create-module-entity/files/__entityFileName__.entity.ts__tmpl__ +150 -0
  17. package/src/generators/create-module-entity/files/__entityFileName__.service.ts__tmpl__ +16 -0
  18. package/src/generators/create-module-entity/files/__entityFileName__.types.ts__tmpl__ +6 -0
  19. package/src/generators/create-module-entity/files/index.ts__tmpl__ +3 -0
  20. package/src/generators/create-module-entity/generator.d.ts +11 -0
  21. package/src/generators/create-module-entity/generator.js +338 -20
  22. package/src/generators/create-module-entity/generator.js.map +1 -1
  23. package/src/generators/create-module-entity/schema.json +85 -2
  24. package/src/generators/create-tag-entity/files/index.ts__tmpl__ +3 -0
  25. package/src/generators/create-tag-entity/files/tag-__entityFileName__.entity.ts__tmpl__ +240 -0
  26. package/src/generators/create-tag-entity/files/tag-__entityFileName__.service.ts__tmpl__ +16 -0
  27. package/src/generators/create-tag-entity/files/tag-__entityFileName__.types.ts__tmpl__ +6 -0
  28. package/src/generators/create-tag-entity/generator.d.ts +7 -0
  29. package/src/generators/create-tag-entity/generator.js +111 -0
  30. package/src/generators/create-tag-entity/generator.js.map +1 -0
  31. package/src/generators/create-tag-entity/schema.json +16 -0
  32. package/src/generators/create-widget/files/__fileName__-widget-column.component.ts__tmpl__ +11 -0
  33. package/src/generators/create-widget/files/__fileName__-widget-edit.component.ts__tmpl__ +35 -0
  34. package/src/generators/create-widget/files/__fileName__-widget-filter.component.ts__tmpl__ +12 -0
  35. package/src/generators/create-widget/files/__fileName__-widget-print.component.ts__tmpl__ +11 -0
  36. package/src/generators/create-widget/files/__fileName__-widget-view.component.ts__tmpl__ +14 -0
  37. package/src/generators/create-widget/files/__fileName__-widget.config.ts__tmpl__ +44 -0
  38. package/src/generators/create-widget/files/index.ts__tmpl__ +6 -0
  39. package/src/generators/create-widget/generator.d.ts +8 -0
  40. package/src/generators/create-widget/generator.js +99 -0
  41. package/src/generators/create-widget/generator.js.map +1 -0
  42. package/src/generators/create-widget/schema.d.ts +6 -0
  43. package/src/generators/create-widget/schema.json +66 -0
  44. package/src/generators/index.d.ts +0 -0
  45. package/src/generators/index.js +1 -0
  46. package/src/generators/index.js.map +1 -0
package/generators.json CHANGED
@@ -14,6 +14,16 @@
14
14
  "factory": "./src/generators/create-module-entity/generator",
15
15
  "schema": "./src/generators/create-module-entity/schema.json",
16
16
  "description": "create-module-entity generator"
17
+ },
18
+ "create-tag-entity": {
19
+ "factory": "./src/generators/create-tag-entity/generator",
20
+ "schema": "./src/generators/create-tag-entity/schema.json",
21
+ "description": "create-tag-entity generator"
22
+ },
23
+ "create-widget": {
24
+ "factory": "./src/generators/create-widget/generator",
25
+ "schema": "./src/generators/create-widget/schema.json",
26
+ "description": "Create a new widget with all required components"
17
27
  }
18
28
  }
19
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acorex/platform-generator",
3
- "version": "19.2.12",
3
+ "version": "19.2.16",
4
4
  "dependencies": {
5
5
  "@nx/devkit": "19.2.2",
6
6
  "tslib": "^2.3.0"
@@ -18,5 +18,8 @@
18
18
  "typings": "./src/index.d.ts",
19
19
  "private": false,
20
20
  "generators": "./generators.json",
21
+ "bin": {
22
+ "acx-create-entity": "./src/bin/interactive-entity-creator.js"
23
+ },
21
24
  "types": "./src/index.d.ts"
22
25
  }
@@ -0,0 +1,448 @@
1
+ #!/usr/bin/env node
2
+
3
+ const readline = require('readline');
4
+ const { spawn } = require('child_process');
5
+ const { join, resolve } = require('path');
6
+ const fs = require('fs');
7
+
8
+ // Find the root directory of the project
9
+ function findProjectRoot() {
10
+ let currentDir = __dirname;
11
+ while (!fs.existsSync(join(currentDir, 'nx.json'))) {
12
+ const parentDir = resolve(currentDir, '..');
13
+ if (parentDir === currentDir) {
14
+ // We've reached the root of the filesystem
15
+ return process.cwd();
16
+ }
17
+ currentDir = parentDir;
18
+ }
19
+ return currentDir;
20
+ }
21
+
22
+ const projectRoot = findProjectRoot();
23
+
24
+ // Function to validate module and entity names
25
+ function validateName(name) {
26
+ // Ensure name is not empty
27
+ if (!name || name.trim() === '') {
28
+ return 'Name cannot be empty.';
29
+ }
30
+
31
+ // Ensure name is not just a number
32
+ if (/^\d+$/.test(name)) {
33
+ return 'Name cannot be just a number. Please include at least one letter.';
34
+ }
35
+
36
+ // Less restrictive validation that allows non-Latin characters
37
+ // Just check for spaces, special characters, and make sure it starts with a letter or non-Latin character
38
+ if (/^[^a-zA-Z\p{L}]|\s|[^\w\p{L}]/u.test(name)) {
39
+ return 'Name must start with a letter and cannot contain spaces or special characters.';
40
+ }
41
+
42
+ return null; // No error
43
+ }
44
+
45
+ // Check for --dryRun flag at the beginning
46
+ const isDryRun = process.argv.includes('--dryRun');
47
+
48
+ // Create an interface for readline
49
+ const rl = readline.createInterface({
50
+ input: process.stdin,
51
+ output: process.stdout
52
+ });
53
+
54
+ // Define widget catalog - copied from widget-catalog.ts
55
+ const widgetCatalog = {
56
+ text: 'text-editor',
57
+ email: 'email-editor',
58
+ password: 'password-editor',
59
+ phone: 'phone-editor',
60
+ largeText: 'large-text-editor',
61
+ richText: 'rich-text-editor',
62
+ number: 'number-editor',
63
+ numberUnit: 'number-unit-editor',
64
+ select: 'select-editor',
65
+ checkbox: 'checkbox-editor',
66
+ toggle: 'toggle-editor',
67
+ dateTime: 'date-time-editor',
68
+ color: 'color-editor',
69
+ link: 'link-editor',
70
+ contact: 'contact-editor',
71
+ tagable: 'tagable-editor',
72
+ file: 'file',
73
+ gallery: 'gallery',
74
+ signature: 'signature',
75
+ map: 'map',
76
+ lookup: 'lookup-editor',
77
+ selectionList: 'selection-list-editor',
78
+ table: 'table-editor',
79
+ qrcode: 'qrcode',
80
+ singleFileBox: 'single-file-box-editor',
81
+ metaData: 'meta-data-editor'
82
+ };
83
+
84
+ // Define widget to data type mapping
85
+ const widgetToDataType = {
86
+ 'text-editor': 'string',
87
+ 'email-editor': 'string',
88
+ 'password-editor': 'string',
89
+ 'phone-editor': 'string',
90
+ 'large-text-editor': 'string',
91
+ 'rich-text-editor': 'string',
92
+ 'number-editor': 'number',
93
+ 'number-unit-editor': 'number',
94
+ 'select-editor': 'object',
95
+ 'checkbox-editor': 'boolean',
96
+ 'toggle-editor': 'boolean',
97
+ 'date-time-editor': 'date',
98
+ 'color-editor': 'string',
99
+ 'link-editor': 'string',
100
+ 'contact-editor': 'object',
101
+ 'tagable-editor': 'string',
102
+ 'file': 'object',
103
+ 'gallery': 'object',
104
+ 'signature': 'string',
105
+ 'map': 'object',
106
+ 'lookup-editor': 'object',
107
+ 'selection-list-editor': 'array',
108
+ 'table-editor': 'array',
109
+ 'qrcode': 'string',
110
+ 'single-file-box-editor': 'object',
111
+ 'meta-data-editor': 'object'
112
+ };
113
+
114
+ // Widget groups for better display
115
+ const widgetGroups = {
116
+ 'Basic': ['text-editor', 'large-text-editor', 'rich-text-editor', 'number-editor', 'checkbox-editor', 'toggle-editor'],
117
+ 'Input': ['email-editor', 'password-editor', 'phone-editor', 'date-time-editor', 'color-editor'],
118
+ 'Complex': ['select-editor', 'lookup-editor', 'selection-list-editor', 'table-editor'],
119
+ 'Media': ['file', 'gallery', 'signature', 'map', 'qrcode']
120
+ };
121
+
122
+ // Define default colSpan based on widget type
123
+ const widgetToColSpan = {
124
+ 'text-editor': 6,
125
+ 'email-editor': 6,
126
+ 'password-editor': 6,
127
+ 'phone-editor': 6,
128
+ 'large-text-editor': 12,
129
+ 'rich-text-editor': 12,
130
+ 'number-editor': 4,
131
+ 'number-unit-editor': 6,
132
+ 'select-editor': 6,
133
+ 'checkbox-editor': 4,
134
+ 'toggle-editor': 4,
135
+ 'date-time-editor': 6,
136
+ 'color-editor': 4,
137
+ 'link-editor': 6,
138
+ 'contact-editor': 8,
139
+ 'tagable-editor': 8,
140
+ 'file': 6,
141
+ 'gallery': 12,
142
+ 'signature': 8,
143
+ 'map': 12,
144
+ 'lookup-editor': 6,
145
+ 'selection-list-editor': 8,
146
+ 'table-editor': 12,
147
+ 'qrcode': 6,
148
+ 'single-file-box-editor': 6,
149
+ 'meta-data-editor': 8
150
+ };
151
+
152
+ // Create data object to store all user input
153
+ const data = {
154
+ moduleName: '',
155
+ name: '',
156
+ properties: [],
157
+ dataTypes: [],
158
+ required: [],
159
+ colSpans: [],
160
+ orders: [],
161
+ widgets: [], // Used locally but not passed to NX generator
162
+ icon: 'fa-light fa-default',
163
+ enableSorts: [],
164
+ enableFilters: [],
165
+ enableInlineFilters: [],
166
+ inColumn: [] // اضافه کردن آرایه جدید برای ذخیره وضعیت نمایش در ستون
167
+ };
168
+
169
+ // Run the prompts in sequence
170
+ async function runPrompts() {
171
+ console.log('\n=== AcoreX Platform Interactive Entity Generator ===\n');
172
+
173
+ // Get module name with validation
174
+ while (true) {
175
+ data.moduleName = await askQuestion('Module name: ');
176
+ const error = validateName(data.moduleName);
177
+ if (error) {
178
+ console.log(`Error: ${error}`);
179
+ } else {
180
+ break;
181
+ }
182
+ }
183
+
184
+ // Get entity name with validation
185
+ while (true) {
186
+ data.name = await askQuestion('Entity name: ');
187
+ const error = validateName(data.name);
188
+ if (error) {
189
+ console.log(`Error: ${error}`);
190
+ } else {
191
+ break;
192
+ }
193
+ }
194
+
195
+ // Get properties
196
+ console.log('\nEnter properties (type "done" when finished):');
197
+ let propCount = 1;
198
+ while (true) {
199
+ const prop = await askQuestion(`Property ${propCount}: `);
200
+ if (prop.toLowerCase() === 'done') {
201
+ break;
202
+ }
203
+ data.properties.push(prop);
204
+
205
+ // Get widget for this property
206
+ const widget = await selectWidget(`Select widget for "${prop}": `);
207
+ data.widgets.push(widget);
208
+
209
+ // Automatically determine data type based on widget
210
+ const dataType = widgetToDataType[widget] || 'string';
211
+ data.dataTypes.push(dataType);
212
+
213
+ // Ask if this property is required
214
+ const isRequired = await askQuestion(`Is "${prop}" required? (y/n): `, 'n');
215
+ if (isRequired.toLowerCase() === 'y') {
216
+ data.required.push(prop);
217
+ }
218
+
219
+ // Ask if this property should be displayed in columns
220
+ const showInColumn = await askQuestion(`Show "${prop}" in table columns? (y/n): `, 'y');
221
+ data.inColumn.push(showInColumn.toLowerCase() === 'y' ? 'true' : 'false');
222
+
223
+ // Get colSpan for this property (1-12)
224
+ const defaultColSpan = widgetToColSpan[widget] || 6;
225
+ const colSpan = await askQuestion(`Column span for "${prop}" (1-12): `, defaultColSpan.toString());
226
+ data.colSpans.push(parseInt(colSpan));
227
+
228
+ // Get order for this property
229
+ const defaultOrder = propCount; // Default order is sequential
230
+ const order = await askQuestion(`Display order for "${prop}" (default: ${defaultOrder}): `, defaultOrder.toString());
231
+ data.orders.push(parseInt(order));
232
+
233
+ // Ask about sort
234
+ const enableSort = await askQuestion(`Enable sorting for "${prop}"? (y/n): `, 'y');
235
+ data.enableSorts.push(enableSort.toLowerCase() === 'y' ? 'true' : 'false');
236
+
237
+ // Ask about filter
238
+ const enableFilter = await askQuestion(`Enable filtering for "${prop}"? (y/n): `, 'y');
239
+ data.enableFilters.push(enableFilter.toLowerCase() === 'y' ? 'true' : 'false');
240
+
241
+ // Ask about inline filter
242
+ const enableInlineFilter = await askQuestion(`Enable inline filtering for "${prop}"? (y/n): `, 'n');
243
+ data.enableInlineFilters.push(enableInlineFilter.toLowerCase() === 'y' ? 'true' : 'false');
244
+
245
+ propCount++;
246
+ }
247
+
248
+ // Get icon
249
+ console.log('\nSelect an icon:');
250
+ console.log('1. Default icon (fa-light fa-default)');
251
+ console.log('2. Box (fa-solid fa-box)');
252
+ console.log('3. User (fa-solid fa-user)');
253
+ console.log('4. Shopping cart (fa-solid fa-shopping-cart)');
254
+ console.log('5. File (fa-solid fa-file)');
255
+ console.log('6. Custom icon');
256
+
257
+ const iconChoice = await askQuestion('Select option (1-6): ', '1');
258
+ const iconOptions = [
259
+ 'fa-light fa-default',
260
+ 'fa-solid fa-box',
261
+ 'fa-solid fa-user',
262
+ 'fa-solid fa-shopping-cart',
263
+ 'fa-solid fa-file'
264
+ ];
265
+
266
+ if (iconChoice >= 1 && iconChoice <= 5) {
267
+ data.icon = iconOptions[iconChoice - 1];
268
+ } else if (iconChoice == 6) {
269
+ data.icon = await askQuestion('Enter custom icon (format: fa-solid fa-xyz): ', 'fa-solid fa-star');
270
+ }
271
+
272
+ // Show summary
273
+ console.log('\n=== Summary ===');
274
+ console.log(`Module: ${data.moduleName}`);
275
+ console.log(`Entity: ${data.name}`);
276
+ console.log('Properties:');
277
+
278
+ // Sort properties by order for display
279
+ const propSummary = data.properties.map((prop, i) => ({
280
+ name: prop,
281
+ widget: data.widgets[i],
282
+ dataType: data.dataTypes[i],
283
+ required: data.required.includes(prop),
284
+ colSpan: data.colSpans[i],
285
+ order: data.orders[i],
286
+ enableSort: data.enableSorts[i],
287
+ enableFilter: data.enableFilters[i],
288
+ enableInlineFilter: data.enableInlineFilters[i],
289
+ inColumn: data.inColumn[i]
290
+ }));
291
+
292
+ // Sort by order
293
+ propSummary.sort((a, b) => a.order - b.order);
294
+
295
+ propSummary.forEach(prop => {
296
+ console.log(` - ${prop.name} (Widget: ${prop.widget}, Type: ${prop.dataType}${prop.required ? ', Required' : ''}, ColSpan: ${prop.colSpan}, Order: ${prop.order}, Sort: ${prop.enableSort ? 'Enabled' : 'Disabled'}, Filter: ${prop.enableFilter ? 'Enabled' : 'Disabled'}, Inline Filter: ${prop.enableInlineFilter ? 'Enabled' : 'Disabled'}, In Column: ${prop.inColumn === 'true' ? 'Yes' : 'No'})`);
297
+ });
298
+
299
+ console.log(`Icon: ${data.icon}`);
300
+
301
+ const confirm = await askQuestion('\nGenerate entity with these settings? (y/n): ', 'y');
302
+ if (confirm.toLowerCase() === 'y') {
303
+ runNxGenerator();
304
+ } else {
305
+ console.log('Operation cancelled');
306
+ rl.close();
307
+ }
308
+ }
309
+
310
+ // Helper function to ask questions and get answers
311
+ function askQuestion(question, defaultAnswer) {
312
+ return new Promise(resolve => {
313
+ const prompt = defaultAnswer ? `${question} [${defaultAnswer}] ` : question;
314
+
315
+ rl.question(prompt, (answer) => {
316
+ // If answer is empty and there's a default, use the default
317
+ const result = answer.trim() === '' && defaultAnswer ? defaultAnswer : answer.trim();
318
+ resolve(result);
319
+ });
320
+ });
321
+ }
322
+
323
+ // Helper function to select a widget with filtering capability
324
+ async function selectWidget(prompt) {
325
+ console.log(`\n${prompt}`);
326
+ console.log('Available widgets (you can type to filter):');
327
+
328
+ // Display widgets by groups
329
+ for (const [groupName, groupWidgets] of Object.entries(widgetGroups)) {
330
+ console.log(`\n${groupName} widgets:`);
331
+ groupWidgets.forEach((widget, index) => {
332
+ const widgetKey = Object.entries(widgetCatalog).find(([key, value]) => value === widget)?.[0] || '';
333
+ console.log(` ${(index + 1).toString().padStart(2)}: ${widget} (${widgetKey})`);
334
+ });
335
+ }
336
+
337
+ // Handling widget selection with filtering
338
+ let selectedWidget = '';
339
+ while (!selectedWidget) {
340
+ const input = await askQuestion('\nEnter widget name or number (or part of name to filter): ');
341
+
342
+ // Check if input is a number
343
+ if (!isNaN(input) && input > 0 && input <= Object.values(widgetCatalog).length) {
344
+ const allWidgets = Object.values(widgetCatalog);
345
+ selectedWidget = allWidgets[parseInt(input) - 1];
346
+ }
347
+ // Check if input exactly matches a widget name
348
+ else if (Object.values(widgetCatalog).includes(input)) {
349
+ selectedWidget = input;
350
+ }
351
+ // Check if input matches a widget key
352
+ else if (widgetCatalog[input]) {
353
+ selectedWidget = widgetCatalog[input];
354
+ }
355
+ // Filter widgets by input
356
+ else {
357
+ const filteredWidgets = Object.entries(widgetCatalog)
358
+ .filter(([key, value]) =>
359
+ key.toLowerCase().includes(input.toLowerCase()) ||
360
+ value.toLowerCase().includes(input.toLowerCase())
361
+ );
362
+
363
+ if (filteredWidgets.length === 1) {
364
+ selectedWidget = filteredWidgets[0][1]; // Pick the only match
365
+ }
366
+ else if (filteredWidgets.length > 1) {
367
+ console.log('\nFiltered widgets:');
368
+ filteredWidgets.forEach(([key, value], index) => {
369
+ console.log(` ${(index + 1).toString().padStart(2)}: ${value} (${key})`);
370
+ });
371
+
372
+ const selection = await askQuestion('Select number or continue typing to filter more: ');
373
+ if (!isNaN(selection) && selection > 0 && selection <= filteredWidgets.length) {
374
+ selectedWidget = filteredWidgets[parseInt(selection) - 1][1];
375
+ }
376
+ }
377
+ else {
378
+ console.log('No matches found. Try again.');
379
+ }
380
+ }
381
+ }
382
+
383
+ return selectedWidget;
384
+ }
385
+
386
+ // Run the NX generator with collected data
387
+ function runNxGenerator() {
388
+ // Handle special cases and ensure proper formatting
389
+
390
+ // For empty required array, use "_none_"
391
+ const requiredValue = data.required.length === 0 ? "_none_" : data.required.join(',');
392
+
393
+ // Ensure single values for colSpans and orders have trailing commas
394
+ let colSpansStr = data.colSpans.join(',');
395
+ if (data.colSpans.length === 1) {
396
+ colSpansStr = colSpansStr + ',';
397
+ }
398
+
399
+ let ordersStr = data.orders.join(',');
400
+ if (data.orders.length === 1) {
401
+ ordersStr = ordersStr + ',';
402
+ }
403
+
404
+ // Prepare arguments properly
405
+ const command = `cd "${projectRoot}" && npx nx g @acorex-platform/generator:create-module-entity` +
406
+ ` --moduleName=${data.moduleName}` +
407
+ ` --name=${data.name}` +
408
+ ` --properties=${data.properties.join(',')}` +
409
+ ` --dataTypes=${data.dataTypes.join(',')}` +
410
+ ` --required=${requiredValue}` +
411
+ ` --colSpans=${colSpansStr}` +
412
+ ` --orders=${ordersStr}` +
413
+ ` --icon="${data.icon}"` +
414
+ ` --enableSorts=${data.enableSorts.join(',')}` +
415
+ ` --enableFilters=${data.enableFilters.join(',')}` +
416
+ ` --enableInlineFilters=${data.enableInlineFilters.join(',')}` +
417
+ ` --inColumn=${data.inColumn.join(',')}` +
418
+ (isDryRun ? ' --dryRun' : '');
419
+
420
+ console.log(`\nRunning: ${command}`);
421
+
422
+ try {
423
+ // Execute the command as a shell command to ensure proper environment
424
+ const { execSync } = require('child_process');
425
+ const options = {
426
+ stdio: 'inherit',
427
+ shell: true
428
+ };
429
+
430
+ execSync(command, options);
431
+ console.log(`\nGenerator completed successfully`);
432
+ } catch (error) {
433
+ console.error(`\nGenerator failed with error: ${error.message}`);
434
+
435
+ // Show more detailed error information
436
+ if (error.stderr) {
437
+ console.error(`Error details: ${error.stderr.toString()}`);
438
+ }
439
+ } finally {
440
+ rl.close();
441
+ }
442
+ }
443
+
444
+ // Start the prompts
445
+ runPrompts().catch(err => {
446
+ console.error('An error occurred:', err);
447
+ rl.close();
448
+ });
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync } = require('child_process');
4
+
5
+ // Check for --dryRun flag at the beginning
6
+ const isDryRun = process.argv.includes('--dryRun');
7
+
8
+ // Store predefined data
9
+ const data = {
10
+ moduleName: 'test',
11
+ name: 't1',
12
+ properties: ['title', 'name'],
13
+ widgets: ['text-editor', 'text-editor'],
14
+ dataTypes: ['string', 'string'],
15
+ required: ['name'],
16
+ colSpans: [6, 6],
17
+ orders: [1, 2],
18
+ icon: 'fa-light fa-default'
19
+ };
20
+
21
+ console.log('\n=== AcoreX Platform Interactive Entity Generator (Test Mode) ===\n');
22
+ console.log('Using predefined values:');
23
+ console.log(`Module: ${data.moduleName}`);
24
+ console.log(`Entity: ${data.name}`);
25
+ console.log(`Properties: ${data.properties.join(', ')}`);
26
+ console.log(`Required: ${data.required.join(', ')}`);
27
+ console.log(`Icon: ${data.icon}`);
28
+
29
+ // Run the NX generator with the predefined data
30
+ function runNxGenerator() {
31
+ // Format the command
32
+ const command = `cd ../../.. && npx nx g @acorex-platform/generator:create-module-entity --moduleName=${data.moduleName} --name=${data.name} --properties=${data.properties.join(',')} --dataTypes=${data.dataTypes.join(',')} --required=${data.required.join(',')} --colSpans=${data.colSpans.join(',')} --orders=${data.orders.join(',')} --icon="${data.icon}"${isDryRun ? ' --dryRun' : ''}`;
33
+
34
+ console.log(`\nRunning: ${command}`);
35
+
36
+ try {
37
+ // Execute the command
38
+ const output = execSync(command, { stdio: 'inherit' });
39
+ console.log('\nGenerator completed successfully');
40
+ return 0;
41
+ } catch (error) {
42
+ console.error(`\nGenerator failed with error: ${error.message}`);
43
+ return 1;
44
+ }
45
+ }
46
+
47
+ // Run the generator
48
+ process.exit(runNxGenerator());
@@ -7,7 +7,6 @@ import { BrowserModule } from '@angular/platform-browser';
7
7
  import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
8
8
  import { RouterModule, provideRouter, withEnabledBlockingInitialNavigation } from '@angular/router';
9
9
  import { EffectsModule } from '@ngrx/effects';
10
- import { StoreModule } from '@ngrx/store';
11
10
  import { StoreDevtoolsModule } from '@ngrx/store-devtools';
12
11
  import { AppComponent } from './app.component';
13
12
  import { appRoutes } from './app.routes';
@@ -41,8 +40,6 @@ import { AXMSampleEntityModule } from './modules/<%= name %>/sample/sample.modul
41
40
  bindToComponentInputs: true,
42
41
  onSameUrlNavigation: 'reload',
43
42
  }),
44
- StoreModule.forRoot([]),
45
- EffectsModule.forRoot(),
46
43
  AXFormatModule.forRoot(),
47
44
  AXValidationModule.forRoot(),
48
45
  //
@@ -1,4 +1,4 @@
1
- import { AXMEntityCrudServiceImpl } from '@acorex/platform/common';
1
+ import { AXMEntityCrudServiceImpl } from '@acorex/platform/layout/entity';
2
2
  import { Injectable } from '@angular/core';
3
3
  import { AXMSampleModuleConst } from '../const';
4
4
  import { AXMSampleEntityModel } from './sample.types';
@@ -1,4 +1,4 @@
1
- import { AXPEntityModel } from '@acorex/platform/common';
1
+ import { AXPEntityModel } from '@acorex/platform/layout/entity';
2
2
 
3
3
  export interface AXMSampleEntityModel extends AXPEntityModel<string> {
4
4
  firstname?: string;
@@ -0,0 +1,9 @@
1
+ export * from './lib/<%= fileName %>.module';
2
+ //export * from './lib/components';
3
+ export * from './lib/const';
4
+ //export * from './lib/entities';
5
+ export * from './lib/entity.provider';
6
+ export * from './lib/menu.provider';
7
+ export * from './lib/search-command.provider';
8
+ export * from './lib/setting.provider';
9
+ //export * from './lib/pages';
@@ -0,0 +1,44 @@
1
+ import { NgModule } from "@angular/core";
2
+ import { AXP_PERMISSION_PROVIDER } from '@acorex/platform/auth';
3
+ import { AXP_MENU_PROVIDER, AXP_SEARCH_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER } from '@acorex/platform/common';
4
+ import { AXP_ENTITY_DEFINITION_LOADER } from '@acorex/platform/layout/entity';
5
+ import { AXMMenuProvider } from './menu.provider';
6
+ import { AXMEntityProvider } from './entity.provider';
7
+ import { AXMPermissionProvider } from './permission.provider';
8
+ import { AXMSettingProvider } from './setting.provider';
9
+ import { AXMSearchCommandProvider } from './search-command.provider';
10
+
11
+ @NgModule({
12
+ imports: [],
13
+ exports: [],
14
+ declarations: [],
15
+ providers : [
16
+
17
+ {
18
+ provide: AXP_MENU_PROVIDER,
19
+ useClass: AXMMenuProvider,
20
+ multi: true,
21
+ },
22
+ {
23
+ provide: AXP_ENTITY_DEFINITION_LOADER,
24
+ useClass: AXMEntityProvider,
25
+ multi: true,
26
+ },
27
+ {
28
+ provide: AXP_SETTING_DEFINITION_PROVIDER,
29
+ useClass: AXMSettingProvider,
30
+ multi: true,
31
+ },
32
+ {
33
+ provide: AXP_SEARCH_PROVIDER,
34
+ useClass: AXMSearchCommandProvider,
35
+ multi: true,
36
+ },
37
+ {
38
+ provide: AXP_PERMISSION_PROVIDER,
39
+ useClass: AXMPermissionProvider,
40
+ multi: true,
41
+ },
42
+ ]
43
+ })
44
+ export class AXM<%= className %>Module {}
@@ -0,0 +1,19 @@
1
+ const config = {
2
+ i18n: '<%= fileName %>',
3
+ };
4
+ export const RootConfig = {
5
+ config,
6
+ module: {
7
+ module: '<%= name %>',
8
+ name: '<%= className %>',
9
+ title: `t('module-name', {scope:"${config.i18n}"})`,
10
+ icon: 'fa-light fa-file-invoice',
11
+ },
12
+ entities: {
13
+ // category: {
14
+ // name: 'Category',
15
+ // title: 't("category", { scope: "common" })',
16
+ // icon: 'fa-light fa-list'
17
+ // },
18
+ },
19
+ };
@@ -0,0 +1,33 @@
1
+ import { AXPEntity } from '@acorex/platform/common';
2
+ import {
3
+ AXPEntityDefinitionLoader,
4
+ AXPEntityDefinitionPreloader,
5
+ AXPEntityPreloadEntity,
6
+ } from '@acorex/platform/layout/entity';
7
+ import { Injectable, Injector, inject } from '@angular/core';
8
+ import { RootConfig } from './const';
9
+
10
+ @Injectable()
11
+ export class AXMEntityProvider implements AXPEntityDefinitionLoader, AXPEntityDefinitionPreloader {
12
+ private injector = inject(Injector);
13
+
14
+ public preload(): AXPEntityPreloadEntity[] {
15
+ const module = RootConfig.module.name;
16
+ return Array.from(Object.values(RootConfig.entities)).map((entity: any) => ({
17
+ module: module,
18
+ entity: entity.name,
19
+ }));
20
+ }
21
+
22
+ async get(moduleName: string, entityName: string): Promise<AXPEntity | null> {
23
+ if (moduleName == RootConfig.module.name) {
24
+ switch (
25
+ entityName
26
+ // case RootConfig.entities.sample.name:
27
+ // return (await import('./entities/sample/sample.entity')).factory(this.injector);
28
+ ) {
29
+ }
30
+ }
31
+ return null;
32
+ }
33
+ }