Paginated scan loading

ref #175
This commit is contained in:
Nicolai Ort 2023-04-18 20:43:04 +02:00
parent faf3893180
commit cac34db1fd
Signed by: niggl
GPG Key ID: 13AFA55AF62F269F

View File

@ -30,6 +30,7 @@
$table?.getSelectedRowModel().rows.map((row) => row.index) || []; $table?.getSelectedRowModel().rows.map((row) => row.index) || [];
$: active_delete = undefined; $: active_delete = undefined;
$: dataLoaded = false;
export let current_scans = []; export let current_scans = [];
export const addScans = (scans) => { export const addScans = (scans) => {
current_scans = current_scans.concat(...scans); current_scans = current_scans.concat(...scans);
@ -39,15 +40,6 @@
})); }));
}; };
const scans_promise = ScanService.scanControllerGetAll().then((val) => {
current_scans = val;
// handler.setRows(val);
current_scans = val;
options.update((options) => ({
...options,
data: current_scans,
}));
});
let allTracks = []; let allTracks = [];
TrackService.trackControllerGetAll().then((val) => { TrackService.trackControllerGetAll().then((val) => {
allTracks = val; allTracks = val;
@ -99,7 +91,7 @@
accessorKey: "timestamp", accessorKey: "timestamp",
header: () => $_("timestamp"), header: () => $_("timestamp"),
cell: (info) => { cell: (info) => {
return (new Date(parseInt(info.getValue())*1000)).toLocaleString() return new Date(parseInt(info.getValue()) * 1000).toLocaleString();
}, },
enableColumnFilter: false, enableColumnFilter: false,
}, },
@ -183,6 +175,29 @@
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
}).showToast(); }).showToast();
} }
onMount(async () => {
let page = 0;
while (page >= 0) {
const scans = await ScanService.scanControllerGetAll(page, 500);
if (scans.length == 0) {
page = -2;
dataLoaded = true;
}
current_scans = current_scans.concat(...scans);
options.update((options) => ({
...options,
data: current_scans,
}));
if (page == 0) {
dataLoaded = true;
}
page++;
}
console.log("All scans loaded");
});
</script> </script>
<DeleteScanModal <DeleteScanModal
@ -193,7 +208,7 @@
}} }}
/> />
{#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:GET")} {#if store.state.jwtinfo.userdetails.permissions.includes("SCAN:GET")}
{#await scans_promise} {#if !dataLoaded}
<div <div
class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2" class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
role="alert" role="alert"
@ -201,105 +216,96 @@
<p class="font-bold">{$_("scans-are-being-loaded")}</p> <p class="font-bold">{$_("scans-are-being-loaded")}</p>
<p class="text-sm">{$_("this-might-take-a-moment")}</p> <p class="text-sm">{$_("this-might-take-a-moment")}</p>
</div> </div>
{:then} {:else if current_scans.length === 0}
{#if current_scans.length === 0} <ScansEmptyState />
<ScansEmptyState /> {:else}
{:else} {#if selected.length > 0}
{#if selected.length > 0} <button
<button type="button"
type="button" class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex"
class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex" id="options-menu"
id="options-menu" on:click={async () => {
on:click={async () => { const prom = [];
const prom = []; for (const scan of selectedScans) {
for (const scan of selectedScans) { prom.push(ScanService.scanControllerRemove(scan.id, true));
prom.push(ScanService.scanControllerRemove(scan.id, true)); }
} await Promise.all(prom);
await Promise.all(prom); for (const scan of selectedScans) {
for (const scan of selectedScans) { current_scans = current_scans.filter((r) => r.id !== scan.id);
current_scans = current_scans.filter((r) => r.id !== scan.id); }
} options.update((options) => ({
options.update((options) => ({ ...options,
...options, data: current_scans,
data: current_scans, }));
})); $table.resetRowSelection();
$table.resetRowSelection(); Toastify({
Toastify({ text: $_("scan-deleted"),
text: $_("scan-deleted"), duration: 3500,
duration: 3500, backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)", }).showToast();
}).showToast(); }}
}} >
{$_("delete-scans")}
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-5 h-5"
> >
{$_("delete-scans")} <path
<svg stroke-linecap="round"
xmlns="http://www.w3.org/2000/svg" stroke-linejoin="round"
fill="none" d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
viewBox="0 0 24 24" />
stroke-width="1.5" </svg>
stroke="currentColor" </button>
class="w-5 h-5" {/if}
> <div class="overflow-x-auto">
<path <table class="w-full">
stroke-linecap="round" <thead>
stroke-linejoin="round" {#each $table.getHeaderGroups() as headerGroup}
d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0" <tr class="select-none">
/> <th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
</svg> <InputElement
</button> type="checkbox"
{/if} checked={$table.getIsAllRowsSelected()}
<div class="overflow-x-auto"> indeterminate={$table.getIsSomeRowsSelected()}
<table class="w-full"> on:change={() => $table.toggleAllRowsSelected()}
<thead> />
{#each $table.getHeaderGroups() as headerGroup} </th>
<tr class="select-none"> {#each headerGroup.headers as header}
<th class="inset-y-0 left-0 px-4 py-2 text-left w-px"> <TableHeader {header} />
<InputElement {/each}
type="checkbox" </tr>
checked={$table.getIsAllRowsSelected()} {/each}
indeterminate={$table.getIsSomeRowsSelected()} </thead>
on:change={() => $table.toggleAllRowsSelected()} <tbody>
/> {#each $table.getRowModel().rows as row}
</th> <tr>
{#each headerGroup.headers as header} <td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
<TableHeader {header} /> <InputElement
{/each} type="checkbox"
</tr> checked={row.getIsSelected()}
{/each} on:change={() => row.toggleSelected()}
</thead> />
<tbody> </td>
{#each $table.getRowModel().rows as row} {#each row.getVisibleCells() as cell}
<tr> <td>
<td class="inset-y-0 left-0 px-4 py-2 text-center w-px"> <svelte:component
<InputElement this={flexRender(
type="checkbox" cell.column.columnDef.cell,
checked={row.getIsSelected()} cell.getContext()
on:change={() => row.toggleSelected()} )}
/> />
</td> </td>
{#each row.getVisibleCells() as cell} {/each}
<td> </tr>
<svelte:component {/each}
this={flexRender( </tbody>
cell.column.columnDef.cell, </table>
cell.getContext()
)}
/>
</td>
{/each}
</tr>
{/each}
</tbody>
</table>
</div>
<TableBottom {table} {selected} />
{/if}
{:catch error}
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
<span class="inline-block align-middle mr-8">
<b class="capitalize">{$_("general_promise_error")}</b>
{error}
</span>
</div> </div>
{/await} <TableBottom {table} {selected} />
{/if}
{/if} {/if}