Skip to content

Commit c1c13e4

Browse files
Merge branch 'main' into feature/kubectl-command-helper-dialogs
2 parents a37d028 + 32343cd commit c1c13e4

File tree

15 files changed

+407
-123
lines changed

15 files changed

+407
-123
lines changed

public/locales/en.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@
2727
"tableHeaderSynced": "Synced",
2828
"tableHeaderReady": "Ready"
2929
},
30+
"ProvidersConfig": {
31+
"headerProviderConfigs": "Provider Configs",
32+
"tableHeaderProvider": "Provider",
33+
"tableHeaderName": "Name",
34+
"tableHeaderCreated": "Created",
35+
"tableHeaderUsage": "Usage"
36+
},
3037
"ControlPlaneListToolbar": {
3138
"buttonText": "Workspace"
3239
},
@@ -222,9 +229,6 @@
222229
"tableHeaderInstalled": "Installed",
223230
"tableHeaderHealthy": "Healthy"
224231
},
225-
"ProvidersConfig": {
226-
"header": "Provider Configs"
227-
},
228232
"validationErrors": {
229233
"required": "This field is required!",
230234
"properFormatting": "Use A-Z, a-z, 0-9, hyphen (-), and period (.), but note that whitespace (spaces, tabs, etc.) is not allowed for proper compatibility.",

src/components/ControlPlane/ComponentList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export default function ComponentList({ mcp }: { mcp: ControlPlaneType }) {
4949
columns={componentTableColumns}
5050
minRows={0}
5151
data={data}
52-
style={{marginLeft: "12px", marginRight: "12px"}}
52+
style={{ marginLeft: '12px', marginRight: '12px' }}
5353
/>
5454
</div>
5555
);

src/components/ControlPlane/ManagedResources.tsx

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
AnalyticalTable,
44
AnalyticalTableColumnDefinition,
55
AnalyticalTableScaleWidthMode,
6-
Icon,
76
Title,
87
} from '@ui5/webcomponents-react';
98
import useResource from '../../lib/api/useApiResource';
@@ -13,7 +12,7 @@ import IllustratedError from '../Shared/IllustratedError';
1312
import '@ui5/webcomponents-icons/dist/sys-enter-2';
1413
import '@ui5/webcomponents-icons/dist/sys-cancel-2';
1514
import { resourcesInterval } from '../../lib/shared/constants';
16-
import { StatusCellProps } from '../../lib/shared/interfaces';
15+
import { ResourceStatusCell } from '../Shared/ResourceStatusCell';
1716

1817
interface CellData<T> {
1918
cell: {
@@ -140,14 +139,3 @@ export function ManagedResources() {
140139
</>
141140
);
142141
}
143-
144-
function ResourceStatusCell({ value, transitionTime }: StatusCellProps) {
145-
return (
146-
<Icon
147-
design={value ? 'Positive' : 'Negative'}
148-
name={value ? 'sys-enter-2' : 'sys-cancel-2'}
149-
showTooltip={true}
150-
accessibleName={timeAgo.format(new Date(transitionTime))}
151-
/>
152-
);
153-
}
Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,47 @@
1-
21
import { useTranslation } from 'react-i18next';
3-
import { AnalyticalTable, AnalyticalTableColumnDefinition, AnalyticalTableScaleWidthMode, Icon, Title } from '@ui5/webcomponents-react';
2+
import {
3+
AnalyticalTable,
4+
AnalyticalTableColumnDefinition,
5+
AnalyticalTableScaleWidthMode,
6+
Title,
7+
} from '@ui5/webcomponents-react';
48
import useResource from '../../lib/api/useApiResource';
59
import IllustratedError from '../Shared/IllustratedError';
610
import '@ui5/webcomponents-icons/dist/sys-enter-2';
711
import '@ui5/webcomponents-icons/dist/sys-cancel-2';
812
import { ProvidersListRequest } from '../../lib/api/types/crossplane/listProviders';
913
import { resourcesInterval } from '../../lib/shared/constants';
1014
import { timeAgo } from '../../utils/i18n/timeAgo';
11-
import { StatusCellProps } from '../../lib/shared/interfaces';
15+
import { ResourceStatusCell } from '../Shared/ResourceStatusCell';
1216

1317
interface CellData<T> {
1418
cell: {
1519
value: T | null; // null for grouping rows
1620
row: {
1721
original?: ProvidersRow; // missing for grouping rows
18-
}
22+
};
1923
};
2024
}
2125

