hamzus-ui 0.0.1
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 +38 -0
- package/index.js +6 -0
- package/package.json +48 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Content.svelte +22 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Label.svelte +1 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Root.svelte +336 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Separator.svelte +12 -0
- package/src/components/hamzus-ui/AdvancedTooltip/Trigger.svelte +5 -0
- package/src/components/hamzus-ui/AdvancedTooltip/index.js +5 -0
- package/src/components/hamzus-ui/AlertCard/AlertCard.svelte +32 -0
- package/src/components/hamzus-ui/Avatar/Avatar.svelte +32 -0
- package/src/components/hamzus-ui/Button/Button.svelte +79 -0
- package/src/components/hamzus-ui/Button/Button_default.svelte +142 -0
- package/src/components/hamzus-ui/Button/Button_link.svelte +138 -0
- package/src/components/hamzus-ui/Checkboxes/Checkbox/Checkbox.svelte +41 -0
- package/src/components/hamzus-ui/Checkboxes/Checkbox/index.css +68 -0
- package/src/components/hamzus-ui/Checkboxes/CheckboxCard/CheckboxCard.svelte +27 -0
- package/src/components/hamzus-ui/Checkboxes/CheckboxCard/index.css +54 -0
- package/src/components/hamzus-ui/Code/Code.svelte +192 -0
- package/src/components/hamzus-ui/CopyCode/CopyCode.svelte +55 -0
- package/src/components/hamzus-ui/CopyLabel/CopyLabel.svelte +43 -0
- package/src/components/hamzus-ui/DataList/DataList.svelte +82 -0
- package/src/components/hamzus-ui/DatePicker/DatePicker.svelte +326 -0
- package/src/components/hamzus-ui/Dialog/Dialog.svelte +61 -0
- package/src/components/hamzus-ui/DropdownMenu/Button.svelte +46 -0
- package/src/components/hamzus-ui/DropdownMenu/Content.svelte +22 -0
- package/src/components/hamzus-ui/DropdownMenu/Label.svelte +1 -0
- package/src/components/hamzus-ui/DropdownMenu/Root.svelte +340 -0
- package/src/components/hamzus-ui/DropdownMenu/Separator.svelte +12 -0
- package/src/components/hamzus-ui/DropdownMenu/Trigger.svelte +1 -0
- package/src/components/hamzus-ui/DropdownMenu/index.js +6 -0
- package/src/components/hamzus-ui/IconButton/IconButton.svelte +80 -0
- package/src/components/hamzus-ui/IconButton/IconButton_default.svelte +140 -0
- package/src/components/hamzus-ui/IconButton/IconButton_link.svelte +141 -0
- package/src/components/hamzus-ui/InfoCard/InfoCard.svelte +32 -0
- package/src/components/hamzus-ui/Input/Input.svelte +304 -0
- package/src/components/hamzus-ui/KBD/KBD.svelte +24 -0
- package/src/components/hamzus-ui/Link/Link.svelte +36 -0
- package/src/components/hamzus-ui/List/List.svelte +30 -0
- package/src/components/hamzus-ui/LoaderCircle/Loader.svelte +25 -0
- package/src/components/hamzus-ui/LoaderCircle/index.js +1 -0
- package/src/components/hamzus-ui/Popover/Button.svelte +46 -0
- package/src/components/hamzus-ui/Popover/Content.svelte +21 -0
- package/src/components/hamzus-ui/Popover/Label.svelte +1 -0
- package/src/components/hamzus-ui/Popover/Root.svelte +374 -0
- package/src/components/hamzus-ui/Popover/Separator.svelte +12 -0
- package/src/components/hamzus-ui/Popover/Trigger.svelte +1 -0
- package/src/components/hamzus-ui/Popover/index.js +6 -0
- package/src/components/hamzus-ui/Portal/Portal.svelte +46 -0
- package/src/components/hamzus-ui/Portal/Wormhole.svelte +7 -0
- package/src/components/hamzus-ui/Radios/Radio/Radio.svelte +43 -0
- package/src/components/hamzus-ui/Radios/Radio/index.css +68 -0
- package/src/components/hamzus-ui/Radios/RadioCard/RadioCard.svelte +32 -0
- package/src/components/hamzus-ui/Radios/RadioCard/index.css +50 -0
- package/src/components/hamzus-ui/Radios/RadioGroup/RadioGroup.svelte +46 -0
- package/src/components/hamzus-ui/Radios/RadioGroup/index.css +8 -0
- package/src/components/hamzus-ui/ScrollArea/ScrollArea.svelte +360 -0
- package/src/components/hamzus-ui/Swicth/Swicth.svelte +84 -0
- package/src/components/hamzus-ui/Swicth/index.css +120 -0
- package/src/components/hamzus-ui/Table/ActionsBar.svelte +174 -0
- package/src/components/hamzus-ui/Table/Content.svelte +68 -0
- package/src/components/hamzus-ui/Table/Header.svelte +268 -0
- package/src/components/hamzus-ui/Table/NavigationBar.svelte +10 -0
- package/src/components/hamzus-ui/Table/Root.svelte +128 -0
- package/src/components/hamzus-ui/Table/index.js +5 -0
- package/src/components/hamzus-ui/Table/table.js +48 -0
- package/src/components/hamzus-ui/Tabs/Tabs.svelte +87 -0
- package/src/components/hamzus-ui/TabsLink/Tabs.svelte +80 -0
- package/src/components/hamzus-ui/Tag/Tag.svelte +43 -0
- package/src/components/hamzus-ui/TinyScrollArea/TinyScrollArea.svelte +350 -0
- package/src/styles/font.css +71 -0
- package/src/styles/global.css +37 -0
- package/src/styles/variables.css +81 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
// import
|
|
3
|
+
import { tableData } from './table';
|
|
4
|
+
import Input from '@hamzus-ui/Input/Input.svelte';
|
|
5
|
+
import Button from '@hamzus-ui/DropdownMenu/Button.svelte';
|
|
6
|
+
import * as DropdownMenu from '@hamzus-ui/DropdownMenu';
|
|
7
|
+
import { Content } from '.';
|
|
8
|
+
import Checkbox from '@hamzus-ui/Checkboxes/Checkbox/Checkbox.svelte';
|
|
9
|
+
// props
|
|
10
|
+
export let tableId = null;
|
|
11
|
+
|
|
12
|
+
// local var
|
|
13
|
+
let globalSearch = $tableData[tableId].globalSearch;
|
|
14
|
+
$: updateGlobalSearch(globalSearch);
|
|
15
|
+
// life cycle
|
|
16
|
+
|
|
17
|
+
// function
|
|
18
|
+
function updateGlobalSearch(value) {
|
|
19
|
+
if (!$tableData || !$tableData[tableId] || $tableData[tableId].globalSearch === undefined) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
tableData.update((actualValue) => {
|
|
23
|
+
actualValue[tableId].globalSearch = value;
|
|
24
|
+
return actualValue;
|
|
25
|
+
});
|
|
26
|
+
document.dispatchEvent(new Event('updateTableResult'));
|
|
27
|
+
}
|
|
28
|
+
function toggleHideColumn(columnName, value) {
|
|
29
|
+
tableData.update((actualValue) => {
|
|
30
|
+
for (let i = 0; i < actualValue[tableId].columns.length; i++) {
|
|
31
|
+
if (actualValue[tableId].columns[i].name === columnName) {
|
|
32
|
+
actualValue[tableId].columns[i].hidden = value;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return actualValue;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function handleRemoveFilter(columnName) {
|
|
41
|
+
let foundedColumn = false;
|
|
42
|
+
tableData.update((actualValue) => {
|
|
43
|
+
for (let i = 0; i < actualValue[tableId].columns.length; i++) {
|
|
44
|
+
const element = actualValue[tableId].columns[i];
|
|
45
|
+
if (element.name === columnName) {
|
|
46
|
+
actualValue[tableId].columns[i].filter = "";
|
|
47
|
+
delete actualValue[tableId].filters[columnName];
|
|
48
|
+
foundedColumn = true;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return actualValue;
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
if (foundedColumn) {
|
|
57
|
+
// emmetre un event
|
|
58
|
+
document.dispatchEvent(new Event('updateTableResult'));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function handleResetSettings() {
|
|
63
|
+
document.dispatchEvent(new Event('resetTableColumnsSettings'));
|
|
64
|
+
}
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<div class="actions-bar">
|
|
68
|
+
<Input placeholder="recherche" bind:value={globalSearch}>
|
|
69
|
+
<svg
|
|
70
|
+
slot="endContent"
|
|
71
|
+
width="24"
|
|
72
|
+
height="24"
|
|
73
|
+
viewBox="0 0 24 24"
|
|
74
|
+
fill="none"
|
|
75
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
76
|
+
>
|
|
77
|
+
<path
|
|
78
|
+
d="M11.5 21.75C5.85 21.75 1.25 17.15 1.25 11.5C1.25 5.85 5.85 1.25 11.5 1.25C17.15 1.25 21.75 5.85 21.75 11.5C21.75 17.15 17.15 21.75 11.5 21.75ZM11.5 2.75C6.67 2.75 2.75 6.68 2.75 11.5C2.75 16.32 6.67 20.25 11.5 20.25C16.33 20.25 20.25 16.32 20.25 11.5C20.25 6.68 16.33 2.75 11.5 2.75Z"
|
|
79
|
+
fill="#292D32"
|
|
80
|
+
/>
|
|
81
|
+
<path
|
|
82
|
+
d="M22.0004 22.7499C21.8104 22.7499 21.6204 22.6799 21.4704 22.5299L19.4704 20.5299C19.1804 20.2399 19.1804 19.7599 19.4704 19.4699C19.7604 19.1799 20.2404 19.1799 20.5304 19.4699L22.5304 21.4699C22.8204 21.7599 22.8204 22.2399 22.5304 22.5299C22.3804 22.6799 22.1904 22.7499 22.0004 22.7499Z"
|
|
83
|
+
fill="#292D32"
|
|
84
|
+
/>
|
|
85
|
+
</svg>
|
|
86
|
+
</Input>
|
|
87
|
+
|
|
88
|
+
<DropdownMenu.Root>
|
|
89
|
+
<DropdownMenu.Trigger slot="trigger">
|
|
90
|
+
<Button variant="secondary">
|
|
91
|
+
<svg
|
|
92
|
+
width="24"
|
|
93
|
+
height="24"
|
|
94
|
+
viewBox="0 0 24 24"
|
|
95
|
+
fill="none"
|
|
96
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
97
|
+
>
|
|
98
|
+
<path
|
|
99
|
+
d="M13 22.75H11C7.7 22.75 5.71 22.09 5.34 18.74C5.28 18.29 5.25 17.75 5.25 17V7C5.25 6.25 5.28 5.71 5.35 5.23C5.71 1.91 7.7 1.25 11 1.25H13C16.3 1.25 18.29 1.91 18.66 5.26C18.72 5.71 18.75 6.25 18.75 7V17C18.75 17.75 18.72 18.29 18.65 18.77C18.29 22.09 16.3 22.75 13 22.75ZM11 2.75C7.69 2.75 7.06 3.42 6.84 5.42C6.78 5.85 6.75 6.32 6.75 7V17C6.75 17.68 6.78 18.15 6.83 18.55C7.05 20.58 7.69 21.25 11 21.25H13C16.31 21.25 16.94 20.58 17.16 18.58C17.22 18.16 17.25 17.68 17.25 17V7C17.25 6.33 17.22 5.85 17.17 5.45C16.95 3.42 16.31 2.75 13 2.75H11Z"
|
|
100
|
+
fill="#292D32"
|
|
101
|
+
/>
|
|
102
|
+
<path
|
|
103
|
+
d="M5.67 19.4201H5.33C2.24 19.4201 1.25 18.4301 1.25 15.3301V8.67008C1.25 5.57008 2.24 4.58008 5.33 4.58008H5.67C5.84 4.58008 5.98 4.58008 6.14 4.59008C6.35 4.60008 6.54 4.70008 6.67 4.87008C6.8 5.04008 6.86 5.24008 6.83 5.45008C6.78 5.85008 6.75 6.32008 6.75 7.00008V17.0001C6.75 17.6801 6.78 18.1501 6.83 18.5501C6.86 18.7601 6.8 18.9701 6.67 19.1301C6.54 19.2901 6.35 19.3901 6.14 19.4101C5.98 19.4201 5.84 19.4201 5.67 19.4201ZM5.27 6.08008C3.08 6.09008 2.75 6.44008 2.75 8.67008V15.3301C2.75 17.5601 3.08 17.9101 5.27 17.9201C5.26 17.6501 5.25 17.3501 5.25 17.0001V7.00008C5.25 6.65008 5.26 6.35008 5.27 6.08008Z"
|
|
104
|
+
fill="#292D32"
|
|
105
|
+
/>
|
|
106
|
+
<path
|
|
107
|
+
d="M18.6697 19.4201H18.3297C18.1597 19.4201 18.0197 19.4201 17.8597 19.4101C17.6497 19.4001 17.4597 19.3001 17.3297 19.1301C17.1997 18.9701 17.1397 18.7601 17.1697 18.5501C17.2297 18.1501 17.2497 17.6701 17.2497 17.0001V7.00008C17.2497 6.33008 17.2197 5.85008 17.1697 5.45008C17.1397 5.24008 17.1997 5.03008 17.3297 4.87008C17.4597 4.71008 17.6497 4.61008 17.8597 4.59008C18.0197 4.58008 18.1597 4.58008 18.3297 4.58008H18.6697C21.7597 4.58008 22.7497 5.57008 22.7497 8.67008V15.3301C22.7497 18.4301 21.7597 19.4201 18.6697 19.4201ZM18.7297 6.08008C18.7397 6.35008 18.7497 6.65008 18.7497 7.00008V17.0001C18.7497 17.3501 18.7397 17.6501 18.7297 17.9201C20.9197 17.9101 21.2497 17.5601 21.2497 15.3301V8.67008C21.2497 6.44008 20.9197 6.09008 18.7297 6.08008Z"
|
|
108
|
+
fill="#292D32"
|
|
109
|
+
/>
|
|
110
|
+
</svg>
|
|
111
|
+
<h4>colonnes</h4>
|
|
112
|
+
</Button>
|
|
113
|
+
</DropdownMenu.Trigger>
|
|
114
|
+
<DropdownMenu.Content slot="content">
|
|
115
|
+
<DropdownMenu.Label>Caché des colonnes</DropdownMenu.Label>
|
|
116
|
+
{#each $tableData[tableId].columns as column}
|
|
117
|
+
<DropdownMenu.Button style="justify-content:space-between;">
|
|
118
|
+
<h4>{column.label}</h4>
|
|
119
|
+
<Checkbox
|
|
120
|
+
checked={column.hidden}
|
|
121
|
+
onChange={(value) => {
|
|
122
|
+
toggleHideColumn(column.name, value);
|
|
123
|
+
}}
|
|
124
|
+
></Checkbox>
|
|
125
|
+
</DropdownMenu.Button>
|
|
126
|
+
{/each}
|
|
127
|
+
<DropdownMenu.Separator></DropdownMenu.Separator>
|
|
128
|
+
|
|
129
|
+
<DropdownMenu.Button onClick={handleResetSettings} style="justify-content:space-between;"><h4>paramètres par defauts</h4></DropdownMenu.Button>
|
|
130
|
+
</DropdownMenu.Content>
|
|
131
|
+
</DropdownMenu.Root>
|
|
132
|
+
|
|
133
|
+
<!-- liste des filtres -->
|
|
134
|
+
{#if $tableData[tableId].filters}
|
|
135
|
+
{#each Object.entries($tableData[tableId].filters) as [key, filter]}
|
|
136
|
+
{@const column = $tableData[tableId].columns.filter((obj) => obj.name === key)[0]}
|
|
137
|
+
|
|
138
|
+
{#if column.searchChoices}
|
|
139
|
+
<Button
|
|
140
|
+
onClick={()=>{handleRemoveFilter(column.name)}}
|
|
141
|
+
style="border-radius:var(--radius-m);padding-left:3px;"
|
|
142
|
+
variant="outline"
|
|
143
|
+
>
|
|
144
|
+
<h4 class="filter-column">{column.label}</h4>
|
|
145
|
+
<h4>: {column.searchChoices.filter((obj) => obj.value === filter)[0].label}</h4>
|
|
146
|
+
</Button>
|
|
147
|
+
{:else}
|
|
148
|
+
<Button
|
|
149
|
+
onClick={()=>{handleRemoveFilter(column.name)}}
|
|
150
|
+
style="border-radius:var(--radius-m);padding-left:3px;"
|
|
151
|
+
variant="outline"
|
|
152
|
+
>
|
|
153
|
+
<h4 class="filter-column">{column.label}</h4>
|
|
154
|
+
<h4>: {filter}</h4>
|
|
155
|
+
</Button>
|
|
156
|
+
{/if}
|
|
157
|
+
{/each}
|
|
158
|
+
{/if}
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<style>
|
|
162
|
+
.actions-bar {
|
|
163
|
+
display: flex;
|
|
164
|
+
align-items: center;
|
|
165
|
+
column-gap: var(--pad-m);
|
|
166
|
+
margin-bottom: var(--pad-m);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.filter-column {
|
|
170
|
+
background-color: var(--bg-2);
|
|
171
|
+
padding: 0px var(--pad-m);
|
|
172
|
+
border-radius: var(--radius-s);
|
|
173
|
+
}
|
|
174
|
+
</style>
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
// import
|
|
3
|
+
import { tableData } from './table';
|
|
4
|
+
// props
|
|
5
|
+
export let tableId = null;
|
|
6
|
+
|
|
7
|
+
// local var
|
|
8
|
+
|
|
9
|
+
// lifeTime component
|
|
10
|
+
|
|
11
|
+
// function
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<div class="content">
|
|
15
|
+
{#each $tableData[tableId].rows as row}
|
|
16
|
+
<div class="row">
|
|
17
|
+
{#each Object.keys(row) as cellKey}
|
|
18
|
+
{@const column = $tableData[tableId].columns.filter((obj) => obj.name === cellKey)[0]}
|
|
19
|
+
|
|
20
|
+
{#if !column.hidden}
|
|
21
|
+
<div
|
|
22
|
+
class="cell"
|
|
23
|
+
style="--cell-width:{column.width ?? column.initialWidth}px;{column.skipLine === true
|
|
24
|
+
? 'white-space:nowrap;'
|
|
25
|
+
: ''}"
|
|
26
|
+
>
|
|
27
|
+
<!-- il se peut que ce soit un composant -->
|
|
28
|
+
{#if typeof row[cellKey] === 'object'}
|
|
29
|
+
<svelte:component this={row[cellKey].component} {...row[cellKey].props}></svelte:component>
|
|
30
|
+
{:else}
|
|
31
|
+
<h4>{row[cellKey]}</h4>
|
|
32
|
+
{/if}
|
|
33
|
+
</div>
|
|
34
|
+
{/if}
|
|
35
|
+
{/each}
|
|
36
|
+
</div>
|
|
37
|
+
{/each}
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
<style>
|
|
41
|
+
.content {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex-direction: column;
|
|
44
|
+
}
|
|
45
|
+
.row {
|
|
46
|
+
display: flex;
|
|
47
|
+
border-bottom: 1px solid var(--stroke);
|
|
48
|
+
flex-shrink: 0;
|
|
49
|
+
min-width: max-content;
|
|
50
|
+
width: 100%;
|
|
51
|
+
}
|
|
52
|
+
.row:hover {
|
|
53
|
+
background-color: var(--bg-2);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.cell {
|
|
57
|
+
width: var(--cell-width);
|
|
58
|
+
padding: var(--pad-m);
|
|
59
|
+
overflow: hidden;
|
|
60
|
+
text-overflow: ellipsis;
|
|
61
|
+
border-right: 1px solid var(--stroke);
|
|
62
|
+
flex-shrink: 0;
|
|
63
|
+
}
|
|
64
|
+
.cell > h4 {
|
|
65
|
+
overflow: hidden;
|
|
66
|
+
text-overflow: ellipsis;
|
|
67
|
+
}
|
|
68
|
+
</style>
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
// import
|
|
3
|
+
import { tableData } from './table';
|
|
4
|
+
import Button from '@hamzus-ui/Button/Button.svelte';
|
|
5
|
+
import * as DropdownMenu from '@hamzus-ui/DropdownMenu';
|
|
6
|
+
import * as Popover from '@hamzus-ui/Popover';
|
|
7
|
+
import Input from '@hamzus-ui/Input/Input.svelte';
|
|
8
|
+
import RadioGroup from '@hamzus-ui/Radios/RadioGroup/RadioGroup.svelte';
|
|
9
|
+
import Swicth from '@hamzus-ui/Swicth/Swicth.svelte';
|
|
10
|
+
// props
|
|
11
|
+
export let tableId = null;
|
|
12
|
+
// local var
|
|
13
|
+
const minimalColumnWidth = 50
|
|
14
|
+
let start = null;
|
|
15
|
+
let trackedColumnName = null;
|
|
16
|
+
let trackedColumnWidth = null;
|
|
17
|
+
// function
|
|
18
|
+
function handleMouseDown(event, columnName) {
|
|
19
|
+
start = event.clientX;
|
|
20
|
+
trackedColumnName = columnName;
|
|
21
|
+
for (let i = 0; i < $tableData[tableId].columns.length; i++) {
|
|
22
|
+
const element = $tableData[tableId].columns[i];
|
|
23
|
+
if (element.name === trackedColumnName) {
|
|
24
|
+
trackedColumnWidth = element.width ?? element.initialWidth ?? 0
|
|
25
|
+
break
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
document.addEventListener('mousemove', handleMouseMove);
|
|
29
|
+
document.addEventListener('mouseup', removeListener);
|
|
30
|
+
}
|
|
31
|
+
function handleMouseMove(event) {
|
|
32
|
+
const deltaX = start - event.clientX;
|
|
33
|
+
|
|
34
|
+
// update la colonne
|
|
35
|
+
tableData.update((actualValue) => {
|
|
36
|
+
for (let i = 0; i < actualValue[tableId].columns.length; i++) {
|
|
37
|
+
const element = actualValue[tableId].columns[i];
|
|
38
|
+
if (element.name === trackedColumnName) {
|
|
39
|
+
const newWidth = trackedColumnWidth - deltaX
|
|
40
|
+
actualValue[tableId].columns[i].width = newWidth > minimalColumnWidth ? newWidth : minimalColumnWidth;
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return actualValue;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function removeListener() {
|
|
49
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
|
50
|
+
document.removeEventListener('mouseup', removeListener);
|
|
51
|
+
}
|
|
52
|
+
function handleChangeSkipLine(columnName, newValue) {
|
|
53
|
+
tableData.update((actualValue) => {
|
|
54
|
+
for (let i = 0; i < actualValue[tableId].columns.length; i++) {
|
|
55
|
+
const element = actualValue[tableId].columns[i];
|
|
56
|
+
if (element.name === columnName) {
|
|
57
|
+
actualValue[tableId].columns[i].skipLine = newValue;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return actualValue;
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function handleFilter(columnName, newValue) {
|
|
66
|
+
|
|
67
|
+
let foundedColumn = false
|
|
68
|
+
tableData.update((actualValue) => {
|
|
69
|
+
for (let i = 0; i < actualValue[tableId].columns.length; i++) {
|
|
70
|
+
const element = actualValue[tableId].columns[i];
|
|
71
|
+
if (element.name === columnName) {
|
|
72
|
+
if (newValue === null || newValue === undefined || newValue === "") {
|
|
73
|
+
actualValue[tableId].columns[i].filter = newValue
|
|
74
|
+
delete actualValue[tableId].filters[columnName]
|
|
75
|
+
foundedColumn = true
|
|
76
|
+
break
|
|
77
|
+
}
|
|
78
|
+
actualValue[tableId].columns[i].filter = newValue
|
|
79
|
+
actualValue[tableId].filters[columnName] = newValue
|
|
80
|
+
foundedColumn = true
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return actualValue;
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (foundedColumn) {
|
|
89
|
+
// emmetre un event
|
|
90
|
+
document.dispatchEvent(new Event("updateTableResult"))
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function handleSort(columnName){
|
|
94
|
+
tableData.update((actualValue) => {
|
|
95
|
+
const actualSort = actualValue[tableId].sort
|
|
96
|
+
|
|
97
|
+
// si la colonne est different alors on set la direction en desc
|
|
98
|
+
let newDirection = ""
|
|
99
|
+
if (actualSort.columnName != columnName) {
|
|
100
|
+
newDirection = "DESC"
|
|
101
|
+
}else{
|
|
102
|
+
// modifier la direction
|
|
103
|
+
switch (actualSort.direction) {
|
|
104
|
+
case "":
|
|
105
|
+
newDirection = "DESC"
|
|
106
|
+
break;
|
|
107
|
+
case "DESC":
|
|
108
|
+
newDirection = "ASC"
|
|
109
|
+
break;
|
|
110
|
+
default:
|
|
111
|
+
// if "ASC" -> remove filter
|
|
112
|
+
newDirection = ""
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
actualValue[tableId].sort = {
|
|
118
|
+
"columnName":columnName,
|
|
119
|
+
"direction":newDirection
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return actualValue;
|
|
123
|
+
});
|
|
124
|
+
document.dispatchEvent(new Event("updateTableResult"))
|
|
125
|
+
}
|
|
126
|
+
function focusInput(columnName) {
|
|
127
|
+
// selectionner l input si il y en a
|
|
128
|
+
|
|
129
|
+
if (document.querySelector(`.input-column-hamzus-${columnName}`)) {
|
|
130
|
+
document.querySelector(`.input-column-hamzus-${columnName} input`).focus()
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
</script>
|
|
134
|
+
|
|
135
|
+
<div class="header">
|
|
136
|
+
{#each $tableData[tableId].columns as column, index}
|
|
137
|
+
{#if !column.hidden}
|
|
138
|
+
<div class="column" style="--width:{column.width ?? column.initialWidth}px;">
|
|
139
|
+
{#if column.isSearchable}
|
|
140
|
+
<DropdownMenu.Root triggerFullWidth onOpen={()=>{focusInput(column.name)}}>
|
|
141
|
+
<DropdownMenu.Trigger slot="trigger">
|
|
142
|
+
<Button
|
|
143
|
+
style="width:100%;"
|
|
144
|
+
avoidRipple={!column.isSearchable}
|
|
145
|
+
variant="ghost"
|
|
146
|
+
>
|
|
147
|
+
<h4>{column.label}</h4>
|
|
148
|
+
<h4>{($tableData[tableId].sort && $tableData[tableId].sort.columnName === column.name && $tableData[tableId].sort.direction !== "" ? ($tableData[tableId].sort.direction === "DESC" ? "⬇️" : "⬆️") : "")}</h4>
|
|
149
|
+
<h4>{$tableData[tableId].filters && $tableData[tableId].filters[column.name] != "" & $tableData[tableId].filters[column.name] != undefined ? "🔍" : ""}</h4>
|
|
150
|
+
|
|
151
|
+
</Button>
|
|
152
|
+
</DropdownMenu.Trigger>
|
|
153
|
+
<DropdownMenu.Content slot="content">
|
|
154
|
+
<DropdownMenu.Label>{column.label}</DropdownMenu.Label>
|
|
155
|
+
{#if !column.searchChoices}
|
|
156
|
+
<div class="input-column-hamzus-{column.name}">
|
|
157
|
+
<Input placeholder="filtre" value={column.filter} onChange={(newValue)=>{handleFilter(column.name, newValue)}}></Input>
|
|
158
|
+
</div>
|
|
159
|
+
{:else}
|
|
160
|
+
<Popover.Root direction="right" triggerFullWidth>
|
|
161
|
+
<Popover.Trigger slot="trigger">
|
|
162
|
+
<Button style="width:100%;justify-content:space-between;" variant="ghost">
|
|
163
|
+
<h4>filtre</h4>
|
|
164
|
+
<svg
|
|
165
|
+
width="24"
|
|
166
|
+
height="24"
|
|
167
|
+
viewBox="0 0 24 24"
|
|
168
|
+
fill="none"
|
|
169
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
170
|
+
>
|
|
171
|
+
<path
|
|
172
|
+
d="M14.4291 18.8201C14.2391 18.8201 14.0491 18.7501 13.8991 18.6001C13.6091 18.3101 13.6091 17.8301 13.8991 17.5401L19.4391 12.0001L13.8991 6.46012C13.6091 6.17012 13.6091 5.69012 13.8991 5.40012C14.1891 5.11012 14.6691 5.11012 14.9591 5.40012L21.0291 11.4701C21.3191 11.7601 21.3191 12.2401 21.0291 12.5301L14.9591 18.6001C14.8091 18.7501 14.6191 18.8201 14.4291 18.8201Z"
|
|
173
|
+
fill="#292D32"
|
|
174
|
+
/>
|
|
175
|
+
<path
|
|
176
|
+
d="M20.33 12.75H3.5C3.09 12.75 2.75 12.41 2.75 12C2.75 11.59 3.09 11.25 3.5 11.25H20.33C20.74 11.25 21.08 11.59 21.08 12C21.08 12.41 20.74 12.75 20.33 12.75Z"
|
|
177
|
+
fill="#292D32"
|
|
178
|
+
/>
|
|
179
|
+
</svg>
|
|
180
|
+
</Button>
|
|
181
|
+
</Popover.Trigger>
|
|
182
|
+
<Popover.Content slot="content">
|
|
183
|
+
<Popover.Button label="aucun" onClick={()=>{handleFilter(column.name, null)}}></Popover.Button>
|
|
184
|
+
{#each column.searchChoices as choice}
|
|
185
|
+
<Popover.Button label={choice.label} onClick={()=>{handleFilter(column.name, choice.value)}}></Popover.Button>
|
|
186
|
+
{/each}
|
|
187
|
+
</Popover.Content>
|
|
188
|
+
</Popover.Root>
|
|
189
|
+
{/if}
|
|
190
|
+
<DropdownMenu.Separator></DropdownMenu.Separator>
|
|
191
|
+
<DropdownMenu.Button variant="ghost">
|
|
192
|
+
<label
|
|
193
|
+
style="display:flex;align-items:center;justify-content:space-between;width:100%;"
|
|
194
|
+
>
|
|
195
|
+
<h4>passer a la ligne</h4>
|
|
196
|
+
<Swicth checked={column.skipLine} onChange={(newValue)=>{handleChangeSkipLine(column.name, newValue)}} size={16}></Swicth>
|
|
197
|
+
</label>
|
|
198
|
+
</DropdownMenu.Button>
|
|
199
|
+
{#if column.isSortable !== false}
|
|
200
|
+
<DropdownMenu.Separator></DropdownMenu.Separator>
|
|
201
|
+
<DropdownMenu.Button onClick={()=>{handleSort(column.name)}} variant="ghost" label="trier"></DropdownMenu.Button>
|
|
202
|
+
{/if}
|
|
203
|
+
</DropdownMenu.Content>
|
|
204
|
+
</DropdownMenu.Root>
|
|
205
|
+
{:else}
|
|
206
|
+
<Button
|
|
207
|
+
style="width:100%;"
|
|
208
|
+
avoidRipple={!column.isSearchable}
|
|
209
|
+
variant="ghost"
|
|
210
|
+
label={column.label}
|
|
211
|
+
></Button>
|
|
212
|
+
{/if}
|
|
213
|
+
<span class="resizer"
|
|
214
|
+
><button
|
|
215
|
+
onmousedown={(event) => {
|
|
216
|
+
handleMouseDown(event, column.name);
|
|
217
|
+
}}
|
|
218
|
+
class="resizer-pad"
|
|
219
|
+
></button></span
|
|
220
|
+
>
|
|
221
|
+
</div>
|
|
222
|
+
{/if}
|
|
223
|
+
{/each}
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<style>
|
|
227
|
+
.header {
|
|
228
|
+
min-width: 100%;
|
|
229
|
+
width: max-content;
|
|
230
|
+
display: flex;
|
|
231
|
+
border-bottom: 1px solid var(--stroke);
|
|
232
|
+
user-select: none;
|
|
233
|
+
background-color: var(--bg-2);
|
|
234
|
+
position: sticky;
|
|
235
|
+
top: 0;
|
|
236
|
+
z-index: 1;
|
|
237
|
+
}
|
|
238
|
+
/* column */
|
|
239
|
+
.column {
|
|
240
|
+
display: flex;
|
|
241
|
+
width: var(--width);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/* track */
|
|
245
|
+
.resizer {
|
|
246
|
+
cursor: ew-resize;
|
|
247
|
+
width: 0px;
|
|
248
|
+
height: 100%;
|
|
249
|
+
position: relative;
|
|
250
|
+
}
|
|
251
|
+
.resizer:has(.resizer-pad:hover) {
|
|
252
|
+
background-color: var(--accent);
|
|
253
|
+
outline: 2px solid var(--accent);
|
|
254
|
+
}
|
|
255
|
+
.resizer:has(.resizer-pad:global(.resizing)) {
|
|
256
|
+
background-color: var(--accent);
|
|
257
|
+
outline: 2px solid var(--accent);
|
|
258
|
+
}
|
|
259
|
+
.resizer-pad {
|
|
260
|
+
all: unset;
|
|
261
|
+
position: absolute;
|
|
262
|
+
top: 50%;
|
|
263
|
+
left: 50%;
|
|
264
|
+
transform: translate(-50%, -50%);
|
|
265
|
+
width: 15px;
|
|
266
|
+
height: 100%;
|
|
267
|
+
}
|
|
268
|
+
</style>
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
// import
|
|
3
|
+
import { onMount } from 'svelte';
|
|
4
|
+
import { tableData } from './table';
|
|
5
|
+
|
|
6
|
+
// props
|
|
7
|
+
export let tableId = 0;
|
|
8
|
+
export let globalSearch = '';
|
|
9
|
+
export let columns = [];
|
|
10
|
+
export let filters = {};
|
|
11
|
+
export let sort = {};
|
|
12
|
+
export let actions = [];
|
|
13
|
+
export let totalOfRows = 0;
|
|
14
|
+
export let limit = 20;
|
|
15
|
+
export let offset = 0;
|
|
16
|
+
export let getRows = (globalSearch, filters) => {};
|
|
17
|
+
|
|
18
|
+
// locale var
|
|
19
|
+
let monted = false;
|
|
20
|
+
let rows = [];
|
|
21
|
+
let defaultColumns = [...columns];
|
|
22
|
+
|
|
23
|
+
// life component
|
|
24
|
+
onMount(async () => {
|
|
25
|
+
// verifier si l utilisateur possede une ocnfigursation enregistre dans le localsotrage
|
|
26
|
+
const savedConfiguration = localStorage.getItem(`table_${tableId}`);
|
|
27
|
+
if (savedConfiguration) {
|
|
28
|
+
try {
|
|
29
|
+
const overrideConfig = JSON.parse(savedConfiguration);
|
|
30
|
+
columns = overrideConfig.columns;
|
|
31
|
+
filters = overrideConfig.filters;
|
|
32
|
+
globalSearch = overrideConfig.globalSearch;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
// suprimmer ce localstorage car il ne peut pas etre decoder
|
|
35
|
+
localStorage.removeItem(`table_${tableId}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// aller chercher les rows
|
|
40
|
+
const request = await getRows(globalSearch, filters, sort, limit, offset)
|
|
41
|
+
totalOfRows = request.totalOfRows
|
|
42
|
+
rows = request.rows;
|
|
43
|
+
|
|
44
|
+
// creer la table dans le store
|
|
45
|
+
|
|
46
|
+
const table = {
|
|
47
|
+
globalSearch: globalSearch,
|
|
48
|
+
columns: columns,
|
|
49
|
+
filters: filters,
|
|
50
|
+
sort: sort,
|
|
51
|
+
actions: actions,
|
|
52
|
+
rows: rows,
|
|
53
|
+
totalOfRows: totalOfRows,
|
|
54
|
+
limit: limit,
|
|
55
|
+
offset: offset,
|
|
56
|
+
getRows: getRows
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
tableData.update((actualValue) => {
|
|
60
|
+
const newValue = {
|
|
61
|
+
...actualValue,
|
|
62
|
+
[tableId]: table
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
...newValue
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// add les event
|
|
70
|
+
document.addEventListener('updateTableResult', handleUpdateResult);
|
|
71
|
+
document.addEventListener('resetTableColumnsSettings', handleResetSettings);
|
|
72
|
+
|
|
73
|
+
monted = true;
|
|
74
|
+
|
|
75
|
+
return () => {
|
|
76
|
+
document.removeEventListener('updateTableResult', handleUpdateResult);
|
|
77
|
+
document.removeEventListener('resetTableColumnsSettings', handleResetSettings);
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
async function handleUpdateResult() {
|
|
82
|
+
const actualTableData = $tableData[tableId];
|
|
83
|
+
|
|
84
|
+
const request = await getRows(
|
|
85
|
+
actualTableData.globalSearch,
|
|
86
|
+
actualTableData.filters,
|
|
87
|
+
actualTableData.sort,
|
|
88
|
+
actualTableData.limit,
|
|
89
|
+
actualTableData.offset
|
|
90
|
+
);
|
|
91
|
+
totalOfRows = request.totalOfRows
|
|
92
|
+
$tableData[tableId].rows = request.rows;
|
|
93
|
+
|
|
94
|
+
saveDataActualData();
|
|
95
|
+
}
|
|
96
|
+
async function saveDataActualData() {
|
|
97
|
+
if (!monted) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
localStorage.setItem(`table_${tableId}`, JSON.stringify($tableData[tableId]));
|
|
101
|
+
}
|
|
102
|
+
function handleResetSettings() {
|
|
103
|
+
tableData.update((actualValue) => {
|
|
104
|
+
actualValue[tableId].columns = JSON.parse(JSON.stringify(defaultColumns));
|
|
105
|
+
return {
|
|
106
|
+
...actualValue
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
</script>
|
|
111
|
+
|
|
112
|
+
{#if monted}
|
|
113
|
+
<div class="table">
|
|
114
|
+
<slot name="actions-bar" {tableId}></slot>
|
|
115
|
+
<slot name="header" {tableId}></slot>
|
|
116
|
+
<slot name="content" {tableId}></slot>
|
|
117
|
+
<slot name="navigation-bar" {tableId}></slot>
|
|
118
|
+
</div>
|
|
119
|
+
{/if}
|
|
120
|
+
|
|
121
|
+
<style>
|
|
122
|
+
.table {
|
|
123
|
+
display: flex;
|
|
124
|
+
flex-direction: column;
|
|
125
|
+
width: 100%;
|
|
126
|
+
overflow-x: scroll;
|
|
127
|
+
}
|
|
128
|
+
</style>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as Root } from './Root.svelte';//main logic
|
|
2
|
+
export { default as ActionsBar } from './ActionsBar.svelte';//search, active filters, columns list,...
|
|
3
|
+
export { default as Header } from './Header.svelte';//table header/columns
|
|
4
|
+
export { default as Content } from './Content.svelte';//table rows
|
|
5
|
+
export { default as NavigationBar } from './NavigationBar.svelte';// bottom navigation bar
|