From d23dbe4126f329e5895ea6a55a6c4da950de203b Mon Sep 17 00:00:00 2001 From: I741485 Date: Fri, 4 Apr 2025 15:55:53 +0200 Subject: [PATCH 1/5] Feat: Support button for MCP github issues with info dump --- frontend-config.json | 4 +- public/locales/en.json | 10 ++- .../ControlPlane/MCPHealthPopoverButton.tsx | 71 ++++++++++++++++++- .../ControlPlanes/ControlPlaneCard.tsx | 7 +- src/lib/shared/links.ts | 3 + 5 files changed, 88 insertions(+), 7 deletions(-) diff --git a/frontend-config.json b/frontend-config.json index f9955793..109163c7 100644 --- a/frontend-config.json +++ b/frontend-config.json @@ -1,5 +1,5 @@ { "backendUrl": "http://localhost:3000", "landscape": "LOCAL", - "documentationBaseUrl": "http://localhost:3000" -} \ No newline at end of file + "documentationBaseUrl": "https://github.tools.sap/openmcp" +} diff --git a/public/locales/en.json b/public/locales/en.json index a9f23741..5bdc1e60 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -55,7 +55,15 @@ "typeHeader": "Type", "messageHeader": "Message", "reasonHeader": "Reason", - "transitionHeader": "Last transition time" + "transitionHeader": "Last transition time", + "createSupportTicketButton": "Create Support Ticket", + "templateId": "1-mcp_issue.yml", + "supportTicketTitle": "Control Plane Not Ready", + "supportTicketTitleIssues": "Issues with Control Plane", + "clusterIdentifierLabel": "cluster-link", + "whatHappenedLabel": "what-happened", + "statusDetailsLabel": "MCP Status", + "detailsLabel": "Details:" }, "CopyKubeconfigButton": { "copiedMessage": "Copied to Clipboard", diff --git a/src/components/ControlPlane/MCPHealthPopoverButton.tsx b/src/components/ControlPlane/MCPHealthPopoverButton.tsx index 35466b0b..d3d2f5ab 100644 --- a/src/components/ControlPlane/MCPHealthPopoverButton.tsx +++ b/src/components/ControlPlane/MCPHealthPopoverButton.tsx @@ -1,4 +1,11 @@ -import { AnalyticalTable, Icon, Popover } from '@ui5/webcomponents-react'; +import { + AnalyticalTable, + Icon, + Popover, + FlexBox, + FlexBoxJustifyContent, + Button, +} from '@ui5/webcomponents-react'; import { AnalyticalTableColumnDefinition } from '@ui5/webcomponents-react/wrappers'; import PopoverPlacement from '@ui5/webcomponents/dist/types/PopoverPlacement.js'; import '@ui5/webcomponents-icons/dist/copy'; @@ -10,14 +17,21 @@ import { import ReactTimeAgo from 'react-time-ago'; import { AnimatedHoverTextButton } from '../Helper/AnimatedHoverTextButton.tsx'; import { useTranslation } from 'react-i18next'; - +import { useFrontendConfig } from '../../context/FrontendConfigContext.tsx'; export default function MCPHealthPopoverButton({ mcpStatus, + projectName, + workspaceName, + mcpName, }: { mcpStatus: ControlPlaneStatusType | undefined; + projectName?: string; + workspaceName?: string; + mcpName?: string; }) { const popoverRef = useRef(null); const [open, setOpen] = useState(false); + const { links } = useFrontendConfig(); const { t } = useTranslation(); @@ -29,6 +43,37 @@ export default function MCPHealthPopoverButton({ } }; + const handleCopyStatusClick = () => { + const clusterDetails = `${projectName}/${workspaceName}/${mcpName}`; + + const statusDetails = mcpStatus?.conditions + ? `${t('MCPHealthPopoverButton.statusDetailsLabel')}: ${mcpStatus.status}\n\n${t('MCPHealthPopoverButton.detailsLabel')}\n` + + mcpStatus.conditions + .map((condition) => { + let text = `- ${condition.type}: ${condition.status}\n`; + if (condition.reason) + text += ` - ${t('MCPHealthPopoverButton.reasonHeader')}: ${condition.reason}\n`; + if (condition.message) + text += ` - ${t('MCPHealthPopoverButton.messageHeader')}: ${condition.message}\n`; + return text; + }) + .join('') + : ''; + + const params = new URLSearchParams({ + template: t('MCPHealthPopoverButton.templateId'), + title: `[${clusterDetails}]: ${ + mcpStatus?.status === ReadyStatus.NotReady + ? t('MCPHealthPopoverButton.supportTicketTitle') + : t('MCPHealthPopoverButton.supportTicketIssues') + }`, + 'cluster-link': clusterDetails, + 'what-happened': statusDetails, + }); + + window.open(`${links.COM_PAGE_SUPPORT_ISSUE}?${params}`, '_blank'); + }; + const statusTableColumns: AnalyticalTableColumnDefinition[] = [ { Header: t('MCPHealthPopoverButton.statusHeader'), @@ -73,7 +118,13 @@ export default function MCPHealthPopoverButton({ onClick={handleOpenerClick} /> - {} + { + + } ); @@ -82,10 +133,16 @@ export default function MCPHealthPopoverButton({ function StatusTable({ status, tableColumns, + onCopyClick, }: { status: ControlPlaneStatusType | undefined; tableColumns: AnalyticalTableColumnDefinition[]; + onCopyClick: () => void; }) { + const showSupportButton = + status?.status === ReadyStatus.NotReady || + status?.status === ReadyStatus.InDeletion; + return (
+ {showSupportButton && ( + + + + )}
); } diff --git a/src/components/ControlPlanes/ControlPlaneCard.tsx b/src/components/ControlPlanes/ControlPlaneCard.tsx index e0ff996c..68f14ed9 100644 --- a/src/components/ControlPlanes/ControlPlaneCard.tsx +++ b/src/components/ControlPlanes/ControlPlaneCard.tsx @@ -83,7 +83,12 @@ export function ControlPlaneCard({ alignItems="Center" style={{ paddingTop: '20px' }} > - + Date: Mon, 7 Apr 2025 11:40:27 +0200 Subject: [PATCH 2/5] Revert on local test --- frontend-config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend-config.json b/frontend-config.json index 109163c7..469730cb 100644 --- a/frontend-config.json +++ b/frontend-config.json @@ -1,5 +1,5 @@ { "backendUrl": "http://localhost:3000", "landscape": "LOCAL", - "documentationBaseUrl": "https://github.tools.sap/openmcp" + "documentationBaseUrl": "http://localhost:3000" } From 71e82f5c736b5eca0df43010531837990449f396 Mon Sep 17 00:00:00 2001 From: I741485 Date: Tue, 8 Apr 2025 16:22:20 +0200 Subject: [PATCH 3/5] Requested Changes Added --- frontend-config.json | 3 ++- .../ControlPlane/MCPHealthPopoverButton.tsx | 22 ++++++++++++------- src/context/FrontendConfigContext.tsx | 21 +++++++++++------- src/lib/shared/links.ts | 14 ++++++++---- src/utils/testing.ts | 8 +++---- src/views/ControlPlanes/ControlPlaneView.tsx | 7 +++++- 6 files changed, 49 insertions(+), 26 deletions(-) diff --git a/frontend-config.json b/frontend-config.json index 469730cb..a9c0bff5 100644 --- a/frontend-config.json +++ b/frontend-config.json @@ -1,5 +1,6 @@ { "backendUrl": "http://localhost:3000", "landscape": "LOCAL", - "documentationBaseUrl": "http://localhost:3000" + "documentationBaseUrl": "http://localhost:3000", + "githubBaseUrl": "http://localhost:3000" } diff --git a/src/components/ControlPlane/MCPHealthPopoverButton.tsx b/src/components/ControlPlane/MCPHealthPopoverButton.tsx index d3d2f5ab..2745de1a 100644 --- a/src/components/ControlPlane/MCPHealthPopoverButton.tsx +++ b/src/components/ControlPlane/MCPHealthPopoverButton.tsx @@ -43,7 +43,7 @@ export default function MCPHealthPopoverButton({ } }; - const handleCopyStatusClick = () => { + const constructGithubIssuesLink = () => { const clusterDetails = `${projectName}/${workspaceName}/${mcpName}`; const statusDetails = mcpStatus?.conditions @@ -61,17 +61,17 @@ export default function MCPHealthPopoverButton({ : ''; const params = new URLSearchParams({ - template: t('MCPHealthPopoverButton.templateId'), + template: '1-mcp_issue.yml', title: `[${clusterDetails}]: ${ mcpStatus?.status === ReadyStatus.NotReady ? t('MCPHealthPopoverButton.supportTicketTitle') - : t('MCPHealthPopoverButton.supportTicketIssues') + : t('MCPHealthPopoverButton.supportTicketTitleIssues') }`, 'cluster-link': clusterDetails, 'what-happened': statusDetails, }); - window.open(`${links.COM_PAGE_SUPPORT_ISSUE}?${params}`, '_blank'); + return `${links.COM_PAGE_SUPPORT_GITHUB_ISSUE}?${params}`; }; const statusTableColumns: AnalyticalTableColumnDefinition[] = [ @@ -122,7 +122,7 @@ export default function MCPHealthPopoverButton({ } @@ -133,16 +133,18 @@ export default function MCPHealthPopoverButton({ function StatusTable({ status, tableColumns, - onCopyClick, + githubIssuesLink, }: { status: ControlPlaneStatusType | undefined; tableColumns: AnalyticalTableColumnDefinition[]; - onCopyClick: () => void; + githubIssuesLink: string; }) { const showSupportButton = status?.status === ReadyStatus.NotReady || status?.status === ReadyStatus.InDeletion; + const { t } = useTranslation(); + return ( diff --git a/src/context/FrontendConfigContext.tsx b/src/context/FrontendConfigContext.tsx index d1d0ebab..a45cdace 100644 --- a/src/context/FrontendConfigContext.tsx +++ b/src/context/FrontendConfigContext.tsx @@ -1,5 +1,5 @@ import { ReactNode, createContext, use } from 'react'; -import { DocLinkCreator } from '../lib/shared/links'; +import { LinkCreator } from '../lib/shared/links'; export enum Landscape { Live = 'LIVE', @@ -13,13 +13,12 @@ interface FrontendConfigContextProps { backendUrl: string; landscape?: Landscape; documentationBaseUrl: string; - links: DocLinkCreator; + githubBaseUrl: string; + links: LinkCreator; } -export const FrontendConfigContext = createContext( - null, -); - +export const FrontendConfigContext = + createContext(null); const fetchPromise = fetch('/frontend-config.json').then((res) => res.json()); @@ -27,14 +26,20 @@ interface FrontendConfigProviderProps { children: ReactNode; } -export function FrontendConfigProvider({ children }: FrontendConfigProviderProps) { +export function FrontendConfigProvider({ + children, +}: FrontendConfigProviderProps) { const config = use(fetchPromise); - const docLinks = new DocLinkCreator(config.documentationBaseUrl); + const docLinks = new LinkCreator( + config.documentationBaseUrl, + config.githubBaseUrl, + ); const value: FrontendConfigContextProps = { links: docLinks, backendUrl: config.backendUrl, landscape: config.landscape, documentationBaseUrl: config.documentationBaseUrl, + githubBaseUrl: config.githubBaseUrl, }; return ( diff --git a/src/lib/shared/links.ts b/src/lib/shared/links.ts index 27df3471..cf163acd 100644 --- a/src/lib/shared/links.ts +++ b/src/lib/shared/links.ts @@ -1,13 +1,19 @@ -export class DocLinkCreator { +export class LinkCreator { private baseUrl: string; + private githubBaseUrl: string; - constructor(baseUrl: string) { + constructor(baseUrl: string, githubBaseUrl: string) { this.baseUrl = baseUrl; + this.githubBaseUrl = githubBaseUrl; } private createLink(path: string) { return `${this.baseUrl}${path}`; } + private createGithubLink(path: string) { + return `${this.githubBaseUrl}${path}`; + } + public get COMMUNITY_PAGE(): string { return this.createLink('/'); } @@ -26,7 +32,7 @@ export class DocLinkCreator { '/docs/managed-control-planes/get-started/get-started-mcp#5-create-managedcontrolplane', ); } - public get COM_PAGE_SUPPORT_ISSUE(): string { - return this.createLink('/support/issues/new'); + public get COM_PAGE_SUPPORT_GITHUB_ISSUE(): string { + return this.createGithubLink('/support/issues/new'); } } diff --git a/src/utils/testing.ts b/src/utils/testing.ts index b191d422..4685b2f2 100644 --- a/src/utils/testing.ts +++ b/src/utils/testing.ts @@ -1,11 +1,11 @@ -import { DocLinkCreator } from '../lib/shared/links.ts'; +import { LinkCreator } from '../lib/shared/links.ts'; import { Landscape } from '../context/FrontendConfigContext.tsx'; -export const isInTestingMode: Boolean = !!window.Cypress; +export const isInTestingMode: boolean = !!window.Cypress; const documentationBaseUrl = 'http://localhost:3000'; export const mockedFrontendConfig = { backendUrl: 'http://localhost:3000', landscape: Landscape.Local, documentationBaseUrl: 'http://localhost:3000', - links: new DocLinkCreator(documentationBaseUrl), -}; \ No newline at end of file + links: new LinkCreator(documentationBaseUrl), +}; diff --git a/src/views/ControlPlanes/ControlPlaneView.tsx b/src/views/ControlPlanes/ControlPlaneView.tsx index f4e3ded9..c011f430 100644 --- a/src/views/ControlPlanes/ControlPlaneView.tsx +++ b/src/views/ControlPlanes/ControlPlaneView.tsx @@ -80,7 +80,12 @@ export default function ControlPlaneView() { justifyContent: 'space-between', }} > - + } From 51d96f71f58b443cb6ac6852d4a0b44458e2114f Mon Sep 17 00:00:00 2001 From: fabianwolski Date: Fri, 2 May 2025 15:35:40 +0100 Subject: [PATCH 4/5] LinkCreator Implementation(will change later) with requested changes --- public/locales/en.json | 5 +- .../ControlPlane/MCPHealthPopoverButton.tsx | 51 ++++++++++--------- .../ControlPlaneCard/ControlPlaneCard.tsx | 7 ++- src/context/FrontendConfigContext.tsx | 10 ++-- src/lib/shared/links.ts | 4 +- src/utils/testing.ts | 2 +- src/views/ControlPlanes/ControlPlaneView.tsx | 7 ++- 7 files changed, 52 insertions(+), 34 deletions(-) diff --git a/public/locales/en.json b/public/locales/en.json index 0ea93af6..da59229f 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -61,8 +61,9 @@ "reasonHeader": "Reason", "transitionHeader": "Last transition time", "createSupportTicketButton": "Create Support Ticket", - "templateId": "1-mcp_issue.yml", - "supportTicketTitle": "Control Plane Not Ready", + "supportTicketTitleReady": "MCP Ready", + "supportTicketTitleNotReady": "MCP Not Ready", + "supportTicketTitleDeletion": "MCP in Deletion", "supportTicketTitleIssues": "Issues with Control Plane", "clusterIdentifierLabel": "cluster-link", "whatHappenedLabel": "what-happened", diff --git a/src/components/ControlPlane/MCPHealthPopoverButton.tsx b/src/components/ControlPlane/MCPHealthPopoverButton.tsx index c57c6395..373601f3 100644 --- a/src/components/ControlPlane/MCPHealthPopoverButton.tsx +++ b/src/components/ControlPlane/MCPHealthPopoverButton.tsx @@ -25,9 +25,9 @@ export default function MCPHealthPopoverButton({ mcpName, }: { mcpStatus: ControlPlaneStatusType | undefined; - projectName?: string; - workspaceName?: string; - mcpName?: string; + projectName: string; + workspaceName: string; + mcpName: string; }) { const popoverRef = useRef(null); const [open, setOpen] = useState(false); @@ -45,6 +45,19 @@ export default function MCPHealthPopoverButton({ } }; + const getTicketTitle = () => { + switch (mcpStatus?.status) { + case ReadyStatus.Ready: + return t('MCPHealthPopoverButton.supportTicketTitleReady'); + case ReadyStatus.NotReady: + return t('MCPHealthPopoverButton.supportTicketTitleNotReady'); + case ReadyStatus.InDeletion: + return t('MCPHealthPopoverButton.supportTicketTitleDeletion'); + default: + return t('MCPHealthPopoverButton.supportTicketTitleIssues'); + } + }; + const constructGithubIssuesLink = () => { const clusterDetails = `${projectName}/${workspaceName}/${mcpName}`; @@ -64,11 +77,7 @@ export default function MCPHealthPopoverButton({ const params = new URLSearchParams({ template: '1-mcp_issue.yml', - title: `[${clusterDetails}]: ${ - mcpStatus?.status === ReadyStatus.NotReady - ? t('MCPHealthPopoverButton.supportTicketTitle') - : t('MCPHealthPopoverButton.supportTicketTitleIssues') - }`, + title: `[${clusterDetails}]: ${getTicketTitle()}`, 'cluster-link': clusterDetails, 'what-happened': statusDetails, }); @@ -143,10 +152,6 @@ function StatusTable({ tableColumns: AnalyticalTableColumnDefinition[]; githubIssuesLink: string; }) { - const showSupportButton = - status?.status === ReadyStatus.NotReady || - status?.status === ReadyStatus.InDeletion; - const { t } = useTranslation(); return ( @@ -160,18 +165,16 @@ function StatusTable({ }) ?? [] } /> - {showSupportButton && ( - - - - - - )} + + + + + ); } diff --git a/src/components/ControlPlanes/ControlPlaneCard/ControlPlaneCard.tsx b/src/components/ControlPlanes/ControlPlaneCard/ControlPlaneCard.tsx index 93c9de69..c6aa7389 100644 --- a/src/components/ControlPlanes/ControlPlaneCard/ControlPlaneCard.tsx +++ b/src/components/ControlPlanes/ControlPlaneCard/ControlPlaneCard.tsx @@ -82,7 +82,12 @@ export function ControlPlaneCard({ alignItems="Center" className={styles.row} > - + - + From a3767bd1c1743a611af760879214bc8b7fb59b28 Mon Sep 17 00:00:00 2001 From: Fabian <108536371+fabianwolski@users.noreply.github.com> Date: Fri, 2 May 2025 18:52:49 +0100 Subject: [PATCH 5/5] Update public/locales/en.json Co-authored-by: Andreas Kienle --- public/locales/en.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/public/locales/en.json b/public/locales/en.json index 9a7e72e0..d81e383e 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -68,8 +68,6 @@ "supportTicketTitleNotReady": "MCP Not Ready", "supportTicketTitleDeletion": "MCP in Deletion", "supportTicketTitleIssues": "Issues with Control Plane", - "clusterIdentifierLabel": "cluster-link", - "whatHappenedLabel": "what-happened", "statusDetailsLabel": "MCP Status", "detailsLabel": "Details:" },