2226
type ProvidersRow = {
23-
name: string
27+
name: string;
2428
version: string;
2529
healthy: boolean;
2630
healthyTransitionTime: string;
2731
installed: boolean;
2832
installedTransitionTime: string;
2933
created: string;
30-
}
34+
};
3135

3236
export function Providers() {
3337
const { t } = useTranslation();
3438

35-
let {data: providers, error, isLoading} = useResource(ProvidersListRequest, {
36-
refreshInterval: resourcesInterval
39+
const {
40+
data: providers,
41+
error,
42+
isLoading,
43+
} = useResource(ProvidersListRequest, {
44+
refreshInterval: resourcesInterval,
3745
});
3846

3947
const columns: AnalyticalTableColumnDefinition[] = [
@@ -48,12 +56,24 @@ export function Providers() {
4856
{
4957
Header: t('Providers.tableHeaderInstalled'),
5058
accessor: 'installed',
51-
Cell: (cellData: CellData<ProvidersRow['installed']>) => cellData.cell.row.original?.installed != null ? <ResourceStatusCell value={cellData.cell.row.original?.installed} transitionTime={cellData.cell.row.original?.installedTransitionTime} /> : null
59+
Cell: (cellData: CellData<ProvidersRow['installed']>) =>
60+
cellData.cell.row.original?.installed != null ? (
61+
<ResourceStatusCell
62+
value={cellData.cell.row.original?.installed}
63+
transitionTime={cellData.cell.row.original?.installedTransitionTime}
64+
/>
65+
) : null,
5266
},
5367
{
5468
Header: t('Providers.tableHeaderHealthy'),
5569
accessor: 'healthy',
56-
Cell: (cellData: CellData<ProvidersRow['healthy']>) => cellData.cell.row.original?.installed != null ? <ResourceStatusCell value={cellData.cell.row.original?.healthy} transitionTime={cellData.cell.row.original?.healthyTransitionTime} /> : null
70+
Cell: (cellData: CellData<ProvidersRow['healthy']>) =>
71+
cellData.cell.row.original?.installed != null ? (
72+
<ResourceStatusCell
73+
value={cellData.cell.row.original?.healthy}
74+
transitionTime={cellData.cell.row.original?.healthyTransitionTime}
75+
/>
76+
) : null,
5777
},
5878
{
5979
Header: t('Providers.tableHeaderCreated'),
@@ -63,28 +83,31 @@ export function Providers() {
6383

6484
const rows: ProvidersRow[] =
6585
providers?.items?.map((item) => {
66-
const installed = item.status.conditions?.find((condition) => condition.type === 'Installed');
67-
const healthy = item.status.conditions?.find((condition) => condition.type === 'Healthy');
86+
const installed = item.status.conditions?.find(
87+
(condition) => condition.type === 'Installed',
88+
);
89+
const healthy = item.status.conditions?.find(
90+
(condition) => condition.type === 'Healthy',
91+
);
6892

6993
return {
7094
name: item.metadata.name,
7195
created: timeAgo.format(new Date(item.metadata.creationTimestamp)),
72-
installed: installed?.status === "True",
73-
installedTransitionTime: installed?.lastTransitionTime ?? "",
74-
healthy: healthy?.status === "True",
75-
healthyTransitionTime: healthy?.lastTransitionTime ?? "",
76-
version: item.spec.package.match(/\d+(\.\d+)+/g)?.toString() ?? "",
77-
}
78-
})
79-
?? [];
96+
installed: installed?.status === 'True',
97+
installedTransitionTime: installed?.lastTransitionTime ?? '',
98+
healthy: healthy?.status === 'True',
99+
healthyTransitionTime: healthy?.lastTransitionTime ?? '',
100+
version: item.spec.package.match(/\d+(\.\d+)+/g)?.toString() ?? '',
101+
};
102+
}) ?? [];
80103

81104
return (
82105
<>
83-
<Title level='H4'>{t('Providers.headerProviders')}</Title>
106+
<Title level="H4">{t('Providers.headerProviders')}</Title>
84107

85-
{error && <IllustratedError error={error}/>}
108+
{error && <IllustratedError error={error} />}
86109

87-
{!error &&
110+
{!error && (
88111
<AnalyticalTable
89112
columns={columns}
90113
data={rows}
@@ -103,19 +126,10 @@ export function Providers() {
103126
autoResetSortBy: false,
104127
autoResetFilters: false,
105128
autoResetRowState: false,
106-
autoResetResize: false
129+
autoResetResize: false,
107130
}}
108131
/>
109-
}
132+
)}
110133
</>
111-
)
112-
}
113-
114-
function ResourceStatusCell({ value, transitionTime }: StatusCellProps) {
115-
return <Icon
116-
design={value ? 'Positive' : 'Negative'}
117-
name={value ? 'sys-enter-2' : 'sys-cancel-2'}
118-
showTooltip={true}
119-
accessibleName={timeAgo.format(new Date(transitionTime))}
120-
/>
134+
);
121135
}
Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,87 @@
1-
21
import { useTranslation } from 'react-i18next';
3-
import { AnalyticalTable, AnalyticalTableColumnDefinition, AnalyticalTableScaleWidthMode, Title } from '@ui5/webcomponents-react';
2+
import {
3+
AnalyticalTable,
4+
AnalyticalTableColumnDefinition,
5+
AnalyticalTableScaleWidthMode,
6+
Title,
7+
} from '@ui5/webcomponents-react';
48
import '@ui5/webcomponents-icons/dist/sys-enter-2';
59
import '@ui5/webcomponents-icons/dist/sys-cancel-2';
10+
import { useProvidersConfigResource } from '../../lib/api/useApiResource';
11+
import { timeAgo } from '../../utils/i18n/timeAgo';
12+
13+
type Rows = {
14+
parent: string;
15+
name: string;
16+
usage: string;
17+
created: string;
18+
};
619

7-
//empty table TBD
820
export function ProvidersConfig() {
921
const { t } = useTranslation();
22+
const rows: Rows[] = [];
23+
24+
const { data: providerConfigsList, isLoading } = useProvidersConfigResource({
25+
refreshInterval: 60000, // Resources are quite expensive to fetch, so we refresh every 60 seconds
26+
});
27+
28+
if (providerConfigsList) {
29+
providerConfigsList.forEach((provider) => {
30+
provider.items.forEach((config) => {
31+
rows.push({
32+
parent: provider.provider,
33+
name: config.metadata.name,
34+
usage: config.metadata.usage ? config.metadata.usage : '0',
35+
created: timeAgo.format(new Date(config.metadata.creationTimestamp)),
36+
});
37+
});
38+
});
39+
}
1040

11-
const columns: AnalyticalTableColumnDefinition[] = [];
41+
const columns: AnalyticalTableColumnDefinition[] = [
42+
{
43+
Header: t('ProvidersConfig.tableHeaderProvider'),
44+
accessor: 'parent',
45+
},
46+
{
47+
Header: t('ProvidersConfig.tableHeaderName'),
48+
accessor: 'name',
49+
},
50+
{
51+
Header: t('ProvidersConfig.tableHeaderUsage'),
52+
accessor: 'usage',
53+
},
54+
{
55+
Header: t('ProvidersConfig.tableHeaderCreated'),
56+
accessor: 'created',
57+
},
58+
];
1259

1360
return (
1461
<>
15-
<Title level='H4'>{t('ProvidersConfig.header')}</Title>
16-
<AnalyticalTable
17-
columns={columns}
18-
data={[]}
19-
minRows={1}
20-
groupBy={['name']}
21-
scaleWidthMode={AnalyticalTableScaleWidthMode.Smart}
22-
loading={false}
23-
filterable
24-
// Prevent the table from resetting when the data changes
25-
retainColumnWidth
26-
reactTableOptions={{
27-
autoResetHiddenColumns: false,
28-
autoResetPage: false,
29-
autoResetExpanded: false,
30-
autoResetGroupBy: false,
31-
autoResetSelectedRows: false,
32-
autoResetSortBy: false,
33-
autoResetFilters: false,
34-
autoResetRowState: false,
35-
autoResetResize: false
36-
}}
37-
/>
62+
<Title level="H4">{t('ProvidersConfig.headerProviderConfigs')}</Title>
63+
<AnalyticalTable
64+
columns={columns}
65+
data={rows ?? []}
66+
minRows={1}
67+
groupBy={['parent']}
68+
scaleWidthMode={AnalyticalTableScaleWidthMode.Smart}
69+
loading={isLoading}
70+
filterable
71+
// Prevent the table from resetting when the data changes
72+
retainColumnWidth
73+
reactTableOptions={{
74+
autoResetHiddenColumns: false,
75+
autoResetPage: false,
76+
autoResetExpanded: false,
77+
autoResetGroupBy: false,
78+
autoResetSelectedRows: false,
79+
autoResetSortBy: false,
80+
autoResetFilters: false,
81+
autoResetRowState: false,
82+
autoResetResize: false,
83+
}}
84+
/>
3885
</>
39-
)
86+
);
4087
}

