mountain-ui 1.0.22 → 1.0.24
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mountain-ui",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.24",
|
|
5
5
|
"description": "A comprehensive UI component library for ERP systems with field types, entities, and registry management built with Svelte",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"module": "index.js",
|
|
@@ -4,44 +4,83 @@
|
|
|
4
4
|
import FieldInput from './FieldInput.svelte';
|
|
5
5
|
import FormCtx from './FormCtx.svelte';
|
|
6
6
|
|
|
7
|
-
let { ctx = {}, entityId, onSubmit = ()=>{}, type = 'create' } = $props();
|
|
7
|
+
let { ctx = {}, entityId, onSubmit = () => {}, type = 'create' } = $props();
|
|
8
8
|
|
|
9
9
|
let detailsCtx = $state({});
|
|
10
10
|
|
|
11
11
|
const entity = entityRegistry.select(entityId);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
function handleSubmit() {
|
|
14
|
+
onSubmit({ ...ctx });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let calculations = $state({});
|
|
18
|
+
|
|
19
|
+
function handleRegisterCalculation(config) {
|
|
20
|
+
calculations = {
|
|
21
|
+
...calculations,
|
|
22
|
+
[config.id]: config
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function handleChange(fieldId, value) {
|
|
27
|
+
ctx[fieldId] = value;
|
|
28
|
+
|
|
29
|
+
recalculate(fieldId);
|
|
30
|
+
|
|
31
|
+
ctx = { ...ctx };
|
|
32
|
+
}
|
|
33
|
+
function handleChangeDetails(fieldId, value) {
|
|
34
|
+
detailsCtx[fieldId] = value;
|
|
35
|
+
|
|
36
|
+
// si c est un type lien alors on parcour ses champs enfant et on reagis
|
|
37
|
+
const field = entityRegistry.getField(fieldId, entity.id)
|
|
38
|
+
if (field.type === "link") {
|
|
39
|
+
const entity = entityRegistry.get(field.props.linkId)
|
|
40
|
+
for (const linkedFields of entity.fields) {
|
|
41
|
+
recalculate(linkedFields.id)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
detailsCtx = { ...detailsCtx };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function recalculate(changedFieldId) {
|
|
49
|
+
// on parcour les calcules et on verifie si un depend du champs changé
|
|
50
|
+
for (const calc of Object.values(calculations)) {
|
|
51
|
+
if (!calc.dependsOn.includes(changedFieldId)) continue;
|
|
52
|
+
|
|
53
|
+
calc.calculate(ctx);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
16
56
|
</script>
|
|
17
57
|
|
|
18
58
|
{#if $entity}
|
|
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
|
-
|
|
44
|
-
</div>
|
|
59
|
+
<div class="form">
|
|
60
|
+
<FormCtx bind:ctx bind:detailsCtx>
|
|
61
|
+
{#each $entity.fields as field}
|
|
62
|
+
<FieldInput
|
|
63
|
+
{detailsCtx}
|
|
64
|
+
{ctx}
|
|
65
|
+
onChangeDetails={(value) => {
|
|
66
|
+
handleChangeDetails(field.id, value);
|
|
67
|
+
}}
|
|
68
|
+
onChange={(value) => {
|
|
69
|
+
handleChange(field.id, value);
|
|
70
|
+
}}
|
|
71
|
+
id={field.id}
|
|
72
|
+
entityId={$entity.id}
|
|
73
|
+
value={ctx?.[field.id] ?? null}
|
|
74
|
+
registerCalculation={handleRegisterCalculation}
|
|
75
|
+
></FieldInput>
|
|
76
|
+
{/each}
|
|
77
|
+
<div class="button">
|
|
78
|
+
<Button onClick={handleSubmit}>
|
|
79
|
+
<h4>{type === 'create' ? 'créer' : 'éditer'}</h4>
|
|
80
|
+
</Button>
|
|
81
|
+
</div>
|
|
82
|
+
</FormCtx>
|
|
83
|
+
</div>
|
|
45
84
|
{/if}
|
|
46
85
|
|
|
47
86
|
<style>
|
|
@@ -19,36 +19,34 @@
|
|
|
19
19
|
...props
|
|
20
20
|
} = $props();
|
|
21
21
|
|
|
22
|
-
|
|
23
22
|
let table = $state([createLine()]);
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
onMount(() => {
|
|
25
|
+
if (value === null) return;
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
const decodedValue = JSON.parse(value);
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
let newLines = [];
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
for (const line of decodedValue) {
|
|
32
|
+
const lineId = line.id;
|
|
33
|
+
delete line.id;
|
|
34
|
+
const newLine = createLine(lineId, line);
|
|
35
|
+
newLines.push(newLine);
|
|
36
|
+
}
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
table = [...newLines];
|
|
39
|
+
});
|
|
41
40
|
|
|
42
41
|
function createLine(dbId = null, line = null) {
|
|
43
42
|
return {
|
|
44
43
|
id: crypto.randomUUID(),
|
|
45
|
-
|
|
46
|
-
ctx: line??{},
|
|
44
|
+
dbId: dbId,
|
|
45
|
+
ctx: line ?? {},
|
|
47
46
|
detailsCtx: {}
|
|
48
47
|
};
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
|
|
52
50
|
function handleAddLine() {
|
|
53
51
|
table = [...table, createLine()];
|
|
54
52
|
}
|
|
@@ -57,32 +55,74 @@
|
|
|
57
55
|
|
|
58
56
|
function handleDeleteLine(lineIndex) {
|
|
59
57
|
table = table.filter((_, i) => i !== lineIndex);
|
|
60
|
-
|
|
58
|
+
onChangeDetails(table)
|
|
61
59
|
handleChange();
|
|
62
60
|
}
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
|
|
62
|
+
let calculations = $state({});
|
|
63
|
+
|
|
64
|
+
function handleRegisterCalculation(config) {
|
|
65
|
+
calculations = {
|
|
66
|
+
...calculations,
|
|
67
|
+
[config.id]: config
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function handleChange(lineIndex, fieldId, value) {
|
|
72
|
+
table[lineIndex].ctx[fieldId] = value;
|
|
73
|
+
|
|
74
|
+
recalculate(lineIndex, fieldId);
|
|
75
|
+
|
|
76
|
+
table = [...table];
|
|
77
|
+
|
|
78
|
+
const newValue = JSON.stringify(
|
|
79
|
+
table.map((line) => {
|
|
80
|
+
const data = {
|
|
81
|
+
...line.ctx
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
if (line.dbId != null) {
|
|
85
|
+
data.id = line.dbId;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return data;
|
|
89
|
+
})
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
onChange(newValue);
|
|
65
93
|
}
|
|
66
|
-
function handleChange() {
|
|
67
|
-
const value = JSON.stringify(table.map((line) => {
|
|
68
|
-
const data = {
|
|
69
|
-
...line.ctx,
|
|
70
|
-
}
|
|
71
94
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
95
|
+
function handleChangeDetails(lineIndex, fieldId, value) {
|
|
96
|
+
table[lineIndex].detailsCtx[fieldId] = value;
|
|
75
97
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
98
|
+
// si c est un type lien alors on parcour ses champs enfant et on reagis
|
|
99
|
+
const field = entityRegistry.getField(fieldId, entity.id);
|
|
100
|
+
if (field.type === 'link') {
|
|
101
|
+
const entity = entityRegistry.get(field.props.linkId);
|
|
102
|
+
for (const linkedFields of entity.fields) {
|
|
103
|
+
recalculate(lineIndex, linkedFields.id);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
79
106
|
|
|
80
|
-
|
|
107
|
+
table = [...table];
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
onChangeDetails(table);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function recalculate(lineIndex, changedFieldId) {
|
|
114
|
+
// on parcour les calcules et on verifie si un depend du champs changé
|
|
115
|
+
for (const calc of Object.values(calculations)) {
|
|
116
|
+
console.log(changedFieldId);
|
|
117
|
+
if (!calc.dependsOn.includes(changedFieldId)) continue;
|
|
118
|
+
|
|
119
|
+
calc.calculate(table[lineIndex].ctx);
|
|
120
|
+
}
|
|
81
121
|
}
|
|
82
122
|
</script>
|
|
83
123
|
|
|
84
124
|
<div class="title">
|
|
85
|
-
|
|
125
|
+
<Label {label} {required} {secret} {unique}></Label>
|
|
86
126
|
</div>
|
|
87
127
|
<ResponsiveTable.Root let:ctx>
|
|
88
128
|
<ResponsiveTable.Header>
|
|
@@ -107,17 +147,14 @@
|
|
|
107
147
|
detailsCtx={table[lineIndex].detailsCtx}
|
|
108
148
|
ctx={table[lineIndex].ctx}
|
|
109
149
|
onChangeDetails={(value) => {
|
|
110
|
-
|
|
111
|
-
table = [...table];
|
|
112
|
-
handleChangeDetailsCtx();
|
|
150
|
+
handleChangeDetails(lineIndex, row.fieldId, value);
|
|
113
151
|
}}
|
|
114
152
|
onChange={(value) => {
|
|
115
|
-
|
|
116
|
-
table = [...table];
|
|
117
|
-
handleChange();
|
|
153
|
+
handleChange(lineIndex, row.fieldId, value);
|
|
118
154
|
}}
|
|
119
155
|
id={row.fieldId}
|
|
120
156
|
value={table[lineIndex].ctx?.[row.fieldId] ?? null}
|
|
157
|
+
registerCalculation={handleRegisterCalculation}
|
|
121
158
|
></FieldInput>
|
|
122
159
|
{/each}
|
|
123
160
|
{#if columnIndex + 1 === columns.length}
|
|
@@ -167,17 +204,17 @@
|
|
|
167
204
|
</ResponsiveTable.Body>
|
|
168
205
|
</ResponsiveTable.Root>
|
|
169
206
|
<div class="title">
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
207
|
+
<Button onClick={handleAddLine}>
|
|
208
|
+
<h5>ajouter une rangée</h5>
|
|
209
|
+
</Button>
|
|
173
210
|
</div>
|
|
174
211
|
|
|
175
212
|
<style>
|
|
176
|
-
.title {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
213
|
+
.title {
|
|
214
|
+
display: flex;
|
|
215
|
+
align-items: center;
|
|
216
|
+
width: 100%;
|
|
217
|
+
}
|
|
181
218
|
:global(.table-container .line):has(.delete :global(.button):hover) {
|
|
182
219
|
background-color: var(--red-b);
|
|
183
220
|
}
|
package/src/lib/registry/fieldTypeRegistry/fieldTypes/calculation/CalculationColumn/Input.svelte
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
detailsCtx = {},
|
|
19
19
|
onChange = () => {},
|
|
20
20
|
onChangeDetails = () => {},
|
|
21
|
+
registerCalculation = () => {},
|
|
21
22
|
operator = '',
|
|
22
23
|
column1 = '',
|
|
23
24
|
column2 = '',
|
|
@@ -29,58 +30,95 @@
|
|
|
29
30
|
const field1 = entityRegistry.selectField(column1);
|
|
30
31
|
const field2 = entityRegistry.selectField(column2);
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
let previousValue1 = Symbol();
|
|
34
|
+
let previousValue2 = Symbol();
|
|
35
|
+
|
|
36
|
+
function getFieldValue(field, ctx) {
|
|
37
|
+
if (!field) return null;
|
|
38
|
+
|
|
39
|
+
// Champ local
|
|
40
|
+
if (field.entity_id === entity_id) {
|
|
41
|
+
let v = ctx[field.id];
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
const raw2 = ctx[column2] ?? null;
|
|
43
|
+
if (v == null) return null;
|
|
37
44
|
|
|
38
|
-
|
|
39
|
-
let value2 = raw2 ? parseFloat(raw2) : null;
|
|
45
|
+
v = parseFloat(v);
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
if (field.type === 'number-float-percent') {
|
|
48
|
+
v /= 100;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return isNaN(v) ? 0 : v;
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
// Champ lié
|
|
55
|
+
const linkField = entityRegistry.getLinkedField(entity_id, field.entity_id);
|
|
56
|
+
|
|
57
|
+
if (!linkField) return null;
|
|
58
|
+
|
|
59
|
+
let v = detailsCtx[linkField.id]?.[field.normalized_name]?.flat;
|
|
60
|
+
|
|
61
|
+
if (v == null) return null;
|
|
62
|
+
|
|
63
|
+
v = parseFloat(v);
|
|
64
|
+
|
|
65
|
+
if (field.type === 'number-float-percent') {
|
|
66
|
+
v /= 100;
|
|
53
67
|
}
|
|
54
68
|
|
|
55
|
-
|
|
69
|
+
return isNaN(v) ? 0 : v;
|
|
70
|
+
}
|
|
56
71
|
|
|
57
|
-
|
|
58
|
-
if (
|
|
72
|
+
function calculate(ctx) {
|
|
73
|
+
if (!$field1 || !$field2) return;
|
|
59
74
|
|
|
60
|
-
const
|
|
75
|
+
const value1 = getFieldValue($field1, ctx);
|
|
76
|
+
const value2 = getFieldValue($field2, ctx);
|
|
77
|
+
|
|
78
|
+
if (value1 === null || value2 === null) return;
|
|
79
|
+
|
|
80
|
+
if (value1 === previousValue1 && value2 === previousValue2) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
previousValue1 = value1;
|
|
85
|
+
previousValue2 = value2;
|
|
86
|
+
|
|
87
|
+
let result = null;
|
|
61
88
|
|
|
62
89
|
switch (operator) {
|
|
63
90
|
case '+':
|
|
64
|
-
|
|
91
|
+
result = value1 + value2;
|
|
65
92
|
break;
|
|
93
|
+
|
|
66
94
|
case '-':
|
|
67
|
-
|
|
95
|
+
result = value1 - value2;
|
|
68
96
|
break;
|
|
97
|
+
|
|
69
98
|
case '*':
|
|
70
|
-
|
|
99
|
+
result = value1 * value2;
|
|
71
100
|
break;
|
|
101
|
+
|
|
72
102
|
case '/':
|
|
73
|
-
|
|
103
|
+
result = value2 === 0 ? null : value1 / value2;
|
|
74
104
|
break;
|
|
75
105
|
}
|
|
76
106
|
|
|
77
|
-
if (
|
|
78
|
-
|
|
107
|
+
if (result !== value) {
|
|
108
|
+
value = result;
|
|
109
|
+
onChange(result);
|
|
79
110
|
}
|
|
80
|
-
}
|
|
111
|
+
};
|
|
81
112
|
|
|
82
113
|
onMount(() => {
|
|
83
114
|
isMounted = true;
|
|
115
|
+
|
|
116
|
+
// On donne notre calcul au parent
|
|
117
|
+
registerCalculation({
|
|
118
|
+
id,
|
|
119
|
+
calculate,
|
|
120
|
+
dependsOn:[column1, column2]
|
|
121
|
+
});
|
|
84
122
|
});
|
|
85
123
|
</script>
|
|
86
124
|
|