Skip to content

Commit

Permalink
Represent the current page number in the url in the resources and ass…
Browse files Browse the repository at this point in the history
…essment results tabs (#41)

* Add Page Param, Fix Table Column Width

* Add page param as page data
  • Loading branch information
70mm1 authored Sep 11, 2023
1 parent 2828d56 commit aded042
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 157 deletions.
248 changes: 132 additions & 116 deletions src/routes/(app)/cloud/[id]/assessments/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
import { Icon } from '@steeze-ui/svelte-icon';
import type { AssessmentResult } from '$lib/api/assessment';
import Button from '$lib/components/Button.svelte';
import { page } from '$app/stores';
import { goto } from '$app/navigation';
export let data: PageData;
let currentPage = 1;
$: currentPage = data.page ? data.page : 1;
let rowsPerPage = 9;
$: totalPages = Math.ceil(filteredData.length / rowsPerPage);
$: filteredData =
data.filterIds === undefined &&
Expand All @@ -24,27 +27,34 @@
);
});
$: totalPages = Math.ceil(filteredData.length / rowsPerPage);
$: currentData = paginate(filteredData, currentPage);
function paginate(results: AssessmentResult[], page: number) {
const startIndex = (page - 1) * rowsPerPage;
const endIndex = startIndex + rowsPerPage;
return results.slice(startIndex, endIndex);
}
function prevPage() {
if (currentPage > 1) {
currentPage--;
updatePageQuery(currentPage);
}
}
function nextPage() {
if (currentPage < totalPages) {
currentPage++;
updatePageQuery(currentPage);
}
}
function updatePageQuery(currentPage: number) {
$page.url.searchParams.set('page', String(currentPage));
goto(`?${$page.url.searchParams.toString()}`);
}
let showModalId: string | null = null;
function showDetails(id: string) {
Expand All @@ -62,125 +72,131 @@
</StarterHint>
{:else}
<main>
<table class="min-w-full divide-y divide-gray-200 table-fixed">
<thead class="bg-gray-50">
<tr>
{#if showModalId != null}
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-40"
>
Details
</th>
{:else}
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-40"
>
Compliance
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 tracking-wider uppercase w-50"
>
Time
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 tracking-wider uppercase w-50"
>
Metric
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-50"
>
Resource Name
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-50"
>
Type
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-50"
/>
{/if}
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{#each currentData as assessment}
{#if showModalId == assessment.id}
<div class="-mx-4 -my-2 overflow-x-clip sm:-mx-6 lg:-mx-8">
<div class="inline-block py-2 align-middle sm:px-6 lg:px-8 min-w-full">
<table class="min-w-full divide-y divide-gray-200 table-fixed">
<thead class="bg-gray-50">
<tr>
<div
class=" inset-0 flex items-center justify-center bg-gray-100 bg-opacity-75 max-w-80"
>
<div class="bg-white rounded shadow-lg p-6">
<pre class="overflow-y-auto bg-gray-100 rounded p-4">
{JSON.stringify(assessment, null, 5)}
</pre>
<Button on:click={closeModal}>Close</Button>
</div>
</div>
</tr>
{:else}
<tr>
<td class="px-6 py-4 whitespace-nowrap">
{#if assessment.compliant}
<Icon src={CheckCircle} theme="solid" class="h-5 w-5 mr-2 text-green-800" />
{:else}
<Icon src={XCircle} theme="solid" class="h-5 w-5 mr-2 text-red-800" />
{/if}
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="text-sm text-gray-900"
>{new Date(assessment.timestamp).toLocaleString()}</span
{#if showModalId != null}
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 tracking-wider"
>
Details
</th>
{:else}
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 tracking-wider w-1/12"
>
Compliance
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 tracking-wider w-1/12"
>
Time
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 tracking-wider w-3/12"
>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="text-sm text-gray-900">
<a href="/metrics/{assessment.metricId}">
{data.metrics.get(assessment.metricId)?.name ?? assessment.metricId}
</a>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="text-sm text-gray-900"
>{assessment.resourceId.split('/')[
assessment.resourceId.split('/').length - 1
]}</span
Metric
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 tracking-wider w-3/12"
>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="text-sm text-gray-900">{assessment.resourceTypes[0]}</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<Button on:click={() => showDetails(assessment.id)}>More Details</Button>
</td>
Resource Name
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 tracking-wider w-2/12"
>
Type
</th>
<th
scope="col"
class="px-6 py-3 text-left text-xs font-medium text-gray-500 tracking-wider w-1/12"
/>
{/if}
</tr>
{/if}
{/each}
</tbody>
</table>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{#each currentData as assessment}
{#if showModalId == assessment.id}
<tr>
<div
class=" inset-0 flex items-center justify-center bg-gray-100 bg-opacity-75 max-w-80"
>
<div class="bg-white rounded shadow-lg p-6">
<pre class="overflow-y-auto bg-gray-100 rounded p-4">
{JSON.stringify(assessment, null, 5)}
</pre>
<Button on:click={closeModal}>Close</Button>
</div>
</div>
</tr>
{:else}
<tr>
<td class="px-6 py-4 whitespace-nowrap">
{#if assessment.compliant}
<Icon src={CheckCircle} theme="solid" class="h-5 w-5 mr-2 text-green-800" />
{:else}
<Icon src={XCircle} theme="solid" class="h-5 w-5 mr-2 text-red-800" />
{/if}
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="text-sm text-gray-900"
>{new Date(assessment.timestamp).toLocaleString()}</span
>
</td>
<td class="px-6 py-4 whitespace-nowrap truncate max-w-0">
<span class="text-sm text-gray-900">
<a href="/metrics/{assessment.metricId}">
{data.metrics.get(assessment.metricId)?.name ?? assessment.metricId}
</a>
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap truncate max-w-xs">
<span class="text-sm text-gray-900"
>{assessment.resourceId.split('/')[
assessment.resourceId.split('/').length - 1
]}</span
>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="text-sm text-gray-900">{assessment.resourceTypes[0]}</span>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<Button on:click={() => showDetails(assessment.id)}>More Details</Button>
</td>
</tr>
{/if}
{/each}
</tbody>
</table>

<div class="mt-4">
<button
class="px-4 py-2 text-sm font-medium text-gray-500 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:bg-gray-200"
on:click={prevPage}
disabled={currentPage === 1}
>
Previous
</button>
<span class="mx-2 text-gray-500">{currentPage} / {totalPages}</span>
<button
class="px-4 py-2 text-sm font-medium text-gray-500 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:bg-gray-200"
on:click={nextPage}
disabled={currentPage === totalPages}
>
Next
</button>
<div class="mt-4">
<button
class={'px-4 py-2 text-sm font-medium text-gray-500 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:bg-gray-200' +
(currentPage === 1 ? ' cursor-not-allowed opacity-50' : '')}
on:click={prevPage}
disabled={currentPage === 1}
>
Previous
</button>
<span class="mx-2 text-gray-500">{currentPage} / {totalPages}</span>
<button
class={'px-4 py-2 text-sm font-medium text-gray-500 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:bg-gray-200' +
(currentPage === totalPages ? ' cursor-not-allowed opacity-50' : '')}
on:click={nextPage}
disabled={currentPage === totalPages}
>
Next
</button>
</div>
</div>
</div>
</main>
{/if}
2 changes: 2 additions & 0 deletions src/routes/(app)/cloud/[id]/assessments/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ export const load = (async ({ fetch, params, url }) => {

const filterIds = url.searchParams.get('filterIds')?.split(',');
const filterResourceId = url.searchParams.get('filterResourceId');
const page = Number(url.searchParams.get('page'));
const results = await listCloudServiceAssessmentResults(params.id, fetch);

return {
filterIds,
filterResourceId,
page,
results
};
}) satisfies PageLoad;
Loading

0 comments on commit aded042

Please sign in to comment.