@bexis2/bexis2-core-ui 0.3.1 → 0.3.3

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 (90) hide show
  1. package/README.md +14 -1
  2. package/dist/TableView.svelte +1 -1
  3. package/dist/components/File/FileIcon.svelte +45 -45
  4. package/dist/components/File/FileInfo.svelte +13 -13
  5. package/dist/components/ListView.svelte +5 -5
  6. package/dist/components/Table/Table.svelte +165 -100
  7. package/dist/components/Table/TableFilter.svelte +1 -0
  8. package/dist/components/form/Checkbox.svelte +13 -13
  9. package/dist/components/form/CheckboxKvPList.svelte +16 -16
  10. package/dist/components/form/CheckboxList.svelte +10 -10
  11. package/dist/components/form/DateInput.svelte +14 -14
  12. package/dist/components/form/DropdownKvP.svelte +54 -54
  13. package/dist/components/form/NumberInput.svelte +15 -15
  14. package/dist/components/form/TextArea.svelte +14 -14
  15. package/dist/components/form/TextInput.svelte +15 -15
  16. package/dist/components/page/Alert.svelte +28 -28
  17. package/dist/components/page/BackToTop.svelte +30 -30
  18. package/dist/components/page/Docs.svelte +22 -22
  19. package/dist/components/page/ErrorMessage.svelte +8 -8
  20. package/dist/components/page/Footer.svelte +5 -5
  21. package/dist/components/page/Header.svelte +5 -5
  22. package/dist/components/page/HelpPopUp.svelte +30 -30
  23. package/dist/components/page/PageCaller.js +19 -19
  24. package/dist/components/page/Spinner.svelte +14 -14
  25. package/dist/components/page/menu/MenuDataCaller.js +10 -10
  26. package/dist/css/core.ui.postcss +17 -17
  27. package/dist/css/themes/theme-bexis2.css +96 -96
  28. package/dist/css/themes/theme-crimson.css +101 -101
  29. package/dist/css/themes/theme-gold-nouveau.css +140 -140
  30. package/dist/css/themes/theme-hamlindigo.css +112 -112
  31. package/dist/css/themes/theme-modern.css +127 -127
  32. package/dist/css/themes/theme-rocket.css +119 -119
  33. package/dist/css/themes/theme-sahara.css +128 -128
  34. package/dist/css/themes/theme-seafoam.css +122 -122
  35. package/dist/css/themes/theme-seasonal.css +115 -115
  36. package/dist/css/themes/theme-skeleton.css +118 -118
  37. package/dist/css/themes/theme-vintage.css +125 -125
  38. package/dist/models/Models.d.ts +2 -0
  39. package/dist/services/BaseCaller.js +16 -16
  40. package/dist/stores/pageStores.js +1 -1
  41. package/dist/themes/theme-bexis2.js +104 -91
  42. package/package.json +2 -2
  43. package/src/lib/TableView.svelte +1 -1
  44. package/src/lib/components/CodeEditor/CodeEditor.svelte +1 -1
  45. package/src/lib/components/ListView.svelte +11 -11
  46. package/src/lib/components/Table/Table.svelte +198 -125
  47. package/src/lib/components/Table/TableFilter.svelte +7 -3
  48. package/src/lib/components/Table/filter.ts +141 -141
  49. package/src/lib/components/file/FileIcon.svelte +45 -45
  50. package/src/lib/components/file/FileInfo.svelte +13 -13
  51. package/src/lib/components/form/Checkbox.svelte +24 -24
  52. package/src/lib/components/form/CheckboxKvPList.svelte +29 -29
  53. package/src/lib/components/form/CheckboxList.svelte +21 -21
  54. package/src/lib/components/form/DateInput.svelte +27 -27
  55. package/src/lib/components/form/DropdownKvP.svelte +54 -54
  56. package/src/lib/components/form/NumberInput.svelte +30 -30
  57. package/src/lib/components/form/TextArea.svelte +28 -28
  58. package/src/lib/components/form/TextInput.svelte +28 -28
  59. package/src/lib/components/page/Alert.svelte +41 -41
  60. package/src/lib/components/page/BackToTop.svelte +30 -30
  61. package/src/lib/components/page/Docs.svelte +46 -46
  62. package/src/lib/components/page/ErrorMessage.svelte +10 -10
  63. package/src/lib/components/page/Footer.svelte +18 -18
  64. package/src/lib/components/page/Header.svelte +18 -18
  65. package/src/lib/components/page/HelpPopUp.svelte +72 -72
  66. package/src/lib/components/page/Notification.svelte +42 -47
  67. package/src/lib/components/page/Page.svelte +0 -1
  68. package/src/lib/components/page/PageCaller.js +19 -19
  69. package/src/lib/components/page/Spinner.svelte +20 -20
  70. package/src/lib/components/page/menu/MenuDataCaller.js +10 -10
  71. package/src/lib/css/core.ui.postcss +17 -17
  72. package/src/lib/css/themes/theme-bexis2.css +96 -96
  73. package/src/lib/css/themes/theme-crimson.css +101 -101
  74. package/src/lib/css/themes/theme-gold-nouveau.css +140 -140
  75. package/src/lib/css/themes/theme-hamlindigo.css +112 -112
  76. package/src/lib/css/themes/theme-modern.css +127 -127
  77. package/src/lib/css/themes/theme-rocket.css +119 -119
  78. package/src/lib/css/themes/theme-sahara.css +128 -128
  79. package/src/lib/css/themes/theme-seafoam.css +122 -122
  80. package/src/lib/css/themes/theme-seasonal.css +115 -115
  81. package/src/lib/css/themes/theme-skeleton.css +118 -118
  82. package/src/lib/css/themes/theme-vintage.css +125 -125
  83. package/src/lib/index.ts +1 -1
  84. package/src/lib/models/Models.ts +6 -4
  85. package/src/lib/models/Page.ts +40 -40
  86. package/src/lib/services/Api.ts +55 -55
  87. package/src/lib/services/BaseCaller.js +16 -16
  88. package/src/lib/stores/apiStores.ts +34 -34
  89. package/src/lib/stores/pageStores.ts +3 -3
  90. package/src/lib/themes/theme-bexis2.ts +107 -96
