Skip to content

Commit 2d4d8b4

Browse files
committed
Merge remote-tracking branch 'remotes/origin/table'
2 parents 16c4856 + 5acc46b commit 2d4d8b4

File tree

5 files changed

+244
-148
lines changed

5 files changed

+244
-148
lines changed

src/lib/components/Table/Table.svelte

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,17 @@
33
import type { TableConfig } from '$models/Models';
44
55
export let config: TableConfig<any>;
6+
7+
let fetched = false;
68
const data = config.data;
9+
10+
$: if ($data.length > 0) fetched = true;
711
</script>
812

9-
{#key $data.length && true}
10-
<Table {config} on:action />
13+
{#key fetched}
14+
<Table
15+
{config}
16+
on:fetch={(columns) => (config = { ...config, columns: columns.detail })}
17+
on:action
18+
/>
1119
{/key}

src/lib/components/Table/TableContent.svelte

Lines changed: 121 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
resetResize,
3434
convertServerColumns
3535
} from './shared';
36-
import { Receive, Send } from '$lib/models/Models';
37-
import type { TableConfig } from '$lib/models/Models';
36+
import { Receive, Send } from '$models/Models';
37+
import type { TableConfig } from '$models/Models';
3838
import type { FilterOptionsEnum } from '$models/Enums';
3939
4040
export let config: TableConfig<any>;
@@ -58,7 +58,7 @@
5858
token = '', // Bearer token to authenticate the request
5959
sendModel = new Send(), // Model to send requests
6060
entityId = 0, // Entity ID to send with the request
61-
versionId = 0 // Version ID to send with the request
61+
versionId = 0 // Version ID to send with the request,
6262
} = config;
6363
6464
let searchValue = '';
@@ -188,7 +188,8 @@
188188
updateTable,
189189
pageIndex,
190190
toFilterableValueFn,
191-
filters
191+
filters,
192+
toStringFn
192193
})
193194
: createRender(colFilterComponent ?? TableFilter, {
194195
filterValue,
@@ -318,11 +319,28 @@
318319
319320
// Format server columns to the client columns
320321
if (response.columns !== undefined) {
321-
columns = convertServerColumns(response.columns);
322+
console.log(response);
323+
324+
columns = convertServerColumns(response.columns, columns);
325+
326+
const clientCols = response.columns.reduce((acc, col) => {
327+
acc[col.key] = col.column;
328+
return acc;
329+
}, {});
330+
331+
const tmpArr: any[] = [];
332+
333+
response.data.forEach((row, index) => {
334+
const tmp: { [key: string]: any } = {};
335+
Object.keys(row).forEach((key) => {
336+
tmp[clientCols[key]] = row[key];
337+
});
338+
tmpArr.push(tmp);
339+
});
340+
dispatch('fetch', columns);
341+
$data = tmpArr;
322342
}
323343
324-
// Update data store
325-
$data = response.data;
326344
$serverItems = response.count;
327345
328346
return response;
@@ -348,95 +366,98 @@
348366
</script>
349367

350368
<div class="grid gap-2 overflow-auto" class:w-fit={!fitToScreen} class:w-full={fitToScreen}>
351-
<div class="table-container">
352-
<!-- Enable the search filter if table is not empty -->
353-
{#if $data.length > 0}
354-
<form
355-
class="flex gap-2"
356-
on:submit|preventDefault={() => {
357-
sendModel.q = searchValue;
358-
$filterValue = searchValue;
359-
}}
360-
>
361-
<div class="relative w-full flex items-center">
362-
<input
363-
class="input p-2 border border-primary-500"
364-
type="text"
365-
bind:value={searchValue}
366-
placeholder="Search rows..."
367-
id="{tableId}-search"
368-
/><button
369-
type="reset"
370-
class="absolute right-3 items-center"
371-
on:click|preventDefault={() => {
372-
searchValue = '';
373-
sendModel.q = '';
374-
$filterValue = '';
375-
}}><Fa icon={faXmark} /></button
376-
>
377-
</div>
378-
<button
379-
type="submit"
380-
class="btn variant-filled-primary"
381-
on:click|preventDefault={() => {
382-
$filterValue = searchValue;
369+
{#if $data.length > 0 || (columns && Object.keys(columns).length > 0)}
370+
<div class="table-container">
371+
<!-- Enable the search filter if table is not empty -->
372+
{#if !serverSide}
373+
<form
374+
class="flex gap-2"
375+
on:submit|preventDefault={() => {
383376
sendModel.q = searchValue;
384-
}}>Search</button
377+
$filterValue = searchValue;
378+
}}
385379
>
386-
</form>
387-
{/if}
388-
<div class="flex justify-between items-center py-2 w-full">
389-
<div>
390-
<!-- Enable the fitToScreen toggle if toggle === true -->
391-
{#if toggle}
392-
<SlideToggle
393-
name="slider-label"
394-
active="bg-primary-500"
395-
size="sm"
396-
checked={fitToScreen}
397-
id="{tableId}-toggle"
398-
on:change={() => (fitToScreen = !fitToScreen)}>Fit to screen</SlideToggle
399-
>
400-
{/if}
401-
</div>
402-
<div class="flex gap-2">
403-
<!-- Enable the resetResize button if resizable !== 'none' -->
404-
{#if resizable !== 'none'}
405-
<button
406-
type="button"
407-
class="btn btn-sm variant-filled-primary rounded-full order-last"
408-
on:click|preventDefault={() =>
409-
resetResize($headerRows, $pageRows, tableId, columns, resizable)}>Reset sizing</button
410-
>
411-
{/if}
412-
{#if exportable}
380+
<div class="relative w-full flex items-center">
381+
<input
382+
class="input p-2 border border-primary-500"
383+
type="text"
384+
bind:value={searchValue}
385+
placeholder="Search rows..."
386+
id="{tableId}-search"
387+
/><button
388+
type="reset"
389+
class="absolute right-3 items-center"
390+
on:click|preventDefault={() => {
391+
searchValue = '';
392+
sendModel.q = '';
393+
$filterValue = '';
394+
}}><Fa icon={faXmark} /></button
395+
>
396+
</div>
413397
<button
414-
type="button"
415-
class="btn btn-sm variant-filled-primary rounded-full order-last"
416-
on:click|preventDefault={() => exportAsCsv(tableId, $exportedData)}
417-
>Export as CSV</button
398+
type="submit"
399+
class="btn variant-filled-primary"
400+
on:click|preventDefault={() => {
401+
$filterValue = searchValue;
402+
sendModel.q = searchValue;
403+
}}>Search</button
418404
>
419-
{/if}
405+
</form>
406+
{/if}
407+
408+
<div class="flex justify-between items-center py-2 w-full">
409+
<div>
410+
<!-- Enable the fitToScreen toggle if toggle === true -->
411+
{#if toggle}
412+
<SlideToggle
413+
name="slider-label"
414+
active="bg-primary-500"
415+
size="sm"
416+
checked={fitToScreen}
417+
id="{tableId}-toggle"
418+
on:change={() => (fitToScreen = !fitToScreen)}>Fit to screen</SlideToggle
419+
>
420+
{/if}
421+
</div>
422+
<div class="flex gap-2">
423+
<!-- Enable the resetResize button if resizable !== 'none' -->
424+
{#if resizable !== 'none'}
425+
<button
426+
type="button"
427+
class="btn btn-sm variant-filled-primary rounded-full order-last"
428+
on:click|preventDefault={() =>
429+
resetResize($headerRows, $pageRows, tableId, columns, resizable)}
430+
>Reset sizing</button
431+
>
432+
{/if}
433+
{#if exportable}
434+
<button
435+
type="button"
436+
class="btn btn-sm variant-filled-primary rounded-full order-last"
437+
on:click|preventDefault={() => exportAsCsv(tableId, $exportedData)}
438+
>Export as CSV</button
439+
>
440+
{/if}
441+
</div>
420442
</div>
421-
</div>
422443

423-
<div class="overflow-auto" style="height: {height}px">
424-
<table
425-
{...$tableAttrs}
426-
class="table table-auto table-compact bg-tertiary-500/30 dark:bg-tertiary-900/10 overflow-clip"
427-
id="{tableId}-table"
428-
>
429-
<!-- If table height is provided, making the top row sticky -->
430-
<thead class=" {height != null ? `sticky top-0` : ''}">
431-
{#if $data.length > 0}
444+
<div class="overflow-auto" style="height: {height}px">
445+
<table
446+
{...$tableAttrs}
447+
class="table table-auto table-compact bg-tertiary-500/30 dark:bg-tertiary-900/10 overflow-clip"
448+
id="{tableId}-table"
449+
>
450+
<!-- If table height is provided, making the top row sticky -->
451+
<thead class={height != null && $pageRows.length > 0 ? `sticky top-0` : ''}>
452+
<!-- {#if $data.length > 0} -->
432453
{#each $headerRows as headerRow (headerRow.id)}
433454
<Subscribe
434455
rowAttrs={headerRow.attrs()}
435456
let:rowAttrs
436457
rowProps={headerRow.props()}
437458
let:rowProps
438459
>
439-
<tr {...rowAttrs} class="bg-primary-300 dark:bg-primary-500">
460+
<tr {...rowAttrs} class="bg-primary-300 dark:bg-primary-800">
440461
{#each headerRow.cells as cell (cell.id)}
441462
<Subscribe attrs={cell.attrs()} props={cell.props()} let:props let:attrs>
442463
<th scope="col" class="!p-2" {...attrs} style={cellStyle(cell.id, columns)}>
@@ -482,16 +503,9 @@
482503
</tr>
483504
</Subscribe>
484505
{/each}
485-
{:else if isFetching}
486-
<div class="p-10"><Spinner /></div>
487-
{:else}
488-
<!-- Table is empty -->
489-
<p class="items-center justify-center flex w-full p-10 italic">Nothing to show here.</p>
490-
{/if}
491-
</thead>
506+
</thead>
492507

493-
<tbody class="overflow-auto" {...$tableBodyAttrs}>
494-
{#if $data.length > 0}
508+
<tbody class="overflow-auto" {...$tableBodyAttrs}>
495509
{#each $pageRows as row (row.id)}
496510
<Subscribe rowAttrs={row.attrs()} let:rowAttrs>
497511
<tr {...rowAttrs} id="{tableId}-row-{row.id}" class="">
@@ -519,13 +533,22 @@
519533
</tr>
520534
</Subscribe>
521535
{/each}
522-
{/if}
523-
</tbody>
524-
</table>
536+
</tbody>
537+
</table>
538+
</div>
539+
</div>
540+
{:else}
541+
<div class="p-10 w-full h-full flex justify-center items-center bg-neutral-200 rounded">
542+
<p>No data available</p>
525543
</div>
526-
</div>
527-
{#if $data.length > 0}
528-
<!-- Adding pagination, if table is not empty -->
544+
{/if}
545+
546+
{#if isFetching}
547+
<div class="p-10 w-full h-full flex justify-center items-center"><Spinner /></div>
548+
{/if}
549+
550+
<!-- Adding pagination, if table is not empty -->
551+
{#if $data.length > 0 || (columns && Object.keys(columns).length > 0)}
529552
{#if serverSide}
530553
<TablePaginationServer
531554
{pageIndex}

0 commit comments

Comments
 (0)