data-primals-engine 1.3.3 → 1.4.0

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 (36) hide show
  1. package/README.md +797 -782
  2. package/client/README.md +20 -0
  3. package/client/package-lock.json +717 -151
  4. package/client/package.json +37 -36
  5. package/client/src/App.jsx +9 -10
  6. package/client/src/App.scss +42 -1
  7. package/client/src/Dashboard.jsx +349 -208
  8. package/client/src/DashboardView.jsx +569 -547
  9. package/client/src/DataEditor.jsx +20 -2
  10. package/client/src/DataLayout.jsx +54 -13
  11. package/client/src/DataTable.jsx +807 -760
  12. package/client/src/DataTable.scss +187 -90
  13. package/client/src/Dialog.scss +0 -3
  14. package/client/src/Field.jsx +1783 -1583
  15. package/client/src/ModelCreator.jsx +25 -3
  16. package/client/src/ModelCreatorField.jsx +906 -804
  17. package/client/src/ModelList.jsx +20 -2
  18. package/client/src/constants.js +16 -4
  19. package/client/src/contexts/UIContext.jsx +19 -10
  20. package/client/src/translations.js +265 -3
  21. package/package.json +4 -3
  22. package/server.js +1 -0
  23. package/src/core.js +18 -0
  24. package/src/defaultModels.js +70 -10
  25. package/src/email.js +2 -1
  26. package/src/filter.js +260 -256
  27. package/src/i18n.js +503 -30
  28. package/src/modules/data/data.core.js +5 -1
  29. package/src/modules/data/data.history.js +489 -489
  30. package/src/modules/data/data.js +76 -10
  31. package/src/modules/data/data.routes.js +3 -20
  32. package/src/modules/user.js +19 -0
  33. package/src/modules/workflow.js +1808 -1817
  34. package/client/public/demo/26899917-d1ba-4df4-bb33-48d09a8778da.jpg +0 -0
  35. package/client/public/demo/4b9894c7-12cd-466d-8fd3-a2757b09ec96.jpg +0 -0
  36. package/client/public/demo/7ed369ac-a1a2-4b45-b0cd-4fd5bcf5a75a.jpg +0 -0
