data-primals-engine 1.3.0 → 1.3.1
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/CHANGELOG.md +440 -0
- package/README.md +782 -748
- package/client/src/App.scss +4 -0
- package/client/src/DataLayout.jsx +2 -2
- package/client/src/DataTable.jsx +19 -2
- package/client/src/Field.jsx +3 -2
- package/client/src/HistoryDialog.jsx +96 -0
- package/client/src/HistoryDialog.scss +73 -0
- package/client/src/ModelCreator.jsx +36 -15
- package/client/src/ModelCreatorField.jsx +5 -6
- package/client/src/hooks/useTutorials.jsx +1 -1
- package/client/src/translations.js +155 -1
- package/package.json +2 -2
- package/src/HistoryDialog.jsx +86 -0
- package/src/HistoryDialog.scss +77 -0
- package/src/email.js +1 -1
- package/src/engine.js +6 -6
- package/src/events.js +15 -5
- package/src/gameObject.js +0 -29
- package/src/modules/data/data.history.js +304 -0
- package/src/modules/data/data.js +4620 -4601
- package/src/modules/data/data.routes.js +4 -4
- package/src/modules/mongodb.js +17 -1
- package/src/modules/user.js +9 -3
- package/src/packs.js +2 -1
- package/src/services/stripe.js +67 -13
- package/src/workers/crypto-worker.js +3 -3
- package/test/data.backup.integration.test.js +5 -0
- package/test/data.history.integration.test.js +193 -0
- package/test/data.integration.test.js +79 -39
- package/test/events.test.js +27 -27
- package/test/globalTeardown.js +1 -0
- package/test/model.integration.test.js +5 -0
- package/test/workflow.actions.integration.test.js +2 -0
- package/test/workflow.integration.test.js +2 -0
- package/test/workflow.robustness.test.js +2 -0
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
export const websiteTranslations = {
|
|
3
3
|
fr: {
|
|
4
4
|
translation: {
|
|
5
|
+
"modelcreator.field.history": "Permet d'afficher et de superviser les modifications effectuées sur vos données. Consomme de l'espace.'",
|
|
6
|
+
"history": "Historique",
|
|
7
|
+
//
|
|
8
|
+
"history.op.delete": "Suppression",
|
|
9
|
+
"history.datePrefix": "On",
|
|
10
|
+
"history.byUser": "by",
|
|
11
|
+
"history.version": "Version:",
|
|
12
|
+
"history.error": "Impossible de charger l'historique.",
|
|
13
|
+
"history.title": "Historique de l'enregistrement",
|
|
14
|
+
"history.loading": "Chargement de l'historique",
|
|
15
|
+
"history.noHistory": "Aucun historique trouvé pour cet enregistrement",
|
|
5
16
|
|
|
6
17
|
"field_endpoint_isPublic": "Accès public",
|
|
7
18
|
"field_endpoint_isPublic_hint": "Si coché, ce point d'accès sera accessible sans authentification. Le script s'exécutera avec les droits du propriétaire du point d'accès.",
|
|
@@ -543,6 +554,19 @@ export const websiteTranslations = {
|
|
|
543
554
|
},
|
|
544
555
|
en: {
|
|
545
556
|
translation: {
|
|
557
|
+
"modelcreator.field.history": "Allows you to view and monitor changes made to your data. Consumes space.",
|
|
558
|
+
"history": "History",
|
|
559
|
+
"history.op.create": "Creation",
|
|
560
|
+
"history.op.update": "Update",
|
|
561
|
+
"history.op.delete": "Deletion",
|
|
562
|
+
"history.datePrefix": "On",
|
|
563
|
+
"history.byUser": "by",
|
|
564
|
+
"history.version": "Version:",
|
|
565
|
+
"history.error": "Unable to load history.",
|
|
566
|
+
"history.title": "Record History",
|
|
567
|
+
"history.loading": "Loading History",
|
|
568
|
+
"history.noHistory": "No history found for this record",
|
|
569
|
+
|
|
546
570
|
"packs.manualInstall": "Import",
|
|
547
571
|
"packs.manualInstall.title": "Manual Pack Installation",
|
|
548
572
|
"packs.manualInstall.instructions": "Paste the configuration JSON of the pack you want to install here.",
|
|
@@ -1957,6 +1981,20 @@ export const websiteTranslations = {
|
|
|
1957
1981
|
},
|
|
1958
1982
|
es: {
|
|
1959
1983
|
translation: {
|
|
1984
|
+
"modelcreator.field.history": "Permite ver y supervisar los cambios realizados en los datos. Consume espacio.",
|
|
1985
|
+
"history": "Historial",
|
|
1986
|
+
|
|
1987
|
+
"history.op.create": "Creación",
|
|
1988
|
+
"history.op.update": "Actualización",
|
|
1989
|
+
"history.op.delete": "Eliminación",
|
|
1990
|
+
"history.datePrefix": "Activado",
|
|
1991
|
+
"history.byUser": "por",
|
|
1992
|
+
"history.version": "Versión:",
|
|
1993
|
+
"history.error": "No se puede cargar el historial",
|
|
1994
|
+
"history.title": "Historial del registro",
|
|
1995
|
+
"history.loading": "Cargando historial",
|
|
1996
|
+
"history.noHistory": "No se encontró historial para este registro",
|
|
1997
|
+
|
|
1960
1998
|
"packs.manualInstall": "Importar",
|
|
1961
1999
|
"packs.manualInstall.title": "Instalación manual del paquete",
|
|
1962
2000
|
"packs.manualInstall.instructions": "Pegue aquí el JSON de configuración del paquete que desea instalar.",
|
|
@@ -3375,6 +3413,19 @@ export const websiteTranslations = {
|
|
|
3375
3413
|
},
|
|
3376
3414
|
pt: {
|
|
3377
3415
|
translation: {
|
|
3416
|
+
"modelcreator.field.history": "Permite visualizar e monitorar as alterações feitas nos seus dados. Consome espaço.",
|
|
3417
|
+
"history": "Histórico",
|
|
3418
|
+
"history.op.create": "Criação",
|
|
3419
|
+
"history.op.update": "Atualização",
|
|
3420
|
+
"history.op.delete": "Exclusão",
|
|
3421
|
+
"history.datePrefix": "Ativado",
|
|
3422
|
+
"history.byUser": "por",
|
|
3423
|
+
"history.version": "Versão:",
|
|
3424
|
+
"history.error": "Não foi possível carregar o histórico.",
|
|
3425
|
+
"history.title": "Histórico do Registro",
|
|
3426
|
+
"history.loading": "Carregando Histórico",
|
|
3427
|
+
"history.noHistory": "Nenhum histórico encontrado para este registro",
|
|
3428
|
+
|
|
3378
3429
|
"packs.manualInstall": "Importar",
|
|
3379
3430
|
"packs.manualInstall.title": "Instalação manual do pacote",
|
|
3380
3431
|
"packs.manualInstall.instructions": "Cole o JSON de configuração do pacote que você deseja instalar aqui.",
|
|
@@ -4788,6 +4839,19 @@ export const websiteTranslations = {
|
|
|
4788
4839
|
},
|
|
4789
4840
|
de: {
|
|
4790
4841
|
translation: {
|
|
4842
|
+
"modelcreator.field.history": "Ermöglicht Ihnen, Änderungen an Ihren Daten anzuzeigen und zu überwachen. Verbraucht Speicherplatz.",
|
|
4843
|
+
"history": "Verlauf",
|
|
4844
|
+
"history.op.create": "Erstellung",
|
|
4845
|
+
"history.op.update": "Aktualisieren",
|
|
4846
|
+
"history.op.delete": "Löschen",
|
|
4847
|
+
"history.datePrefix": "Am",
|
|
4848
|
+
"history.byUser": "von",
|
|
4849
|
+
"history.version": "Version:",
|
|
4850
|
+
"history.error": "Verlauf konnte nicht geladen werden.",
|
|
4851
|
+
"history.title": "Datensatzverlauf",
|
|
4852
|
+
"history.loading": "Verlauf wird geladen",
|
|
4853
|
+
"history.noHistory": "Kein Verlauf für diesen Datensatz gefunden",
|
|
4854
|
+
|
|
4791
4855
|
"packs.manualInstall": "Importieren",
|
|
4792
4856
|
"packs.manualInstall.title": "Manuelle Paketinstallation",
|
|
4793
4857
|
"packs.manualInstall.instructions": "Fügen Sie hier die JSON-Konfiguration des zu installierenden Pakets ein.",
|
|
@@ -6185,6 +6249,19 @@ export const websiteTranslations = {
|
|
|
6185
6249
|
},
|
|
6186
6250
|
it: {
|
|
6187
6251
|
translation: {
|
|
6252
|
+
"modelcreator.field.history": "Consente di visualizzare e monitorare le modifiche apportate ai dati. Occupa spazio.",
|
|
6253
|
+
"history": "Cronologia",
|
|
6254
|
+
"history.op.create": "Creazione",
|
|
6255
|
+
"history.op.update": "Aggiorna",
|
|
6256
|
+
"history.op.delete": "Eliminazione",
|
|
6257
|
+
"history.datePrefix": "Attivo",
|
|
6258
|
+
"history.byUser": "di",
|
|
6259
|
+
"history.version": "Versione:",
|
|
6260
|
+
"history.error": "Impossibile caricare la cronologia.",
|
|
6261
|
+
"history.title": "Cronologia record",
|
|
6262
|
+
"history.loading": "Caricamento cronologia",
|
|
6263
|
+
"history.noHistory": "Nessuna cronologia trovata per questo record",
|
|
6264
|
+
|
|
6188
6265
|
"packs.manualInstall": "Importa",
|
|
6189
6266
|
"packs.manualInstall.title": "Installazione manuale del pacchetto",
|
|
6190
6267
|
"packs.manualInstall.instructions": "Incolla qui il file JSON di configurazione del pacchetto che desideri installare.",
|
|
@@ -7595,6 +7672,19 @@ export const websiteTranslations = {
|
|
|
7595
7672
|
},
|
|
7596
7673
|
cs: {
|
|
7597
7674
|
translation: {
|
|
7675
|
+
"modelcreator.field.history": "Umožňuje zobrazit a sledovat změny provedené ve vašich datech. Spotřebovává místo.",
|
|
7676
|
+
"history": "Historie",
|
|
7677
|
+
"history.op.create": "Vytvoření",
|
|
7678
|
+
"history.op.update": "Aktualizace",
|
|
7679
|
+
"history.op.delete": "Smazání",
|
|
7680
|
+
"history.datePrefix": "Zapnuto",
|
|
7681
|
+
"history.byUser": "od",
|
|
7682
|
+
"history.version": "Verze:",
|
|
7683
|
+
"history.error": "Nelze načíst historii.",
|
|
7684
|
+
"history.title": "Historie záznamu",
|
|
7685
|
+
"history.loading": "Načítání historie",
|
|
7686
|
+
"history.noHistory": "Pro tento záznam nebyla nalezena žádná historie",
|
|
7687
|
+
|
|
7598
7688
|
"packs.manualInstall": "Importovat",
|
|
7599
7689
|
"packs.manualInstall.title": "Ruční instalace balíčku",
|
|
7600
7690
|
"packs.manualInstall.instructions": "Sem vložte konfigurační JSON balíčku, který chcete nainstalovat.",
|
|
@@ -9000,6 +9090,19 @@ export const websiteTranslations = {
|
|
|
9000
9090
|
},
|
|
9001
9091
|
ru: {
|
|
9002
9092
|
translation: {
|
|
9093
|
+
"modelcreator.field.history": "Позволяет просматривать и отслеживать изменения, внесённые в ваши данные. Занимает место.",
|
|
9094
|
+
"history": "История",
|
|
9095
|
+
"history.op.create": "Создание",
|
|
9096
|
+
"history.op.update": "Обновление",
|
|
9097
|
+
"history.op.delete": "Удаление",
|
|
9098
|
+
"history.datePrefix": "Вкл",
|
|
9099
|
+
"history.byUser": "Автор",
|
|
9100
|
+
"history.version": "Версия:",
|
|
9101
|
+
"history.error": "Не удалось загрузить историю",
|
|
9102
|
+
"history.title": "История записи",
|
|
9103
|
+
"history.loading": "Загрузка истории",
|
|
9104
|
+
"history.noHistory": "История для этой записи не найдена",
|
|
9105
|
+
|
|
9003
9106
|
"packs.manualInstall": "Импорт",
|
|
9004
9107
|
"packs.manualInstall.title": "Ручная установка пакета",
|
|
9005
9108
|
"packs.manualInstall.instructions": "Вставьте сюда JSON-файл конфигурации пакета, который вы хотите установить.",
|
|
@@ -10415,6 +10518,19 @@ export const websiteTranslations = {
|
|
|
10415
10518
|
},
|
|
10416
10519
|
ar: {
|
|
10417
10520
|
translation: {
|
|
10521
|
+
"modelcreator.field.history": "يسمح لك بعرض ومراقبة التغييرات التي أجريتها على بياناتك. يستهلك مساحة.",
|
|
10522
|
+
"history": "السجل",
|
|
10523
|
+
"history.op.create": "إنشاء",
|
|
10524
|
+
"history.op.update": "تحديث",
|
|
10525
|
+
"history.op.delete": "حذف",
|
|
10526
|
+
"history.datePrefix": "تشغيل",
|
|
10527
|
+
"history.byUser": "بواسطة",
|
|
10528
|
+
"history.version": "الإصدار:",
|
|
10529
|
+
"history.error": "تعذر تحميل السجل",
|
|
10530
|
+
"history.title": "سجل السجل",
|
|
10531
|
+
"history.loading": "جارٍ تحميل السجل",
|
|
10532
|
+
"history.noHistory": "لم يتم العثور على سجل لهذا السجل",
|
|
10533
|
+
|
|
10418
10534
|
"packs.manualInstall": "استيراد",
|
|
10419
10535
|
"packs.manualInstall.title": "تثبيت الحزمة يدويًا",
|
|
10420
10536
|
"packs.manualInstall.instructions": "الصق ملف JSON الخاص بتكوين الحزمة التي تريد تثبيتها هنا",
|
|
@@ -11846,6 +11962,19 @@ export const websiteTranslations = {
|
|
|
11846
11962
|
},
|
|
11847
11963
|
sv: {
|
|
11848
11964
|
translation: {
|
|
11965
|
+
"modelcreator.field.history": "Låter dig visa och övervaka ändringar som gjorts i dina data. Tar plats.",
|
|
11966
|
+
"history": "Historik",
|
|
11967
|
+
"history.op.create": "Skapande",
|
|
11968
|
+
"history.op.update": "Uppdatering",
|
|
11969
|
+
"history.op.delete": "Bortning",
|
|
11970
|
+
"history.datePrefix": "På",
|
|
11971
|
+
"history.byUser": "av",
|
|
11972
|
+
"history.version": "Version:",
|
|
11973
|
+
"history.error": "Det gick inte att läsa in historiken.",
|
|
11974
|
+
"history.title": "Posthistorik",
|
|
11975
|
+
"history.loading": "Laddar in historik",
|
|
11976
|
+
"history.noHistory": "Ingen historik hittades för den här posten",
|
|
11977
|
+
|
|
11849
11978
|
"packs.manualInstall": "Importera",
|
|
11850
11979
|
"packs.manualInstall.title": "Manuell paketinstallation",
|
|
11851
11980
|
"packs.manualInstall.instructions": "Klistra in konfigurations-JSON-filen för paketet du vill installera här.",
|
|
@@ -13251,6 +13380,19 @@ export const websiteTranslations = {
|
|
|
13251
13380
|
},
|
|
13252
13381
|
el: {
|
|
13253
13382
|
translation: {
|
|
13383
|
+
"modelcreator.field.history": "Σας επιτρέπει να βλέπετε και να παρακολουθείτε τις αλλαγές που έγιναν στα δεδομένα σας. Καταλαμβάνει χώρο.",
|
|
13384
|
+
"history": "Ιστορικό",
|
|
13385
|
+
"history.op.create": "Δημιουργία",
|
|
13386
|
+
"history.op.update": "Ενημέρωση",
|
|
13387
|
+
"history.op.delete": "Διαγραφή",
|
|
13388
|
+
"history.datePrefix": "Ενεργοποίηση",
|
|
13389
|
+
"history.byUser": "από",
|
|
13390
|
+
"history.version": "Έκδοση:",
|
|
13391
|
+
"history.error": "Δεν είναι δυνατή η φόρτωση του ιστορικού.",
|
|
13392
|
+
"history.title": "Ιστορικό Εγγραφών",
|
|
13393
|
+
"history.loading": "Φόρτωση Ιστορικού",
|
|
13394
|
+
"history.noHistory": "Δεν βρέθηκε ιστορικό για αυτήν την εγγραφή",
|
|
13395
|
+
|
|
13254
13396
|
"packs.manualInstall": "Εισαγωγή",
|
|
13255
13397
|
"packs.manualInstall.title": "Χειροκίνητη εγκατάσταση πακέτου",
|
|
13256
13398
|
"packs.manualInstall.instructions": "Επικολλήστε εδώ το JSON διαμόρφωσης του πακέτου που θέλετε να εγκαταστήσετε.",
|
|
@@ -14664,7 +14806,19 @@ export const websiteTranslations = {
|
|
|
14664
14806
|
},
|
|
14665
14807
|
fa: {
|
|
14666
14808
|
"translation": {
|
|
14667
|
-
|
|
14809
|
+
"modelcreator.field.history": "به شما امکان میدهد تغییرات ایجاد شده در دادههای خود را مشاهده و نظارت کنید. فضا مصرف میکند.",
|
|
14810
|
+
"history": "تاریخچه",
|
|
14811
|
+
"history.op.create": "ایجاد",
|
|
14812
|
+
"history.op.update": "بهروزرسانی",
|
|
14813
|
+
"history.op.delete": "حذف",
|
|
14814
|
+
"history.datePrefix": "روشن",
|
|
14815
|
+
"history.byUser": "توسط",
|
|
14816
|
+
"history.version": "نسخه:",
|
|
14817
|
+
"history.error": "بارگیری تاریخچه امکانپذیر نیست.",
|
|
14818
|
+
"history.title": "تاریخچه رکورد",
|
|
14819
|
+
"history.loading": "بارگیری تاریخچه",
|
|
14820
|
+
"history.noHistory": "هیچ تاریخچهای برای این رکورد یافت نشد",
|
|
14821
|
+
|
|
14668
14822
|
"packs.manualInstall": "وارد کردن",
|
|
14669
14823
|
"packs.manualInstall.title": "نصب دستی بسته",
|
|
14670
14824
|
"packs.manualInstall.instructions": "فایل JSON پیکربندی بستهای که میخواهید نصب کنید را اینجا جایگذاری کنید.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "data-primals-engine",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "data-primals-engine is a package responsible from handling large amount of data using MongoDB in a practical and performant way. It can also get workflow models working (for automation), and fully supports internationalisation. It also has integrated AI assistant.",
|
|
5
5
|
"main": "src/engine.js",
|
|
6
6
|
"type": "module",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"lint": "eslint .",
|
|
17
17
|
"format": "prettier --write .",
|
|
18
18
|
"clean": "rm -rf node_modules package-lock.json",
|
|
19
|
-
"test": "cross-env MONGO_DB_URL=\"mongodb://localhost:27017\" PORT=7635 vitest --no-file-parallelism",
|
|
19
|
+
"test": "cross-env MONGO_DB_URL=\"mongodb://localhost:27017\" PORT=7635 vitest --no-file-parallelism --no-watch",
|
|
20
20
|
"audit": "npm audit --audit-level=high",
|
|
21
21
|
"migrate:create": "node src/migrate.js create",
|
|
22
22
|
"migrate:up": "node src/migrate.js up",
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { Dialog } from "../Dialog.jsx";
|
|
3
|
+
import { api } from "../utils/api.js"; // Assurez-vous que le chemin vers votre utilitaire api est correct
|
|
4
|
+
import { FaHistory } from "react-icons/fa";
|
|
5
|
+
import "./HistoryDialog.scss";
|
|
6
|
+
|
|
7
|
+
// Sous-composant pour afficher une seule entrée de l'historique
|
|
8
|
+
const HistoryEntry = ({ entry }) => {
|
|
9
|
+
// _id: id du doc d'historique, _v: version, _op: type d'opération, _rid: id de l'enregistrement original
|
|
10
|
+
const { _id, _v, _op, _updatedAt, _user, _rid, ...data } = entry;
|
|
11
|
+
const operationDetails = {
|
|
12
|
+
'i': { label: 'Création', className: 'op-insert' },
|
|
13
|
+
'u': { label: 'Mise à jour', className: 'op-update' },
|
|
14
|
+
'd': { label: 'Suppression', className: 'op-delete' },
|
|
15
|
+
};
|
|
16
|
+
const opInfo = operationDetails[_op] || { label: _op, className: '' };
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div className="history-entry">
|
|
20
|
+
<div className="history-entry-header">
|
|
21
|
+
<span className={`op-badge ${opInfo.className}`}>{opInfo.label}</span>
|
|
22
|
+
<span className="history-date">Le {new Date(_updatedAt).toLocaleString()}</span>
|
|
23
|
+
{_user && <span className="history-user">par <strong>{_user}</strong></span>}
|
|
24
|
+
<span className="history-version">Version: {_v}</span>
|
|
25
|
+
</div>
|
|
26
|
+
<div className="history-entry-data">
|
|
27
|
+
<pre>{JSON.stringify(data, null, 2)}</pre>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const HistoryDialog = ({ modelName, recordId, onClose }) => {
|
|
34
|
+
const [history, setHistory] = useState([]);
|
|
35
|
+
const [loading, setLoading] = useState(true);
|
|
36
|
+
const [error, setError] = useState(null);
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (!modelName || !recordId) return;
|
|
40
|
+
|
|
41
|
+
const fetchHistory = async () => {
|
|
42
|
+
setLoading(true);
|
|
43
|
+
setError(null);
|
|
44
|
+
try {
|
|
45
|
+
// J'assume que l'endpoint de l'API pour l'historique est structuré ainsi
|
|
46
|
+
const response = await api.get(`/data/history/${modelName}/${recordId}`);
|
|
47
|
+
if (response.success) {
|
|
48
|
+
// L'API devrait retourner l'historique trié du plus récent au plus ancien
|
|
49
|
+
setHistory(response.data);
|
|
50
|
+
} else {
|
|
51
|
+
setError(response.error || "Échec de la récupération de l'historique.");
|
|
52
|
+
}
|
|
53
|
+
} catch (err) {
|
|
54
|
+
setError("Une erreur est survenue lors de la récupération de l'historique.");
|
|
55
|
+
console.error(err);
|
|
56
|
+
} finally {
|
|
57
|
+
setLoading(false);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
fetchHistory();
|
|
62
|
+
}, [modelName, recordId]);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<Dialog
|
|
66
|
+
title={<><FaHistory style={{ marginRight: '8px' }} /> Historique de l'enregistrement</>}
|
|
67
|
+
onClose={onClose}
|
|
68
|
+
isClosable={true}
|
|
69
|
+
className="history-dialog"
|
|
70
|
+
>
|
|
71
|
+
<div className="history-dialog-content">
|
|
72
|
+
{loading && <div>Chargement de l'historique...</div>}
|
|
73
|
+
{error && <div className="error-message">{error}</div>}
|
|
74
|
+
{!loading && !error && (
|
|
75
|
+
<div className="history-list">
|
|
76
|
+
{history.length > 0 ? (
|
|
77
|
+
history.map(entry => <HistoryEntry key={entry._id} entry={entry} />)
|
|
78
|
+
) : (
|
|
79
|
+
<div>Aucun historique trouvé pour cet enregistrement.</div>
|
|
80
|
+
)}
|
|
81
|
+
</div>
|
|
82
|
+
)}
|
|
83
|
+
</div>
|
|
84
|
+
</Dialog>
|
|
85
|
+
);
|
|
86
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
.history-dialog {
|
|
2
|
+
width: 80vw;
|
|
3
|
+
max-width: 900px;
|
|
4
|
+
height: 70vh;
|
|
5
|
+
|
|
6
|
+
.dialog-content {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
height: 100%;
|
|
10
|
+
padding: 0; // Le padding sera sur le content wrapper
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.history-dialog-content {
|
|
15
|
+
flex-grow: 1;
|
|
16
|
+
overflow-y: auto;
|
|
17
|
+
padding: 1rem;
|
|
18
|
+
background-color: #f4f4f4;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.history-list {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
gap: 1rem;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.history-entry {
|
|
28
|
+
border: 1px solid #ddd;
|
|
29
|
+
border-radius: 4px;
|
|
30
|
+
background-color: #fff;
|
|
31
|
+
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
|
32
|
+
|
|
33
|
+
.history-entry-header {
|
|
34
|
+
display: flex;
|
|
35
|
+
align-items: center;
|
|
36
|
+
gap: 1rem;
|
|
37
|
+
padding: 0.5rem 1rem;
|
|
38
|
+
background-color: #f9f9f9;
|
|
39
|
+
border-bottom: 1px solid #eee;
|
|
40
|
+
font-size: 0.9em;
|
|
41
|
+
color: #333;
|
|
42
|
+
|
|
43
|
+
.op-badge {
|
|
44
|
+
padding: 0.2rem 0.6rem;
|
|
45
|
+
border-radius: 12px;
|
|
46
|
+
color: white;
|
|
47
|
+
font-weight: bold;
|
|
48
|
+
font-size: 0.8em;
|
|
49
|
+
text-transform: uppercase;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.op-insert { background-color: #28a745; } // green
|
|
53
|
+
.op-update { background-color: #007bff; } // blue
|
|
54
|
+
.op-delete { background-color: #dc3545; } // red
|
|
55
|
+
|
|
56
|
+
.history-version {
|
|
57
|
+
margin-left: auto;
|
|
58
|
+
font-weight: bold;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.history-entry-data {
|
|
63
|
+
padding: 1rem;
|
|
64
|
+
|
|
65
|
+
pre {
|
|
66
|
+
white-space: pre-wrap;
|
|
67
|
+
word-wrap: break-word;
|
|
68
|
+
background-color: #2d2d2d;
|
|
69
|
+
color: #f8f8f2;
|
|
70
|
+
padding: 1rem;
|
|
71
|
+
border-radius: 4px;
|
|
72
|
+
margin: 0;
|
|
73
|
+
font-family: 'Courier New', Courier, monospace;
|
|
74
|
+
font-size: 0.85em;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
package/src/email.js
CHANGED
|
@@ -54,7 +54,7 @@ export const sendEmail = async (email = "", data, smtpConfig = null, lang, tpl =
|
|
|
54
54
|
|
|
55
55
|
Event.Listen("OnEmailTemplate", (data, lang) => data.content, "event", "system");
|
|
56
56
|
|
|
57
|
-
if (tpl === null) tpl = Event.Trigger("OnEmailTemplate", "event", "system", data, lang);
|
|
57
|
+
if (tpl === null) tpl = await Event.Trigger("OnEmailTemplate", "event", "system", data, lang);
|
|
58
58
|
let html = tpl;
|
|
59
59
|
try {
|
|
60
60
|
html = juice(tpl);
|
package/src/engine.js
CHANGED
|
@@ -198,7 +198,7 @@ export const Engine = {
|
|
|
198
198
|
logger.warn(`Aucun point d'entrée trouvé pour le module '${moduleIdentifier}'.`);
|
|
199
199
|
}
|
|
200
200
|
} catch (e) {
|
|
201
|
-
logger.error(
|
|
201
|
+
logger.error(`Could not load module '${moduleIdentifier}':`, e.stack);
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
|
|
@@ -246,12 +246,12 @@ export const Engine = {
|
|
|
246
246
|
process.exit(1);
|
|
247
247
|
});
|
|
248
248
|
|
|
249
|
-
Event.Trigger("OnServerStart", "event", "system", engine);
|
|
249
|
+
await Event.Trigger("OnServerStart", "event", "system", engine);
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
engine.stop = async () => {
|
|
253
253
|
await server.close();
|
|
254
|
-
Event.Trigger("OnServerStop", "event", "system", engine);
|
|
254
|
+
await Event.Trigger("OnServerStop", "event", "system", engine);
|
|
255
255
|
};
|
|
256
256
|
|
|
257
257
|
async function setupInitialModels() {
|
|
@@ -262,7 +262,7 @@ export const Engine = {
|
|
|
262
262
|
|
|
263
263
|
for(let i = 0; i < ms.length; ++i){
|
|
264
264
|
const model = ms[i];
|
|
265
|
-
validateModelStructure(model);
|
|
265
|
+
await validateModelStructure(model);
|
|
266
266
|
// Création des modèles
|
|
267
267
|
if( !dbModels.find(m =>m.name === model.name) )
|
|
268
268
|
{
|
|
@@ -274,11 +274,11 @@ export const Engine = {
|
|
|
274
274
|
logger.info('Model loaded (' + model.name + ')');
|
|
275
275
|
}
|
|
276
276
|
logger.info("All models loaded.");
|
|
277
|
-
Event.Trigger("OnModelsLoaded", "event", "system", engine, dbModels);
|
|
277
|
+
await Event.Trigger("OnModelsLoaded", "event", "system", engine, dbModels);
|
|
278
278
|
}
|
|
279
279
|
engine.resetModels = async () => {
|
|
280
280
|
await deleteModels();
|
|
281
|
-
Event.Trigger("OnModelsDeleted", "event", "system", engine);
|
|
281
|
+
await Event.Trigger("OnModelsDeleted", "event", "system", engine);
|
|
282
282
|
};
|
|
283
283
|
return engine;
|
|
284
284
|
}
|
package/src/events.js
CHANGED
|
@@ -12,14 +12,20 @@ const eventLayerSystems = {
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
export const Event = {
|
|
15
|
-
Trigger: (name, system = "priority", layer = "medium", ...args) => { // Ajout des arguments system et layer
|
|
15
|
+
Trigger: async (name, system = "priority", layer = "medium", ...args) => { // Ajout des arguments system et layer
|
|
16
|
+
if (!name || typeof name !== 'string') {
|
|
17
|
+
throw new Error('Event name must be a non-empty string');
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
if (!events[system] || !events[system][name] || (layer && !events[system][name][layer])) {
|
|
17
21
|
//console.warn(`No trigger found for ${name} in system ${system} layer ${layer}`);
|
|
18
22
|
return null;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
const systemsToProcess = system ? [system] : Object.keys(events); // Si system est spécifié, on cible ce système uniquement, sinon tous les systèmes
|
|
22
|
-
|
|
26
|
+
console.log(`[Event] Triggering ${system}.${layer}.${name}`, {
|
|
27
|
+
callbacks: events[system]?.[name]?.[layer]?.length || 0
|
|
28
|
+
});
|
|
23
29
|
let ret = null;
|
|
24
30
|
for (const currentSystem of systemsToProcess) {
|
|
25
31
|
if (events[currentSystem] && events[currentSystem][name]) {
|
|
@@ -30,12 +36,12 @@ export const Event = {
|
|
|
30
36
|
if (events[currentSystem][name][currentLayer]) {
|
|
31
37
|
for (const callback of events[currentSystem][name][currentLayer]) {
|
|
32
38
|
try {
|
|
33
|
-
const res = callback(...args);
|
|
39
|
+
const res = await callback(...args);
|
|
34
40
|
if (typeof res === "object" && !Array.isArray(res)) {
|
|
35
41
|
if (typeof ret !== "object") ret = {};
|
|
36
42
|
ret = {...ret, ...res};
|
|
37
43
|
} else if (Array.isArray(res)) {
|
|
38
|
-
if (!Array.isArray(ret)) ret = [];
|
|
44
|
+
if (!ret || !Array.isArray(ret)) ret = [];
|
|
39
45
|
ret = ret.concat(res);
|
|
40
46
|
} else if (typeof res === "string") {
|
|
41
47
|
if (typeof ret !== "string") ret = "";
|
|
@@ -50,7 +56,11 @@ export const Event = {
|
|
|
50
56
|
ret = res || ret;
|
|
51
57
|
}
|
|
52
58
|
} catch (error) {
|
|
53
|
-
|
|
59
|
+
const errorMsg = `Error in callback for event ${name} in system ${currentSystem} layer ${currentLayer}: ${error.message}`;
|
|
60
|
+
const newError = new Error(errorMsg);
|
|
61
|
+
newError.originalError = error; // Conserve l'erreur originale
|
|
62
|
+
newError.eventDetails = { name, system: currentSystem, layer: currentLayer };
|
|
63
|
+
throw newError;
|
|
54
64
|
}
|
|
55
65
|
}
|
|
56
66
|
}
|
package/src/gameObject.js
CHANGED
|
@@ -61,35 +61,6 @@ export class MovableBehaviour extends Behaviour {
|
|
|
61
61
|
this.gameObject.x += this.speed;
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
|
|
65
|
-
// UsableBehavior.js
|
|
66
|
-
export class UsableBehaviour extends Behaviour {
|
|
67
|
-
constructor(gameObject) {
|
|
68
|
-
super(gameObject);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
use() {
|
|
72
|
-
Event.Trigger("GameObject.UsableBehavior.use", "system", "calls", this);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const mainDriver = GameObject.Create("MainDrivers");
|
|
77
|
-
|
|
78
|
-
// Exemple d'attachement de comportements
|
|
79
|
-
mainDriver.addComponent(MovableBehaviour, 10);
|
|
80
|
-
mainDriver.addComponent(UsableBehaviour);
|
|
81
|
-
|
|
82
|
-
// Accéder et utiliser les composants
|
|
83
|
-
const movable = mainDriver.getComponent(MovableBehaviour);
|
|
84
|
-
if (movable) {
|
|
85
|
-
movable.update();
|
|
86
|
-
}
|
|
87
|
-
const usable = mainDriver.getComponent(UsableBehaviour);
|
|
88
|
-
if (usable) {
|
|
89
|
-
usable.use();
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
64
|
export class Logger extends Behaviour {
|
|
94
65
|
constructor(gameObject) {
|
|
95
66
|
super(gameObject);
|