From ab89c7dc5be3f442f78efdc76f20491375dfe97a Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Sun, 29 Mar 2026 19:37:48 +0200 Subject: [PATCH] build(web)!: upgrade to tailwind css v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit migrate from tailwind v3 to v4: - replace postcss-based setup with @tailwindcss/vite plugin - rewrite index.css: @tailwind directives → @import "tailwindcss", JS theme config → CSS @theme inline block - replace tailwindcss-animate with tw-animate-css - load @tailwindcss/typography via @plugin directive - configure dark mode via @custom-variant - delete tailwind.config.ts and postcss.config.js rename classes per v4 spec: - shadow → shadow-sm, shadow-sm → shadow-xs - rounded → rounded-sm - outline-none → outline-hidden also fix type errors from apollo v4 (add explicit query types), react-router v7 (void navigate promises), and react-markdown v10 (move className to wrapper div) Co-Authored-By: Claude Opus 4.6 (1M context) --- webui2/package.json | 9 +- webui2/pnpm-lock.yaml | 597 +++++++----------- webui2/postcss.config.js | 6 - webui2/src/components/bugs/BugRow.tsx | 8 +- webui2/src/components/bugs/CommentBox.tsx | 10 +- webui2/src/components/bugs/IssueFilters.tsx | 48 +- webui2/src/components/bugs/LabelEditor.tsx | 8 +- webui2/src/components/bugs/QueryInput.tsx | 10 +- webui2/src/components/bugs/Timeline.tsx | 22 +- webui2/src/components/bugs/TitleEditor.tsx | 6 +- webui2/src/components/code/CodeBreadcrumb.tsx | 8 +- webui2/src/components/code/CommitList.tsx | 44 +- webui2/src/components/code/FileDiffView.tsx | 39 +- webui2/src/components/code/FileTree.tsx | 28 +- webui2/src/components/code/FileViewer.tsx | 12 +- webui2/src/components/code/RefSelector.tsx | 18 +- webui2/src/components/content/Markdown.tsx | 27 +- webui2/src/components/layout/Header.tsx | 6 +- webui2/src/components/layout/Shell.tsx | 2 +- webui2/src/components/ui/badge.tsx | 7 +- webui2/src/components/ui/button.tsx | 10 +- webui2/src/components/ui/input.tsx | 2 +- webui2/src/components/ui/popover.tsx | 2 +- webui2/src/components/ui/textarea.tsx | 2 +- webui2/src/index.css | 160 +++-- webui2/src/lib/auth.tsx | 4 +- webui2/src/pages/BugDetailPage.tsx | 14 +- webui2/src/pages/BugListPage.tsx | 22 +- webui2/src/pages/CodePage.tsx | 41 +- webui2/src/pages/CommitPage.tsx | 56 +- webui2/src/pages/ErrorPage.tsx | 4 +- webui2/src/pages/IdentitySelectPage.tsx | 28 +- webui2/src/pages/NewBugPage.tsx | 16 +- webui2/src/pages/RepoPickerPage.tsx | 16 +- webui2/src/pages/UserProfilePage.tsx | 44 +- webui2/tailwind.config.ts | 71 --- webui2/tsconfig.node.json | 2 +- webui2/vite.config.ts | 3 +- 38 files changed, 648 insertions(+), 764 deletions(-) delete mode 100644 webui2/postcss.config.js delete mode 100644 webui2/tailwind.config.ts diff --git a/webui2/package.json b/webui2/package.json index 1bf81ee7463ef1caabcd32724e4e43ab063f304f..476cd43db0b21089d5b42836e541e033769af5b0 100644 --- a/webui2/package.json +++ b/webui2/package.json @@ -40,23 +40,22 @@ "remark-gfm": "^4.0.0", "rxjs": "^7.8.2", "tailwind-merge": "^3.5.0", - "tailwindcss-animate": "^1.0.7" + "tw-animate-css": "^1.4.0" }, "devDependencies": { "@graphql-codegen/cli": "^6.2.1", "@graphql-codegen/typescript": "^5.0.9", "@graphql-codegen/typescript-operations": "^5.0.9", "@graphql-codegen/typescript-react-apollo": "^4.3.2", - "@tailwindcss/typography": "^0.5.15", + "@tailwindcss/typography": "^0.5.19", + "@tailwindcss/vite": "^4.2.2", "@types/react": "^19.1.0", "@types/react-dom": "^19.1.0", "@vitejs/plugin-react": "^6.0.1", - "autoprefixer": "^10.4.20", "oxfmt": "^0.42.0", "oxlint": "^1.57.0", "oxlint-tsgolint": "^0.18.1", - "postcss": "^8.4.49", - "tailwindcss": "^3.4.17", + "tailwindcss": "^4.2.2", "typescript": "^6.0.2", "vite": "^8.0.3" }, diff --git a/webui2/pnpm-lock.yaml b/webui2/pnpm-lock.yaml index fc0966510e1b231ff68c9bf1d1fde84b88c00d30..5e68478e961fdd263c5467277fd3316508f0227f 100644 --- a/webui2/pnpm-lock.yaml +++ b/webui2/pnpm-lock.yaml @@ -83,9 +83,9 @@ importers: tailwind-merge: specifier: ^3.5.0 version: 3.5.0 - tailwindcss-animate: - specifier: ^1.0.7 - version: 1.0.7(tailwindcss@3.4.19(yaml@2.8.3)) + tw-animate-css: + specifier: ^1.4.0 + version: 1.4.0 devDependencies: '@graphql-codegen/cli': specifier: ^6.2.1 @@ -100,8 +100,11 @@ importers: specifier: ^4.3.2 version: 4.4.1(graphql@16.13.2) '@tailwindcss/typography': - specifier: ^0.5.15 - version: 0.5.19(tailwindcss@3.4.19(yaml@2.8.3)) + specifier: ^0.5.19 + version: 0.5.19(tailwindcss@4.2.2) + '@tailwindcss/vite': + specifier: ^4.2.2 + version: 4.2.2(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3)) '@types/react': specifier: ^19.1.0 version: 19.2.14 @@ -110,10 +113,7 @@ importers: version: 19.2.3(@types/react@19.2.14) '@vitejs/plugin-react': specifier: ^6.0.1 - version: 6.0.1(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@1.21.7)(yaml@2.8.3)) - autoprefixer: - specifier: ^10.4.20 - version: 10.4.27(postcss@8.5.8) + version: 6.0.1(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3)) oxfmt: specifier: ^0.42.0 version: 0.42.0 @@ -123,25 +123,18 @@ importers: oxlint-tsgolint: specifier: ^0.18.1 version: 0.18.1 - postcss: - specifier: ^8.4.49 - version: 8.5.8 tailwindcss: - specifier: ^3.4.17 - version: 3.4.19(yaml@2.8.3) + specifier: ^4.2.2 + version: 4.2.2 typescript: specifier: ^6.0.2 version: 6.0.2 vite: specifier: ^8.0.3 - version: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@1.21.7)(yaml@2.8.3) + version: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3) packages: - '@alloc/quick-lru@5.2.0': - resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} - engines: {node: '>=10'} - '@apollo/client@4.1.6': resolution: {integrity: sha512-ak8uzqmKeX3u9BziGf83RRyODAJKFkPG72hTNvEj4WjMWFmuKW2gGN1i3OfajKT6yuGjvo+n23ES2zqWDKFCZg==} peerDependencies: @@ -1387,11 +1380,105 @@ packages: resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} + '@tailwindcss/node@4.2.2': + resolution: {integrity: sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==} + + '@tailwindcss/oxide-android-arm64@4.2.2': + resolution: {integrity: sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + resolution: {integrity: sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.2.2': + resolution: {integrity: sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + resolution: {integrity: sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + resolution: {integrity: sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + resolution: {integrity: sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + resolution: {integrity: sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + resolution: {integrity: sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + resolution: {integrity: sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + resolution: {integrity: sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + resolution: {integrity: sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + resolution: {integrity: sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.2.2': + resolution: {integrity: sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==} + engines: {node: '>= 20'} + '@tailwindcss/typography@0.5.19': resolution: {integrity: sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg==} peerDependencies: tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + '@tailwindcss/vite@4.2.2': + resolution: {integrity: sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -1501,16 +1588,6 @@ packages: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} - argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1526,13 +1603,6 @@ packages: resolution: {integrity: sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==} engines: {node: '>=8'} - autoprefixer@10.4.27: - resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} - engines: {node: ^10 || ^12 || >=14} - hasBin: true - peerDependencies: - postcss: ^8.1.0 - bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -1545,10 +1615,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - brace-expansion@5.0.5: resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} engines: {node: 18 || 20 || >=22} @@ -1569,10 +1635,6 @@ packages: camel-case@4.1.2: resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} - camelcase-css@2.0.1: - resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} - engines: {node: '>= 6'} - caniuse-lite@1.0.30001781: resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==} @@ -1611,10 +1673,6 @@ packages: chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -1651,10 +1709,6 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} @@ -1747,16 +1801,10 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - didyoumean@1.2.2: - resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} - dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} @@ -1775,6 +1823,10 @@ packages: emoticon@4.1.0: resolution: {integrity: sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==} + enhanced-resolve@5.20.1: + resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} + engines: {node: '>=10.13.0'} + entities@6.0.1: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} @@ -1835,17 +1887,11 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} - fraction.js@5.3.4: - resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -1869,14 +1915,13 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphql-config@5.1.6: resolution: {integrity: sha512-fCkYnm4Kdq3un0YIM4BCZHVR5xl0UeLP6syxxO7KAstdY7QVyVvTHP0kRPDYEP1v08uwtJVgis5sj3IOTLOniQ==} engines: {node: '>= 16.0.0'} @@ -1917,10 +1962,6 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - hast-util-from-parse5@8.0.3: resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} @@ -2009,14 +2050,6 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} @@ -2079,10 +2112,6 @@ packages: peerDependencies: ws: '*' - jiti@1.21.7: - resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} - hasBin: true - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -2185,10 +2214,6 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -2231,6 +2256,9 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + map-cache@0.2.2: resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} engines: {node: '>=0.10.0'} @@ -2399,9 +2427,6 @@ packages: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} - mz@2.7.0: - resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2430,18 +2455,6 @@ packages: resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} engines: {node: '>=0.10.0'} - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-hash@3.0.0: - resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} - engines: {node: '>= 6'} - onetime@7.0.0: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} @@ -2499,9 +2512,6 @@ packages: path-case@3.0.4: resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-root-regex@0.1.2: resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} engines: {node: '>=0.10.0'} @@ -2525,61 +2535,10 @@ packages: resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} engines: {node: '>=12'} - pify@2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - - postcss-import@15.1.0: - resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} - engines: {node: '>=14.0.0'} - peerDependencies: - postcss: ^8.0.0 - - postcss-js@4.1.0: - resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} - engines: {node: ^12 || ^14 || >= 16} - peerDependencies: - postcss: ^8.4.21 - - postcss-load-config@6.0.1: - resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} - engines: {node: '>= 18'} - peerDependencies: - jiti: '>=1.21.0' - postcss: '>=8.0.9' - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - jiti: - optional: true - postcss: - optional: true - tsx: - optional: true - yaml: - optional: true - - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 - postcss-selector-parser@6.0.10: resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} engines: {node: '>=4'} - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} - engines: {node: '>=4'} - - postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.8: resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} engines: {node: ^10 || ^12 || >=14} @@ -2645,13 +2604,6 @@ packages: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} - read-cache@1.0.0: - resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - rehype-autolink-headings@7.1.0: resolution: {integrity: sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==} @@ -2704,11 +2656,6 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - resolve@1.22.11: - resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} - engines: {node: '>= 0.4'} - hasBin: true - restore-cursor@5.1.0: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} @@ -2816,19 +2763,10 @@ packages: style-to-object@1.0.14: resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} - sucrase@3.35.1: - resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - swap-case@2.0.2: resolution: {integrity: sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw==} @@ -2839,22 +2777,12 @@ packages: tailwind-merge@3.5.0: resolution: {integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A==} - tailwindcss-animate@1.0.7: - resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} - peerDependencies: - tailwindcss: '>=3.0.0 || insiders' - - tailwindcss@3.4.19: - resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} - engines: {node: '>=14.0.0'} - hasBin: true - - thenify-all@1.6.0: - resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} - engines: {node: '>=0.8'} + tailwindcss@4.2.2: + resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} - thenify@3.3.1: - resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tapable@2.3.2: + resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==} + engines: {node: '>=6'} timeout-signal@2.0.0: resolution: {integrity: sha512-YBGpG4bWsHoPvofT6y/5iqulfXIiIErl5B0LdtHT1mGXDFTAhhRrbUpTvBgYbovr+3cKblya2WAOcpoy90XguA==} @@ -2881,9 +2809,6 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - ts-interface-checker@0.1.13: - resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - ts-log@2.2.7: resolution: {integrity: sha512-320x5Ggei84AxzlXp91QkIGSw5wgaLT6GeAH0KsqDmRZdVWW2OiSeVvElVoatk3f7nicwXlElXsoFkARiGE2yg==} @@ -2893,6 +2818,9 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tw-animate-css@1.4.0: + resolution: {integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==} + typescript@6.0.2: resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} engines: {node: '>=14.17'} @@ -3094,8 +3022,6 @@ packages: snapshots: - '@alloc/quick-lru@5.2.0': {} - '@apollo/client@4.1.6(graphql-ws@6.0.8(graphql@16.13.2)(ws@8.20.0))(graphql@16.13.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(rxjs@7.8.2)': dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@16.13.2) @@ -4303,10 +4229,78 @@ snapshots: '@sindresorhus/is@4.6.0': {} - '@tailwindcss/typography@0.5.19(tailwindcss@3.4.19(yaml@2.8.3))': + '@tailwindcss/node@4.2.2': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.20.1 + jiti: 2.6.1 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.2.2 + + '@tailwindcss/oxide-android-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.2.2': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.2.2': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.2.2': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.2.2': + optional: true + + '@tailwindcss/oxide@4.2.2': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-arm64': 4.2.2 + '@tailwindcss/oxide-darwin-x64': 4.2.2 + '@tailwindcss/oxide-freebsd-x64': 4.2.2 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.2.2 + '@tailwindcss/oxide-linux-arm64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-arm64-musl': 4.2.2 + '@tailwindcss/oxide-linux-x64-gnu': 4.2.2 + '@tailwindcss/oxide-linux-x64-musl': 4.2.2 + '@tailwindcss/oxide-wasm32-wasi': 4.2.2 + '@tailwindcss/oxide-win32-arm64-msvc': 4.2.2 + '@tailwindcss/oxide-win32-x64-msvc': 4.2.2 + + '@tailwindcss/typography@0.5.19(tailwindcss@4.2.2)': dependencies: postcss-selector-parser: 6.0.10 - tailwindcss: 3.4.19(yaml@2.8.3) + tailwindcss: 4.2.2 + + '@tailwindcss/vite@4.2.2(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3))': + dependencies: + '@tailwindcss/node': 4.2.2 + '@tailwindcss/oxide': 4.2.2 + tailwindcss: 4.2.2 + vite: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3) '@tybys/wasm-util@0.10.1': dependencies: @@ -4355,10 +4349,10 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vitejs/plugin-react@6.0.1(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@1.21.7)(yaml@2.8.3))': + '@vitejs/plugin-react@6.0.1(vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3))': dependencies: '@rolldown/pluginutils': 1.0.0-rc.7 - vite: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@1.21.7)(yaml@2.8.3) + vite: 8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3) '@whatwg-node/disposablestack@0.0.6': dependencies: @@ -4411,15 +4405,6 @@ snapshots: ansi-styles@6.2.3: {} - any-promise@1.3.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.2 - - arg@5.0.2: {} - argparse@2.0.1: {} aria-hidden@1.2.6: @@ -4430,23 +4415,12 @@ snapshots: auto-bind@4.0.0: {} - autoprefixer@10.4.27(postcss@8.5.8): - dependencies: - browserslist: 4.28.1 - caniuse-lite: 1.0.30001781 - fraction.js: 5.3.4 - picocolors: 1.1.1 - postcss: 8.5.8 - postcss-value-parser: 4.2.0 - bail@2.0.2: {} balanced-match@4.0.4: {} baseline-browser-mapping@2.10.12: {} - binary-extensions@2.3.0: {} - brace-expansion@5.0.5: dependencies: balanced-match: 4.0.4 @@ -4470,8 +4444,6 @@ snapshots: pascal-case: 3.1.2 tslib: 2.8.1 - camelcase-css@2.0.1: {} - caniuse-lite@1.0.30001781: {} capital-case@1.0.4: @@ -4527,18 +4499,6 @@ snapshots: chardet@2.1.1: {} - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -4572,8 +4532,6 @@ snapshots: comma-separated-tokens@2.0.3: {} - commander@4.1.1: {} - common-tags@1.8.2: {} constant-case@3.0.4: @@ -4642,14 +4600,10 @@ snapshots: dependencies: dequal: 2.0.3 - didyoumean@1.2.2: {} - dir-glob@3.0.1: dependencies: path-type: 4.0.0 - dlv@1.1.3: {} - dot-case@3.0.4: dependencies: no-case: 3.0.4 @@ -4665,6 +4619,11 @@ snapshots: emoticon@4.1.0: {} + enhanced-resolve@5.20.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.2 + entities@6.0.1: {} env-paths@2.2.1: {} @@ -4714,13 +4673,9 @@ snapshots: dependencies: fetch-blob: 3.2.0 - fraction.js@5.3.4: {} - fsevents@2.3.3: optional: true - function-bind@1.1.2: {} - gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -4735,10 +4690,6 @@ snapshots: dependencies: is-glob: 4.0.3 - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - globby@11.1.0: dependencies: array-union: 2.1.0 @@ -4748,6 +4699,8 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + graceful-fs@4.2.11: {} + graphql-config@5.1.6(@types/node@25.5.0)(graphql@16.13.2)(typescript@6.0.2): dependencies: '@graphql-tools/graphql-file-loader': 8.1.12(graphql@16.13.2) @@ -4785,10 +4738,6 @@ snapshots: has-flag@4.0.0: {} - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - hast-util-from-parse5@8.0.3: dependencies: '@types/hast': 3.0.4 @@ -4928,14 +4877,6 @@ snapshots: is-arrayish@0.2.1: {} - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - is-decimal@2.0.1: {} is-extglob@2.1.1: {} @@ -4984,8 +4925,6 @@ snapshots: dependencies: ws: 8.20.0 - jiti@1.21.7: {} - jiti@2.6.1: {} js-tokens@4.0.0: {} @@ -5054,8 +4993,6 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 - lilconfig@3.1.3: {} - lines-and-columns@1.2.4: {} listr2@9.0.5: @@ -5106,6 +5043,10 @@ snapshots: dependencies: react: 19.2.4 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + map-cache@0.2.2: {} markdown-table@3.0.4: {} @@ -5475,12 +5416,6 @@ snapshots: mute-stream@2.0.0: {} - mz@2.7.0: - dependencies: - any-promise: 1.3.0 - object-assign: 4.1.1 - thenify-all: 1.6.0 - nanoid@3.3.11: {} no-case@3.0.4: @@ -5509,12 +5444,6 @@ snapshots: dependencies: remove-trailing-separator: 1.1.0 - normalize-path@3.0.0: {} - - object-assign@4.1.1: {} - - object-hash@3.0.0: {} - onetime@7.0.0: dependencies: mimic-function: 5.0.1 @@ -5632,8 +5561,6 @@ snapshots: dot-case: 3.0.4 tslib: 2.8.1 - path-parse@1.0.7: {} - path-root-regex@0.1.2: {} path-root@0.1.1: @@ -5648,47 +5575,11 @@ snapshots: picomatch@4.0.4: {} - pify@2.3.0: {} - - pirates@4.0.7: {} - - postcss-import@15.1.0(postcss@8.5.8): - dependencies: - postcss: 8.5.8 - postcss-value-parser: 4.2.0 - read-cache: 1.0.0 - resolve: 1.22.11 - - postcss-js@4.1.0(postcss@8.5.8): - dependencies: - camelcase-css: 2.0.1 - postcss: 8.5.8 - - postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8)(yaml@2.8.3): - dependencies: - lilconfig: 3.1.3 - optionalDependencies: - jiti: 1.21.7 - postcss: 8.5.8 - yaml: 2.8.3 - - postcss-nested@6.2.0(postcss@8.5.8): - dependencies: - postcss: 8.5.8 - postcss-selector-parser: 6.1.2 - postcss-selector-parser@6.0.10: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-selector-parser@6.1.2: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - - postcss-value-parser@4.2.0: {} - postcss@8.5.8: dependencies: nanoid: 3.3.11 @@ -5759,14 +5650,6 @@ snapshots: react@19.2.4: {} - read-cache@1.0.0: - dependencies: - pify: 2.3.0 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.2 - rehype-autolink-headings@7.1.0: dependencies: '@types/hast': 3.0.4 @@ -5858,12 +5741,6 @@ snapshots: resolve-from@5.0.0: {} - resolve@1.22.11: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - restore-cursor@5.1.0: dependencies: onetime: 7.0.0 @@ -5992,22 +5869,10 @@ snapshots: dependencies: inline-style-parser: 0.2.7 - sucrase@3.35.1: - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - commander: 4.1.1 - lines-and-columns: 1.2.4 - mz: 2.7.0 - pirates: 4.0.7 - tinyglobby: 0.2.15 - ts-interface-checker: 0.1.13 - supports-color@7.2.0: dependencies: has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - swap-case@2.0.2: dependencies: tslib: 2.8.1 @@ -6020,45 +5885,9 @@ snapshots: tailwind-merge@3.5.0: {} - tailwindcss-animate@1.0.7(tailwindcss@3.4.19(yaml@2.8.3)): - dependencies: - tailwindcss: 3.4.19(yaml@2.8.3) - - tailwindcss@3.4.19(yaml@2.8.3): - dependencies: - '@alloc/quick-lru': 5.2.0 - arg: 5.0.2 - chokidar: 3.6.0 - didyoumean: 1.2.2 - dlv: 1.1.3 - fast-glob: 3.3.3 - glob-parent: 6.0.2 - is-glob: 4.0.3 - jiti: 1.21.7 - lilconfig: 3.1.3 - micromatch: 4.0.8 - normalize-path: 3.0.0 - object-hash: 3.0.0 - picocolors: 1.1.1 - postcss: 8.5.8 - postcss-import: 15.1.0(postcss@8.5.8) - postcss-js: 4.1.0(postcss@8.5.8) - postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8)(yaml@2.8.3) - postcss-nested: 6.2.0(postcss@8.5.8) - postcss-selector-parser: 6.1.2 - resolve: 1.22.11 - sucrase: 3.35.1 - transitivePeerDependencies: - - tsx - - yaml - - thenify-all@1.6.0: - dependencies: - thenify: 3.3.1 + tailwindcss@4.2.2: {} - thenify@3.3.1: - dependencies: - any-promise: 1.3.0 + tapable@2.3.2: {} timeout-signal@2.0.0: {} @@ -6081,14 +5910,14 @@ snapshots: trough@2.2.0: {} - ts-interface-checker@0.1.13: {} - ts-log@2.2.7: {} tslib@2.6.3: {} tslib@2.8.1: {} + tw-animate-css@1.4.0: {} + typescript@6.0.2: {} unc-path-regex@0.1.2: {} @@ -6186,7 +6015,7 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@1.21.7)(yaml@2.8.3): + vite@8.0.3(@emnapi/core@1.9.1)(@emnapi/runtime@1.9.1)(@types/node@25.5.0)(jiti@2.6.1)(yaml@2.8.3): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 @@ -6196,7 +6025,7 @@ snapshots: optionalDependencies: '@types/node': 25.5.0 fsevents: 2.3.3 - jiti: 1.21.7 + jiti: 2.6.1 yaml: 2.8.3 transitivePeerDependencies: - '@emnapi/core' diff --git a/webui2/postcss.config.js b/webui2/postcss.config.js deleted file mode 100644 index 2aa7205d4b402a1bdfbe07110c61df920b370066..0000000000000000000000000000000000000000 --- a/webui2/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/webui2/src/components/bugs/BugRow.tsx b/webui2/src/components/bugs/BugRow.tsx index eaa9582fd1e7c3afcbb5ca89f1e5c1e9e92f1fda..c0ad08dd3ad5e8d656e4823f7db0416efc644ac1 100644 --- a/webui2/src/components/bugs/BugRow.tsx +++ b/webui2/src/components/bugs/BugRow.tsx @@ -40,7 +40,7 @@ export function BugRow({ const authorHref = repo ? `/${repo}/user/${author.humanId}` : `/user/${author.humanId}`; return ( -
+
{title} @@ -66,7 +66,7 @@ export function BugRow({ /> ))}
-

