mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-25 21:36:52 +08:00
feat: Add GitHub token validation check to Issues/PRs page
- Check if GitHub token is configured before displaying the page - Show loading state while checking settings - Display message with link to git settings when token is not configured - Add translations for NO_TOKEN and CONFIGURE_TOKEN messages - Add tests for token validation states Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
parent
6185b7e419
commit
46dde54230
@ -7,6 +7,7 @@ import GitHubIssuesPRsPage from "#/routes/github-issues-prs";
|
||||
import GitHubIssuesPRsService from "#/api/github-service/github-issues-prs.api";
|
||||
import ConversationService from "#/api/conversation-service/conversation-service.api";
|
||||
import { useShouldShowUserFeatures } from "#/hooks/use-should-show-user-features";
|
||||
import { useUserProviders } from "#/hooks/use-user-providers";
|
||||
|
||||
// Mock the services
|
||||
vi.mock("#/api/github-service/github-issues-prs.api", () => ({
|
||||
@ -32,6 +33,10 @@ vi.mock("#/hooks/use-should-show-user-features", () => ({
|
||||
useShouldShowUserFeatures: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("#/hooks/use-user-providers", () => ({
|
||||
useUserProviders: vi.fn(),
|
||||
}));
|
||||
|
||||
// Mock react-i18next to return the key as the translation
|
||||
vi.mock("react-i18next", () => ({
|
||||
useTranslation: () => ({
|
||||
@ -45,6 +50,7 @@ const mockSearchConversations = vi.mocked(
|
||||
ConversationService.searchConversations,
|
||||
);
|
||||
const mockUseShouldShowUserFeatures = vi.mocked(useShouldShowUserFeatures);
|
||||
const mockUseUserProviders = vi.mocked(useUserProviders);
|
||||
|
||||
const renderGitHubIssuesPRsPage = () =>
|
||||
render(
|
||||
@ -96,6 +102,10 @@ describe("GitHubIssuesPRsPage", () => {
|
||||
localStorage.clear();
|
||||
|
||||
mockUseShouldShowUserFeatures.mockReturnValue(true);
|
||||
mockUseUserProviders.mockReturnValue({
|
||||
providers: ["github"],
|
||||
isLoadingSettings: false,
|
||||
});
|
||||
|
||||
mockGetGitHubItems.mockResolvedValue({
|
||||
items: MOCK_GITHUB_ITEMS,
|
||||
@ -261,4 +271,46 @@ describe("GitHubIssuesPRsPage", () => {
|
||||
expect(viewLinks.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
it("should show loading state while checking settings", async () => {
|
||||
mockUseUserProviders.mockReturnValue({
|
||||
providers: [],
|
||||
isLoadingSettings: true,
|
||||
});
|
||||
|
||||
renderGitHubIssuesPRsPage();
|
||||
|
||||
// Should show loading spinner
|
||||
expect(screen.getByTestId("loading-spinner")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should show no-token message when GitHub token is not configured", async () => {
|
||||
mockUseUserProviders.mockReturnValue({
|
||||
providers: [],
|
||||
isLoadingSettings: false,
|
||||
});
|
||||
|
||||
renderGitHubIssuesPRsPage();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText("GITHUB_ISSUES_PRS$NO_TOKEN")).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText("GITHUB_ISSUES_PRS$CONFIGURE_TOKEN"),
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
it("should have a link to git settings when no token is configured", async () => {
|
||||
mockUseUserProviders.mockReturnValue({
|
||||
providers: [],
|
||||
isLoadingSettings: false,
|
||||
});
|
||||
|
||||
renderGitHubIssuesPRsPage();
|
||||
|
||||
await waitFor(() => {
|
||||
const configureLink = screen.getByText("GITHUB_ISSUES_PRS$CONFIGURE_TOKEN");
|
||||
expect(configureLink).toHaveAttribute("href", "/settings/git");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
44
frontend/package-lock.json
generated
44
frontend/package-lock.json
generated
@ -192,7 +192,6 @@
|
||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
@ -732,7 +731,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
@ -779,7 +777,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
@ -2331,7 +2328,6 @@
|
||||
"version": "2.4.24",
|
||||
"resolved": "https://registry.npmjs.org/@heroui/system/-/system-2.4.24.tgz",
|
||||
"integrity": "sha512-9GKQgUc91otQfwmq6TLE72QKxtB341aK5NpBHS3gRoWYEuNN714Zl3OXwIZNvdXPJpsTaUo1ID1ibJU9tfgwdg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@heroui/react-utils": "2.1.14",
|
||||
"@heroui/system-rsc": "2.3.21",
|
||||
@ -2411,7 +2407,6 @@
|
||||
"version": "2.4.24",
|
||||
"resolved": "https://registry.npmjs.org/@heroui/theme/-/theme-2.4.24.tgz",
|
||||
"integrity": "sha512-lL+anmY4GGWwKyTbJ2PEBZE4talIZ3hu4yGpku9TktCVG2nC2YTwiWQFJ+Jcbf8Cf9vuLzI1sla5bz2jUqiBRA==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@heroui/shared-utils": "2.1.12",
|
||||
"color": "^4.2.3",
|
||||
@ -5127,7 +5122,6 @@
|
||||
"integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.21.3",
|
||||
"@svgr/babel-preset": "8.1.0",
|
||||
@ -5588,7 +5582,6 @@
|
||||
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
@ -5766,7 +5759,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz",
|
||||
"integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==",
|
||||
"devOptional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~7.16.0"
|
||||
}
|
||||
@ -5782,7 +5774,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz",
|
||||
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.2.2"
|
||||
}
|
||||
@ -5793,7 +5784,6 @@
|
||||
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.2.0"
|
||||
}
|
||||
@ -5834,7 +5824,6 @@
|
||||
"integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.10.0",
|
||||
"@typescript-eslint/scope-manager": "7.18.0",
|
||||
@ -5892,7 +5881,6 @@
|
||||
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "7.18.0",
|
||||
"@typescript-eslint/types": "7.18.0",
|
||||
@ -6406,8 +6394,7 @@
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz",
|
||||
"integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.8",
|
||||
@ -6435,7 +6422,6 @@
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@ -6972,7 +6958,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.9.0",
|
||||
"caniuse-lite": "^1.0.30001759",
|
||||
@ -7661,8 +7646,7 @@
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
@ -8380,7 +8364,6 @@
|
||||
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.6.1",
|
||||
@ -8504,7 +8487,6 @@
|
||||
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"eslint-config-prettier": "bin/cli.js"
|
||||
},
|
||||
@ -8585,7 +8567,6 @@
|
||||
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@rtsao/scc": "^1.1.0",
|
||||
"array-includes": "^3.1.9",
|
||||
@ -8677,7 +8658,6 @@
|
||||
"integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"aria-query": "^5.3.2",
|
||||
"array-includes": "^3.1.8",
|
||||
@ -8773,7 +8753,6 @@
|
||||
"integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"array-includes": "^3.1.8",
|
||||
"array.prototype.findlast": "^1.2.5",
|
||||
@ -8807,7 +8786,6 @@
|
||||
"integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@ -9076,7 +9054,6 @@
|
||||
"version": "4.22.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz",
|
||||
"integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.8",
|
||||
"array-flatten": "1.1.1",
|
||||
@ -9407,7 +9384,6 @@
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.26.tgz",
|
||||
"integrity": "sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"motion-dom": "^12.23.23",
|
||||
"motion-utils": "^12.23.6",
|
||||
@ -10075,7 +10051,6 @@
|
||||
"url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
|
||||
}
|
||||
],
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.4"
|
||||
},
|
||||
@ -10853,7 +10828,6 @@
|
||||
"integrity": "sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@acemir/cssom": "^0.9.28",
|
||||
"@asamuzakjp/dom-selector": "^6.7.6",
|
||||
@ -12555,7 +12529,6 @@
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz",
|
||||
"integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"dompurify": "3.2.7",
|
||||
"marked": "14.0.0"
|
||||
@ -12650,7 +12623,6 @@
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@inquirer/confirm": "^5.0.0",
|
||||
"@mswjs/interceptors": "^0.40.0",
|
||||
@ -13375,7 +13347,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
@ -13437,7 +13408,6 @@
|
||||
"integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
@ -13634,7 +13604,6 @@
|
||||
"version": "19.2.3",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
|
||||
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -13683,7 +13652,6 @@
|
||||
"version": "19.2.3",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
|
||||
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.27.0"
|
||||
},
|
||||
@ -13796,7 +13764,6 @@
|
||||
"version": "7.11.0",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.11.0.tgz",
|
||||
"integrity": "sha512-uI4JkMmjbWCZc01WVP2cH7ZfSzH91JAZUDd7/nIprDgWxBV1TkkmLToFh7EbMTcMak8URFRa2YoBL/W8GWnCTQ==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cookie": "^1.0.1",
|
||||
"set-cookie-parser": "^2.6.0"
|
||||
@ -14158,7 +14125,6 @@
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz",
|
||||
"integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.8"
|
||||
},
|
||||
@ -15154,7 +15120,6 @@
|
||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz",
|
||||
"integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/dcastil"
|
||||
@ -15281,7 +15246,6 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@ -15583,7 +15547,6 @@
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@ -15889,7 +15852,6 @@
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz",
|
||||
"integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.27.0",
|
||||
"fdir": "^6.5.0",
|
||||
@ -16059,7 +16021,6 @@
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@ -16072,7 +16033,6 @@
|
||||
"resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.16.tgz",
|
||||
"integrity": "sha512-E4t7DJ9pESL6E3I8nFjPa4xGUd3PmiWDLsDztS2qXSJWfHtbQnwAWylaBvSNY48I3vr8PTqIZlyK8TE3V3CA4Q==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vitest/expect": "4.0.16",
|
||||
"@vitest/mocker": "4.0.16",
|
||||
|
||||
@ -980,5 +980,7 @@ export enum I18nKey {
|
||||
GITHUB_ISSUES_PRS$VIEW_ON_GITHUB = "GITHUB_ISSUES_PRS$VIEW_ON_GITHUB",
|
||||
GITHUB_ISSUES_PRS$START_SESSION = "GITHUB_ISSUES_PRS$START_SESSION",
|
||||
GITHUB_ISSUES_PRS$RESUME_SESSION = "GITHUB_ISSUES_PRS$RESUME_SESSION",
|
||||
GITHUB_ISSUES_PRS$NO_TOKEN = "GITHUB_ISSUES_PRS$NO_TOKEN",
|
||||
GITHUB_ISSUES_PRS$CONFIGURE_TOKEN = "GITHUB_ISSUES_PRS$CONFIGURE_TOKEN",
|
||||
SIDEBAR$GITHUB_ISSUES_PRS = "SIDEBAR$GITHUB_ISSUES_PRS",
|
||||
}
|
||||
|
||||
@ -15679,6 +15679,38 @@
|
||||
"de": "Sitzung fortsetzen",
|
||||
"uk": "Відновити сеанс"
|
||||
},
|
||||
"GITHUB_ISSUES_PRS$NO_TOKEN": {
|
||||
"en": "To view your GitHub issues and pull requests, you need to configure a GitHub token.",
|
||||
"ja": "GitHubのIssueとプルリクエストを表示するには、GitHubトークンを設定する必要があります。",
|
||||
"zh-CN": "要查看您的GitHub问题和拉取请求,您需要配置GitHub令牌。",
|
||||
"zh-TW": "要查看您的GitHub問題和拉取請求,您需要配置GitHub令牌。",
|
||||
"ko-KR": "GitHub 이슈와 풀 리퀘스트를 보려면 GitHub 토큰을 구성해야 합니다.",
|
||||
"no": "For å se dine GitHub-issues og pull requests, må du konfigurere et GitHub-token.",
|
||||
"it": "Per visualizzare le tue issue e pull request di GitHub, devi configurare un token GitHub.",
|
||||
"pt": "Para ver suas issues e pull requests do GitHub, você precisa configurar um token do GitHub.",
|
||||
"es": "Para ver tus issues y pull requests de GitHub, necesitas configurar un token de GitHub.",
|
||||
"ar": "لعرض مشكلات GitHub وطلبات السحب الخاصة بك، تحتاج إلى تكوين رمز GitHub.",
|
||||
"fr": "Pour voir vos issues et pull requests GitHub, vous devez configurer un token GitHub.",
|
||||
"tr": "GitHub sorunlarınızı ve çekme isteklerinizi görüntülemek için bir GitHub belirteci yapılandırmanız gerekir.",
|
||||
"de": "Um Ihre GitHub-Issues und Pull Requests anzuzeigen, müssen Sie ein GitHub-Token konfigurieren.",
|
||||
"uk": "Щоб переглянути ваші GitHub issues та pull requests, вам потрібно налаштувати токен GitHub."
|
||||
},
|
||||
"GITHUB_ISSUES_PRS$CONFIGURE_TOKEN": {
|
||||
"en": "Configure GitHub Token",
|
||||
"ja": "GitHubトークンを設定",
|
||||
"zh-CN": "配置GitHub令牌",
|
||||
"zh-TW": "配置GitHub令牌",
|
||||
"ko-KR": "GitHub 토큰 구성",
|
||||
"no": "Konfigurer GitHub-token",
|
||||
"it": "Configura token GitHub",
|
||||
"pt": "Configurar token do GitHub",
|
||||
"es": "Configurar token de GitHub",
|
||||
"ar": "تكوين رمز GitHub",
|
||||
"fr": "Configurer le token GitHub",
|
||||
"tr": "GitHub belirtecini yapılandır",
|
||||
"de": "GitHub-Token konfigurieren",
|
||||
"uk": "Налаштувати токен GitHub"
|
||||
},
|
||||
"SIDEBAR$GITHUB_ISSUES_PRS": {
|
||||
"en": "Issues & PRs",
|
||||
"ja": "Issues & PRs",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { useNavigate } from "react-router";
|
||||
import { Link, useNavigate } from "react-router";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { I18nKey } from "#/i18n/declaration";
|
||||
import {
|
||||
@ -8,6 +8,7 @@ import {
|
||||
} from "#/hooks/query/use-github-issues-prs";
|
||||
import { useSearchConversations } from "#/hooks/query/use-search-conversations";
|
||||
import { useCreateConversation } from "#/hooks/mutation/use-create-conversation";
|
||||
import { useUserProviders } from "#/hooks/use-user-providers";
|
||||
import { LoadingSpinner } from "#/components/shared/loading-spinner";
|
||||
import {
|
||||
GitHubItem,
|
||||
@ -132,6 +133,10 @@ function GitHubIssuesPRsPage() {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Check if GitHub token is configured
|
||||
const { providers, isLoadingSettings } = useUserProviders();
|
||||
const hasGitHubToken = providers.includes("github");
|
||||
|
||||
// Filter state
|
||||
const [viewType, setViewType] = React.useState<ViewType>("all");
|
||||
const [assignedToMe, setAssignedToMe] = React.useState(true);
|
||||
@ -268,6 +273,37 @@ PR: ${item.url}`;
|
||||
return items;
|
||||
}, [githubData?.items, viewType]);
|
||||
|
||||
// Show loading state while checking settings
|
||||
if (isLoadingSettings) {
|
||||
return (
|
||||
<div className="h-full flex items-center justify-center">
|
||||
<LoadingSpinner size="large" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Show message if GitHub token is not configured
|
||||
if (!hasGitHubToken) {
|
||||
return (
|
||||
<div className="h-full flex flex-col items-center justify-center p-6">
|
||||
<div className="max-w-md text-center">
|
||||
<h1 className="text-xl font-semibold text-white mb-4">
|
||||
{t(I18nKey.GITHUB_ISSUES_PRS$TITLE)}
|
||||
</h1>
|
||||
<p className="text-neutral-400 mb-6">
|
||||
{t(I18nKey.GITHUB_ISSUES_PRS$NO_TOKEN)}
|
||||
</p>
|
||||
<Link
|
||||
to="/settings/git"
|
||||
className="inline-block px-4 py-2 text-sm font-medium rounded bg-blue-600 hover:bg-blue-700 text-white transition-colors"
|
||||
>
|
||||
{t(I18nKey.GITHUB_ISSUES_PRS$CONFIGURE_TOKEN)}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col bg-transparent overflow-hidden">
|
||||
{/* Header */}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user