data-primals-engine 1.7.1 → 1.7.3

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 (99) hide show
  1. package/README.md +9 -9
  2. package/client/package-lock.json +8430 -8121
  3. package/client/package.json +7 -4
  4. package/client/src/APIInfo.jsx +1 -1
  5. package/client/src/App.jsx +2 -1
  6. package/client/src/App.scss +1635 -1626
  7. package/client/src/AssistantChat.jsx +2 -3
  8. package/client/src/CalendarView.jsx +1 -0
  9. package/client/src/ContentView.jsx +3 -3
  10. package/client/src/Dashboard.jsx +5 -2
  11. package/client/src/DashboardChart.jsx +1 -0
  12. package/client/src/DashboardFlexViewItem.jsx +1 -0
  13. package/client/src/DashboardHtmlViewItem.jsx +1 -0
  14. package/client/src/DashboardView.jsx +2 -0
  15. package/client/src/DataEditor.jsx +0 -1
  16. package/client/src/DataImporter.jsx +489 -468
  17. package/client/src/DataLayout.jsx +25 -23
  18. package/client/src/DataTable.jsx +6 -5
  19. package/client/src/Dialog.jsx +92 -90
  20. package/client/src/Dialog.scss +122 -116
  21. package/client/src/DisplayFlexNodeRenderer.jsx +1 -0
  22. package/client/src/DocumentationPageLayout.scss +1 -1
  23. package/client/src/FlexBuilderControls.jsx +1 -0
  24. package/client/src/FlexBuilderPreview.jsx +1 -1
  25. package/client/src/FlexNode.jsx +1 -1
  26. package/client/src/HistoryDialog.jsx +3 -2
  27. package/client/src/KPIWidget.jsx +1 -1
  28. package/client/src/KanbanView.jsx +1 -0
  29. package/client/src/ModelCreator.jsx +4 -0
  30. package/client/src/ModelList.jsx +1 -0
  31. package/client/src/PackGallery.jsx +5 -4
  32. package/client/src/RTETrans.jsx +1 -1
  33. package/client/src/RelationField.jsx +2 -0
  34. package/client/src/RelationSelectorWidget.jsx +2 -0
  35. package/client/src/RelationValue.jsx +1 -0
  36. package/client/src/RestoreDialog.jsx +1 -0
  37. package/client/src/ViewSwitcher.jsx +1 -1
  38. package/client/src/WorkflowEditor.jsx +3 -0
  39. package/client/src/contexts/CommandContext.jsx +2 -1
  40. package/client/src/contexts/ModelContext.jsx +3 -3
  41. package/client/src/hooks/data.js +1 -0
  42. package/client/src/hooks/useValidation.js +1 -0
  43. package/client/src/translations.js +24 -24
  44. package/client/vite.config.js +31 -30
  45. package/doc/AI-assistance.md +87 -63
  46. package/doc/Concepts.md +122 -0
  47. package/doc/Custom-Endpoints.md +31 -0
  48. package/doc/Event-system.md +13 -14
  49. package/doc/Home.md +33 -0
  50. package/doc/Modules.md +83 -0
  51. package/doc/Packs-gallery.md +8 -23
  52. package/doc/Workflows.md +32 -0
  53. package/doc/automation-workflows.md +141 -102
  54. package/doc/dashboards-kpis-charts.md +47 -49
  55. package/doc/data-management.md +126 -120
  56. package/doc/data-models.md +68 -75
  57. package/doc/roles-permissions.md +144 -43
  58. package/doc/sharding-replication.md +158 -0
  59. package/doc/users.md +54 -30
  60. package/package.json +27 -17
  61. package/server.js +37 -37
  62. package/src/ai.jobs.js +135 -0
  63. package/src/constants.js +560 -545
  64. package/src/data.js +521 -518
  65. package/src/email.js +157 -154
  66. package/src/engine.js +167 -49
  67. package/src/gameObject.js +6 -0
  68. package/src/i18n.js +0 -1
  69. package/src/modules/assistant/assistant.js +782 -763
  70. package/src/modules/assistant/constants.js +23 -16
  71. package/src/modules/assistant/providers.js +77 -37
  72. package/src/modules/auth-google/index.js +53 -50
  73. package/src/modules/bucket.js +346 -335
  74. package/src/modules/data/data.backup.js +400 -376
  75. package/src/modules/data/data.cluster.js +559 -0
  76. package/src/modules/data/data.core.js +11 -8
  77. package/src/modules/data/data.js +311 -311
  78. package/src/modules/data/data.operations.js +3666 -3555
  79. package/src/modules/data/data.relations.js +1 -0
  80. package/src/modules/data/data.replication.js +125 -0
  81. package/src/modules/data/data.routes.js +2206 -1879
  82. package/src/modules/data/data.scheduling.js +2 -1
  83. package/src/modules/file.js +248 -247
  84. package/src/modules/mongodb.js +76 -73
  85. package/src/modules/user.js +18 -2
  86. package/src/modules/worker-script-runner.js +97 -0
  87. package/src/modules/workflow.js +177 -52
  88. package/src/packs.js +5701 -5701
  89. package/src/providers.js +298 -297
  90. package/src/sso.js +91 -25
  91. package/test/assistant.test.js +207 -206
  92. package/test/cluster.test.js +221 -0
  93. package/test/core.test.js +0 -2
  94. package/test/data.integration.test.js +1425 -1416
  95. package/test/import_export.integration.test.js +210 -210
  96. package/test/replication.test.js +163 -0
  97. package/test/workflow.actions.integration.test.js +487 -475
  98. package/test/workflow.integration.test.js +332 -329
  99. package/doc/core-concepts.md +0 -33
