Skip to content
Merged
2 changes: 1 addition & 1 deletion frontend-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
"issuerUrl": "issuer-url",
"scopes": []
}
}
}
9 changes: 8 additions & 1 deletion public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@
"typeHeader": "Type",
"messageHeader": "Message",
"reasonHeader": "Reason",
"transitionHeader": "Last transition time"
"transitionHeader": "Last transition time",
"createSupportTicketButton": "Create Support Ticket",
"supportTicketTitleReady": "MCP Ready",
"supportTicketTitleNotReady": "MCP Not Ready",
"supportTicketTitleDeletion": "MCP in Deletion",
"supportTicketTitleIssues": "Issues with Control Plane",
"statusDetailsLabel": "MCP Status",
"detailsLabel": "Details:"
},
"CopyKubeconfigButton": {
"copiedMessage": "Copied to Clipboard",
Expand Down
80 changes: 77 additions & 3 deletions src/components/ControlPlane/MCPHealthPopoverButton.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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();

Expand All @@ -31,6 +45,46 @@ 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}`;

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: '1-mcp_issue.yml',
title: `[${clusterDetails}]: ${getTicketTitle()}`,
'cluster-link': clusterDetails,
'what-happened': statusDetails,
});

return `${links.COM_PAGE_SUPPORT_GITHUB_ISSUE}?${params}`;
};

const statusTableColumns: AnalyticalTableColumnDefinition[] = [
{
Header: t('MCPHealthPopoverButton.statusHeader'),
Expand Down Expand Up @@ -77,7 +131,13 @@ export default function MCPHealthPopoverButton({
onClick={handleOpenerClick}
/>
<Popover ref={popoverRef} open={open} placement={PopoverPlacement.Bottom}>
{<StatusTable status={mcpStatus} tableColumns={statusTableColumns} />}
{
<StatusTable
status={mcpStatus}
tableColumns={statusTableColumns}
githubIssuesLink={constructGithubIssuesLink()}
/>
}
</Popover>
</div>
);
Expand All @@ -86,10 +146,14 @@ export default function MCPHealthPopoverButton({
function StatusTable({
status,
tableColumns,
githubIssuesLink,
}: {
status: ControlPlaneStatusType | undefined;
tableColumns: AnalyticalTableColumnDefinition[];
githubIssuesLink: string;
}) {
const { t } = useTranslation();

return (
<div style={{ width: 600 }}>
<AnalyticalTable
Expand All @@ -101,6 +165,16 @@ function StatusTable({
}) ?? []
}
/>
<FlexBox
justifyContent={FlexBoxJustifyContent.End}
style={{ marginTop: '0.5rem' }}
>
<a href={githubIssuesLink} target="_blank" rel="noreferrer">
<Button>
{t('MCPHealthPopoverButton.createSupportTicketButton')}
</Button>
</a>
</FlexBox>
</div>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,12 @@ export function ControlPlaneCard({
alignItems="Center"
className={styles.row}
>
<MCPHealthPopoverButton mcpStatus={controlPlane.status} />
<MCPHealthPopoverButton
mcpStatus={controlPlane.status}
projectName={projectName}
workspaceName={workspace.metadata.name ?? ''}
mcpName={controlPlane.metadata.name}
/>
<FlexBox
direction="Row"
justifyContent="SpaceBetween"
Expand Down
10 changes: 7 additions & 3 deletions src/context/FrontendConfigContext.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ReactNode, createContext, use } from 'react';
import { DocLinkCreator } from '../lib/shared/links';
import { LinkCreator } from '../lib/shared/links';
import { z } from 'zod';

export enum Landscape {
Expand All @@ -11,7 +11,7 @@ export enum Landscape {
}

interface FrontendConfigContextType extends FrontendConfig {
links: DocLinkCreator;
links: LinkCreator;
}

export const FrontendConfigContext =
Expand All @@ -29,7 +29,10 @@ 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: FrontendConfigContextType = {
links: docLinks,
...config,
Expand Down Expand Up @@ -61,6 +64,7 @@ const FrontendConfigSchema = z.object({
backendUrl: z.string(),
gatewayUrl: z.string(),
documentationBaseUrl: z.string(),
githubBaseUrl: z.string(),
oidcConfig: OidcConfigSchema,
landscape: z.optional(z.nativeEnum(Landscape)),
});
Expand Down
13 changes: 11 additions & 2 deletions src/lib/shared/links.ts
Original file line number Diff line number Diff line change
@@ -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 || baseUrl;
}
private createLink(path: string) {
return `${this.baseUrl}${path}`;
}

private createGithubLink(path: string) {
return `${this.githubBaseUrl}${path}`;
}

public get COMMUNITY_PAGE(): string {
return this.createLink('/');
}
Expand All @@ -26,4 +32,7 @@ export class DocLinkCreator {
'/docs/managed-control-planes/get-started/get-started-mcp#5-create-managedcontrolplane',
);
}
public get COM_PAGE_SUPPORT_GITHUB_ISSUE(): string {
return this.createGithubLink('/support/issues/new');
}
}
4 changes: 2 additions & 2 deletions src/utils/testing.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
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;
Expand All @@ -7,5 +7,5 @@ export const mockedFrontendConfig = {
backendUrl: 'http://localhost:3000',
landscape: Landscape.Local,
documentationBaseUrl: 'http://localhost:3000',
links: new DocLinkCreator(documentationBaseUrl),
links: new LinkCreator(documentationBaseUrl),
};
7 changes: 6 additions & 1 deletion src/views/ControlPlanes/ControlPlaneView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ export default function ControlPlaneView() {
justifyContent: 'space-between',
}}
>
<MCPHealthPopoverButton mcpStatus={mcp?.status} />
<MCPHealthPopoverButton
mcpStatus={mcp?.status}
projectName={projectName}
workspaceName={workspaceName ?? ''}
mcpName={controlPlaneName}
/>

<CopyKubeconfigButton />
</div>
Expand Down
Loading