data-primals-engine 1.3.4 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +797 -782
- package/client/README.md +20 -0
- package/client/package-lock.json +712 -147
- package/client/package.json +38 -37
- package/client/src/App.jsx +9 -10
- package/client/src/App.scss +7 -1
- package/client/src/Dashboard.jsx +349 -208
- package/client/src/DashboardView.jsx +569 -547
- package/client/src/DataEditor.jsx +20 -2
- package/client/src/DataLayout.jsx +24 -12
- package/client/src/DataTable.jsx +807 -760
- package/client/src/DataTable.scss +187 -90
- package/client/src/Field.jsx +1783 -1656
- package/client/src/ModelCreator.jsx +2 -2
- package/client/src/ModelCreatorField.jsx +906 -804
- package/client/src/ModelList.jsx +2 -2
- package/client/src/constants.js +16 -4
- package/client/src/translations.js +241 -3
- package/package.json +3 -3
- package/src/core.js +9 -0
- package/src/defaultModels.js +18 -10
- package/src/email.js +2 -1
- package/src/i18n.js +501 -28
- package/src/modules/data/data.core.js +5 -1
- package/src/modules/data/data.history.js +489 -489
- package/src/modules/data/data.js +75 -9
- package/src/modules/data/data.routes.js +3 -20
- package/src/modules/user.js +19 -0
- package/src/modules/workflow.js +2 -12
- package/client/public/demo/26899917-d1ba-4df4-bb33-48d09a8778da.jpg +0 -0
- package/client/public/demo/4b9894c7-12cd-466d-8fd3-a2757b09ec96.jpg +0 -0
- package/client/public/demo/7ed369ac-a1a2-4b45-b0cd-4fd5bcf5a75a.jpg +0 -0
|
@@ -8,10 +8,10 @@ import RelationField from "./RelationField.jsx";
|
|
|
8
8
|
import {
|
|
9
9
|
CheckboxField,
|
|
10
10
|
CodeField,
|
|
11
|
-
ColorField, EmailField,
|
|
11
|
+
ColorField, DurationField, EmailField,
|
|
12
12
|
EnumField,
|
|
13
13
|
FileField, ModelField, NumberField,
|
|
14
|
-
PhoneField,
|
|
14
|
+
PhoneField, RangeField,
|
|
15
15
|
SelectField,
|
|
16
16
|
TextField
|
|
17
17
|
} from "./Field.jsx";
|
|
@@ -212,6 +212,24 @@ export const DataEditor = forwardRef(function MyDataEditor({
|
|
|
212
212
|
}}/></>;
|
|
213
213
|
}
|
|
214
214
|
case "number":
|
|
215
|
+
if (field.type === 'number' && field.gauge) {
|
|
216
|
+
return <RangeField
|
|
217
|
+
name={field.name}
|
|
218
|
+
value={value}
|
|
219
|
+
onChange={(value) => handleChange({name: field.name, value})}
|
|
220
|
+
min={field.min}
|
|
221
|
+
max={field.max}
|
|
222
|
+
percent={field.percent}
|
|
223
|
+
step={field.step || 1}
|
|
224
|
+
/>;
|
|
225
|
+
}
|
|
226
|
+
if (field.delay) {
|
|
227
|
+
return <DurationField
|
|
228
|
+
{...inputProps}
|
|
229
|
+
// DurationField's onChange provides an object: { name, value }
|
|
230
|
+
onChange={({ value }) => handleChange({name: field.name, value})}
|
|
231
|
+
/>;
|
|
232
|
+
}
|
|
215
233
|
inputProps["step"] = field.step || 0.1;
|
|
216
234
|
if( field.min )
|
|
217
235
|
inputProps["min"] = field.min;
|
|
@@ -9,9 +9,10 @@ import {Pagination} from "./Pagination.jsx";
|
|
|
9
9
|
import {Event} from "../../src/events.js";
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
|
+
FaEye,
|
|
12
13
|
FaFilter, FaInfo,
|
|
13
14
|
} from "react-icons/fa";
|
|
14
|
-
import {getDefaultForType, getUserId} from "../../src/data.js";
|
|
15
|
+
import {getDefaultForType, getUserHash, getUserId} from "../../src/data.js";
|
|
15
16
|
import {Trans, useTranslation} from "react-i18next";
|
|
16
17
|
|
|
17
18
|
import {getObjectHash} from "../../src/core.js";
|
|
@@ -32,7 +33,8 @@ import KanbanConfigModal from "./KanbanConfigModal.jsx";
|
|
|
32
33
|
import CalendarConfigModal from "./CalendarConfigModal.jsx";
|
|
33
34
|
import KanbanView from "./KanbanView.jsx";
|
|
34
35
|
import CalendarView from "./CalendarView.jsx";
|
|
35
|
-
import {useParams, useSearchParams} from "react-router-dom";
|
|
36
|
+
import {useLocation, useParams, useSearchParams} from "react-router-dom";
|
|
37
|
+
import { useNavigate } from "react-router-dom";
|
|
36
38
|
|
|
37
39
|
|
|
38
40
|
const NotConfiguredPlaceholder = ({ type, onConfigure }) => (
|
|
@@ -45,7 +47,7 @@ const NotConfiguredPlaceholder = ({ type, onConfigure }) => (
|
|
|
45
47
|
</div>
|
|
46
48
|
);
|
|
47
49
|
|
|
48
|
-
function DataLayout() {
|
|
50
|
+
function DataLayout({refreshUI}) {
|
|
49
51
|
const [ searchParams, setSearchParams ] = useSearchParams();
|
|
50
52
|
const [viewSettings, setViewSettings] = useLocalStorage('viewSettings', {});
|
|
51
53
|
|
|
@@ -89,16 +91,14 @@ function DataLayout() {
|
|
|
89
91
|
const [editionMode, setEditionMode] = useState(false);
|
|
90
92
|
const [showDataEditor, setDataEditorVisible] = useState(false);
|
|
91
93
|
const [showAPIInfo, setAPIInfoVisible] = useState(false);
|
|
92
|
-
|
|
94
|
+
const nav = useNavigate();
|
|
93
95
|
const mod = searchParams.get('model');
|
|
96
|
+
const loc = useLocation();
|
|
94
97
|
useEffect(() =>{
|
|
95
|
-
if (selectedModel?.name)
|
|
96
|
-
|
|
98
|
+
if (selectedModel?.name) {
|
|
99
|
+
nav('/user/' + getUserHash(me) + '/?model=' + selectedModel?.name);
|
|
100
|
+
}
|
|
97
101
|
}, [selectedModel?.name])
|
|
98
|
-
useEffect(() =>{
|
|
99
|
-
setSelectedModel(models.find(f => f.name === mod));
|
|
100
|
-
setEditionMode(false);
|
|
101
|
-
}, [mod, models])
|
|
102
102
|
|
|
103
103
|
|
|
104
104
|
useEffect(() => {
|
|
@@ -107,6 +107,13 @@ function DataLayout() {
|
|
|
107
107
|
setAPIInfoVisible(false);
|
|
108
108
|
setEditionMode(true);
|
|
109
109
|
}, []);
|
|
110
|
+
|
|
111
|
+
useEffect(() =>{
|
|
112
|
+
setSelectedModel(models.find(f => f.name === mod));
|
|
113
|
+
setEditionMode(false);
|
|
114
|
+
}, [mod, models, searchParams])
|
|
115
|
+
|
|
116
|
+
|
|
110
117
|
// La vue courante est dérivée du modèle sélectionné et des préférences stockées.
|
|
111
118
|
const currentView = useMemo(() => {
|
|
112
119
|
if (!selectedModel) return 'table';
|
|
@@ -689,10 +696,15 @@ function DataLayout() {
|
|
|
689
696
|
onConfigureView={handleConfigureCurrentView}
|
|
690
697
|
/>}
|
|
691
698
|
<h2>{t(`model_${selectedModel?.name}`, selectedModel?.name)} <>({countByModel?.[selectedModel?.name]})</></h2>
|
|
692
|
-
|
|
699
|
+
|
|
700
|
+
<div className={"flex"}>
|
|
701
|
+
{t(`model_${selectedModel?.name}`, selectedModel?.name) !== selectedModel?.name && (
|
|
693
702
|
<span className="badge"><strong>model</strong> : {selectedModel?.name}</span>)}
|
|
703
|
+
{selectedModel.name === 'dashboard' && <button onClick={() => {
|
|
704
|
+
nav('/user/'+getUserHash(me)+'/dashboards');
|
|
705
|
+
}}><FaEye /> Afficher les tableaux de bord</button> }
|
|
706
|
+
</div>
|
|
694
707
|
<p className="model-desc hint">{t(`model_description_${selectedModel.name}`, selectedModel.description)}</p>
|
|
695
|
-
|
|
696
708
|
{renderCurrentView()}
|
|
697
709
|
|
|
698
710
|
{isDataLoaded && currentView === 'table' && (<>
|