From 03301518f063fc2f83823931cba059663b471f05 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Sun, 22 Mar 2026 02:55:17 +0000 Subject: [PATCH] TypeScript checking is clean. Tons and tons of broken functionality. Now the crawl begins. --- package.json | 7 +- pnpm-lock.yaml | 10 ++ ts/components/CommunicationColumnList.vue | 131 ++++++++++++++++++++++ ts/env.d.ts | 8 ++ ts/sidebar.ts | 70 ------------ ts/vue-shim.d.ts | 5 + tsconfig.json | 18 +++ 7 files changed, 176 insertions(+), 73 deletions(-) create mode 100644 ts/components/CommunicationColumnList.vue create mode 100644 ts/env.d.ts delete mode 100644 ts/sidebar.ts create mode 100644 ts/vue-shim.d.ts create mode 100644 tsconfig.json diff --git a/package.json b/package.json index aa37bde0..aa098520 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "vue-router": "^5.0.4" }, "devDependencies": { + "@types/bootstrap": "^5.2.10", "esbuild": "^0.25.5", "esbuild-plugin-vue3": "^0.5.1", "esbuild-sass-plugin": "^3.7.0", @@ -22,10 +23,10 @@ "scripts": { "build": "node build.js", "build:prod": "node build.js --minify", - "dev": "pnpm typecheck:watch & pnpm watch", + "dev": "pnpm typecheck:watch & pnpm watch", "generate-icons": "node generate-icons.js", - "typecheck": "tsc --noEmit", - "typecheck:watch": "tsc --noEmit --watch --preserveWatchOutput", + "typecheck": "tsc --noEmit", + "typecheck:watch": "tsc --noEmit --watch --preserveWatchOutput", "watch": "node build.js --watch" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5d1e8464..f3608f92 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,6 +30,9 @@ importers: specifier: ^5.0.4 version: 5.0.4(@vue/compiler-sfc@3.5.30)(pinia@3.0.4(typescript@5.9.3)(vue@3.5.30(typescript@5.9.3)))(vue@3.5.30(typescript@5.9.3)) devDependencies: + '@types/bootstrap': + specifier: ^5.2.10 + version: 5.2.10 esbuild: specifier: ^0.25.5 version: 0.25.12 @@ -365,6 +368,9 @@ packages: '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@types/bootstrap@5.2.10': + resolution: {integrity: sha512-F2X+cd6551tep0MvVZ6nM8v7XgGN/twpdNDjqS1TUM7YFNEtQYWk+dKAnH+T1gr6QgCoGMPl487xw/9hXooa2g==} + '@types/geojson@7946.0.16': resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} @@ -1143,6 +1149,10 @@ snapshots: '@popperjs/core@2.11.8': {} + '@types/bootstrap@5.2.10': + dependencies: + '@popperjs/core': 2.11.8 + '@types/geojson@7946.0.16': {} '@types/supercluster@7.1.3': diff --git a/ts/components/CommunicationColumnList.vue b/ts/components/CommunicationColumnList.vue new file mode 100644 index 00000000..e56df826 --- /dev/null +++ b/ts/components/CommunicationColumnList.vue @@ -0,0 +1,131 @@ + + + diff --git a/ts/env.d.ts b/ts/env.d.ts new file mode 100644 index 00000000..3473de44 --- /dev/null +++ b/ts/env.d.ts @@ -0,0 +1,8 @@ +declare global { + interface Window { + bootstrap: typeof import("bootstrap"); + SSEManager: typeof import("./sse-manager").SSEManager; + } +} + +export {}; diff --git a/ts/sidebar.ts b/ts/sidebar.ts deleted file mode 100644 index 2676dadf..00000000 --- a/ts/sidebar.ts +++ /dev/null @@ -1,70 +0,0 @@ -export function SetupSidebar() { - var popoverTriggerList = [].slice.call( - document.querySelectorAll('[data-bs-toggle="popover"]'), - ); - var popoverList = popoverTriggerList.map(function (popoverTriggerEl) { - return new bootstrap.Popover(popoverTriggerEl); - }); - console.log("Initialized ", popoverTriggerList.length, " popovers"); - - var tooltipTriggerList = [].slice.call( - document.querySelectorAll('[data-bs-toggle="tooltip"]'), - ); - var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { - let t = new bootstrap.Tooltip(tooltipTriggerEl); - return t; - }); - console.log("Initialized ", tooltipTriggerList.length, " tooltips"); - restoreLocalStorage(); - setTooltipsForSidebar(); - SSEManager.subscribe("*", function (e) { - if (e.type != "heartbeat") { - updateUserState(); - } - }); - document.getElementById("sidebarToggle").addEventListener("click", () => { - const sidebar = document.getElementById("sidebar"); - sidebar.classList.toggle("collapsed"); - document.getElementById("content").classList.toggle("expanded"); - setTooltipsForSidebar(); - localStorage.setItem( - "sidebar.expanded", - (!sidebar.classList.contains("collapsed")).toString(), - ); - }); - updateUserState(); -} -function restoreLocalStorage() { - const expanded = localStorage.getItem("sidebar.expanded"); - if (expanded == "false") { - document.getElementById("sidebar").classList.add("collapsed"); - document.getElementById("content").classList.add("expanded"); - } else { - document.getElementById("sidebar").classList.remove("collapsed"); - document.getElementById("content").classList.remove("expanded"); - localStorage.setItem("sidebar.expanded", "true"); - } -} -function setTooltipsForSidebar() { - const sidebarTooltips = document.querySelectorAll( - '#sidebar [data-bs-toggle="tooltip"]', - ); - const isExpanded = document - .getElementById("content") - .classList.contains("expanded"); - sidebarTooltips.forEach((t) => { - const tooltip = bootstrap.Tooltip.getOrCreateInstance(t); - if (isExpanded) { - tooltip.enable(); - } else { - tooltip.disable(); - } - }); -} -async function updateUserState() { - const response = await fetch("/api/user/self"); - const data = await response.json(); - Object.keys(data).forEach((key) => { - store_user[key] = data[key]; - }); -} diff --git a/ts/vue-shim.d.ts b/ts/vue-shim.d.ts new file mode 100644 index 00000000..9d452a7a --- /dev/null +++ b/ts/vue-shim.d.ts @@ -0,0 +1,5 @@ +declare module "*.vue" { + import type { DefineComponent } from "vue"; + const component: DefineComponent; + export default component; +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..d9588f72 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "moduleResolution": "bundler", + "strict": true, + "jsx": "preserve", + "esModuleInterop": true, + "skipLibCheck": true, + "noEmit": true, + "paths": { + "@/*": ["./ts/*"] + } + }, + "include": ["ts/**/*", "ts/**/*.vue", "ts/vue-shim.d.ts"], + "exclude": ["node_modules"] +}