@@ -60,12 +60,12 @@ const NotConfiguredPlaceholder = ({ type, onConfigure }) => (
60
60
 
61
61
  const WorkflowSelectorModal = ({ onClose, onSelectWorkflow }) => {
62
62
  const { t } = useTranslation();
63
- const { searchData } = useModelContext();
64
63
  const { me } = useAuthContext();
65
64
  const { data: activeWorkflows, isLoading } = useQuery(
66
65
  'activeWorkflowsList',
67
66
  () => fetch('/api/data/search?_user='+me.username, {
68
67
  method: 'POST',
68
+ credentials: "include",
69
69
  headers: { 'Content-Type': 'application/json' },
70
70
  body: JSON.stringify({
71
71
  model: 'workflow',
@@ -96,7 +96,7 @@ const WorkflowSelectorModal = ({ onClose, onSelectWorkflow }) => {
96
96
  );
97
97
  };
98
98
 
99
- function DataLayout({refreshUI}) {
99
+ function DataLayout({refreshUI}, ref) {
100
100
  const [ searchParams, setSearchParams ] = useSearchParams();
101
101
  const [viewSettings, setViewSettings] = useLocalStorage('viewSettings', {});
102
102
 
@@ -147,6 +147,7 @@ function DataLayout({refreshUI}) {
147
147
 
148
148
  const mainPartRef = useRef();
149
149
  const modelCreatorRef = useRef();
150
+ const dataEditorRef = useRef(null);
150
151
 
151
152
  const [tutorialDialogVisible, setTutorialDialogVisible] = useState(false);
152
153
  const [importModalVisible, setImportModalVisible] = useState(false);
@@ -155,7 +156,6 @@ function DataLayout({refreshUI}) {
155
156
  const [showAPIInfo, setAPIInfoVisible] = useState(false);
156
157
  const nav = useNavigate();
157
158
  const mod = searchParams.get('model');
158
- const loc = useLocation();
159
159
 
160
160
 
161
161
  // --- AJOUT : Récupérer le paramètre de l'URL pour l'édition de workflow ---
@@ -300,18 +300,24 @@ function DataLayout({refreshUI}) {
300
300
  setFilterValues={setFilterValues}
301
301
  model={selectedModel}
302
302
  onAddData={(model) => {
303
- mainPartRef.current.scrollIntoView({behavior: "smooth"});
304
303
  handleAddData(model);
304
+ setTimeout(() => {
305
+ dataEditorRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
306
+ }, 100);
305
307
  }}
306
308
  onDuplicateData={(data) => {
307
- mainPartRef.current.scrollIntoView({behavior: "smooth"});
308
309
  handleAddData(selectedModel, data);
310
+ setTimeout(() => {
311
+ dataEditorRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
312
+ }, 100);
309
313
  }}
310
314
  onEdit={(item) => {
311
- mainPartRef.current.scrollIntoView({behavior: "smooth"});
312
315
  setRecordToEdit(item);
313
316
  setFormData(item);
314
317
  setDataEditorVisible(true);
318
+ setTimeout(() => {
319
+ dataEditorRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
320
+ }, 100);
315
321
  }}
316
322
  deleteApiCall={deleteApiCall}
317
323
  queryClient={queryClient}
@@ -428,7 +434,8 @@ function DataLayout({refreshUI}) {
428
434
  ///fd.append("files", fd2);
429
435
  return fetch(`${url}?lang=${lang}&_user=${encodeURIComponent(getUserId(me))}`, {
430
436
  method,
431
- body: fd
437
+ body: fd,
438
+ credentials: "include",
432
439
  }).then(e => e.json());
433
440
  } catch (error) {
434
441
  console.error('Erreur lors de l\'enregistrement des données:', error);
@@ -508,7 +515,8 @@ function DataLayout({refreshUI}) {
508
515
  return fetch(`/api/data/${ids}?lang=${lang}&_user=${encodeURIComponent(getUserId(me))}`, {
509
516
  method: 'DELETE', headers: {
510
517
  'Content-Type': 'application/json'
511
- }
518
+ },
519
+ credentials: "include"
512
520
  }).then(e => e.json());
513
521
  }, [lang, me]);
514
522
 
@@ -531,7 +539,7 @@ function DataLayout({refreshUI}) {
531
539
  return fetch('/api/models/import', { method: 'POST', headers: {
532
540
  'Content-Type': 'application/json'
533
541
  },
534
- body: JSON.stringify({ models: selectedModels.map(m => m.name) })
542
+ credentials: "include",body: JSON.stringify({ models: selectedModels.map(m => m.name) })
535
543
  })
536
544
  });
537
545
 
@@ -586,13 +594,6 @@ function DataLayout({refreshUI}) {
586
594
  setImportModalVisible(false);
587
595
  }
588
596
 
589
- useEffect(() => {
590
- if( showDataEditor && mainPartRef.current ){
591
-
592
- }
593
- }, [showDataEditor,mainPartRef.current]);
594
-
595
-
596
597
  const [currentProfile, setCurrentProfile] = useLocalStorage('profile', null);
597
598
  const {isTourOpen, setIsTourOpen, currentTourSteps, allTourSteps, setTourStepIndex, setCurrentTourSteps, currentTour,setCurrentTour, addLaunchedTour, assistantConfig, setAssistantConfig} = useUI();
598
599
 
@@ -707,7 +708,7 @@ function DataLayout({refreshUI}) {
707
708
  onSelectWorkflow={(id) => {
708
709
  nav(`?edit-workflow=${id}`);
709
710
  setEditionMode(false)
710
- mainPartRef.current.scrollIntoView();
711
+ mainPartRef.current?.scrollIntoView();
711
712
  setCurrentView('workflow'); // Ajout pour forcer le changement de vue
712
713
  setWorkflowListModalOpen(false);
713
714
  }}
@@ -740,7 +741,7 @@ function DataLayout({refreshUI}) {
740
741
  setAPIInfoVisible(false);
741
742
  setDataEditorVisible(false);
742
743
  setEditionMode(true);
743
- mainPartRef.current.scrollIntoView({behavior: 'smooth'});
744
+ mainPartRef.current?.scrollIntoView({behavior: 'smooth'});
744
745
  gtag("event", "select_content", {
745
746
  content_type: "create_model",
746
747
  });
@@ -750,7 +751,7 @@ function DataLayout({refreshUI}) {
750
751
  setAPIInfoVisible(false);
751
752
  setEditionMode(true);
752
753
 
753
- mainPartRef.current.scrollIntoView({behavior: 'smooth'});
754
+ mainPartRef.current?.scrollIntoView({behavior: 'smooth'});
754
755
  gtag("event", "select_content", {
755
756
  content_type: "edit_model",
756
757
  content_id: model.name
@@ -760,7 +761,7 @@ function DataLayout({refreshUI}) {
760
761
  setDataEditorVisible(false);
761
762
  setEditionMode(false);
762
763
  setAPIInfoVisible(false);
763
- mainPartRef.current.scrollIntoView({behavior: 'smooth'});
764
+ //mainPartRef.current?.scrollIntoView({behavior: 'smooth'});
764
765
  gtag("event", "select_content", {
765
766
  content_type: "select_model",
766
767
  content_id: model.name
@@ -768,12 +769,12 @@ function DataLayout({refreshUI}) {
768
769
  }} onImportPack={() => {
769
770
  setShowPackGallery(true);
770
771
  }} onNewData={(model) => {
771
- mainPartRef.current.scrollIntoView({behavior: 'smooth'});
772
+ mainPartRef.current?.scrollIntoView({behavior: 'smooth'});
772
773
  handleAddData(model);
773
774
  }}/>
774
775
  {(editionMode) && (
775
776
  <ModelCreator ref={modelCreatorRef} onModelGenerated={() =>{
776
- modelCreatorRef.current.scrollIntoView({behavior: 'smooth'});
777
+ modelCreatorRef?.current?.scrollIntoView({behavior: 'smooth'});
777
778
  }} initialModel={selectedModel} onModelSaved={(model) => {
778
779
  setRefreshTime(new Date().getTime());
779
780
  handleModelSelect(model);
@@ -785,7 +786,8 @@ function DataLayout({refreshUI}) {
785
786
  )}
786
787
  <div className="hidden-anchor" ref={mainPartRef}></div>
787
788
 
788
- {showDataEditor && (<DataEditor ref={mainPartRef}
789
+ {showDataEditor && (<DataEditor
790
+ ref={dataEditorRef}
789
791
  key={selectedModel?.name}
790
792
  isLoading={isLoading}
791
793
  model={selectedModel}
@@ -6,7 +6,6 @@ import {useAuthContext} from "./contexts/AuthContext.jsx";
6
6
  import React, {useEffect, useMemo, useRef, useState} from "react";
7
7
  import {getUserHash, getUserId} from "../../src/data.js";
8
8
  import cronstrue from 'cronstrue/i18n';
9
- import {Event} from "../../src/events.js";
10
9
 
11
10
  import {
12
11
  FaBook,
@@ -337,6 +336,7 @@ export function DataTable({
337
336
  return fetch(`/api/data/export?lang=${lang}&${params.toString()}`, {
338
337
  method: 'POST',
339
338
  body,
339
+ credentials: "include",
340
340
  headers: {"Content-Type": "application/json"}
341
341
  })
342
342
  .then(async resp => {
@@ -391,8 +391,9 @@ export function DataTable({
391
391
  const handleConfirmRestore = async () => {
392
392
  try {
393
393
  // Make the API call to request the restore link
394
- const response = await fetch('/api/backup/request-restore', {
394
+ const response = await fetch('/api/backup/request-restore?lang='+lang, {
395
395
  method: 'POST',
396
+ credentials: "include",
396
397
  // ... other options ...
397
398
  });
398
399
 
@@ -451,7 +452,7 @@ export function DataTable({
451
452
  <Button onClick={handleImport} title={t("btns.import")}><FaFileImport/><Trans
452
453
  i18nKey="btns.import">Importer</Trans></Button>
453
454
  <Button disabled={isLoading} onClick={handleExport} title={t("btns.export")}><FaFileExport/><Trans i18nKey="btns.export">Exporter</Trans></Button>
454
- {!/^demo[0-9]{1,2}$/.test(me.username) && (<Button onClick={handleBackup} title={t("btns.backup")}><FaDatabase/><Trans
455
+ {(<Button onClick={handleBackup} title={t("btns.backup")}><FaDatabase/><Trans
455
456
  i18nKey="btns.backup">Backup</Trans></Button>)}
456
457
 
457
458
  </div>}
@@ -738,10 +739,10 @@ export function DataTable({
738
739
  </button>)}
739
740
  {/* AJOUT : Bouton pour ouvrir l'éditeur de workflow */}
740
741
  {model.name === 'workflow' && (
741
- <NavLink to={`?edit-workflow=${item._id}`} className="datatable-action-btn workflow-edit"
742
+ <button onClick={() => nav(`?edit-workflow=${item._id}`)} className="btn-nav datatable-action-btn workflow-edit"
742
743
  data-tooltip-id="tooltipActions" data-tooltip-content={t('workflow.editor.title', "Éditeur de Workflow")}>
743
744
  <FaGear />
744
- </NavLink>
745
+ </button>
745
746
  )}
746
747
 
747
748
  <button data-tooltip-id="tooltipActions"
@@ -1,90 +1,92 @@
1
- import Button from "./Button.jsx";
2
- import { FaWindowClose } from "react-icons/fa";
3
-
4
- import "./Dialog.scss";
5
- import { createContext, useContext, useEffect, useState } from "react";
6
- import {useUI} from "./contexts/UIContext.jsx";
7
-
8
- const DialogContext = createContext({});
9
-
10
- export const useDialogContext = () => useContext(DialogContext);
11
-
12
- export const DialogProvider = ({ children }) => {
13
- const [dialogs, setDialogs] = useState(0);
14
- const { locked, setLocked } = useUI()
15
- const values = {
16
- addDialog: () => setDialogs((dialogs) => dialogs + 1),
17
- removeDialog: () =>
18
- setDialogs((dialogs) => {
19
- return dialogs > 0 ? dialogs - 1 : 0;
20
- }),
21
- };
22
- useEffect(() => {
23
- if( dialogs === 0){
24
- setLocked(false);
25
- }else{
26
- setLocked(true);
27
- }
28
- }, [dialogs]);
29
- return (
30
- <DialogContext.Provider value={values}>
31
- {dialogs > 0 ? (
32
- <>
33
- <div className="dialog-bg"></div>
34
- {children}
35
- </>
36
- ) : (
37
- children
38
- )}
39
- </DialogContext.Provider>
40
- );
41
- };
42
- export const Dialog = ({
43
- title,
44
- children,
45
- className,
46
- onClose,
47
- isClosable,
48
- isModal,
49
- }) => {
50
- const [showModal, setModalVisible] = useState(true);
51
- const { addDialog, removeDialog } = useDialogContext();
52
- const handleClose = () => {
53
- setModalVisible(false);
54
- onClose?.();
55
- removeDialog();
56
- };
57
- const clickEvent = (e) => {
58
-
59
- if( !e.target.closest('.dialog') && !e.target.closest('.notification') ){
60
- onClose?.();
61
- }
62
- };
63
- useEffect(() => {
64
- addDialog();
65
- document.addEventListener('mousedown', clickEvent);
66
- return () => {
67
- removeDialog();
68
- document.removeEventListener('mousedown', clickEvent);
69
- }
70
- }, [addDialog, removeDialog]);
71
- return showModal ? (
72
- <div
73
- aria-modal={true}
74
- aria-label={title}
75
- className={`${className ? className : ""} dialog ${isModal ? "dialog-modal" : ""}`}
76
- >
77
- <div className="dialog-header">
78
- {title && <h2>{title}</h2>}
79
- {isClosable && (
80
- <Button className={"btn btn-close"} onClick={handleClose}>
81
- <FaWindowClose />
82
- </Button>
83
- )}
84
- </div>
85
- <div className="dialog-content">{children}</div>
86
- </div>
87
- ) : (
88
- <></>
89
- );
90
- };
1
+ import Button from "./Button.jsx";
2
+ import { FaWindowClose } from "react-icons/fa";
3
+
4
+ import "./Dialog.scss";
5
+ import { createContext, useContext, useEffect, useState } from "react";
6
+ import {useUI} from "./contexts/UIContext.jsx";
7
+
8
+ const DialogContext = createContext({});
9
+
10
+ export const useDialogContext = () => useContext(DialogContext);
11
+
12
+ export const DialogProvider = ({ children }) => {
13
+ const [dialogs, setDialogs] = useState(0);
14
+ const { locked, setLocked } = useUI()
15
+ const values = {
16
+ addDialog: () => setDialogs((dialogs) => dialogs + 1),
17
+ removeDialog: () =>
18
+ setDialogs((dialogs) => {
19
+ return dialogs > 0 ? dialogs - 1 : 0;
20
+ }),
21
+ };
22
+ useEffect(() => {
23
+ if( dialogs === 0){
24
+ setLocked(false);
25
+ }else{
26
+ setLocked(true);
27
+ }
28
+ }, [dialogs]);
29
+ return (
30
+ <DialogContext.Provider value={values}>
31
+ {dialogs > 0 ? (
32
+ <>
33
+ <div className="dialog-bg"></div>
34
+ {children}
35
+ </>
36
+ ) : (
37
+ children
38
+ )}
39
+ </DialogContext.Provider>
40
+ );
41
+ };
42
+ export const Dialog = ({
43
+ title,
44
+ children,
45
+ className,
46
+ onClose,
47
+ isClosable,
48
+ isModal,
49
+ }) => {
50
+ const [showModal, setModalVisible] = useState(true);
51
+ const { addDialog, removeDialog } = useDialogContext();
52
+ const handleClose = () => {
53
+ setModalVisible(false);
54
+ onClose?.();
55
+ removeDialog();
56
+ };
57
+ const clickEvent = (e) => {
58
+
59
+ if( !e.target.closest('.dialog') && !e.target.closest('.notification') ){
60
+ onClose?.();
61
+ }
62
+ };
63
+ useEffect(() => {
64
+ addDialog();
65
+ document.addEventListener('mousedown', clickEvent);
66
+ return () => {
67
+ removeDialog();
68
+ document.removeEventListener('mousedown', clickEvent);
69
+ }
70
+ }, [addDialog, removeDialog]);
71
+ return showModal ? (
72
+ <div className="dialog-container">
73
+ <div
74
+ aria-modal={true}
75
+ aria-label={title}
76
+ className={`${className ? className : ""} dialog ${isModal ? "dialog-modal" : ""}`}
77
+ >
78
+ <div className="dialog-header">
79
+ {title && <h2>{title}</h2>}
80
+ {isClosable && (
81
+ <Button className={"btn btn-close"} onClick={handleClose}>
82
+ <FaWindowClose />
83
+ </Button>
84
+ )}
85
+ </div>
86
+ <div className="dialog-content">{children}</div>
87
+ </div>
88
+ </div>
89
+ ) : (
90
+ <></>
91
+ );
92
+ };
@@ -1,116 +1,122 @@
1
-
2
- .dialog-bg {
3
- position: fixed;
4
- top: 0;
5
- left: 0;
6
- width: 100%;
7
- height: 100%;
8
- z-index: 10000;
9
- pointer-events: none;
10
- background-color: rgba(59, 59, 59, 0.51);
11
- }
12
-
13
- #content .dialog {
14
- box-sizing: border-box;
15
- filter: opacity(1);
16
- pointer-events: all;
17
- position: fixed;
18
- overflow: visible;
19
- z-index: 10000;
20
- top: 50%;
21
- left: 50%;
22
- transform: translate(-50%, -50%);
23
- background-color: #F8F8F8;
24
- border: 1px solid #DDDDDD;
25
- border-radius: 8px;
26
- color: black;
27
- width: 90%;
28
- max-width: 1024px;
29
- min-width: 320px;
30
- box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
31
- text-align: left;
32
-
33
- }
34
-
35
- .dialog .actions {
36
- justify-content: flex-end;
37
- }
38
-
39
- .dark .dialog {
40
- background-color: #191919;
41
- color: #e3e3e3;
42
- }
43
-
44
- #content .dialog-header {
45
- display: flex;
46
- gap: 8px;
47
- justify-content: flex-start;
48
- border: none;
49
- border-bottom: 1px solid #E2E2E2;
50
- h2 {
51
- display: flex;
52
- flex: 1;
53
- padding: 0;
54
- align-items: center;
55
- margin: 8px;
56
- font-size: 100%;
57
- line-height: 208%;
58
- }
59
- .btn {
60
- display: flex;
61
- justify-self: flex-end;
62
- &.btn-close {
63
- position: absolute;
64
- right: 0px;
65
- z-index: 100;
66
- }
67
- }
68
- }
69
-
70
- #ui .dialog-content {
71
- padding: 16px;
72
- cursor: auto;
73
- word-wrap: break-word;
74
- max-height: 85vh;
75
- overflow-y: auto;
76
- .field {
77
- margin: 0;
78
- }
79
- }
80
- table {
81
- width: 100%;
82
- border: 1px solid #DDDDDD;
83
- border-collapse: collapse;
84
- td,th {
85
- padding: 3px;
86
- @media only screen and (min-width: 480px) {
87
- padding: 5px;
88
- }
89
- &.mini {
90
- cursor: pointer;
91
- min-width: auto;
92
- width: 40px;
93
- }
94
- }
95
- thead tr {
96
- background-color: #F1F1F1;
97
- font-weight: lighter;
98
- }
99
- tbody tr {
100
- }
101
- @media only screen and (max-width: 480px){
102
- font-size: 80%;
103
- }
104
- }
105
- .dark table {
106
- thead tr {
107
- background-color: #191919;
108
- color: #e3e3e3;
109
- }
110
- tbody tr {
111
- background-color: #191919;
112
- }
113
- td,th {
114
- border: 1px solid #3f3f3f;
115
- }
116
- }
1
+
2
+ .dialog-bg {
3
+ position: fixed;
4
+ top: 0;
5
+ left: 0;
6
+ width: 100%;
7
+ height: 100%;
8
+ z-index: 10000;
9
+ pointer-events: none;
10
+ background-color: rgba(59, 59, 59, 0.51);
11
+ }
12
+
13
+ .dialog-container {
14
+ position: fixed;
15
+ top: 0;
16
+ left: 0;
17
+ width: 100%;
18
+ height: 100%;
19
+ z-index: 10000;
20
+ display: flex;
21
+ align-items: center;
22
+ justify-content: center;
23
+ pointer-events: none; /* Permet de cliquer "à travers" le conteneur */
24
+ }
25
+
26
+ #content .dialog {
27
+ box-sizing: border-box;
28
+ pointer-events: all;
29
+ background-color: #F8F8F8;
30
+ border: 1px solid #DDDDDD;
31
+ border-radius: 8px;
32
+ color: black;
33
+ width: 90%;
34
+ max-width: 1024px;
35
+ min-width: 320px;
36
+ box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.25);
37
+ text-align: left;
38
+
39
+ }
40
+
41
+ .dialog .actions {
42
+ justify-content: flex-end;
43
+ }
44
+
45
+ .dark .dialog {
46
+ background-color: #191919;
47
+ color: #e3e3e3;
48
+ }
49
+
50
+ #content .dialog-header {
51
+ display: flex;
52
+ gap: 8px;
53
+ justify-content: flex-start;
54
+ border: none;
55
+ border-bottom: 1px solid #E2E2E2;
56
+ h2 {
57
+ display: flex;
58
+ flex: 1;
59
+ padding: 0;
60
+ align-items: center;
61
+ margin: 8px;
62
+ font-size: 100%;
63
+ line-height: 208%;
64
+ }
65
+ .btn {
66
+ display: flex;
67
+ justify-self: flex-end;
68
+ &.btn-close {
69
+ position: absolute;
70
+ right: 0px;
71
+ z-index: 100;
72
+ }
73
+ }
74
+ }
75
+
76
+ #ui .dialog-content {
77
+ padding: 16px;
78
+ cursor: auto;
79
+ word-wrap: break-word;
80
+ max-height: 85vh;
81
+ overflow-y: auto;
82
+ .field {
83
+ margin: 0;
84
+ }
85
+ }
86
+ table {
87
+ width: 100%;
88
+ border: 1px solid #DDDDDD;
89
+ border-collapse: collapse;
90
+ td,th {
91
+ padding: 3px;
92
+ @media only screen and (min-width: 480px) {
93
+ padding: 5px;
94
+ }
95
+ &.mini {
96
+ cursor: pointer;
97
+ min-width: auto;
98
+ width: 40px;
99
+ }
100
+ }
101
+ thead tr {
102
+ background-color: #F1F1F1;
103
+ font-weight: lighter;
104
+ }
105
+ tbody tr {
106
+ }
107
+ @media only screen and (max-width: 480px){
108
+ font-size: 80%;
109
+ }
110
+ }
111
+ .dark table {
112
+ thead tr {
113
+ background-color: #191919;
114
+ color: #e3e3e3;
115
+ }
116
+ tbody tr {
117
+ background-color: #191919;
118
+ }
119
+ td,th {
120
+ border: 1px solid #3f3f3f;
121
+ }
122
+ }
@@ -79,6 +79,7 @@ const CtaNode = ({ node, nodeStyle, dataItem }) => {
79
79
 
80
80
  if (method !== 'GET' && method !== 'HEAD' && node.requestBodyTemplate) {
81
81
  fetchOptions.body = substituteClientVariables(node.requestBodyTemplate, dataItem);
82
+ fetchOptions.credentials= "include";
82
83
  }
83
84
 
84
85
  // 3. Exécuter la requête
@@ -235,7 +235,7 @@
235
235
  }
236
236
  }
237
237
 
238
- @media only screen and (min-width: 1024Fpx){
238
+ @media only screen and (min-width: 1024px){
239
239
  .documentation-sidebar{
240
240
  max-width: 360px; // Largeur fixe pour le menu latéral
241
241
  }
@@ -30,6 +30,7 @@ const FlexBuilderControls = ({
30
30
  ['endpoints', 'GET'], // Clé de requête
31
31
  () => fetch('/api/data/search', {
32
32
  method: 'POST',
33
+ credentials: "include",
33
34
  headers: { 'Content-Type': 'application/json' },
34
35
  body: JSON.stringify({
35
36
  model: 'endpoint',