mountain-ui 1.0.110 → 1.0.111

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 (43) hide show
  1. package/index.d.ts +29 -0
  2. package/index.js +29 -0
  3. package/package.json +1 -1
  4. package/src/lib/registry/navigationRegistry/components/NavigationGroupRow.svelte +30 -32
  5. package/src/lib/registry/navigationRegistry/components/NewNavbarGroupDialog.svelte +43 -39
  6. package/src/lib/registry/projectRegistry/createProject.js +2 -0
  7. package/src/lib/registry/widgetGroupRegistry/components/EmptySlot.svelte +47 -0
  8. package/src/lib/registry/widgetGroupRegistry/components/GroupPreview.svelte +142 -0
  9. package/src/lib/registry/widgetGroupRegistry/components/NewWidgetGroup.svelte +122 -0
  10. package/src/lib/registry/widgetGroupRegistry/components/WidgetGroup.svelte +39 -0
  11. package/src/lib/registry/widgetGroupRegistry/createWidget.js +17 -0
  12. package/src/lib/registry/widgetGroupRegistry/createWidgetGroup.js +19 -0
  13. package/src/lib/registry/widgetGroupRegistry/registerWidgetGroups.js +37 -0
  14. package/src/lib/registry/widgetGroupRegistry/registry.svelte.js +47 -0
  15. package/src/lib/registry/widgetTypeRegistry/components/CreateWidgetDialog.svelte +25 -0
  16. package/src/lib/registry/widgetTypeRegistry/components/Widget.svelte +18 -0
  17. package/src/lib/registry/widgetTypeRegistry/components/WidgetConfig.svelte +16 -0
  18. package/src/lib/registry/widgetTypeRegistry/components/WidgetPreview.svelte +59 -0
  19. package/src/lib/registry/widgetTypeRegistry/components/WidgetTypeButton.svelte +20 -0
  20. package/src/lib/registry/widgetTypeRegistry/components/WidgetTypeSelector.svelte +32 -0
  21. package/src/lib/registry/widgetTypeRegistry/createWidgetType.js +20 -0
  22. package/src/lib/registry/widgetTypeRegistry/registerWidgetTypes.js +14 -0
  23. package/src/lib/registry/widgetTypeRegistry/registry.svelte.js +43 -0
  24. package/src/lib/registry/widgetTypeRegistry/widgetTypes/Bar/Bar.svelte +79 -0
  25. package/src/lib/registry/widgetTypeRegistry/widgetTypes/Bar/ConfigBar.svelte +176 -0
  26. package/src/lib/registry/widgetTypeRegistry/widgetTypes/Bar/index.js +13 -0
  27. package/src/lib/registry/widgetTypeRegistry/widgetTypes/Bar/text.js +21 -0
  28. package/src/lib/registry/widgetTypeRegistry/widgetTypes/Evolution/ConfigEvolution.svelte +180 -0
  29. package/src/lib/registry/widgetTypeRegistry/widgetTypes/Evolution/Evolution.svelte +81 -0
  30. package/src/lib/registry/widgetTypeRegistry/widgetTypes/Evolution/index.js +13 -0
  31. package/src/lib/registry/widgetTypeRegistry/widgetTypes/Evolution/text.js +21 -0
  32. package/src/lib/registry/widgetTypeRegistry/widgetTypes/KPI/ConfigKPI.svelte +201 -0
  33. package/src/lib/registry/widgetTypeRegistry/widgetTypes/KPI/KPI.svelte +118 -0
  34. package/src/lib/registry/widgetTypeRegistry/widgetTypes/KPI/index.js +12 -0
  35. package/src/lib/registry/widgetTypeRegistry/widgetTypes/KPI/text.js +22 -0
  36. package/src/lib/registry/widgetTypeRegistry/widgetTypes/List/ConfigList.svelte +199 -0
  37. package/src/lib/registry/widgetTypeRegistry/widgetTypes/List/List.svelte +97 -0
  38. package/src/lib/registry/widgetTypeRegistry/widgetTypes/List/index.js +12 -0
  39. package/src/lib/registry/widgetTypeRegistry/widgetTypes/List/text.js +21 -0
  40. package/src/routes/exemple/[project_normalized_name]/+layout.svelte +1 -1
  41. package/src/routes/exemple/[project_normalized_name]/home/+page.svelte +61 -1
  42. package/src/routes/exemple/[project_normalized_name]/navigation/+page.svelte +28 -0
  43. package/src/routes/exemple/[project_normalized_name]/widgets/+page.svelte +92 -0
package/index.d.ts CHANGED
@@ -131,3 +131,32 @@ export { default as EntryActionCard } from './src/lib/registry/entryActionRegist
131
131
  export { default as EntryActionForm } from './src/lib/registry/entryActionRegistry/components/EntryActionForm.svelte';
132
132
  export { default as EntryActionButton } from './src/lib/registry/entryActionRegistry/components/EntryActionButton.svelte';
133
133
  export { default as EntryActionsButtons } from './src/lib/registry/entryActionRegistry/components/EntryActionsButtons.svelte';
