@bexis2/bexis2-core-ui 0.4.8 → 0.4.10

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 (57) hide show
  1. package/README.md +12 -0
  2. package/dist/components/CodeEditor/CodeEditor.svelte +1 -2
  3. package/dist/components/CodeEditor/CodeEditor.svelte.d.ts +8 -8
  4. package/dist/components/Facets/Facets.svelte +108 -0
  5. package/dist/components/Facets/Facets.svelte.d.ts +24 -0
  6. package/dist/components/Facets/ShowMore.svelte +75 -0
  7. package/dist/components/Facets/ShowMore.svelte.d.ts +21 -0
  8. package/dist/components/File/FileUploader.svelte +3 -6
  9. package/dist/components/File/FileUploader.svelte.d.ts +5 -5
  10. package/dist/components/Table/ColumnsMenu.svelte +33 -0
  11. package/dist/components/Table/ColumnsMenu.svelte.d.ts +21 -0
  12. package/dist/components/Table/Table.svelte +1 -3
  13. package/dist/components/Table/Table.svelte.d.ts +12 -1
  14. package/dist/components/Table/TableContent.svelte +49 -36
  15. package/dist/components/Table/TableFilter.svelte +20 -15
  16. package/dist/components/Table/TableFilterServer.svelte +10 -12
  17. package/dist/components/Table/TablePagination.svelte +35 -13
  18. package/dist/components/Table/TablePaginationServer.svelte +7 -13
  19. package/dist/components/Table/shared.d.ts +2 -19
  20. package/dist/components/form/Checkbox.svelte.d.ts +3 -3
  21. package/dist/components/form/CheckboxKvPList.svelte.d.ts +2 -2
  22. package/dist/components/form/CheckboxList.svelte.d.ts +1 -1
  23. package/dist/components/form/DateInput.svelte.d.ts +9 -9
  24. package/dist/components/form/InputContainer.svelte.d.ts +3 -3
  25. package/dist/components/form/NumberInput.svelte.d.ts +10 -10
  26. package/dist/components/form/TextArea.svelte.d.ts +10 -10
  27. package/dist/components/form/TextInput.svelte.d.ts +10 -10
  28. package/dist/components/page/Alert.svelte +1 -2
  29. package/dist/components/page/Alert.svelte.d.ts +4 -4
  30. package/dist/components/page/Docs.svelte.d.ts +1 -1
  31. package/dist/components/page/Footer.svelte +1 -2
  32. package/dist/components/page/Header.svelte +1 -2
  33. package/dist/components/page/HelpPopUp.svelte +4 -6
  34. package/dist/components/page/HelpPopUp.svelte.d.ts +1 -1
  35. package/dist/components/page/Notification.svelte +2 -4
  36. package/dist/components/page/Page.svelte.d.ts +8 -8
  37. package/dist/components/page/Spinner.svelte.d.ts +3 -3
  38. package/dist/components/page/TablePlaceholder.svelte.d.ts +2 -2
  39. package/dist/components/page/breadcrumb/Breadcrumb.svelte +5 -8
  40. package/dist/components/toggle/Toggle.svelte +7 -14
  41. package/dist/components/toggle/Toggle.svelte.d.ts +9 -8
  42. package/dist/models/Models.d.ts +14 -6
  43. package/dist/stores/apiStores.d.ts +0 -1
  44. package/dist/stores/pageStores.d.ts +0 -1
  45. package/package.json +114 -114
  46. package/src/lib/components/Facets/Facets.svelte +120 -0
  47. package/src/lib/components/Facets/ShowMore.svelte +87 -0
  48. package/src/lib/components/Table/ColumnsMenu.svelte +37 -0
  49. package/src/lib/components/Table/TableContent.svelte +167 -141
  50. package/src/lib/components/Table/TableFilter.svelte +17 -7
  51. package/src/lib/components/Table/TableFilterServer.svelte +6 -3
  52. package/src/lib/components/Table/TablePagination.svelte +33 -5
  53. package/src/lib/components/Table/TablePaginationServer.svelte +1 -1
  54. package/src/lib/models/Models.ts +18 -7
  55. /package/src/lib/components/{file → File}/FileIcon.svelte +0 -0
  56. /package/src/lib/components/{file → File}/FileInfo.svelte +0 -0
  57. /package/src/lib/components/{file → File}/FileUploader.svelte +0 -0