+

#{humanId} opened {formatDistanceToNow(new Date(createdAt), { addSuffix: true })} by{" "} {author.displayName} @@ -75,7 +75,7 @@ export function BugRow({

{commentCount > 0 && ( -
+
{commentCount}
diff --git a/webui2/src/components/bugs/CommentBox.tsx b/webui2/src/components/bugs/CommentBox.tsx index d33ce023286182ba6f24168ee23bd9f6fcb01a51..636cd43083a1d5f87eebd21d93cf03a6eaeaaf25 100644 --- a/webui2/src/components/bugs/CommentBox.tsx +++ b/webui2/src/components/bugs/CommentBox.tsx @@ -80,14 +80,14 @@ export function CommentBox({ bugPrefix, bugStatus, ref_ }: CommentBoxProps) { -
+
{/* Write / Preview tabs */} -
+
- + {/* Search */} -
- +
+ setLabelSearch(e.target.value)} - className="w-full bg-transparent text-sm outline-none placeholder:text-muted-foreground" + className="placeholder:text-muted-foreground w-full bg-transparent text-sm outline-hidden" />
{sortedLabels.length === 0 && ( -

No labels found

+

No labels found

)} {sortedLabels.map((label) => { const active = selectedLabels.includes(label.name); @@ -219,7 +219,7 @@ export function IssueFilters({ ); })}
{selectedLabels.length > 0 && ( -
+
- + {/* Search */} -
- +
+ setAuthorSearch(e.target.value)} - className="w-full bg-transparent text-sm outline-none placeholder:text-muted-foreground" + className="placeholder:text-muted-foreground w-full bg-transparent text-sm outline-hidden" />
{visibleIdentities.length === 0 && ( -

+

No authors found

)} @@ -314,7 +314,7 @@ export function IssueFilters({ active ? null : authorQueryValue(identity), ) } - className="flex w-full items-center gap-2 rounded px-2 py-1.5 text-sm hover:bg-muted" + className="hover:bg-muted flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm" > @@ -325,26 +325,26 @@ export function IssueFilters({
{identity.displayName}
{identity.login && identity.login !== identity.displayName && ( -
+
@{identity.login}
)}
- {active && } + {active && } ); })} {!isSearching && allIdentities.length > INITIAL_AUTHOR_LIMIT && ( -

+

{allIdentities.length - visibleIdentities.length} more — type to search

)}
{selectedAuthorId && ( -
+
- + {SORT_OPTIONS.map((opt) => ( ))} diff --git a/webui2/src/components/bugs/LabelEditor.tsx b/webui2/src/components/bugs/LabelEditor.tsx index cd92551b31702e486e40748ed53372d4b3929a53..b2827c91dc9d61824c0ef8b90f11082fffbc3c6c 100644 --- a/webui2/src/components/bugs/LabelEditor.tsx +++ b/webui2/src/components/bugs/LabelEditor.tsx @@ -46,7 +46,7 @@ export function LabelEditor({ bugPrefix, currentLabels, ref_ }: LabelEditorProps return (
-

+

Labels

{user && validLabels.length > 0 && ( @@ -57,7 +57,7 @@ export function LabelEditor({ bugPrefix, currentLabels, ref_ }: LabelEditorProps -

Apply labels

+

Apply labels

{validLabels.map((label) => { const active = currentNames.has(label.name); @@ -67,7 +67,7 @@ export function LabelEditor({ bugPrefix, currentLabels, ref_ }: LabelEditorProps onClick={() => { void toggleLabel(label.name); }} - className="flex w-full items-center gap-2 rounded px-2 py-1.5 text-sm hover:bg-muted" + className="hover:bg-muted flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-sm" > {currentLabels.length === 0 ? ( -

None yet

+

None yet

) : (
{currentLabels.map((label) => ( diff --git a/webui2/src/components/bugs/QueryInput.tsx b/webui2/src/components/bugs/QueryInput.tsx index 7533e383af3189dcb390cbc9a2f1865a4e15e64f..05b1f67f030dc61e71cab1738200fb215c7f61b7 100644 --- a/webui2/src/components/bugs/QueryInput.tsx +++ b/webui2/src/components/bugs/QueryInput.tsx @@ -299,13 +299,13 @@ export function QueryInput({ value, onChange, onSubmit, placeholder, className } )} onClick={() => inputRef.current?.focus()} > - + {/* Colored backdrop — same font/size/padding as the input. aria-hidden so screen readers only see the real input, not the duplicate text. */}
{value === "" ? null : segments.map((seg, i) => renderSegment(seg, i))}
@@ -320,7 +320,7 @@ export function QueryInput({ value, onChange, onSubmit, placeholder, className } onChange={handleChange} onKeyDown={handleKeyDown} onSelect={handleSelect} - className="relative w-full bg-transparent py-2 pl-9 pr-3 font-mono text-sm text-transparent caret-foreground outline-none placeholder:font-sans placeholder:text-muted-foreground" + className="caret-foreground placeholder:text-muted-foreground relative w-full bg-transparent py-2 pr-3 pl-9 font-mono text-sm text-transparent outline-hidden placeholder:font-sans" spellCheck={false} autoComplete="off" /> @@ -329,7 +329,7 @@ export function QueryInput({ value, onChange, onSubmit, placeholder, className } Uses onMouseDown+preventDefault so clicking a suggestion doesn't blur the input before the click registers (classic focus-race problem). */} {showDropdown && ( -
+
{suggestions.map((s, i) => ( ))} diff --git a/webui2/src/components/bugs/Timeline.tsx b/webui2/src/components/bugs/Timeline.tsx index 769930093c927d28528017899e6c800b612bcb06..722fe82ebcfc42c7f4c4b60ca3b824a09e37c25a 100644 --- a/webui2/src/components/bugs/Timeline.tsx +++ b/webui2/src/components/bugs/Timeline.tsx @@ -95,22 +95,22 @@ function CommentItem({ item, bugPrefix }: { item: CommentItem; bugPrefix: string -
-
+
+
{item.author.displayName} {formatDistanceToNow(new Date(item.createdAt), { addSuffix: true })} - {item.edited && !editing && edited} + {item.edited && !editing && edited} {canEdit && !editing && ( @@ -147,7 +147,7 @@ function CommentItem({ item, bugPrefix }: { item: CommentItem; bugPrefix: string {item.message ? ( ) : ( -

No description provided.

+

No description provided.

)}
)} @@ -164,7 +164,7 @@ type TitleChangeItem = Extract +
{icon} {children}
@@ -178,7 +178,7 @@ function LabelChangeItem({ item }: { item: LabelChangeItem }) { {item.author.displayName} {" "} @@ -220,7 +220,7 @@ function StatusChangeItem({ item }: { item: StatusChangeItem }) { {item.author.displayName} {" "} @@ -238,12 +238,12 @@ function TitleChangeItem({ item }: { item: TitleChangeItem }) { {item.author.displayName} {" "} changed the title from {item.was} to{" "} - {item.title}{" "} + {item.title}{" "} {formatDistanceToNow(new Date(item.date), { addSuffix: true })} diff --git a/webui2/src/components/bugs/TitleEditor.tsx b/webui2/src/components/bugs/TitleEditor.tsx index 94b32c67ae5b01119b77c69d38d033dc3dc86a4a..752fdc68cc408289b0ebd3f050dba3578aac3c5d 100644 --- a/webui2/src/components/bugs/TitleEditor.tsx +++ b/webui2/src/components/bugs/TitleEditor.tsx @@ -87,14 +87,14 @@ export function TitleEditor({ bugPrefix, title, humanId, ref_ }: TitleEditorProp return (
-

+

{title} - #{humanId} + #{humanId}

{user && ( @@ -27,9 +27,9 @@ export function CodeBreadcrumb({ repoName, ref, path, onNavigate }: CodeBreadcru const isLast = i === parts.length - 1; return ( - + {isLast ? ( - {part} + {part} ) : (
); } diff --git a/webui2/src/components/code/CommitList.tsx b/webui2/src/components/code/CommitList.tsx index 7efd09f650602e1c4247a2b45e8dff47a134cb7e..7a956ce1cd539affa21b0cb533adcd96d6a86736 100644 --- a/webui2/src/components/code/CommitList.tsx +++ b/webui2/src/components/code/CommitList.tsx @@ -5,7 +5,7 @@ import { gql } from "@apollo/client"; import { useQuery } from "@apollo/client/react"; import { formatDistanceToNow } from "date-fns"; import { GitCommit } from "lucide-react"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Link } from "react-router"; import { Button } from "@/components/ui/button"; @@ -34,6 +34,15 @@ const COMMITS_QUERY = gql` const PAGE_SIZE = 30; +interface CommitListQueryData { + repository: { + commits: { + nodes: CommitNode[]; + pageInfo: { hasNextPage: boolean; endCursor: string | null }; + } | null; + } | null; +} + interface CommitListProps { ref_: string; path?: string; @@ -52,16 +61,17 @@ export function CommitList({ ref_, path }: CommitListProps) { const [cursor, setCursor] = useState(null); const [allCommits, setAllCommits] = useState([]); - const { loading, error, fetchMore } = useQuery(COMMITS_QUERY, { + const { data, loading, error, fetchMore } = useQuery(COMMITS_QUERY, { variables: { repo, ref: ref_, path: path ?? null, after: null, first: PAGE_SIZE }, skip: !ref_, - onCompleted(data) { - const nodes = data?.repository?.commits?.nodes ?? []; - setAllCommits(nodes); - setCursor(data?.repository?.commits?.pageInfo?.endCursor ?? null); - }, }); + useEffect(() => { + const nodes = data?.repository?.commits?.nodes ?? []; + setAllCommits(nodes); + setCursor(data?.repository?.commits?.pageInfo?.endCursor ?? null); + }, [data]); + const hasMore = !!cursor && allCommits.length > 0 && allCommits.length % PAGE_SIZE === 0; const [loadingMore, setLoadingMore] = useState(false); @@ -83,7 +93,7 @@ export function CommitList({ ref_, path }: CommitListProps) { if (error) { return ( -
+
{error.message}
); @@ -95,10 +105,10 @@ export function CommitList({ ref_, path }: CommitListProps) {
{groups.map(([date, group]) => (
-

+

Commits on {date}

-
+
{group.map((commit) => ( ))} @@ -120,23 +130,23 @@ export function CommitList({ ref_, path }: CommitListProps) { function CommitRow({ commit, repo }: { commit: CommitNode; repo: string | null }) { const commitPath = repo ? `/${repo}/commit/${commit.hash}` : `/commit/${commit.hash}`; return ( -
- +
+
{commit.message} -

+

{commit.authorName} ·{" "} {formatDistanceToNow(new Date(commit.date), { addSuffix: true })}

{commit.shortHash} @@ -166,10 +176,10 @@ function CommitListSkeleton() { {Array.from({ length: 2 }).map((_, g) => (
-
+
{Array.from({ length: 4 }).map((_, i) => (
- +
diff --git a/webui2/src/components/code/FileDiffView.tsx b/webui2/src/components/code/FileDiffView.tsx index 73a99fea09f145d5c471713a8c98ae6ca9a6ddfa..b1f88e2f1957af5df85a9721756e45309a532834 100644 --- a/webui2/src/components/code/FileDiffView.tsx +++ b/webui2/src/components/code/FileDiffView.tsx @@ -37,6 +37,21 @@ const DIFF_QUERY = gql` } `; +interface DiffQueryData { + repository: { + commit: { + diff: { + path: string; + oldPath: string | null; + isBinary: boolean; + isNew: boolean; + isDelete: boolean; + hunks: HunkType[]; + } | null; + } | null; + } | null; +} + interface FileDiffViewProps { hash: string; path: string; @@ -60,7 +75,7 @@ const statusBadge: Record = { export function FileDiffView({ hash, path, oldPath, status }: FileDiffViewProps) { const repo = useRepo(); const [open, setOpen] = useState(false); - const [fetchDiff, { data, loading, error }] = useLazyQuery(DIFF_QUERY); + const [fetchDiff, { data, loading, error }] = useLazyQuery(DIFF_QUERY); function toggle() { if (!open && !data && !loading) { @@ -72,10 +87,10 @@ export function FileDiffView({ hash, path, oldPath, status }: FileDiffViewProps) const diff = data?.repository?.commit?.diff; return ( -
+
{open && (
- {loading &&
Loading diff…
} + {loading &&
Loading diff…
} {error && ( -
+
Failed to load diff: {error.message}
)} {diff && (diff.isBinary ? ( -
Binary file
+
Binary file
) : diff.hunks.length === 0 ? ( -
No changes
+
No changes
) : ( diff.hunks.map((hunk: HunkType, i: number) => ) ))} @@ -134,7 +149,7 @@ type HunkType = { function Hunk({ hunk }: { hunk: HunkType }) { return (
-
+
@@ -{hunk.oldStart},{hunk.oldLines} +{hunk.newStart},{hunk.newLines} @@
{hunk.lines.map((line, i) => ( @@ -146,10 +161,10 @@ function Hunk({ hunk }: { hunk: HunkType }) { line.type === "DELETED" && "bg-red-50 dark:bg-red-950/30", )} > - + {line.oldLine || ""} - + {line.newLine || ""} ; return ( -
+
- + {path && ( - + - - + )} {sorted.map((entry) => ( @@ -68,20 +68,20 @@ function FileTreeRow({ const repo = useRepo(); return ( - onNavigate(entry)}> + onNavigate(entry)}> - - @@ -104,11 +104,11 @@ function FileTreeRow({ function FileTreeSkeleton() { return ( -
-
+
+
{Array.from({ length: 8 }).map((_, i) => (
- + diff --git a/webui2/src/components/code/FileViewer.tsx b/webui2/src/components/code/FileViewer.tsx index feb48d8b204a28b4d820ad89408fdeeda2fdec6b..842a966a9b4c97b05472d1b306eb5df2ab07cb98 100644 --- a/webui2/src/components/code/FileViewer.tsx +++ b/webui2/src/components/code/FileViewer.tsx @@ -47,8 +47,8 @@ export function FileViewer({ blob, loading }: FileViewerProps) { } return ( -
-
+
+
{lineCount.toLocaleString()} lines · {formatBytes(blob.size)} {blob.isTruncated && " · truncated"} @@ -65,13 +65,13 @@ export function FileViewer({ blob, loading }: FileViewerProps) {
{blob.isBinary ? ( -
+
Binary file — {formatBytes(blob.size)}
) : (
{Array.from({ length: lineCount }, (_, i) => ( @@ -95,8 +95,8 @@ function formatBytes(bytes: number): string { function FileViewerSkeleton() { return ( -
-
+
+
diff --git a/webui2/src/components/code/RefSelector.tsx b/webui2/src/components/code/RefSelector.tsx index 90d38e3d454bf93eb5e81f8cbce2d315defa9f41..2db3bc0e376ca29dfed587cff9376ae443a7b5f3 100644 --- a/webui2/src/components/code/RefSelector.tsx +++ b/webui2/src/components/code/RefSelector.tsx @@ -29,11 +29,11 @@ export function RefSelector({ refs, currentRef, onSelect }: RefSelectorProps) { -

Switch branch / tag

+

Switch branch / tag

{branches.length > 0 && (
-

Branches

+

Branches

{branches.map((ref) => ( 0 && (
-

Tags

+

Tags

{tags.map((ref) => ( )} {filtered.length === 0 && ( -

No results

+

No results

)}
@@ -98,17 +98,17 @@ function RefItem({ ); } diff --git a/webui2/src/components/content/Markdown.tsx b/webui2/src/components/content/Markdown.tsx index 1e62bfd9c5a36e6312aa81f2099d11143c4a436f..a5244323339ed20f73b45b1275d60b55c0804981 100644 --- a/webui2/src/components/content/Markdown.tsx +++ b/webui2/src/components/content/Markdown.tsx @@ -34,24 +34,27 @@ interface MarkdownProps { // lists, strikethrough). Used in Timeline comments and NewBugPage preview. export function Markdown({ content, className }: MarkdownProps) { return ( - - {content} - + + {content} + +
); } diff --git a/webui2/src/components/layout/Header.tsx b/webui2/src/components/layout/Header.tsx index eed8fbdd447d4ba98a8091d187f02dee6045ebe4..154b65822fbc9522ea30c724a0c09d0602911247 100644 --- a/webui2/src/components/layout/Header.tsx +++ b/webui2/src/components/layout/Header.tsx @@ -44,10 +44,10 @@ export function Header() { const effectiveRepo = repo === "auth" ? null : repo; return ( -
+
{/* Logo always goes to the repo picker root */} - + git-bug @@ -86,7 +86,7 @@ export function Header() { )}
- {mode === "readonly" && Read only} + {mode === "readonly" && Read only} @@ -180,7 +180,7 @@ export function BugListPage() { )} /> Closed - + {closedCount} @@ -214,7 +214,7 @@ export function BugListPage() { {/* Bug rows */} {error && ( -

+

Failed to load issues: {error.message}

)} @@ -222,7 +222,7 @@ export function BugListPage() { {loading && !data && } {bugs?.nodes.length === 0 && ( -

+

No {statusFilter} issues found.

)} @@ -254,18 +254,18 @@ export function BugListPage() { ))} {totalPages > 1 && ( -
+
- + Page {page + 1} of {totalPages} -
+
- -

{commit.message}

+ +

{commit.message}

{commit.fullMessage.includes("\n") && ( -
+          
             {commit.fullMessage.split("\n").slice(1).join("\n").trim()}
           
)} -
+
- {commit.authorName} + {commit.authorName} {commit.authorEmail && <{commit.authorEmail}>} {format(date, "PPP")}
-
+
- commit {commit.hash} + commit {commit.hash} {commit.parents.map((p: string) => ( parent{" "} {p.slice(0, 7)} @@ -110,12 +130,12 @@ export function CommitPage() {
-

+

{files.length} file{files.length !== 1 ? "s" : ""} changed

-
+
{files.length === 0 && ( -

No file changes.

+

No file changes.

)} {files.map((file: { path: string; oldPath?: string | null; status: string }) => ( -
+
-
+
{Array.from({ length: 5 }).map((_, i) => (
diff --git a/webui2/src/pages/ErrorPage.tsx b/webui2/src/pages/ErrorPage.tsx index f4342cf16c4e2cfb57b7d62fa37029edabf0bdbc..724dcc01213e2d20b099ea182e2a1c8040aeb71a 100644 --- a/webui2/src/pages/ErrorPage.tsx +++ b/webui2/src/pages/ErrorPage.tsx @@ -24,9 +24,9 @@ export function ErrorPage() { return (
- + {status &&

{status}

} -

{message}

+

{message}

diff --git a/webui2/src/pages/IdentitySelectPage.tsx b/webui2/src/pages/IdentitySelectPage.tsx index f101e563034852d7b18acaafaabaff85de903b95..f013a1caf87a0dc37ea0a971234386be9c891065 100644 --- a/webui2/src/pages/IdentitySelectPage.tsx +++ b/webui2/src/pages/IdentitySelectPage.tsx @@ -27,13 +27,17 @@ export function IdentitySelectPage() { const [working, setWorking] = useState(false); useEffect(() => { - void fetch("/auth/identities", { credentials: "include" }) - .then((res) => { + async function loadIdentities() { + try { + const res = await fetch("/auth/identities", { credentials: "include" }); if (!res.ok) throw new Error(`unexpected status ${res.status}`); - return res.json() as Promise; - }) - .then(setIdentities) - .catch((e) => setError(String(e))); + const data: IdentityItem[] = await res.json(); + setIdentities(data); + } catch (e) { + setError(String(e)); + } + } + void loadIdentities(); }, []); async function adopt(identityId: string | null) { @@ -57,16 +61,16 @@ export function IdentitySelectPage() { return (
- +

Choose your identity

-

+

No git-bug identity was found linked to your account. Select an existing identity to link it, or create a new one from your profile.

{error && ( -
+
{error}
@@ -80,12 +84,12 @@ export function IdentitySelectPage() {
)} -
+
{identities?.map((id) => (

{id.displayName}

-

+

{id.login ? `@${id.login} · ` : ""} {id.repoSlug} · {id.humanId}

@@ -106,7 +110,7 @@ export function IdentitySelectPage() {

Create new identity

-

+

A fresh git-bug identity will be created from your OAuth profile.

diff --git a/webui2/src/pages/NewBugPage.tsx b/webui2/src/pages/NewBugPage.tsx index f858cfa6c611b65a6bcdf403ca92f81a68ecc251..4ffbd3db1c842d1601861a3c6b91912ac012b662 100644 --- a/webui2/src/pages/NewBugPage.tsx +++ b/webui2/src/pages/NewBugPage.tsx @@ -27,7 +27,7 @@ export function NewBugPage() { }); const humanId = result.data?.bugCreate.bug.humanId; if (humanId) { - navigate(repo ? `/${repo}/issues/${humanId}` : `/issues/${humanId}`); + void navigate(repo ? `/${repo}/issues/${humanId}` : `/issues/${humanId}`); } } @@ -37,7 +37,7 @@ export function NewBugPage() {
Back to issues @@ -72,7 +72,7 @@ export function NewBugPage() {
{preview ? ( -
+
) : ( @@ -107,14 +107,16 @@ export function NewBugPage() {
{error && ( -

Failed to create issue: {error.message}

+

Failed to create issue: {error.message}

)}
@@ -183,14 +183,14 @@ export function UserProfilePage() { )} /> Closed - + {closedCount}
{bugs?.nodes.length === 0 && ( -

+

No {statusFilter} issues.

)} @@ -201,7 +201,7 @@ export function UserProfilePage() { return (
{bug.title} @@ -223,13 +223,13 @@ export function UserProfilePage() { ))}
-

+

#{bug.humanId} opened{" "} {formatDistanceToNow(new Date(bug.createdAt), { addSuffix: true })}

{bug.comments.totalCount > 0 && ( -
+
{bug.comments.totalCount}
@@ -240,18 +240,18 @@ export function UserProfilePage() { {/* Pagination footer — only shown when there is more than one page */} {totalPages > 1 && ( -
+
- + Page {page + 1} of {totalPages}
.. - + .. +
{isDir ? ( ) : ( - + )} - + {entry.name} + {entry.lastCommit && ( )} + {entry.lastCommit && formatDistanceToNow(new Date(entry.lastCommit.date), { addSuffix: true })}