trident-git 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -0
- package/.next/app-path-routes-manifest.json +23 -0
- package/.next/build-manifest.json +20 -0
- package/.next/export-marker.json +6 -0
- package/.next/images-manifest.json +73 -0
- package/.next/next-minimal-server.js.nft.json +1 -0
- package/.next/next-server.js.nft.json +1 -0
- package/.next/package.json +1 -0
- package/.next/prerender-manifest.json +282 -0
- package/.next/react-loadable-manifest.json +1 -0
- package/.next/required-server-files.js +330 -0
- package/.next/required-server-files.json +330 -0
- package/.next/routes-manifest.json +170 -0
- package/.next/server/app/_global-error/page.js +3 -0
- package/.next/server/app/_global-error/page.js.nft.json +1 -0
- package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_global-error.html +2 -0
- package/.next/server/app/_global-error.meta +16 -0
- package/.next/server/app/_global-error.rsc +12 -0
- package/.next/server/app/_global-error.segments/_full.segment.rsc +12 -0
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +4 -0
- package/.next/server/app/_global-error.segments/_head.segment.rsc +5 -0
- package/.next/server/app/_global-error.segments/_index.segment.rsc +4 -0
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -0
- package/.next/server/app/_not-found/page.js +2 -0
- package/.next/server/app/_not-found/page.js.nft.json +1 -0
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -0
- package/.next/server/app/_not-found.html +1 -0
- package/.next/server/app/_not-found.meta +16 -0
- package/.next/server/app/_not-found.rsc +19 -0
- package/.next/server/app/_not-found.segments/_full.segment.rsc +19 -0
- package/.next/server/app/_not-found.segments/_head.segment.rsc +6 -0
- package/.next/server/app/_not-found.segments/_index.segment.rsc +8 -0
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +5 -0
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +4 -0
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +6 -0
- package/.next/server/app/api/credentials/route.js +1 -0
- package/.next/server/app/api/credentials/route.js.nft.json +1 -0
- package/.next/server/app/api/credentials/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/custom-scripts/route.js +3 -0
- package/.next/server/app/api/custom-scripts/route.js.nft.json +1 -0
- package/.next/server/app/api/custom-scripts/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/fs/route.js +1 -0
- package/.next/server/app/api/fs/route.js.nft.json +1 -0
- package/.next/server/app/api/fs/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/git/action/route.js +1 -0
- package/.next/server/app/api/git/action/route.js.nft.json +1 -0
- package/.next/server/app/api/git/action/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/git/branches/route.js +1 -0
- package/.next/server/app/api/git/branches/route.js.nft.json +1 -0
- package/.next/server/app/api/git/branches/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/git/diff/route.js +1 -0
- package/.next/server/app/api/git/diff/route.js.nft.json +1 -0
- package/.next/server/app/api/git/diff/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/git/log/route.js +1 -0
- package/.next/server/app/api/git/log/route.js.nft.json +1 -0
- package/.next/server/app/api/git/log/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/git/status/route.js +1 -0
- package/.next/server/app/api/git/status/route.js.nft.json +1 -0
- package/.next/server/app/api/git/status/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/repos/route.js +1 -0
- package/.next/server/app/api/repos/route.js.nft.json +1 -0
- package/.next/server/app/api/repos/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/settings/route.js +1 -0
- package/.next/server/app/api/settings/route.js.nft.json +1 -0
- package/.next/server/app/api/settings/route_client-reference-manifest.js +1 -0
- package/.next/server/app/credentials/page.js +4 -0
- package/.next/server/app/credentials/page.js.nft.json +1 -0
- package/.next/server/app/credentials/page_client-reference-manifest.js +1 -0
- package/.next/server/app/credentials.html +1 -0
- package/.next/server/app/credentials.meta +15 -0
- package/.next/server/app/credentials.rsc +23 -0
- package/.next/server/app/credentials.segments/_full.segment.rsc +23 -0
- package/.next/server/app/credentials.segments/_head.segment.rsc +6 -0
- package/.next/server/app/credentials.segments/_index.segment.rsc +8 -0
- package/.next/server/app/credentials.segments/_tree.segment.rsc +6 -0
- package/.next/server/app/credentials.segments/credentials/__PAGE__.segment.rsc +9 -0
- package/.next/server/app/credentials.segments/credentials.segment.rsc +4 -0
- package/.next/server/app/icon.png/route.js +1 -0
- package/.next/server/app/icon.png/route.js.nft.json +1 -0
- package/.next/server/app/icon.png.meta +1 -0
- package/.next/server/app/index.html +1 -0
- package/.next/server/app/index.meta +14 -0
- package/.next/server/app/index.rsc +20 -0
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +6 -0
- package/.next/server/app/index.segments/_full.segment.rsc +20 -0
- package/.next/server/app/index.segments/_head.segment.rsc +6 -0
- package/.next/server/app/index.segments/_index.segment.rsc +8 -0
- package/.next/server/app/index.segments/_tree.segment.rsc +6 -0
- package/.next/server/app/page.js +2 -0
- package/.next/server/app/page.js.nft.json +1 -0
- package/.next/server/app/page_client-reference-manifest.js +1 -0
- package/.next/server/app/workspace/changes/page.js +4 -0
- package/.next/server/app/workspace/changes/page.js.nft.json +1 -0
- package/.next/server/app/workspace/changes/page_client-reference-manifest.js +1 -0
- package/.next/server/app/workspace/changes.html +1 -0
- package/.next/server/app/workspace/changes.meta +16 -0
- package/.next/server/app/workspace/changes.rsc +26 -0
- package/.next/server/app/workspace/changes.segments/_full.segment.rsc +26 -0
- package/.next/server/app/workspace/changes.segments/_head.segment.rsc +6 -0
- package/.next/server/app/workspace/changes.segments/_index.segment.rsc +8 -0
- package/.next/server/app/workspace/changes.segments/_tree.segment.rsc +7 -0
- package/.next/server/app/workspace/changes.segments/workspace/changes/__PAGE__.segment.rsc +10 -0
- package/.next/server/app/workspace/changes.segments/workspace/changes.segment.rsc +4 -0
- package/.next/server/app/workspace/changes.segments/workspace.segment.rsc +7 -0
- package/.next/server/app/workspace/custom-scripts/page.js +2 -0
- package/.next/server/app/workspace/custom-scripts/page.js.nft.json +1 -0
- package/.next/server/app/workspace/custom-scripts/page_client-reference-manifest.js +1 -0
- package/.next/server/app/workspace/custom-scripts.html +1 -0
- package/.next/server/app/workspace/custom-scripts.meta +16 -0
- package/.next/server/app/workspace/custom-scripts.rsc +25 -0
- package/.next/server/app/workspace/custom-scripts.segments/_full.segment.rsc +25 -0
- package/.next/server/app/workspace/custom-scripts.segments/_head.segment.rsc +6 -0
- package/.next/server/app/workspace/custom-scripts.segments/_index.segment.rsc +8 -0
- package/.next/server/app/workspace/custom-scripts.segments/_tree.segment.rsc +6 -0
- package/.next/server/app/workspace/custom-scripts.segments/workspace/custom-scripts/__PAGE__.segment.rsc +9 -0
- package/.next/server/app/workspace/custom-scripts.segments/workspace/custom-scripts.segment.rsc +4 -0
- package/.next/server/app/workspace/custom-scripts.segments/workspace.segment.rsc +7 -0
- package/.next/server/app/workspace/history/page.js +2 -0
- package/.next/server/app/workspace/history/page.js.nft.json +1 -0
- package/.next/server/app/workspace/history/page_client-reference-manifest.js +1 -0
- package/.next/server/app/workspace/history.html +1 -0
- package/.next/server/app/workspace/history.meta +16 -0
- package/.next/server/app/workspace/history.rsc +26 -0
- package/.next/server/app/workspace/history.segments/_full.segment.rsc +26 -0
- package/.next/server/app/workspace/history.segments/_head.segment.rsc +6 -0
- package/.next/server/app/workspace/history.segments/_index.segment.rsc +8 -0
- package/.next/server/app/workspace/history.segments/_tree.segment.rsc +7 -0
- package/.next/server/app/workspace/history.segments/workspace/history/__PAGE__.segment.rsc +10 -0
- package/.next/server/app/workspace/history.segments/workspace/history.segment.rsc +4 -0
- package/.next/server/app/workspace/history.segments/workspace.segment.rsc +7 -0
- package/.next/server/app/workspace/page.js +2 -0
- package/.next/server/app/workspace/page.js.nft.json +1 -0
- package/.next/server/app/workspace/page_client-reference-manifest.js +1 -0
- package/.next/server/app/workspace/settings/page.js +2 -0
- package/.next/server/app/workspace/settings/page.js.nft.json +1 -0
- package/.next/server/app/workspace/settings/page_client-reference-manifest.js +1 -0
- package/.next/server/app/workspace/settings.html +1 -0
- package/.next/server/app/workspace/settings.meta +16 -0
- package/.next/server/app/workspace/settings.rsc +25 -0
- package/.next/server/app/workspace/settings.segments/_full.segment.rsc +25 -0
- package/.next/server/app/workspace/settings.segments/_head.segment.rsc +6 -0
- package/.next/server/app/workspace/settings.segments/_index.segment.rsc +8 -0
- package/.next/server/app/workspace/settings.segments/_tree.segment.rsc +6 -0
- package/.next/server/app/workspace/settings.segments/workspace/settings/__PAGE__.segment.rsc +9 -0
- package/.next/server/app/workspace/settings.segments/workspace/settings.segment.rsc +4 -0
- package/.next/server/app/workspace/settings.segments/workspace.segment.rsc +7 -0
- package/.next/server/app/workspace/stashes/page.js +2 -0
- package/.next/server/app/workspace/stashes/page.js.nft.json +1 -0
- package/.next/server/app/workspace/stashes/page_client-reference-manifest.js +1 -0
- package/.next/server/app/workspace/stashes.html +1 -0
- package/.next/server/app/workspace/stashes.meta +16 -0
- package/.next/server/app/workspace/stashes.rsc +26 -0
- package/.next/server/app/workspace/stashes.segments/_full.segment.rsc +26 -0
- package/.next/server/app/workspace/stashes.segments/_head.segment.rsc +6 -0
- package/.next/server/app/workspace/stashes.segments/_index.segment.rsc +8 -0
- package/.next/server/app/workspace/stashes.segments/_tree.segment.rsc +7 -0
- package/.next/server/app/workspace/stashes.segments/workspace/stashes/__PAGE__.segment.rsc +10 -0
- package/.next/server/app/workspace/stashes.segments/workspace/stashes.segment.rsc +4 -0
- package/.next/server/app/workspace/stashes.segments/workspace.segment.rsc +7 -0
- package/.next/server/app/workspace.html +1 -0
- package/.next/server/app/workspace.meta +15 -0
- package/.next/server/app/workspace.rsc +26 -0
- package/.next/server/app/workspace.segments/_full.segment.rsc +26 -0
- package/.next/server/app/workspace.segments/_head.segment.rsc +6 -0
- package/.next/server/app/workspace.segments/_index.segment.rsc +8 -0
- package/.next/server/app/workspace.segments/_tree.segment.rsc +7 -0
- package/.next/server/app/workspace.segments/workspace/__PAGE__.segment.rsc +10 -0
- package/.next/server/app/workspace.segments/workspace.segment.rsc +7 -0
- package/.next/server/app-paths-manifest.json +23 -0
- package/.next/server/chunks/116.js +1 -0
- package/.next/server/chunks/170.js +1 -0
- package/.next/server/chunks/309.js +6 -0
- package/.next/server/chunks/356.js +1 -0
- package/.next/server/chunks/392.js +1 -0
- package/.next/server/chunks/443.js +37 -0
- package/.next/server/chunks/445.js +22 -0
- package/.next/server/chunks/471.js +13 -0
- package/.next/server/chunks/557.js +5 -0
- package/.next/server/chunks/680.js +1 -0
- package/.next/server/chunks/739.js +5 -0
- package/.next/server/chunks/781.js +1 -0
- package/.next/server/chunks/813.js +1 -0
- package/.next/server/chunks/816.js +13 -0
- package/.next/server/functions-config-manifest.json +6 -0
- package/.next/server/interception-route-rewrite-manifest.js +1 -0
- package/.next/server/middleware-build-manifest.js +1 -0
- package/.next/server/middleware-manifest.json +6 -0
- package/.next/server/middleware-react-loadable-manifest.js +1 -0
- package/.next/server/next-font-manifest.js +1 -0
- package/.next/server/next-font-manifest.json +1 -0
- package/.next/server/pages/404.html +1 -0
- package/.next/server/pages/500.html +2 -0
- package/.next/server/pages-manifest.json +4 -0
- package/.next/server/server-reference-manifest.js +1 -0
- package/.next/server/server-reference-manifest.json +1 -0
- package/.next/server/webpack-runtime.js +1 -0
- package/.next/static/VTWJwhFJd5VcC6GP5bbli/_buildManifest.js +1 -0
- package/.next/static/VTWJwhFJd5VcC6GP5bbli/_ssgManifest.js +1 -0
- package/.next/static/chunks/131-6237c77d708182b1.js +1 -0
- package/.next/static/chunks/147-d4cb3e03218d75df.js +6 -0
- package/.next/static/chunks/176-b068120641913226.js +1 -0
- package/.next/static/chunks/200-3664e65687e716a2.js +1 -0
- package/.next/static/chunks/26-d93e82c9c09ff972.js +1 -0
- package/.next/static/chunks/4bd1b696-096d35a2bd1da3af.js +1 -0
- package/.next/static/chunks/500-5d45efbf86b8d36e.js +1 -0
- package/.next/static/chunks/772-b39107b40c31b6b6.js +3 -0
- package/.next/static/chunks/785-e6d755147ff87934.js +1 -0
- package/.next/static/chunks/790-3e8fa6e595d97940.js +6 -0
- package/.next/static/chunks/794-37dad9bbc14b04b8.js +2 -0
- package/.next/static/chunks/841-4d865378216d36eb.js +13 -0
- package/.next/static/chunks/app/_global-error/page-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/_not-found/page-5bea07380837254f.js +1 -0
- package/.next/static/chunks/app/api/credentials/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/api/custom-scripts/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/api/fs/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/api/git/action/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/api/git/branches/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/api/git/diff/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/api/git/log/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/api/git/status/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/api/repos/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/api/settings/route-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/app/credentials/page-23c1807ad9f68a40.js +1 -0
- package/.next/static/chunks/app/layout-a06241c385e50ae0.js +1 -0
- package/.next/static/chunks/app/page-c8404790f5191fd7.js +1 -0
- package/.next/static/chunks/app/workspace/changes/page-8cca17f80e66f534.js +3 -0
- package/.next/static/chunks/app/workspace/custom-scripts/page-ee24b9dd7779244f.js +1 -0
- package/.next/static/chunks/app/workspace/history/page-b7017fea285c804c.js +1 -0
- package/.next/static/chunks/app/workspace/layout-cb86c00fdcd8db08.js +1 -0
- package/.next/static/chunks/app/workspace/page-21211acc90c08509.js +1 -0
- package/.next/static/chunks/app/workspace/settings/page-7ccb58ece31492e9.js +1 -0
- package/.next/static/chunks/app/workspace/stashes/page-0e1b8304c4b0f4f3.js +1 -0
- package/.next/static/chunks/framework-75892d61b920805f.js +1 -0
- package/.next/static/chunks/main-app-221e1b945693a142.js +1 -0
- package/.next/static/chunks/main-f1d55fffd3cc9809.js +5 -0
- package/.next/static/chunks/next/dist/client/components/builtin/app-error-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/forbidden-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/global-error-f2a2c324f3740ed8.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/not-found-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-9eb8a19109bbd711.js +1 -0
- package/.next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/.next/static/chunks/webpack-7dec27dc3bfe207a.js +1 -0
- package/.next/static/css/36968b90b2339533.css +1 -0
- package/.next/static/css/c56c0e57397a3a60.css +1 -0
- package/.next/static/css/de70bee13400563f.css +1 -0
- package/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
- package/.next/static/media/747892c23ea88013-s.woff2 +0 -0
- package/.next/static/media/8d697b304b401681-s.woff2 +0 -0
- package/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
- package/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
- package/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
- package/README.md +2 -0
- package/bin/trident-git.mjs +9 -11
- package/{next.config.ts → next.config.mjs} +7 -8
- package/package.json +8 -6
- package/eslint.config.mjs +0 -18
- package/postcss.config.mjs +0 -7
- package/src/app/api/credentials/route.ts +0 -113
- package/src/app/api/custom-scripts/route.ts +0 -203
- package/src/app/api/fs/route.ts +0 -75
- package/src/app/api/git/action/route.ts +0 -383
- package/src/app/api/git/branches/route.ts +0 -20
- package/src/app/api/git/diff/route.ts +0 -104
- package/src/app/api/git/log/route.ts +0 -28
- package/src/app/api/git/status/route.ts +0 -28
- package/src/app/api/repos/route.ts +0 -84
- package/src/app/api/settings/route.ts +0 -37
- package/src/app/credentials/page.tsx +0 -408
- package/src/app/globals.css +0 -109
- package/src/app/layout.tsx +0 -38
- package/src/app/page.tsx +0 -10
- package/src/app/providers.tsx +0 -21
- package/src/app/workspace/changes/page.tsx +0 -27
- package/src/app/workspace/custom-scripts/page.tsx +0 -247
- package/src/app/workspace/history/page.tsx +0 -27
- package/src/app/workspace/layout.tsx +0 -26
- package/src/app/workspace/page.tsx +0 -27
- package/src/app/workspace/settings/page.tsx +0 -233
- package/src/app/workspace/stashes/page.tsx +0 -395
- package/src/components/command-palette.tsx +0 -178
- package/src/components/context-menu.tsx +0 -200
- package/src/components/fs-browser.tsx +0 -154
- package/src/components/git/diff-view.tsx +0 -137
- package/src/components/git/git-graph.tsx +0 -489
- package/src/components/git/grouped-diff-viewer.tsx +0 -332
- package/src/components/git/history-view.tsx +0 -4862
- package/src/components/git/image-diff-view.tsx +0 -342
- package/src/components/git/status-view.tsx +0 -597
- package/src/components/home-settings-modal.tsx +0 -192
- package/src/components/layout/sidebar.tsx +0 -256
- package/src/components/repo-list.tsx +0 -206
- package/src/components/theme-toggle.tsx +0 -37
- package/src/components/toaster.tsx +0 -36
- package/src/components/workspace-repo-open-tracker.tsx +0 -39
- package/src/hooks/use-credentials.ts +0 -123
- package/src/hooks/use-escape-dismiss.ts +0 -72
- package/src/hooks/use-git.ts +0 -448
- package/src/hooks/use-toast.ts +0 -280
- package/src/hooks/use-workspace-title.ts +0 -23
- package/src/lib/api-utils.ts +0 -24
- package/src/lib/branch-colors.ts +0 -98
- package/src/lib/credentials.ts +0 -404
- package/src/lib/git.ts +0 -1510
- package/src/lib/graph-utils.ts +0 -253
- package/src/lib/store.ts +0 -145
- package/src/lib/types.ts +0 -95
- package/src/lib/utils.ts +0 -266
- package/tsconfig.json +0 -34
- /package/{src/app/icon.png → .next/server/app/icon.png.body} +0 -0
|
@@ -1,408 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useState } from 'react';
|
|
4
|
-
import { useCredentials, useCreateCredential, useUpdateCredential, useDeleteCredential } from '@/hooks/use-credentials';
|
|
5
|
-
import type { Credential, GitLabCredential } from '@/hooks/use-credentials';
|
|
6
|
-
import Image from 'next/image';
|
|
7
|
-
import Link from 'next/link';
|
|
8
|
-
import { useEscapeDismiss } from '@/hooks/use-escape-dismiss';
|
|
9
|
-
|
|
10
|
-
type CredentialFormType = 'github' | 'gitlab' | null;
|
|
11
|
-
type ProviderType = 'github' | 'gitlab';
|
|
12
|
-
|
|
13
|
-
const PROVIDER_ICON_URLS: Record<ProviderType, string> = {
|
|
14
|
-
github: 'https://www.google.com/s2/favicons?domain=github.com&sz=64',
|
|
15
|
-
gitlab: 'https://www.google.com/s2/favicons?domain=gitlab.com&sz=64',
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
function ProviderIcon({
|
|
19
|
-
type,
|
|
20
|
-
size,
|
|
21
|
-
className = '',
|
|
22
|
-
}: {
|
|
23
|
-
type: ProviderType;
|
|
24
|
-
size: number;
|
|
25
|
-
className?: string;
|
|
26
|
-
}) {
|
|
27
|
-
const label = type === 'github' ? 'GitHub' : 'GitLab';
|
|
28
|
-
return (
|
|
29
|
-
<Image
|
|
30
|
-
src={PROVIDER_ICON_URLS[type]}
|
|
31
|
-
alt={`${label} icon`}
|
|
32
|
-
width={size}
|
|
33
|
-
height={size}
|
|
34
|
-
className={className}
|
|
35
|
-
unoptimized
|
|
36
|
-
/>
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default function CredentialsPage() {
|
|
41
|
-
const { data: credentials, isLoading, error } = useCredentials();
|
|
42
|
-
const createCredential = useCreateCredential();
|
|
43
|
-
const updateCredential = useUpdateCredential();
|
|
44
|
-
const deleteCredential = useDeleteCredential();
|
|
45
|
-
|
|
46
|
-
const [formType, setFormType] = useState<CredentialFormType>(null);
|
|
47
|
-
const [editingCredential, setEditingCredential] = useState<Credential | null>(null);
|
|
48
|
-
const [deletingCredential, setDeletingCredential] = useState<Credential | null>(null);
|
|
49
|
-
|
|
50
|
-
// Form state
|
|
51
|
-
const [token, setToken] = useState('');
|
|
52
|
-
const [serverUrl, setServerUrl] = useState('');
|
|
53
|
-
const [showToken, setShowToken] = useState(false);
|
|
54
|
-
const [formError, setFormError] = useState<string | null>(null);
|
|
55
|
-
|
|
56
|
-
const resetForm = () => {
|
|
57
|
-
setFormType(null);
|
|
58
|
-
setEditingCredential(null);
|
|
59
|
-
setToken('');
|
|
60
|
-
setServerUrl('');
|
|
61
|
-
setShowToken(false);
|
|
62
|
-
setFormError(null);
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const handleOpenCreate = (type: CredentialFormType) => {
|
|
66
|
-
resetForm();
|
|
67
|
-
setFormType(type);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const handleOpenEdit = (credential: Credential) => {
|
|
71
|
-
setEditingCredential(credential);
|
|
72
|
-
setFormType(credential.type);
|
|
73
|
-
setToken('');
|
|
74
|
-
if (credential.type === 'gitlab') {
|
|
75
|
-
setServerUrl(credential.serverUrl);
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const handleSubmit = async (e: React.FormEvent) => {
|
|
80
|
-
e.preventDefault();
|
|
81
|
-
setFormError(null);
|
|
82
|
-
|
|
83
|
-
try {
|
|
84
|
-
if (editingCredential) {
|
|
85
|
-
await updateCredential.mutateAsync({ id: editingCredential.id, token });
|
|
86
|
-
} else if (formType === 'github') {
|
|
87
|
-
await createCredential.mutateAsync({ type: 'github', token });
|
|
88
|
-
} else if (formType === 'gitlab') {
|
|
89
|
-
await createCredential.mutateAsync({ type: 'gitlab', serverUrl, token });
|
|
90
|
-
}
|
|
91
|
-
resetForm();
|
|
92
|
-
} catch (err) {
|
|
93
|
-
setFormError((err as Error).message);
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
const handleDelete = async () => {
|
|
98
|
-
if (!deletingCredential) return;
|
|
99
|
-
try {
|
|
100
|
-
await deleteCredential.mutateAsync(deletingCredential.id);
|
|
101
|
-
setDeletingCredential(null);
|
|
102
|
-
} catch (err) {
|
|
103
|
-
console.error('Failed to delete credential:', err);
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
const isSubmitting = createCredential.isPending || updateCredential.isPending;
|
|
108
|
-
useEscapeDismiss(formType !== null, resetForm);
|
|
109
|
-
useEscapeDismiss(deletingCredential !== null, () => setDeletingCredential(null));
|
|
110
|
-
|
|
111
|
-
return (
|
|
112
|
-
<main className="min-h-screen bg-base-100">
|
|
113
|
-
<div className="container mx-auto max-w-4xl py-12 px-6">
|
|
114
|
-
{/* Header */}
|
|
115
|
-
<div className="flex items-center justify-between mb-8">
|
|
116
|
-
<div className="flex items-center gap-4">
|
|
117
|
-
<Link href="/" className="btn btn-ghost btn-square">
|
|
118
|
-
<i className="iconoir-arrow-left text-[20px]" aria-hidden="true" />
|
|
119
|
-
</Link>
|
|
120
|
-
<div>
|
|
121
|
-
<h1 className="text-2xl font-bold tracking-tight">Credentials</h1>
|
|
122
|
-
<p className="text-sm opacity-70 mt-1">
|
|
123
|
-
Manage your remote repository credentials
|
|
124
|
-
</p>
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
</div>
|
|
128
|
-
|
|
129
|
-
{/* Add Credential Buttons */}
|
|
130
|
-
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8">
|
|
131
|
-
<div
|
|
132
|
-
className="card bg-base-100 shadow-lg hover:shadow-xl transition-shadow cursor-pointer border border-base-200"
|
|
133
|
-
onClick={() => handleOpenCreate('github')}
|
|
134
|
-
>
|
|
135
|
-
<div className="card-body p-6">
|
|
136
|
-
<div className="flex items-center gap-3 mb-2">
|
|
137
|
-
<div className="p-2 bg-base-200 rounded-lg">
|
|
138
|
-
<ProviderIcon type="github" size={24} className="h-6 w-6 rounded-sm" />
|
|
139
|
-
</div>
|
|
140
|
-
<div>
|
|
141
|
-
<h3 className="card-title text-base">GitHub</h3>
|
|
142
|
-
<p className="text-xs opacity-70">
|
|
143
|
-
Personal Access Token
|
|
144
|
-
</p>
|
|
145
|
-
</div>
|
|
146
|
-
</div>
|
|
147
|
-
<button className="btn btn-sm w-full gap-2">
|
|
148
|
-
<i className="iconoir-plus text-[16px]" aria-hidden="true" />
|
|
149
|
-
Add GitHub
|
|
150
|
-
</button>
|
|
151
|
-
</div>
|
|
152
|
-
</div>
|
|
153
|
-
|
|
154
|
-
<div
|
|
155
|
-
className="card bg-base-100 shadow-lg hover:shadow-xl transition-shadow cursor-pointer border border-base-200"
|
|
156
|
-
onClick={() => handleOpenCreate('gitlab')}
|
|
157
|
-
>
|
|
158
|
-
<div className="card-body p-6">
|
|
159
|
-
<div className="flex items-center gap-3 mb-2">
|
|
160
|
-
<div className="p-2 bg-base-200 rounded-lg">
|
|
161
|
-
<ProviderIcon type="gitlab" size={24} className="h-6 w-6 rounded-sm" />
|
|
162
|
-
</div>
|
|
163
|
-
<div>
|
|
164
|
-
<h3 className="card-title text-base">GitLab</h3>
|
|
165
|
-
<p className="text-xs opacity-70">Server URL + Personal Access Token</p>
|
|
166
|
-
</div>
|
|
167
|
-
</div>
|
|
168
|
-
<button className="btn btn-sm w-full gap-2">
|
|
169
|
-
<i className="iconoir-plus text-[16px]" aria-hidden="true" />
|
|
170
|
-
Add GitLab Server
|
|
171
|
-
</button>
|
|
172
|
-
</div>
|
|
173
|
-
</div>
|
|
174
|
-
</div>
|
|
175
|
-
|
|
176
|
-
{/* Credentials List */}
|
|
177
|
-
<div className="border border-base-200 rounded-lg overflow-hidden bg-base-100">
|
|
178
|
-
<div className="px-6 py-3 bg-base-200/50 border-b border-base-200">
|
|
179
|
-
<h2 className="text-sm font-bold opacity-70">Saved Credentials</h2>
|
|
180
|
-
</div>
|
|
181
|
-
|
|
182
|
-
{isLoading ? (
|
|
183
|
-
<div className="p-12 text-center opacity-70">
|
|
184
|
-
<span className="loading loading-spinner"></span>
|
|
185
|
-
<p className="mt-2 text-sm">Loading credentials...</p>
|
|
186
|
-
</div>
|
|
187
|
-
) : error ? (
|
|
188
|
-
<div className="p-12 text-center text-error">
|
|
189
|
-
<p>Failed to load credentials</p>
|
|
190
|
-
</div>
|
|
191
|
-
) : credentials?.length === 0 ? (
|
|
192
|
-
<div className="p-12 text-center opacity-50">
|
|
193
|
-
<i className="iconoir-key text-[40px] mx-auto" aria-hidden="true" />
|
|
194
|
-
<p className="font-bold mt-2">No credentials saved yet.</p>
|
|
195
|
-
<p className="text-xs mt-1">Add your first credential using the cards above.</p>
|
|
196
|
-
</div>
|
|
197
|
-
) : (
|
|
198
|
-
<div className="divide-y divide-base-200">
|
|
199
|
-
{credentials?.map((credential) => (
|
|
200
|
-
<CredentialItem
|
|
201
|
-
key={credential.id}
|
|
202
|
-
credential={credential}
|
|
203
|
-
onEdit={() => handleOpenEdit(credential)}
|
|
204
|
-
onDelete={() => setDeletingCredential(credential)}
|
|
205
|
-
/>
|
|
206
|
-
))}
|
|
207
|
-
</div>
|
|
208
|
-
)}
|
|
209
|
-
</div>
|
|
210
|
-
</div>
|
|
211
|
-
|
|
212
|
-
{/* Create/Edit Dialog */}
|
|
213
|
-
{formType !== null && (
|
|
214
|
-
<dialog className="modal modal-open">
|
|
215
|
-
<div className="modal-box">
|
|
216
|
-
<h3 className="font-bold text-lg flex items-center gap-2">
|
|
217
|
-
{formType === 'github' ? (
|
|
218
|
-
<>
|
|
219
|
-
<ProviderIcon type="github" size={20} className="h-5 w-5 rounded-sm" />
|
|
220
|
-
GitHub Credential
|
|
221
|
-
</>
|
|
222
|
-
) : (
|
|
223
|
-
<>
|
|
224
|
-
<ProviderIcon type="gitlab" size={20} className="h-5 w-5 rounded-sm" />
|
|
225
|
-
GitLab Credential
|
|
226
|
-
</>
|
|
227
|
-
)}
|
|
228
|
-
</h3>
|
|
229
|
-
<p className="py-4 text-sm opacity-70">
|
|
230
|
-
{editingCredential
|
|
231
|
-
? 'Enter a new personal access token to update this credential.'
|
|
232
|
-
: formType === 'github'
|
|
233
|
-
? 'Enter your GitHub personal access token. This will be stored securely in your system keychain.'
|
|
234
|
-
: 'Enter your GitLab server URL and personal access token.'}
|
|
235
|
-
</p>
|
|
236
|
-
|
|
237
|
-
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
|
238
|
-
{formType === 'gitlab' && !editingCredential && (
|
|
239
|
-
<div className="form-control w-full">
|
|
240
|
-
<label className="label"><span className="label-text">Server URL</span></label>
|
|
241
|
-
<input
|
|
242
|
-
type="url"
|
|
243
|
-
placeholder="https://gitlab.example.com"
|
|
244
|
-
value={serverUrl}
|
|
245
|
-
onChange={(e) => setServerUrl(e.target.value)}
|
|
246
|
-
required
|
|
247
|
-
className="input input-bordered w-full"
|
|
248
|
-
autoFocus
|
|
249
|
-
/>
|
|
250
|
-
<label className="label"><span className="label-text-alt opacity-70">Enter the full URL of your GitLab server</span></label>
|
|
251
|
-
</div>
|
|
252
|
-
)}
|
|
253
|
-
|
|
254
|
-
{formType === 'gitlab' && editingCredential && (
|
|
255
|
-
<div className="form-control w-full">
|
|
256
|
-
<label className="label"><span className="label-text">Server URL</span></label>
|
|
257
|
-
<div className="p-3 bg-base-200 rounded-lg text-sm font-mono flex items-center gap-2 min-w-0 break-all">
|
|
258
|
-
<ProviderIcon type="gitlab" size={16} className="h-4 w-4 shrink-0 rounded-sm" />
|
|
259
|
-
{(editingCredential as GitLabCredential).serverUrl}
|
|
260
|
-
</div>
|
|
261
|
-
</div>
|
|
262
|
-
)}
|
|
263
|
-
|
|
264
|
-
<div className="form-control w-full">
|
|
265
|
-
<label className="label"><span className="label-text">Personal Access Token</span></label>
|
|
266
|
-
<div className="relative">
|
|
267
|
-
<input
|
|
268
|
-
type={showToken ? 'text' : 'password'}
|
|
269
|
-
placeholder={editingCredential ? 'Enter new token' : 'ghp_xxxxxxxxxxxx or glpat-xxxxx'}
|
|
270
|
-
value={token}
|
|
271
|
-
onChange={(e) => setToken(e.target.value)}
|
|
272
|
-
className="input input-bordered w-full pr-10"
|
|
273
|
-
required
|
|
274
|
-
autoFocus={!(formType === 'gitlab' && !editingCredential)}
|
|
275
|
-
/>
|
|
276
|
-
<button
|
|
277
|
-
type="button"
|
|
278
|
-
className="absolute right-2 top-2 btn btn-ghost btn-xs btn-square"
|
|
279
|
-
onClick={() => setShowToken(!showToken)}
|
|
280
|
-
>
|
|
281
|
-
{showToken ? <i className="iconoir-eye-closed text-[16px]" aria-hidden="true" /> : <i className="iconoir-eye text-[16px]" aria-hidden="true" />}
|
|
282
|
-
</button>
|
|
283
|
-
</div>
|
|
284
|
-
<label className="label">
|
|
285
|
-
<span className="label-text-alt opacity-70">
|
|
286
|
-
{formType === 'github' ? (
|
|
287
|
-
<>
|
|
288
|
-
Token needs repo scope.{' '}
|
|
289
|
-
<a
|
|
290
|
-
href="https://github.com/settings/tokens/new?description=Trident&scopes=repo,user,notifications,workflow"
|
|
291
|
-
target="_blank"
|
|
292
|
-
rel="noreferrer"
|
|
293
|
-
className="link link-primary"
|
|
294
|
-
>
|
|
295
|
-
Create new token
|
|
296
|
-
</a>
|
|
297
|
-
</>
|
|
298
|
-
) : (
|
|
299
|
-
'Token needs api scope for GitLab access'
|
|
300
|
-
)}
|
|
301
|
-
</span>
|
|
302
|
-
</label>
|
|
303
|
-
</div>
|
|
304
|
-
|
|
305
|
-
{formError && (
|
|
306
|
-
<div className="alert alert-error text-sm">
|
|
307
|
-
<span>{formError}</span>
|
|
308
|
-
</div>
|
|
309
|
-
)}
|
|
310
|
-
|
|
311
|
-
<div className="modal-action">
|
|
312
|
-
<button type="button" className="btn" onClick={resetForm} disabled={isSubmitting}>Cancel</button>
|
|
313
|
-
<button type="submit" className="btn btn-primary" disabled={isSubmitting}>
|
|
314
|
-
{isSubmitting && <span className="loading loading-spinner loading-xs"></span>}
|
|
315
|
-
{editingCredential ? 'Update' : 'Verify & Save'}
|
|
316
|
-
</button>
|
|
317
|
-
</div>
|
|
318
|
-
</form>
|
|
319
|
-
</div>
|
|
320
|
-
<form method="dialog" className="modal-backdrop">
|
|
321
|
-
<button onClick={resetForm}>close</button>
|
|
322
|
-
</form>
|
|
323
|
-
</dialog>
|
|
324
|
-
)}
|
|
325
|
-
|
|
326
|
-
{/* Delete Confirmation Dialog */}
|
|
327
|
-
{deletingCredential !== null && (
|
|
328
|
-
<dialog className="modal modal-open">
|
|
329
|
-
<div className="modal-box">
|
|
330
|
-
<h3 className="font-bold text-lg">Delete Credential</h3>
|
|
331
|
-
<p className="py-4 break-words">
|
|
332
|
-
Are you sure you want to delete this {deletingCredential?.type === 'github' ? 'GitHub' : 'GitLab'}{' '}
|
|
333
|
-
credential for <strong className="break-all">{deletingCredential?.username}</strong>? This action cannot be undone.
|
|
334
|
-
</p>
|
|
335
|
-
<div className="modal-action">
|
|
336
|
-
<button className="btn" onClick={() => setDeletingCredential(null)}>Cancel</button>
|
|
337
|
-
<button className="btn btn-error" onClick={handleDelete} disabled={deleteCredential.isPending}>
|
|
338
|
-
{deleteCredential.isPending && <span className="loading loading-spinner loading-xs"></span>}
|
|
339
|
-
Delete
|
|
340
|
-
</button>
|
|
341
|
-
</div>
|
|
342
|
-
</div>
|
|
343
|
-
<form method="dialog" className="modal-backdrop">
|
|
344
|
-
<button onClick={() => setDeletingCredential(null)}>close</button>
|
|
345
|
-
</form>
|
|
346
|
-
</dialog>
|
|
347
|
-
)}
|
|
348
|
-
</main>
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
function CredentialItem({
|
|
353
|
-
credential,
|
|
354
|
-
onEdit,
|
|
355
|
-
onDelete,
|
|
356
|
-
}: {
|
|
357
|
-
credential: Credential;
|
|
358
|
-
onEdit: () => void;
|
|
359
|
-
onDelete: () => void;
|
|
360
|
-
}) {
|
|
361
|
-
const isGitLab = credential.type === 'gitlab';
|
|
362
|
-
|
|
363
|
-
return (
|
|
364
|
-
<div className="px-6 py-4 flex items-center justify-between hover:bg-base-200/30 transition-colors">
|
|
365
|
-
<div className="flex items-center gap-4">
|
|
366
|
-
<div className="p-2 bg-base-200 rounded-lg">
|
|
367
|
-
{isGitLab ? (
|
|
368
|
-
<ProviderIcon type="gitlab" size={20} className="h-5 w-5 rounded-sm" />
|
|
369
|
-
) : (
|
|
370
|
-
<ProviderIcon type="github" size={20} className="h-5 w-5 rounded-sm" />
|
|
371
|
-
)}
|
|
372
|
-
</div>
|
|
373
|
-
<div>
|
|
374
|
-
<div className="flex items-center gap-2">
|
|
375
|
-
<span className="font-bold text-sm">{isGitLab ? 'GitLab' : 'GitHub'}</span>
|
|
376
|
-
{isGitLab && (
|
|
377
|
-
<span className="text-xs opacity-70 font-mono bg-base-200 px-1.5 py-0.5 rounded">
|
|
378
|
-
{(credential as GitLabCredential).serverUrl.replace(/^https?:\/\//, '')}
|
|
379
|
-
</span>
|
|
380
|
-
)}
|
|
381
|
-
</div>
|
|
382
|
-
<div className="flex items-center gap-3 text-xs opacity-70 mt-1">
|
|
383
|
-
<span className="flex items-center gap-1">
|
|
384
|
-
<i className="iconoir-user text-[14px]" aria-hidden="true" />
|
|
385
|
-
{credential.username}
|
|
386
|
-
</span>
|
|
387
|
-
<span className="flex items-center gap-1">
|
|
388
|
-
<i className="iconoir-calendar text-[14px]" aria-hidden="true" />
|
|
389
|
-
{new Date(credential.updatedAt).toLocaleDateString()}
|
|
390
|
-
</span>
|
|
391
|
-
</div>
|
|
392
|
-
</div>
|
|
393
|
-
</div>
|
|
394
|
-
<div className="flex items-center gap-1">
|
|
395
|
-
<button className="btn btn-ghost btn-sm btn-square" onClick={onEdit} title="Edit">
|
|
396
|
-
<i className="iconoir-edit-pencil text-[16px]" aria-hidden="true" />
|
|
397
|
-
</button>
|
|
398
|
-
<button
|
|
399
|
-
className="btn btn-ghost btn-sm btn-square text-error hover:bg-error/10"
|
|
400
|
-
onClick={onDelete}
|
|
401
|
-
title="Delete"
|
|
402
|
-
>
|
|
403
|
-
<i className="iconoir-trash text-[16px]" aria-hidden="true" />
|
|
404
|
-
</button>
|
|
405
|
-
</div>
|
|
406
|
-
</div>
|
|
407
|
-
);
|
|
408
|
-
}
|
package/src/app/globals.css
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
@import "tailwindcss";
|
|
2
|
-
@plugin "daisyui";
|
|
3
|
-
|
|
4
|
-
@layer base {
|
|
5
|
-
body {
|
|
6
|
-
@apply bg-base-100 text-base-content;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/* Custom styles for React Diff Viewer to match original design */
|
|
11
|
-
.diff-viewer-wrapper {
|
|
12
|
-
width: 100% !important;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/* Force diff-library layout elements to be full width */
|
|
16
|
-
.diff-viewer-wrapper .diff-container,
|
|
17
|
-
.diff-viewer-wrapper .diff-container div,
|
|
18
|
-
.diff-viewer-wrapper .diff-container table,
|
|
19
|
-
.diff-viewer-wrapper .diff-container tbody {
|
|
20
|
-
width: 100% !important;
|
|
21
|
-
max-width: 100% !important;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.diff-container {
|
|
25
|
-
font-size: 11px !important;
|
|
26
|
-
font-family: monospace !important;
|
|
27
|
-
width: 100% !important;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.diff-container .line,
|
|
31
|
-
.diff-container .gutter,
|
|
32
|
-
.diff-container pre {
|
|
33
|
-
line-height: 1.3 !important;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/* Force Equal Split View using Wrapper Class and Nth-Child */
|
|
37
|
-
/* This is necessary because the library's fixed layout algorithm behaves unpredictably with width:auto */
|
|
38
|
-
|
|
39
|
-
/* 1. Force fixed table layout */
|
|
40
|
-
.diff-viewer-wrapper table.split-view {
|
|
41
|
-
table-layout: fixed !important;
|
|
42
|
-
width: 100% !important;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/* 2. Constrain Gutters (Columns 1 & 4) */
|
|
46
|
-
.diff-viewer-wrapper table.split-view tbody tr td:nth-child(1),
|
|
47
|
-
.diff-viewer-wrapper table.split-view tbody tr td:nth-child(4) {
|
|
48
|
-
width: 64px !important;
|
|
49
|
-
min-width: 64px !important;
|
|
50
|
-
white-space: nowrap !important;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/* 3. Constrain Markers (Columns 2 & 5) */
|
|
54
|
-
.diff-viewer-wrapper table.split-view tbody tr td:nth-child(2),
|
|
55
|
-
.diff-viewer-wrapper table.split-view tbody tr td:nth-child(5) {
|
|
56
|
-
width: 20px !important;
|
|
57
|
-
min-width: 20px !important;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/* 4. Force Content Columns (Columns 3 & 6) to be equal */
|
|
61
|
-
.diff-viewer-wrapper table.split-view tbody tr td:nth-child(3),
|
|
62
|
-
.diff-viewer-wrapper table.split-view tbody tr td:nth-child(6) {
|
|
63
|
-
width: auto !important;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/* 5. Force text wrapping in diff content to prevent overflow */
|
|
67
|
-
.diff-viewer-wrapper td.content pre {
|
|
68
|
-
white-space: pre-wrap !important;
|
|
69
|
-
word-wrap: break-word !important;
|
|
70
|
-
overflow-wrap: break-word !important;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/* Keep gutter line numbers on a single line (prevents 1694 -> 169 + 4 wrapping) */
|
|
74
|
-
.diff-viewer-wrapper td.gutter pre.line-number {
|
|
75
|
-
white-space: nowrap !important;
|
|
76
|
-
word-wrap: normal !important;
|
|
77
|
-
overflow-wrap: normal !important;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/* Unified view: constrain table and allow content to wrap */
|
|
81
|
-
.diff-viewer-wrapper table:not(.split-view) {
|
|
82
|
-
width: 100% !important;
|
|
83
|
-
max-width: 100% !important;
|
|
84
|
-
table-layout: auto !important;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/* Unified view: Constrain gutter columns to not expand */
|
|
88
|
-
.diff-viewer-wrapper table:not(.split-view) td.gutter {
|
|
89
|
-
width: 1% !important;
|
|
90
|
-
white-space: nowrap !important;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/* Unified view: Constrain marker column */
|
|
94
|
-
.diff-viewer-wrapper table:not(.split-view) td.marker {
|
|
95
|
-
width: 1% !important;
|
|
96
|
-
white-space: nowrap !important;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/* Unified view: Content column - force it to constrain and wrap */
|
|
100
|
-
.diff-viewer-wrapper table:not(.split-view) td.content {
|
|
101
|
-
width: 97% !important;
|
|
102
|
-
max-width: 0 !important;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.diff-viewer-wrapper table:not(.split-view) td.content pre {
|
|
106
|
-
white-space: pre-wrap !important;
|
|
107
|
-
word-wrap: break-word !important;
|
|
108
|
-
overflow-wrap: anywhere !important;
|
|
109
|
-
}
|
package/src/app/layout.tsx
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { Metadata } from "next";
|
|
2
|
-
import { Geist, Geist_Mono } from "next/font/google";
|
|
3
|
-
import "./globals.css";
|
|
4
|
-
import { Providers } from "./providers";
|
|
5
|
-
|
|
6
|
-
const geistSans = Geist({
|
|
7
|
-
variable: "--font-geist-sans",
|
|
8
|
-
subsets: ["latin"],
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
const geistMono = Geist_Mono({
|
|
12
|
-
variable: "--font-geist-mono",
|
|
13
|
-
subsets: ["latin"],
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
export const metadata: Metadata = {
|
|
17
|
-
title: "Trident",
|
|
18
|
-
description: "Git repository management tool"
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export default function RootLayout({
|
|
22
|
-
children,
|
|
23
|
-
}: Readonly<{
|
|
24
|
-
children: React.ReactNode;
|
|
25
|
-
}>) {
|
|
26
|
-
return (
|
|
27
|
-
<html lang="en" suppressHydrationWarning>
|
|
28
|
-
<head>
|
|
29
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/iconoir-icons/iconoir@main/css/iconoir.css" />
|
|
30
|
-
</head>
|
|
31
|
-
<body
|
|
32
|
-
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
|
33
|
-
>
|
|
34
|
-
<Providers>{children}</Providers>
|
|
35
|
-
</body>
|
|
36
|
-
</html>
|
|
37
|
-
);
|
|
38
|
-
}
|
package/src/app/page.tsx
DELETED
package/src/app/providers.tsx
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
4
|
-
import { useState } from 'react';
|
|
5
|
-
import { ThemeProvider } from 'next-themes';
|
|
6
|
-
import { Toaster } from '@/components/toaster';
|
|
7
|
-
import { CommandPalette } from '@/components/command-palette';
|
|
8
|
-
|
|
9
|
-
export function Providers({ children }: { children: React.ReactNode }) {
|
|
10
|
-
const [queryClient] = useState(() => new QueryClient());
|
|
11
|
-
|
|
12
|
-
return (
|
|
13
|
-
<QueryClientProvider client={queryClient}>
|
|
14
|
-
<ThemeProvider attribute="data-theme" defaultTheme="system" enableSystem>
|
|
15
|
-
{children}
|
|
16
|
-
<CommandPalette />
|
|
17
|
-
<Toaster />
|
|
18
|
-
</ThemeProvider>
|
|
19
|
-
</QueryClientProvider>
|
|
20
|
-
);
|
|
21
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { useSearchParams } from 'next/navigation';
|
|
4
|
-
import { StatusView } from '@/components/git/status-view';
|
|
5
|
-
import { Suspense } from 'react';
|
|
6
|
-
import { useWorkspaceTitle } from '@/hooks/use-workspace-title';
|
|
7
|
-
|
|
8
|
-
function WorkspaceChangesContent() {
|
|
9
|
-
const searchParams = useSearchParams();
|
|
10
|
-
const repoPath = searchParams.get('path');
|
|
11
|
-
|
|
12
|
-
useWorkspaceTitle(repoPath, 'Changes');
|
|
13
|
-
|
|
14
|
-
if (!repoPath) {
|
|
15
|
-
return <div className="p-8">No repository path specified.</div>;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return <StatusView repoPath={repoPath} />;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export default function WorkspaceChangesPage() {
|
|
22
|
-
return (
|
|
23
|
-
<Suspense fallback={<div className="flex items-center justify-center h-full"><span className="loading loading-spinner"></span></div>}>
|
|
24
|
-
<WorkspaceChangesContent />
|
|
25
|
-
</Suspense>
|
|
26
|
-
);
|
|
27
|
-
}
|