src/components/ControlPlane/ProvidersList.tsx

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
1-
import { Toolbar, ToolbarButton } from "@ui5/webcomponents-react";
2-
import { useState } from "react";
1+
import { Toolbar, ToolbarButton } from '@ui5/webcomponents-react';
2+
import { useState } from 'react';
33
import { useTranslation } from 'react-i18next';
4-
import {CreateWorkspaceDialogContainer} from "../../Dialogs/CreateWorkspaceDialogContainer.tsx";
4+
import { CreateWorkspaceDialogContainer } from '../../Dialogs/CreateWorkspaceDialogContainer.tsx';
55

6-
7-
8-
export function ControlPlaneListToolbar({ projectName }: { projectName: string }) {
6+
export function ControlPlaneListToolbar({
7+
projectName,
8+
}: {
9+
projectName: string;
10+
}) {
911
const [dialogCreateProjectIsOpen, setDialogIsOpen] = useState(false);
1012
const { t } = useTranslation();
1113

1214
return (
1315
<>
1416
<Toolbar>
15-
<ToolbarButton icon="add" text={t('ControlPlaneListToolbar.buttonText')} onClick={() => setDialogIsOpen(true)} />
17+
<ToolbarButton
18+
icon="add"
19+
text={t('ControlPlaneListToolbar.buttonText')}
20+
onClick={() => setDialogIsOpen(true)}
21+
/>
1622
</Toolbar>
17-
<CreateWorkspaceDialogContainer isOpen={dialogCreateProjectIsOpen} setIsOpen={setDialogIsOpen} project={projectName}/>
23+
<CreateWorkspaceDialogContainer
24+
isOpen={dialogCreateProjectIsOpen}
25+
setIsOpen={setDialogIsOpen}
26+
project={projectName}
27+
/>
1828
</>
19-
)
20-
21-
}
29+
);
30+
}

0 commit comments

Comments
 (0)