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.
- package/README.md +5 -1
- package/client/package-lock.json +11580 -11664
- package/client/package.json +69 -69
- package/client/src/APIInfo.jsx +2 -5
- package/client/src/App.jsx +12 -7
- package/client/src/CalculationBuilder.jsx +2 -2
- package/client/src/ConditionBuilder.scss +24 -0
- package/client/src/ConditionBuilder2.jsx +56 -0
- package/client/src/Dashboard.jsx +2 -2
- package/client/src/DashboardChart.jsx +1 -1
- package/client/src/DashboardFlexViewItem.jsx +1 -1
- package/client/src/DashboardView.jsx +1 -1
- package/client/src/DataEditor.jsx +3 -3
- package/client/src/DataLayout.jsx +23 -20
- package/client/src/DataTable.jsx +80 -13
- package/client/src/Dialog.scss +1 -0
- package/client/src/DisplayFlexNodeRenderer.jsx +2 -2
- package/client/src/Field.jsx +2 -2
- package/client/src/FlexBuilder.jsx +1 -1
- package/client/src/KPIWidget.jsx +1 -1
- package/client/src/KanbanCard.jsx +1 -1
- package/client/src/ModelCreator.jsx +3 -3
- package/client/src/ModelCreatorField.jsx +2 -2
- package/client/src/ModelImporter.jsx +1 -1
- package/client/src/PackGallery.jsx +1 -1
- package/client/src/RTETrans.jsx +1 -1
- package/client/src/RelationField.jsx +1 -1
- package/client/src/RelationValue.jsx +1 -1
- package/client/src/TourSpotlight.jsx +14 -10
- package/client/src/TutorialsMenu.scss +0 -1
- package/client/src/Webpage.jsx +2 -2
- package/client/src/constants.js +2 -1
- package/client/src/contexts/ModelContext.jsx +5 -11
- package/client/src/core/dom.js +26 -0
- package/client/src/filter.js +40 -1
- package/client/src/hooks/data.js +1 -1
- package/client/src/hooks/useTutorials.jsx +1 -1
- package/package.json +4 -6
- package/server.js +3 -2
- package/src/constants.js +3 -0
- package/src/engine.js +18 -13
- package/src/i18n.js +77 -3
- package/src/modules/assistant.js +1 -1
- package/src/modules/bucket.js +1 -1
- package/src/modules/data.js +14 -3
- package/src/modules/file.js +1 -1
- package/src/modules/user.js +1 -1
- package/src/modules/workflow.js +1 -1
- package/src/packs.js +4 -3
- package/src/setenv.js +1 -1
- package/test/data.integration.test.js +4 -10
- package/test/workflow.robustness.test.js +1 -1
package/client/package.json
CHANGED
|
@@ -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
|
-
"
|
|
15
|
-
"@
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"react-
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"react-
|
|
47
|
-
"react-
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"
|
|
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
|
}
|
package/client/src/APIInfo.jsx
CHANGED
|
@@ -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 "
|
|
6
|
+
import {getDefaultForType} from "../../src/data.js";
|
|
7
7
|
import { CodeBlock, tomorrowNightBright } from 'react-code-blocks';
|
|
8
|
-
import {
|
|
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= {}}) => {
|
package/client/src/App.jsx
CHANGED
|
@@ -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 "
|
|
56
|
-
import {getRandom} from "
|
|
57
|
-
import {getUserHash} from "
|
|
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
|
-
|
|
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 "
|
|
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 "
|
|
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 (
|
package/client/src/Dashboard.jsx
CHANGED
|
@@ -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 "
|
|
14
|
-
import {getUserHash, getUserId} from "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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('
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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.
|
|
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é
|