@@ -11,7 +11,8 @@
11
11
  addExpandedRows,
12
12
  addColumnFilters,
13
13
  addTableFilter,
14
- addDataExport
14
+ addDataExport,
15
+ addHiddenColumns
15
16
  } from 'svelte-headless-table/plugins';
16
17
  import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom';
17
18
  import { SlideToggle, storePopup } from '@skeletonlabs/skeleton';
@@ -24,6 +25,7 @@
24
25
  import TableFilterServer from './TableFilterServer.svelte';
25
26
  import TablePagination from './TablePagination.svelte';
26
27
  import TablePaginationServer from './TablePaginationServer.svelte';
28
+ import ColumnsMenu from './ColumnsMenu.svelte';
27
29
  import { columnFilter, searchFilter } from './filter';
28
30
  import {
29
31
  cellStyle,
@@ -51,19 +53,16 @@
51
53
  defaultPageSize = 10, // Default page size - number of rows to display per page
52
54
  toggle = false, // Whether to display the fitToScreen toggle
53
55
  search = true, // Whether to display the search input
54
- pageSizes = [5, 10, 15, 20], // Page sizes to display in the pagination component
56
+ pageSizes = [5, 10, 20, 50, 100], // Page sizes to display in the pagination component
55
57
  fitToScreen = true, // Whether to fit the table to the screen,
56
58
  exportable = false, // Whether to display the export button and enable export functionality
57
- serverSide = false, // Whether the table is client or server-side
58
- URL = '', // URL to fetch data from
59
- token = '', // Bearer token to authenticate the request
60
- sendModel = new Send(), // Model to send requests
61
- entityId = 0, // Entity ID to send with the request
62
- versionId = 0 // Version ID to send with the request,
59
+ server
63
60
  } = config;
64
61
 
65
62
  let searchValue = '';
66
63
  let isFetching = false;
64
+ const serverSide = server !== undefined;
65
+ const { baseUrl, sendModel, entityId, versionId } = server ?? {};
67
66
 
68
67
  const filters = writable<{
69
68
  [key: string]: { [key in FilterOptionsEnum]?: number | string | Date };
@@ -90,6 +89,7 @@
90
89
  fn: searchFilter,
91
90
  serverSide
92
91
  }),