@@ -2,6 +2,7 @@
2
2
  export const defaultModels = {
3
3
  permission: {
4
4
  "name": "permission",
5
+ "icon": "FaKey",
5
6
  "description": "",
6
7
  "fields": [
7
8
  {
@@ -17,6 +18,7 @@ export const defaultModels = {
17
18
  },
18
19
  role: {
19
20
  name: 'role',
21
+ "icon": "FaUserTag",
20
22
  "description": "",
21
23
  fields: [
22
24
  { name: 'name', type: 'string_t', required: true, unique: true, color: '#363636' },
@@ -26,6 +28,7 @@ export const defaultModels = {
26
28
  user: {
27
29
  name: 'user',
28
30
  "description": "",
31
+ "icon": "FaUser",
29
32
  locked: true,
30
33
  fields: [
31
34
  { name: 'username', type: 'string', required: true, unique: true, color: '#3C7D08' },
@@ -47,6 +50,7 @@ export const defaultModels = {
47
50
  ]
48
51
  },
49
52
  userPermission: {
53
+ "icon": "FaUserCheck",
50
54
  "name": "userPermission",
51
55
  "description": "Gère les exceptions aux permissions des rôles pour un utilisateur (ajouts ou retraits, permanents ou temporaires).",
52
56
  "fields": [
@@ -81,6 +85,7 @@ export const defaultModels = {
81
85
  },
82
86
  token: {
83
87
  name: 'token',
88
+ "icon": "FaKey",
84
89
  "description": "",
85
90
  fields: [
86
91
  { name: 'name', type: 'string' },
@@ -90,6 +95,7 @@ export const defaultModels = {
90
95
  },
91
96
  translation: {
92
97
  name: 'translation',
98
+ "icon": "FaLanguage",
93
99
  locked: true,
94
100
  "description": "",
95
101
  fields: [
@@ -100,6 +106,7 @@ export const defaultModels = {
100
106
  },
101
107
  lang: {
102
108
  name: 'lang',
109
+ "icon": "FaGlobe",
103
110
  locked: true,
104
111
  "description": "",
105
112
  fields: [
@@ -109,6 +116,7 @@ export const defaultModels = {
109
116
  },
110
117
  currency: {
111
118
  name: 'currency',
119
+ "icon": "FaMoneyBill",
112
120
  "description": "",
113
121
  locked: true,
114
122
  fields: [
@@ -121,6 +129,7 @@ export const defaultModels = {
121
129
  },
122
130
  channel: {
123
131
  name: 'channel',
132
+ "icon": "FaComments",
124
133
  "description": "",
125
134
  fields: [
126
135
  { name: 'name', type: 'string_t', required: true, unique: true }, // Nom du canal (ex: "email", "SMS")
@@ -130,6 +139,7 @@ export const defaultModels = {
130
139
  },
131
140
  message: {
132
141
  name: 'message',
142
+ "icon": "FaEnvelope",
133
143
  "description": "",
134
144
  locked: true,
135
145
  fields: [
@@ -148,6 +158,7 @@ export const defaultModels = {
148
158
  },
149
159
  alert: {
150
160
  name: "alert",
161
+ "icon": "FaBell",
151
162
  description: "Définit les règles pour les alertes et les insights automatiques.",
152
163
  fields: [
153
164
  { name: "name", type: "string", required: true, asMain: true },
@@ -169,23 +180,31 @@ export const defaultModels = {
169
180
  cronMask: [false, true, true, true, true, true],
170
181
  hint: "À quelle fréquence vérifier si la condition est remplie."
171
182
  },
183
+ { name: "isActive", type: "boolean", default: true },
172
184
  {
173
- name: "notificationChannel",
174
- type: "enum",
175
- items: ["in_app", "email"],
176
- default: "in_app"
185
+ name: "sendEmail",
186
+ type: "boolean",
187
+ default: false,
188
+ hint: "Cochez pour envoyer également une notification par e-mail."
177
189
  },
178
- { name: "isActive", type: "boolean", default: true },
179
190
  {
180
191
  name: "lastNotifiedAt",
181
192
  type: "datetime",
182
193
  required: false, // Important: ce champ est géré par le système
183
194
  hint: "Timestamp de la dernière notification envoyée pour cette alerte."
195
+ },
196
+ {
197
+ name: "message",
198
+ type: "richtext_t",
199
+ required: false,
200
+ hint: "Message personnalisé pour l'e-mail. Si vide, un message par défaut sera utilisé. Vous pouvez utiliser les variables {count}, {alert.name}....",
201
+ condition: { $eq: ["$sendEmail", true] }
184
202
  }
185
203
  ]
186
204
  },
187
205
  env: {
188
206
  name: "env",
207
+ "icon": "FaCog",
189
208
  description: "Définit les variables d'environnement qui seront accessibles dans vos scripts et webhooks.",
190
209
  fields: [
191
210
  { name: "name", type: "string", required: true, unique: true, asMain: true },
@@ -194,6 +213,7 @@ export const defaultModels = {
194
213
  },
195
214
  webpage: {
196
215
  name: 'webpage',
216
+ "icon": "FaFileAlt",
197
217
  locked: true,
198
218
  "description": "",
199
219
  fields: [
@@ -210,6 +230,7 @@ export const defaultModels = {
210
230
  },
211
231
  content: {
212
232
  name: 'content',
233
+ "icon": "FaFileAlt",
213
234
  "description": "",
214
235
  fields: [
215
236
  { name: 'lang', type: 'relation', relation: 'lang' },
@@ -240,6 +261,7 @@ export const defaultModels = {
240
261
  },
241
262
  resource: {
242
263
  name: 'resource',
264
+ "icon": "FaBoxOpen",
243
265
  "description": "",
244
266
  fields: [
245
267
  { name: "source", type: "url"},
@@ -248,6 +270,7 @@ export const defaultModels = {
248
270
  },
249
271
  taxonomy: {
250
272
  name: 'taxonomy',
273
+ "icon": "FaTags",
251
274
  "description": "",
252
275
  fields: [
253
276
  { name: 'name', type: 'string_t', required: true, color: '#71A314' },
@@ -261,6 +284,7 @@ export const defaultModels = {
261
284
  contact: {
262
285
  locked: true,
263
286
  name: 'contact',
287
+ "icon": "FaAddressBook",
264
288
  "description": "",
265
289
  fields: [
266
290
  { name: 'legalName', type: 'string', asMain: true, color: '#D9D9D9' },
@@ -274,6 +298,7 @@ export const defaultModels = {
274
298
 
275
299
  location: {
276
300
  "name": "location",
301
+ "icon": "FaMapMarkerAlt",
277
302
  locked: true,
278
303
  "description": "",
279
304
  "fields": [
@@ -332,6 +357,7 @@ export const defaultModels = {
332
357
 
333
358
  brand: {
334
359
  name: 'brand',
360
+ "icon": "FaTrademark",
335
361
  "description": "",
336
362
  fields: [
337
363
  { name: 'name', type: 'string', required: true },
@@ -342,6 +368,7 @@ export const defaultModels = {
342
368
 
343
369
  product: {
344
370
  name: 'product',
371
+ "icon": "FaShoppingBag",
345
372
  "description": "",
346
373
  fields: [
347
374
  { name: 'name', type: 'string_t', required: true },
@@ -359,6 +386,7 @@ export const defaultModels = {
359
386
  },
360
387
  productVariant: {
361
388
  name: 'productVariant',
389
+ "icon": "FaBox",
362
390
  "description": "",
363
391
  fields: [
364
392
  { name: 'product', type: 'relation', relation: 'product', required: true },
@@ -374,6 +402,7 @@ export const defaultModels = {
374
402
  },
375
403
  cart: {
376
404
  name: 'cart',
405
+ "icon": "FaShoppingCart",
377
406
  "description": "",
378
407
  fields: [
379
408
  { name: 'user', type: 'relation', relation: 'user', required: true },
@@ -385,6 +414,7 @@ export const defaultModels = {
385
414
  },
386
415
  cartItem: {
387
416
  name: 'cartItem',
417
+ "icon": "FaShoppingBasket",
388
418
  "description": "",
389
419
  fields: [
390
420
  { name: 'product', type: 'relation', relation: 'product', required: true },
@@ -394,6 +424,7 @@ export const defaultModels = {
394
424
  },
395
425
  discount: {
396
426
  name: "discount",
427
+ "icon": "FaTicketAlt",
397
428
  locked: true,
398
429
  "description": "",
399
430
  fields: [
@@ -411,6 +442,7 @@ export const defaultModels = {
411
442
  },
412
443
  order: {
413
444
  name: "order",
445
+ "icon": "FaClipboardList",
414
446
  locked: true,
415
447
  "description": "",
416
448
  fields: [
@@ -432,6 +464,7 @@ export const defaultModels = {
432
464
  },
433
465
  invoice: {
434
466
  name: 'invoice',
467
+ "icon": "FaFileInvoice",
435
468
  "description": "",
436
469
  fields: [
437
470
  { name: 'order', type: 'relation', relation: 'order', required: true },
@@ -443,6 +476,7 @@ export const defaultModels = {
443
476
  },
444
477
  userSubscription: {
445
478
  name: 'userSubscription',
479
+ "icon": "FaCalendarCheck",
446
480
  "description": "",
447
481
  locked: true,
448
482
  fields: [
@@ -463,6 +497,7 @@ export const defaultModels = {
463
497
  },
464
498
  stock: {
465
499
  name: 'stock',
500
+ "icon": "FaWarehouse",
466
501
  "description": "",
467
502
  fields: [
468
503
  { name: 'product', type: 'relation', relation: 'product', required: true },
@@ -474,6 +509,7 @@ export const defaultModels = {
474
509
  },
475
510
  stockAlert: {
476
511
  name: 'stockAlert',
512
+ "icon": "FaExclamationTriangle",
477
513
  "description": "",
478
514
  fields: [
479
515
  { name: 'user', type: 'relation', relation: 'user', required: true },
@@ -484,6 +520,7 @@ export const defaultModels = {
484
520
  },
485
521
  shipment: {
486
522
  name: 'shipment',
523
+ "icon": "FaTruck",
487
524
  "description": "",
488
525
  fields: [
489
526
  { name: 'order', type: 'relation', relation: 'order', required: true },
@@ -497,6 +534,7 @@ export const defaultModels = {
497
534
  warehouse: {
498
535
  name: 'warehouse',
499
536
  "description": "",
537
+ "icon": "FaWarehouse",
500
538
  fields: [
501
539
  { name: 'name', type: 'string_t', required: true },
502
540
  { name: 'location', type: 'relation', relation: 'location' },
@@ -506,6 +544,7 @@ export const defaultModels = {
506
544
  'return': {
507
545
  name: "return",
508
546
  "description": "",
547
+ "icon": "FaUndo",
509
548
  fields: [
510
549
  { "name": "order", "type": "relation", "relation": "order", "required": true },
511
550
  { "name": "user", "type": "relation", relation: "user" },
@@ -519,6 +558,7 @@ export const defaultModels = {
519
558
  },
520
559
  returnItem: {
521
560
  name: 'returnItem',
561
+ "icon": "FaBoxOpen",
522
562
  "description": "",
523
563
  fields: [
524
564
  { name: 'return', type: 'relation', relation: 'return', required: true },
@@ -530,6 +570,7 @@ export const defaultModels = {
530
570
  },
531
571
  ticket: {
532
572
  name: 'ticket',
573
+ "icon": "FaTicketAlt",
533
574
  "description": "",
534
575
  locked: true,
535
576
  fields: [
@@ -547,6 +588,7 @@ export const defaultModels = {
547
588
  },
548
589
  review: {
549
590
  name: "review",
591
+ "icon": "FaStar",
550
592
  "description": "",
551
593
  fields: [
552
594
  { "name": "user", "type": "relation", relation: "user" },
@@ -559,6 +601,7 @@ export const defaultModels = {
559
601
  },
560
602
  device: {
561
603
  name: "device",
604
+ "icon": "FaMobile",
562
605
  "description": "",
563
606
  fields: [
564
607
  { "name": "location", "type": "relation", relation: 'location' },
@@ -568,6 +611,7 @@ export const defaultModels = {
568
611
  // Modèle pour l'exercice comptable et l'entreprise
569
612
  accountingExercise: {
570
613
  name: 'accountingExercise',
614
+ "icon": "FaBook",
571
615
  description: "Représente un exercice comptable pour une entreprise donnée.",
572
616
  fields: [
573
617
  { name: 'name', type: 'string_t', 'required': true, unique: true, hint: "Intitulé de l'exercice comptable" },
@@ -581,6 +625,7 @@ export const defaultModels = {
581
625
  // Modèle pour définir la structure des lignes comptables (le "plan")
582
626
  accountingLineItem: {
583
627
  name: 'accountingLineItem',
628
+ "icon": "FaListAlt",
584
629
  description: "Définit une ligne/catégorie dans un document comptable.",
585
630
  locked: true, // Probablement géré par l'application, pas par l'utilisateur final
586
631
  fields: [
@@ -610,6 +655,7 @@ export const defaultModels = {
610
655
  },
611
656
  accountingEntry: {
612
657
  "name": "accountingEntry",
658
+ "icon": "FaPenAlt",
613
659
  "description": "",
614
660
  "fields": [
615
661
  {
@@ -679,6 +725,7 @@ export const defaultModels = {
679
725
  },
680
726
  employee: {
681
727
  "name": "employee",
728
+ "icon": "FaUserTie",
682
729
  "description": "",
683
730
  "fields": [
684
731
  {
@@ -819,6 +866,7 @@ export const defaultModels = {
819
866
  },
820
867
  workflow: {
821
868
  name: 'workflow',
869
+ "icon": "FaProjectDiagram",
822
870
  description: "Defines an automated process.",
823
871
  fields: [
824
872
  { name: 'name', type: 'string_t', required: true, hint: "Unique name for the workflow (e.g., 'Order Validation', 'Low Stock Notification')." },
@@ -828,6 +876,7 @@ export const defaultModels = {
828
876
  },
829
877
  workflowTrigger: {
830
878
  name: 'workflowTrigger',
879
+ "icon": "FaPlay",
831
880
  description: "Represents an event that can initiate a workflow.",
832
881
  fields: [
833
882
  { name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow this step belongs to." },
@@ -879,6 +928,7 @@ export const defaultModels = {
879
928
  },
880
929
  workflowStep: {
881
930
  name: 'workflowStep',
931
+ "icon": "FaStepForward",
882
932
  description: "A single step within a workflow process.",
883
933
  fields: [
884
934
  { name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow this step belongs to." },
@@ -892,6 +942,7 @@ export const defaultModels = {
892
942
  },
893
943
  workflowAction: {
894
944
  name: 'workflowAction',
945
+ "icon": "FaCogs",
895
946
  description: "Defines a specific operation to be performed by a workflow step.",
896
947
  fields: [
897
948
  { name: 'name', type: 'string_t', required: true, hint: "Name of the action (e.g., 'Update Order Status', 'Send Email', 'Call Payment API')." },
@@ -991,6 +1042,7 @@ export const defaultModels = {
991
1042
 
992
1043
  workflowRun: {
993
1044
  name: 'workflowRun',
1045
+ "icon": "FaRunning",
994
1046
  description: "Tracks a specific execution instance of a workflow.",
995
1047
  fields: [
996
1048
  { name: 'workflow', type: 'relation', relation: 'workflow', required: true, hint: "The workflow definition that was executed." },
@@ -1013,6 +1065,7 @@ export const defaultModels = {
1013
1065
  },
1014
1066
  dashboard:{
1015
1067
  name: 'dashboard', // Nom technique du modèle
1068
+ "icon": "FaTachometerAlt",
1016
1069
  description: "Configuration d'un tableau de bord personnalisé par l'utilisateur.", // Description du modèle
1017
1070
  locked: false, // Indique si le modèle peut être modifié par l'utilisateur (false = modifiable)
1018
1071
  fields: [
@@ -1036,11 +1089,12 @@ export const defaultModels = {
1036
1089
  hint: "Structure JSON décrivant l'organisation des KPIs. Exemple : { \"type\": \"columns\", \"columns\": [ [\"kpi_id_1\"], [\"kpi_id_2\", \"kpi_id_3\"] ] }."
1037
1090
  },
1038
1091
  {
1039
- name: 'settings', // Paramètres spécifiques à ce tableau de bord
1040
- type: 'code', // Utilisation du type 'code' pour stocker des paramètres JSON
1041
- language: 'json',
1042
- default: { "defaultTimeRange": "last_7_days", "refreshInterval": null }, // Paramètres par défaut (plage de temps, pas de rafraîchissement auto)
1043
- hint: "Paramètres JSON pour le tableau de bord, comme la plage de temps par défaut ('defaultTimeRange') ou l'intervalle de rafraîchissement en secondes ('refreshInterval')."
1092
+ name: 'refreshInterval',
1093
+ type: 'number',
1094
+ delay: true, // Sera interprété par le front-end comme un champ de durée
1095
+ unit: 's',
1096
+ min: 0,
1097
+ hint: "Intervalle de rafraîchissement automatique en secondes. Laisser vide ou à 0 pour désactiver."
1044
1098
  },
1045
1099
  {
1046
1100
  name: 'isDefault', // Indicateur pour le tableau de bord par défaut
@@ -1052,6 +1106,7 @@ export const defaultModels = {
1052
1106
  },
1053
1107
  'request': {
1054
1108
  name: 'request',
1109
+ "icon": "FaExchangeAlt",
1055
1110
  description: "Journal des requêtes reçues par l'API.",
1056
1111
  locked: true, // Géré par le système, non modifiable directement par l'utilisateur via l'UI standard
1057
1112
  fields: [
@@ -1137,6 +1192,7 @@ export const defaultModels = {
1137
1192
 
1138
1193
  kpi : {
1139
1194
  name: 'kpi',
1195
+ "icon": "FaChartLine",
1140
1196
  description: "Configuration d'un Indicateur Clé de Performance (KPI)",
1141
1197
  fields: [
1142
1198
  { name: 'name', type: 'string_t', required: true, hint: "Nom affiché du KPI (ex: Chiffre d'affaires total)" },
@@ -1200,6 +1256,7 @@ export const defaultModels = {
1200
1256
  },
1201
1257
  imageGallery: {
1202
1258
  name: 'imageGallery',
1259
+ "icon": "FaImages",
1203
1260
  description: "Représente une galerie d'images avec un titre et une description.",
1204
1261
  locked: false, // Les utilisateurs peuvent créer/gérer leurs galeries
1205
1262
  fields: [
@@ -1241,6 +1298,7 @@ export const defaultModels = {
1241
1298
  },
1242
1299
  budget: {
1243
1300
  name: 'budget',
1301
+ "icon": "FaMoneyCheck",
1244
1302
  description: "Un budget permet de lister vos transactions personnelles.",
1245
1303
  fields: [
1246
1304
  {
@@ -1312,6 +1370,7 @@ export const defaultModels = {
1312
1370
  },
1313
1371
  event: {
1314
1372
  "name": "event",
1373
+ "icon": "FaCalendar",
1315
1374
  "description": "A model for managing events, conferences, meetups, and gatherings.",
1316
1375
  "fields": [
1317
1376
  {
@@ -1424,6 +1483,7 @@ export const defaultModels = {
1424
1483
  },
1425
1484
  endpoint: {
1426
1485
  name: "endpoint",
1486
+ "icon": "FaCode",
1427
1487
  description: "Defines custom API endpoints that execute a server-side script.",
1428
1488
  fields: [
1429
1489
  {
package/src/email.js CHANGED
@@ -47,7 +47,7 @@ const createTransporter = (smtpConfig) => {
47
47
  export const sendEmail = async (email = "", data, smtpConfig = null, lang, tpl = null) => {
48
48
  const contactEmail = smtpConfig ? (smtpConfig.from || emailDefaultConfig.from) :"Our company <noreply@ourdomain.tld>";
49
49
  const emails = Array.isArray(email) ? email : [email];
50
- if (emails.length === 0) return;
50
+ if (emails.length === 0) return false;
51
51
 
52
52
  // Choisir le transporteur à utiliser
53
53
  const transporter = smtpConfig ? createTransporter(smtpConfig||emailDefaultConfig) : defaultTransporter;
@@ -76,6 +76,7 @@ export const sendEmail = async (email = "", data, smtpConfig = null, lang, tpl =
76
76
  try {
77
77
  await Promise.all(sendPromises);
78
78
  console.log(`Email(s) sent successfully to : ${emails.join(', ')}`);
79
+ return true;
79
80
  } catch (error) {
80
81
  console.error("Error when sending to one ore more emails :", error);
81
82
  // Vous pouvez relancer l'erreur si vous voulez que l'appelant la gère