data-primals-engine 1.1.3 → 1.1.5

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 (52) hide show
  1. package/README.md +5 -1
  2. package/client/package-lock.json +11580 -11664
  3. package/client/package.json +69 -69
  4. package/client/src/APIInfo.jsx +2 -5
  5. package/client/src/App.jsx +12 -7
  6. package/client/src/CalculationBuilder.jsx +2 -2
  7. package/client/src/ConditionBuilder.scss +24 -0
  8. package/client/src/ConditionBuilder2.jsx +56 -0
  9. package/client/src/Dashboard.jsx +2 -2
  10. package/client/src/DashboardChart.jsx +1 -1
  11. package/client/src/DashboardFlexViewItem.jsx +1 -1
  12. package/client/src/DashboardView.jsx +1 -1
  13. package/client/src/DataEditor.jsx +3 -3
  14. package/client/src/DataLayout.jsx +23 -20
  15. package/client/src/DataTable.jsx +80 -13
  16. package/client/src/Dialog.scss +1 -0
  17. package/client/src/DisplayFlexNodeRenderer.jsx +2 -2
  18. package/client/src/Field.jsx +2 -2
  19. package/client/src/FlexBuilder.jsx +1 -1
  20. package/client/src/KPIWidget.jsx +1 -1
  21. package/client/src/KanbanCard.jsx +1 -1
  22. package/client/src/ModelCreator.jsx +3 -3
  23. package/client/src/ModelCreatorField.jsx +2 -2
  24. package/client/src/ModelImporter.jsx +1 -1
  25. package/client/src/PackGallery.jsx +1 -1
  26. package/client/src/RTETrans.jsx +1 -1
  27. package/client/src/RelationField.jsx +1 -1
  28. package/client/src/RelationValue.jsx +1 -1
  29. package/client/src/TourSpotlight.jsx +14 -10
  30. package/client/src/TutorialsMenu.scss +0 -1
  31. package/client/src/Webpage.jsx +2 -2
  32. package/client/src/constants.js +2 -1
  33. package/client/src/contexts/ModelContext.jsx +5 -11
  34. package/client/src/core/dom.js +26 -0
  35. package/client/src/filter.js +40 -1
  36. package/client/src/hooks/data.js +1 -1
  37. package/client/src/hooks/useTutorials.jsx +1 -1
  38. package/package.json +4 -6
  39. package/server.js +3 -2
  40. package/src/constants.js +3 -0
  41. package/src/engine.js +18 -13
  42. package/src/i18n.js +77 -3
  43. package/src/modules/assistant.js +1 -1
  44. package/src/modules/bucket.js +1 -1
  45. package/src/modules/data.js +14 -3
  46. package/src/modules/file.js +1 -1
  47. package/src/modules/user.js +1 -1
  48. package/src/modules/workflow.js +1 -1
  49. package/src/packs.js +4 -3
  50. package/src/setenv.js +1 -1
  51. package/test/data.integration.test.js +4 -10
  52. package/test/workflow.robustness.test.js +1 -1