92
+ hideColumns: addHiddenColumns(),
93
93
  sort: addSortBy({
94
94
  disableMultiSort: true,
95
95
  serverSide
@@ -121,137 +121,149 @@
121
121
  // Creating an array of all the keys
122
122
  const accessors: AccessorType[] = Object.keys(allCols) as AccessorType[];
123
123
 
124
+ // Filtering out the excluded columns
125
+ const unexcludedColumns = accessors.filter((accessor) => {
126
+ // Filtering only unexcluded columns
127
+ const key = accessor as string;
128
+ if (columns !== undefined && key in columns && columns[key].exclude === true) {
129
+ return false;
130
+ }
131
+ return true;
132
+ });
133
+
134
+ // To control the visibility of columns in menu
135
+ let shownColumns = unexcludedColumns.map((c) => {
136
+ const key = c as string;
137
+ const label = key.charAt(0).toUpperCase() + key.slice(1);
138
+ return {
139
+ id: c as string,
140
+ label: columns && columns[key] && columns[key].header ? columns[key].header : label,
141
+ visible: true
142
+ };
143
+ });
144
+
124
145
  // Configuring every table column with the provided options
125
146
  const tableColumns = [
126
- ...accessors
127
- .filter((accessor) => {
128
- // Filtering only unexcluded columns
129
- const key = accessor as string;
130
- if (columns !== undefined && key in columns && columns[key].exclude === true) {
131
- return false;
132
- }
133
- return true;
134
- })
135
- .map((accessor) => {
136
- const key = accessor as string;
137
- // Applying configuration options for configured columns
138
- if (columns !== undefined && key in columns) {
139
- const {
140
- header, // Custom header to display
141
- colFilterFn, // Custom column filter function
142
- colFilterComponent, // Custom column filter component
143
- instructions, // Custom instructions for the column cells (sorting, filtering, searching, rendering)
144
- disableFiltering = false, // Whether to disable filtering for the column
145
- disableSorting = false // Whether to disable sorting for the column
146
- } = columns[key];
147
-
148
- const { toSortableValueFn, toFilterableValueFn, toStringFn, renderComponent } =
149
- instructions ?? {};
150
-
151
- return table.column({
152
- // If header is not provided, use the key as the header
153
- header: header ?? key,
154
- accessor: accessor,
155
- // Render the cell with the provided component, or use the toStringFn if provided, or just use the value
156
- cell: ({ value, row }) => {
157
- return renderComponent
158
- ? createRender(renderComponent, { value, row, dispatchFn: actionDispatcher })
159
- : toStringFn
160
- ? toStringFn(value)
161
- : value;
147
+ ...unexcludedColumns.map((accessor) => {
148
+ const key = accessor as string;
149
+ // Applying configuration options for configured columns
150
+ if (columns !== undefined && key in columns) {
151
+ const {
152
+ header, // Custom header to display
153
+ colFilterFn, // Custom column filter function
154
+ colFilterComponent, // Custom column filter component
155
+ instructions, // Custom instructions for the column cells (sorting, filtering, searching, rendering)
156
+ disableFiltering = false, // Whether to disable filtering for the column
157
+ disableSorting = false // Whether to disable sorting for the column
158
+ } = columns[key];
159
+
160
+ const { toSortableValueFn, toFilterableValueFn, toStringFn, renderComponent } =
161
+ instructions ?? {};
162
+
163
+ return table.column({
164
+ // If header is not provided, use the key as the header
165
+ header: header ?? key,
166
+ accessor: accessor,
167
+ // Render the cell with the provided component, or use the toStringFn if provided, or just use the value
168
+ cell: ({ value, row }) => {
169
+ return renderComponent
170
+ ? createRender(renderComponent, { value, row, dispatchFn: actionDispatcher })
171
+ : toStringFn
172
+ ? toStringFn(value)
173
+ : value;
174
+ },
175
+ plugins: {
176
+ // Sorting config
177
+ sort: {
178
+ disable: disableSorting,
179
+ getSortValue: (row) => {
180
+ // If provided, use the custom sorting function toSortableValueFn(), or just use the value
181
+ return toSortableValueFn ? toSortableValueFn(row) : row;
182
+ }
162
183
  },
163
- plugins: {
164
- // Sorting config
165
- sort: {
166
- disable: disableSorting,
167
- getSortValue: (row) => {
168
- // If provided, use the custom sorting function toSortableValueFn(), or just use the value
169
- return toSortableValueFn ? toSortableValueFn(row) : row;
170
- }
171
- },
172
- colFilter: !disableFiltering
173
- ? {
174
- fn: ({ filterValue, value }) => {
175
- // If provided, use the custom filtering function toFilterableValueFn(), or just use the value
176
- const val = toFilterableValueFn ? toFilterableValueFn(value) : value;
177
- // If provided, use the custom filtering function colFilterFn(), or just use the default columnFilter()
178
- return colFilterFn
179
- ? colFilterFn({ filterValue, value: val })
180
- : columnFilter({ filterValue, value: val });
181
- },
182
- render: ({ filterValue, values, id }) => {
183
- filterValue.set($filters[key]);
184
- return serverSide
185
- ? createRender(TableFilterServer, {
186
- id,
187
- tableId,
188
- values,
189
- updateTable,
190
- pageIndex,
191
- toFilterableValueFn,
192
- filters,
193
- toStringFn
194
- })
195
- : createRender(colFilterComponent ?? TableFilter, {
196
- filterValue,
197
- id,
198
- tableId,
199
- values,
200
- toFilterableValueFn,
201
- filters,
202
- toStringFn,
203
- pageIndex
204
- });
205
- }
206
- }
207
- : undefined,
208
- tableFilter: {
209
- // Search filter config
210
- getFilterValue: (row) => {
211
- // If provided, use the custom toString function toStringFn(), or just use the value
212
- return toStringFn ? toStringFn(row) : row;
213
- }
184
+ colFilter: !disableFiltering
185
+ ? {
186
+ fn: ({ filterValue, value }) => {
187
+ // If provided, use the custom filtering function toFilterableValueFn(), or just use the value
188
+ const val = toFilterableValueFn ? toFilterableValueFn(value) : value;
189
+ // If provided, use the custom filtering function colFilterFn(), or just use the default columnFilter()
190
+ return colFilterFn
191
+ ? colFilterFn({ filterValue, value: val })
192
+ : columnFilter({ filterValue, value: val });
193
+ },
194
+ render: ({ filterValue, values, id }) => {
195
+ filterValue.set($filters[key]);
196
+ return serverSide
197
+ ? createRender(TableFilterServer, {
198
+ id,
199
+ tableId,
200
+ values,
201
+ updateTable,
202
+ pageIndex,
203
+ toFilterableValueFn,
204
+ filters,
205
+ toStringFn
206
+ })
207
+ : createRender(colFilterComponent ?? TableFilter, {
208
+ filterValue,
209
+ id,
210
+ tableId,
211
+ values,
212
+ toFilterableValueFn,
213
+ filters,
214
+ toStringFn,
215
+ pageIndex
216
+ });
217
+ }
218
+ }
219
+ : undefined,
220
+ tableFilter: {
221
+ // Search filter config
222
+ getFilterValue: (row) => {
223
+ // If provided, use the custom toString function toStringFn(), or just use the value
224
+ return toStringFn ? toStringFn(row) : row;
214
225
  }
215
226
  }
216
- });
217
- } else {
218
- return table.column({
219
- header: key,
220
- accessor: accessor,
221
- cell: ({ value }) => {
222
- // If null or undefined, return an empty string
223
- return value ? value : '';
224
- },
225
- plugins: {
226
- // Sorting enabled by default
227
- sort: {},
228
- // Filtering enabled by default
229
- colFilter: {
230
- fn: columnFilter,
231
- render: ({ filterValue, values, id }) => {
232
- return serverSide
233
- ? createRender(TableFilterServer, {
234
- id,
235
- tableId,
236
- values,
237
- updateTable,
238
- pageIndex,
239
- filters
240
- })
241
- : createRender(TableFilter, {
242
- filterValue,
243
- id,
244
- tableId,
245
- values,
246
- filters,
247
- pageIndex
248
- });
249
- }
227
+ }
228
+ });
229
+ } else {
230
+ return table.column({
231
+ header: key,
232
+ accessor: accessor,
233
+ cell: ({ value }) => {
234
+ // If null or undefined, return an empty string
235
+ return value ? value : '';
236
+ },
237
+ plugins: {
238
+ // Sorting enabled by default
239
+ sort: {},
240
+ // Filtering enabled by default
241
+ colFilter: {
242
+ fn: columnFilter,
243
+ render: ({ filterValue, values, id }) => {
244
+ return serverSide
245
+ ? createRender(TableFilterServer, {
246
+ id,
247
+ tableId,
248
+ values,
249
+ updateTable,
250
+ pageIndex,
251
+ filters
252
+ })
253
+ : createRender(TableFilter, {
254
+ filterValue,
255
+ id,
256
+ tableId,
257
+ values,
258
+ filters,
259
+ pageIndex
260
+ });
250
261
  }
251
262
  }
252
- });
253
- }
254
- })
263
+ }
264
+ });
265
+ }
266
+ })
255
267
  ];
256
268
 
257
269
  // If optionsComponent is provided, add a column for it at the end
@@ -286,22 +298,25 @@
286
298
  const { exportedData } = pluginStates.export;
287
299
  // Page configuration
288
300
  const { pageIndex, pageSize } = pluginStates.page;
301
+ // Column visibility configuration
302
+ const { hiddenColumnIds } = pluginStates.hideColumns;
289
303
 
290
304
  const updateTable = async () => {
305
+ if (!sendModel) throw new Error('Server-side configuration is missing');
306
+
291
307
  sendModel.limit = $pageSize;
292
308
  sendModel.offset = $pageSize * $pageIndex;
293
- sendModel.version = versionId;
294
- sendModel.id = entityId;
309
+ sendModel.version = versionId || -1;
310
+ sendModel.id = entityId || -1;
295
311
  sendModel.filter = normalizeFilters($filters);
296
312
 
297
313
  let fetchData;
298
314
 
299
315
  try {
300
316
  isFetching = true;
301
- fetchData = await fetch(URL, {
317
+ fetchData = await fetch(baseUrl || '', {
302
318
  headers: {
303
- 'Content-Type': 'application/json',
304
- Authorization: `Bearer ${token}`
319
+ 'Content-Type': 'application/json'
305
320
  },
306
321
  method: 'POST',
307
322
  body: JSON.stringify(sendModel)
@@ -346,6 +361,7 @@
346
361
  };
347
362
 
348
363
  const sortServer = (order: 'asc' | 'desc' | undefined, id: string) => {
364
+ if (!sendModel) throw new Error('Server-side configuration is missing');
349
365
  // Set parameter for sorting
350
366
  if (order === undefined) {
351
367
  sendModel.order = [];
@@ -362,16 +378,19 @@
362
378
  $: sortKeys = pluginStates.sort.sortKeys;
363
379
  $: serverSide && updateTable();
364
380
  $: serverSide && sortServer($sortKeys[0]?.order, $sortKeys[0]?.id);
381
+ $: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => col.id);
365
382
  </script>
366
383
 
367
384
  <div class="grid gap-2 overflow-auto" class:w-fit={!fitToScreen} class:w-full={fitToScreen}>
368
385
  {#if $data.length > 0 || (columns && Object.keys(columns).length > 0)}
369
386
  <div class="table-container">
370
387
  <!-- Enable the search filter if table is not empty -->
371
- {#if !serverSide && search}
388
+ {#if search}
372
389
  <form
373
390
  class="flex gap-2"
374
391
  on:submit|preventDefault={() => {
392
+ if (!sendModel) throw new Error('Server-side configuration is missing');
393
+
375
394
  sendModel.q = searchValue;
376
395
  $filterValue = searchValue;
377
396
  }}
@@ -388,6 +407,8 @@
388
407
  id="{tableId}-searchReset"
389
408
  class="absolute right-3 items-center"
390
409
  on:click|preventDefault={() => {
410
+ if (!sendModel) throw new Error('Server-side configuration is missing');
411
+
391
412
  searchValue = '';
392
413
  sendModel.q = '';
393
414
  $filterValue = '';
@@ -399,6 +420,8 @@
399
420
  id="{tableId}-searchSubmit"
400
421
  class="btn variant-filled-primary"
401
422
  on:click|preventDefault={() => {
423
+ if (!sendModel) throw new Error('Server-side configuration is missing');
424
+
402
425
  $filterValue = searchValue;
403
426
  sendModel.q = searchValue;
404
427
  }}>Search</button
@@ -439,6 +462,9 @@
439
462
  >Export as CSV</button
440
463
  >
441
464
  {/if}
465
+ {#if shownColumns.length > 0}
466
+ <ColumnsMenu bind:columns={shownColumns} {tableId} />
467
+ {/if}
442
468
  </div>
443
469
  </div>
444
470
 
@@ -491,9 +517,7 @@
491
517
  <!-- Adding column filter config -->
492
518
  {#if cell.isData()}
493
519
  {#if props.colFilter?.render}
494
- <div class="">
495
- <Render of={props.colFilter.render} />
496
- </div>
520
+ <Render of={props.colFilter.render} />
497
521
  {/if}
498
522
  {/if}
499
523
  </div>
@@ -564,3 +588,5 @@
564
588
  {/if}
565
589
  {/if}
566
590
  </div>
591
+
592
+ <div id="{tableId}-popups" />
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
- import Fa from 'svelte-fa';
2
+ import Fa from 'svelte-fa/src/fa.svelte';
3
+ import { onMount } from 'svelte';
3
4
  import { faFilter, faPlus, faXmark } from '@fortawesome/free-solid-svg-icons';
4
5
  import { popup } from '@skeletonlabs/skeleton';
5
6
  import type { PopupSettings } from '@skeletonlabs/skeleton';
@@ -22,6 +23,7 @@
22
23
  let dropdowns: {
23
24
  option: FilterOptionsEnum;
24
25
  value: string | number | Date | undefined;
26
+ formValue: string | number | undefined;
25
27
  }[] = [];
26
28
 
27
29
  // Check the type of the column
@@ -173,7 +175,8 @@
173
175
  const valueChangeHandler = (e, index) => {
174
176
  dropdowns[index] = {
175
177
  ...dropdowns[index],
176
- value: type === 'date' ? new Date(e.target.value) : e.target.value
178
+ value: type === 'date' ? new Date(e.target.value) : e.target.value,
179
+ formValue: e.target.value
177
180
  };
178
181
 
179
182
  $filters = {
@@ -195,7 +198,8 @@
195
198
  ...dropdowns,
196
199
  {
197
200
  option: option,
198
- value: undefined
201
+ value: undefined,
202
+ formValue: undefined
199
203
  }
200
204
  ];
201
205
  };
@@ -221,9 +225,15 @@
221
225
 
222
226
  // Start by adding the default filter
223
227
  $: addFilter(options[type][0].value, undefined);
228
+
229
+ onMount(() => {
230
+ const element = document.getElementById(popupId);
231
+ element?.parentElement?.removeChild(element);
232
+ element && document.getElementById(`${tableId}-popups`)?.appendChild(element);
233
+ });
224
234
  </script>
225
235
 
226
- <form class="">
236
+ <div id="parent-{popupId}">
227
237
  <button
228
238
  class:variant-filled-primary={active}
229
239
  class="btn w-max p-2"
@@ -234,7 +244,7 @@
234
244
  <Fa icon={faFilter} size="12" />
235
245
  </button>
236
246
 
237
- <div data-popup={`${popupId}`} id={popupId} class="z-50">
247
+ <div data-popup={popupId} id={popupId} class="">
238
248
  <div class="card p-3 grid gap-2 shadow-lg w-max bg-base-100">
239
249
  <button
240
250
  class="btn variant-filled-primary btn-sm"
@@ -292,7 +302,7 @@
292
302
  type="date"
293
303
  class="input p-1 border border-primary-500"
294
304
  on:input={(e) => valueChangeHandler(e, index)}
295
- bind:value={dropdown.value}
305
+ bind:value={dropdown.formValue}
296
306
  />
297
307
  {/if}
298
308
  </div>
@@ -326,4 +336,4 @@
326
336
  >
327
337
  </div>
328
338
  </div>
329
- </form>
339
+ </div>
@@ -22,6 +22,7 @@
22
22
  let dropdowns: {
23
23
  option: FilterOptionsEnum;
24
24
  value: string | number | Date | undefined;
25
+ formValue: string | number | undefined;
25
26
  }[] = [];
26
27
 
27
28
  // Check the type of the column
@@ -111,7 +112,7 @@
111
112
  {
112
113
  value: FilterOptionsEnum.b,
113
114
  label: 'Is before'
114
- },
115
+ }
115
116
  // TODO: 'Not on' filter should be fixed on the server side
116
117
  // {
117
118
  // value: FilterOptionsEnum.no,
@@ -159,7 +160,8 @@
159
160
  const valueChangeHandler = (e, index) => {
160
161
  dropdowns[index] = {
161
162
  ...dropdowns[index],
162
- value: type === 'date' ? new Date(e.target.value) : e.target.value
163
+ value: type === 'date' ? new Date(e.target.value) : e.target.value,
164
+ formValue: e.target.value
163
165
  };
164
166
 
165
167
  $filters = {
@@ -181,7 +183,8 @@
181
183
  ...dropdowns,
182
184
  {
183
185
  option: option,
184
- value: undefined
186
+ value: undefined,
187
+ formValue: undefined
185
188
  }
186
189
  ];
187
190
  };
@@ -4,8 +4,10 @@
4
4
  faAnglesRight,
5
5
  faAngleRight,
6
6
  faAnglesLeft,
7
- faAngleLeft
7
+ faAngleLeft,
8
+ faChevronDown
8
9
  } from '@fortawesome/free-solid-svg-icons';
10
+ import { ListBox, ListBoxItem, popup, type PopupSettings } from '@skeletonlabs/skeleton';
9
11
 
10
12
  export let pageConfig;
11
13
  export let pageSizes;
@@ -31,24 +33,50 @@
31
33
  }
32
34
  };
33
35
 
36
+ let pageSizeDropdownValue: string = $pageSize;
37
+
38
+ const pageSizePopup: PopupSettings = {
39
+ event: 'click',
40
+ target: `#${id}-pageSizeDropdown`,
41
+ placement: 'bottom',
42
+ closeQuery: '.listbox-item'
43
+ };
44
+
34
45
  $: goToFirstPageDisabled = !$pageIndex;
35
46
  $: goToLastPageDisabled = $pageIndex == $pageCount - 1;
36
47
  $: goToNextPageDisabled = !$hasNextPage;
37
48
  $: goToPreviousPageDisabled = !$hasPreviousPage;
49
+ $: $pageSize = pageSizeDropdownValue;
38
50
  </script>
39
51
 
40
- <div class="flex justify-between w-full items-stretch gap-10">
52
+ <div class="flex justify-between w-full items-stretch gap-10 z-50">
41
53
  <div class="flex justify-start">
42
- <select
54
+ <!-- <select
43
55
  name="pageSize"
44
56
  id="{id}-pageSize"
45
57
  class="select variant-filled-primary w-min font-bold"
46
58
  bind:value={$pageSize}
47
59
  >
48
60
  {#each pageSizes as size}
49
- <option value={size}>{size}</option>
61
+ <option value={size} class="">{size}</option>
50
62
  {/each}
51
- </select>
63
+ </select> -->
64
+
65
+ <button class="btn variant-filled-primary w-20 justify-between" use:popup={pageSizePopup}>
66
+ <span class="capitalize font-semibold">{pageSizeDropdownValue}</span>
67
+ <Fa icon={faChevronDown} size="xs" />
68
+ </button>
69
+
70
+ <div class="card w-20 shadow-xl py-2" data-popup={`#${id}-pageSizeDropdown`}>
71
+ <ListBox rounded="rounded-none">
72
+ {#each pageSizes as size}
73
+ <ListBoxItem bind:group={pageSizeDropdownValue} name="medium" value={size}
74
+ >{size}</ListBoxItem
75
+ >
76
+ {/each}
77
+ </ListBox>
78
+ <div class="arrow bg-surface-100-800-token" />
79
+ </div>
52
80
  </div>
53
81
  <div class="flex justify-center gap-1">
54
82
  <button
@@ -77,7 +77,7 @@
77
77
  bind:value={$pageSize}
78
78
  >
79
79
  {#each pageSizes as size}
80
- <option value={size}>{size}</option>
80
+ <option value={size} class="!bg-primary-700">{size}</option>
81
81
  {/each}
82
82
  </select>
83
83
  </div>
@@ -104,6 +104,14 @@ export interface Columns {
104
104
  [key: string]: Column;
105
105
  }
106
106
 
107
+ // Server config type for the table
108
+ export type ServerConfig = {
109
+ baseUrl?: string; // Base URL for server-side table
110
+ sendModel: Send; // Send model for server-side table
111
+ entityId?: number; // Entity ID for server-side table
112
+ versionId?: number; // Version ID for server-side table
113
+ };
114
+
107
115
  // Table config type
108
116
  export interface TableConfig<T> {
109
117
  id: string;
@@ -120,12 +128,7 @@ export interface TableConfig<T> {
120
128
  defaultPageSize?: number; // 10 by default
121
129
  optionsComponent?: typeof SvelteComponent;
122
130
 
123
- serverSide?: boolean; // false by default
124
- URL?: string; // Base URL for server-side table
125
- token?: string; // Authorization token for server-side table
126
- sendModel?: Send; // Send model for server-side table
127
- entityId?: number; // Entity ID for server-side table
128
- versionId?: number; // Version ID for server-side table
131
+ server?: ServerConfig;
129
132
  }
130
133
 
131
134
  // lists
@@ -188,6 +191,15 @@ export type Filter = {
188
191
  value: string | number | Date | boolean;
189
192
  };
190
193
 
194
+ export type FacetOption = {
195
+ value: string;
196
+ count?: number;
197
+ };
198
+
199
+ export type FacetGroup = {
200
+ [key: string]: FacetOption[];
201
+ };
202
+
191
203
  export class Send {
192
204
  id: number;
193
205
  limit: number;
@@ -222,7 +234,6 @@ export class Receive {
222
234
  }
223
235
  }
224
236
 
225
-
226
237
  export class errorType {
227
238
  statusText: string;
228
239
  status: number;