From 53f00d21b8f77daa6a34cc5972083868f184ddee Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Sat, 8 Feb 2025 09:27:54 -0600 Subject: [PATCH] Next: Organization switcher and filter improvements. (#1821) * Updated dependencies * Filter updates * Added ability to switch organizations. * Fixed filter builder * Reset page filters on org change * Fixed ci --- .../ClientApp/package-lock.json | 556 +++++++++--------- src/Exceptionless.Web/ClientApp/package.json | 24 +- .../boolean-faceted-filter-builder.svelte | 18 +- .../date-faceted-filter-builder.svelte | 18 +- .../events/components/filters/helpers.ts | 130 +++- .../events/components/filters/index.ts | 27 +- .../keyword-faceted-filter-builder.svelte | 18 +- .../components/filters/models.svelte.ts | 229 +------- .../number-faceted-filter-builder.svelte | 18 +- ...ion-defaults-faceted-filter-builder.svelte | 11 +- .../project-faceted-filter-builder.svelte | 18 +- .../filters/project-faceted-filter.svelte | 5 +- .../reference-faceted-filter-builder.svelte | 18 +- .../session-faceted-filter-builder.svelte | 18 +- .../status-faceted-filter-builder.svelte | 18 +- .../string-faceted-filter-builder.svelte | 18 +- .../type-faceted-filter-builder.svelte | 18 +- .../version-faceted-filter-builder.svelte | 18 +- .../features/organizations/context.svelte.ts | 9 + .../faceted-filter-builder.svelte | 16 +- .../components/faceted-filter/models.ts | 4 +- .../sidebar-organization-switcher.svelte | 4 + .../ClientApp/src/routes/(app)/+layout.svelte | 12 +- .../ClientApp/src/routes/(app)/+page.svelte | 91 ++- .../src/routes/(app)/issues/+page.svelte | 95 ++- .../src/routes/(app)/stream/+page.svelte | 81 ++- 26 files changed, 747 insertions(+), 745 deletions(-) diff --git a/src/Exceptionless.Web/ClientApp/package-lock.json b/src/Exceptionless.Web/ClientApp/package-lock.json index 50c7ab1de..b7db0859f 100644 --- a/src/Exceptionless.Web/ClientApp/package-lock.json +++ b/src/Exceptionless.Web/ClientApp/package-lock.json @@ -15,18 +15,18 @@ "@tanstack/svelte-query-devtools": "https://pkg.pr.new/@tanstack/svelte-query-devtools@28f98f9", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@typeschema/class-validator": "^0.3.0", - "bits-ui": "^1.0.0-next.78", + "bits-ui": "^1.0.0-next.89", "class-validator": "^0.14.1", "clsx": "^2.1.1", "formsnap": "^2.0.0", - "lucide-svelte": "^0.474.0", + "kit-query-params": "^0.0.26", + "lucide-svelte": "^0.475.0", "mode-watcher": "^0.5.1", "oidc-client-ts": "^3.1.0", "pretty-ms": "^9.2.0", "runed": "^0.23.2", "svelte-sonner": "^0.3.28", "svelte-time": "^2.0.0", - "sveltekit-search-params": "^4.0.0-next.0", "sveltekit-superforms": "^2.23.1", "tailwind-merge": "^2.6.0", "tailwind-variants": "^0.3.1", @@ -37,32 +37,32 @@ }, "devDependencies": { "@iconify-json/lucide": "^1.2.25", - "@playwright/test": "^1.50.0", + "@playwright/test": "^1.50.1", "@sveltejs/adapter-static": "^3.0.8", - "@sveltejs/kit": "^2.16.1", + "@sveltejs/kit": "^2.17.1", "@sveltejs/vite-plugin-svelte": "^5.0.3", "@types/eslint": "^9.6.1", - "@types/node": "^22.12.0", + "@types/node": "^22.13.1", "@types/throttle-debounce": "^5.0.2", "autoprefixer": "^10.4.20", "cross-env": "^7.0.3", - "eslint": "^9.19.0", + "eslint": "^9.20.0", "eslint-config-prettier": "^10.0.1", - "eslint-plugin-perfectionist": "^4.7.0", + "eslint-plugin-perfectionist": "^4.8.0", "eslint-plugin-svelte": "^2.46.1", "npm-run-all": "^4.1.5", "postcss": "^8.5.1", "prettier": "^3.4.2", "prettier-plugin-svelte": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.11", - "svelte": "^5.19.6", + "svelte": "^5.19.9", "svelte-check": "^4.1.4", "swagger-typescript-api": "^13.0.23", "tslib": "^2.8.1", "typescript": "^5.7.3", - "typescript-eslint": "^8.22.0", - "vite": "^6.0.11", - "vitest": "3.0.4" + "typescript-eslint": "^8.23.0", + "vite": "^6.1.0", + "vitest": "3.0.5" } }, "node_modules/@alloc/quick-lru": { @@ -662,9 +662,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.19.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", - "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.20.0.tgz", + "integrity": "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==", "dev": true, "license": "MIT", "engines": { @@ -1042,13 +1042,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.50.0.tgz", - "integrity": "sha512-ZGNXbt+d65EGjBORQHuYKj+XhCewlwpnSd/EDuLPZGSiEWmgOJB5RmMCCYGy5aMfTs9wx61RivfDKi8H/hcMvw==", + "version": "1.50.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.50.1.tgz", + "integrity": "sha512-Jii3aBg+CEDpgnuDxEp/h7BimHcUTDlpEtce89xEumlJ5ef2hqepZ+PWp1DDpYC/VO9fmWVI1IlEaoI5fK9FXQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.50.0" + "playwright": "1.50.1" }, "bin": { "playwright": "cli.js" @@ -1074,9 +1074,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.0.tgz", - "integrity": "sha512-wLJuPLT6grGZsy34g4N1yRfYeouklTgPhH1gWXCYspenKYD0s3cR99ZevOGw5BexMNywkbV3UkjADisozBmpPQ==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz", + "integrity": "sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==", "cpu": [ "arm" ], @@ -1087,9 +1087,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.28.0.tgz", - "integrity": "sha512-eiNkznlo0dLmVG/6wf+Ifi/v78G4d4QxRhuUl+s8EWZpDewgk7PX3ZyECUXU0Zq/Ca+8nU8cQpNC4Xgn2gFNDA==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz", + "integrity": "sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==", "cpu": [ "arm64" ], @@ -1100,9 +1100,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.28.0.tgz", - "integrity": "sha512-lmKx9yHsppblnLQZOGxdO66gT77bvdBtr/0P+TPOseowE7D9AJoBw8ZDULRasXRWf1Z86/gcOdpBrV6VDUY36Q==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz", + "integrity": "sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==", "cpu": [ "arm64" ], @@ -1113,9 +1113,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.28.0.tgz", - "integrity": "sha512-8hxgfReVs7k9Js1uAIhS6zq3I+wKQETInnWQtgzt8JfGx51R1N6DRVy3F4o0lQwumbErRz52YqwjfvuwRxGv1w==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz", + "integrity": "sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==", "cpu": [ "x64" ], @@ -1126,9 +1126,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.28.0.tgz", - "integrity": "sha512-lA1zZB3bFx5oxu9fYud4+g1mt+lYXCoch0M0V/xhqLoGatbzVse0wlSQ1UYOWKpuSu3gyN4qEc0Dxf/DII1bhQ==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz", + "integrity": "sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==", "cpu": [ "arm64" ], @@ -1139,9 +1139,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.28.0.tgz", - "integrity": "sha512-aI2plavbUDjCQB/sRbeUZWX9qp12GfYkYSJOrdYTL/C5D53bsE2/nBPuoiJKoWp5SN78v2Vr8ZPnB+/VbQ2pFA==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz", + "integrity": "sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==", "cpu": [ "x64" ], @@ -1152,9 +1152,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.28.0.tgz", - "integrity": "sha512-WXveUPKtfqtaNvpf0iOb0M6xC64GzUX/OowbqfiCSXTdi/jLlOmH0Ba94/OkiY2yTGTwteo4/dsHRfh5bDCZ+w==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz", + "integrity": "sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==", "cpu": [ "arm" ], @@ -1165,9 +1165,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.28.0.tgz", - "integrity": "sha512-yLc3O2NtOQR67lI79zsSc7lk31xjwcaocvdD1twL64PK1yNaIqCeWI9L5B4MFPAVGEVjH5k1oWSGuYX1Wutxpg==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz", + "integrity": "sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==", "cpu": [ "arm" ], @@ -1178,9 +1178,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.28.0.tgz", - "integrity": "sha512-+P9G9hjEpHucHRXqesY+3X9hD2wh0iNnJXX/QhS/J5vTdG6VhNYMxJ2rJkQOxRUd17u5mbMLHM7yWGZdAASfcg==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz", + "integrity": "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==", "cpu": [ "arm64" ], @@ -1191,9 +1191,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.28.0.tgz", - "integrity": "sha512-1xsm2rCKSTpKzi5/ypT5wfc+4bOGa/9yI/eaOLW0oMs7qpC542APWhl4A37AENGZ6St6GBMWhCCMM6tXgTIplw==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz", + "integrity": "sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==", "cpu": [ "arm64" ], @@ -1203,10 +1203,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz", + "integrity": "sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.28.0.tgz", - "integrity": "sha512-zgWxMq8neVQeXL+ouSf6S7DoNeo6EPgi1eeqHXVKQxqPy1B2NvTbaOUWPn/7CfMKL7xvhV0/+fq/Z/J69g1WAQ==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz", + "integrity": "sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==", "cpu": [ "ppc64" ], @@ -1217,9 +1230,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.28.0.tgz", - "integrity": "sha512-VEdVYacLniRxbRJLNtzwGt5vwS0ycYshofI7cWAfj7Vg5asqj+pt+Q6x4n+AONSZW/kVm+5nklde0qs2EUwU2g==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz", + "integrity": "sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==", "cpu": [ "riscv64" ], @@ -1230,9 +1243,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.28.0.tgz", - "integrity": "sha512-LQlP5t2hcDJh8HV8RELD9/xlYtEzJkm/aWGsauvdO2ulfl3QYRjqrKW+mGAIWP5kdNCBheqqqYIGElSRCaXfpw==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz", + "integrity": "sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==", "cpu": [ "s390x" ], @@ -1243,9 +1256,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.28.0.tgz", - "integrity": "sha512-Nl4KIzteVEKE9BdAvYoTkW19pa7LR/RBrT6F1dJCV/3pbjwDcaOq+edkP0LXuJ9kflW/xOK414X78r+K84+msw==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz", + "integrity": "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==", "cpu": [ "x64" ], @@ -1256,9 +1269,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.28.0.tgz", - "integrity": "sha512-eKpJr4vBDOi4goT75MvW+0dXcNUqisK4jvibY9vDdlgLx+yekxSm55StsHbxUsRxSTt3JEQvlr3cGDkzcSP8bw==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz", + "integrity": "sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==", "cpu": [ "x64" ], @@ -1269,9 +1282,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.28.0.tgz", - "integrity": "sha512-Vi+WR62xWGsE/Oj+mD0FNAPY2MEox3cfyG0zLpotZdehPFXwz6lypkGs5y38Jd/NVSbOD02aVad6q6QYF7i8Bg==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz", + "integrity": "sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==", "cpu": [ "arm64" ], @@ -1282,9 +1295,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.28.0.tgz", - "integrity": "sha512-kN/Vpip8emMLn/eOza+4JwqDZBL6MPNpkdaEsgUtW1NYN3DZvZqSQrbKzJcTL6hd8YNmFTn7XGWMwccOcJBL0A==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz", + "integrity": "sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==", "cpu": [ "ia32" ], @@ -1295,9 +1308,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.28.0.tgz", - "integrity": "sha512-Bvno2/aZT6usSa7lRDL2+hMjVAGjuqaymF1ApZm31JXzniR/hvr14jpU+/z4X6Gt5BPlzosscyJZGUvguXIqeQ==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz", + "integrity": "sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==", "cpu": [ "x64" ], @@ -1349,9 +1362,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.16.1.tgz", - "integrity": "sha512-2pF5sgGJx9brYZ/9nNDYnh5KX0JguPF14dnvvtf/MqrvlWrDj/e7Rk3LBJPecFLLK1GRs6ZniD24gFPqZm/NFw==", + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.17.1.tgz", + "integrity": "sha512-CpoGSLqE2MCmcQwA2CWJvOsZ9vW+p/1H3itrFykdgajUNAEyQPbsaSn7fZb6PLHQwe+07njxje9ss0fjZoCAyw==", "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", @@ -1542,9 +1555,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.12.0.tgz", - "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", + "version": "22.13.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz", + "integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1603,21 +1616,21 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.22.0.tgz", - "integrity": "sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz", + "integrity": "sha512-vBz65tJgRrA1Q5gWlRfvoH+w943dq9K1p1yDBY2pc+a1nbBLZp7fB9+Hk8DaALUbzjqlMfgaqlVPT1REJdkt/w==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/type-utils": "8.22.0", - "@typescript-eslint/utils": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/type-utils": "8.23.0", + "@typescript-eslint/utils": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1633,16 +1646,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.22.0.tgz", - "integrity": "sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.23.0.tgz", + "integrity": "sha512-h2lUByouOXFAlMec2mILeELUbME5SZRN/7R9Cw2RD2lRQQY08MWMM+PmVVKKJNK1aIwqTo9t/0CvOxwPbRIE2Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/typescript-estree": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/typescript-estree": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4" }, "engines": { @@ -1658,14 +1671,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", - "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.23.0.tgz", + "integrity": "sha512-OGqo7+dXHqI7Hfm+WqkZjKjsiRtFUQHPdGMXzk5mYXhJUedO7e/Y7i8AK3MyLMgZR93TX4bIzYrfyVjLC+0VSw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0" + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1676,16 +1689,16 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.22.0.tgz", - "integrity": "sha512-NzE3aB62fDEaGjaAYZE4LH7I1MUwHooQ98Byq0G0y3kkibPJQIXVUspzlFOmOfHhiDLwKzMlWxaNv+/qcZurJA==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.23.0.tgz", + "integrity": "sha512-iIuLdYpQWZKbiH+RkCGc6iu+VwscP5rCtQ1lyQ7TYuKLrcZoeJVpcLiG8DliXVkUxirW/PWlmS+d6yD51L9jvA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.22.0", - "@typescript-eslint/utils": "8.22.0", + "@typescript-eslint/typescript-estree": "8.23.0", + "@typescript-eslint/utils": "8.23.0", "debug": "^4.3.4", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1700,9 +1713,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", - "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.23.0.tgz", + "integrity": "sha512-1sK4ILJbCmZOTt9k4vkoulT6/y5CHJ1qUYxqpF1K/DBAd8+ZUL4LlSCxOssuH5m4rUaaN0uS0HlVPvd45zjduQ==", "dev": true, "license": "MIT", "engines": { @@ -1714,20 +1727,20 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", - "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.23.0.tgz", + "integrity": "sha512-LcqzfipsB8RTvH8FX24W4UUFk1bl+0yTOf9ZA08XngFwMg4Kj8A+9hwz8Cr/ZS4KwHrmo9PJiLZkOt49vPnuvQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/visitor-keys": "8.23.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1767,16 +1780,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", - "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.23.0.tgz", + "integrity": "sha512-uB/+PSo6Exu02b5ZEiVtmY6RVYO7YU5xqgzTIVZwTHvvK3HsL8tZZHFaTLFtRG3CsV4A5mhOv+NZx5BlhXPyIA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/typescript-estree": "8.22.0" + "@typescript-eslint/scope-manager": "8.23.0", + "@typescript-eslint/types": "8.23.0", + "@typescript-eslint/typescript-estree": "8.23.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1791,13 +1804,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", - "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.23.0.tgz", + "integrity": "sha512-oWWhcWDLwDfu++BGTZcmXWqpwtkwb5o7fxUIGksMQQDSdPW9prsSnfIOZMlsj4vBOSrcnjIUZMiIjODgGosFhQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/types": "8.23.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -1839,14 +1852,14 @@ } }, "node_modules/@vitest/expect": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.4.tgz", - "integrity": "sha512-Nm5kJmYw6P2BxhJPkO3eKKhGYKRsnqJqf+r0yOGRKpEP+bSCBDsjXgiu1/5QFrnPMEgzfC38ZEjvCFgaNBC0Eg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.5.tgz", + "integrity": "sha512-nNIOqupgZ4v5jWuQx2DSlHLEs7Q4Oh/7AYwNyE+k0UQzG7tSmjPXShUikn1mpNGzYEN2jJbTvLejwShMitovBA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.0.4", - "@vitest/utils": "3.0.4", + "@vitest/spy": "3.0.5", + "@vitest/utils": "3.0.5", "chai": "^5.1.2", "tinyrainbow": "^2.0.0" }, @@ -1855,13 +1868,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.4.tgz", - "integrity": "sha512-gEef35vKafJlfQbnyOXZ0Gcr9IBUsMTyTLXsEQwuyYAerpHqvXhzdBnDFuHLpFqth3F7b6BaFr4qV/Cs1ULx5A==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.5.tgz", + "integrity": "sha512-CLPNBFBIE7x6aEGbIjaQAX03ZZlBMaWwAjBdMkIf/cAn6xzLTiM3zYqO/WAbieEjsAZir6tO71mzeHZoodThvw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "3.0.4", + "@vitest/spy": "3.0.5", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, @@ -1882,9 +1895,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.4.tgz", - "integrity": "sha512-ts0fba+dEhK2aC9PFuZ9LTpULHpY/nd6jhAQ5IMU7Gaj7crPCTdCFfgvXxruRBLFS+MLraicCuFXxISEq8C93g==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.5.tgz", + "integrity": "sha512-CjUtdmpOcm4RVtB+up8r2vVDLR16Mgm/bYdkGFe3Yj/scRfCpbSi2W/BDSDcFK7ohw8UXvjMbOp9H4fByd/cOA==", "dev": true, "license": "MIT", "dependencies": { @@ -1895,13 +1908,13 @@ } }, "node_modules/@vitest/runner": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.4.tgz", - "integrity": "sha512-dKHzTQ7n9sExAcWH/0sh1elVgwc7OJ2lMOBrAm73J7AH6Pf9T12Zh3lNE1TETZaqrWFXtLlx3NVrLRb5hCK+iw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.5.tgz", + "integrity": "sha512-BAiZFityFexZQi2yN4OX3OkJC6scwRo8EhRB0Z5HIGGgd2q+Nq29LgHU/+ovCtd0fOfXj5ZI6pwdlUmC5bpi8A==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "3.0.4", + "@vitest/utils": "3.0.5", "pathe": "^2.0.2" }, "funding": { @@ -1916,13 +1929,13 @@ "license": "MIT" }, "node_modules/@vitest/snapshot": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.4.tgz", - "integrity": "sha512-+p5knMLwIk7lTQkM3NonZ9zBewzVp9EVkVpvNta0/PlFWpiqLaRcF4+33L1it3uRUCh0BGLOaXPPGEjNKfWb4w==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.5.tgz", + "integrity": "sha512-GJPZYcd7v8QNUJ7vRvLDmRwl+a1fGg4T/54lZXe+UOGy47F9yUfE18hRCtXL5aHN/AONu29NGzIXSVFh9K0feA==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.0.4", + "@vitest/pretty-format": "3.0.5", "magic-string": "^0.30.17", "pathe": "^2.0.2" }, @@ -1938,9 +1951,9 @@ "license": "MIT" }, "node_modules/@vitest/spy": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.4.tgz", - "integrity": "sha512-sXIMF0oauYyUy2hN49VFTYodzEAu744MmGcPR3ZBsPM20G+1/cSW/n1U+3Yu/zHxX2bIDe1oJASOkml+osTU6Q==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.5.tgz", + "integrity": "sha512-5fOzHj0WbUNqPK6blI/8VzZdkBlQLnT25knX0r4dbZI9qoZDf3qAdjoMmDcLG5A83W6oUUFJgUd0EYBc2P5xqg==", "dev": true, "license": "MIT", "dependencies": { @@ -1951,13 +1964,13 @@ } }, "node_modules/@vitest/utils": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.4.tgz", - "integrity": "sha512-8BqC1ksYsHtbWH+DfpOAKrFw3jl3Uf9J7yeFh85Pz52IWuh1hBBtyfEbRNNZNjl8H8A5yMLH9/t+k7HIKzQcZQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.5.tgz", + "integrity": "sha512-N9AX0NUoUtVwKwy21JtwzaqR5L5R5A99GAbrHfCCXK1lp593i/3AZAXhSP43wRQuxYsflrdzEfXZFo1reR1Nkg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "3.0.4", + "@vitest/pretty-format": "3.0.5", "loupe": "^3.1.2", "tinyrainbow": "^2.0.0" }, @@ -2224,17 +2237,18 @@ } }, "node_modules/bits-ui": { - "version": "1.0.0-next.78", - "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-1.0.0-next.78.tgz", - "integrity": "sha512-jZjG2ObZ/CNyCNaXecpItC7hRXqJAgEfMhr06/eNrf3wHiiPyhdcy4OkzLcJyxeOrDyj+xma8cZTd3JRWqJdAw==", + "version": "1.0.0-next.89", + "resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-1.0.0-next.89.tgz", + "integrity": "sha512-WbCVLKDlDyIFwhAtjR6KLhlaqpSKWZ1u15W/IiYE8p3szO0xrPx3i6ND0o5gk7q0QOTj3jjHQsKpNx54AR0LPg==", "license": "MIT", "dependencies": { "@floating-ui/core": "^1.6.4", "@floating-ui/dom": "^1.6.7", "@internationalized/date": "^3.5.6", "esm-env": "^1.1.2", - "runed": "^0.22.0", - "svelte-toolbelt": "^0.7.0" + "runed": "^0.23.2", + "svelte-toolbelt": "^0.7.1", + "tabbable": "^6.2.0" }, "engines": { "node": ">=18", @@ -2247,21 +2261,6 @@ "svelte": "^5.11.0" } }, - "node_modules/bits-ui/node_modules/runed": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.22.0.tgz", - "integrity": "sha512-ZWVXWhOr0P5xdNgtviz6D1ivLUDWKLCbeC5SUEJ3zBkqLReVqWHenFxMNFeFaiC5bfxhFxyxzyzB+98uYFtwdA==", - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3170,18 +3169,18 @@ } }, "node_modules/eslint": { - "version": "9.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.19.0.tgz", - "integrity": "sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==", + "version": "9.20.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.20.0.tgz", + "integrity": "sha512-aL4F8167Hg4IvsW89ejnpTwx+B/UQRzJPGgbIOl+4XqffWsahVVsLEWoZvnrVuwpWmnRd7XeXmQI1zlKcFDteA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", - "@eslint/core": "^0.10.0", + "@eslint/core": "^0.11.0", "@eslint/eslintrc": "^3.2.0", - "@eslint/js": "9.19.0", + "@eslint/js": "9.20.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -3259,14 +3258,14 @@ } }, "node_modules/eslint-plugin-perfectionist": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-4.7.0.tgz", - "integrity": "sha512-e2ODzm2SsAztFWY3ZRJd1K702vyl8Sapacjc3JluOW294CfA3+jfjin+UxjcrK48EvlNIMOp+JJB9N54YR2LRw==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-perfectionist/-/eslint-plugin-perfectionist-4.8.0.tgz", + "integrity": "sha512-ZF04IAPGItYMlj9xjgvvl/QpksZf79g0dkxbNcuxDjbcUSZ4CwucJ7h5Yzt5JuHe+i6igQbUYEp40j4ndfbvWQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "^8.21.0", - "@typescript-eslint/utils": "^8.21.0", + "@typescript-eslint/types": "^8.23.0", + "@typescript-eslint/utils": "^8.23.0", "natural-orderby": "^5.0.0" }, "engines": { @@ -3341,6 +3340,19 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/@eslint/core": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.11.0.tgz", + "integrity": "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/esm-env": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", @@ -4607,6 +4619,14 @@ "json-buffer": "3.0.1" } }, + "node_modules/kit-query-params": { + "version": "0.0.26", + "resolved": "https://registry.npmjs.org/kit-query-params/-/kit-query-params-0.0.26.tgz", + "integrity": "sha512-Tvb2QUgzSKCkxwn0zPv/nswsbuA8ExI9vqoUzgHbF0nkEUMW8YwQLMufEV5kCLoyeMN4Z3noAVdVhZderpGUQw==", + "peerDependencies": { + "svelte": "^5.0.0-next.1" + } + }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -4734,9 +4754,9 @@ "license": "MIT" }, "node_modules/loupe": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", - "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", + "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", "dev": true, "license": "MIT" }, @@ -4747,9 +4767,9 @@ "license": "ISC" }, "node_modules/lucide-svelte": { - "version": "0.474.0", - "resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-0.474.0.tgz", - "integrity": "sha512-yOSqjXPoEDOXCceBIfDaed6RinOvhp03ShiTXH6O+vlXE/NsyjQpktL8gm2vGDxi9d81HMuPFN1dwhVURh6mGg==", + "version": "0.475.0", + "resolved": "https://registry.npmjs.org/lucide-svelte/-/lucide-svelte-0.475.0.tgz", + "integrity": "sha512-N5+hFTPHaZe9HhqJDxxxODfYuOmI6v+JIowzERcea/uxytN/JZlehVTcINBNp8wMo7l6ov1Jf5srrDbkI/WsJg==", "license": "ISC", "peerDependencies": { "svelte": "^3 || ^4 || ^5.0.0-next.42" @@ -5614,13 +5634,13 @@ } }, "node_modules/playwright": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.0.tgz", - "integrity": "sha512-+GinGfGTrd2IfX1TA4N2gNmeIksSb+IAe589ZH+FlmpV3MYTx6+buChGIuDLQwrGNCw2lWibqV50fU510N7S+w==", + "version": "1.50.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.50.1.tgz", + "integrity": "sha512-G8rwsOQJ63XG6BbKj2w5rHeavFjy5zynBA9zsJMMtBoe/Uf757oG12NXz6e6OirF7RCrTVAKFXbLmn1RbL7Qaw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.50.0" + "playwright-core": "1.50.1" }, "bin": { "playwright": "cli.js" @@ -5633,9 +5653,9 @@ } }, "node_modules/playwright-core": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.0.tgz", - "integrity": "sha512-CXkSSlr4JaZs2tZHI40DsZUN/NIwgaUPsyLuOAaIZp2CyF2sN5MM5NJsyB188lFSSozFxQ5fPT4qM+f0tH/6wQ==", + "version": "1.50.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.50.1.tgz", + "integrity": "sha512-ra9fsNWayuYumt+NiM069M6OkcRb1FZSK8bgi66AtpFoWkg2+y0bJSNmkFrWhMbEBbVKC/EruAHH3g0zmtwGmQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -6185,9 +6205,9 @@ } }, "node_modules/rollup": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.28.0.tgz", - "integrity": "sha512-G9GOrmgWHBma4YfCcX8PjH0qhXSdH8B4HDE2o4/jaxj93S4DPCIDoLcXz99eWMji4hB29UFCEd7B2gwGJDR9cQ==", + "version": "4.34.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.6.tgz", + "integrity": "sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==", "license": "MIT", "dependencies": { "@types/estree": "1.0.6" @@ -6200,24 +6220,25 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.28.0", - "@rollup/rollup-android-arm64": "4.28.0", - "@rollup/rollup-darwin-arm64": "4.28.0", - "@rollup/rollup-darwin-x64": "4.28.0", - "@rollup/rollup-freebsd-arm64": "4.28.0", - "@rollup/rollup-freebsd-x64": "4.28.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.28.0", - "@rollup/rollup-linux-arm-musleabihf": "4.28.0", - "@rollup/rollup-linux-arm64-gnu": "4.28.0", - "@rollup/rollup-linux-arm64-musl": "4.28.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.28.0", - "@rollup/rollup-linux-riscv64-gnu": "4.28.0", - "@rollup/rollup-linux-s390x-gnu": "4.28.0", - "@rollup/rollup-linux-x64-gnu": "4.28.0", - "@rollup/rollup-linux-x64-musl": "4.28.0", - "@rollup/rollup-win32-arm64-msvc": "4.28.0", - "@rollup/rollup-win32-ia32-msvc": "4.28.0", - "@rollup/rollup-win32-x64-msvc": "4.28.0", + "@rollup/rollup-android-arm-eabi": "4.34.6", + "@rollup/rollup-android-arm64": "4.34.6", + "@rollup/rollup-darwin-arm64": "4.34.6", + "@rollup/rollup-darwin-x64": "4.34.6", + "@rollup/rollup-freebsd-arm64": "4.34.6", + "@rollup/rollup-freebsd-x64": "4.34.6", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.6", + "@rollup/rollup-linux-arm-musleabihf": "4.34.6", + "@rollup/rollup-linux-arm64-gnu": "4.34.6", + "@rollup/rollup-linux-arm64-musl": "4.34.6", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.6", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.6", + "@rollup/rollup-linux-riscv64-gnu": "4.34.6", + "@rollup/rollup-linux-s390x-gnu": "4.34.6", + "@rollup/rollup-linux-x64-gnu": "4.34.6", + "@rollup/rollup-linux-x64-musl": "4.34.6", + "@rollup/rollup-win32-arm64-msvc": "4.34.6", + "@rollup/rollup-win32-ia32-msvc": "4.34.6", + "@rollup/rollup-win32-x64-msvc": "4.34.6", "fsevents": "~2.3.2" } }, @@ -6889,9 +6910,9 @@ } }, "node_modules/svelte": { - "version": "5.19.6", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.19.6.tgz", - "integrity": "sha512-6ydekB3qyqUal+UhfMjmVOjRGtxysR8vuiMhi2nwuBtPJWnctVlsGspjVFB05qmR+TXI1emuqtZt81c0XiFleA==", + "version": "5.19.9", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.19.9.tgz", + "integrity": "sha512-860s752/ZZxHIsii31ELkdKBOCeAuDsfb/AGUXJyQyzUVLRSt4oqEw/BV5+2+mNg8mbqmD3OK+vMvwWMPM6f8A==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.3.0", @@ -7062,15 +7083,15 @@ } }, "node_modules/svelte-toolbelt": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.7.0.tgz", - "integrity": "sha512-i/Tv4NwAWWqJnK5H0F8y/ubDnogDYlwwyzKhrspTUFzrFuGnYshqd2g4/R43ds841wmaFiSW/HsdsdWhPOlrAA==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.7.1.tgz", + "integrity": "sha512-HcBOcR17Vx9bjaOceUvxkY3nGmbBmCBBbuWLLEWO6jtmWH8f/QoWmbyUfQZrpDINH39en1b8mptfPQT9VKQ1xQ==", "funding": [ "https://github.com/sponsors/huntabyte" ], "dependencies": { "clsx": "^2.1.1", - "runed": "^0.20.0", + "runed": "^0.23.2", "style-to-object": "^1.0.8" }, "engines": { @@ -7081,31 +7102,6 @@ "svelte": "^5.0.0" } }, - "node_modules/svelte-toolbelt/node_modules/runed": { - "version": "0.20.0", - "resolved": "https://registry.npmjs.org/runed/-/runed-0.20.0.tgz", - "integrity": "sha512-YqPxaUdWL5nUXuSF+/v8a+NkVN8TGyEGbQwTA25fLY35MR/2bvZ1c6sCbudoo1kT4CAJPh4kUkcgGVxW127WKw==", - "funding": [ - "https://github.com/sponsors/huntabyte", - "https://github.com/sponsors/tglide" - ], - "dependencies": { - "esm-env": "^1.0.0" - }, - "peerDependencies": { - "svelte": "^5.7.0" - } - }, - "node_modules/sveltekit-search-params": { - "version": "4.0.0-next.0", - "resolved": "https://registry.npmjs.org/sveltekit-search-params/-/sveltekit-search-params-4.0.0-next.0.tgz", - "integrity": "sha512-haFr5seakusriPePAv2F5/lsOa37rr9AOGDa5JOZ9CaB0Vrl8V8PdtqNWfh/kF0jlANdkdqz5gKK66nhhHT8tg==", - "license": "MIT", - "peerDependencies": { - "@sveltejs/kit": "^2.0.0", - "svelte": "^5.0.0" - } - }, "node_modules/sveltekit-superforms": { "version": "2.23.1", "resolved": "https://registry.npmjs.org/sveltekit-superforms/-/sveltekit-superforms-2.23.1.tgz", @@ -7305,6 +7301,12 @@ "node": ">= 6" } }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "license": "MIT" + }, "node_modules/tailwind-merge": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", @@ -7605,9 +7607,9 @@ "optional": true }, "node_modules/ts-api-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", - "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", "dev": true, "license": "MIT", "engines": { @@ -7757,15 +7759,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.22.0.tgz", - "integrity": "sha512-Y2rj210FW1Wb6TWXzQc5+P+EWI9/zdS57hLEc0gnyuvdzWo8+Y8brKlbj0muejonhMI/xAZCnZZwjbIfv1CkOw==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.23.0.tgz", + "integrity": "sha512-/LBRo3HrXr5LxmrdYSOCvoAMm7p2jNizNfbIpCgvG4HMsnoprRUOce/+8VJ9BDYWW68rqIENE/haVLWPeFZBVQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.22.0", - "@typescript-eslint/parser": "8.22.0", - "@typescript-eslint/utils": "8.22.0" + "@typescript-eslint/eslint-plugin": "8.23.0", + "@typescript-eslint/parser": "8.23.0", + "@typescript-eslint/utils": "8.23.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7950,14 +7952,14 @@ } }, "node_modules/vite": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz", - "integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz", + "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==", "license": "MIT", "dependencies": { "esbuild": "^0.24.2", - "postcss": "^8.4.49", - "rollup": "^4.23.0" + "postcss": "^8.5.1", + "rollup": "^4.30.1" }, "bin": { "vite": "bin/vite.js" @@ -8021,9 +8023,9 @@ } }, "node_modules/vite-node": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.4.tgz", - "integrity": "sha512-7JZKEzcYV2Nx3u6rlvN8qdo3QV7Fxyt6hx+CCKz9fbWxdX5IvUOmTWEAxMrWxaiSf7CKGLJQ5rFu8prb/jBjOA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.5.tgz", + "integrity": "sha512-02JEJl7SbtwSDJdYS537nU6l+ktdvcREfLksk/NDAqtdKWGqHl+joXzEubHROmS3E6pip+Xgu2tFezMu75jH7A==", "dev": true, "license": "MIT", "dependencies": { @@ -8083,19 +8085,19 @@ } }, "node_modules/vitest": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.4.tgz", - "integrity": "sha512-6XG8oTKy2gnJIFTHP6LD7ExFeNLxiTkK3CfMvT7IfR8IN+BYICCf0lXUQmX7i7JoxUP8QmeP4mTnWXgflu4yjw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.5.tgz", + "integrity": "sha512-4dof+HvqONw9bvsYxtkfUp2uHsTN9bV2CZIi1pWgoFpL1Lld8LA1ka9q/ONSsoScAKG7NVGf2stJTI7XRkXb2Q==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/expect": "3.0.4", - "@vitest/mocker": "3.0.4", - "@vitest/pretty-format": "^3.0.4", - "@vitest/runner": "3.0.4", - "@vitest/snapshot": "3.0.4", - "@vitest/spy": "3.0.4", - "@vitest/utils": "3.0.4", + "@vitest/expect": "3.0.5", + "@vitest/mocker": "3.0.5", + "@vitest/pretty-format": "^3.0.5", + "@vitest/runner": "3.0.5", + "@vitest/snapshot": "3.0.5", + "@vitest/spy": "3.0.5", + "@vitest/utils": "3.0.5", "chai": "^5.1.2", "debug": "^4.4.0", "expect-type": "^1.1.0", @@ -8107,7 +8109,7 @@ "tinypool": "^1.0.2", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0", - "vite-node": "3.0.4", + "vite-node": "3.0.5", "why-is-node-running": "^2.3.0" }, "bin": { @@ -8123,8 +8125,8 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "@vitest/browser": "3.0.4", - "@vitest/ui": "3.0.4", + "@vitest/browser": "3.0.5", + "@vitest/ui": "3.0.5", "happy-dom": "*", "jsdom": "*" }, diff --git a/src/Exceptionless.Web/ClientApp/package.json b/src/Exceptionless.Web/ClientApp/package.json index ffd78e20c..3aa79d89f 100644 --- a/src/Exceptionless.Web/ClientApp/package.json +++ b/src/Exceptionless.Web/ClientApp/package.json @@ -24,32 +24,32 @@ }, "devDependencies": { "@iconify-json/lucide": "^1.2.25", - "@playwright/test": "^1.50.0", + "@playwright/test": "^1.50.1", "@sveltejs/adapter-static": "^3.0.8", - "@sveltejs/kit": "^2.16.1", + "@sveltejs/kit": "^2.17.1", "@sveltejs/vite-plugin-svelte": "^5.0.3", "@types/eslint": "^9.6.1", - "@types/node": "^22.12.0", + "@types/node": "^22.13.1", "@types/throttle-debounce": "^5.0.2", "autoprefixer": "^10.4.20", "cross-env": "^7.0.3", - "eslint": "^9.19.0", + "eslint": "^9.20.0", "eslint-config-prettier": "^10.0.1", - "eslint-plugin-perfectionist": "^4.7.0", + "eslint-plugin-perfectionist": "^4.8.0", "eslint-plugin-svelte": "^2.46.1", "npm-run-all": "^4.1.5", "postcss": "^8.5.1", "prettier": "^3.4.2", "prettier-plugin-svelte": "^3.3.3", "prettier-plugin-tailwindcss": "^0.6.11", - "svelte": "^5.19.6", + "svelte": "^5.19.9", "svelte-check": "^4.1.4", "swagger-typescript-api": "^13.0.23", "tslib": "^2.8.1", "typescript": "^5.7.3", - "typescript-eslint": "^8.22.0", - "vite": "^6.0.11", - "vitest": "3.0.4" + "typescript-eslint": "^8.23.0", + "vite": "^6.1.0", + "vitest": "3.0.5" }, "dependencies": { "@exceptionless/browser": "^3.1.0", @@ -59,18 +59,18 @@ "@tanstack/svelte-query-devtools": "https://pkg.pr.new/@tanstack/svelte-query-devtools@28f98f9", "@tanstack/svelte-table": "^9.0.0-alpha.10", "@typeschema/class-validator": "^0.3.0", - "bits-ui": "^1.0.0-next.78", + "bits-ui": "^1.0.0-next.89", "class-validator": "^0.14.1", "clsx": "^2.1.1", "formsnap": "^2.0.0", - "lucide-svelte": "^0.474.0", + "kit-query-params": "^0.0.26", + "lucide-svelte": "^0.475.0", "mode-watcher": "^0.5.1", "oidc-client-ts": "^3.1.0", "pretty-ms": "^9.2.0", "runed": "^0.23.2", "svelte-sonner": "^0.3.28", "svelte-time": "^2.0.0", - "sveltekit-search-params": "^4.0.0-next.0", "sveltekit-superforms": "^2.23.1", "tailwind-merge": "^2.6.0", "tailwind-variants": "^0.3.1", diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/boolean-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/boolean-faceted-filter-builder.svelte index 76470a860..0f4ca2ae7 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/boolean-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/boolean-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/date-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/date-faceted-filter-builder.svelte index f03561e2c..3009e4906 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/date-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/date-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/helpers.ts b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/helpers.ts index e482a2740..b8c513aaa 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/helpers.ts +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/helpers.ts @@ -2,11 +2,88 @@ import type { IFilter } from '$comp/faceted-filter'; import { organization } from '$features/organizations/context.svelte'; -import { getKeywordFilter, getProjectFilter, getStackFilter } from './models.svelte'; +import { DateFilter, KeywordFilter, type ProjectFilter, type StringFilter } from './models.svelte'; + +const filterCache = new Map(); + +export function applyDefaultDateFilter(filters: IFilter[], time: null | string): IFilter[] { + if (!time) { + return filters; + } + + const dateFilter = filters.find((f) => f.key === 'date-date'); + if (dateFilter) { + return filters; + } + + return [...filters, new DateFilter('date', time)]; +} + +export function clearFilterCache() { + filterCache.clear(); +} + +export function filterChanged(filters: IFilter[], addedOrUpdated: IFilter): IFilter[] { + const index = filters.findIndex((f) => f.id === addedOrUpdated.id); + if (index === -1) { + return processFilterRules([...filters, addedOrUpdated]); + } + + return processFilterRules([...filters.slice(0, index), addedOrUpdated, ...filters.slice(index + 1)]); +} + +export function filterRemoved(filters: IFilter[], removed?: IFilter): IFilter[] { + // If detail is undefined, remove all filters. + if (!removed) { + return []; + } + + return filters.filter((f) => f.id !== removed.id); +} + +export function getFiltersFromCache(filter: null | string): IFilter[] { + if (!filter) { + return []; + } + + if (filterCache.has(filter)) { + return filterCache.get(filter) ?? []; + } + + // If filter is not in cache, return it in a new KeywordFilter instance. + return [new KeywordFilter(filter)]; +} + +export function getKeywordFilter(filters: IFilter[]): KeywordFilter | undefined { + return filters.find((f) => f.type === 'keyword') as KeywordFilter; +} + +export function getProjectFilter(filters: IFilter[]): ProjectFilter { + return filters.find((f) => f.type === 'project') as ProjectFilter; +} + +export function getStackFilter(filters: IFilter[]): StringFilter | undefined { + return filters.find((f) => f.type === 'string') as StringFilter; +} + +export function quote(value?: null | string): string | undefined { + return value ? `"${value}"` : undefined; +} + +export function quoteIfSpecialCharacters(value?: null | string): null | string | undefined { + // Check for lucene special characters or whitespace + const regex = new RegExp('\\+|\\-|\\&|\\||\\!|\\(|\\)|\\{|\\}|\\[|\\]|\\^|\\"|\\~|\\*|\\?|\\:|\\\\|\\/|\\s', 'g'); + + if (value && value.match(regex)) { + return quote(value); + } + + return value; +} export function shouldRefreshPersistentEventChanged( filters: IFilter[], - filter: string, + filter: null | string, organization_id?: string, project_id?: string, stack_id?: string, @@ -19,7 +96,7 @@ export function shouldRefreshPersistentEventChanged( if (id) { // This could match any kind of lucene query (even must not filtering) const keywordFilter = getKeywordFilter(filters); - if (keywordFilter && !keywordFilter.isEmpty()) { + if (keywordFilter && keywordFilter.value) { if (keywordFilter.value!.includes(id)) { return true; } @@ -28,14 +105,14 @@ export function shouldRefreshPersistentEventChanged( if (stack_id) { const stackFilter = getStackFilter(filters); - if (stackFilter && !stackFilter.isEmpty()) { + if (stackFilter && stackFilter.value) { return stackFilter.value === stack_id; } } if (project_id) { const projectFilter = getProjectFilter(filters); - if (projectFilter && !projectFilter.isEmpty()) { + if (projectFilter && projectFilter.value.length) { return projectFilter.value.includes(project_id); } } @@ -46,3 +123,46 @@ export function shouldRefreshPersistentEventChanged( return true; } + +export function toFilter(filters: IFilter[]): string { + return filters + .map((f) => f.toFilter()) + .filter(Boolean) + .join(' ') + .trim(); +} + +export function updateFilterCache(filter: null | string, filters: IFilter[]) { + if (filter) { + filterCache.set(filter, filters); + } +} + +function processFilterRules(filters: IFilter[]): IFilter[] { + // 1. There can only be one date filter by term at a time. + // 2. There can only be one project filter. + const uniqueFilters = new Map(); + for (const filter of filters) { + if (filter.type === 'project' || filter.type === 'date') { + const existingFilter = uniqueFilters.get(filter.key); + if (existingFilter) { + existingFilter.id = filter.id; + if ('value' in existingFilter && 'value' in filter) { + if (Array.isArray(existingFilter.value) && Array.isArray(filter.value)) { + existingFilter.value = [...new Set([...existingFilter.value, ...filter.value])]; + } else if (filter.value !== undefined) { + existingFilter.value = filter.value; + } + } else { + throw new Error('Unable to merge filters'); + } + } + + uniqueFilters.set(filter.key, existingFilter ?? filter); + } else { + uniqueFilters.set(filter.id, filter); + } + } + + return Array.from(uniqueFilters.values()); +} diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/index.ts b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/index.ts index 8f0b912b9..4bf8bc91e 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/index.ts +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/index.ts @@ -6,19 +6,6 @@ import DateFacetedFilterTrigger from './date-faceted-filter-trigger.svelte'; import DateFacetedFilter from './date-faceted-filter.svelte'; import KeywordFacetedFilterBuilder from './keyword-faceted-filter-builder.svelte'; import KeywordFacetedFilter from './keyword-faceted-filter.svelte'; -export { - type BooleanFilter, - type DateFilter, - KeywordFilter, - type NumberFilter, - ProjectFilter, - ReferenceFilter, - SessionFilter, - StatusFilter, - type StringFilter, - TypeFilter, - type VersionFilter -} from './models.svelte'; import NumberFacetedFilterBuilder from './number-faceted-filter-builder.svelte'; import NumberFacetedFilterTrigger from './number-faceted-filter-trigger.svelte'; import NumberFacetedFilter from './number-faceted-filter.svelte'; @@ -110,3 +97,17 @@ export { VersionFacetedFilterTrigger, VersionFacetedFilterTrigger as VersionTrigger }; + +export { + type BooleanFilter, + type DateFilter, + KeywordFilter, + type NumberFilter, + ProjectFilter, + ReferenceFilter, + SessionFilter, + StatusFilter, + type StringFilter, + TypeFilter, + type VersionFilter +} from './models.svelte'; diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/keyword-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/keyword-faceted-filter-builder.svelte index eb785e12b..013e920d7 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/keyword-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/keyword-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/models.svelte.ts b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/models.svelte.ts index 8f38404ce..59b12b10c 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/models.svelte.ts +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/models.svelte.ts @@ -2,6 +2,8 @@ import type { IFilter } from '$comp/faceted-filter'; import type { PersistentEventKnownTypes } from '$features/events/models'; import type { StackStatus } from '$features/stacks/models'; +import { quoteIfSpecialCharacters } from './helpers'; + export class BooleanFilter implements IFilter { public id: string = crypto.randomUUID(); public term = $state(); @@ -18,14 +20,6 @@ export class BooleanFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return this.value === undefined; - } - - public reset(): void { - this.value = undefined; - } - public toFilter(): string { if (this.term === undefined) { return ''; @@ -63,14 +57,6 @@ export class DateFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return this.value === undefined; - } - - public reset(): void { - this.value = undefined; - } - public toFilter(): string { if (this.term === undefined) { return ''; @@ -107,16 +93,8 @@ export class KeywordFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return !this.value?.trim(); - } - - public reset(): void { - this.value = undefined; - } - public toFilter(): string { - if (this.isEmpty()) { + if (!this.value?.trim()) { return ''; } @@ -147,14 +125,6 @@ export class NumberFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return this.value === undefined; - } - - public reset(): void { - this.value = undefined; - } - public toFilter(): string { if (this.term === undefined) { return ''; @@ -190,14 +160,6 @@ export class ProjectFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return this.value.length === 0; - } - - public reset(): void { - this.value = []; - } - public toFilter(): string { if (this.value.length == 0) { return ''; @@ -232,16 +194,8 @@ export class ReferenceFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return !this.value?.trim(); - } - - public reset(): void { - this.value = undefined; - } - public toFilter(): string { - if (this.isEmpty()) { + if (!this.value?.trim()) { return ''; } @@ -270,16 +224,8 @@ export class SessionFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return !this.value?.trim(); - } - - public reset(): void { - this.value = undefined; - } - public toFilter(): string { - if (this.isEmpty()) { + if (!this.value?.trim()) { return ''; } @@ -309,14 +255,6 @@ export class StatusFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return this.value.length === 0; - } - - public reset(): void { - this.value = []; - } - public toFilter(): string { if (this.value.length == 0) { return ''; @@ -353,14 +291,6 @@ export class StringFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return this.value === undefined; - } - - public reset(): void { - this.value = undefined; - } - public toFilter(): string { if (this.term === undefined) { return ''; @@ -396,14 +326,6 @@ export class TypeFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return this.value.length === 0; - } - - public reset(): void { - this.value = []; - } - public toFilter(): string { if (this.value.length == 0) { return ''; @@ -440,14 +362,6 @@ export class VersionFilter implements IFilter { this.value = value; } - public isEmpty(): boolean { - return this.value === undefined; - } - - public reset(): void { - this.value = undefined; - } - public toFilter(): string { if (this.term === undefined) { return ''; @@ -468,136 +382,3 @@ export class VersionFilter implements IFilter { }; } } - -export function filterChanged(filters: IFilter[], addedOrUpdated: IFilter): IFilter[] { - const index = filters.findIndex((f) => f.id === addedOrUpdated.id); - if (index === -1) { - return processFilterRules([...filters, addedOrUpdated]); - } - - return processFilterRules([...filters.slice(0, index), addedOrUpdated, ...filters.slice(index + 1)]); -} - -export const filterSerializer = { - deserialize: (value: string): IFilter[] => { - if (!value) { - return []; - } - - const data: unknown[] = JSON.parse(value); - const filters: IFilter[] = []; - for (const filterData of data) { - const filter = getFilter(filterData as Omit); - if (filter) { - filters.push(filter); - } - } - - return filters; - }, - serialize: JSON.stringify -}; - -export function filterRemoved(filters: IFilter[], removed?: IFilter): IFilter[] { - // If detail is undefined, remove all filters. - if (!removed) { - return []; - } - - return filters.filter((f) => f.id !== removed.id); -} - -export function getFilter(filter: Omit & Record): IFilter | undefined { - switch (filter.type) { - case 'boolean': - return new BooleanFilter(filter.term as string, filter.value as boolean); - case 'date': - return new DateFilter(filter.term as string, filter.value as Date); - case 'keyword': - return new KeywordFilter(filter.value as string); - case 'number': - return new NumberFilter(filter.term as string, filter.value as number); - case 'project': - return new ProjectFilter(filter.value as string[]); - case 'reference': - return new ReferenceFilter(filter.value as string); - case 'session': - return new SessionFilter(filter.value as string); - case 'status': - return new StatusFilter(filter.value as StackStatus[]); - case 'string': - return new StringFilter(filter.term as string, filter.value as string); - case 'type': - return new TypeFilter(filter.value as PersistentEventKnownTypes[]); - case 'version': - return new VersionFilter(filter.term as string, filter.value as string); - default: - throw new Error(`Unknown filter type: ${filter.type}`); - } -} - -export function getKeywordFilter(filters: IFilter[]): KeywordFilter | undefined { - return filters.find((f) => f.type === 'keyword') as KeywordFilter; -} - -export function getProjectFilter(filters: IFilter[]): ProjectFilter { - return filters.find((f) => f.type === 'project') as ProjectFilter; -} - -export function getStackFilter(filters: IFilter[]): StringFilter | undefined { - return filters.find((f) => f.type === 'string') as StringFilter; -} - -export function quote(value?: null | string): string | undefined { - return value ? `"${value}"` : undefined; -} - -export function quoteIfSpecialCharacters(value?: null | string): null | string | undefined { - // Check for lucene special characters or whitespace - const regex = new RegExp('\\+|\\-|\\&|\\||\\!|\\(|\\)|\\{|\\}|\\[|\\]|\\^|\\"|\\~|\\*|\\?|\\:|\\\\|\\/|\\s', 'g'); - - if (value && value.match(regex)) { - return quote(value); - } - - return value; -} - -export function toFilter(filters: IFilter[]): string { - return filters - .map((f) => f.toFilter()) - .filter(Boolean) - .join(' ') - .trim(); -} - -function processFilterRules(filters: IFilter[]): IFilter[] { - // 1. There can only be one date filter by term at a time. - // 2. There can only be one project filter. - - const uniqueFilters = new Map(); - for (const filter of filters) { - if (filter.type === 'project' || filter.type === 'date') { - const existingFilter = uniqueFilters.get(filter.key); - if (existingFilter) { - if ('value' in existingFilter && 'value' in filter) { - if (Array.isArray(existingFilter.value) && Array.isArray(filter.value)) { - existingFilter.value = [...new Set([...existingFilter.value, ...filter.value])]; - } else if (filter.value !== undefined) { - existingFilter.value = filter.value; - } - } else { - const { id, ...props } = filter; - console.trace(`Filter with key ${existingFilter.type} (${id}) already exists. Merging properties`); - Object.assign(existingFilter, props); - } - } - - uniqueFilters.set(filter.key, existingFilter ?? filter); - } else { - uniqueFilters.set(filter.id, filter); - } - } - - return Array.from(uniqueFilters.values()); -} diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/number-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/number-faceted-filter-builder.svelte index fb4dd719d..1c5e96709 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/number-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/number-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/organization-defaults-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/organization-defaults-faceted-filter-builder.svelte index 7df844cc9..a3c2adf2a 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/organization-defaults-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/organization-defaults-faceted-filter-builder.svelte @@ -72,28 +72,37 @@ ]; + + {#each eventsBooleanFilters as { priority, term, title }} {/each} + {#if includeDateFacets} {#each eventsDateFilters as { priority, term, title }} {/each} {/if} + {#each eventsGeoFilters as { priority, term, title }} {/each} + {#each eventsNumberFilters as { priority, term, title }} {/each} + + {#each eventsStringFilters as { priority, term, title }} {/each} - + + + {#each eventsVersionFilters as { priority, term, title }} {/each} diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/project-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/project-faceted-filter-builder.svelte index 69987ddc2..fada74336 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/project-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/project-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/project-faceted-filter.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/project-faceted-filter.svelte index 81257c8cb..45e5f589f 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/project-faceted-filter.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/project-faceted-filter.svelte @@ -3,17 +3,18 @@ import * as FacetedFilter from '$comp/faceted-filter'; import { organization } from '$features/organizations/context.svelte'; - // TODO: look at why we go across features here import { getOrganizationProjectsQuery } from '$features/projects/api.svelte'; import { ProjectFilter } from './models.svelte'; let { filter, filterChanged, filterRemoved, title = 'Project', ...props }: FacetedFilterProps = $props(); + // Store the organizationId to prevent loading when switching organizations. + const organizationId = organization.current; const response = getOrganizationProjectsQuery({ route: { get organizationId() { - return organization.current; + return organizationId; } } }); diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/reference-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/reference-faceted-filter-builder.svelte index 48101fa2f..30d8caf2e 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/reference-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/reference-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/session-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/session-faceted-filter-builder.svelte index b49d83101..19df40b7b 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/session-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/session-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/status-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/status-faceted-filter-builder.svelte index 87806b5f1..e57801549 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/status-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/status-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/string-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/string-faceted-filter-builder.svelte index 7cb57e32e..8c3d27d4e 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/string-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/string-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/type-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/type-faceted-filter-builder.svelte index df0bfa57a..a373ef2b4 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/type-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/type-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/version-faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/version-faceted-filter-builder.svelte index 1a8eabbfd..529b4be4e 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/version-faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/events/components/filters/version-faceted-filter-builder.svelte @@ -1,6 +1,5 @@ diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/organizations/context.svelte.ts b/src/Exceptionless.Web/ClientApp/src/lib/features/organizations/context.svelte.ts index ca26f7ed9..8de197c48 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/organizations/context.svelte.ts +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/organizations/context.svelte.ts @@ -1,3 +1,12 @@ import { PersistedState } from 'runed'; export const organization = new PersistedState('organization', undefined); + +export function dispatchSwitchOrganizationEvent() { + document.dispatchEvent( + new CustomEvent('switch-organization', { + bubbles: true, + detail: organization.current + }) + ); +} diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/faceted-filter/faceted-filter-builder.svelte b/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/faceted-filter/faceted-filter-builder.svelte index 744d97c94..ed0d01eee 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/faceted-filter/faceted-filter-builder.svelte +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/faceted-filter/faceted-filter-builder.svelte @@ -21,8 +21,15 @@ let open = $state(false); let lastOpenFilterId = $state(); - let facets: FacetedFilter[] = $derived( - filters.map((filter) => { + + // Clear the builder context because multiple builders will be loaded during page navigation. + builderContext.clear(); + let facets: FacetedFilter[] = $derived.by(() => { + if (builderContext.size === 0) { + return []; + } + + return filters.map((filter) => { const builder = builderContext.get(filter.key); if (!builder) { throw new Error(`Facet filter builder not found for key: ${filter.key}`); @@ -35,8 +42,8 @@ open: lastOpenFilterId === f.id, title: builder.title }; - }) - ); + }); + }); const sortedBuilders = $derived( [...builderContext.entries()].sort((facetA, facetB) => { @@ -74,7 +81,6 @@ function onRemoveAll() { lastOpenFilterId = undefined; - facets.forEach((facet) => facet.filter.reset()); remove(); } diff --git a/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/faceted-filter/models.ts b/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/faceted-filter/models.ts index 9e1e2b8e4..cf4aa3972 100644 --- a/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/faceted-filter/models.ts +++ b/src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/faceted-filter/models.ts @@ -9,10 +9,8 @@ export type FacetedFilterProps = { }; export interface IFilter { - readonly id: string; - isEmpty(): boolean; + id: string; readonly key: string; - reset(): void; toFilter(): string; readonly type: string; } diff --git a/src/Exceptionless.Web/ClientApp/src/routes/(app)/(components)/layouts/sidebar-organization-switcher.svelte b/src/Exceptionless.Web/ClientApp/src/routes/(app)/(components)/layouts/sidebar-organization-switcher.svelte index 499b24b18..2acb7082c 100644 --- a/src/Exceptionless.Web/ClientApp/src/routes/(app)/(components)/layouts/sidebar-organization-switcher.svelte +++ b/src/Exceptionless.Web/ClientApp/src/routes/(app)/(components)/layouts/sidebar-organization-switcher.svelte @@ -24,6 +24,10 @@ let activeOrganization = $derived(organizations?.find((organization) => organization.id === selected)); function onOrganizationSelected(organization: ViewOrganization): void { + if (organization.id === selected) { + return; + } + selected = organization.id; } diff --git a/src/Exceptionless.Web/ClientApp/src/routes/(app)/+layout.svelte b/src/Exceptionless.Web/ClientApp/src/routes/(app)/+layout.svelte index 2a7e07655..4c1b9b91a 100644 --- a/src/Exceptionless.Web/ClientApp/src/routes/(app)/+layout.svelte +++ b/src/Exceptionless.Web/ClientApp/src/routes/(app)/+layout.svelte @@ -6,7 +6,7 @@ import { accessToken, gotoLogin } from '$features/auth/index.svelte'; import { invalidatePersistentEventQueries } from '$features/events/api.svelte'; import { getOrganizationQuery, invalidateOrganizationQueries } from '$features/organizations/api.svelte'; - import { organization } from '$features/organizations/context.svelte'; + import { dispatchSwitchOrganizationEvent, organization } from '$features/organizations/context.svelte'; import { invalidateProjectQueries } from '$features/projects/api.svelte'; import { invalidateStackQueries } from '$features/stacks/api.svelte'; import { getMeQuery, invalidateUserQueries } from '$features/users/api.svelte'; @@ -163,11 +163,13 @@ if (organizationsResponse.data.length === 0) { // TODO: Redirect to create organization page. organization.current = undefined; + dispatchSwitchOrganizationEvent(); return; } if (!organizationsResponse.data.find((org) => org.id === organization.current)) { organization.current = organizationsResponse.data[0]!.id; + dispatchSwitchOrganizationEvent(); } }); @@ -185,7 +187,13 @@ class="pt-2" isLoading={organizationsResponse.isLoading} organizations={organizationsResponse.data} - bind:selected={organization.current} + bind:selected={ + () => organization.current, + (v) => { + organization.current = v; + dispatchSwitchOrganizationEvent(); + } + } /> {/snippet} diff --git a/src/Exceptionless.Web/ClientApp/src/routes/(app)/+page.svelte b/src/Exceptionless.Web/ClientApp/src/routes/(app)/+page.svelte index abaedabe5..195220d54 100644 --- a/src/Exceptionless.Web/ClientApp/src/routes/(app)/+page.svelte +++ b/src/Exceptionless.Web/ClientApp/src/routes/(app)/+page.svelte @@ -1,4 +1,5 @@