@@ -1,70 +1,70 @@
1
- {
2
- "name": "client",
3
- "private": true,
4
- "version": "0.0.0",
5
- "type": "module",
6
- "scripts": {
7
- "dev": "vite",
8
- "build": "vite build --mode development",
9
- "build:ssr-client": "vite build --ssrManifest --outDir dist/client --mode development",
10
- "build:ssr-server": "vite build --ssr src/entry-server.jsx --outDir dist/server --mode development",
11
- "lint": "eslint .",
12
- "preview": "vite preview"
13
- },
14
- "dependencies": {
15
- "@babel/runtime": "^7.24.7",
16
- "@codeium/react-code-editor": "^1.0.12",
17
- "@codemirror/lang-javascript": "^6.2.3",
18
- "@tiptap/extension-code": "^2.12.0",
19
- "@tiptap/extension-code-block": "^2.12.0",
20
- "@tiptap/extension-code-block-lowlight": "^2.12.0",
21
- "@tiptap/extension-color": "^2.11.5",
22
- "@tiptap/extension-hard-break": "^2.12.0",
23
- "@tiptap/extension-image": "^2.12.0",
24
- "@tiptap/extension-link": "^2.12.0",
25
- "@tiptap/extension-list-item": "^2.11.5",
26
- "@tiptap/extension-text-style": "^2.11.5",
27
- "@tiptap/pm": "^2.11.5",
28
- "@tiptap/react": "^2.11.5",
29
- "@tiptap/starter-kit": "^2.11.5",
30
- "@uiw/react-codemirror": "^4.23.10",
31
- "chart.js": "^4.4.9",
32
- "chartjs-adapter-date-fns": "^3.0.0",
33
- "classnames": "^2.5.1",
34
- "date-fns": "^4.1.0",
35
- "express-rate-limit": "^7.5.1",
36
- "lowlight": "^3.3.0",
37
- "react-chartjs-2": "^5.3.0",
38
- "react-code-blocks": "^0.1.6",
39
- "react-cookie": "^8.0.0",
40
- "react-dom": "^18.3.1",
41
- "react-ga": "^3.3.1",
42
- "react-icons": "^5.0.1",
43
- "react-international-phone": "^4.5.0",
44
- "react-router": "^7.2.0",
45
- "react-router-dom": "^7.1.5",
46
- "react-syntax-highlighter": "^15.6.1",
47
- "react-tooltip": "^5.28.1",
48
- "uniqid": "^5.4.0",
49
- "yet-another-react-lightbox": "^3.22.0",
50
- "data-primals-engine": "^1.0.11",
51
- "react-query": "^3.39.3"
52
- },
53
- "peerDependencies": {
54
- "react": ">=18.0.0"
55
- },
56
- "devDependencies": {
57
- "@eslint/js": "^9.17.0",
58
- "@types/react": "^18.3.18",
59
- "@types/react-dom": "^18.3.5",
60
- "@vitejs/plugin-react": "^4.3.4",
61
- "eslint": "^9.17.0",
62
- "eslint-plugin-react": "^7.37.2",
63
- "eslint-plugin-react-hooks": "^5.0.0",
64
- "eslint-plugin-react-refresh": "^0.4.16",
65
- "globals": "^15.14.0",
66
- "process": "^0.11.10",
67
- "sass-embedded": "^1.83.4",
68
- "vite": "^6.1.1"
69
- }
1
+ {
2
+ "name": "client",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "vite build --mode development",
9
+ "build:ssr-client": "vite build --ssrManifest --outDir dist/client --mode development",
10
+ "build:ssr-server": "vite build --ssr src/entry-server.jsx --outDir dist/server --mode development",
11
+ "lint": "eslint .",
12
+ "preview": "vite preview"
13
+ },
14
+ "peerDependencies": {
15
+ "@tiptap/react": "^2.11.5",
16
+ "react-router-dom": "^7.1.5",
17
+ "react-query": "^3.39.3",
18
+ "react-icons": "^5.0.1",
19
+ "react-tooltip": "^5.28.1",
20
+ "react-helmet": "^6.1.0",
21
+ "react-cookie": "^8.0.0",
22
+ "react-syntax-highlighter": "^15.6.1",
23
+ "react-international-phone": "^4.5.0",
24
+ "react-chartjs-2": "^5.3.0",
25
+ "react-code-blocks": "^0.1.6",
26
+ "react-ga": "^3.3.1"
27
+ },
28
+ "dependencies": {
29
+ "@babel/runtime": "^7.24.7",
30
+ "@codeium/react-code-editor": "^1.0.12",
31
+ "@codemirror/lang-javascript": "^6.2.3",
32
+ "@tiptap/extension-code": "^2.12.0",
33
+ "@tiptap/extension-code-block": "^2.12.0",
34
+ "@tiptap/extension-code-block-lowlight": "^2.12.0",
35
+ "@tiptap/extension-color": "^2.11.5",
36
+ "@tiptap/extension-hard-break": "^2.12.0",
37
+ "@tiptap/extension-image": "^2.12.0",
38
+ "@tiptap/extension-link": "^2.12.0",
39
+ "@tiptap/extension-list-item": "^2.11.5",
40
+ "@tiptap/extension-text-style": "^2.11.5",
41
+ "@tiptap/pm": "^2.11.5",
42
+ "@tiptap/starter-kit": "^2.11.5",
43
+ "@uiw/react-codemirror": "^4.23.10",
44
+ "chart.js": "^4.4.9",
45
+ "chartjs-adapter-date-fns": "^3.0.0",
46
+ "react-dom": "^18.3.1",
47
+ "react-router": "^7.2.0",
48
+ "yet-another-react-lightbox": "^3.22.0",
49
+ "react": ">=18.0.0",
50
+ "classnames": "^2.5.1",
51
+ "date-fns": "^4.1.0",
52
+ "express-rate-limit": "^7.5.1",
53
+ "lowlight": "^3.3.0",
54
+ "uniqid": "^5.4.0"
55
+ },
56
+ "devDependencies": {
57
+ "@eslint/js": "^9.17.0",
58
+ "@types/react": "^18.3.18",
59
+ "@types/react-dom": "^18.3.5",
60
+ "@vitejs/plugin-react": "^4.3.4",
61
+ "eslint": "^9.17.0",
62
+ "eslint-plugin-react": "^7.37.2",
63
+ "eslint-plugin-react-hooks": "^5.0.0",
64
+ "eslint-plugin-react-refresh": "^0.4.16",
65
+ "globals": "^15.14.0",
66
+ "process": "^0.11.10",
67
+ "sass-embedded": "^1.83.4",
68
+ "vite": "^6.1.1"
69
+ }
70
70
  }
