Skip to content

Commit 05a7b50

Browse files
Base
base before rebase
1 parent e2a675f commit 05a7b50

File tree

5 files changed

+172
-47
lines changed

5 files changed

+172
-47
lines changed

public/locales/en.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,16 @@
143143
},
144144
"main": {
145145
"failedMessage": "Failed to load frontend configuration"
146+
},
147+
"Providers": {
148+
"headerProviders": "Providers",
149+
"tableHeaderVersion": "Version",
150+
"tableHeaderName": "Name",
151+
"tableHeaderCreated": "Created",
152+
"tableHeaderInstalled": "Installed",
153+
"tableHeaderHealthy": "Healthy"
154+
},
155+
"ProvidersConfig": {
156+
"headerProvidersConfig": "Providers Config"
146157
}
147158
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
2+
import { useTranslation } from 'react-i18next';
3+
import { AnalyticalTable, AnalyticalTableColumnDefinition, AnalyticalTableScaleWidthMode, Icon, Title } from '@ui5/webcomponents-react';
4+
import useResource from '../../lib/api/useApiResource';
5+
import IllustratedError from '../Shared/IllustratedError';
6+
import '@ui5/webcomponents-icons/dist/sys-enter-2';
7+
import '@ui5/webcomponents-icons/dist/sys-cancel-2';
8+
import { ProvidersListRequest } from '../../lib/api/types/crossplane/listProviders';
9+
import ReactTimeAgo from 'react-time-ago';
10+
11+
interface CellData<T> {
12+
cell: {
13+
value: T | null;
14+
};
15+
}
16+
17+
export function Providers() {
18+
const { t } = useTranslation();
19+
20+
let {data: providers, error, isLoading} = useResource(ProvidersListRequest, {
21+
refreshInterval: 300000
22+
});
23+
24+
const columns: AnalyticalTableColumnDefinition[] = [
25+
{
26+
Header: t('Providers.tableHeaderName'),
27+
accessor: 'metadata.name',
28+
},
29+
{
30+
Header: t('Providers.tableHeaderVersion'),
31+
accessor: 'spec.package',
32+
Cell: (cellData: CellData<string>) => cellData.cell.value?.match(/\d+(\.\d+)+/)
33+
},
34+
{
35+
Header: t('Providers.tableHeaderInstalled'),
36+
accessor: 'status.conditions[1].status',
37+
Cell: (cellData: CellData<boolean>) => <ResourceStatusCell cellData={cellData}/>
38+
},
39+
//last.transitiontime on hover
40+
{
41+
Header: t('Providers.tableHeaderHealthy'),
42+
accessor: 'status.conditions[0].status',
43+
Cell: (cellData: CellData<boolean>) => <ResourceStatusCell cellData={cellData}/>
44+
},
45+
{
46+
Header: t('Providers.tableHeaderCreated'),
47+
accessor: 'metadata.creationTimestamp',
48+
Cell: (props: any) => <ReactTimeAgo date={new Date(props.cell.value)} />,
49+
},
50+
];
51+
52+
return (
53+
<>
54+
<Title level='H4'>{t('Providers.headerProviders')}</Title>
55+
56+
{error && <IllustratedError error={error}/>}
57+
58+
{!error &&
59+
<AnalyticalTable
60+
columns={columns}
61+
data={providers?.items ?? []}
62+
minRows={1}
63+
groupBy={['name']}
64+
scaleWidthMode={AnalyticalTableScaleWidthMode.Smart}
65+
loading={isLoading}
66+
filterable
67+
// Prevent the table from resetting when the data changes
68+
retainColumnWidth
69+
reactTableOptions={{
70+
autoResetHiddenColumns: false,
71+
autoResetPage: false,
72+
autoResetExpanded: false,
73+
autoResetGroupBy: false,
74+
autoResetSelectedRows: false,
75+
autoResetSortBy: false,
76+
autoResetFilters: false,
77+
autoResetRowState: false,
78+
autoResetResize: false
79+
}}
80+
/>
81+
}
82+
</>
83+
)
84+
}
85+
86+
interface ResourceStatusCellProps {
87+
cellData: CellData<boolean>;
88+
}
89+
90+
function ResourceStatusCell({ cellData }: ResourceStatusCellProps) {
91+
const { t } = useTranslation();
92+
93+
if (cellData.cell.value === null) {
94+
return null;
95+
}
96+
97+
return <Icon
98+
design={cellData.cell.value ? 'Positive' : 'Negative'}
99+
accessibleName={cellData.cell.value ? t('ManagedResources.iconAriaYes') : t('ManagedResources.iconAriaNo')}
100+
name={cellData.cell.value ? 'sys-enter-2' : 'sys-cancel-2'}
101+
/>
102+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
import { useTranslation } from 'react-i18next';
3+
import { AnalyticalTable, AnalyticalTableColumnDefinition, AnalyticalTableScaleWidthMode, Title } from '@ui5/webcomponents-react';
4+
import '@ui5/webcomponents-icons/dist/sys-enter-2';
5+
import '@ui5/webcomponents-icons/dist/sys-cancel-2';
6+
7+
export function ProvidersConfig() {
8+
const { t } = useTranslation();
9+
10+
const columns: AnalyticalTableColumnDefinition[] = [];
11+
12+
return (
13+
<>
14+
<Title level='H4'>{t('ProvidersConfig.headerProvidersConfig')}</Title>
15+
<AnalyticalTable
16+
columns={columns}
17+
data={[]}
18+
minRows={1}
19+
groupBy={['name']}
20+
scaleWidthMode={AnalyticalTableScaleWidthMode.Smart}
21+
loading={false}
22+
filterable
23+
// Prevent the table from resetting when the data changes
24+
retainColumnWidth
25+
reactTableOptions={{
26+
autoResetHiddenColumns: false,
27+
autoResetPage: false,
28+
autoResetExpanded: false,
29+
autoResetGroupBy: false,
30+
autoResetSelectedRows: false,
31+
autoResetSortBy: false,
32+
autoResetFilters: false,
33+
autoResetRowState: false,
34+
autoResetResize: false
35+
}}
36+
/>
37+
</>
38+
)
39+
}

src/components/ControlPlane/ProvidersList.tsx

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,12 @@
1-
import ConfiguredAnalyticstable from "../Shared/ConfiguredAnalyticsTable.tsx";
2-
import { AnalyticalTableColumnDefinition, Title } from "@ui5/webcomponents-react";
3-
import ReactTimeAgo from "react-time-ago";
4-
import IllustratedError from "../Shared/IllustratedError.tsx";
5-
import useResource from "../../lib/api/useApiResource";
6-
import { ListProviders } from "../../lib/api/types/crossplane/listProviders";
7-
import { useTranslation } from 'react-i18next';
1+
import { Providers } from "./Providers.tsx";
2+
import { ProvidersConfig } from "./ProvidersConfig.tsx";
83
import { ManagedResources } from './ManagedResources';
94

105
export default function ProvidersList() {
11-
const { data, error, isLoading } = useResource(ListProviders);
12-
const { t } = useTranslation();
13-
14-
if (error) {
15-
return <IllustratedError error={error} />;
16-
}
17-
18-
const columns: AnalyticalTableColumnDefinition[] = [
19-
{
20-
Header: t('ProvidersList.tableNameHeader'),
21-
accessor: "metadata.name",
22-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
23-
},
24-
{
25-
Header: t('ProvidersList.tableStatusHeader'),
26-
accessor: "status.phase",
27-
},
28-
{
29-
Header: t('ProvidersList.tableCreatedHeader'),
30-
accessor: "metadata.creationTimestamp",
31-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
32-
Cell: (props: any) => <ReactTimeAgo date={new Date(props.cell.value)} />,
33-
},
34-
];
35-
366
return (
377
<>
38-
<Title level="H4">Providers</Title>
39-
<ConfiguredAnalyticstable
40-
columns={columns}
41-
isLoading={isLoading}
42-
data={data ?? []}
43-
/>
44-
<Title level="H2">ProviderConfigs</Title>
45-
<ConfiguredAnalyticstable
46-
columns={columns}
47-
data={[]}
48-
/>
49-
8+
<Providers />
9+
<ProvidersConfig />
5010
<ManagedResources />
5111
</>
5212
);
Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
11
import { Resource } from "../resource";
22

3-
//TODO: type any to correct type and adapt the jq query to the required paramters
4-
export const ListProviders: Resource<any> = {
3+
export type ProvidersListResponse = {
4+
items: [{
5+
kind: string;
6+
metadata: {
7+
name: string;
8+
creationTimestamp: string;
9+
};
10+
status: {
11+
conditions: [{
12+
type: "Ready" | "Synced" | unknown;
13+
}]
14+
};
15+
}];
16+
};
17+
18+
export const ProvidersListRequest: Resource<ProvidersListResponse> = {
519
path: "/apis/pkg.crossplane.io/v1/providers",
6-
jq: "[.items[]]",
720
};

0 commit comments

Comments
 (0)