@@ -6,7 +6,8 @@
6
6
  addPagination,
7
7
  addExpandedRows,
8
8
  addColumnFilters,
9
- addTableFilter
9
+ addTableFilter,
10
+ addDataExport
10
11
  } from 'svelte-headless-table/plugins';
11
12
  import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom';
12
13
  import { SlideToggle, storePopup } from '@skeletonlabs/skeleton';
@@ -20,24 +21,30 @@
20
21
 
21
22
  export let config: TableConfig<any>;
22
23
 
24
+ // Destructuring the config object and setting default values
23
25
  let {
24
- id: tableId,
25
- data,
26
- columns,
27
- resizable = 'none',
28
- height = null,
29
- optionsComponent,
30
- defaultPageSize = 10,
31
- toggle = false,
32
- pageSizes = [5, 10, 15, 20],
33
- fitToScreen = true
26
+ id: tableId, // Unique table ID
27
+ data, // Data store
28
+ columns, // Column configuration
29
+ resizable = 'none', // Resizability config
30
+ height = null, // Table height
31
+ rowHeight = null, // Row height
32
+ optionsComponent, // Custom component to render in the last column
33
+ defaultPageSize = 10, // Default page size - number of rows to display per page
34
+ toggle = false, // Whether to display the fitToScreen toggle
35
+ pageSizes = [5, 10, 15, 20], // Page sizes to display in the pagination component
36
+ fitToScreen = true, // Whether to fit the table to the screen,
37
+ exportable = false // Whether to display the export button and enable export functionality
34
38
  } = config;
35
39
 
40
+ // Creatign a type to access keys of the objects in the data store
36
41
  type AccessorType = keyof (typeof $data)[number];
37
42
 
43
+ // Creating a dispatcher to dispatch actions to the parent component
38
44
  const dispatch = createEventDispatcher();
39
45
  const actionDispatcher = (obj) => dispatch('action', obj);
40
46
 
