Skip to content

Commit 9499aac

Browse files
committed
Re-render Table on server side fetch
1 parent 82bda52 commit 9499aac

File tree

2 files changed

+160
-139
lines changed

2 files changed

+160
-139
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: 150 additions & 137 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;
@@ -350,41 +368,41 @@
350368
<div class="grid gap-2 overflow-auto" class:w-fit={!fitToScreen} class:w-full={fitToScreen}>
351369
<div class="table-container">
352370
<!-- 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"
371+
372+
<form
373+
class="flex gap-2"
374+
on:submit|preventDefault={() => {
375+
sendModel.q = searchValue;
376+
$filterValue = searchValue;
377+
}}
378+
>
379+
<div class="relative w-full flex items-center">
380+
<input
381+
class="input p-2 border border-primary-500"
382+
type="text"
383+
bind:value={searchValue}
384+
placeholder="Search rows..."
385+
id="{tableId}-search"
386+
/><button
387+
type="reset"
388+
class="absolute right-3 items-center"
381389
on:click|preventDefault={() => {
382-
$filterValue = searchValue;
383-
sendModel.q = searchValue;
384-
}}>Search</button
390+
searchValue = '';
391+
sendModel.q = '';
392+
$filterValue = '';
393+
}}><Fa icon={faXmark} /></button
385394
>
386-
</form>
387-
{/if}
395+
</div>
396+
<button
397+
type="submit"
398+
class="btn variant-filled-primary"
399+
on:click|preventDefault={() => {
400+
$filterValue = searchValue;
401+
sendModel.q = searchValue;
402+
}}>Search</button
403+
>
404+
</form>
405+
388406
<div class="flex justify-between items-center py-2 w-full">
389407
<div>
390408
<!-- Enable the fitToScreen toggle if toggle === true -->
@@ -428,115 +446,110 @@
428446
>
429447
<!-- If table height is provided, making the top row sticky -->
430448
<thead class=" {height != null ? `sticky top-0` : ''}">
431-
{#if $data.length > 0}
432-
{#each $headerRows as headerRow (headerRow.id)}
433-
<Subscribe
434-
rowAttrs={headerRow.attrs()}
435-
let:rowAttrs
436-
rowProps={headerRow.props()}
437-
let:rowProps
438-
>
439-
<tr {...rowAttrs} class="bg-primary-300 dark:bg-primary-500">
440-
{#each headerRow.cells as cell (cell.id)}
441-
<Subscribe attrs={cell.attrs()} props={cell.props()} let:props let:attrs>
442-
<th scope="col" class="!p-2" {...attrs} style={cellStyle(cell.id, columns)}>
443-
<div
444-
class="overflow-auto"
445-
class:resize-x={(resizable === 'columns' || resizable === 'both') &&
446-
!fixedWidth(cell.id, columns)}
447-
id="th-{tableId}-{cell.id}"
448-
>
449-
<div class="flex justify-between items-center">
450-
<div class="flex gap-1 whitespace-pre-wrap">
451-
<!-- Adding sorting config and styling -->
452-
<span
453-
class:underline={props.sort.order}
454-
class:normal-case={cell.id !== cell.label}
455-
class:cursor-pointer={!props.sort.disabled}
456-
on:click={props.sort.toggle}
457-
on:keydown={props.sort.toggle}
458-
>
459-
{cell.render()}
460-
</span>
461-
<div class="w-2">
462-
{#if props.sort.order === 'asc'}
463-
464-
{:else if props.sort.order === 'desc'}
465-
466-
{/if}
467-
</div>
468-
</div>
469-
<!-- Adding column filter config -->
470-
{#if cell.isData()}
471-
{#if props.colFilter?.render}
472-
<div class="">
473-
<Render of={props.colFilter.render} />
474-
</div>
449+
<!-- {#if $data.length > 0} -->
450+
{#each $headerRows as headerRow (headerRow.id)}
451+
<Subscribe
452+
rowAttrs={headerRow.attrs()}
453+
let:rowAttrs
454+
rowProps={headerRow.props()}
455+
let:rowProps
456+
>
457+
<tr {...rowAttrs} class="bg-primary-300 dark:bg-primary-800">
458+
{#each headerRow.cells as cell (cell.id)}
459+
<Subscribe attrs={cell.attrs()} props={cell.props()} let:props let:attrs>
460+
<th scope="col" class="!p-2" {...attrs} style={cellStyle(cell.id, columns)}>
461+
<div
462+
class="overflow-auto"
463+
class:resize-x={(resizable === 'columns' || resizable === 'both') &&
464+
!fixedWidth(cell.id, columns)}
465+
id="th-{tableId}-{cell.id}"
466+
>
467+
<div class="flex justify-between items-center">
468+
<div class="flex gap-1 whitespace-pre-wrap">
469+
<!-- Adding sorting config and styling -->
470+
<span
471+
class:underline={props.sort.order}
472+
class:normal-case={cell.id !== cell.label}
473+
class:cursor-pointer={!props.sort.disabled}
474+
on:click={props.sort.toggle}
475+
on:keydown={props.sort.toggle}
476+
>
477+
{cell.render()}
478+
</span>
479+
<div class="w-2">
480+
{#if props.sort.order === 'asc'}
481+
482+
{:else if props.sort.order === 'desc'}
483+
475484
{/if}
476-
{/if}
485+
</div>
477486
</div>
487+
<!-- Adding column filter config -->
488+
{#if cell.isData()}
489+
{#if props.colFilter?.render}
490+
<div class="">
491+
<Render of={props.colFilter.render} />
492+
</div>
493+
{/if}
494+
{/if}
478495
</div>
479-
</th>
480-
</Subscribe>
481-
{/each}
482-
</tr>
483-
</Subscribe>
484-
{/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}
496+
</div>
497+
</th>
498+
</Subscribe>
499+
{/each}
500+
</tr>
501+
</Subscribe>
502+
{/each}
491503
</thead>
492504

493505
<tbody class="overflow-auto" {...$tableBodyAttrs}>
494-
{#if $data.length > 0}
495-
{#each $pageRows as row (row.id)}
496-
<Subscribe rowAttrs={row.attrs()} let:rowAttrs>
497-
<tr {...rowAttrs} id="{tableId}-row-{row.id}" class="">
498-
{#each row.cells as cell, index (cell?.id)}
499-
<Subscribe attrs={cell.attrs()} let:attrs>
500-
<td {...attrs} class="!p-2">
506+
{#each $pageRows as row (row.id)}
507+
<Subscribe rowAttrs={row.attrs()} let:rowAttrs>
508+
<tr {...rowAttrs} id="{tableId}-row-{row.id}" class="">
509+
{#each row.cells as cell, index (cell?.id)}
510+
<Subscribe attrs={cell.attrs()} let:attrs>
511+
<td {...attrs} class="!p-2">
512+
<div
513+
class=" overflow-auto h-max {index === 0 &&
514+
(resizable === 'rows' || resizable === 'both')
515+
? 'resize-y'
516+
: ''}"
517+
id="{tableId}-{cell.id}-{row.id}"
518+
>
519+
<!-- Adding config for initial rowHeight, if provided -->
501520
<div
502-
class=" overflow-auto h-max {index === 0 &&
503-
(resizable === 'rows' || resizable === 'both')
504-
? 'resize-y'
505-
: ''}"
506-
id="{tableId}-{cell.id}-{row.id}"
521+
class="flex items-center overflow-auto"
522+
style="height: {rowHeight ? `${rowHeight}px` : 'auto'};"
507523
>
508-
<!-- Adding config for initial rowHeight, if provided -->
509-
<div
510-
class="flex items-center overflow-auto"
511-
style="height: {rowHeight ? `${rowHeight}px` : 'auto'};"
512-
>
513-
<div class="grow h-full"><Render of={cell.render()} /></div>
514-
</div>
524+
<div class="grow h-full"><Render of={cell.render()} /></div>
515525
</div>
516-
</td>
517-
</Subscribe>
518-
{/each}
519-
</tr>
520-
</Subscribe>
521-
{/each}
522-
{/if}
526+
</div>
527+
</td>
528+
</Subscribe>
529+
{/each}
530+
</tr>
531+
</Subscribe>
532+
{/each}
523533
</tbody>
524534
</table>
525535
</div>
526536
</div>
527-
{#if $data.length > 0}
528-
<!-- Adding pagination, if table is not empty -->
529-
{#if serverSide}
530-
<TablePaginationServer
531-
{pageIndex}
532-
{pageSize}
533-
{serverItemCount}
534-
{updateTable}
535-
{pageSizes}
536-
id={tableId}
537-
/>
538-
{:else}
539-
<TablePagination pageConfig={pluginStates.page} {pageSizes} id={tableId} />
540-
{/if}
537+
538+
{#if isFetching}
539+
<div class="p-10 w-full h-full flex justify-center items-center"><Spinner /></div>
540+
{/if}
541+
542+
<!-- Adding pagination, if table is not empty -->
543+
{#if serverSide}
544+
<TablePaginationServer
545+
{pageIndex}
546+
{pageSize}
547+
{serverItemCount}
548+
{updateTable}
549+
{pageSizes}
550+
id={tableId}
551+
/>
552+
{:else}
553+
<TablePagination pageConfig={pluginStates.page} {pageSizes} id={tableId} />
541554
{/if}
542555
</div>

0 commit comments

Comments
 (0)