mirror of
https://github.com/LukeHagar/idn-admin-console.git
synced 2025-12-06 04:20:02 +00:00
Update package version, updated Logout function to delete cookies, Cleaned Logs, Added Breadcrumbs, Added Pagination to sources, Cleaned Styles, and improve code structure
This commit is contained in:
@@ -6,7 +6,7 @@ export function formatDate(date: string | null | undefined) {
|
||||
}
|
||||
|
||||
export function getLimit(url: URL) {
|
||||
return url.searchParams.get('limit') || '10';
|
||||
return url.searchParams.get('limit') || '250';
|
||||
}
|
||||
|
||||
export function getFilters(url: URL) {
|
||||
|
||||
@@ -17,14 +17,14 @@ export const actions = {
|
||||
const sessionString = cookies.get('idnSession');
|
||||
|
||||
if (sessionString) {
|
||||
console.log('sessionString', sessionString);
|
||||
// console.log('sessionString', sessionString);
|
||||
|
||||
const session = JSON.parse(sessionString);
|
||||
if (session.org == tenant) {
|
||||
console.debug('Credential Cache Hit');
|
||||
// console.debug('Credential Cache Hit');
|
||||
throw redirect(302, '/home');
|
||||
} else {
|
||||
console.debug('Credential Cache Miss');
|
||||
// console.debug('Credential Cache Miss');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ export const load: PageServerLoad = async ({ url, cookies }) => {
|
||||
});
|
||||
|
||||
const idnSession: IdnSession = response.data as IdnSession;
|
||||
console.log(idnSession);
|
||||
// console.log(idnSession);
|
||||
cookies.set('idnSession', JSON.stringify(idnSession));
|
||||
|
||||
return { idnSession, counterList };
|
||||
|
||||
@@ -1,6 +1,25 @@
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import LeftSidebar from '$lib/sidebar/LeftSidebar.svelte';
|
||||
import { AppBar, AppShell, LightSwitch } from '@skeletonlabs/skeleton';
|
||||
import { AppBar, AppShell, Avatar, LightSwitch } from '@skeletonlabs/skeleton';
|
||||
|
||||
let crumbs: Array<{ label: string; href: string }> = [];
|
||||
|
||||
$: {
|
||||
// Remove zero-length tokens.
|
||||
const tokens = $page.url.pathname.split('/').filter((t) => t !== '');
|
||||
|
||||
// Create { label, href } pairs for each token.
|
||||
let tokenPath = '';
|
||||
crumbs = tokens.map((t) => {
|
||||
tokenPath += '/' + t;
|
||||
t = t.charAt(0).toUpperCase() + t.slice(1);
|
||||
return { label: t, href: tokenPath };
|
||||
});
|
||||
|
||||
// Add a way to get home too.
|
||||
// crumbs.unshift({ label: 'Home', href: '/' });
|
||||
}
|
||||
</script>
|
||||
|
||||
<AppShell>
|
||||
@@ -12,7 +31,8 @@
|
||||
<p class="text-xl">IdentityNow Admin Console</p>
|
||||
<svelte:fragment slot="trail">
|
||||
<LightSwitch />
|
||||
<a href="/logout" class="btn variant-filled-primary !text-white text-lg">Logout</a>
|
||||
<Avatar width="w-10" />
|
||||
<a href="/logout" class="btn variant-filled-primary !text-white text-xs">Logout</a>
|
||||
</svelte:fragment>
|
||||
</AppBar>
|
||||
</svelte:fragment>
|
||||
@@ -22,8 +42,23 @@
|
||||
<!-- <svelte:fragment slot="sidebarRight">Sidebar Right</svelte:fragment> -->
|
||||
<!-- <svelte:fragment slot="pageHeader">Page Header</svelte:fragment> -->
|
||||
<!-- Router Slot -->
|
||||
<div class="h-full">
|
||||
<slot />
|
||||
<div class="max-h-screen">
|
||||
<div class="pl-2 pt-2 pr-2">
|
||||
<ol class="breadcrumb card p-2">
|
||||
{#each crumbs as crumb, i}
|
||||
<!-- If crumb index is less than the breadcrumb length minus 1 -->
|
||||
{#if i < crumbs.length - 1}
|
||||
<li class="crumb"><a class="anchor" href={crumb.href}>{crumb.label}</a></li>
|
||||
<li class="crumb-separator" aria-hidden>›</li>
|
||||
{:else}
|
||||
<li class="crumb">{crumb.label}</li>
|
||||
{/if}
|
||||
{/each}
|
||||
</ol>
|
||||
</div>
|
||||
<div class="p-2">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
<!-- ---- / ---- -->
|
||||
<!-- <svelte:fragment slot="pageFooter">Page Footer</svelte:fragment> -->
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { reports } from '$lib/sidebar/reports';
|
||||
</script>
|
||||
|
||||
<div class="flex flex-row flex-wrap gap-4 p-4 justify-center">
|
||||
<div class="flex flex-row flex-wrap gap-4 justify-center">
|
||||
{#each reports as report (report.url)}
|
||||
<a
|
||||
class="card card-hover overflow-hidden w-modal-slim"
|
||||
|
||||
@@ -38,117 +38,117 @@
|
||||
let sorters = '';
|
||||
</script>
|
||||
|
||||
<div class="p-4">
|
||||
<div class="card flex justify-center flex-col align-middle">
|
||||
<div class=" p-4 flex flex-row justify-between gap-4 flex-wrap">
|
||||
<div class="flex flex-row gap-1">
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={filters}
|
||||
class="input"
|
||||
title="Filter"
|
||||
type="text"
|
||||
placeholder="Filter"
|
||||
/>
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={sorters}
|
||||
class="input"
|
||||
title="Sorter"
|
||||
type="text"
|
||||
placeholder="Sorter"
|
||||
/>
|
||||
<button on:click={onGo} class="btn variant-filled-primary text-white"> Go </button>
|
||||
</div>
|
||||
<Paginator
|
||||
bind:settings
|
||||
on:page={onPageChange}
|
||||
on:amount={onAmountChange}
|
||||
showNumerals
|
||||
maxNumerals={1}
|
||||
showFirstLastButtons={true}
|
||||
showPreviousNextButtons={true}
|
||||
<div class="card flex justify-center flex-col align-middle">
|
||||
<div class=" p-4 flex flex-row justify-between gap-4 flex-wrap">
|
||||
<div class="flex flex-row gap-1">
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={filters}
|
||||
class="input"
|
||||
title="Filter"
|
||||
type="text"
|
||||
placeholder="Filter"
|
||||
/>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Lifecycle State</th>
|
||||
<th>eMail</th>
|
||||
<th>Created</th>
|
||||
<th>Modified</th>
|
||||
<th />
|
||||
</thead>
|
||||
<tbody class="overflow-hidden">
|
||||
{#each data.identities as identity}
|
||||
<tr>
|
||||
<td>
|
||||
<p class="text-center">{identity.id}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{identity.name}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{identity.lifecycleState?.stateName}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{identity.emailAddress}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{formatDate(identity.created)}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{formatDate(identity.modified)}</p>
|
||||
</td>
|
||||
<td class="flex flex-col justify-center gap-1">
|
||||
<a
|
||||
href={`/home/identities/${identity.id}`}
|
||||
class="btn variant-filled-primary text-white"
|
||||
data-sveltekit-preload-data="hover"
|
||||
>
|
||||
Open
|
||||
</a>
|
||||
<button
|
||||
on:click={() => TriggerSourceViewModal(identity)}
|
||||
class="btn variant-filled-primary text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class=" p-4 flex flex-row justify-between gap-4 flex-wrap">
|
||||
<div class="flex flex-row gap-1">
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={filters}
|
||||
class="input"
|
||||
title="Filter"
|
||||
type="text"
|
||||
placeholder="Filter"
|
||||
/>
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={sorters}
|
||||
class="input"
|
||||
title="Sorter"
|
||||
type="text"
|
||||
placeholder="Sorter"
|
||||
/>
|
||||
<button on:click={onGo} class="btn variant-filled-primary text-white"> Go </button>
|
||||
</div>
|
||||
<Paginator
|
||||
bind:settings
|
||||
on:page={onPageChange}
|
||||
on:amount={onAmountChange}
|
||||
showNumerals
|
||||
maxNumerals={1}
|
||||
showFirstLastButtons={true}
|
||||
showPreviousNextButtons={true}
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={sorters}
|
||||
class="input"
|
||||
title="Sorter"
|
||||
type="text"
|
||||
placeholder="Sorter"
|
||||
/>
|
||||
<button on:click={onGo} class="btn variant-filled-primary text-white"> Go </button>
|
||||
</div>
|
||||
<p class="my-auto">Total Count: {data.totalCount}</p>
|
||||
<Paginator
|
||||
bind:settings
|
||||
on:page={onPageChange}
|
||||
on:amount={onAmountChange}
|
||||
showNumerals
|
||||
maxNumerals={1}
|
||||
showFirstLastButtons={true}
|
||||
showPreviousNextButtons={true}
|
||||
/>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Lifecycle State</th>
|
||||
<th>eMail</th>
|
||||
<th>Created</th>
|
||||
<th>Modified</th>
|
||||
<th />
|
||||
</thead>
|
||||
<tbody class="overflow-hidden">
|
||||
{#each data.identities as identity}
|
||||
<tr>
|
||||
<td>
|
||||
<p class="text-center">{identity.id}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{identity.name}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{identity.lifecycleState?.stateName}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{identity.emailAddress}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{formatDate(identity.created)}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{formatDate(identity.modified)}</p>
|
||||
</td>
|
||||
<td class="flex flex-col justify-center gap-1">
|
||||
<a
|
||||
href={`/home/identities/${identity.id}`}
|
||||
class="btn variant-filled-primary text-white"
|
||||
data-sveltekit-preload-data="hover"
|
||||
>
|
||||
Open
|
||||
</a>
|
||||
<button
|
||||
on:click={() => TriggerSourceViewModal(identity)}
|
||||
class="btn variant-filled-primary text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class=" p-4 flex flex-row justify-between gap-4 flex-wrap">
|
||||
<div class="flex flex-row gap-1">
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={filters}
|
||||
class="input"
|
||||
title="Filter"
|
||||
type="text"
|
||||
placeholder="Filter"
|
||||
/>
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={sorters}
|
||||
class="input"
|
||||
title="Sorter"
|
||||
type="text"
|
||||
placeholder="Sorter"
|
||||
/>
|
||||
<button on:click={onGo} class="btn variant-filled-primary text-white"> Go </button>
|
||||
</div>
|
||||
<p class="my-auto">Total Count: {data.totalCount}</p>
|
||||
<Paginator
|
||||
bind:settings
|
||||
on:page={onPageChange}
|
||||
on:amount={onAmountChange}
|
||||
showNumerals
|
||||
maxNumerals={1}
|
||||
showFirstLastButtons={true}
|
||||
showPreviousNextButtons={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -25,8 +25,6 @@ export const load = async ({ cookies, url }) => {
|
||||
|
||||
const apiResponse = await api.listSources(requestParams);
|
||||
|
||||
console.log(apiResponse);
|
||||
|
||||
return {
|
||||
totalCount: apiResponse.headers['x-total-count'],
|
||||
sources: apiResponse.data,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import type { ModalSettings } from '@skeletonlabs/skeleton';
|
||||
import { getModalStore } from '@skeletonlabs/skeleton';
|
||||
import { createOnAmountChange, createOnGo, createOnPageChange } from '$lib/Utils.js';
|
||||
import type { ModalSettings, PaginationSettings } from '@skeletonlabs/skeleton';
|
||||
import { Paginator, getModalStore } from '@skeletonlabs/skeleton';
|
||||
|
||||
const modalStore = getModalStore();
|
||||
|
||||
@@ -18,61 +19,138 @@
|
||||
|
||||
modalStore.trigger(modal);
|
||||
}
|
||||
|
||||
$: onPageChange = createOnPageChange({ ...data.params, filters, sorters }, '/home/identities');
|
||||
$: onAmountChange = createOnAmountChange(
|
||||
{ ...data.params, filters, sorters },
|
||||
'/home/identities'
|
||||
);
|
||||
$: onGo = createOnGo({ ...data.params, filters, sorters }, '/home/identities');
|
||||
|
||||
let settings = {
|
||||
page: Number(data.params.page),
|
||||
limit: Number(data.params.limit),
|
||||
size: data.totalCount,
|
||||
amounts: [10, 50, 100, 250]
|
||||
} satisfies PaginationSettings;
|
||||
|
||||
let filters = '';
|
||||
let sorters = '';
|
||||
</script>
|
||||
|
||||
<div class="p-4">
|
||||
<div class="flex justify-center flex-col align-middle">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Type</th>
|
||||
<th>Authoritative</th>
|
||||
<th>Healthy</th>
|
||||
<th />
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each data.sources as source}
|
||||
<tr>
|
||||
<td>
|
||||
<p class="text-center">{source.id}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{source.name}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{source.description}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{source.type}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{source.authoritative ? 'True' : 'False'}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center font-bold {source.healthy ? 'text-green-500' : 'text-red-500'}">
|
||||
{source.healthy ? 'True' : 'False'}
|
||||
</p>
|
||||
</td>
|
||||
<td class="flex flex-col justify-center gap-1">
|
||||
<a
|
||||
href={`/home/sources/${source.id}`}
|
||||
class="btn variant-filled-primary text-white"
|
||||
data-sveltekit-preload-data="hover"
|
||||
>
|
||||
Open
|
||||
</a>
|
||||
<button
|
||||
on:click={() => TriggerSourceViewModal(source)}
|
||||
class="btn variant-filled-primary text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="card flex justify-center flex-col align-middle">
|
||||
<div class=" p-4 flex flex-row justify-between gap-4 flex-wrap">
|
||||
<div class="flex flex-row gap-1">
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={filters}
|
||||
class="input"
|
||||
title="Filter"
|
||||
type="text"
|
||||
placeholder="Filter"
|
||||
/>
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={sorters}
|
||||
class="input"
|
||||
title="Sorter"
|
||||
type="text"
|
||||
placeholder="Sorter"
|
||||
/>
|
||||
<button on:click={onGo} class="btn variant-filled-primary text-white"> Go </button>
|
||||
</div>
|
||||
<p class="my-auto">Total Count: {data.totalCount}</p>
|
||||
<Paginator
|
||||
bind:settings
|
||||
on:page={onPageChange}
|
||||
on:amount={onAmountChange}
|
||||
showNumerals={true}
|
||||
maxNumerals={1}
|
||||
showFirstLastButtons={true}
|
||||
showPreviousNextButtons={true}
|
||||
/>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>ID</th>
|
||||
<th>Name</th>
|
||||
<th>Description</th>
|
||||
<th>Type</th>
|
||||
<th>Authoritative</th>
|
||||
<th>Healthy</th>
|
||||
<th />
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each data.sources as source}
|
||||
<tr>
|
||||
<td>
|
||||
<p class="text-center">{source.id}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{source.name}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{source.description}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{source.type}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center">{source.authoritative ? 'True' : 'False'}</p>
|
||||
</td>
|
||||
<td>
|
||||
<p class="text-center font-bold {source.healthy ? 'text-green-500' : 'text-red-500'}">
|
||||
{source.healthy ? 'True' : 'False'}
|
||||
</p>
|
||||
</td>
|
||||
<td class="flex flex-col justify-center gap-1">
|
||||
<a
|
||||
href={`/home/sources/${source.id}`}
|
||||
class="btn variant-filled-primary text-white"
|
||||
data-sveltekit-preload-data="hover"
|
||||
>
|
||||
Open
|
||||
</a>
|
||||
<button
|
||||
on:click={() => TriggerSourceViewModal(source)}
|
||||
class="btn variant-filled-primary text-white"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class=" p-4 flex flex-row justify-between gap-4 flex-wrap">
|
||||
<div class="flex flex-row gap-1">
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={filters}
|
||||
class="input"
|
||||
title="Filter"
|
||||
type="text"
|
||||
placeholder="Filter"
|
||||
/>
|
||||
<input
|
||||
on:keydown={onGo}
|
||||
bind:value={sorters}
|
||||
class="input"
|
||||
title="Sorter"
|
||||
type="text"
|
||||
placeholder="Sorter"
|
||||
/>
|
||||
<button on:click={onGo} class="btn variant-filled-primary text-white"> Go </button>
|
||||
</div>
|
||||
<p class="my-auto">Total Count: {data.totalCount}</p>
|
||||
<Paginator
|
||||
bind:settings
|
||||
on:page={onPageChange}
|
||||
on:amount={onAmountChange}
|
||||
showNumerals={true}
|
||||
maxNumerals={1}
|
||||
showFirstLastButtons={true}
|
||||
showPreviousNextButtons={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export const load = async ({ cookies }) => {
|
||||
cookies.delete('session');
|
||||
cookies.delete('idnSession');
|
||||
|
||||
return { sessionLoggedOut: true };
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "idn-admin-console",
|
||||
"description": "A troubleshooting and administration app for IdentityNow",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"private": true,
|
||||
"author": {
|
||||
"name": "Luke Hagar",
|
||||
|
||||
Reference in New Issue
Block a user