47
+ // Initializing the table
41
48
  const table = createTable(data, {
42
49
  colFilter: addColumnFilters(),
43
50
  tableFilter: addTableFilter({
@@ -45,11 +52,13 @@
45
52
  }),
46
53
  sort: addSortBy({ disableMultiSort: true }),
47
54
  page: addPagination({ initialPageSize: defaultPageSize }),
48
- expand: addExpandedRows()
55
+ expand: addExpandedRows(),
56
+ export: addDataExport({ format: 'csv' })
49
57
  });
50
58
 
59
+ // A variable to hold all the keys
51
60
  const allCols: { [key: string]: any } = {};
52
-
61
+ // Iterating over each item to get all the possible keys
53
62
  $data.forEach((item) => {
54
63
  Object.keys(item).forEach((key) => {
55
64
  if (!allCols[key]) {
@@ -57,12 +66,13 @@
57
66
  }
58
67
  });
59
68
  });
60
-
69
+ // Creating an array of all the keys
61
70
  const accessors: AccessorType[] = Object.keys(allCols) as AccessorType[];
62
-
71
+ // Configuring every table column with the provided options
63
72
  const tableColumns = [
64
73
  ...accessors
65
74
  .filter((accessor) => {
75
+ // Filtering only unexcluded columns
66
76
  const key = accessor as string;
67
77
  if (columns !== undefined && key in columns && columns[key].exclude === true) {
68
78
  return false;
@@ -71,22 +81,25 @@
71
81
  })
72
82
  .map((accessor) => {
73
83
  const key = accessor as string;
84
+ // Applying configuration options for configured columns
74
85
  if (columns !== undefined && key in columns) {
75
86
  const {
76
- header,
77
- colFilterFn,
78
- colFilterComponent,
79
- instructions,
80
- disableFiltering = false,
81
- disableSorting = false
87
+ header, // Custom header to display
88
+ colFilterFn, // Custom column filter function
89
+ colFilterComponent, // Custom column filter component
90
+ instructions, // Custom instructions for the column cells (sorting, filtering, searching, rendering)
91
+ disableFiltering = false, // Whether to disable filtering for the column
92
+ disableSorting = false // Whether to disable sorting for the column
82
93
  } = columns[key];
83
94
 
84
95
  const { toSortableValueFn, toFilterableValueFn, toStringFn, renderComponent } =
85
96
  instructions ?? {};
86
97
 
87
98
  return table.column({
99
+ // If header is not provided, use the key as the header
88
100
  header: header ?? key,
89
101
  accessor: accessor,
102
+ // Render the cell with the provided component, or use the toStringFn if provided, or just use the value
90
103
  cell: ({ value, row }) => {
91
104
  return renderComponent
92
105
  ? createRender(renderComponent, { value, row })
@@ -95,23 +108,27 @@
95
108
  : value;
96
109
  },
97
110
  plugins: {
111
+ // Sorting config
98
112
  sort: {
99
113
  disable: disableSorting,
100
114
  invert: true,
101
115
  getSortValue: (row) => {
116
+ // If provided, use the custom sorting function toSortableValueFn(), or just use the value
102
117
  return toSortableValueFn ? toSortableValueFn(row) : row;
103
118
  }
104
119
  },
105
120
  colFilter: !disableFiltering
106
121
  ? {
107
122
  fn: ({ filterValue, value }) => {
123
+ // If provided, use the custom filtering function toFilterableValueFn(), or just use the value
108
124
  const val = toFilterableValueFn ? toFilterableValueFn(value) : value;
109
-
125
+ // If provided, use the custom filtering function colFilterFn(), or just use the default columnFilter()
110
126
  return colFilterFn
111
127
  ? colFilterFn({ filterValue, value: val })
112
128
  : columnFilter({ filterValue, value: val });
113
129
  },
114
130
  render: ({ filterValue, values, id }) => {
131
+ // If provided, use the custom filter component, or use the default TableFilter component
115
132
  return createRender(colFilterComponent ?? TableFilter, {
116
133
  filterValue,
117
134
  id,
@@ -123,23 +140,29 @@
123
140
  }
124
141
  : undefined,
125
142
  tableFilter: {
143
+ // Search filter config
126
144
  getFilterValue: (row) => {
145
+ // If provided, use the custom toString function toStringFn(), or just use the value
127
146
  return toStringFn ? toStringFn(row) : row;
128
147
  }
129
148
  }
130
149
  }
131
150
  });
132
151
  } else {
152
+ // Default configuration for unconfigured columns
133
153
  return table.column({
134
154
  header: key,
135
155
  accessor: accessor,
136
156
  cell: ({ value }) => {
157
+ // If null or undefined, return an empty string
137
158
  return value ? value : '';
138
159
  },
139
160
  plugins: {
161
+ // Sorting enabled by default
140
162
  sort: {
141
163
  invert: true
142
164
  },
165
+ // Filtering enabled by default
143
166
  colFilter: {
144
167
  fn: columnFilter,
145
168
  render: ({ filterValue, values, id }) =>
@@ -156,11 +179,17 @@
156
179
  })
157
180
  ];
158
181
 
182
+ // If optionsComponent is provided, add a column for it at the end
159
183
  if (optionsComponent !== undefined) {
160
184
  tableColumns.push(
161
185
  table.display({
162
186
  id: 'optionsColumn',
163
187
  header: '',
188
+ plugins: {
189
+ export: {
190
+ exclude: true
191
+ }
192
+ },
164
193
  cell: ({ row }, _) => {
165
194
  return createRender(optionsComponent!, {
166
195
  row: row.isData() ? row.original : null,
@@ -171,53 +200,63 @@
171
200
  );
172
201
  }
173
202
 
203
+ // Creating the table columns
174
204
  const createdTableColumns = table.createColumns(tableColumns);
175
-
205
+ // Creating the table view model
176
206
  const { headerRows, pageRows, tableAttrs, tableBodyAttrs, pluginStates } =
177
207
  table.createViewModel(createdTableColumns);
208
+ // Extracting filterValue to bind it for the search input and search immediately on input
178
209
  const { filterValue } = pluginStates.tableFilter;
210
+ // CSV content to be exported. If unexportable, then null
211
+ const { exportedData } = pluginStates.export;
179
212
 
213
+ // Function to determine minWidth for a column to simplify the logic in the HTML
180
214
  const minWidth = (id: string) => {
181
215
  if (columns && id in columns) {
182
216
  return columns[id].minWidth ?? 0;
183
217
  }
184
218
  return 0;
185
219
  };
186
-
220
+ // Function to determine fixedWidth for a column to simplify the logic in the HTML
187
221
  const fixedWidth = (id: string) => {
188
222
  if (columns && id in columns) {
189
223
  return columns[id].fixedWidth ?? 0;
190
224
  }
191
225
  return 0;
192
226
  };
193
-
227
+ // Function to create custom styles for the columns to simplify the logic in the HTML
194
228
  const cellStyle = (id: string) => {
195
229
  const minW = minWidth(id);
196
230
  const fixedW = fixedWidth(id);
197
231
  const styles: string[] = [];
198
232
 
233
+ // If minWidth is provided, add to styles
199
234
  minW && styles.push(`min-width: ${minW}px`);
235
+ // If fixedWidth is provided, add to styles
200
236
  fixedW && styles.push(`width: ${fixedW}px`);
201
-
237
+ // Create and return styles separated by ';'
202
238
  return styles.join(';');
203
239
  };
204
240
 
241
+ // Resetting the resized columns and/or rows
205
242
  const resetResize = () => {
243
+ // Run only if resizable is not none
206
244
  if (resizable === 'columns' || resizable === 'both') {
207
245
  $headerRows.forEach((row) => {
208
246
  row.cells.forEach((cell) => {
209
247
  const minW = minWidth(cell.id);
210
248
  const fixedW = fixedWidth(cell.id);
211
-
249
+ // If a fixedWidth is provided for a column, then reset the width to that value
212
250
  fixedW &&
213
251
  document
214
252
  .getElementById(`th-${tableId}-${cell.id}`)
215
253
  ?.style.setProperty('width', `${fixedW}px`);
254
+ // If a minWidth is provided for a column, then reset the width to that value
216
255
  minW &&
217
256
  document
218
257
  .getElementById(`th-${tableId}-${cell.id}`)
219
258
  ?.style.setProperty('min-width', `${minW}px`);
220
-
259
+ // If neither minWidth nor fixedWidth provided for a column, then reset the width to auto
221
260
  !minW &&
222
261
  !fixedW &&
223
262
  document.getElementById(`th-${tableId}-${cell.id}`)?.style.setProperty('width', 'auto');
@@ -228,6 +267,7 @@
228
267
  if (resizable === 'rows' || resizable === 'both') {
229
268
  $pageRows.forEach((row) => {
230
269
  row.cells.forEach((cell) => {
270
+ // Reset all row heights to auto
231
271
  document
232
272
  .getElementById(`${tableId}-${cell.id}-${row.id}`)
233
273
  ?.style.setProperty('height', 'auto');
@@ -235,10 +275,22 @@
235
275
  });
236
276
  }
237
277
  };
278
+
279
+ const exportAsCsv = () => {
280
+ // Creating a hidden anchor element to download the CSV file
281
+ const anchor = document.createElement('a');
282
+ anchor.style.display = 'none';
283
+ anchor.href = `data:text/csv;charset=utf-8,${encodeURIComponent($exportedData)}`;
284
+ anchor.download = `${tableId}.csv`;
285
+ document.body.appendChild(anchor);
286
+ anchor.click();
287
+ document.body.removeChild(anchor);
288
+ };
238
289
  </script>
239
290
 
240
291
  <div class="grid gap-2 overflow-auto" class:w-fit={!fitToScreen} class:w-full={fitToScreen}>
241
292
  <div class="table-container">
293
+ <!-- Enable the search filter if table is not empty -->
242
294
  {#if $data.length > 0}
243
295
  <input
244
296
  class="input p-2 border border-primary-500"
@@ -247,123 +299,144 @@
247
299
  placeholder="Search rows..."
248
300
  id="{tableId}-search"
249
301
  />
250
- {/if}
251
-
252
- <div class="flex justify-between items-center py-2 w-full">
253
- <div>
254
- {#if toggle}
255
- <SlideToggle
256
- name="slider-label"
257
- active="bg-primary-500"
258
- size="sm"
259
- checked={fitToScreen}
260
- id="{tableId}-toggle"
261
- on:change={() => (fitToScreen = !fitToScreen)}>Fit to screen</SlideToggle
262
- >
263
- {/if}
264
- </div>
265
- <div>
266
- {#if resizable !== 'none'}
267
- <button
268
- type="button"
269
- class="btn btn-sm variant-filled-primary rounded-full order-last"
270
- on:click|preventDefault={resetResize}>Reset sizing</button
271
- >
272
- {/if}
302
+ <div class="flex justify-between items-center py-2 w-full">
303
+ <div>
304
+ <!-- Enable the fitToScreen toggle if toggle === true -->
305
+ {#if toggle}
306
+ <SlideToggle
307
+ name="slider-label"
308
+ active="bg-primary-500"
309
+ size="sm"
310
+ checked={fitToScreen}
311
+ id="{tableId}-toggle"
312
+ on:change={() => (fitToScreen = !fitToScreen)}>Fit to screen</SlideToggle
313
+ >
314
+ {/if}
315
+ </div>
316
+ <div class="flex gap-2">
317
+ <!-- Enable the resetResize button if resizable !== 'none' -->
318
+ {#if resizable !== 'none'}
319
+ <button
320
+ type="button"
321
+ class="btn btn-sm variant-filled-primary rounded-full order-last"
322
+ on:click|preventDefault={resetResize}>Reset sizing</button
323
+ >
324
+ {/if}
325
+ {#if exportable}
326
+ <button
327
+ type="button"
328
+ class="btn btn-sm variant-filled-primary rounded-full order-last"
329
+ on:click|preventDefault={exportAsCsv}>Export as CSV</button
330
+ >
331
+ {/if}
332
+ </div>
273
333
  </div>
274
- </div>
334
+ {/if}
275
335
 
276
336
  <div class="overflow-auto" style="height: {height}px">
277
337
  <table
278
338
  {...$tableAttrs}
279
- class="table table-auto table-compact bg-tertiary-500/30 overflow-clip"
339
+ class="table table-auto table-compact bg-tertiary-500/30 dark:bg-tertiary-900/10 overflow-clip"
280
340
  id="{tableId}-table"
281
341
  >
342
+ <!-- If table height is provided, making the top row sticky -->
282
343
  <thead class=" {height != null ? `sticky top-0` : ''}">
283
- {#each $headerRows as headerRow (headerRow.id)}
284
- <Subscribe
285
- rowAttrs={headerRow.attrs()}
286
- let:rowAttrs
287
- rowProps={headerRow.props()}
288
- let:rowProps
289
- >
290
- <tr {...rowAttrs} class="bg-primary-300 items-stretch">
291
- {#each headerRow.cells as cell (cell.id)}
292
- <Subscribe attrs={cell.attrs()} props={cell.props()} let:props let:attrs>
293
- <th
294
- scope="col"
295
- class="!p-2 overflow-auto"
296
- class:resize-x={(resizable === 'columns' || resizable === 'both') &&
297
- !fixedWidth(cell.id)}
298
- {...attrs}
299
- id="th-{tableId}-{cell.id}"
300
- style={cellStyle(cell.id)}
301
- >
302
- <div class="flex justify-between items-center">
303
- <div class="flex gap-1 whitespace-pre-wrap">
304
- <span
305
- class:underline={props.sort.order}
306
- class:normal-case={cell.id !== cell.label}
307
- class:cursor-pointer={!props.sort.disabled}
308
- on:click={props.sort.toggle}
309
- on:keydown={props.sort.toggle}
310
- >
311
- {cell.render()}
312
- </span>
313
- <div class="w-2">
314
- {#if props.sort.order === 'asc'}
315
-
316
- {:else if props.sort.order === 'desc'}
317
-
318
- {/if}
319
- </div>
320
- </div>
321
- {#if cell.isData()}
322
- {#if props.colFilter?.render}
323
- <div class="">
324
- <Render of={props.colFilter.render} />
344
+ {#if $data.length > 0}
345
+ {#each $headerRows as headerRow (headerRow.id)}
346
+ <Subscribe
347
+ rowAttrs={headerRow.attrs()}
348
+ let:rowAttrs
349
+ rowProps={headerRow.props()}
350
+ let:rowProps
351
+ >
352
+ <tr {...rowAttrs} class="bg-primary-300 dark:bg-primary-500 items-stretch">
353
+ {#each headerRow.cells as cell (cell.id)}
354
+ <Subscribe attrs={cell.attrs()} props={cell.props()} let:props let:attrs>
355
+ <th
356
+ scope="col"
357
+ class="!p-2 overflow-auto"
358
+ class:resize-x={(resizable === 'columns' || resizable === 'both') &&
359
+ !fixedWidth(cell.id)}
360
+ {...attrs}
361
+ id="th-{tableId}-{cell.id}"
362
+ style={cellStyle(cell.id)}
363
+ >
364
+ <div class="flex justify-between items-center">
365
+ <div class="flex gap-1 whitespace-pre-wrap">
366
+ <!-- Adding sorting config and styling -->
367
+ <span
368
+ class:underline={props.sort.order}
369
+ class:normal-case={cell.id !== cell.label}
370
+ class:cursor-pointer={!props.sort.disabled}
371
+ on:click={props.sort.toggle}
372
+ on:keydown={props.sort.toggle}
373
+ >
374
+ {cell.render()}
375
+ </span>
376
+ <div class="w-2">
377
+ {#if props.sort.order === 'asc'}
378
+
379
+ {:else if props.sort.order === 'desc'}
380
+
381
+ {/if}
325
382
  </div>
383
+ </div>
384
+ <!-- Adding column filter config -->
385
+ {#if cell.isData()}
386
+ {#if props.colFilter?.render}
387
+ <div class="">
388
+ <Render of={props.colFilter.render} />
389
+ </div>
390
+ {/if}
326
391
  {/if}
327
- {/if}
328
- </div>
329
- </th>
330
- </Subscribe>
331
- {/each}
332
- </tr>
333
- </Subscribe>
392
+ </div>
393
+ </th>
394
+ </Subscribe>
395
+ {/each}
396
+ </tr>
397
+ </Subscribe>
398
+ {/each}
334
399
  {:else}
400
+ <!-- Table is empty -->
335
401
  <p class="items-center justify-center flex w-full p-10 italic">Nothing to show here.</p>
336
- {/each}
402
+ {/if}
337
403
  </thead>
338
404
 
339
405
  <tbody class="overflow-auto" {...$tableBodyAttrs}>
340
- {#each $pageRows as row (row.id)}
341
- <Subscribe rowAttrs={row.attrs()} let:rowAttrs>
342
- <tr {...rowAttrs} id="{tableId}-row-{row.id}" class="">
343
- {#each row.cells as cell, index (cell?.id)}
344
- <Subscribe attrs={cell.attrs()} let:attrs>
345
- <td
346
- {...attrs}
347
- class="!p-2 overflow-auto {index === 0 &&
348
- (resizable === 'rows' || resizable === 'both')
349
- ? 'resize-y'
350
- : ''}"
351
- id="{tableId}-{cell.id}-{row.id}"
352
- >
353
- <div class="flex items-center h-max overflow-x-auto">
354
- <Render of={cell.render()} />
355
- </div>
356
- </td>
357
- </Subscribe>
358
- {/each}
359
- </tr>
360
- </Subscribe>
361
- {/each}
406
+ {#if $data.length > 0}
407
+ {#each $pageRows as row (row.id)}
408
+ <Subscribe rowAttrs={row.attrs()} let:rowAttrs>
409
+ <tr {...rowAttrs} id="{tableId}-row-{row.id}" class="">
410
+ {#each row.cells as cell, index (cell?.id)}
411
+ <Subscribe attrs={cell.attrs()} let:attrs>
412
+ <td
413
+ {...attrs}
414
+ class="!p-2 overflow-auto {index === 0 &&
415
+ (resizable === 'rows' || resizable === 'both')
416
+ ? 'resize-y'
417
+ : ''}"
418
+ id="{tableId}-{cell.id}-{row.id}"
419
+ >
420
+ <!-- Adding config for initial rowHeight, if provided -->
421
+ <div
422
+ class="flex items-center"
423
+ style="height: {rowHeight ? `${rowHeight}px` : 'auto'};"
424
+ >
425
+ <div class="grow h-full"><Render of={cell.render()} /></div>
426
+ </div>
427
+ </td>
428
+ </Subscribe>
429
+ {/each}
430
+ </tr>
431
+ </Subscribe>
432
+ {/each}
433
+ {/if}
362
434
  </tbody>
363
435
  </table>
364
436
  </div>
365
437
  </div>
366
438
  {#if $data.length > 0}
439
+ <!-- Adding pagination, if table is not empty -->
367
440
  <TablePagination pageConfig={pluginStates.page} {pageSizes} id={tableId} />
368
441
  {/if}
369
442
  </div>
@@ -14,8 +14,10 @@
14
14
  let firstValue;
15
15
  let secondOption;
16
16
  let secondValue;
17
+ // If the filter is applied and the displayed values are filtered
17
18
  let active = false;
18
19
 
20
+ // Options for different types of values
19
21
  const options = {
20
22
  number: [
21
23
  {
@@ -97,8 +99,9 @@
97
99
  ]
98
100
  };
99
101
 
102
+ // Unique ID for the column filter popup
100
103
  const popupId = `${tableId}-${id}`;
101
-
104
+ // Popup config
102
105
  const popupFeatured: PopupSettings = {
103
106
  event: 'click',
104
107
  target: popupId,
@@ -107,7 +110,7 @@
107
110
 
108
111
  let type: string = 'string';
109
112
  let isDate = false;
110
-
113
+ // Check the type of the column
111
114
  $values.forEach((item) => {
112
115
  if (item) {
113
116
  type = typeof (toFilterableValueFn ? toFilterableValueFn(item) : item);
@@ -119,7 +122,7 @@
119
122
  }
120
123
  }
121
124
  });
122
-
125
+ // Determine if the type is date
123
126
  type = isDate ? 'date' : type;
124
127
  </script>
125
128
 
@@ -140,6 +143,7 @@
140
143
  class="btn variant-filled-primary btn-sm"
141
144
  type="button"
142
145
  on:click|preventDefault={() => {
146
+ // Set the defaults when cleared
143
147
  firstOption = 'isequal';
144
148
  firstValue = undefined;
145
149
  secondOption = 'isequal';