Skip to content

Commit f6936c5

Browse files
committed
feat: add MCP header
1 parent 99d7445 commit f6936c5

File tree

6 files changed

+95
-1
lines changed

6 files changed

+95
-1
lines changed

public/locales/en.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@
203203
"landscapersTitle": "Landscapers",
204204
"graphTitle": "Graph"
205205
},
206+
"McpHeader": {
207+
"nameLabel": "Name",
208+
"createdByLabel": "Created By",
209+
"createdOnLabel": "Created On"
210+
},
206211
"ToastContext": {
207212
"errorMessage": "useToast must be used within a ToastProvider"
208213
},

src/lib/api/types/crate/controlPlanes.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ export type ListControlPlanesType = ControlPlaneType;
55
export interface Metadata {
66
name: string;
77
namespace: string;
8+
creationTimestamp: string;
89
annotations: {
910
'openmcp.cloud/display-name': string;
11+
'openmcp.cloud/created-by': string;
1012
};
1113
}
1214

@@ -82,6 +84,6 @@ export const ControlPlane = (
8284
): Resource<ControlPlaneType> => {
8385
return {
8486
path: `/apis/core.openmcp.cloud/v1alpha1/namespaces/project-${projectName}--ws-${workspaceName}/managedcontrolplanes/${controlPlaneName}`,
85-
jq: '{ spec: .spec | {components}, metadata: .metadata | {name, namespace, annotations}, status: { conditions: [.status.conditions[] | {type: .type, status: .status, message: .message, reason: .reason, lastTransitionTime: .lastTransitionTime}], access: .status.components.authentication.access, status: .status.status }}',
87+
jq: '{ spec: .spec | {components}, metadata: .metadata | {name, namespace, creationTimestamp, annotations}, status: { conditions: [.status.conditions[] | {type: .type, status: .status, message: .message, reason: .reason, lastTransitionTime: .lastTransitionTime}], access: .status.components.authentication.access, status: .status.status }}',
8688
};
8789
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { McpHeader } from './McpHeader';
2+
import { ControlPlaneType } from '../../../lib/api/types/crate/controlPlanes.ts';
3+
4+
const mcp = {
5+
metadata: {
6+
name: 'my-control-plane',
7+
creationTimestamp: '2024-04-15T10:30:00.000Z',
8+
annotations: {
9+
'openmcp.cloud/created-by': '[email protected]',
10+
},
11+
},
12+
} as ControlPlaneType;
13+
14+
describe('McpHeader', () => {
15+
it('renders MCP matadata', () => {
16+
cy.clock(new Date('2024-04-17T10:30:00.000Z').getTime()); // 2 days after MCP creation date
17+
const creationDateAsString = new Date('2024-04-15T10:30:00.000Z').toLocaleDateString(undefined, {
18+
day: 'numeric',
19+
month: 'long',
20+
year: 'numeric',
21+
});
22+
23+
cy.mount(<McpHeader mcp={mcp} />);
24+
25+
cy.contains('span', 'my-control-plane').should('be.visible');
26+
cy.contains('span', '[email protected]').should('be.visible');
27+
cy.contains('span', `${creationDateAsString} (2 days ago)`).should('be.visible');
28+
});
29+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
.container {
2+
display: flex;
3+
}
4+
5+
.grid {
6+
display: grid;
7+
grid-template-columns: auto auto;
8+
gap: 6px 12px;
9+
align-items: center;
10+
font-size: var(--sapFontSize);
11+
}
12+
13+
.label {
14+
color: var(--sapContent_LabelColor);
15+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { ControlPlaneType } from '../../../lib/api/types/crate/controlPlanes.ts';
2+
3+
import styles from './McpHeader.module.css';
4+
import { formatDateAsTimeAgo } from '../../../utils/i18n/timeAgo.ts';
5+
import { useTranslation } from 'react-i18next';
6+
import { Button, Icon } from '@ui5/webcomponents-react';
7+
8+
export interface McpHeaderProps {
9+
mcp: ControlPlaneType;
10+
}
11+
12+
export function McpHeader({ mcp }: McpHeaderProps) {
13+
const { t } = useTranslation();
14+
15+
const created = new Date(mcp.metadata.creationTimestamp).toLocaleDateString(undefined, {
16+
day: 'numeric',
17+
month: 'long',
18+
year: 'numeric',
19+
});
20+
return (
21+
<div className={styles.container}>
22+
<div className={styles.grid}>
23+
<span className={styles.label}>{t('McpHeader.nameLabel')}</span>
24+
<span>{mcp.metadata.name}</span>
25+
26+
<span className={styles.label}>{t('McpHeader.createdOnLabel')}</span>
27+
<span>
28+
{created} ({formatDateAsTimeAgo(mcp.metadata.creationTimestamp)})
29+
</span>
30+
31+
<span className={styles.label}>{t('McpHeader.createdByLabel')}</span>
32+
<span>{mcp.metadata.annotations['openmcp.cloud/created-by']}</span>
33+
</div>
34+
</div>
35+
);
36+
}

src/spaces/mcp/pages/McpPage.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
Button,
44
FlexBox,
55
ObjectPage,
6+
ObjectPageHeader,
67
ObjectPageSection,
78
ObjectPageTitle,
89
Panel,
@@ -42,6 +43,7 @@ import { EditManagedControlPlaneWizardDataLoader } from '../../../components/Wiz
4243
import { ControlPlanePageMenu } from '../../../components/ControlPlanes/ControlPlanePageMenu.tsx';
4344
import { DISPLAY_NAME_ANNOTATION } from '../../../lib/api/types/shared/keyNames.ts';
4445
import { WizardStepType } from '../../../components/Wizards/CreateManagedControlPlane/CreateManagedControlPlaneWizardContainer.tsx';
46+
import { McpHeader } from '../components/McpHeader.tsx';
4547

4648
export default function McpPage() {
4749
const { projectName, workspaceName, controlPlaneName } = useParams();
@@ -126,6 +128,11 @@ export default function McpPage() {
126128
}
127129
/>
128130
}
131+
headerArea={
132+
<ObjectPageHeader>
133+
<McpHeader mcp={mcp} />
134+
</ObjectPageHeader>
135+
}
129136
>
130137
<ObjectPageSection
131138
className="cp-page-section-overview"

0 commit comments

Comments
 (0)