From 4dbef3fcd7a14437d55c555cf10d50de8e50d7d1 Mon Sep 17 00:00:00 2001 From: ivarlovlie Date: Fri, 9 Dec 2022 11:57:12 +0900 Subject: feat: Move everything out of $lib --- code/app/src/actions/pwKey.ts | 2 +- code/app/src/api/_fetch.ts | 94 ++++ code/app/src/api/account/index.ts | 39 ++ code/app/src/api/api-tokens/index.ts | 23 + code/app/src/api/projects/index.ts | 12 + code/app/src/components/alert.svelte | 268 +++++++++++ code/app/src/components/badge.svelte | 77 +++ code/app/src/components/button.svelte | 116 +++++ code/app/src/components/checkbox.svelte | 29 ++ code/app/src/components/combobox.svelte | 452 +++++++++++++++++ code/app/src/components/icons/adjustments.svelte | 14 + .../src/components/icons/bars-3-center-left.svelte | 15 + code/app/src/components/icons/calendar.svelte | 14 + code/app/src/components/icons/check-circle.svelte | 13 + code/app/src/components/icons/chevron-down.svelte | 7 + .../src/components/icons/chevron-up-down.svelte | 13 + code/app/src/components/icons/chevron-up.svelte | 7 + code/app/src/components/icons/database.svelte | 14 + .../src/components/icons/exclamation-circle.svelte | 13 + .../components/icons/exclamation-triangle.svelte | 13 + code/app/src/components/icons/folder-open.svelte | 14 + code/app/src/components/icons/funnel.svelte | 7 + code/app/src/components/icons/home.svelte | 14 + code/app/src/components/icons/index.ts | 47 ++ .../src/components/icons/information-circle.svelte | 13 + .../src/components/icons/magnifying-glass.svelte | 13 + code/app/src/components/icons/megaphone.svelte | 14 + code/app/src/components/icons/menu.svelte | 14 + code/app/src/components/icons/queue-list.svelte | 14 + code/app/src/components/icons/spinner.svelte | 20 + code/app/src/components/icons/x-circle.svelte | 13 + code/app/src/components/icons/x-mark.svelte | 11 + code/app/src/components/icons/x.svelte | 14 + code/app/src/components/index.ts | 23 + code/app/src/components/input.svelte | 112 +++++ code/app/src/components/locale-switcher.svelte | 56 +++ .../app/src/components/project-status-badge.svelte | 25 + code/app/src/components/switch.svelte | 125 +++++ code/app/src/components/textarea.svelte | 81 ++++ code/app/src/configuration/index.ts | 60 +++ code/app/src/help/colors.ts | 47 ++ code/app/src/help/index.ts | 466 ++++++++++++++++++ code/app/src/help/logger.ts | 86 ++++ code/app/src/help/persistent-store.ts | 102 ++++ code/app/src/hooks.server.ts | 36 +- code/app/src/i18n/en/app/index.ts | 7 + code/app/src/i18n/en/index.ts | 59 +++ code/app/src/i18n/formatters.ts | 13 + code/app/src/i18n/i18n-svelte.ts | 12 + code/app/src/i18n/i18n-types.ts | 429 +++++++++++++++++ code/app/src/i18n/i18n-util.async.ts | 42 ++ code/app/src/i18n/i18n-util.sync.ts | 35 ++ code/app/src/i18n/i18n-util.ts | 41 ++ code/app/src/i18n/nb/app/index.ts | 7 + code/app/src/i18n/nb/index.ts | 51 ++ code/app/src/lib/api/_fetch.ts | 95 ---- code/app/src/lib/api/account/index.ts | 39 -- code/app/src/lib/api/api-tokens/index.ts | 23 - code/app/src/lib/api/projects/index.ts | 12 - code/app/src/lib/colors.ts | 47 -- code/app/src/lib/components/alert.svelte | 268 ----------- code/app/src/lib/components/badge.svelte | 76 --- code/app/src/lib/components/button.svelte | 115 ----- code/app/src/lib/components/checkbox.svelte | 29 -- code/app/src/lib/components/combobox.svelte | 450 ----------------- .../src/lib/components/icons/adjustments.svelte | 14 - .../lib/components/icons/bars-3-center-left.svelte | 15 - code/app/src/lib/components/icons/calendar.svelte | 14 - .../src/lib/components/icons/check-circle.svelte | 13 - .../src/lib/components/icons/chevron-down.svelte | 7 - .../lib/components/icons/chevron-up-down.svelte | 13 - .../app/src/lib/components/icons/chevron-up.svelte | 7 - code/app/src/lib/components/icons/database.svelte | 14 - .../lib/components/icons/exclamation-circle.svelte | 13 - .../components/icons/exclamation-triangle.svelte | 13 - .../src/lib/components/icons/folder-open.svelte | 14 - code/app/src/lib/components/icons/funnel.svelte | 7 - code/app/src/lib/components/icons/home.svelte | 14 - code/app/src/lib/components/icons/index.ts | 47 -- .../lib/components/icons/information-circle.svelte | 13 - .../lib/components/icons/magnifying-glass.svelte | 13 - code/app/src/lib/components/icons/megaphone.svelte | 14 - code/app/src/lib/components/icons/menu.svelte | 14 - .../app/src/lib/components/icons/queue-list.svelte | 14 - code/app/src/lib/components/icons/spinner.svelte | 20 - code/app/src/lib/components/icons/x-circle.svelte | 13 - code/app/src/lib/components/icons/x-mark.svelte | 11 - code/app/src/lib/components/icons/x.svelte | 14 - code/app/src/lib/components/index.ts | 23 - code/app/src/lib/components/input.svelte | 113 ----- code/app/src/lib/components/locale-switcher.svelte | 56 --- .../src/lib/components/project-status-badge.svelte | 24 - code/app/src/lib/components/switch.svelte | 125 ----- code/app/src/lib/components/textarea.svelte | 81 ---- code/app/src/lib/configuration.ts | 60 --- code/app/src/lib/helpers.ts | 464 ------------------ code/app/src/lib/i18n/en/app/index.ts | 7 - code/app/src/lib/i18n/en/index.ts | 59 --- code/app/src/lib/i18n/formatters.ts | 13 - code/app/src/lib/i18n/i18n-svelte.ts | 12 - code/app/src/lib/i18n/i18n-types.ts | 429 ----------------- code/app/src/lib/i18n/i18n-util.async.ts | 42 -- code/app/src/lib/i18n/i18n-util.sync.ts | 35 -- code/app/src/lib/i18n/i18n-util.ts | 41 -- code/app/src/lib/i18n/nb/app/index.ts | 7 - code/app/src/lib/i18n/nb/index.ts | 51 -- code/app/src/lib/logger.ts | 86 ---- code/app/src/lib/models/base/Customer.ts | 21 - code/app/src/lib/models/base/CustomerContact.ts | 8 - code/app/src/lib/models/base/CustomerEvent.ts | 6 - code/app/src/lib/models/base/SessionData.ts | 5 - code/app/src/lib/models/base/Tenant.ts | 8 - code/app/src/lib/models/base/User.ts | 13 - code/app/src/lib/models/base/UserRole.ts | 5 - code/app/src/lib/models/internal/FormError.ts | 24 - code/app/src/lib/models/internal/ISession.ts | 8 - code/app/src/lib/models/internal/KnownProblem.ts | 10 - code/app/src/lib/models/projects/Project.ts | 13 - code/app/src/lib/models/projects/ProjectLabel.ts | 5 - code/app/src/lib/models/projects/ProjectMember.ts | 10 - code/app/src/lib/models/projects/ProjectMeta.ts | 7 - code/app/src/lib/models/projects/ProjectRole.ts | 7 - code/app/src/lib/models/projects/ProjectStatus.ts | 5 - code/app/src/lib/models/work/WorkCategory.ts | 5 - code/app/src/lib/models/work/WorkEntry.ts | 13 - .../src/lib/models/work/WorkEntryQueryResponse.ts | 27 -- code/app/src/lib/models/work/WorkLabel.ts | 5 - code/app/src/lib/models/work/WorkQuery.ts | 30 -- code/app/src/lib/persistent-store.ts | 102 ---- .../lib/services/abstractions/IAccountService.ts | 54 --- .../services/abstractions/IPasswordResetService.ts | 21 - .../lib/services/abstractions/ISettingsService.ts | 3 - code/app/src/lib/services/account-service.ts | 61 --- .../app/src/lib/services/password-reset-service.ts | 38 -- code/app/src/lib/services/settings-service.ts | 7 - code/app/src/lib/session.ts | 69 --- code/app/src/models/base/Customer.ts | 21 + code/app/src/models/base/CustomerContact.ts | 8 + code/app/src/models/base/CustomerEvent.ts | 6 + code/app/src/models/base/SessionData.ts | 5 + code/app/src/models/base/Tenant.ts | 8 + code/app/src/models/base/User.ts | 13 + code/app/src/models/base/UserRole.ts | 5 + code/app/src/models/internal/FormError.ts | 24 + code/app/src/models/internal/KnownProblem.ts | 10 + code/app/src/models/projects/Project.ts | 13 + code/app/src/models/projects/ProjectLabel.ts | 5 + code/app/src/models/projects/ProjectMember.ts | 10 + code/app/src/models/projects/ProjectMeta.ts | 7 + code/app/src/models/projects/ProjectRole.ts | 7 + code/app/src/models/projects/ProjectStatus.ts | 5 + code/app/src/models/work/WorkCategory.ts | 5 + code/app/src/models/work/WorkEntry.ts | 13 + code/app/src/models/work/WorkEntryQueryResponse.ts | 27 ++ code/app/src/models/work/WorkLabel.ts | 5 + code/app/src/models/work/WorkQuery.ts | 17 + code/app/src/routes/(main)/(app)/+layout.svelte | 534 +++++++++++---------- .../src/routes/(main)/(app)/projects/+page.svelte | 228 ++++----- .../(main)/(app)/projects/create/+page.svelte | 20 +- .../src/routes/(main)/(app)/settings/+page.svelte | 106 ++-- code/app/src/routes/(main)/(public)/+layout.svelte | 8 +- .../(main)/(public)/reset-password/+page.svelte | 30 +- .../(public)/reset-password/[id]/+page.server.ts | 10 +- .../(public)/reset-password/[id]/+page.svelte | 33 +- .../routes/(main)/(public)/sign-in/+page.svelte | 88 ++-- .../(main)/(public)/sign-in/tests/index.spec.ts | 12 +- .../routes/(main)/(public)/sign-up/+page.svelte | 46 +- code/app/src/routes/(main)/+layout.server.ts | 35 +- code/app/src/routes/(main)/+layout.svelte | 12 +- code/app/src/routes/(main)/+layout.ts | 18 +- code/app/src/routes/book/alerts/+page.svelte | 50 +- code/app/src/routes/book/badges/+page.svelte | 25 +- code/app/src/routes/book/buttons/+page.svelte | 16 +- code/app/src/routes/book/inputs/+page.svelte | 28 +- code/app/src/routes/book/toggles/+page.svelte | 12 +- .../src/services/abstractions/IAccountService.ts | 58 +++ .../services/abstractions/IPasswordResetService.ts | 21 + .../src/services/abstractions/ISettingsService.ts | 3 + code/app/src/services/account-service.ts | 116 +++++ code/app/src/services/password-reset-service.ts | 45 ++ code/app/src/services/settings-service.ts | 7 + 181 files changed, 4476 insertions(+), 4460 deletions(-) create mode 100644 code/app/src/api/_fetch.ts create mode 100644 code/app/src/api/account/index.ts create mode 100644 code/app/src/api/api-tokens/index.ts create mode 100644 code/app/src/api/projects/index.ts create mode 100644 code/app/src/components/alert.svelte create mode 100644 code/app/src/components/badge.svelte create mode 100644 code/app/src/components/button.svelte create mode 100644 code/app/src/components/checkbox.svelte create mode 100644 code/app/src/components/combobox.svelte create mode 100644 code/app/src/components/icons/adjustments.svelte create mode 100644 code/app/src/components/icons/bars-3-center-left.svelte create mode 100644 code/app/src/components/icons/calendar.svelte create mode 100644 code/app/src/components/icons/check-circle.svelte create mode 100644 code/app/src/components/icons/chevron-down.svelte create mode 100644 code/app/src/components/icons/chevron-up-down.svelte create mode 100644 code/app/src/components/icons/chevron-up.svelte create mode 100644 code/app/src/components/icons/database.svelte create mode 100644 code/app/src/components/icons/exclamation-circle.svelte create mode 100644 code/app/src/components/icons/exclamation-triangle.svelte create mode 100644 code/app/src/components/icons/folder-open.svelte create mode 100644 code/app/src/components/icons/funnel.svelte create mode 100644 code/app/src/components/icons/home.svelte create mode 100644 code/app/src/components/icons/index.ts create mode 100644 code/app/src/components/icons/information-circle.svelte create mode 100644 code/app/src/components/icons/magnifying-glass.svelte create mode 100644 code/app/src/components/icons/megaphone.svelte create mode 100644 code/app/src/components/icons/menu.svelte create mode 100644 code/app/src/components/icons/queue-list.svelte create mode 100644 code/app/src/components/icons/spinner.svelte create mode 100644 code/app/src/components/icons/x-circle.svelte create mode 100644 code/app/src/components/icons/x-mark.svelte create mode 100644 code/app/src/components/icons/x.svelte create mode 100644 code/app/src/components/index.ts create mode 100644 code/app/src/components/input.svelte create mode 100644 code/app/src/components/locale-switcher.svelte create mode 100644 code/app/src/components/project-status-badge.svelte create mode 100644 code/app/src/components/switch.svelte create mode 100644 code/app/src/components/textarea.svelte create mode 100644 code/app/src/configuration/index.ts create mode 100644 code/app/src/help/colors.ts create mode 100644 code/app/src/help/index.ts create mode 100644 code/app/src/help/logger.ts create mode 100644 code/app/src/help/persistent-store.ts create mode 100644 code/app/src/i18n/en/app/index.ts create mode 100644 code/app/src/i18n/en/index.ts create mode 100644 code/app/src/i18n/formatters.ts create mode 100644 code/app/src/i18n/i18n-svelte.ts create mode 100644 code/app/src/i18n/i18n-types.ts create mode 100644 code/app/src/i18n/i18n-util.async.ts create mode 100644 code/app/src/i18n/i18n-util.sync.ts create mode 100644 code/app/src/i18n/i18n-util.ts create mode 100644 code/app/src/i18n/nb/app/index.ts create mode 100644 code/app/src/i18n/nb/index.ts delete mode 100644 code/app/src/lib/api/_fetch.ts delete mode 100644 code/app/src/lib/api/account/index.ts delete mode 100644 code/app/src/lib/api/api-tokens/index.ts delete mode 100644 code/app/src/lib/api/projects/index.ts delete mode 100644 code/app/src/lib/colors.ts delete mode 100644 code/app/src/lib/components/alert.svelte delete mode 100644 code/app/src/lib/components/badge.svelte delete mode 100644 code/app/src/lib/components/button.svelte delete mode 100644 code/app/src/lib/components/checkbox.svelte delete mode 100644 code/app/src/lib/components/combobox.svelte delete mode 100644 code/app/src/lib/components/icons/adjustments.svelte delete mode 100644 code/app/src/lib/components/icons/bars-3-center-left.svelte delete mode 100644 code/app/src/lib/components/icons/calendar.svelte delete mode 100644 code/app/src/lib/components/icons/check-circle.svelte delete mode 100644 code/app/src/lib/components/icons/chevron-down.svelte delete mode 100644 code/app/src/lib/components/icons/chevron-up-down.svelte delete mode 100644 code/app/src/lib/components/icons/chevron-up.svelte delete mode 100644 code/app/src/lib/components/icons/database.svelte delete mode 100644 code/app/src/lib/components/icons/exclamation-circle.svelte delete mode 100644 code/app/src/lib/components/icons/exclamation-triangle.svelte delete mode 100644 code/app/src/lib/components/icons/folder-open.svelte delete mode 100644 code/app/src/lib/components/icons/funnel.svelte delete mode 100644 code/app/src/lib/components/icons/home.svelte delete mode 100644 code/app/src/lib/components/icons/index.ts delete mode 100644 code/app/src/lib/components/icons/information-circle.svelte delete mode 100644 code/app/src/lib/components/icons/magnifying-glass.svelte delete mode 100644 code/app/src/lib/components/icons/megaphone.svelte delete mode 100644 code/app/src/lib/components/icons/menu.svelte delete mode 100644 code/app/src/lib/components/icons/queue-list.svelte delete mode 100644 code/app/src/lib/components/icons/spinner.svelte delete mode 100644 code/app/src/lib/components/icons/x-circle.svelte delete mode 100644 code/app/src/lib/components/icons/x-mark.svelte delete mode 100644 code/app/src/lib/components/icons/x.svelte delete mode 100644 code/app/src/lib/components/index.ts delete mode 100644 code/app/src/lib/components/input.svelte delete mode 100644 code/app/src/lib/components/locale-switcher.svelte delete mode 100644 code/app/src/lib/components/project-status-badge.svelte delete mode 100644 code/app/src/lib/components/switch.svelte delete mode 100644 code/app/src/lib/components/textarea.svelte delete mode 100644 code/app/src/lib/configuration.ts delete mode 100644 code/app/src/lib/helpers.ts delete mode 100644 code/app/src/lib/i18n/en/app/index.ts delete mode 100644 code/app/src/lib/i18n/en/index.ts delete mode 100644 code/app/src/lib/i18n/formatters.ts delete mode 100644 code/app/src/lib/i18n/i18n-svelte.ts delete mode 100644 code/app/src/lib/i18n/i18n-types.ts delete mode 100644 code/app/src/lib/i18n/i18n-util.async.ts delete mode 100644 code/app/src/lib/i18n/i18n-util.sync.ts delete mode 100644 code/app/src/lib/i18n/i18n-util.ts delete mode 100644 code/app/src/lib/i18n/nb/app/index.ts delete mode 100644 code/app/src/lib/i18n/nb/index.ts delete mode 100644 code/app/src/lib/logger.ts delete mode 100644 code/app/src/lib/models/base/Customer.ts delete mode 100644 code/app/src/lib/models/base/CustomerContact.ts delete mode 100644 code/app/src/lib/models/base/CustomerEvent.ts delete mode 100644 code/app/src/lib/models/base/SessionData.ts delete mode 100644 code/app/src/lib/models/base/Tenant.ts delete mode 100644 code/app/src/lib/models/base/User.ts delete mode 100644 code/app/src/lib/models/base/UserRole.ts delete mode 100644 code/app/src/lib/models/internal/FormError.ts delete mode 100644 code/app/src/lib/models/internal/ISession.ts delete mode 100644 code/app/src/lib/models/internal/KnownProblem.ts delete mode 100644 code/app/src/lib/models/projects/Project.ts delete mode 100644 code/app/src/lib/models/projects/ProjectLabel.ts delete mode 100644 code/app/src/lib/models/projects/ProjectMember.ts delete mode 100644 code/app/src/lib/models/projects/ProjectMeta.ts delete mode 100644 code/app/src/lib/models/projects/ProjectRole.ts delete mode 100644 code/app/src/lib/models/projects/ProjectStatus.ts delete mode 100644 code/app/src/lib/models/work/WorkCategory.ts delete mode 100644 code/app/src/lib/models/work/WorkEntry.ts delete mode 100644 code/app/src/lib/models/work/WorkEntryQueryResponse.ts delete mode 100644 code/app/src/lib/models/work/WorkLabel.ts delete mode 100644 code/app/src/lib/models/work/WorkQuery.ts delete mode 100644 code/app/src/lib/persistent-store.ts delete mode 100644 code/app/src/lib/services/abstractions/IAccountService.ts delete mode 100644 code/app/src/lib/services/abstractions/IPasswordResetService.ts delete mode 100644 code/app/src/lib/services/abstractions/ISettingsService.ts delete mode 100644 code/app/src/lib/services/account-service.ts delete mode 100644 code/app/src/lib/services/password-reset-service.ts delete mode 100644 code/app/src/lib/services/settings-service.ts delete mode 100644 code/app/src/lib/session.ts create mode 100644 code/app/src/models/base/Customer.ts create mode 100644 code/app/src/models/base/CustomerContact.ts create mode 100644 code/app/src/models/base/CustomerEvent.ts create mode 100644 code/app/src/models/base/SessionData.ts create mode 100644 code/app/src/models/base/Tenant.ts create mode 100644 code/app/src/models/base/User.ts create mode 100644 code/app/src/models/base/UserRole.ts create mode 100644 code/app/src/models/internal/FormError.ts create mode 100644 code/app/src/models/internal/KnownProblem.ts create mode 100644 code/app/src/models/projects/Project.ts create mode 100644 code/app/src/models/projects/ProjectLabel.ts create mode 100644 code/app/src/models/projects/ProjectMember.ts create mode 100644 code/app/src/models/projects/ProjectMeta.ts create mode 100644 code/app/src/models/projects/ProjectRole.ts create mode 100644 code/app/src/models/projects/ProjectStatus.ts create mode 100644 code/app/src/models/work/WorkCategory.ts create mode 100644 code/app/src/models/work/WorkEntry.ts create mode 100644 code/app/src/models/work/WorkEntryQueryResponse.ts create mode 100644 code/app/src/models/work/WorkLabel.ts create mode 100644 code/app/src/models/work/WorkQuery.ts create mode 100644 code/app/src/services/abstractions/IAccountService.ts create mode 100644 code/app/src/services/abstractions/IPasswordResetService.ts create mode 100644 code/app/src/services/abstractions/ISettingsService.ts create mode 100644 code/app/src/services/account-service.ts create mode 100644 code/app/src/services/password-reset-service.ts create mode 100644 code/app/src/services/settings-service.ts (limited to 'code/app/src') diff --git a/code/app/src/actions/pwKey.ts b/code/app/src/actions/pwKey.ts index a2f22e7..351a4b8 100644 --- a/code/app/src/actions/pwKey.ts +++ b/code/app/src/actions/pwKey.ts @@ -1,4 +1,4 @@ -import { is_development, is_testing } from "$lib/configuration"; +import {is_development, is_testing} from "$configuration"; export default function pwKey(node: HTMLElement, value: string | undefined) { if (!value) return; diff --git a/code/app/src/api/_fetch.ts b/code/app/src/api/_fetch.ts new file mode 100644 index 0000000..370b071 --- /dev/null +++ b/code/app/src/api/_fetch.ts @@ -0,0 +1,94 @@ +import {Temporal} from "temporal-polyfill"; +import {redirect} from "@sveltejs/kit"; +import {browser} from "$app/environment"; +import {goto} from "$app/navigation"; +import {SignInPageMessage, signInPageMessageQueryKey} from "$routes/(main)/(public)/sign-in"; +import {log_error} from "$help/logger"; + +export async function http_post_async(url: string, body?: object | string, timeout = -1, skip_401_check = false, abort_signal?: AbortSignal): Promise { + const init = make_request_init("post", body, abort_signal); + const response = await internal_fetch_async({url, init, timeout}); + if (!skip_401_check && await redirect_if_401_async(response)) throw new Error("Server returned 401"); + return response; +} + +export async function http_get_async(url: string, timeout = -1, skip_401_check = false, abort_signal?: AbortSignal): Promise { + const init = make_request_init("get", undefined, abort_signal); + const response = await internal_fetch_async({url, init, timeout}); + if (!skip_401_check && await redirect_if_401_async(response)) throw new Error("Server returned 401"); + return response; +} + +export async function http_delete_async(url: string, body?: object | string, timeout = -1, skip_401_check = false, abort_signal?: AbortSignal): Promise { + const init = make_request_init("delete", body, abort_signal); + const response = await internal_fetch_async({url, init, timeout}); + if (!skip_401_check && await redirect_if_401_async(response)) throw new Error("Server returned 401"); + return response; +} + +async function internal_fetch_async(request: InternalFetchRequest): Promise { + if (!request.init) throw new Error("request.init is required"); + const fetch_request = new Request(request.url, request.init); + let response: any; + + try { + if (request.timeout && request.timeout > 500) { + response = await Promise.race([ + fetch(fetch_request), + new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), request.timeout)), + ]); + } else { + response = await fetch(fetch_request); + } + } catch (error: any) { + log_error(error); + if (error.message === "Timeout") { + console.error("Request timed out"); + } else if (error.message === "Network request failed") { + console.error("No internet connection"); + } else { + throw error; + } + } + + return response; +} + +async function redirect_if_401_async(response: Response): Promise { + if (response.status === 401) { + const redirectUrl = `/sign-in?${signInPageMessageQueryKey}=${SignInPageMessage.LOGGED_OUT}`; + clear_session_data(); + if (browser) { + await goto(redirectUrl); + } else { + throw redirect(307, redirectUrl); + } + } + return false; +} + +function make_request_init(method: string, body?: any, signal?: AbortSignal): RequestInit { + const init = { + method, + credentials: "include", + signal, + headers: { + "X-TimeZone": Temporal.Now.timeZone().id, + }, + } as RequestInit; + + if (body) { + init.body = JSON.stringify(body); + init.headers["Content-Type"] = "application/json;charset=UTF-8"; + } + + return init; +} + + +export type InternalFetchRequest = { + url: string, + init: RequestInit, + timeout?: number + retry_count?: number, +} \ No newline at end of file diff --git a/code/app/src/api/account/index.ts b/code/app/src/api/account/index.ts new file mode 100644 index 0000000..7cbcefc --- /dev/null +++ b/code/app/src/api/account/index.ts @@ -0,0 +1,39 @@ +import {api_base} from "$configuration"; +import {http_delete_async, http_get_async, http_post_async} from "../_fetch"; + +export const http_account = { + login_async(payload: LoginPayload): Promise { + return http_post_async(api_base("_/account/login"), payload); + }, + logout_async(): Promise { + return http_get_async(api_base("_/account/logout")); + }, + delete_account_async(): Promise { + return http_delete_async(api_base("_/account/delete")); + }, + update_profile_async(payload: UpdateProfilePayload): Promise { + return http_post_async(api_base("_/account/update"), payload); + }, + create_account_async(payload: CreateAccountPayload): Promise { + return http_post_async(api_base("_/account/create"), payload); + }, + get_profile_async(suppress_401: boolean): Promise { + return http_get_async(api_base("_/account"), 0, suppress_401); + }, +}; + +export interface CreateAccountPayload { + username: string, + password: string +} + +export interface LoginPayload { + username: string, + password: string, + persist: boolean +} + +export interface UpdateProfilePayload { + username?: string, + password?: string, +} diff --git a/code/app/src/api/api-tokens/index.ts b/code/app/src/api/api-tokens/index.ts new file mode 100644 index 0000000..6c27a06 --- /dev/null +++ b/code/app/src/api/api-tokens/index.ts @@ -0,0 +1,23 @@ +import {http_delete_async, http_get_async, http_post_async} from "../_fetch"; +import {api_base} from "$configuration"; +import type {Temporal} from "temporal-polyfill"; + +export const http_api_tokens = { + create_token_async(payload: CreateTokenPayload): Promise { + return http_post_async(api_base("v1/api-tokens/create"), payload); + }, + delete_token_async(id: string): Promise { + return http_delete_async(api_base("v1/api-tokens/delete?id=" + id)); + }, + get_tokens_async(): Promise { + return http_get_async(api_base("v1/api-tokens")); + }, +}; + +export type CreateTokenPayload = { + expiryDate: Temporal.PlainDateTime, + allowRead: boolean, + allowCreate: boolean, + allowUpdate: boolean, + allowDelete: boolean +} \ No newline at end of file diff --git a/code/app/src/api/projects/index.ts b/code/app/src/api/projects/index.ts new file mode 100644 index 0000000..316785f --- /dev/null +++ b/code/app/src/api/projects/index.ts @@ -0,0 +1,12 @@ +import {api_base} from "$configuration"; +import {http_post_async} from "../_fetch"; + +export const http_projects = { + create_async(payload: CreateProjectPayload): Promise { + return http_post_async(api_base("projects/create"), payload); + }, +}; + +export type CreateProjectPayload = { + name: "" +} \ No newline at end of file diff --git a/code/app/src/components/alert.svelte b/code/app/src/components/alert.svelte new file mode 100644 index 0000000..b0abe81 --- /dev/null +++ b/code/app/src/components/alert.svelte @@ -0,0 +1,268 @@ + + +{#if visible} +
+
+
+ +
+
+ {#if !rightLinkText} + {#if title} +

+ {title} +

+ {/if} + {#if message} +
+

+ {@html message} +

+
+ {/if} + {#if listItems?.length ?? 0} +
    + {#each listItems as listItem} +
  • {listItem}
  • + {/each} +
+ {/if} + {:else} +
+
+ {#if title} +

+ {title} +

+ {/if} + {#if message} +
+

+ {@html message} +

+
+ {/if} + {#if listItems?.length ?? 0} +
    + {#each listItems as listItem} +
  • {listItem}
  • + {/each} +
+ {/if} +
+

+ rightLinkClicked()} + class="whitespace-nowrap font-medium text-{colorClassPart}-700 hover:text-{colorClassPart}-600" + > + {rightLinkText} + + +

+
+ {/if} + {#if actions?.length ?? 0} +
+
+ {#each actions as action} + {@const color = action?.color ?? colorClassPart} + + {/each} +
+
+ {/if} +
+ {#if closeable} +
+
+ +
+
+ {/if} +
+
+{/if} diff --git a/code/app/src/components/badge.svelte b/code/app/src/components/badge.svelte new file mode 100644 index 0000000..e89ef36 --- /dev/null +++ b/code/app/src/components/badge.svelte @@ -0,0 +1,77 @@ + + + + {#if withDot} + + + + {/if} + {text} + {#if removable} + + {/if} + diff --git a/code/app/src/components/button.svelte b/code/app/src/components/button.svelte new file mode 100644 index 0000000..d573d01 --- /dev/null +++ b/code/app/src/components/button.svelte @@ -0,0 +1,116 @@ + + + + +{#if href} + + {#if loading} + + {/if} + {text} + +{:else} + +{/if} + + diff --git a/code/app/src/components/checkbox.svelte b/code/app/src/components/checkbox.svelte new file mode 100644 index 0000000..bf3c293 --- /dev/null +++ b/code/app/src/components/checkbox.svelte @@ -0,0 +1,29 @@ + + +
+ + +
diff --git a/code/app/src/components/combobox.svelte b/code/app/src/components/combobox.svelte new file mode 100644 index 0000000..5df3ec9 --- /dev/null +++ b/code/app/src/components/combobox.svelte @@ -0,0 +1,452 @@ + + + + + + +
+ {#if label} + + {/if} +
+
+ {#if multiple === true && hasSelection} +
+ {#each options.filter((c) => c.selected === true) as option} + methods.deselect_entry(e.detail.id)} + text={option.name} + /> + {/each} +
+ {/if} +
+ search.do()} + on:click={search.on_input_click} + on:focus={search.on_input_focus} + on:blur={search.on_input_focusout} + autocomplete="off" + /> + {#if hasSelection} + + {:else} + + + + {/if} +
+
+ {#if errorText} +

+ {errorText} +

+ {/if} +
+
    + {#if searchResults.length > 0} + {#each searchResults.filter((c) => !c.selected) as result} +
  • + {@html highlight(result, '', "")} +
  • + {/each} + {:else if options.length > 0} + {#each options as option} + +
  • + {option.name} + {#if option.selected} + + + + {/if} +
  • + {/each} + {:else} + +

    {noResultsText}

    + {#if createable && !searchValue} +

    {$LL.combobox.createRecordHelpText()}

    + {/if} +
    + {/if} +
+ {#if showCreationHint} +
+
+ {/if} +
+
+
+ + diff --git a/code/app/src/components/icons/adjustments.svelte b/code/app/src/components/icons/adjustments.svelte new file mode 100644 index 0000000..83bda27 --- /dev/null +++ b/code/app/src/components/icons/adjustments.svelte @@ -0,0 +1,14 @@ + + + diff --git a/code/app/src/components/icons/bars-3-center-left.svelte b/code/app/src/components/icons/bars-3-center-left.svelte new file mode 100644 index 0000000..785ece3 --- /dev/null +++ b/code/app/src/components/icons/bars-3-center-left.svelte @@ -0,0 +1,15 @@ + diff --git a/code/app/src/components/icons/calendar.svelte b/code/app/src/components/icons/calendar.svelte new file mode 100644 index 0000000..e0053ee --- /dev/null +++ b/code/app/src/components/icons/calendar.svelte @@ -0,0 +1,14 @@ + + + diff --git a/code/app/src/components/icons/check-circle.svelte b/code/app/src/components/icons/check-circle.svelte new file mode 100644 index 0000000..e30778e --- /dev/null +++ b/code/app/src/components/icons/check-circle.svelte @@ -0,0 +1,13 @@ + diff --git a/code/app/src/components/icons/chevron-down.svelte b/code/app/src/components/icons/chevron-down.svelte new file mode 100644 index 0000000..5b29ece --- /dev/null +++ b/code/app/src/components/icons/chevron-down.svelte @@ -0,0 +1,7 @@ + + + diff --git a/code/app/src/components/icons/chevron-up-down.svelte b/code/app/src/components/icons/chevron-up-down.svelte new file mode 100644 index 0000000..c07aed5 --- /dev/null +++ b/code/app/src/components/icons/chevron-up-down.svelte @@ -0,0 +1,13 @@ + diff --git a/code/app/src/components/icons/chevron-up.svelte b/code/app/src/components/icons/chevron-up.svelte new file mode 100644 index 0000000..289e71d --- /dev/null +++ b/code/app/src/components/icons/chevron-up.svelte @@ -0,0 +1,7 @@ + + + diff --git a/code/app/src/components/icons/database.svelte b/code/app/src/components/icons/database.svelte new file mode 100644 index 0000000..6ffdadb --- /dev/null +++ b/code/app/src/components/icons/database.svelte @@ -0,0 +1,14 @@ + + + diff --git a/code/app/src/components/icons/exclamation-circle.svelte b/code/app/src/components/icons/exclamation-circle.svelte new file mode 100644 index 0000000..2ce79b1 --- /dev/null +++ b/code/app/src/components/icons/exclamation-circle.svelte @@ -0,0 +1,13 @@ + diff --git a/code/app/src/components/icons/exclamation-triangle.svelte b/code/app/src/components/icons/exclamation-triangle.svelte new file mode 100644 index 0000000..8d807db --- /dev/null +++ b/code/app/src/components/icons/exclamation-triangle.svelte @@ -0,0 +1,13 @@ + diff --git a/code/app/src/components/icons/folder-open.svelte b/code/app/src/components/icons/folder-open.svelte new file mode 100644 index 0000000..409c8e2 --- /dev/null +++ b/code/app/src/components/icons/folder-open.svelte @@ -0,0 +1,14 @@ + + + diff --git a/code/app/src/components/icons/funnel.svelte b/code/app/src/components/icons/funnel.svelte new file mode 100644 index 0000000..7e9daeb --- /dev/null +++ b/code/app/src/components/icons/funnel.svelte @@ -0,0 +1,7 @@ + + + diff --git a/code/app/src/components/icons/home.svelte b/code/app/src/components/icons/home.svelte new file mode 100644 index 0000000..ee8305d --- /dev/null +++ b/code/app/src/components/icons/home.svelte @@ -0,0 +1,14 @@ + + + diff --git a/code/app/src/components/icons/index.ts b/code/app/src/components/icons/index.ts new file mode 100644 index 0000000..eb5b439 --- /dev/null +++ b/code/app/src/components/icons/index.ts @@ -0,0 +1,47 @@ +import XIcon from "./x.svelte"; +import MenuIcon from "./menu.svelte"; +import AdjustmentsIcon from "./adjustments.svelte"; +import DatabaseIcon from "./database.svelte"; +import HomeIcon from "./home.svelte"; +import InformationCircleIcon from "./information-circle.svelte"; +import ExclamationTriangleIcon from "./exclamation-triangle.svelte"; +import XCircleIcon from "./x-circle.svelte"; +import CheckCircleIcon from "./check-circle.svelte"; +import XMarkIcon from "./x-mark.svelte"; +import SpinnerIcon from "./spinner.svelte"; +import ExclamationCircleIcon from "./exclamation-circle.svelte"; +import ChevronUpDownIcon from "./chevron-up-down.svelte"; +import MagnifyingGlassIcon from "./magnifying-glass.svelte"; +import Bars3CenterLeftIcon from "./bars-3-center-left.svelte"; +import CalendarIcon from "./calendar.svelte"; +import FolderOpenIcon from "./folder-open.svelte"; +import MegaphoneIcon from "./megaphone.svelte"; +import QueueListIcon from "./queue-list.svelte"; +import ChevronDownIcon from "./chevron-down.svelte"; +import ChevronUpIcon from "./chevron-up.svelte"; +import FunnelIcon from "./funnel.svelte"; + +export { + FunnelIcon, + ChevronDownIcon, + ChevronUpIcon, + QueueListIcon, + FolderOpenIcon, + MegaphoneIcon, + CalendarIcon, + Bars3CenterLeftIcon, + MagnifyingGlassIcon, + ChevronUpDownIcon, + XIcon, + MenuIcon, + HomeIcon, + DatabaseIcon, + AdjustmentsIcon, + InformationCircleIcon, + ExclamationTriangleIcon, + ExclamationCircleIcon, + XCircleIcon, + CheckCircleIcon, + XMarkIcon, + SpinnerIcon +} \ No newline at end of file diff --git a/code/app/src/components/icons/information-circle.svelte b/code/app/src/components/icons/information-circle.svelte new file mode 100644 index 0000000..68dbc60 --- /dev/null +++ b/code/app/src/components/icons/information-circle.svelte @@ -0,0 +1,13 @@ + diff --git a/code/app/src/components/icons/magnifying-glass.svelte b/code/app/src/components/icons/magnifying-glass.svelte new file mode 100644 index 0000000..f8fdb6e --- /dev/null +++ b/code/app/src/components/icons/magnifying-glass.svelte @@ -0,0 +1,13 @@ + diff --git a/code/app/src/components/icons/megaphone.svelte b/code/app/src/components/icons/megaphone.svelte new file mode 100644 index 0000000..7ada5f3 --- /dev/null +++ b/code/app/src/components/icons/megaphone.svelte @@ -0,0 +1,14 @@ + + + diff --git a/code/app/src/components/icons/menu.svelte b/code/app/src/components/icons/menu.svelte new file mode 100644 index 0000000..471d85f --- /dev/null +++ b/code/app/src/components/icons/menu.svelte @@ -0,0 +1,14 @@ + + + diff --git a/code/app/src/components/icons/queue-list.svelte b/code/app/src/components/icons/queue-list.svelte new file mode 100644 index 0000000..6148394 --- /dev/null +++ b/code/app/src/components/icons/queue-list.svelte @@ -0,0 +1,14 @@ + + + diff --git a/code/app/src/components/icons/spinner.svelte b/code/app/src/components/icons/spinner.svelte new file mode 100644 index 0000000..80cc57c --- /dev/null +++ b/code/app/src/components/icons/spinner.svelte @@ -0,0 +1,20 @@ + + + + diff --git a/code/app/src/components/icons/x-circle.svelte b/code/app/src/components/icons/x-circle.svelte new file mode 100644 index 0000000..3793b5a --- /dev/null +++ b/code/app/src/components/icons/x-circle.svelte @@ -0,0 +1,13 @@ + diff --git a/code/app/src/components/icons/x-mark.svelte b/code/app/src/components/icons/x-mark.svelte new file mode 100644 index 0000000..fd1c6a1 --- /dev/null +++ b/code/app/src/components/icons/x-mark.svelte @@ -0,0 +1,11 @@ + diff --git a/code/app/src/components/icons/x.svelte b/code/app/src/components/icons/x.svelte new file mode 100644 index 0000000..6125ab8 --- /dev/null +++ b/code/app/src/components/icons/x.svelte @@ -0,0 +1,14 @@ + + + diff --git a/code/app/src/components/index.ts b/code/app/src/components/index.ts new file mode 100644 index 0000000..2285f08 --- /dev/null +++ b/code/app/src/components/index.ts @@ -0,0 +1,23 @@ +import Alert from "./alert.svelte"; +import Button from "./button.svelte"; +import Checkbox from "./checkbox.svelte"; +import Input from "./input.svelte"; +import LocaleSwitcher from "./locale-switcher.svelte"; +import Switch from "./switch.svelte"; +import Badge from "./badge.svelte"; +import ProjectStatusBadge from "./project-status-badge.svelte"; +import TextArea from "./textarea.svelte"; +import Combobox from "./combobox.svelte"; + +export { + Badge, + Combobox, + TextArea, + ProjectStatusBadge, + Alert, + Button, + Checkbox, + Input, + LocaleSwitcher, + Switch, +}; \ No newline at end of file diff --git a/code/app/src/components/input.svelte b/code/app/src/components/input.svelte new file mode 100644 index 0000000..4fcec16 --- /dev/null +++ b/code/app/src/components/input.svelte @@ -0,0 +1,112 @@ + + +
+ {#if label && !cornerHint && !hideLabel} + + {:else if cornerHint && !hideLabel} +
+ {#if label} + + {/if} + + {cornerHint} + +
+ {/if} +
+ {#if icon} +
+ +
+ {:else if addon} +
+ {addon} +
+ {/if} + + {#if errorText} +
+ +
+ {/if} +
+ {#if helpText && !errorText} +

+ {helpText} +

+ {/if} + {#if errorText || errors?.length === 1} +

+ {errorText ?? errors[0]} +

+ {:else if errors && errors.length} +
    + {#each errors as error} +
  • {error}
  • + {/each} +
+ {/if} +
diff --git a/code/app/src/components/locale-switcher.svelte b/code/app/src/components/locale-switcher.svelte new file mode 100644 index 0000000..fc03f39 --- /dev/null +++ b/code/app/src/components/locale-switcher.svelte @@ -0,0 +1,56 @@ + + + diff --git a/code/app/src/components/project-status-badge.svelte b/code/app/src/components/project-status-badge.svelte new file mode 100644 index 0000000..3e93935 --- /dev/null +++ b/code/app/src/components/project-status-badge.svelte @@ -0,0 +1,25 @@ + + + diff --git a/code/app/src/components/switch.svelte b/code/app/src/components/switch.svelte new file mode 100644 index 0000000..1b67f80 --- /dev/null +++ b/code/app/src/components/switch.svelte @@ -0,0 +1,125 @@ + + + + +
+ {#if hasLabelOrDescription && !rightAlignedLabelDescription} + + {#if label} + {label} + {/if} + {#if description} + {description} + {/if} + + {/if} + {#if type === "short"} + + {:else if type === "icon"} + + {:else if type === "default"} + + {/if} + {#if hasLabelOrDescription && rightAlignedLabelDescription} + + {#if label} + {label} + {/if} + {#if description} + {description} + {/if} + + {/if} +
diff --git a/code/app/src/components/textarea.svelte b/code/app/src/components/textarea.svelte new file mode 100644 index 0000000..fa77e5c --- /dev/null +++ b/code/app/src/components/textarea.svelte @@ -0,0 +1,81 @@ + + +
+ {#if label} + + {/if} +
+