@bexis2/bexis2-core-ui 0.3.12 → 0.3.14

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 (30) hide show
  1. package/README.md +2 -0
  2. package/dist/components/File/FileUploader.svelte +3 -3
  3. package/dist/components/Table/TableContent.svelte +202 -119
  4. package/dist/components/Table/TableFilter.svelte +146 -102
  5. package/dist/components/Table/TableFilter.svelte.d.ts +2 -3
  6. package/dist/components/Table/TableFilterServer.svelte +274 -0
  7. package/dist/components/Table/TableFilterServer.svelte.d.ts +22 -0
  8. package/dist/components/Table/TablePagination.svelte +72 -39
  9. package/dist/components/Table/TablePaginationServer.svelte +125 -0
  10. package/dist/components/Table/TablePaginationServer.svelte.d.ts +21 -0
  11. package/dist/components/Table/filter.js +40 -78
  12. package/dist/components/Table/shared.d.ts +32 -0
  13. package/dist/components/Table/shared.js +117 -0
  14. package/dist/components/form/DropdownKvP.svelte.d.ts +4 -4
  15. package/dist/components/form/MultiSelect.svelte.d.ts +6 -6
  16. package/dist/models/Enums.d.ts +18 -0
  17. package/dist/models/Enums.js +20 -0
  18. package/dist/models/Models.d.ts +43 -2
  19. package/dist/models/Models.js +28 -1
  20. package/package.json +2 -2
  21. package/src/lib/components/Table/TableContent.svelte +227 -151
  22. package/src/lib/components/Table/TableFilter.svelte +166 -102
  23. package/src/lib/components/Table/TableFilterServer.svelte +310 -0
  24. package/src/lib/components/Table/TablePagination.svelte +75 -39
  25. package/src/lib/components/Table/TablePaginationServer.svelte +133 -0
  26. package/src/lib/components/Table/filter.ts +42 -86
  27. package/src/lib/components/Table/shared.ts +141 -0
  28. package/src/lib/components/file/FileUploader.svelte +3 -3
  29. package/src/lib/models/Enums.ts +22 -0
  30. package/src/lib/models/Models.ts +63 -2
@@ -1,96 +1,95 @@
1
1
  <script>import Fa from "svelte-fa/src/fa.svelte";
2
- import { faFilter } from "@fortawesome/free-solid-svg-icons";
2
+ import { faFilter, faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
3
3
  import { popup } from "@skeletonlabs/skeleton";
4
- export let filterValue;
4
+ import { FilterOptionsEnum } from "../../models/Enums";
5
5
  export let values;
6
6
  export let id;
7
7
  export let tableId;
8
8
  export let toFilterableValueFn = void 0;
9
- let firstOption;
10
- let firstValue;
11
- let secondOption;
12
- let secondValue;
9
+ export let filterValue;
10
+ export let filters;
13
11
  let active = false;
14
12
  const options = {
15
13
  number: [
16
14
  {
17
- value: "isequal",
15
+ value: FilterOptionsEnum.e,
18
16
  label: "Is equal to"
19
17
  },
20
18
  {
21
- value: "isgreaterorequal",
19
+ value: FilterOptionsEnum.gte,
22
20
  label: "Is greater than or equal to"
23
21
  },
24
22
  {
25
- value: "isgreater",
23
+ value: FilterOptionsEnum.gt,
26
24
  label: "Is greater than"
27
25
  },
28
26
  {
29
- value: "islessorequal",
27
+ value: FilterOptionsEnum.lte,
30
28
  label: "Is less than or equal to"
31
29
  },
32
30
  {
33
- value: "isless",
31
+ value: FilterOptionsEnum.lt,
34
32
  label: "Is less than"
35
33
  },
36
34
  {
37
- value: "isnotequal",
35
+ value: FilterOptionsEnum.ne,
38
36
  label: "Is not equal to"
39
37
  }
40
38
  ],
41
39
  string: [
42
40
  {
43
- value: "contains",
41
+ value: FilterOptionsEnum.c,
44
42
  label: "Contains"
45
43
  },
46
44
  {
47
- value: "notcontains",
45
+ value: FilterOptionsEnum.nc,
48
46
  label: "Does not contain"
49
47
  },
50
48
  {
51
- value: "isequal",
49
+ value: FilterOptionsEnum.e,
52
50
  label: "Is equal to"
53
51
  },
54
52
  {
55
- value: "isnotequal",
53
+ value: FilterOptionsEnum.ne,
56
54
  label: "Is not equal to"
57
55
  },
58
56
  {
59
- value: "starts",
57
+ value: FilterOptionsEnum.sw,
60
58
  label: "Starts with"
61
59
  },
62
60
  {
63
- value: "ends",
61
+ value: FilterOptionsEnum.ew,
64
62
  label: "Ends with"
65
63
  }
66
64
  ],
67
65
  date: [
68
66
  {
69
- value: "ison",
67
+ value: FilterOptionsEnum.o,
70
68
  label: "Is on"
71
69
  },
72
70
  {
73
- value: "isstartingfrom",
71
+ value: FilterOptionsEnum.sf,
74
72
  label: "Is starting from"
75
73
  },
76
74
  {
77
- value: "isafter",
75
+ value: FilterOptionsEnum.a,
78
76
  label: "Is after"
79
77
  },
80
78
  {
81
- value: "isuntil",
79
+ value: FilterOptionsEnum.u,
82
80
  label: "Is until"
83
81
  },
84
82
  {
85
- value: "isbefore",
83
+ value: FilterOptionsEnum.b,
86
84
  label: "Is before"
87
85
  },
88
86
  {
89
- value: "isnoton",
87
+ value: FilterOptionsEnum.no,
90
88
  label: "Is not on"
91
89
  }
92
90
  ]
93
91
  };
92
+ let dropdowns = [];
94
93
  const popupId = `${tableId}-${id}`;
95
94
  const popupFeatured = {
96
95
  event: "click",
@@ -109,7 +108,52 @@ $values.forEach((item) => {
109
108
  }
110
109
  }
111
110
  });