134
+
135
+ // ============================================
136
+ // WidgetGroup Registry
137
+ // ============================================
138
+
139
+ export { widgetGroupRegistry } from './src/lib/registry/widgetGroupRegistry/registry.svelte.js';
140
+ export { createWidget } from './src/lib/registry/widgetGroupRegistry/createWidget.js';
141
+ export { createWidgetGroup } from './src/lib/registry/widgetGroupRegistry/createWidgetGroup.js';
142
+ export { registerWidgetGroups } from './src/lib/registry/widgetGroupRegistry/registerWidgetGroups.js';
143
+
144
+ export { default as EmptySlot } from './src/lib/registry/widgetGroupRegistry/components/EmptySlot.svelte';
145
+ export { default as GroupPreview } from './src/lib/registry/widgetGroupRegistry/components/GroupPreview.svelte';
146
+ export { default as NewWidgetGroup } from './src/lib/registry/widgetGroupRegistry/components/NewWidgetGroup.svelte';
147
+ export { default as WidgetGroup } from './src/lib/registry/widgetGroupRegistry/components/WidgetGroup.svelte';
148
+
149
+ // ============================================
150
+ // WidgetType Registry
151
+ // ============================================
152
+
153
+ export { widgetTypeRegistry } from './src/lib/registry/widgetTypeRegistry/registry.svelte.js';
154
+ export { createWidgetType } from './src/lib/registry/widgetTypeRegistry/createWidgetType.js';
155
+ export { registerWidgetTypes } from './src/lib/registry/widgetTypeRegistry/registerWidgetTypes.js';
156
+
157
+ export { default as CreateWidgetDialog } from './src/lib/registry/widgetTypeRegistry/components/CreateWidgetDialog.svelte';
158
+ export { default as Widget } from './src/lib/registry/widgetTypeRegistry/components/Widget.svelte';
159
+ export { default as WidgetConfig } from './src/lib/registry/widgetTypeRegistry/components/WidgetConfig.svelte';
160
+ export { default as WidgetPreview } from './src/lib/registry/widgetTypeRegistry/components/WidgetPreview.svelte';
161
+ export { default as WidgetTypeButton } from './src/lib/registry/widgetTypeRegistry/components/WidgetTypeButton.svelte';
162
+ export { default as WidgetTypeSelector } from './src/lib/registry/widgetTypeRegistry/components/WidgetTypeSelector.svelte';
package/index.js CHANGED
@@ -135,3 +135,32 @@ export { default as EntryActionCard } from './src/lib/registry/entryActionRegist
135
135
  export { default as EntryActionForm } from './src/lib/registry/entryActionRegistry/components/EntryActionForm.svelte';
136
136
  export { default as EntryActionButton } from './src/lib/registry/entryActionRegistry/components/EntryActionButton.svelte';
137
137
  export { default as EntryActionsButtons } from './src/lib/registry/entryActionRegistry/components/EntryActionsButtons.svelte';
138
+
139
+ // ============================================
140
+ // WidgetGroup Registry
141
+ // ============================================
142
+
143
+ export { widgetGroupRegistry } from './src/lib/registry/widgetGroupRegistry/registry.svelte.js';
144
+ export { createWidget } from './src/lib/registry/widgetGroupRegistry/createWidget.js';
145
+ export { createWidgetGroup } from './src/lib/registry/widgetGroupRegistry/createWidgetGroup.js';
146
+ export { registerWidgetGroups } from './src/lib/registry/widgetGroupRegistry/registerWidgetGroups.js';
147
+
148
+ export { default as EmptySlot } from './src/lib/registry/widgetGroupRegistry/components/EmptySlot.svelte';
149
+ export { default as GroupPreview } from './src/lib/registry/widgetGroupRegistry/components/GroupPreview.svelte';
150
+ export { default as NewWidgetGroup } from './src/lib/registry/widgetGroupRegistry/components/NewWidgetGroup.svelte';
151
+ export { default as WidgetGroup } from './src/lib/registry/widgetGroupRegistry/components/WidgetGroup.svelte';
152
+
153
+ // ============================================
154
+ // WidgetType Registry
155
+ // ============================================
156
+
157
+ export { widgetTypeRegistry } from './src/lib/registry/widgetTypeRegistry/registry.svelte.js';
158
+ export { createWidgetType } from './src/lib/registry/widgetTypeRegistry/createWidgetType.js';
159
+ export { registerWidgetTypes } from './src/lib/registry/widgetTypeRegistry/registerWidgetTypes.js';
160
+
161
+ export { default as CreateWidgetDialog } from './src/lib/registry/widgetTypeRegistry/components/CreateWidgetDialog.svelte';
162
+ export { default as Widget } from './src/lib/registry/widgetTypeRegistry/components/Widget.svelte';
163
+ export { default as WidgetConfig } from './src/lib/registry/widgetTypeRegistry/components/WidgetConfig.svelte';
164
+ export { default as WidgetPreview } from './src/lib/registry/widgetTypeRegistry/components/WidgetPreview.svelte';
165
+ export { default as WidgetTypeButton } from './src/lib/registry/widgetTypeRegistry/components/WidgetTypeButton.svelte';
166
+ export { default as WidgetTypeSelector } from './src/lib/registry/widgetTypeRegistry/components/WidgetTypeSelector.svelte';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mountain-ui",
3
3
  "private": false,
