Skip to content

Commit 0350bac

Browse files
authored
Fix/control panel styling (#330)
* fix: evoting groups * fix: search UI & pagination
1 parent 1448443 commit 0350bac

File tree

1 file changed

+197
-92
lines changed

1 file changed

+197
-92
lines changed

infrastructure/control-panel/src/routes/+page.svelte

Lines changed: 197 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,81 @@
1919
let platformsError = $state<string | null>(null);
2020
let mappedData = $state<any[]>([]);
2121
22+
// Pagination for eVaults
23+
let currentPage = $state(1);
24+
let itemsPerPage = $state(10);
25+
let totalPages = $state(1);
26+
2227
// Track selected items
2328
let selectedEVaults = $state<number[]>([]);
2429
let selectedPlatforms = $state<number[]>([]);
2530
26-
const mappedPlatformsData = $derived(
27-
platforms.map((platform) => ({
31+
// Filtered data for search
32+
let filteredEVaults = $derived(() => {
33+
if (!evaultsSearchValue.trim()) return evaults;
34+
return evaults.filter(
35+
(evault) =>
36+
evault.name.toLowerCase().includes(evaultsSearchValue.toLowerCase()) ||
37+
evault.evaultId.toLowerCase().includes(evaultsSearchValue.toLowerCase()) ||
38+
evault.namespace.toLowerCase().includes(evaultsSearchValue.toLowerCase())
39+
);
40+
});
41+
42+
let filteredPlatforms = $derived(() => {
43+
if (!platformsSearchQuery.trim()) return platforms;
44+
return platforms.filter(
45+
(platform) =>
46+
platform.name.toLowerCase().includes(platformsSearchQuery.toLowerCase()) ||
47+
platform.status.toLowerCase().includes(platformsSearchQuery.toLowerCase())
48+
);
49+
});
50+
51+
// Paginated eVaults
52+
let paginatedEVaults = $derived(() => {
53+
const startIndex = (currentPage - 1) * itemsPerPage;
54+
const endIndex = startIndex + itemsPerPage;
55+
const filtered = filteredEVaults();
56+
return filtered.slice(startIndex, endIndex);
57+
});
58+
59+
// Update total pages when filtered data changes
60+
$effect(() => {
61+
const filtered = filteredEVaults();
62+
totalPages = Math.ceil(filtered.length / itemsPerPage);
63+
if (currentPage > totalPages && totalPages > 0) {
64+
currentPage = totalPages;
65+
}
66+
});
67+
68+
// Mapped data for eVaults table
69+
let mappedEVaultsData = $derived(() => {
70+
const paginated = paginatedEVaults();
71+
return paginated.map((evault) => ({
72+
eName: {
73+
type: 'text',
74+
value: evault.evaultId,
75+
className: 'cursor-pointer text-blue-600 hover:text-blue-800 hover:underline'
76+
},
77+
Uptime: {
78+
type: 'text',
79+
value: evault.age
80+
},
81+
IP: {
82+
type: 'text',
83+
value: evault.ip
84+
},
85+
URI: {
86+
type: 'link',
87+
value: evault.serviceUrl || 'N/A',
88+
link: evault.serviceUrl || '#',
89+
external: true
90+
}
91+
}));
92+
});
93+
94+
const mappedPlatformsData = $derived(() => {
95+
const filtered = filteredPlatforms();
96+
return filtered.map((platform) => ({
2897
Name: {
2998
type: 'text',
3099
value: platform.name
@@ -43,15 +112,19 @@
43112
link: platform.url,
44113
external: true
45114
}
46-
}))
47-
);
115+
}));
116+
});
48117
49118
const handlePreviousPage = async () => {
50-
alert('Previous btn clicked. Make a call to your server to fetch data.');
119+
if (currentPage > 1) {
120+
currentPage--;
121+
}
51122
};
52123
53124
const handleNextPage = async () => {
54-
alert('Next btn clicked. Make a call to your server to fetch data.');
125+
if (currentPage < totalPages) {
126+
currentPage++;
127+
}
55128
};
56129
57130
const tableHeadings = ['eName', 'Uptime', 'IP', 'URI'];
@@ -249,92 +322,124 @@
249322
});
250323
</script>
251324