@@ -3,16 +3,13 @@ import {useModelContext} from './contexts/ModelContext';
3
3
  import {useAuthContext} from "./contexts/AuthContext.jsx";
4
4
  import Button from "./Button.jsx";
5
5
  import {Trans, useTranslation} from "react-i18next";
6
- import {getDefaultForType} from "data-primals-engine/data";
6
+ import {getDefaultForType} from "../../src/data.js";
7
7
  import { CodeBlock, tomorrowNightBright } from 'react-code-blocks';
8
- import {getObjectHash, shuffle} from "data-primals-engine/core";
9
- import {mainFieldsTypes} from "data-primals-engine/constants";
10
- import {end} from "express-mongo-sanitize";
8
+ import {mainFieldsTypes} from "../../src/constants.js";
11
9
  import {FaFile, FaPlay, FaRunning} from "react-icons/fa";
12
10
  import {Tooltip} from "react-tooltip";
13
11
  import {CodeField} from "./Field.jsx";
14
12
  import {useMutation} from "react-query";
15
- import {FaF} from "react-icons/fa6";
16
13
  import {getHost} from "./constants.js";
17
14
 
18
15
  const Test= ({endpoint, lang, index, headers= {}}) => {
@@ -52,11 +52,11 @@ import {
52
52
  import {Helmet} from "react-helmet";
53
53
  import {useCookies, CookiesProvider} from "react-cookie";
54
54
 
55
- import { translations as allTranslations} from "data-primals-engine/i18n";
56
- import {getRandom} from "data-primals-engine/core";
57
- import {getUserHash} from "data-primals-engine/data";
55
+ import { translations as allTranslations} from "../../src/i18n.js";
56
+ import {getRandom} from "../../src/core.js";
57
+ import {getUserHash} from "../../src/data.js";
58
58
  import {seoTitle} from "./constants.js";
59
- import {host} from "../../src/constants.js";
59
+ import {host, useAI} from "../../src/constants.js";
60
60
  import i18next from "i18next";
61
61
  import {websiteTranslations} from "./translations.js";
62
62
 
@@ -138,8 +138,8 @@ function Layout ({header, translationMutation, routes, body, footer}) {
138
138
  const availableKeys = response.data;
139
139
 
140
140
  const newConfig = {
141
- openai: availableKeys.find(key => key.name === 'OPENAI_API_KEY')?.value,
142
- google: availableKeys.find(key => key.name === 'GOOGLE_API_KEY')?.value
141
+ openai: availableKeys.find(key => key.name === 'OPENAI_API_KEY')?.value || (useAI ? process.env.OPENAI_API_KEY : undefined),
142
+ google: availableKeys.find(key => key.name === 'GOOGLE_API_KEY')?.value || (useAI ? process.env.GOOGLE_API_KEY : undefined),
143
143
  };
144
144
 
145
145
 
@@ -495,7 +495,12 @@ function UserPage({notifs,triggerSignin, onAuthenticated}) {
495
495
  position: 'bottom',
496
496
  },
497
497
  ],
498
- datapacks: [
498
+ guides: [
499
+ {
500
+ selector: '.tourStep-tutorials',
501
+ content: t('tourpoint.tutorials'),
502
+ position: 'bottom'
503
+ },
499
504
  {
500
505
  selector: '.tourStep-import-datapack',
501
506
  content: t('tourpoint.importDatapack'),
@@ -1,9 +1,9 @@
1
1
  import React, {useState, useEffect, useCallback, useRef} from 'react';
2
2
  import { FaPlus, FaTrash, FaEquals } from 'react-icons/fa';
3
- import {object_equals} from "data-primals-engine/core"; // Assuming this is a deep equality check
3
+ import {object_equals} from "../../src/core.js"; // Assuming this is a deep equality check
4
4
  import CalculationStepRow from "./CalculationStepRow.jsx";
5
5
  import {getFieldDefinitionFromPath, isAtomicDateOperator} from "./core/data.js";
6
- import {MONGO_OPERATORS, OPERAND_TYPES} from "../src/constants.js";
6
+ import {MONGO_OPERATORS, OPERAND_TYPES} from "./constants.js";
7
7
 
8
8
  // --- Helper Functions & Constants ---
9
9
  const generateId = () => `step_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
@@ -563,6 +563,8 @@
563
563
  padding: 8px;
564
564
  border: 1px solid #ddd;
565
565
  border-radius: 4px;
566
+ width: 100%;
567
+ box-sizing: border-box;
566
568
  }
567
569
 
568
570
  .switch-to-expr {
@@ -669,4 +671,26 @@
669
671
  margin-left: 20px;
670
672
  border-left: 2px solid #eee;
671
673
  padding-left: 10px;
674
+ }
675
+
676
+ .special-structure-block {
677
+ border: 1px solid #ddd;
678
+ border-radius: 4px;
679
+ padding: 10px;
680
+ margin: 5px 0;
681
+ }
682
+
683
+ .special-structure-args {
684
+ margin-top: 10px;
685
+ }
686
+
687
+ .special-arg {
688
+ margin-bottom: 8px;
689
+ }
690
+
691
+ .special-arg label {
692
+ display: block;
693
+ font-weight: bold;
694
+ margin-bottom: 4px;
695
+ color: #555;
672
696
  }
@@ -86,6 +86,14 @@ const ExpressionField = ({ value, onChange, path = [], fieldNames, isRoot = fals
86
86
  }else if (operator === '$find') {
87
87
  // Cas spécial pour $find qui prend une expression de recherche
88
88
  newValue = { [operator]: { $eq: ["", ""] } };
89
+ }else if (operator === '$regexMatch') {
90
+ // Structure spéciale pour $regexMatch
91
+ newValue = {
92
+ [operator]: {
93
+ input: "",
94
+ regex: ""
95
+ }
96
+ };
89
97
  }else if (opConfig.converter || (!opConfig.multi && !opConfig.args)) {
90
98
  newValue = { [operator]: "" };
91
99
  } else {
@@ -418,6 +426,54 @@ const ExpressionField = ({ value, onChange, path = [], fieldNames, isRoot = fals
418
426
  </div>
419
427
  );
420
428
  }
429
+
430
+ if (opConfig.specialStructure) {
431
+ // Cas spécial pour les opérateurs comme $regexMatch
432
+ return (
433
+ <div className="expression-block special-structure-block">
434
+ <div className="expression-header">
435
+ <span className="operator">{operator}</span>
436
+ {editing && (
437
+ <div className="operator-selector-overlay">
438
+ <OperatorSelector onSelect={handleOperatorSelect}/>
439
+ <button type="button" onClick={() => setEditing(false)}>Annuler</button>
440
+ </div>
441
+ )}
442
+ <div className="expression-actions">
443
+ <button type="button" onClick={() => setEditing(!editing)}><FaRepeat/></button>
444
+ <button type="button" onClick={() => openDoc(operator.substring(1))}><FaInfoCircle/></button>
445
+ <button
446
+ type="button"
447
+ onClick={() => onChange(null, path)}
448
+ className="remove-expr"
449
+ title={i18n.t("cb.deleteBlock")}
450
+ >
451
+ <FaTrash/>
452
+ </button>
453
+ </div>
454
+ </div>
455
+ <div className="special-structure-args">
456
+ {Object.entries(args).map(([key, val]) => (
457
+ <div key={key} className="special-arg">
458
+ <label>{key}</label>
459
+ <ExpressionField
460
+ value={val}
461
+ onChange={(newVal) => {
462
+ const newArgs = {...args, [key]: newVal};
463
+ onChange({[operator]: newArgs}, path);
464
+ }}
465
+ fieldNames={fieldNames}
466
+ path={[...path, operator, key]}
467
+ models={models}
468
+ currentModelFields={currentModelFields}
469
+ isInFindContext={isInFindContext}
470
+ />
471
+ </div>
472
+ ))}
473
+ </div>
474
+ </div>
475
+ );
476
+ }
421
477
  // Rendu pour les opérateurs avec nombre d'arguments fixe
422
478
  if (isFixedArgs) {
423
479
  return (
@@ -10,8 +10,8 @@ import { SelectField } from "./Field.jsx";
10
10
  import {DashboardView} from "./DashboardView.jsx";
11
11
  import {useModelContext} from "./contexts/ModelContext.jsx";
12
12
  import {useParams, useSearchParams} from "react-router-dom";
13
- import {getObjectHash} from "data-primals-engine/core";
14
- import {getUserHash, getUserId} from "data-primals-engine/data";
13
+ import {getObjectHash} from "../../src/core.js";
14
+ import {getUserHash, getUserId} from "../../src/data.js";
15
15
 
16
16
  // --- DashboardsPage (Reste inchangé) ---
17
17
  export function DashboardsPage() {
@@ -14,7 +14,7 @@ import i18n from 'i18next';
14
14
 
15
15
  import 'chartjs-adapter-date-fns';
16
16
  import {useModelContext} from "./contexts/ModelContext.jsx";
17
- import {isDate} from "data-primals-engine/core";
17
+ import {isDate} from "../../src/core.js";
18
18
  import useWindowSize from "./hooks/useWindowSize.js";
19
19
  import useDebounce from "./hooks/useDebounce.js";
20
20
 
@@ -4,7 +4,7 @@ import {useTranslation} from "react-i18next";
4
4
  import {useAuthContext} from "./contexts/AuthContext.jsx";
5
5
  import React, {useEffect, useMemo, useRef} from "react";
6
6
  import {useQuery} from "react-query";
7
- import {conditionToApiSearchFilter} from "data-primals-engine/data";
7
+ import {conditionToApiSearchFilter} from "../../src/data.js";
8
8
  import {FaSpinner} from "react-icons/fa";
9
9
  import {DisplayFlexNodeRenderer} from "./DisplayFlexNodeRenderer.jsx";
10
10
 
@@ -15,7 +15,7 @@ import { useAuthContext } from "./contexts/AuthContext.jsx";
15
15
  import { DialogProvider } from "./Dialog.jsx";
16
16
  import {useModelContext} from "./contexts/ModelContext.jsx";
17
17
  import FlexDataRenderer from "./FlexDataRenderer.jsx";
18
- import {conditionToApiSearchFilter} from "data-primals-engine/data";
18
+ import {conditionToApiSearchFilter} from "../../src/data.js";
19
19
  // --- MODIFICATION : Import de la fonction cssProps ---
20
20
  import { cssProps } from 'data-primals-engine/core';
21
21
  import {DashboardFlexViewItem} from "./DashboardFlexViewItem.jsx";
@@ -1,5 +1,5 @@
1
1
  import React, {forwardRef, useEffect, useState} from "react"; // Ajout de useEffect
2
- import {conditionToApiSearchFilter, getDefaultForType} from "data-primals-engine/data";
2
+ import {conditionToApiSearchFilter, getDefaultForType} from "../../src/data.js";
3
3
  import { Trans, useTranslation } from "react-i18next";
4
4
  import {FaCode, FaLanguage, FaMinus, FaPlus, FaSitemap} from "react-icons/fa";
5
5
  import Button from "./Button.jsx";
@@ -15,7 +15,7 @@ import {
15
15
  SelectField,
16
16
  TextField
17
17
  } from "./Field.jsx";
18
- import i18n from "data-primals-engine/i18n";
18
+ import i18n from "../../src/i18n.js";
19
19
  import ConditionBuilder from "./ConditionBuilder.jsx";
20
20
  import {useModelContext} from "./contexts/ModelContext.jsx";
21
21
  import {useAuthContext} from "./contexts/AuthContext.jsx";
@@ -508,7 +508,7 @@ export const DataEditor = forwardRef(function MyDataEditor({
508
508
  return <p>Sélectionnez un modèle pour afficher le formulaire.</p>;
509
509
  }
510
510
 
511
- const title = record ? t('btns.editModel', `Edit ${model.name}`) : `${t('add_in_model')} ${t(`model_${model.name}`, model.name)}`;
511
+ const title = record ? t('editData', 'Edit {{0}}', [model.name]) : `${t('add_in_model')} ${t(`model_${model.name}`, model.name)}`;
512
512
 
513
513
  const hint = (model, field) => <div className="hint-icon"><FaCircleInfo data-field={t(`field_${model.name}_${field.name}`, field.name)} data-tooltip-id={`tooltipHint`} data-tooltip-content={i18n.t(`field_${model.name}_${field.name}_hint`, field.hint || '')} /></div>
514
514
 
@@ -14,7 +14,7 @@ import {
14
14
  maxBytesPerSecondThrottleData,
15
15
  maxFileSize,
16
16
  maxRequestData, metaModels
17
- } from "data-primals-engine/constants";
17
+ } from "../../src/constants.js";
18
18
  import {
19
19
  FaArrowDown,
20
20
  FaArrowUp, FaBell,
@@ -27,20 +27,14 @@ import {
27
27
  FaPlus,
28
28
  FaTrash
29
29
  } from "react-icons/fa";
30
- import {getDefaultForType, getUserId} from "data-primals-engine/data";
30
+ import {getDefaultForType, getUserId} from "../../src/data.js";
31
31
  import {Trans, useTranslation} from "react-i18next";
32
32
 
33
- import {debounce, escapeRegExp, event_trigger, getObjectHash, isGUID} from "data-primals-engine/core";
33
+ import {debounce, escapeRegExp, event_trigger, getObjectHash, isGUID} from "../../src/core.js";
34
34
  import Button from "./Button.jsx";
35
35
  import {useAuthContext} from "./contexts/AuthContext.jsx";
36
- import {RTE} from "./RTE.jsx";
37
36
  import APIInfo from "./APIInfo.jsx";
38
- import {xt256} from "react-code-blocks";
39
- import {isList} from "@tiptap/react";
40
37
  import {useNotificationContext} from "./NotificationProvider.jsx";
41
- import modelCreator from "./ModelCreator.jsx";
42
- import RelationField from "./RelationField.jsx";
43
- import RelationValue from "./RelationValue.jsx";
44
38
  import {ModelImporter} from "./ModelImporter.jsx";
45
39
  import {DataTable} from "./DataTable.jsx";
46
40
  import {ModelList} from "./ModelList.jsx";
@@ -217,6 +211,10 @@ function DataLayout() {
217
211
  mainPartRef.current.scrollIntoView({behavior: "smooth"});
218
212
  handleAddData(model);
219
213
  }}
214
+ onDuplicateData={(data) => {
215
+ mainPartRef.current.scrollIntoView({behavior: "smooth"});
216
+ handleAddData(selectedModel, data);
217
+ }}
220
218
  onShowAPI={() => {
221
219
  setAPIInfoVisible(true);
222
220
  setDataEditorVisible(false);
@@ -482,18 +480,23 @@ function DataLayout() {
482
480
  }
483
481
  };
484
482
 
485
- const handleAddData = (model)=>{
483
+ const handleAddData = (model, data)=>{
486
484
 
487
485
  handleModelSelect(model);
488
- const t = model ? [...model.fields].reduce((acc, field) => {
489
- if( field.type === "relation"){
490
- acc[field.name] = field.multiple ? [] : null;
491
- }else {
492
- acc[field.name] = getDefaultForType(field);
493
- }
494
- return acc;
495
- }, {}) : [];
496
- setFormData(t)
486
+
487
+ if( data ){
488
+ setFormData(data);
489
+ }else {
490
+ const t = model ? [...model.fields].reduce((acc, field) => {
491
+ if (field.type === "relation") {
492
+ acc[field.name] = field.multiple ? [] : null;
493
+ } else {
494
+ acc[field.name] = getDefaultForType(field);
495
+ }
496
+ return acc;
497
+ }, {}) : [];
498
+ setFormData(t)
499
+ }
497
500
  setEditionMode(false);
498
501
  setDataEditorVisible(true);
499
502
  setAPIInfoVisible(false);
@@ -545,7 +548,7 @@ function DataLayout() {
545
548
  // Si un modèle est sélectionné...
546
549
  if (selectedModel) {
547
550
  // Récupérer les étapes du tour "datapacks"
548
- const datapacksSteps = allTourSteps.datapacks;
551
+ const datapacksSteps = allTourSteps.guides;
549
552
  // S'assurer que ce tour existe et a des étapes
550
553
  if (datapacksSteps && datapacksSteps.length > 0) {
551
554
  // 1. Définir les étapes du tour qui doit être affiché