mountain-ui 1.0.28 → 1.0.29

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.28",
4
+ "version": "1.0.29",
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",
@@ -0,0 +1,8 @@
1
+ <script>
2
+ import FieldTypeButton from '../../FieldTypeButton.svelte';
3
+ import Icon from './Icon.svelte';
4
+
5
+ let { ...props } = $props();
6
+ </script>
7
+
8
+ <FieldTypeButton {...props}></FieldTypeButton>
@@ -0,0 +1,6 @@
1
+ <script>
2
+ import FieldCard from '../../FieldTypeCard.svelte';
3
+ let { ...props } = $props();
4
+ </script>
5
+
6
+ <FieldCard {...props}></FieldCard>
@@ -0,0 +1,30 @@
1
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path
3
+ d="M21.6997 6.39014H14.4297C14.0197 6.39014 13.6797 6.05014 13.6797 5.64014C13.6797 5.23014 14.0197 4.89014 14.4297 4.89014H21.6997C22.1097 4.89014 22.4497 5.23014 22.4497 5.64014C22.4497 6.05014 22.1097 6.39014 21.6997 6.39014Z"
4
+ fill="#292D32"
5
+ />
6
+ <path
7
+ d="M9.58078 6.39014H2.30078C1.89078 6.39014 1.55078 6.05014 1.55078 5.64014C1.55078 5.23014 1.89078 4.89014 2.30078 4.89014H9.57078C9.98078 4.89014 10.3208 5.23014 10.3208 5.64014C10.3208 6.05014 9.99078 6.39014 9.58078 6.39014Z"
8
+ fill="#292D32"
9
+ />
10
+ <path
11
+ d="M21.6997 16.0801H14.4297C14.0197 16.0801 13.6797 15.7401 13.6797 15.3301C13.6797 14.9201 14.0197 14.5801 14.4297 14.5801H21.6997C22.1097 14.5801 22.4497 14.9201 22.4497 15.3301C22.4497 15.7401 22.1097 16.0801 21.6997 16.0801Z"
12
+ fill="#292D32"
13
+ />
14
+ <path
15
+ d="M21.6997 22.1401H14.4297C14.0197 22.1401 13.6797 21.8001 13.6797 21.3901C13.6797 20.9801 14.0197 20.6401 14.4297 20.6401H21.6997C22.1097 20.6401 22.4497 20.9801 22.4497 21.3901C22.4497 21.8001 22.1097 22.1401 21.6997 22.1401Z"
16
+ fill="#292D32"
17
+ />
18
+ <path
19
+ d="M18.0898 10.02C17.6798 10.02 17.3398 9.68 17.3398 9.27V2C17.3398 1.59 17.6798 1.25 18.0898 1.25C18.4998 1.25 18.8398 1.59 18.8398 2V9.27C18.8398 9.69 18.5098 10.02 18.0898 10.02Z"
20
+ fill="#292D32"
21
+ />
22
+ <path
23
+ d="M2.30023 22.7499C2.11023 22.7499 1.92023 22.6799 1.77023 22.5299C1.48023 22.2399 1.48023 21.7599 1.77023 21.4699L9.04023 14.1999C9.33023 13.9099 9.81024 13.9099 10.1002 14.1999C10.3902 14.4899 10.3902 14.9699 10.1002 15.2599L2.83023 22.5299C2.69023 22.6799 2.50023 22.7499 2.30023 22.7499Z"
24
+ fill="#292D32"
25
+ />
26
+ <path
27
+ d="M9.58 22.7499C9.39 22.7499 9.2 22.6799 9.05 22.5299L1.78 15.2599C1.49 14.9699 1.49 14.4899 1.78 14.1999C2.07 13.9099 2.55 13.9099 2.84 14.1999L10.11 21.4699C10.4 21.7599 10.4 22.2399 10.11 22.5299C9.96 22.6799 9.77 22.7499 9.58 22.7499Z"
28
+ fill="#292D32"
29
+ />
30
+ </svg>
@@ -0,0 +1,153 @@
1
+ <script>
2
+ import { entityRegistry } from '../../../../entityRegistry/registry.svelte.js';
3
+ import { Tooltip } from 'hamzus-ui';
4
+ import { onMount } from 'svelte';
5
+
6
+ let {
7
+ id = null,
8
+ entity_id = null,
9
+ value = $bindable(null),
10
+ name = '',
11
+ label = '',
12
+ required = false,
13
+ unique = false,
14
+ secret = false,
15
+ compact = false,
16
+ ctx = {},
17
+ detailsCtx = {},
18
+ onChange = () => {},
19
+ onChangeDetails = () => {},
20
+ registerCalculation = () => {},
21
+ operator = '',
22
+ fieldId = '',
23
+ lineFieldId = '',
24
+ ...props
25
+ } = $props();
26
+
27
+ let isMounted = false;
28
+
29
+ const field = entityRegistry.selectField(fieldId); // champ de type ligne
30
+ const lineField = entityRegistry.selectField(lineFieldId); // champ dans la ligne
31
+
32
+ let previousValue1 = Symbol();
33
+ let previousValue2 = Symbol();
34
+
35
+ function getFieldValue(field, ctx) {
36
+ if (!field) return 0;
37
+
38
+ if (!ctx[field.id]) return 0;
39
+
40
+ // retourne les lignes
41
+ return JSON.parse(ctx[field.id]);
42
+ }
43
+
44
+ function calculate(ctx) {
45
+ if (!$field || !$lineField) return;
46
+
47
+ const lines = getFieldValue($field, ctx);
48
+
49
+ let values = lines.map((line) => Number(getFieldValue($lineField, line)) || 0);
50
+
51
+ let total;
52
+
53
+ switch (operator) {
54
+ case '+':
55
+ total = values.reduce((a, b) => a + b, 0);
56
+ break;
57
+
58
+ case '-':
59
+ total = values.reduce((a, b) => a - b);
60
+ break;
61
+
62
+ case '*':
63
+ total = values.reduce((a, b) => a * b, 1);
64
+ break;
65
+
66
+ case '/':
67
+ total = values.reduce((a, b) => (b === 0 ? null : a / b));
68
+ break;
69
+ }
70
+
71
+ if (total !== value) {
72
+ value = total;
73
+ onChange(total);
74
+ }
75
+ }
76
+
77
+ onMount(() => {
78
+ isMounted = true;
79
+
80
+ // On donne notre calcul au parent
81
+ registerCalculation({
82
+ id,
83
+ calculate,
84
+ dependsOn: [fieldId]
85
+ });
86
+ });
87
+ </script>
88
+
89
+ <div class="total-container">
90
+ <input type="hidden" {name} {value} />
91
+ <div class="total">
92
+ <div class="total-content">
93
+ <Tooltip.Root direction="bottom">
94
+ <Tooltip.Trigger slot="trigger">
95
+ <h4>{label}</h4>
96
+ </Tooltip.Trigger>
97
+ <Tooltip.Content slot="content" style="background-color:var(--bg-2)">
98
+ <h6 style="color: var(--font-2);">
99
+ {#if fieldId}
100
+ {$field.name}
101
+ {/if}
102
+ >
103
+ {#if lineFieldId}
104
+ {$lineField.name}
105
+ {/if}
106
+ {operator}
107
+ </h6>
108
+ </Tooltip.Content>
109
+ </Tooltip.Root>
110
+ <h4>{value === null ? '-' : value}</h4>
111
+ </div>
112
+ </div>
113
+ </div>
114
+
115
+ <style>
116
+ .total-container {
117
+ width: 100%;
118
+ display: flex;
119
+ justify-content: end;
120
+ }
121
+
122
+ .total {
123
+ width: min(100%, 350px);
124
+ border-left: 1px solid var(--stroke);
125
+ border-right: 1px solid var(--stroke);
126
+ padding: var(--pad-m);
127
+ row-gap: var(--pad-m);
128
+ }
129
+
130
+ /* Premier d'une suite (ou élément seul) */
131
+ .total-container:not(.total-container + .total-container) .total {
132
+ border-top-left-radius: var(--radius-xxl);
133
+ border-top-right-radius: var(--radius-xxl);
134
+ border-top: 1px solid var(--stroke);
135
+ }
136
+
137
+ /* Dernier d'une suite (ou élément seul) */
138
+ .total-container:not(:has(+ .total-container)) .total {
139
+ border-bottom-left-radius: var(--radius-xxl);
140
+ border-bottom-right-radius: var(--radius-xxl);
141
+ border-bottom: 1px solid var(--stroke);
142
+ }
143
+
144
+ .total-content {
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: space-between;
148
+ width: 100%;
149
+ padding: var(--pad-m) var(--pad-xxl);
150
+ border-radius: var(--radius-l);
151
+ background-color: var(--bg-2);
152
+ }
153
+ </style>
@@ -0,0 +1,37 @@
1
+ import { createFieldType } from '../../../createFieldType.js';
2
+
3
+ import Icon from './Icon.svelte';
4
+ import Button from './Button.svelte';
5
+ import Card from './Card.svelte';
6
+ import Input from './Input.svelte';
7
+
8
+ export default createFieldType({
9
+ type: 'calculation-line',
10
+
11
+ category_path: 'calculation',
12
+
13
+ label: 'Calcul de ligne',
14
+ description: 'Calcul automatique sur les lignes.',
15
+
16
+ is_hidden: false,
17
+
18
+ defaultProps: {},
19
+
20
+ can_be_required: false,
21
+ can_be_unique: false,
22
+
23
+ components: {
24
+ icon: Icon,
25
+ button: Button,
26
+ card: Card,
27
+ input: Input,
28
+ cell: null,
29
+ filter: null,
30
+ properties: null
31
+ },
32
+
33
+ formatter: (value) => value,
34
+ parser: (value) => value,
35
+
36
+ validate: () => true
37
+ });
@@ -6,6 +6,7 @@ import NumberFloatDefault from './fieldTypes/number/float/NumberFloatDefault';
6
6
  import NumberFloatPrice from './fieldTypes/number/float/NumberFloatPrice';
7
7
  import NumberFloatPercent from './fieldTypes/number/float/NumberFloatPercent';
8
8
  import CalculationColumn from './fieldTypes/calculation/CalculationColumn';
9
+ import CalculationLine from './fieldTypes/calculation/CalculationLine';
9
10
  import TextTextarea from './fieldTypes/text/TextTextarea';
10
11
  import TextVarcharDefault from './fieldTypes/text/varchar/TextVarcharDefault';
11
12
  import TextVarcharEmail from './fieldTypes/text/varchar/TextVarcharEmail';
@@ -35,6 +36,7 @@ export function registerDefaultFieldTypes() {
35
36
  fieldTypeRegistry.register(NumberFloatPercent);
36
37
  // calculation
37
38
  fieldTypeRegistry.register(CalculationColumn);
39
+ fieldTypeRegistry.register(CalculationLine);
38
40
  // text
39
41
  fieldTypeRegistry.register(TextTextarea);
40
42
 
@@ -605,6 +605,24 @@
605
605
  }
606
606
  ]
607
607
  }
608
+ },
609
+ {
610
+ id: 456,
611
+ link_to_field_id: null,
612
+ entity_id: 2,
613
+ type: 'calculation-line',
614
+ width: 160,
615
+ name: 'total de ligne',
616
+ normalized_name: 'total de ligne',
617
+ is_locked: false,
618
+ is_required: false,
619
+ is_secret: false,
620
+ is_unique: false,
621
+ props: {
622
+ fieldId: 305,
623
+ operator: '-',
624
+ lineFieldId: 207
625
+ }
608
626
  }
609
627
  ]
610
628
  })