mountain-ui 1.0.23 → 1.0.25

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.23",
4
+ "version": "1.0.25",
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
- function handleSubmit() {
14
- onSubmit({...ctx})
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
- <div class="form">
20
- <FormCtx bind:ctx bind:detailsCtx>
21
- {#each $entity.fields as field}
22
- <FieldInput
23
- {detailsCtx}
24
- {ctx}
25
- onChangeDetails={(value) => {
26
- detailsCtx[field.id] = value;
27
- detailsCtx = { ...detailsCtx };
28
- }}
29
- onChange={(value) => {
30
- ctx[field.id] = value;
31
- ctx = { ...ctx };
32
- }}
33
- id={field.id}
34
- entityId={$entity.id}
35
- value={ctx?.[field.id] ?? null}
36
- ></FieldInput>
37
- {/each}
38
- <div class="button">
39
- <Button onClick={handleSubmit}>
40
- <h4>{type === 'create' ? 'créer' : 'éditer'}</h4>
41
- </Button>
42
- </div>
43
- </FormCtx>
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
- onMount(()=>{
26
- if (value === null) return
24
+ onMount(() => {
25
+ if (value === null) return;
27
26
 
28
- const decodedValue = JSON.parse(value)
27
+ const decodedValue = JSON.parse(value);
29
28
 
30
- let newLines = []
29
+ let newLines = [];
31
30
 
32
- for (const line of decodedValue) {
33
- const lineId = line.id
34
- delete line.id
35
- const newLine = createLine(lineId, line)
36
- newLines.push(newLine)
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
- table = [...newLines]
40
- })
38
+ table = [...newLines];
39
+ });
41
40
 
42
41
  function createLine(dbId = null, line = null) {
43
42
  return {
44
43
  id: crypto.randomUUID(),
45
- dbId:dbId,
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,77 @@
57
55
 
58
56
  function handleDeleteLine(lineIndex) {
59
57
  table = table.filter((_, i) => i !== lineIndex);
60
- handleChangeDetailsCtx();
58
+ onChangeDetails(table)
61
59
  handleChange();
62
60
  }
63
- function handleChangeDetailsCtx() {
64
- onChangeDetails(table);
61
+
62
+ let calculations = $state({});
63
+
64
+ function handleRegisterCalculation(lineIndex, config) {
65
+ if (!calculations[lineIndex]) {
66
+ calculations[lineIndex] = {};
65
67
  }
66
- function handleChange() {
67
- const value = JSON.stringify(table.map((line) => {
68
- const data = {
69
- ...line.ctx,
70
- }
71
68
 
72
- if (line.dbId != null) {
73
- data.id = line.dbId
74
- }
69
+ calculations[lineIndex][config.id] = config;
70
+
71
+ calculations = {...calculations};
72
+ }
75
73
 
76
- return data
77
- } ));
78
-
74
+ function handleChange(lineIndex, fieldId, value) {
75
+ table[lineIndex].ctx[fieldId] = value;
79
76
 
80
- onChange(value);
77
+ recalculate(lineIndex, fieldId);
78
+
79
+ table = [...table];
80
+
81
+ const newValue = JSON.stringify(
82
+ table.map((line) => {
83
+ const data = {
84
+ ...line.ctx
85
+ };
86
+
87
+ if (line.dbId != null) {
88
+ data.id = line.dbId;
89
+ }
90
+
91
+ return data;
92
+ })
93
+ );
94
+
95
+ onChange(newValue);
96
+ }
97
+
98
+ function handleChangeDetails(lineIndex, fieldId, value) {
99
+ table[lineIndex].detailsCtx[fieldId] = value;
100
+
101
+ // si c est un type lien alors on parcour ses champs enfant et on reagis
102
+ const field = entityRegistry.getField(fieldId, entity.id);
103
+ if (field.type === 'link') {
104
+ const entity = entityRegistry.get(field.props.linkId);
105
+ for (const linkedFields of entity.fields) {
106
+ recalculate(lineIndex, linkedFields.id);
107
+ }
108
+ }
109
+
110
+ table = [...table];
111
+
112
+
113
+ onChangeDetails(table);
114
+ }
115
+
116
+ function recalculate(lineIndex, changedFieldId) {
117
+ // on parcour les calcules et on verifie si un depend du champs changé
118
+ for (const calc of Object.values(calculations)) {
119
+ console.log(changedFieldId);
120
+ if (!calc.dependsOn.includes(changedFieldId)) continue;
121
+
122
+ calc.calculate(table[lineIndex].ctx);
123
+ }
81
124
  }
82
125
  </script>
83
126
 
84
127
  <div class="title">
85
- <Label {label} {required} {secret} {unique}></Label>
128
+ <Label {label} {required} {secret} {unique}></Label>
86
129
  </div>
87
130
  <ResponsiveTable.Root let:ctx>
88
131
  <ResponsiveTable.Header>
@@ -107,17 +150,16 @@
107
150
  detailsCtx={table[lineIndex].detailsCtx}
108
151
  ctx={table[lineIndex].ctx}
109
152
  onChangeDetails={(value) => {
110
- table[lineIndex].detailsCtx[row.fieldId] = value;
111
- table = [...table];
112
- handleChangeDetailsCtx();
153
+ handleChangeDetails(lineIndex, row.fieldId, value);
113
154
  }}
114
155
  onChange={(value) => {
115
- table[lineIndex].ctx[row.fieldId] = value;
116
- table = [...table];
117
- handleChange();
156
+ handleChange(lineIndex, row.fieldId, value);
118
157
  }}
119
158
  id={row.fieldId}
120
159
  value={table[lineIndex].ctx?.[row.fieldId] ?? null}
160
+ registerCalculation={(config)=>{
161
+ handleRegisterCalculation(lineIndex, config);
162
+ }}
121
163
  ></FieldInput>
122
164
  {/each}
123
165
  {#if columnIndex + 1 === columns.length}
@@ -167,17 +209,17 @@
167
209
  </ResponsiveTable.Body>
168
210
  </ResponsiveTable.Root>
169
211
  <div class="title">
170
- <Button onClick={handleAddLine}>
171
- <h5>ajouter une rangée</h5>
172
- </Button>
212
+ <Button onClick={handleAddLine}>
213
+ <h5>ajouter une rangée</h5>
214
+ </Button>
173
215
  </div>
174
216
 
175
217
  <style>
176
- .title {
177
- display: flex;
178
- align-items: center;
179
- width: 100%;
180
- }
218
+ .title {
219
+ display: flex;
220
+ align-items: center;
221
+ width: 100%;
222
+ }
181
223
  :global(.table-container .line):has(.delete :global(.button):hover) {
182
224
  background-color: var(--red-b);
183
225
  }
@@ -18,6 +18,7 @@
18
18
  detailsCtx = {},
19
19
  onChange = () => {},
20
20
  onChangeDetails = () => {},
21
+ registerCalculation = () => {},
21
22
  operator = '',
22
23
  column1 = '',
23
24
  column2 = '',
@@ -32,7 +33,7 @@
32
33
  let previousValue1 = Symbol();
33
34
  let previousValue2 = Symbol();
34
35
 
35
- function getFieldValue(field) {
36
+ function getFieldValue(field, ctx) {
36
37
  if (!field) return null;
37
38
 
38
39
  // Champ local
@@ -68,18 +69,15 @@
68
69
  return isNaN(v) ? 0 : v;
69
70
  }
70
71
 
71
- $effect(() => {
72
+ function calculate(ctx) {
72
73
  if (!$field1 || !$field2) return;
73
74
 
74
- const value1 = getFieldValue($field1);
75
- const value2 = getFieldValue($field2);
75
+ const value1 = getFieldValue($field1, ctx);
76
+ const value2 = getFieldValue($field2, ctx);
76
77
 
77
78
  if (value1 === null || value2 === null) return;
78
79
 
79
- if (
80
- value1 === previousValue1 &&
81
- value2 === previousValue2
82
- ) {
80
+ if (value1 === previousValue1 && value2 === previousValue2) {
83
81
  return;
84
82
  }
85
83
 
@@ -110,10 +108,17 @@
110
108
  value = result;
111
109
  onChange(result);
112
110
  }
113
- });
111
+ };
114
112
 
115
113
  onMount(() => {
116
114
  isMounted = true;
115
+
116
+ // On donne notre calcul au parent
117
+ registerCalculation({
118
+ id,
119
+ calculate,
120
+ dependsOn:[column1, column2]
121
+ });
117
122
  });
118
123
  </script>
119
124