112
- type = isDate ? "date" : type;
111
+ const optionChangeHandler = (e, index) => {
112
+ delete $filters[id][dropdowns[index].option];
113
+ $filters[id] = { ...$filters[id], [e.target.value]: dropdowns[index].value };
114
+ $filters = $filters;
115
+ dropdowns[index] = {
116
+ ...dropdowns[index],
117
+ option: e.target.value
118
+ };
119
+ };
120
+ const valueChangeHandler = (e, index) => {
121
+ dropdowns[index] = {
122
+ ...dropdowns[index],
123
+ value: type === "number" ? +e.target.value : type === "date" ? new Date(e.target.value) : e.target.value
124
+ };
125
+ $filters = {
126
+ ...$filters,
127
+ [id]: { ...$filters[id], [dropdowns[index].option]: dropdowns[index].value }
128
+ };
129
+ };
130
+ const addFilter = (option, value) => {
131
+ $filters = { ...$filters, [id]: { ...$filters[id], [option]: value } };
132
+ dropdowns = [
133
+ ...dropdowns,
134
+ {
135
+ option,
136
+ value: void 0
137
+ }
138
+ ];
139
+ };
140
+ const removeFilter = (option) => {
141
+ dropdowns = dropdowns.filter((dropdown) => dropdown.option !== option);
142
+ delete $filters[id][option];
143
+ $filters = $filters;
144
+ };
145
+ const clearFilters = () => {
146
+ dropdowns = [];
147
+ $filters[id] = {};
148
+ };
149
+ $:
150
+ type = isDate ? "date" : type;
151
+ $:
152
+ remainingFilters = options[type].filter(
153
+ (option) => !Object.keys($filters[id]).includes(option.value)
154
+ );
155
+ $:
156
+ addFilter(options[type][0].value, void 0);
113
157
  </script>
114
158
 
115
159
  <form class="">
@@ -124,98 +168,98 @@ type = isDate ? "date" : type;
124
168
  </button>
125
169
 
126
170
  <div data-popup={`${popupId}`} id={popupId} class="z-50">
127
- <div class="card p-3 grid gap-2 shadow-lg w-min bg-base-100">
171
+ <div class="card p-3 grid gap-2 shadow-lg w-max bg-base-100">
128
172
  <button
129
173
  class="btn variant-filled-primary btn-sm"