252-
<section class="flex flex-col gap-7">
253-
<TableCard>
254-
<TableCardHeader
255-
title="eVaults"
256-
placeholder="Search eVaults"
257-
bind:searchValue={evaultsSearchValue}
258-
rightTitle={selectedEVaults.length > 0
259-
? `${selectedEVaults.length} eVault${selectedEVaults.length === 1 ? '' : 's'} selected`
260-
: 'Monitoring all eVault pods across Kubernetes clusters'}
261-
showClearSelection={selectedEVaults.length > 0}
262-
onClearSelection={clearEVaultSelection}
263-
/>
264-
265-
{#if isLoading}
266-
<div class="flex justify-center py-8">
267-
<div class="h-8 w-8 animate-spin rounded-full border-b-2 border-blue-600"></div>
268-
</div>
269-
{:else if error}
270-
<div class="py-8 text-center text-red-500">
271-
{error}
272-
<button
273-
onclick={fetchEVaults}
274-
class="ml-4 rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
275-
>
276-
Retry
277-
</button>
278-
</div>
279-
{:else if evaults.length === 0}
280-
<div class="py-8 text-center text-gray-500">
281-
No eVault pods found. Make sure kubectl is configured and eVault pods are running.
282-
</div>
283-
{:else}
284-
<Table
285-
class="mb-7"
286-
tableData={mappedData}
287-
withSelection={true}
288-
{handlePreviousPage}
289-
{handleNextPage}
290-
handleSelectedRow={handleEVaultRowClick}
291-
onSelectionChange={handleEVaultSelectionChange}
292-
onSelectAllChange={handleSelectAllEVaults}
293-
selectedIndices={selectedEVaults}
325+
<section class="flex gap-7">
326+
<!-- Left Column: eVaults -->
327+
<div class="flex-1">
328+
<TableCard>
329+
<TableCardHeader
330+
title="eVaults"
331+
placeholder="Search eVaults"
332+
bind:searchValue={evaultsSearchValue}
333+
rightTitle={selectedEVaults.length > 0
334+
? `${selectedEVaults.length} eVault${selectedEVaults.length === 1 ? '' : 's'} selected`
335+
: 'Monitoring all eVault pods across Kubernetes clusters'}
336+
showClearSelection={selectedEVaults.length > 0}
337+
onClearSelection={clearEVaultSelection}
294338
/>
295-
{/if}
296-
</TableCard>
297-
298-
<TableCard>
299-
<TableCardHeader
300-
title="Platforms"
301-
placeholder="Search Platforms"
302-
bind:searchValue={platformsSearchQuery}
303-
rightTitle={selectedPlatforms.length > 0
304-
? `${selectedPlatforms.length} platform${selectedPlatforms.length === 1 ? '' : 's'} selected`
305-
: 'No platform selected. Select a platform to monitor logs'}
306-
showClearSelection={selectedPlatforms.length > 0}
307-
onClearSelection={clearPlatformSelection}
308-
/>
309-
{#if platformsLoading}
310-
<div class="flex justify-center py-8">
311-
<div class="h-8 w-8 animate-spin rounded-full border-b-2 border-blue-600"></div>
312-
</div>
313-
{:else if platformsError}
314-
<div class="py-8 text-center text-red-500">
315-
{platformsError}
316-
<button
317-
onclick={fetchPlatforms}
318-
class="ml-4 rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
319-
>
320-
Retry
321-
</button>
322-
</div>
323-
{:else if platforms.length === 0}
324-
<div class="py-8 text-center text-gray-500">
325-
No platforms found. Make sure the registry service is running.
326-
</div>
327-
{:else}
328-
<Table
329-
class="mb-7"
330-
tableData={mappedPlatformsData}
331-
withSelection={true}
332-
{handlePreviousPage}
333-
{handleNextPage}
334-
onSelectionChange={handlePlatformSelectionChange}
335-
onSelectAllChange={handleSelectAllPlatforms}
336-
selectedIndices={selectedPlatforms}
339+
340+
{#if isLoading}
341+
<div class="flex justify-center py-8">
342+
<div class="h-8 w-8 animate-spin rounded-full border-b-2 border-blue-600"></div>
343+
</div>
344+
{:else if error}
345+
<div class="py-8 text-center text-red-500">
346+
{error}
347+
<button
348+
onclick={fetchEVaults}
349+
class="ml-4 rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
350+
>
351+
Retry
352+
</button>
353+
</div>
354+
{:else if evaults.length === 0}
355+
<div class="py-8 text-center text-gray-500">
356+
No eVault pods found. Make sure kubectl is configured and eVault pods are
357+
running.
358+
</div>
359+
{:else}
360+
<Table
361+
class="mb-4"
362+
tableData={mappedEVaultsData}
363+
withSelection={true}
364+
{handlePreviousPage}
365+
{handleNextPage}
366+
handleSelectedRow={handleEVaultRowClick}
367+
onSelectionChange={handleEVaultSelectionChange}
368+
onSelectAllChange={handleSelectAllEVaults}
369+
selectedIndices={selectedEVaults}
370+
/>
371+
372+
<!-- Pagination Info -->
373+
<div class="mb-4 flex items-center justify-between text-sm text-gray-600">
374+
<div>
375+
Showing {(currentPage - 1) * itemsPerPage + 1} - {Math.min(
376+
currentPage * itemsPerPage,
377+
filteredEVaults().length
378+
)} of {filteredEVaults().length} eVaults
379+
</div>
380+
<div class="flex gap-2">
381+
<button
382+
onclick={handlePreviousPage}
383+
disabled={currentPage <= 1}
384+
class="rounded border px-3 py-1 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50"
385+
>
386+
Previous
387+
</button>
388+
<span class="px-3 py-1">Page {currentPage} of {totalPages}</span>
389+
<button
390+
onclick={handleNextPage}
391+
disabled={currentPage >= totalPages}
392+
class="rounded border px-3 py-1 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-50"
393+
>
394+
Next
395+
</button>
396+
</div>
397+
</div>
398+
{/if}
399+
</TableCard>
400+
</div>
401+
402+
<!-- Right Column: Platforms -->
403+
<div class="flex-1">
404+
<TableCard>
405+
<TableCardHeader
406+
title="Platforms"
407+
placeholder="Search Platforms"
408+
bind:searchValue={platformsSearchQuery}
409+
rightTitle={selectedPlatforms.length > 0
410+
? `${selectedPlatforms.length} platform${selectedPlatforms.length === 1 ? '' : 's'} selected`
411+
: 'No platform selected. Select a platform to monitor logs'}
412+
showClearSelection={selectedPlatforms.length > 0}
413+
onClearSelection={clearPlatformSelection}
337414
/>
338-
{/if}
339-
</TableCard>
415+
{#if platformsLoading}
416+
<div class="flex justify-center py-8">
417+
<div class="h-8 w-8 animate-spin rounded-full border-b-2 border-blue-600"></div>
418+
</div>
419+
{:else if platformsError}
420+
<div class="py-8 text-center text-red-500">
421+
{platformsError}
422+
<button
423+
onclick={fetchPlatforms}
424+
class="ml-4 rounded bg-blue-600 px-4 py-2 text-white hover:bg-blue-700"
425+
>
426+
Retry
427+
</button>
428+
</div>
429+
{:else if platforms.length === 0}
430+
<div class="py-8 text-center text-gray-500">
431+
No platforms found. Make sure the registry service is running.
432+
</div>
433+
{:else}
434+
<Table
435+
class="mb-4"
436+
tableData={mappedPlatformsData}
437+
withSelection={true}
438+
onSelectionChange={handlePlatformSelectionChange}
439+
onSelectAllChange={handleSelectAllPlatforms}
440+
selectedIndices={selectedPlatforms}
441+
/>
442+
{/if}
443+
</TableCard>
444+
</div>
340445
</section>

0 commit comments

Comments
 (0)