-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ALS-5911] Api Page refactor
- Loading branch information
Showing
42 changed files
with
640 additions
and
137 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<script lang="ts"> | ||
import { clipboard } from '@skeletonlabs/skeleton'; | ||
export let buttonText = 'Copy'; | ||
export let itemToCopy: string; | ||
export let classes: string[] = ['variant-ringed-primary']; | ||
let timer: ReturnType<typeof setTimeout>; | ||
function debounce(text: string) { | ||
clearTimeout(timer); | ||
timer = setTimeout(() => { | ||
buttonText = text; | ||
}, 4500); | ||
} | ||
function updateCopyButtonText() { | ||
debounce(buttonText); | ||
buttonText = 'Copied!'; | ||
} | ||
</script> | ||
|
||
<button | ||
type="button" | ||
data-testid="copy-button" | ||
class={'btn ' + classes.join(' ')} | ||
on:click={updateCopyButtonText} | ||
use:clipboard={itemToCopy} | ||
> | ||
{buttonText} | ||
</button> |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
<script lang="ts"> | ||
import { | ||
type ToastSettings, | ||
type ModalSettings, | ||
getModalStore, | ||
getToastStore, | ||
ProgressRadial, | ||
} from '@skeletonlabs/skeleton'; | ||
import * as api from '$lib/api'; | ||
import type { User } from '../models/User'; | ||
import CopyButton from './CopyButton.svelte'; | ||
import ErrorAlert from './ErrorAlert.svelte'; | ||
type LongTermTokenResponse = { | ||
userLongTermToken: string; | ||
}; | ||
const modalStore = getModalStore(); | ||
const toastStore = getToastStore(); | ||
let rows = 1; | ||
let account = ''; | ||
let placeHolderToken = | ||
'•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••'; | ||
let textarea: HTMLTextAreaElement; | ||
let revealed = false; | ||
let refreshButtonDisabled = false; | ||
let refreshButtonText = 'Refresh'; | ||
let user: User; | ||
$: displayedToken = revealed ? user?.token : placeHolderToken; | ||
$: revealButtonText = revealed ? 'Hide' : 'Reveal'; | ||
$: expires = user && user.token ? extractExperationDate(user.token) : 0; | ||
$: badge = expires && checkIfExpired(); | ||
$: account = user?.email || 'There was an error retrieving your account.'; | ||
function checkIfExpired() { | ||
if (!expires || expires === 0) { | ||
return 'unknown'; | ||
} | ||
const daysLeftOnToken = Math.floor((expires - Date.now()) / (1000 * 60 * 60 * 24)); | ||
if (expires < Date.now()) { | ||
return 'expired'; | ||
} else if (daysLeftOnToken < 7) { | ||
return 'expiring soon'; | ||
} else { | ||
return 'valid for ' + daysLeftOnToken + ' more days'; | ||
} | ||
} | ||
function confirmRefreshToken() { | ||
const modal: ModalSettings = { | ||
type: 'confirm', | ||
title: 'Please Confirm', | ||
body: 'Are you sure you wish to invalidate your old token and create a new one?', | ||
response: (r: boolean) => r && refreshToken(), | ||
}; | ||
modalStore.trigger(modal); | ||
} | ||
function extractExperationDate(token: string) { | ||
if (!token) return 0; | ||
try { | ||
return JSON.parse(atob(token.split('.')[1])).exp * 1000; | ||
} catch (error) { | ||
console.error(error); | ||
const extractExperationDateErrorToast: ToastSettings = { | ||
message: | ||
'An error occured while parsing your token. Please try again later. If this problem persists, please contact an administrator.', | ||
background: 'variant-filled-error', | ||
}; | ||
toastStore.trigger(extractExperationDateErrorToast); | ||
return 0; //TODO: Handle errors | ||
} | ||
} | ||
async function getUser(): Promise<User> { | ||
return await api | ||
.get('/psama/user/me?hasToken') | ||
.then((response: User) => { | ||
user = response; | ||
return response; | ||
}) | ||
.catch((error) => { | ||
console.error('Error getting user:\n', error); | ||
throw error; | ||
}); | ||
} | ||
async function refreshToken() { | ||
const newLongTermToken = await api | ||
.get('/psama/user/me/refresh_long_term_token') | ||
.then((response: LongTermTokenResponse) => { | ||
return response.userLongTermToken; | ||
}) | ||
.catch((error) => { | ||
console.error(error); | ||
return; | ||
}); | ||
if (!newLongTermToken) { | ||
refreshButtonText = 'Error'; | ||
const refreshErrorToast: ToastSettings = { | ||
message: | ||
'An error occured while refreshing your token. Please try again later. If this problem persists, please contact an administrator.', | ||
background: 'variant-filled-error', | ||
}; | ||
toastStore.trigger(refreshErrorToast); | ||
return; | ||
} | ||
user.token = newLongTermToken; | ||
refreshButtonText = 'Refreshed!'; | ||
refreshButtonDisabled = true; | ||
rows = updateRows(); | ||
} | ||
function revealToken() { | ||
revealed = !revealed; | ||
rows = updateRows(); | ||
} | ||
function updateRows() { | ||
if (!revealed || !user.token) return 1; | ||
let fontSizeInPt = +window.getComputedStyle(textarea).fontSize.split('px')[0] * 0.75; | ||
return Math.ceil((user.token.length * (fontSizeInPt - 1)) / textarea.clientWidth); | ||
} | ||
</script> | ||
|
||
<div id="user-token-container"> | ||
{#await getUser()} | ||
<ProgressRadial width="w-10" value={undefined} /> | ||
{:then} | ||
<div id="user-token" class="card variant-filled-sureface"> | ||
<header class="card-header">PIC-SURE Token</header> | ||
<section class="p-4 grid grid-cols-2 gap-y-2 items-center"> | ||
<label for="account">Account:</label> | ||
<span id="account" class="w-full">{account}</span> | ||
<label for="token">Token:</label> | ||
<textarea id="token" bind:value={displayedToken} bind:this={textarea} {rows} disabled | ||
></textarea> | ||
<label for="expires">Expires:</label> | ||
<div> | ||
<span id="expires" class="w-1/3 mr-2" | ||
>{new Date(expires).toString().substring(0, 24)}</span | ||
> | ||
{#if badge} | ||
<span id="expires-badge" class="badge {badge}" data-testid="expires-badge" | ||
>{badge.toUpperCase()}</span | ||
> | ||
{/if} | ||
</div> | ||
</section> | ||
<footer class="card-footer"> | ||
<CopyButton | ||
buttonText="Copy" | ||
itemToCopy={user.token || ''} | ||
classes={['variant-ringed-primary']} | ||
/> | ||
<button | ||
id="refresh-button" | ||
class="btn variant-ringed-primary" | ||
on:click={confirmRefreshToken} | ||
disabled={refreshButtonDisabled}>{refreshButtonText}</button | ||
> | ||
<button id="reveal-button" class="btn variant-ringed-primary" on:click={revealToken} | ||
>{revealButtonText}</button | ||
> | ||
</footer> | ||
</div> | ||
{:catch} | ||
<ErrorAlert | ||
title="An error occured while to retrieving your account. If this problem persists, please | ||
contact an administrator." | ||
/> | ||
{/await} | ||
</div> | ||
|
||
<style> | ||
#user-token-container { | ||
display: flex; | ||
justify-content: center; | ||
width: 52rem; | ||
} | ||
#user-token-container #user-token { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
padding: 1rem; | ||
} | ||
#user-token-container #user-token section { | ||
min-width: 50rem; | ||
grid-template-columns: min-content auto; | ||
} | ||
#user-token-container #user-token section textarea { | ||
max-width: 48rem; | ||
word-wrap: break-word; | ||
height: fit-content; | ||
} | ||
#user-token-container #user-token section label { | ||
text-align: right; | ||
clear: both; | ||
float: left; | ||
margin-right: 15px; | ||
} | ||
</style> |
2 changes: 1 addition & 1 deletion
2
...lib/component/dataset/cell/actions.svelte → ...ib/components/dataset/cell/Actions.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<script lang="ts"> | ||
import CopyButton from '$lib/components/CopyButton.svelte'; | ||
export let data = { cell: '', row: {} }; | ||
let buttonText = 'Copy'; | ||
const buttonClasses = ['w-24', 'bg-primary-500', 'text-on-primary-token']; | ||
</script> | ||
|
||
<div class="flex justify-between items-center"> | ||
<span class="uuid">{data.cell}</span> | ||
<CopyButton {buttonText} itemToCopy={data.cell} classes={buttonClasses} /> | ||
</div> |
12 changes: 6 additions & 6 deletions
12
src/lib/component/datatable/table.svelte → src/lib/components/datatable/Table.svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.