130
174
  type="button"
131
175
  on:click|preventDefault={() => {
132
176
  // Set the defaults when cleared
133
- firstOption = 'isequal';
134
- firstValue = undefined;
135
- secondOption = 'isequal';
136
- secondValue = undefined;
137
-
138
- $filterValue = [firstOption, firstValue, secondOption, secondValue];
177
+ clearFilters();
178
+ addFilter(options[type][0].value, undefined);
179
+ $filterValue = $filters[id];
139
180
  active = false;
140
- }}>Clear Filter</button
181
+ }}>Clear Filters</button
141
182
  >
142
183
 
143
184
  <label for="" class="label normal-case text-sm">Show rows with value that</label>
144
- <div class="grid gap-2 w-full">
145
- <select
146
- class="select border border-primary-500 text-sm p-1"
147
- aria-label="Show rows with value that"
148
- bind:value={firstOption}
149
- on:click|stopPropagation
150
- >
151
- {#each options[type] as option (option)}
152
- <option value={option.value}>{option.label}</option>
153
- {/each}
154
- </select>
155
- {#if type === 'number'}
156
- <input
157
- type="number"
158
- class="input p-1 border border-primary-500"
159
- bind:value={firstValue}
160
- on:click|stopPropagation
161
- />
162
- {:else if type === 'string'}
163
- <input
164
- type="text"
165
- class="input p-1 border border-primary-500"
166
- bind:value={firstValue}
167
- on:click|stopPropagation
168
- />
169
- {:else}
170
- <input
171
- type="date"
172
- class="input p-1 border border-primary-500"
173
- bind:value={firstValue}
174
- on:click|stopPropagation
175
- />
176
- {/if}
185
+ <div class="grid gap-2 overflow-auto">
186
+ {#each dropdowns as dropdown, index (index)}
187
+ <div class="grid gap-2 w-full">
188
+ <div class="flex gap-1 items-center">
189
+ <select
190
+ class="select border border-primary-500 text-sm p-1"
191
+ aria-label="Show rows with value that"
192
+ on:change={(e) => optionChangeHandler(e, index)}
193
+ bind:value={dropdown.option}
194
+ >
195
+ {#each options[type] as option (option)}
196
+ <option
197
+ value={option.value}
198
+ selected={dropdown.option === option.value}
199
+ disabled={Object.keys($filters[id]).includes(option.value) &&
200
+ dropdown.option !== option.value}>{option.label}</option
201
+ >
202
+ {/each}
203
+ </select>
204
+ {#if dropdowns.length > 1}
205
+ <div
206
+ class="btn variant-filled-warning btn-sm h-full"
207
+ on:click|preventDefault={() => removeFilter(dropdown.option)}
208
+ on:keydown|preventDefault={() => removeFilter(dropdown.option)}
209
+ >
210
+ <Fa icon={faXmark} />
211
+ </div>
212
+ {/if}
213
+ </div>
214
+
215
+ {#if type === 'number'}
216
+ <input
217
+ type="number"
218
+ class="input p-1 border border-primary-500"
219
+ on:input={(e) => valueChangeHandler(e, index)}
220
+ bind:value={dropdown.value}
221
+ />
222
+ {:else if type === 'string'}
223
+ <input
224
+ type="text"
225
+ class="input p-1 border border-primary-500"
226
+ on:input={(e) => valueChangeHandler(e, index)}
227
+ bind:value={dropdown.value}
228
+ />
229
+ {:else}
230
+ <input
231
+ type="date"
232
+ class="input p-1 border border-primary-500"
233
+ on:input={(e) => valueChangeHandler(e, index)}
234
+ bind:value={dropdown.value}
235
+ />
236
+ {/if}
237
+ </div>
238
+ {#if index !== dropdowns.length - 1 && dropdowns.length > 1}
239
+ <label for="" class="label normal-case">And</label>
240
+ {/if}
241
+ {/each}
177
242
  </div>
178
- <label for="" class="label normal-case">And</label>
179
- <div class="grid gap-2 w-max">
180
- <select
181
- class="select border border-primary-500 text-sm p-1"
182
- aria-label="Show rows with value that"
183
- bind:value={secondOption}
184
- on:click|stopPropagation
243
+
244
+ {#if remainingFilters.length}
245
+ <div
246
+ class="btn variant-filled-secondary btn-sm cursor-pointer"
247
+ on:click|stopPropagation={() => {
248
+ addFilter(remainingFilters[0].value, undefined);
249
+ }}
250
+ on:keydown|stopPropagation={() => {
251
+ addFilter(remainingFilters[0].value, undefined);
252
+ }}
185
253
  >
186
- {#each options[type] as option (option)}
187
- <option value={option.value}>{option.label}</option>
188
- {/each}
189
- </select>
190
- {#if type === 'number'}
191
- <input
192
- type="number"
193
- class="input p-1 border border-primary-500"
194
- bind:value={secondValue}
195
- on:click|stopPropagation
196
- />
197
- {:else if type === 'string'}
198
- <input
199
- type="text"
200
- class="input p-1 border border-primary-500"
201
- bind:value={secondValue}
202
- on:click|stopPropagation
203
- />
204
- {:else}
205
- <input
206
- type="date"
207
- class="input p-1 border border-primary-500"
208
- bind:value={secondValue}
209
- on:click|stopPropagation
210
- />
211
- {/if}
212
- </div>
254
+ <div class="flex gap-1 items-center"><Fa icon={faPlus} />Add Filter</div>
255
+ </div>
256
+ {/if}
213
257
  <button
214
258
  class="btn variant-filled-primary btn-sm"
215
259
  type="button"
216
260
  on:click|preventDefault={() => {
217
- active = firstValue?.toString().length > 0 || secondValue?.toString().length > 0;
218
- $filterValue = [firstOption, firstValue, secondOption, secondValue];
261
+ $filterValue = $filters[id];
262
+ active = true;
219
263
  }}>Apply</button
220
264
  >
221
265
  </div>
@@ -1,15 +1,14 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
- filterValue: any;
5
4
  values: any;
6
5
  id: any;
7
6
  tableId: any;
8
7
  toFilterableValueFn?: ((value: any) => any) | undefined;
8
+ filterValue: any;
9
+ filters: any;
9
10
  };
10
11
  events: {
11
- click: MouseEvent;
12
- } & {
13
12
  [evt: string]: CustomEvent<any>;
14
13
  };
15
14
  slots: {};
@@ -0,0 +1,274 @@
1
+ <script>import Fa from "svelte-fa/src/fa.svelte";
2
+ import { faFilter, faPlus, faXmark } from "@fortawesome/free-solid-svg-icons";
3
+ import { popup } from "@skeletonlabs/skeleton";
4
+ import { FilterOptionsEnum } from "../../models/Enums";
5
+ export let values;
6
+ export let id;
7
+ export let tableId;
8
+ export let toFilterableValueFn = void 0;
9
+ export let filters;
10
+ export let updateTable;
11
+ export let pageIndex;
12
+ let active = false;
13
+ const options = {
14
+ number: [
15
+ {
16
+ value: FilterOptionsEnum.e,
17
+ label: "Is equal to"
18
+ },
19
+ {
20
+ value: FilterOptionsEnum.gte,
21
+ label: "Is greater than or equal to"
22
+ },
23
+ {
24
+ value: FilterOptionsEnum.gt,
25
+ label: "Is greater than"
26
+ },
27
+ {
28
+ value: FilterOptionsEnum.lte,
29
+ label: "Is less than or equal to"
30
+ },
31
+ {
32
+ value: FilterOptionsEnum.lt,
33
+ label: "Is less than"
34
+ },
35
+ {
36
+ value: FilterOptionsEnum.ne,
37
+ label: "Is not equal to"
38
+ }
39
+ ],
40
+ string: [
41
+ {
42
+ value: FilterOptionsEnum.c,
43
+ label: "Contains"
44
+ },
45
+ {
46
+ value: FilterOptionsEnum.nc,
47
+ label: "Does not contain"
48
+ },
49
+ {
50
+ value: FilterOptionsEnum.e,
51
+ label: "Is equal to"
52
+ },
53
+ {
54
+ value: FilterOptionsEnum.ne,
55
+ label: "Is not equal to"
56
+ },
57
+ {
58
+ value: FilterOptionsEnum.sw,
59
+ label: "Starts with"
60
+ },
61
+ {
62
+ value: FilterOptionsEnum.ew,
63
+ label: "Ends with"
64
+ }
65
+ ],
66
+ date: [
67
+ {
68
+ value: FilterOptionsEnum.o,
69
+ label: "Is on"
70
+ },
71
+ {
72
+ value: FilterOptionsEnum.sf,
73
+ label: "Is starting from"
74
+ },
75
+ {
76
+ value: FilterOptionsEnum.a,
77
+ label: "Is after"
78
+ },
79
+ {
80
+ value: FilterOptionsEnum.u,
81
+ label: "Is until"
82
+ },
83
+ {
84
+ value: FilterOptionsEnum.b,
85
+ label: "Is before"
86
+ },
87
+ {
88
+ value: FilterOptionsEnum.no,
89
+ label: "Is not on"
90
+ }
91
+ ]
92
+ };
93
+ let dropdowns = [];
94
+ const popupId = `${tableId}-${id}`;
95
+ const popupFeatured = {
96
+ event: "click",
97
+ target: popupId,
98
+ placement: "bottom-start"
99
+ };
100
+ let type = "string";
101
+ let isDate = false;
102
+ $values.forEach((item) => {
103
+ if (item) {
104
+ type = typeof (toFilterableValueFn ? toFilterableValueFn(item) : item);
105
+ if (type === "object") {
106
+ if (item instanceof Date) {
107
+ isDate = true;
108
+ }
109
+ }
110
+ }
111
+ });
112
+ const optionChangeHandler = (e, index) => {
113
+ delete $filters[id][dropdowns[index].option];
114
+ $filters[id] = { ...$filters[id], [e.target.value]: dropdowns[index].value };
115
+ $filters = $filters;
116
+ dropdowns[index] = {
117
+ ...dropdowns[index],
118
+ option: e.target.value
119
+ };
120
+ };
121
+ const valueChangeHandler = (e, index) => {
122
+ dropdowns[index] = {
123
+ ...dropdowns[index],
124
+ value: type === "number" ? +e.target.value : type === "date" ? new Date(e.target.value) : e.target.value
125
+ };
126
+ $filters = {
127
+ ...$filters,
128
+ [id]: { ...$filters[id], [dropdowns[index].option]: dropdowns[index].value }
129
+ };
130
+ };
131
+ const addFilter = (option, value) => {
132
+ $filters = { ...$filters, [id]: { ...$filters[id], [option]: value } };
133
+ dropdowns = [
134
+ ...dropdowns,
135
+ {
136
+ option,
137
+ value: void 0
138
+ }
139
+ ];
140
+ };
141
+ const removeFilter = (option) => {
142
+ dropdowns = dropdowns.filter((dropdown) => dropdown.option !== option);
143
+ delete $filters[id][option];
144
+ $filters = $filters;
145
+ };
146
+ const clearFilters = () => {
147
+ dropdowns = [];
148
+ $filters[id] = {};
149
+ $pageIndex = 0;
150
+ updateTable().then(() => {
151
+ active = false;
152
+ });
153
+ };
154
+ const applyFilters = () => {
155
+ $pageIndex = 0;
156
+ updateTable().then(() => {
157
+ active = true;
158
+ });
159
+ };
160
+ $:
161
+ type = isDate ? "date" : type;
162
+ $:
163
+ remainingFilters = options[type].filter(
164
+ (option) => !Object.keys($filters[id]).includes(option.value)
165
+ );
166
+ $:
167
+ addFilter(options[type][0].value, void 0);
168
+ </script>
169
+
170
+ <form class="">
171
+ <button
172
+ class:variant-filled-primary={active}
173
+ class="btn w-max p-2"
174
+ type="button"
175
+ use:popup={popupFeatured}
176
+ id="{popupId}-button"
177
+ >
178
+ <Fa icon={faFilter} size="12" />
179
+ </button>
180
+
181
+ <div data-popup={`${popupId}`} id={popupId} class="z-50">
182
+ <div class="card p-3 grid gap-2 shadow-lg w-max bg-base-100">
183
+ <button
184
+ class="btn variant-filled-primary btn-sm"
185
+ type="button"
186
+ on:click|preventDefault={() => {
187
+ // Set the defaults when cleared
188
+ clearFilters();
189
+ addFilter(options[type][0].value, undefined);
190
+ active = false;
191
+ }}>Clear Filters</button
192
+ >
193
+
194
+ <label for="" class="label normal-case text-sm">Show rows with value that</label>
195
+ <div class="grid gap-2 overflow-auto">
196
+ {#each dropdowns as dropdown, index (index)}
197
+ <div class="grid gap-2 w-full">
198
+ <div class="flex gap-1 items-center">
199
+ <select
200
+ class="select border border-primary-500 text-sm p-1"
201
+ aria-label="Show rows with value that"
202
+ on:change={(e) => optionChangeHandler(e, index)}
203
+ bind:value={dropdown.option}
204
+ >
205
+ {#each options[type] as option (option)}
206
+ <option
207
+ value={option.value}
208
+ selected={dropdown.option === option.value}
209
+ disabled={Object.keys($filters[id]).includes(option.value) &&
210
+ dropdown.option !== option.value}>{option.label}</option
211
+ >
212
+ {/each}
213
+ </select>
214
+ {#if dropdowns.length > 1}
215
+ <div
216
+ class="btn variant-filled-warning btn-sm h-full"
217
+ on:click|preventDefault={() => removeFilter(dropdown.option)}
218
+ on:keydown|preventDefault={() => removeFilter(dropdown.option)}
219
+ >
220
+ <Fa icon={faXmark} />
221
+ </div>
222
+ {/if}
223
+ </div>
224
+
225
+ {#if type === 'number'}
226
+ <input
227
+ type="number"
228
+ class="input p-1 border border-primary-500"
229
+ on:input={(e) => valueChangeHandler(e, index)}
230
+ bind:value={dropdown.value}
231
+ />
232
+ {:else if type === 'string'}
233
+ <input
234
+ type="text"
235
+ class="input p-1 border border-primary-500"
236
+ on:input={(e) => valueChangeHandler(e, index)}
237
+ bind:value={dropdown.value}
238
+ />
239
+ {:else}
240
+ <input
241
+ type="date"
242
+ class="input p-1 border border-primary-500"
243
+ on:input={(e) => valueChangeHandler(e, index)}
244
+ bind:value={dropdown.value}
245
+ />
246
+ {/if}
247
+ </div>
248
+ {#if index !== dropdowns.length - 1 && dropdowns.length > 1}
249
+ <label for="" class="label normal-case">And</label>
250
+ {/if}
251
+ {/each}
252
+ </div>
253
+
254
+ {#if remainingFilters.length}
255
+ <div
256
+ class="btn variant-filled-secondary btn-sm cursor-pointer"
257
+ on:click|stopPropagation={() => {
258
+ addFilter(remainingFilters[0].value, undefined);
259
+ }}
260
+ on:keydown|stopPropagation={() => {
261
+ addFilter(remainingFilters[0].value, undefined);
262
+ }}
263
+ >
264
+ <div class="flex gap-1 items-center"><Fa icon={faPlus} />Add Filter</div>
265
+ </div>
266
+ {/if}
267
+ <button
268
+ class="btn variant-filled-primary btn-sm"
269
+ type="button"
270
+ on:click|preventDefault={applyFilters}>Apply</button
271
+ >
272
+ </div>
273
+ </div>
274
+ </form>
@@ -0,0 +1,22 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ values: any;
5
+ id: any;
6
+ tableId: any;
7
+ toFilterableValueFn?: ((value: any) => any) | undefined;
8
+ filters: any;
9
+ updateTable: any;
10
+ pageIndex: any;
11
+ };
12
+ events: {
13
+ [evt: string]: CustomEvent<any>;
14
+ };
15
+ slots: {};
16
+ };
17
+ export type TableFilterServerProps = typeof __propDef.props;
18
+ export type TableFilterServerEvents = typeof __propDef.events;
19
+ export type TableFilterServerSlots = typeof __propDef.slots;
20
+ export default class TableFilterServer extends SvelteComponentTyped<TableFilterServerProps, TableFilterServerEvents, TableFilterServerSlots> {
21
+ }
22
+ export {};