@bexis2/bexis2-core-ui 0.4.22 → 0.4.24
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 +16 -0
- package/dist/components/Facets/Facets.svelte +13 -9
- package/dist/components/Table/ColumnsMenu.svelte +35 -9
- package/dist/components/Table/TableContent.svelte +146 -87
- package/dist/components/Table/TableContent.svelte.d.ts +0 -1
- package/dist/components/Table/TablePagination.svelte +15 -7
- package/dist/components/Table/TablePagination.svelte.d.ts +2 -0
- package/dist/components/Table/TablePaginationServer.svelte +11 -9
- package/dist/components/Table/TablePaginationServer.svelte.d.ts +1 -0
- package/dist/components/Table/utils.d.ts +34 -0
- package/dist/components/Table/{shared.js → utils.js} +134 -0
- package/dist/components/form/MultiSelect.svelte +1 -1
- package/dist/models/Models.d.ts +2 -0
- package/package.json +1 -1
- package/src/lib/components/Facets/Facets.svelte +13 -9
- package/src/lib/components/Table/ColumnsMenu.svelte +36 -8
- package/src/lib/components/Table/TableContent.svelte +166 -97
- package/src/lib/components/Table/TablePagination.svelte +17 -7
- package/src/lib/components/Table/TablePaginationServer.svelte +16 -9
- package/src/lib/components/Table/utils.ts +373 -0
- package/src/lib/components/form/MultiSelect.svelte +1 -1
- package/src/lib/models/Models.ts +2 -0
- package/dist/components/Table/shared.d.ts +0 -14
- package/src/lib/components/Table/shared.ts +0 -186
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { createEventDispatcher } from 'svelte';
|
|
2
|
+
import { afterUpdate, createEventDispatcher, onDestroy } from 'svelte';
|
|
3
3
|
import { readable, writable } from 'svelte/store';
|
|
4
4
|
|
|
5
5
|
import Fa from 'svelte-fa';
|
|
6
|
-
import { faXmark } from '@fortawesome/free-solid-svg-icons';
|
|
6
|
+
import { faCompress, faDownload, faXmark } from '@fortawesome/free-solid-svg-icons';
|
|
7
7
|
import { createTable, Subscribe, Render, createRender } from 'svelte-headless-table';
|
|
8
8
|
import {
|
|
9
9
|
addSortBy,
|
|
@@ -26,16 +26,9 @@
|
|
|
26
26
|
import TablePagination from './TablePagination.svelte';
|
|
27
27
|
import TablePaginationServer from './TablePaginationServer.svelte';
|
|
28
28
|
import ColumnsMenu from './ColumnsMenu.svelte';
|
|
29
|
+
import * as utils from './utils';
|
|
29
30
|
import { columnFilter, searchFilter } from './filter';
|
|
30
|
-
import {
|
|
31
|
-
cellStyle,
|
|
32
|
-
exportAsCsv,
|
|
33
|
-
fixedWidth,
|
|
34
|
-
normalizeFilters,
|
|
35
|
-
resetResize,
|
|
36
|
-
convertServerColumns
|
|
37
|
-
} from './shared';
|
|
38
|
-
import { Receive, Send } from '$models/Models';
|
|
31
|
+
import { Send } from '$models/Models';
|
|
39
32
|
import type { TableConfig } from '$models/Models';
|
|
40
33
|
import type { FilterOptionsEnum } from '$models/Enums';
|
|
41
34
|
|
|
@@ -46,6 +39,7 @@
|
|
|
46
39
|
id: tableId, // Unique table ID
|
|
47
40
|
data, // Data store
|
|
48
41
|
columns, // Column configuration
|
|
42
|
+
showColumnsMenu = false, // Whether to display the columns menu
|
|
49
43
|
resizable = 'none', // Resizability config
|
|
50
44
|
height = null, // Table height
|
|
51
45
|
rowHeight = null, // Row height
|
|
@@ -54,6 +48,7 @@
|
|
|
54
48
|
toggle = false, // Whether to display the fitToScreen toggle
|
|
55
49
|
search = true, // Whether to display the search input
|
|
56
50
|
pageSizes = [5, 10, 20, 50, 100], // Page sizes to display in the pagination component
|
|
51
|
+
pageIndexStringType = 'pages', // pages by default
|
|
57
52
|
fitToScreen = true, // Whether to fit the table to the screen,
|
|
58
53
|
exportable = false, // Whether to display the export button and enable export functionality
|
|
59
54
|
server
|
|
@@ -61,8 +56,10 @@
|
|
|
61
56
|
|
|
62
57
|
let searchValue = '';
|
|
63
58
|
let isFetching = false;
|
|
59
|
+
let tableRef: HTMLTableElement;
|
|
60
|
+
|
|
64
61
|
const serverSide = server !== undefined;
|
|
65
|
-
const {
|
|
62
|
+
const { sendModel = new Send() } = server ?? {};
|
|
66
63
|
|
|
67
64
|
const filters = writable<{
|
|
68
65
|
[key: string]: { [key in FilterOptionsEnum]?: number | string | Date };
|
|
@@ -75,7 +72,12 @@
|
|
|
75
72
|
const dispatch = createEventDispatcher();
|
|
76
73
|
const actionDispatcher = (obj) => dispatch('action', obj);
|
|
77
74
|
|
|
78
|
-
|
|
75
|
+
// Stores to hold the width and height information for resizing
|
|
76
|
+
const rowHeights = writable<{ [key: number]: { max: number; min: number } }>({});
|
|
77
|
+
const colWidths = writable<number[]>([]);
|
|
78
|
+
|
|
79
|
+
// Server-side variables
|
|
80
|
+
const serverItems = serverSide ? writable<number>(0) : undefined;
|
|
79
81
|
const serverItemCount = serverSide
|
|
80
82
|
? readable<Number>(0, (set) => {
|
|
81
83
|
serverItems!.subscribe((val) => set(val));
|
|
@@ -100,7 +102,7 @@
|
|
|
100
102
|
serverItemCount
|
|
101
103
|
} as PaginationConfig),
|
|
102
104
|
expand: addExpandedRows(),
|
|
103
|
-
export: addDataExport({ format: '
|
|
105
|
+
export: addDataExport({ format: 'json' })
|
|
104
106
|
});
|
|
105
107
|
|
|
106
108
|
// A variable to hold all the keys
|
|
@@ -198,7 +200,7 @@
|
|
|
198
200
|
id,
|
|
199
201
|
tableId,
|
|
200
202
|
values,
|
|
201
|
-
updateTable,
|
|
203
|
+
updateTable: updateTableWithParams,
|
|
202
204
|
pageIndex,
|
|
203
205
|
toFilterableValueFn,
|
|
204
206
|
filters,
|
|
@@ -232,7 +234,7 @@
|
|
|
232
234
|
accessor: accessor,
|
|
233
235
|
cell: ({ value }) => {
|
|
234
236
|
// If null or undefined, return an empty string
|
|
235
|
-
return value
|
|
237
|
+
return value ?? '';
|
|
236
238
|
},
|
|
237
239
|
plugins: {
|
|
238
240
|
// Sorting enabled by default
|
|
@@ -246,7 +248,7 @@
|
|
|
246
248
|
id,
|
|
247
249
|
tableId,
|
|
248
250
|
values,
|
|
249
|
-
updateTable,
|
|
251
|
+
updateTable: updateTableWithParams,
|
|
250
252
|
pageIndex,
|
|
251
253
|
filters
|
|
252
254
|
})
|
|
@@ -290,7 +292,7 @@
|
|
|
290
292
|
// Creating the table columns
|
|
291
293
|
const createdTableColumns = table.createColumns(tableColumns);
|
|
292
294
|
// Creating the table view model
|
|
293
|
-
const { headerRows, pageRows, tableAttrs, tableBodyAttrs, pluginStates } =
|
|
295
|
+
const { headerRows, pageRows, tableAttrs, tableBodyAttrs, pluginStates, rows } =
|
|
294
296
|
table.createViewModel(createdTableColumns);
|
|
295
297
|
// Extracting filterValue to bind it for the search input and search immediately on input
|
|
296
298
|
const { filterValue } = pluginStates.tableFilter;
|
|
@@ -301,82 +303,110 @@
|
|
|
301
303
|
// Column visibility configuration
|
|
302
304
|
const { hiddenColumnIds } = pluginStates.hideColumns;
|
|
303
305
|
|
|
304
|
-
const
|
|
306
|
+
const sortServer = (order: 'asc' | 'desc' | undefined, id: string) => {
|
|
305
307
|
if (!sendModel) throw new Error('Server-side configuration is missing');
|
|
308
|
+
// Set parameter for sorting
|
|
309
|
+
if (order === undefined) {
|
|
310
|
+
sendModel.order = [];
|
|
311
|
+
} else {
|
|
312
|
+
sendModel.order = [{ column: id, direction: order }];
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Reset pagination
|
|
316
|
+
$pageIndex = 0;
|
|
306
317
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
sendModel.version = versionId || -1;
|
|
310
|
-
sendModel.id = entityId || -1;
|
|
311
|
-
sendModel.filter = normalizeFilters($filters);
|
|
318
|
+
updateTableWithParams();
|
|
319
|
+
};
|
|
312
320
|
|
|
313
|
-
|
|
321
|
+
// Function to update the table with the provided parameters for easily passing to other components
|
|
322
|
+
const updateTableWithParams = async () => {
|
|
323
|
+
isFetching = true;
|
|
324
|
+
const result = await utils.updateTable(
|
|
325
|
+
$pageSize,
|
|
326
|
+
$pageIndex,
|
|
327
|
+
server,
|
|
328
|
+
$filters,
|
|
329
|
+
data,
|
|
330
|
+
serverItems,
|
|
331
|
+
columns,
|
|
332
|
+
dispatch
|
|
333
|
+
);
|
|
334
|
+
isFetching = false;
|
|
314
335
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
fetchData = await fetch(baseUrl || '', {
|
|
318
|
-
headers: {
|
|
319
|
-
'Content-Type': 'application/json'
|
|
320
|
-
},
|
|
321
|
-
method: 'POST',
|
|
322
|
-
body: JSON.stringify(sendModel)
|
|
323
|
-
});
|
|
324
|
-
} catch (error) {
|
|
325
|
-
throw new Error(`Network error: ${(error as Error).message}`);
|
|
326
|
-
} finally {
|
|
327
|
-
isFetching = false;
|
|
328
|
-
}
|
|
336
|
+
return result;
|
|
337
|
+
};
|
|
329
338
|
|
|
330
|
-
|
|
331
|
-
|
|
339
|
+
// Initializes observers for rows and columns
|
|
340
|
+
const getDimensions = () => {
|
|
341
|
+
if (!tableRef) return;
|
|
342
|
+
if (resizable === 'none') return;
|
|
343
|
+
else if (resizable === 'columns') {
|
|
344
|
+
observeHeaderColumns();
|
|
345
|
+
} else if (resizable === 'rows') {
|
|
346
|
+
observeFirstCells();
|
|
347
|
+
} else {
|
|
348
|
+
observeHeaderColumns();
|
|
349
|
+
observeFirstCells();
|
|
332
350
|
}
|
|
351
|
+
};
|
|
333
352
|
|
|
334
|
-
|
|
353
|
+
// Resize observer for rows
|
|
354
|
+
const resizeRowsObserver = new ResizeObserver(() => {
|
|
355
|
+
utils.getMaxCellHeightInRow(
|
|
356
|
+
tableRef,
|
|
357
|
+
resizable,
|
|
358
|
+
optionsComponent,
|
|
359
|
+
rowHeights,
|
|
360
|
+
tableId,
|
|
361
|
+
rowHeight
|
|
362
|
+
);
|
|
363
|
+
});
|
|
335
364
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
365
|
+
// Resize observers for columns
|
|
366
|
+
const resizeColumnsObserver = new ResizeObserver(() => {
|
|
367
|
+
utils.getMinCellWidthInColumn(tableRef, colWidths, $headerRows[0].cells.length, resizable);
|
|
368
|
+
});
|
|
339
369
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}, {});
|
|
370
|
+
// Adds observers on the first cells of each row to resize rows
|
|
371
|
+
const observeFirstCells = () => {
|
|
372
|
+
if (!tableRef) return;
|
|
344
373
|
|
|
345
|
-
|
|
374
|
+
tableRef.querySelectorAll('tbody tr td:first-child').forEach((cell) => {
|
|
375
|
+
resizeRowsObserver.observe(cell);
|
|
376
|
+
});
|
|
346
377
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
Object.keys(row).forEach((key) => {
|
|
350
|
-
tmp[clientCols[key]] = row[key];
|
|
351
|
-
});
|
|
352
|
-
tmpArr.push(tmp);
|
|
353
|
-
});
|
|
354
|
-
dispatch('fetch', columns);
|
|
355
|
-
$data = tmpArr;
|
|
356
|
-
}
|
|
378
|
+
return resizeRowsObserver;
|
|
379
|
+
};
|
|
357
380
|
|
|
358
|
-
|
|
381
|
+
// Adds observers on the header columns to resize columns
|
|
382
|
+
const observeHeaderColumns = () => {
|
|
383
|
+
if (!tableRef) return;
|
|
359
384
|
|
|
360
|
-
|
|
385
|
+
tableRef.querySelectorAll('thead tr th').forEach((cell) => {
|
|
386
|
+
resizeColumnsObserver.observe(cell);
|
|
387
|
+
});
|
|
361
388
|
};
|
|
362
389
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
sendModel.order = [];
|
|
368
|
-
} else {
|
|
369
|
-
sendModel.order = [{ column: id, direction: order }];
|
|
390
|
+
afterUpdate(() => {
|
|
391
|
+
// If not resizable, return
|
|
392
|
+
if (resizable !== 'rows' && resizable !== 'both') {
|
|
393
|
+
return;
|
|
370
394
|
}
|
|
395
|
+
// Making sure tableRef is up to date and contains the new rows
|
|
396
|
+
// If it contains even one element, it means it contains them all
|
|
397
|
+
const e = tableRef?.querySelector(`#${tableId}-row-${$pageRows[0].id}`);
|
|
398
|
+
if (e) {
|
|
399
|
+
getDimensions();
|
|
400
|
+
}
|
|
401
|
+
});
|
|
371
402
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
};
|
|
403
|
+
onDestroy(() => {
|
|
404
|
+
resizeColumnsObserver.disconnect();
|
|
405
|
+
resizeRowsObserver.disconnect();
|
|
406
|
+
});
|
|
377
407
|
|
|
378
408
|
$: sortKeys = pluginStates.sort.sortKeys;
|
|
379
|
-
$: serverSide &&
|
|
409
|
+
$: serverSide && updateTableWithParams();
|
|
380
410
|
$: serverSide && sortServer($sortKeys[0]?.order, $sortKeys[0]?.id);
|
|
381
411
|
$: $hiddenColumnIds = shownColumns.filter((col) => !col.visible).map((col) => col.id);
|
|
382
412
|
</script>
|
|
@@ -445,7 +475,8 @@
|
|
|
445
475
|
{/if}
|
|
446
476
|
|
|
447
477
|
<div
|
|
448
|
-
class="flex justify-between items-center w-full {search &&
|
|
478
|
+
class="flex justify-between overflow-x-auto items-center w-full {search &&
|
|
479
|
+
'py-2'} {!search &&
|
|
449
480
|
(shownColumns.length > 0 || toggle || resizable !== 'none' || exportable) &&
|
|
450
481
|
'pb-2'}"
|
|
451
482
|
>
|
|
@@ -472,25 +503,26 @@
|
|
|
472
503
|
{#if resizable !== 'none'}
|
|
473
504
|
<button
|
|
474
505
|
type="button"
|
|
475
|
-
|
|
476
|
-
class="btn btn-sm variant-filled-primary rounded-full order-last"
|
|
506
|
+
class="btn btn-sm variant-filled-primary rounded-full order-last flex gap-2 items-center"
|
|
477
507
|
aria-label="Reset sizing of columns and rows"
|
|
478
508
|
on:click|preventDefault={() =>
|
|
479
|
-
resetResize($headerRows, $pageRows, tableId, columns, resizable)}
|
|
480
|
-
|
|
509
|
+
utils.resetResize($headerRows, $pageRows, tableId, columns, resizable)}
|
|
510
|
+
><Fa icon={faCompress} /> Reset sizing</button
|
|
481
511
|
>
|
|
482
512
|
{/if}
|
|
513
|
+
<!-- Enable export as CSV button if exportable === true -->
|
|
483
514
|
{#if exportable}
|
|
484
515
|
<button
|
|
485
516
|
type="button"
|
|
486
|
-
|
|
487
|
-
class="btn btn-sm variant-filled-primary rounded-full order-last"
|
|
517
|
+
class="btn btn-sm variant-filled-primary rounded-full order-last flex items-center gap-2"
|
|
488
518
|
aria-label="Export table data as CSV"
|
|
489
|
-
on:click|preventDefault={() =>
|
|
490
|
-
|
|
519
|
+
on:click|preventDefault={() =>
|
|
520
|
+
utils.exportAsCsv(tableId, utils.jsonToCsv($exportedData))}
|
|
521
|
+
><Fa icon={faDownload} /> Export as CSV</button
|
|
491
522
|
>
|
|
492
523
|
{/if}
|
|
493
|
-
|
|
524
|
+
<!-- Enable show/hide columns menu if showColumnsMenu === true -->
|
|
525
|
+
{#if showColumnsMenu && shownColumns.length > 0}
|
|
494
526
|
<ColumnsMenu bind:columns={shownColumns} {tableId} />
|
|
495
527
|
{/if}
|
|
496
528
|
</div>
|
|
@@ -498,6 +530,7 @@
|
|
|
498
530
|
|
|
499
531
|
<div class="overflow-auto" style="height: {height}px">
|
|
500
532
|
<table
|
|
533
|
+
bind:this={tableRef}
|
|
501
534
|
{...$tableAttrs}
|
|
502
535
|
class="table table-auto table-compact bg-tertiary-500/30 dark:bg-tertiary-900/10 overflow-clip"
|
|
503
536
|
id="{tableId}-table"
|
|
@@ -514,14 +547,29 @@
|
|
|
514
547
|
let:rowProps
|
|
515
548
|
>
|
|
516
549
|
<tr {...rowAttrs} class="bg-primary-300 dark:bg-primary-800">
|
|
517
|
-
{#each headerRow.cells as cell (cell.id)}
|
|
550
|
+
{#each headerRow.cells as cell, index (cell.id)}
|
|
518
551
|
<Subscribe attrs={cell.attrs()} props={cell.props()} let:props let:attrs>
|
|
519
|
-
<th
|
|
552
|
+
<th
|
|
553
|
+
scope="col"
|
|
554
|
+
class="!p-2"
|
|
555
|
+
{...attrs}
|
|
556
|
+
style={`
|
|
557
|
+
width: ${cell.isData() ? 'auto' : '0'};
|
|
558
|
+
${utils.cellStyle(cell.id, columns)}
|
|
559
|
+
`}
|
|
560
|
+
>
|
|
520
561
|
<div
|
|
521
562
|
class="overflow-auto"
|
|
522
563
|
class:resize-x={(resizable === 'columns' || resizable === 'both') &&
|
|
523
|
-
!fixedWidth(cell.id, columns)}
|
|
564
|
+
!utils.fixedWidth(cell.id, columns)}
|
|
524
565
|
id="th-{tableId}-{cell.id}"
|
|
566
|
+
style={`
|
|
567
|
+
min-width: ${
|
|
568
|
+
utils.minWidth(cell.id, columns)
|
|
569
|
+
? utils.minWidth(cell.id, columns)
|
|
570
|
+
: $colWidths[index]
|
|
571
|
+
}px;
|
|
572
|
+
`}
|
|
525
573
|
>
|
|
526
574
|
<div class="flex justify-between items-center">
|
|
527
575
|
<div class="flex gap-1 whitespace-pre-wrap">
|
|
@@ -572,20 +620,34 @@
|
|
|
572
620
|
<tr {...rowAttrs} id="{tableId}-row-{row.id}" class="">
|
|
573
621
|
{#each row.cells as cell, index (cell?.id)}
|
|
574
622
|
<Subscribe attrs={cell.attrs()} let:attrs>
|
|
575
|
-
<td {...attrs} class="
|
|
623
|
+
<td {...attrs} class="">
|
|
576
624
|
<div
|
|
577
|
-
class="
|
|
625
|
+
class=" h-full {index === 0 &&
|
|
578
626
|
(resizable === 'rows' || resizable === 'both')
|
|
579
|
-
? 'resize-y'
|
|
580
|
-
: ''}"
|
|
627
|
+
? 'resize-y overflow-auto'
|
|
628
|
+
: 'block'}"
|
|
581
629
|
id="{tableId}-{cell.id}-{row.id}"
|
|
630
|
+
style={utils.getResizeStyles($rowHeights, row.id, index)}
|
|
582
631
|
>
|
|
583
632
|
<!-- Adding config for initial rowHeight, if provided -->
|
|
584
633
|
<div
|
|
585
|
-
class="flex items-
|
|
586
|
-
style=
|
|
634
|
+
class="flex items-start overflow-auto"
|
|
635
|
+
style={`
|
|
636
|
+
max-height: ${$rowHeights && $rowHeights[+row.id] ? `${$rowHeights[+row.id].max}px` : 'auto'};
|
|
637
|
+
`}
|
|
587
638
|
>
|
|
588
|
-
<div
|
|
639
|
+
<div
|
|
640
|
+
class="grow overflow-auto"
|
|
641
|
+
style={cell.isData()
|
|
642
|
+
? `width: ${
|
|
643
|
+
utils.minWidth(cell.id, columns)
|
|
644
|
+
? utils.minWidth(cell.id, columns)
|
|
645
|
+
: $colWidths[index]
|
|
646
|
+
}px;`
|
|
647
|
+
: 'max-width: min-content;'}
|
|
648
|
+
>
|
|
649
|
+
<Render of={cell.render()} />
|
|
650
|
+
</div>
|
|
589
651
|
</div>
|
|
590
652
|
</div>
|
|
591
653
|
</td>
|
|
@@ -622,12 +684,19 @@
|
|
|
622
684
|
{pageIndex}
|
|
623
685
|
{pageSize}
|
|
624
686
|
{serverItemCount}
|
|
625
|
-
{
|
|
687
|
+
updateTable={updateTableWithParams}
|
|
626
688
|
{pageSizes}
|
|
689
|
+
{pageIndexStringType}
|
|
627
690
|
id={tableId}
|
|
628
691
|
/>
|
|
629
692
|
{:else}
|
|
630
|
-
<TablePagination
|
|
693
|
+
<TablePagination
|
|
694
|
+
itemCount={$rows.length}
|
|
695
|
+
pageConfig={pluginStates.page}
|
|
696
|
+
{pageSizes}
|
|
697
|
+
id={tableId}
|
|
698
|
+
{pageIndexStringType}
|
|
699
|
+
/>
|
|
631
700
|
{/if}
|
|
632
701
|
{/if}
|
|
633
702
|
</div>
|
|
@@ -9,10 +9,14 @@
|
|
|
9
9
|
} from '@fortawesome/free-solid-svg-icons';
|
|
10
10
|
import { ListBox, ListBoxItem, popup, type PopupSettings } from '@skeletonlabs/skeleton';
|
|
11
11
|
|
|
12
|
+
export let itemCount;
|
|
12
13
|
export let pageConfig;
|
|
13
14
|
export let pageSizes;
|
|
15
|
+
export let pageIndexStringType;
|
|
14
16
|
export let id;
|
|
15
17
|
|
|
18
|
+
let indexInformation = '';
|
|
19
|
+
|
|
16
20
|
const { pageIndex, pageCount, pageSize, hasNextPage, hasPreviousPage } = pageConfig;
|
|
17
21
|
|
|
18
22
|
const goToFirstPage = () => ($pageIndex = 0);
|
|
@@ -42,11 +46,23 @@
|
|
|
42
46
|
closeQuery: '.listbox-item'
|
|
43
47
|
};
|
|
44
48
|
|
|
49
|
+
const getIndexInfomationString = () => {
|
|
50
|
+
if (pageIndexStringType === 'pages') {
|
|
51
|
+
return $pageCount > 0 ? `Page ${$pageIndex + 1} of ${$pageCount}` : 'No pages';
|
|
52
|
+
} else {
|
|
53
|
+
return itemCount === 0 ? 'No items' : `Displaying items ${$pageIndex * $pageSize + 1} - ${Math.min(
|
|
54
|
+
($pageIndex + 1) * $pageSize,
|
|
55
|
+
itemCount
|
|
56
|
+
)} of ${Math.min($pageCount * $pageSize, itemCount)}`;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
45
60
|
$: goToFirstPageDisabled = !$pageIndex;
|
|
46
61
|
$: goToLastPageDisabled = $pageIndex == $pageCount - 1;
|
|
47
62
|
$: goToNextPageDisabled = !$hasNextPage;
|
|
48
63
|
$: goToPreviousPageDisabled = !$hasPreviousPage;
|
|
49
64
|
$: $pageSize = pageSizeDropdownValue;
|
|
65
|
+
$: $pageCount, $pageIndex, $pageSize, (indexInformation = getIndexInfomationString());
|
|
50
66
|
</script>
|
|
51
67
|
|
|
52
68
|
<div class="flex justify-between w-full items-stretch gap-10">
|
|
@@ -124,12 +140,6 @@
|
|
|
124
140
|
>
|
|
125
141
|
</div>
|
|
126
142
|
<div class="flex justify-end items-center">
|
|
127
|
-
<span class="text-sm text-gray-500">
|
|
128
|
-
{#if $pageCount > 0}
|
|
129
|
-
Page {$pageIndex + 1} of {$pageCount}
|
|
130
|
-
{:else}
|
|
131
|
-
No pages
|
|
132
|
-
{/if}
|
|
133
|
-
</span>
|
|
143
|
+
<span class="text-sm text-gray-500">{indexInformation}</span>
|
|
134
144
|
</div>
|
|
135
145
|
</div>
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
export let id; // Unique table ID
|
|
11
11
|
export let pageIndex;
|
|
12
12
|
export let pageSize;
|
|
13
|
+
export let pageIndexStringType;
|
|
13
14
|
export let pageSizes; // Available page sizes
|
|
14
15
|
export let serverItemCount; // Total number of items expected from the server. `serverSide` must be true on table config.
|
|
15
16
|
export let updateTable; // Function to update table
|
|
@@ -20,6 +21,9 @@
|
|
|
20
21
|
let goToNextPageDisabled = true;
|
|
21
22
|
let goToPreviousPageDisabled = true;
|
|
22
23
|
|
|
24
|
+
// Index information string
|
|
25
|
+
let indexInformation = '';
|
|
26
|
+
|
|
23
27
|
// Handles the input change event
|
|
24
28
|
const handleChange = (e) => {
|
|
25
29
|
const value = e.target.value;
|
|
@@ -58,12 +62,23 @@
|
|
|
58
62
|
updateTable();
|
|
59
63
|
};
|
|
60
64
|
|
|
65
|
+
const getIndexInfomationString = () => {
|
|
66
|
+
if (pageIndexStringType === 'pages') {
|
|
67
|
+
return pageCount > 0 ? `Page ${$pageIndex + 1} of ${pageCount}` : 'No pages';
|
|
68
|
+
} else {
|
|
69
|
+
return `Showing ${$pageIndex * $pageSize + 1} - ${($pageIndex + 1) * $pageSize} of ${
|
|
70
|
+
pageCount * $pageSize
|
|
71
|
+
} items`;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
61
75
|
$: pageCount = Math.ceil($serverItemCount / $pageSize);
|
|
62
76
|
$: goToFirstPageDisabled = !$pageIndex;
|
|
63
77
|
$: goToLastPageDisabled = $pageIndex == pageCount - 1;
|
|
64
78
|
$: goToNextPageDisabled = $pageIndex == pageCount - 1;
|
|
65
79
|
$: goToPreviousPageDisabled = !$pageIndex;
|
|
66
80
|
$: $pageSize && updateTable(); // Update query when page size changes
|
|
81
|
+
$: pageCount, $pageIndex, $pageSize, (indexInformation = getIndexInfomationString());
|
|
67
82
|
|
|
68
83
|
updateTable();
|
|
69
84
|
</script>
|
|
@@ -127,15 +142,7 @@
|
|
|
127
142
|
</div>
|
|
128
143
|
<div class="flex justify-end items-center">
|
|
129
144
|
<span class="text-sm text-gray-500">
|
|
130
|
-
{
|
|
131
|
-
{#if pageCount == 1}
|
|
132
|
-
1 page
|
|
133
|
-
{:else}
|
|
134
|
-
{pageCount} pages
|
|
135
|
-
{/if}
|
|
136
|
-
{:else}
|
|
137
|
-
No pages
|
|
138
|
-
{/if}
|
|
145
|
+
{indexInformation}
|
|
139
146
|
</span>
|
|
140
147
|
</div>
|
|
141
148
|
</div>
|