4
- "version": "1.0.110",
4
+ "version": "1.0.111",
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",
@@ -3,13 +3,14 @@
3
3
  import { navigationRegistry } from '../registry.svelte';
4
4
  import { onMount } from 'svelte';
5
5
  import NavbarIcon from './NavbarIcon.svelte';
6
+ import NewNavbarGroupDialog from './NewNavbarGroupDialog.svelte';
6
7
 
7
- let { id, onOpen = (val)=>{}, isOpen = false, activeDrag = null, onRename, onDelete = null, onDrop } = $props();
8
+ let { id, onOpen = (val)=>{}, isOpen = false, activeDrag = null, onEdit, onDelete = null, onDrop } = $props();
8
9
 
9
10
  const navigationGroup = $derived(navigationRegistry.select(id));
10
11
  const navigationChildren = $derived(navigationRegistry.getAllFromGroup(id));
11
12
 
12
- let renameIsOpen = $state(false);
13
+ let editIsOpen = $state(false);
13
14
  let newName = $state('');
14
15
  let isRenaming = $state(false);
15
16
 
@@ -19,14 +20,14 @@
19
20
  let isHovered = $state(false);
20
21
 
21
22
  async function handleRename() {
22
- if (!onRename) return;
23
+ if (!onEdit) return;
23
24
 
24
25
  isRenaming = true;
25
- await onRename(id, newName);
26
+ await onEdit(id);
26
27
  isRenaming = false;
27
28
 
28
29
  newName = '';
29
- renameIsOpen = false;
30
+ editIsOpen = false;
30
31
  }
31
32
  async function handleDelete() {
32
33
  if (!onDelete) return;
@@ -37,6 +38,10 @@
37
38
 
38
39
  deleteIsOpen = false;
39
40
  }
41
+ async function handleEdit(icon, color, name) {
42
+ if (!onEdit) return;
43
+ await onEdit(id, icon, color, name);
44
+ }
40
45
 
