-
+
+
+ {#if $loginStore == null}
+
+
+
+ {:else}
+
+
+
{$loginStore.userinfo.name}
+
+
+ {/if}
+
+
+
+
+
{sidebarSelection.name}
+ {#if $loginStore == null}
+
Please login to continue
+ {:else}
+
+ {/if}
-
-
- Check out SvelteKit, the official Svelte app framework powered by Vite!
-
-
-
- Click on the Vite and Svelte logos to learn more
-
-
diff --git a/src/app.css b/src/app.css
deleted file mode 100644
index b87aec7..0000000
--- a/src/app.css
+++ /dev/null
@@ -1,80 +0,0 @@
-:root {
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
- line-height: 1.5;
- font-weight: 400;
-
- color-scheme: light dark;
- color: rgba(255, 255, 255, 0.87);
- background-color: #242424;
-
- font-synthesis: none;
- text-rendering: optimizeLegibility;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- -webkit-text-size-adjust: 100%;
-}
-
-a {
- font-weight: 500;
- color: #646cff;
- text-decoration: inherit;
-}
-a:hover {
- color: #535bf2;
-}
-
-body {
- margin: 0;
- display: flex;
- place-items: center;
- min-width: 320px;
- min-height: 100vh;
-}
-
-h1 {
- font-size: 3.2em;
- line-height: 1.1;
-}
-
-.card {
- padding: 2em;
-}
-
-#app {
- max-width: 1280px;
- margin: 0 auto;
- padding: 2rem;
- text-align: center;
-}
-
-button {
- border-radius: 8px;
- border: 1px solid transparent;
- padding: 0.6em 1.2em;
- font-size: 1em;
- font-weight: 500;
- font-family: inherit;
- background-color: #1a1a1a;
- cursor: pointer;
- transition: border-color 0.25s;
-}
-button:hover {
- border-color: #646cff;
-}
-button:focus,
-button:focus-visible {
- outline: 4px auto -webkit-focus-ring-color;
-}
-
-@media (prefers-color-scheme: light) {
- :root {
- color: #213547;
- background-color: #ffffff;
- }
- a:hover {
- color: #747bff;
- }
- button {
- background-color: #f9f9f9;
- }
-}
diff --git a/src/app.scss b/src/app.scss
new file mode 100644
index 0000000..6ba2807
--- /dev/null
+++ b/src/app.scss
@@ -0,0 +1,46 @@
+$theme-text: rgba(255, 255, 255, 0.87);
+$theme-bg: #242424;
+
+@media (prefers-color-scheme: light) {
+ $theme-text: #213547;
+ $theme-bg: #ffffff;
+}
+
+:root {
+ font-family: Ubuntu, Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ font-size: 16px;
+ line-height: normal;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: $theme-text;
+ background-color: $theme-bg;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-text-size-adjust: 100%;
+}
+
+#app {
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-content: stretch;
+}
+
+a {
+ font-weight: 500;
+ color: tomato;
+ text-decoration: inherit;
+}
+
+a:hover {
+ color: tomato;
+}
+
+body {
+ margin: 0;
+}
diff --git a/src/assets/svelte.svg b/src/assets/svelte.svg
deleted file mode 100644
index c5e0848..0000000
--- a/src/assets/svelte.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/lib/Counter.svelte b/src/lib/Counter.svelte
deleted file mode 100644
index 979b4df..0000000
--- a/src/lib/Counter.svelte
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/src/main.ts b/src/main.ts
index 8a909a1..50dff1a 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,4 +1,4 @@
-import './app.css'
+import './app.scss'
import App from './App.svelte'
const app = new App({
diff --git a/src/stores/login.ts b/src/stores/login.ts
new file mode 100644
index 0000000..b7a4544
--- /dev/null
+++ b/src/stores/login.ts
@@ -0,0 +1,28 @@
+import {writable} from "svelte/store";
+
+export interface LoginStore {
+ userinfo: {
+ email: string;
+ name: string;
+ sub: string;
+ picture: string;
+ };
+ tokens: {
+ access: string;
+ refresh: string;
+ };
+}
+
+export const loginStore = writable
(
+ (() => {
+ try {
+ return JSON.parse(localStorage.getItem("login-session") || "");
+ } catch (_) {
+ return null;
+ }
+ })(),
+);
+
+loginStore.subscribe(x => {
+ localStorage.setItem("login-session", JSON.stringify(x));
+});
diff --git a/src/utils/login-popup.ts b/src/utils/login-popup.ts
new file mode 100644
index 0000000..79064f0
--- /dev/null
+++ b/src/utils/login-popup.ts
@@ -0,0 +1,53 @@
+import {loginStore} from "../stores/login";
+
+let currentLoginPopup: {close: () => void} | null = null;
+
+const ssoOrigin = import.meta.env.VITE_SSO_ORIGIN;
+
+window.addEventListener("message", function (event) {
+ if (event.origin !== ssoOrigin) return;
+ if (isObject(event.data)) {
+ loginStore.set(event.data);
+ if (currentLoginPopup) currentLoginPopup.close();
+ return;
+ }
+ alert("Failed to log user in: the login data was probably corrupted");
+});
+
+function isObject(obj: Object) {
+ return obj != null && obj.constructor.name === "Object";
+}
+
+function popupCenterScreen(url: string, title: string, w: number, h: number, focus: boolean) {
+ const top = (screen.availHeight - h) / 4,
+ left = (screen.availWidth - w) / 2;
+ const popup = openWindow(url, title, `scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`);
+ if (focus === true && window.focus !== undefined && popup !== null) popup.focus();
+ return popup;
+}
+
+function openWindow(url: string | URL, winnm: string, options: string): Window | null {
+ var wTop = firstAvailableValue([window.screen.availTop, window.screenY, window.screenTop, 0]);
+ var wLeft = firstAvailableValue([window.screen.availLeft, window.screenX, window.screenLeft, 0]);
+ let w: Window | null;
+ var top = 0,
+ left = 0;
+ var result;
+ if ((result = /top=(\d+)/g.exec(options))) top = parseInt(result[1]);
+ if ((result = /left=(\d+)/g.exec(options))) left = parseInt(result[1]);
+ if (options) {
+ options = options.replace("top=" + top, "top=" + (top + wTop));
+ options = options.replace("left=" + left, "left=" + (left + wLeft));
+ w = window.open(url, winnm, options);
+ } else w = window.open(url, winnm);
+ return w;
+}
+
+function firstAvailableValue(arr: any) {
+ for (var i = 0; i < arr.length; i++) if (typeof arr[i] != "undefined") return arr[i];
+}
+
+export function openLoginPopup() {
+ if (currentLoginPopup) currentLoginPopup.close();
+ currentLoginPopup = popupCenterScreen(ssoOrigin + "/popup?origin=" + encodeURIComponent(location.origin), "Login with 1f349 SSO", 500, 500, false);
+}
diff --git a/src/views/GeneralView.svelte b/src/views/GeneralView.svelte
new file mode 100644
index 0000000..7360a9e
--- /dev/null
+++ b/src/views/GeneralView.svelte
@@ -0,0 +1 @@
+No options available here
diff --git a/src/views/OrchidView.svelte b/src/views/OrchidView.svelte
new file mode 100644
index 0000000..ad7456e
--- /dev/null
+++ b/src/views/OrchidView.svelte
@@ -0,0 +1 @@
+No options available here: {import.meta.env.VITE_API_ORCHID}
diff --git a/src/views/VioletView.svelte b/src/views/VioletView.svelte
new file mode 100644
index 0000000..a42c7e6
--- /dev/null
+++ b/src/views/VioletView.svelte
@@ -0,0 +1,36 @@
+
+
+{#await promiseForRoutes}
+ Loading...
+{:then allRoutes}
+
+
+ Source |
+ Destination |
+ Flags |
+ Active |
+
+
+ |
+ |
+ |
+ |
+
+
+{:catch err}
+ {err}
+{/await}
diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts
index 4078e74..cfb23bc 100644
--- a/src/vite-env.d.ts
+++ b/src/vite-env.d.ts
@@ -1,2 +1,12 @@
///
///
+
+interface ImportMetaEnv {
+ VITE_SSO_ORIGIN: string;
+ VITE_API_VIOLET: string;
+ VITE_API_ORCHID: string;
+}
+
+interface ImportMeta {
+ readonly env: ImportMetaEnv;
+}
diff --git a/yarn.lock b/yarn.lock
index 6dfac6a..a5574fd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -270,7 +270,7 @@ callsites@^3.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
-chokidar@^3.4.1:
+"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.1:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
@@ -430,6 +430,11 @@ graceful-fs@^4.1.3:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
+immutable@^4.0.0:
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f"
+ integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==
+
import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
@@ -675,6 +680,15 @@ sander@^0.5.0:
mkdirp "^0.5.1"
rimraf "^2.5.2"
+sass@^1.69.4:
+ version "1.69.4"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.4.tgz#10c735f55e3ea0b7742c6efa940bce30e07fbca2"
+ integrity sha512-+qEreVhqAy8o++aQfCJwp0sklr2xyEzkm9Pp/Igu9wNPoe7EZEQ8X/MBvvXggI2ql607cxKg/RKOwDj6pp2XDA==
+ dependencies:
+ chokidar ">=3.0.0 <4.0.0"
+ immutable "^4.0.0"
+ source-map-js ">=0.6.2 <2.0.0"
+
sorcery@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/sorcery/-/sorcery-0.11.0.tgz#310c80ee993433854bb55bb9aa4003acd147fca8"
@@ -685,7 +699,7 @@ sorcery@^0.11.0:
minimist "^1.2.0"
sander "^0.5.0"
-source-map-js@^1.0.1, source-map-js@^1.0.2:
+"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==