41
46
  function handleDragEnter(event) {
42
47
  event.preventDefault();
@@ -77,7 +82,7 @@
77
82
  </Button>
78
83
  </div>
79
84
  </Dialog>
80
- <Dialog bind:isOpen={deleteIsOpen}>
85
+ <Dialog bind:isOpen={editIsOpen}>
81
86
  <div style="display:flex;row-gap:var(--pad-m);flex-direction:column;">
82
87
  <h3>Renommer ce groupe ?</h3>
83
88
  <Input bind:value={newName} label="nouveau nom" placeholder="mon groupe"></Input>
@@ -87,7 +92,8 @@
87
92
  </div>
88
93
  </Dialog>
89
94
  {#if $navigationGroup}
90
- <div
95
+ <NewNavbarGroupDialog reset={false} onCreate={handleEdit} bind:isOpen={editIsOpen} icon={$navigationGroup.icon} name={$navigationGroup.name} color={$navigationGroup.color}></NewNavbarGroupDialog>
96
+ <div
91
97
  class="group"
92
98
  class:is-hovered={isHovered}
93
99
  ondragenter={handleDragEnter}
@@ -102,37 +108,20 @@
102
108
  <h4>{$navigationGroup.name}</h4>
103
109
  </div>
104
110
  <div class="right">
105
- {#if onRename}
111
+ {#if onEdit}
106
112
  <IconButton
107
113
  onClick={() => {
108
- renameIsOpen = true;
114
+ editIsOpen = true;
109
115
  }}
110
116
  size="26px"
111
117
  variant="ghost"
112
- ><svg
113
- width="24"
114
- height="24"
115
- viewBox="0 0 24 24"
116
- fill="none"
117
- xmlns="http://www.w3.org/2000/svg"
118
118
  >
119
- <path
120
- d="M11.02 20.25H7.5C6.75 20.25 6.2 20.22 5.73 20.15C2.4 19.78 1.75 17.8 1.75 14.5V9.5C1.75 6.2 2.41 4.21 5.76 3.84C6.2 3.78 6.75 3.75 7.5 3.75H10.96C11.37 3.75 11.71 4.09 11.71 4.5C11.71 4.91 11.37 5.25 10.96 5.25H7.5C6.82 5.25 6.34 5.28 5.95 5.33C3.92 5.55 3.25 6.19 3.25 9.5V14.5C3.25 17.81 3.92 18.44 5.92 18.67C6.34 18.73 6.82 18.75 7.5 18.75H11.02C11.43 18.75 11.77 19.09 11.77 19.5C11.77 19.91 11.43 20.25 11.02 20.25Z"
121
- fill="#292D32"
122
- />
123
- <path
124
- d="M16.4995 20.25H15.0195C14.6095 20.25 14.2695 19.91 14.2695 19.5C14.2695 19.09 14.6095 18.75 15.0195 18.75H16.4995C17.1795 18.75 17.6595 18.72 18.0495 18.67C20.0795 18.45 20.7495 17.81 20.7495 14.5V9.5C20.7495 6.19 20.0795 5.56 18.0795 5.33C17.6595 5.27 17.1795 5.25 16.4995 5.25H15.0195C14.6095 5.25 14.2695 4.91 14.2695 4.5C14.2695 4.09 14.6095 3.75 15.0195 3.75H16.4995C17.2495 3.75 17.7995 3.78 18.2695 3.85C21.5995 4.22 22.2495 6.2 22.2495 9.5V14.5C22.2495 17.8 21.5895 19.79 18.2395 20.16C17.7995 20.22 17.2495 20.25 16.4995 20.25Z"
125
- fill="#292D32"
126
- />
127
- <path
128
- d="M15 22.75C14.59 22.75 14.25 22.41 14.25 22V2C14.25 1.59 14.59 1.25 15 1.25C15.41 1.25 15.75 1.59 15.75 2V22C15.75 22.41 15.41 22.75 15 22.75Z"
129
- fill="#292D32"
130
- />
131
- <path
132
- d="M8 16.25C7.59 16.25 7.25 15.91 7.25 15.5V8.5C7.25 8.09 7.59 7.75 8 7.75C8.41 7.75 8.75 8.09 8.75 8.5V15.5C8.75 15.91 8.41 16.25 8 16.25Z"
133
- fill="#292D32"
134
- />
135
- </svg>
119
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
120
+ <path d="M15 22.75H9C3.57 22.75 1.25 20.43 1.25 15V9C1.25 3.57 3.57 1.25 9 1.25H11C11.41 1.25 11.75 1.59 11.75 2C11.75 2.41 11.41 2.75 11 2.75H9C4.39 2.75 2.75 4.39 2.75 9V15C2.75 19.61 4.39 21.25 9 21.25H15C19.61 21.25 21.25 19.61 21.25 15V13C21.25 12.59 21.59 12.25 22 12.25C22.41 12.25 22.75 12.59 22.75 13V15C22.75 20.43 20.43 22.75 15 22.75Z" fill="#292D32"/>
121
+ <path d="M8.49935 17.6901C7.88935 17.6901 7.32935 17.4701 6.91935 17.0701C6.42935 16.5801 6.21935 15.8701 6.32935 15.1201L6.75935 12.1101C6.83935 11.5301 7.21935 10.7801 7.62935 10.3701L15.5093 2.49006C17.4993 0.500059 19.5193 0.500059 21.5093 2.49006C22.5993 3.58006 23.0893 4.69006 22.9893 5.80006C22.8993 6.70006 22.4193 7.58006 21.5093 8.48006L13.6293 16.3601C13.2193 16.7701 12.4693 17.1501 11.8893 17.2301L8.87935 17.6601C8.74935 17.6901 8.61935 17.6901 8.49935 17.6901ZM16.5693 3.55006L8.68935 11.4301C8.49935 11.6201 8.27935 12.0601 8.23935 12.3201L7.80935 15.3301C7.76935 15.6201 7.82935 15.8601 7.97935 16.0101C8.12935 16.1601 8.36935 16.2201 8.65935 16.1801L11.6693 15.7501C11.9293 15.7101 12.3793 15.4901 12.5593 15.3001L20.4393 7.42006C21.0893 6.77006 21.4293 6.19006 21.4793 5.65006C21.5393 5.00006 21.1993 4.31006 20.4393 3.54006C18.8393 1.94006 17.7393 2.39006 16.5693 3.55006Z" fill="#292D32"/>
122
+ <path d="M19.8496 9.82978C19.7796 9.82978 19.7096 9.81978 19.6496 9.79978C17.0196 9.05978 14.9296 6.96978 14.1896 4.33978C14.0796 3.93978 14.3096 3.52978 14.7096 3.40978C15.1096 3.29978 15.5196 3.52978 15.6296 3.92978C16.2296 6.05978 17.9196 7.74978 20.0496 8.34978C20.4496 8.45978 20.6796 8.87978 20.5696 9.27978C20.4796 9.61978 20.1796 9.82978 19.8496 9.82978Z" fill="#292D32"/>
123
+ </svg>
124
+
136
125
  </IconButton>
137
126
  {/if}
138
127
  {#if onDelete}
@@ -172,6 +161,7 @@
172
161
  </svg>
173
162
  </IconButton>
174
163
  {/if}
164
+ <span class="separator"></span>
175
165
  <IconButton
176
166
  onClick={() => {
177
167
  isOpen = !isOpen;
@@ -247,4 +237,12 @@
247
237
  .is-hovered :global( svg path) {
248
238
  fill: var(--accent);
249
239
  }
240
+
241
+ .separator {
242
+ display: flex;
243
+ width: 1px;
244
+ height: 20px;
245
+ background-color: var(--bg-2);
246
+ flex-shrink: 0;
247
+ }
250
248
  </style>
@@ -4,22 +4,17 @@
4
4
  import IconSelector from '../../../components/Icons/IconSelector.svelte';
5
5
  import { Button, Dialog, IconButton, Input } from 'hamzus-ui';
6
6
 
7
- let { isOpen = $bindable(false), onCreate = async (icon, color, name) => {} } = $props();
7
+ let {
8
+ name = $bindable(''),
9
+ color = $bindable('var(--font-2)'),
10
+ icon = $bindable('Files|folder'),
11
+ isOpen = $bindable(false),
12
+ onCreate = async (icon, color, name) => {},
13
+ reset = true
14
+ } = $props();
8
15
 
9
16
  let isCreating = $state(false);
10
17
 
11
- let name = $state('');
12
- let color = $state('var(--font-2)');
13
- let icon = $state('Files|folder');
14
-
15
- $effect(() => {
16
- if (isOpen) return;
17
-
18
- name = '';
19
- color = 'var(--font-2)';
20
- icon = 'Files|folder';
21
- });
22
-
23
18
  function handleChangeIcon(newIcon) {
24
19
  icon = newIcon;
25
20
  }
@@ -27,6 +22,15 @@
27
22
  async function handleCreate() {
28
23
  isCreating = true;
29
24
  await onCreate(icon, color, name);
25
+
26
+ if (reset) {
27
+ // reset des valeurs
28
+ name = '';
29
+ color = 'var(--font-2)';
30
+ icon = 'Files|folder';
31
+ }
32
+
33
+ // fermeture du dialog
30
34
  isCreating = false;
31
35
  isOpen = false;
32
36
  }
@@ -36,23 +40,23 @@
36
40
  <div style="display:flex;row-gap:var(--pad-m);flex-direction:column;">
37
41
  <h3>Nouveau groupe</h3>
38
42
  <div class="icon-data">
39
- <h5>Icon</h5>
43
+ <h5>Icon</h5>
40
44
  <div class="right">
41
- <ColorSelector
42
- value={color}
43
- onChange={(value) => {
44
- color = value;
45
- }}
46
- ></ColorSelector>
47
- <IconSelector onClick={handleChangeIcon}>
48
- <div class="icon" style="--icon-color:{color};">
49
- <Icon value={icon}></Icon>
50
- </div>
51
- </IconSelector>
52
- </div>
45
+ <ColorSelector
46
+ value={color}
47
+ onChange={(value) => {
48
+ color = value;
49
+ }}
50
+ ></ColorSelector>
51
+ <IconSelector onClick={handleChangeIcon}>
52
+ <div class="icon" style="--icon-color:{color};">
53
+ <Icon value={icon}></Icon>
54
+ </div>
55
+ </IconSelector>
56
+ </div>
53
57
  </div>
54
58
  <Input bind:value={name} placeholder="nom du groupe" />
55
- <Button loading={isCreating} onClick={handleCreate}>créer</Button>
59
+ <Button loading={isCreating} onClick={handleCreate}>enregistrer</Button>
56
60
  </div>
57
61
  </Dialog>
58
62
 
@@ -60,18 +64,18 @@
60
64
  .icon-data {
61
65
  display: flex;
62
66
  align-items: center;
63
- column-gap: var(--pad-m);
64
- justify-content: space-between;
65
- width: 100%;
66
- padding: var(--pad-s) 0;
67
- border-bottom: 1px solid var(--bg-2);
67
+ column-gap: var(--pad-m);
68
+ justify-content: space-between;
69
+ width: 100%;
70
+ padding: var(--pad-s) 0;
71
+ border-bottom: 1px solid var(--bg-2);
68
72
  }
69
73
 
70
- .right {
74
+ .right {
71
75
  display: flex;
72
76
  align-items: center;
73
- column-gap: var(--pad-m);
74
- }
77
+ column-gap: var(--pad-m);
78
+ }
75
79
  .icon {
76
80
  width: fit-content;
77
81
  display: flex;
@@ -81,13 +85,13 @@
81
85
  min-height: 35px;
82
86
  background-color: var(--bg-blur);
83
87
  border-radius: var(--radius-m);
84
- cursor: pointer;
88
+ cursor: pointer;
85
89
  }
86
90
  .icon :global(svg path) {
87
91
  fill: var(--icon-color);
88
92
  }
89
93
 
90
- .icon:hover {
91
- background-color: var(--bg-2);
92
- }
94
+ .icon:hover {
95
+ background-color: var(--bg-2);
96
+ }
93
97
  </style>
@@ -5,6 +5,7 @@ import { registerDefaultViewEntriesTypes } from "../viewEntriesTypeRegistry/regi
5
5
  import { projectRegistry } from "./registry.svelte";
6
6
  import { navigationRegistry } from "../navigationRegistry/registry.svelte";
7
7
  import { registerNavigation } from "../navigationRegistry/registerNavigation";
8
+ import { registerWidgetTypes } from "../widgetTypeRegistry/registerWidgetTypes";
8
9
 
9
10
  export function createProject(config = {}) {
10
11
  const project = {
@@ -97,6 +98,7 @@ export function createProject(config = {}) {
97
98
  // charger les fieldType
98
99
  registerDefaultFieldTypes();
99
100
  registerDefaultViewEntriesTypes();
101
+ registerWidgetTypes()
100
102
  // charger les constant
101
103
 
102
104
  // charger les entité
@@ -0,0 +1,47 @@
1
+ <script>
2
+ let { onClick = () => {} } = $props();
3
+ </script>
4
+
5
+ <div onclick={onClick} class="empty-slot">
6
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
7
+ <path
8
+ d="M18 12.75H6C5.59 12.75 5.25 12.41 5.25 12C5.25 11.59 5.59 11.25 6 11.25H18C18.41 11.25 18.75 11.59 18.75 12C18.75 12.41 18.41 12.75 18 12.75Z"
9
+ fill="#292D32"
10
+ />
11
+ <path
12
+ d="M12 18.75C11.59 18.75 11.25 18.41 11.25 18V6C11.25 5.59 11.59 5.25 12 5.25C12.41 5.25 12.75 5.59 12.75 6V18C12.75 18.41 12.41 18.75 12 18.75Z"
13
+ fill="#292D32"
14
+ />
15
+ </svg>
16
+ </div>
17
+
18
+ <style>
19
+ .empty-slot {
20
+ width: 100%;
21
+ height: 1fr;
22
+ flex: 1;
23
+ background-color: var(--bg-blur);
24
+ border-radius: var(--radius-l);
25
+ cursor: pointer;
26
+ display: flex;
27
+ align-items: center;
28
+ justify-content: center;
29
+ transition: background-color .2s ease-out;
30
+ }
31
+ .empty-slot:hover {
32
+ background-color: var(--bg-2);
33
+ }
34
+
35
+ .empty-slot svg {
36
+ width: 35px;
37
+ height: auto;
38
+ }
39
+
40
+ .empty-slot svg path {
41
+ fill: var(--font-2);
42
+ transition: fill .2s ease-out;
43
+ }
44
+ .empty-slot:hover svg path {
45
+ fill: var(--font-1);
46
+ }
47
+ </style>
@@ -0,0 +1,142 @@
1
+ <script>
2
+ import { handlers } from 'svelte/legacy';
3
+ import EmptySlot from './EmptySlot.svelte';
4
+ import CreateWidgetDialog from '$lib/registry/widgetTypeRegistry/components/CreateWidgetDialog.svelte';
5
+ import { IconButton, sendRequest, toast } from 'hamzus-ui';
6
+ import { registerWidgetGroups } from '../registerWidgetGroups';
7
+ import { widgetGroupRegistry } from '../registry.svelte';
8
+ import WidgetPreview from '$lib/registry/widgetTypeRegistry/components/WidgetPreview.svelte';
9
+
10
+ let { id = null, numberOfColumn = 1, children = [] } = $props();
11
+
12
+ let targetPosition = $state(null);
13
+ let newWidgetIsOpen = $state(false);
14
+
15
+ const group = $derived(widgetGroupRegistry.get(id));
16
+
17
+ async function handleAdd(position) {
18
+ targetPosition = position;
19
+ newWidgetIsOpen = true;
20
+ }
21
+
22
+ async function handleSave(data) {
23
+ console.log(data);
24
+
25
+ const request = await sendRequest({
26
+ path: '/create-widget',
27
+ data: {
28
+ type: data.type,
29
+ props: JSON.stringify({
30
+ ...data,
31
+ group_id: id,
32
+ position: targetPosition
33
+ })
34
+ }
35
+ });
36
+
37
+ if (request.statusType === 'error') {
38
+ toast.error({
39
+ title: 'Erreur !',
40
+ description: request.message
41
+ });
42
+ return;
43
+ }
44
+
45
+ registerWidgetGroups();
46
+ }
47
+
48
+ async function handleDelete(id) {
49
+ const request = await sendRequest({
50
+ path: '/delete-widget',
51
+ data: {
52
+ widgetId: id
53
+ }
54
+ });
55
+
56
+ if (request.statusType === 'error') {
57
+ toast.error({
58
+ title: 'Erreur !',
59
+ description: request.message
60
+ });
61
+ return;
62
+ }
63
+ registerWidgetGroups();
64
+ }
65
+ async function handleDeleteGroup() {
66
+ const request = await sendRequest({
67
+ path: '/delete-widget-group',
68
+ data: {
69
+ groupId: id
70
+ }
71
+ });
72
+
73
+ if (request.statusType === 'error') {
74
+ toast.error({
75
+ title: 'Erreur !',
76
+ description: request.message
77
+ });
78
+ return;
79
+ }
80
+ registerWidgetGroups();
81
+ }
82
+ </script>
83
+
84
+ <CreateWidgetDialog save={handleSave} bind:isOpen={newWidgetIsOpen}></CreateWidgetDialog>
85
+
86
+ <div class="row">
87
+ <IconButton onClick={handleDeleteGroup} variant="secondary">
88
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
89
+ <path d="M20.9997 6.72998C20.9797 6.72998 20.9497 6.72998 20.9197 6.72998C15.6297 6.19998 10.3497 5.99998 5.11967 6.52998L3.07967 6.72998C2.65967 6.76998 2.28967 6.46998 2.24967 6.04998C2.20967 5.62998 2.50967 5.26998 2.91967 5.22998L4.95967 5.02998C10.2797 4.48998 15.6697 4.69998 21.0697 5.22998C21.4797 5.26998 21.7797 5.63998 21.7397 6.04998C21.7097 6.43998 21.3797 6.72998 20.9997 6.72998Z" fill="#292D32"/>
90
+ <path d="M8.50074 5.72C8.46074 5.72 8.42074 5.72 8.37074 5.71C7.97074 5.64 7.69074 5.25 7.76074 4.85L7.98074 3.54C8.14074 2.58 8.36074 1.25 10.6907 1.25H13.3107C15.6507 1.25 15.8707 2.63 16.0207 3.55L16.2407 4.85C16.3107 5.26 16.0307 5.65 15.6307 5.71C15.2207 5.78 14.8307 5.5 14.7707 5.1L14.5507 3.8C14.4107 2.93 14.3807 2.76 13.3207 2.76H10.7007C9.64074 2.76 9.62074 2.9 9.47074 3.79L9.24074 5.09C9.18074 5.46 8.86074 5.72 8.50074 5.72Z" fill="#292D32"/>
91
+ <path d="M15.2104 22.7501H8.79039C5.30039 22.7501 5.16039 20.8201 5.05039 19.2601L4.40039 9.19007C4.37039 8.78007 4.69039 8.42008 5.10039 8.39008C5.52039 8.37008 5.87039 8.68008 5.90039 9.09008L6.55039 19.1601C6.66039 20.6801 6.70039 21.2501 8.79039 21.2501H15.2104C17.3104 21.2501 17.3504 20.6801 17.4504 19.1601L18.1004 9.09008C18.1304 8.68008 18.4904 8.37008 18.9004 8.39008C19.3104 8.42008 19.6304 8.77007 19.6004 9.19007L18.9504 19.2601C18.8404 20.8201 18.7004 22.7501 15.2104 22.7501Z" fill="#292D32"/>
92
+ <path d="M13.6601 17.25H10.3301C9.92008 17.25 9.58008 16.91 9.58008 16.5C9.58008 16.09 9.92008 15.75 10.3301 15.75H13.6601C14.0701 15.75 14.4101 16.09 14.4101 16.5C14.4101 16.91 14.0701 17.25 13.6601 17.25Z" fill="#292D32"/>
93
+ <path d="M14.5 13.25H9.5C9.09 13.25 8.75 12.91 8.75 12.5C8.75 12.09 9.09 11.75 9.5 11.75H14.5C14.91 11.75 15.25 12.09 15.25 12.5C15.25 12.91 14.91 13.25 14.5 13.25Z" fill="#292D32"/>
94
+ </svg>
95
+
96
+ </IconButton>
97
+ <div
98
+ class="group-container"
99
+ style="grid-template-columns:repeat({numberOfColumn}, minmax(0, 1fr));"
100
+ >
101
+ {#each Array.from({ length: numberOfColumn }) as column, index}
102
+ {const child = group.getChild(index + 1)}
103
+ {#if child}
104
+ <WidgetPreview
105
+ onDelete={() => {
106
+ handleDelete(child.id);
107
+ }}
108
+ type={child.type}
109
+ {...child.props}
110
+ ></WidgetPreview>
111
+ {:else}
112
+ <EmptySlot
113
+ onClick={() => {
114
+ handleAdd(index + 1);
115
+ }}
116
+ ></EmptySlot>
117
+ {/if}
118
+ {/each}
119
+ </div>
120
+ </div>
121
+
122
+ <style>
123
+ .row {
124
+ display: flex;
125
+ column-gap: var(--pad-s);
126
+ width: 100%;
127
+ }
128
+ .group-container {
129
+ width: 100%;
130
+ display: grid;
131
+ padding: var(--pad-xl);
132
+ column-gap: var(--pad-m);
133
+ min-height: 150px;
134
+ border: 1px solid var(--bg-2);
135
+ transition: border 0.2s ease-out;
136
+ border-radius: var(--radius-xxl);
137
+ }
138
+
139
+ .group-container:hover {
140
+ border: 1px solid var(--stroke);
141
+ }
142
+ </style>
@@ -0,0 +1,122 @@
1
+ <script>
2
+ import { IconButton } from 'hamzus-ui';
3
+
4
+ let {onCreate = (numberColumn) =>{}} = $props()
5
+ </script>
6
+
7
+ <div class="group">
8
+ <h4>Nouvelle rangée</h4>
9
+ <div class="btn">
10
+ <IconButton onClick={()=>{onCreate(1)}} size="48px" style="border-radius:var(--radius-l);" variant="outline">
11
+ <svg
12
+ width="24"
13
+ height="24"
14
+ viewBox="0 0 24 24"
15
+ fill="none"
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ >
18
+ <path
19
+ d="M19.9 7.75H4.1C2.6 7.75 2 8.39 2 9.98V14.02C2 15.61 2.6 16.25 4.1 16.25H19.9C21.4 16.25 22 15.61 22 14.02V9.98C22 8.39 21.4 7.75 19.9 7.75Z"
20
+ fill="#292D32"
21
+ />
22
+ </svg>
23
+ </IconButton>
24
+ <IconButton onClick={()=>{onCreate(2)}} size="48px" style="border-radius:var(--radius-l);" variant="outline"
25
+ ><svg
26
+ width="24"
27
+ height="24"
28
+ viewBox="0 0 24 24"
29
+ fill="none"
30
+ xmlns="http://www.w3.org/2000/svg"
31
+ >
32
+ <path
33
+ opacity="0.4"
34
+ d="M13.5 4.1V19.9C13.5 21.4 14.14 22 15.73 22H19.77C21.36 22 22 21.4 22 19.9V4.1C22 2.6 21.36 2 19.77 2H15.73C14.14 2 13.5 2.6 13.5 4.1Z"
35
+ fill="#292D32"
36
+ />
37
+ <path
38
+ d="M2 4.1V19.9C2 21.4 2.64 22 4.23 22H8.27C9.86 22 10.5 21.4 10.5 19.9V4.1C10.5 2.6 9.86 2 8.27 2H4.23C2.64 2 2 2.6 2 4.1Z"
39
+ fill="#292D32"
40
+ />
41
+ </svg>
42
+ </IconButton>
43
+ <IconButton onClick={()=>{onCreate(3)}} size="48px" style="border-radius:var(--radius-l);" variant="outline"
44
+ ><svg
45
+ width="24"
46
+ height="24"
47
+ viewBox="0 0 24 24"
48
+ fill="none"
49
+ xmlns="http://www.w3.org/2000/svg"
50
+ >
51
+ <path
52
+ d="M2 4.1V19.9C2 21.4 2.45147 22 3.57309 22H6.423C7.54462 22 7.99609 21.4 7.99609 19.9V4.1C7.99609 2.6 7.54462 2 6.423 2H3.57309C2.45147 2 2 2.6 2 4.1Z"
53
+ fill="#292D32"
54
+ />
55
+ <path
56
+ opacity="0.4"
57
+ d="M9.00195 4.1V19.9C9.00195 21.4 9.45342 22 10.575 22H13.425C14.5466 22 14.998 21.4 14.998 19.9V4.1C14.998 2.6 14.5466 2 13.425 2H10.575C9.45342 2 9.00195 2.6 9.00195 4.1Z"
58
+ fill="#292D32"
59
+ />
60
+ <path
61
+ d="M16.0039 4.1V19.9C16.0039 21.4 16.4554 22 17.577 22H20.4269C21.5485 22 22 21.4 22 19.9V4.1C22 2.6 21.5485 2 20.4269 2H17.577C16.4554 2 16.0039 2.6 16.0039 4.1Z"
62
+ fill="#292D32"
63
+ />
64
+ </svg>
65
+ </IconButton>
66
+ <IconButton onClick={()=>{onCreate(4)}} size="48px" style="border-radius:var(--radius-l);" variant="outline"
67
+ ><svg
68
+ width="24"
69
+ height="24"
70
+ viewBox="0 0 24 24"
71
+ fill="none"
72
+ xmlns="http://www.w3.org/2000/svg"
73
+ >
74
+ <path
75
+ d="M2.21875 4.1V19.9C2.21875 21.4 2.51366 22 3.24633 22H5.10795C5.84062 22 6.13553 21.4 6.13553 19.9V4.1C6.13553 2.6 5.84062 2 5.10795 2H3.24633C2.51366 2 2.21875 2.6 2.21875 4.1Z"
76
+ fill="#292D32"
77
+ />
78
+ <path
79
+ opacity="0.4"
80
+ d="M7.43359 4.1V19.9C7.43359 21.4 7.7285 22 8.46117 22H10.3228C11.0555 22 11.3504 21.4 11.3504 19.9V4.1C11.3504 2.6 11.0555 2 10.3228 2H8.46117C7.7285 2 7.43359 2.6 7.43359 4.1Z"
81
+ fill="#292D32"
82
+ />
83
+ <path
84
+ d="M12.6484 4.1V19.9C12.6484 21.4 12.9433 22 13.676 22H15.5376C16.2703 22 16.5652 21.4 16.5652 19.9V4.1C16.5652 2.6 16.2703 2 15.5376 2H13.676C12.9433 2 12.6484 2.6 12.6484 4.1Z"
85
+ fill="#292D32"
86
+ />
87
+ <path
88
+ opacity="0.4"
89
+ d="M17.8652 4.1V19.9C17.8652 21.4 18.1601 22 18.8928 22H20.7544C21.4871 22 21.782 21.4 21.782 19.9V4.1C21.782 2.6 21.4871 2 20.7544 2H18.8928C18.1601 2 17.8652 2.6 17.8652 4.1Z"
90
+ fill="#292D32"
91
+ />
92
+ </svg>
93
+ </IconButton>
94
+ </div>
95
+ </div>
96
+
97
+ <style>
98
+ .group {
99
+ display: flex;
100
+ align-items: center;
101
+ justify-content: center;
102
+ flex-direction: column;
103
+ gap: var(--pad-m);
104
+ padding: 50px var(--pad-xl);
105
+ border-radius: var(--radius-xl);
106
+ background-color: var(--bg-blur);
107
+ border: 5px solid var(--bg-1);
108
+ outline: 1px solid var(--bg-2);
109
+ transition: outline 0.2s ease-out;
110
+ width: 100%;
111
+ }
112
+
113
+ .group:hover {
114
+ outline: 1px solid var(--stroke);
115
+ }
116
+
117
+ .btn {
118
+ display: flex;
119
+ align-items: center;
120
+ column-gap: var(--pad-m);
121
+ }
122
+ </style>