Skip to content

Commit 29dfd6e

Browse files
flux list display
1 parent a909ae1 commit 29dfd6e

File tree

5 files changed

+190
-28
lines changed

5 files changed

+190
-28
lines changed

public/locales/en.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
"FluxList": {
1313
"tableNameHeader": "Name",
1414
"tableStatusHeader": "Status",
15-
"tableCreatedHeader": "Created"
15+
"tableCreatedHeader": "Created",
16+
"tableVersionHeader": "Revision",
17+
"noFluxError": "Please install flux to view this component",
18+
"gitOpsTitle": "GitOps",
19+
"kustomizationsTitle": "Kustomizations"
1620
},
1721
"ProvidersList": {
1822
"tableNameHeader": "Name",

src/components/ControlPlane/FluxList.tsx

Lines changed: 120 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ import {
33
AnalyticalTableColumnDefinition,
44
Title,
55
} from '@ui5/webcomponents-react';
6-
import ReactTimeAgo from 'react-time-ago';
76
import IllustratedError from '../Shared/IllustratedError.tsx';
87
import useResource from '../../lib/api/useApiResource';
9-
import { FluxGitRepo } from '../../lib/api/types/flux/listGitRepo';
8+
import { FluxRequest } from '../../lib/api/types/flux/listGitRepo';
109
import { FluxKustomization } from '../../lib/api/types/flux/listKustomization';
1110
import { useTranslation } from 'react-i18next';
11+
import { timeAgo } from '../../utils/i18n/timeAgo.ts';
12+
import { ResourceStatusCell } from '../Shared/ResourceStatusCell.tsx';
13+
import { shortenCommitHash } from '../../lib/api/types/shared/helpers.ts';
1214

1315
export default function FluxList() {
1416
const {
15-
data: repoData,
17+
data: gitReposData,
1618
error: repoErr,
1719
isLoading: repoIsLoading,
18-
} = useResource(FluxGitRepo); //404 if component not enabled
20+
} = useResource(FluxRequest); //404 if component not enabled
1921
const {
2022
data: kustmizationData,
2123
error: kustomizationErr,
@@ -24,43 +26,138 @@ export default function FluxList() {
2426

2527
const { t } = useTranslation();
2628

29+
interface CellData<T> {
30+
cell: {
31+
value: T | null; // null for grouping rows
32+
row: {
33+
original?: FluxRows; // missing for grouping rows
34+
};
35+
};
36+
}
37+
38+
type FluxRows = {
39+
name: string;
40+
created: string;
41+
status: boolean;
42+
statusUptadeTime?: string;
43+
};
44+
2745
if (repoErr) {
28-
return <IllustratedError error={repoErr} />;
46+
return (
47+
<IllustratedError error={repoErr} title={t('FluxList.noFluxError')} />
48+
);
2949
}
3050
if (kustomizationErr) {
31-
return <IllustratedError error={kustomizationErr} />;
51+
return (
52+
<IllustratedError
53+
error={kustomizationErr}
54+
title={t('FluxList.noFluxError')}
55+
/>
56+
);
3257
}
3358

34-
const columns: AnalyticalTableColumnDefinition[] = [
59+
const gitReposColumns: AnalyticalTableColumnDefinition[] = [
3560
{
3661
Header: t('FluxList.tableNameHeader'),
37-
accessor: 'metadata.name',
62+
accessor: 'name',
3863
},
3964
{
4065
Header: t('FluxList.tableStatusHeader'),
41-
accessor: 'status.usages',
66+
accessor: 'status',
67+
Cell: (cellData: CellData<FluxRows['status']>) =>
68+
cellData.cell.row.original?.status != null ? (
69+
<ResourceStatusCell
70+
value={cellData.cell.row.original?.status}
71+
transitionTime={
72+
cellData.cell.row.original?.statusUptadeTime
73+
? cellData.cell.row.original?.statusUptadeTime
74+
: ''
75+
}
76+
/>
77+
) : null,
78+
},
79+
{
80+
Header: t('FluxList.tableVersionHeader'),
81+
accessor: 'revision',
4282
},
4383
{
4484
Header: t('FluxList.tableCreatedHeader'),
45-
accessor: 'metadata.creationTimestamp',
46-
Cell: (props: any) => <ReactTimeAgo date={new Date(props.cell.value)} />,
85+
accessor: 'created',
4786
},
4887
];
4988

89+
const kustomizationsColumns: AnalyticalTableColumnDefinition[] = [
90+
{
91+
Header: t('FluxList.tableNameHeader'),
92+
accessor: 'name',
93+
},
94+
{
95+
Header: t('FluxList.tableStatusHeader'),
96+
accessor: 'status',
97+
Cell: (cellData: CellData<FluxRows['status']>) =>
98+
cellData.cell.row.original?.status != null ? (
99+
<ResourceStatusCell
100+
value={cellData.cell.row.original?.status}
101+
transitionTime={
102+
cellData.cell.row.original?.statusUptadeTime
103+
? cellData.cell.row.original?.statusUptadeTime
104+
: ''
105+
}
106+
/>
107+
) : null,
108+
},
109+
{
110+
Header: t('FluxList.tableCreatedHeader'),
111+
accessor: 'created',
112+
},
113+
];
114+
115+
const gitReposRows: FluxRows[] =
116+
gitReposData?.items?.map((item) => {
117+
return {
118+
name: item.metadata.name,
119+
status:
120+
item.status.conditions.find((x) => x.type === 'Ready')?.status ===
121+
'True',
122+
statusUptadeTime: item.status.conditions.find((x) => x.type === 'Ready')
123+
?.lastTransitionTime,
124+
revision: shortenCommitHash(item.status.artifact.revision),
125+
created: timeAgo.format(new Date(item.metadata.creationTimestamp)),
126+
};
127+
}) ?? [];
128+
129+
const kustomizationsRows: FluxRows[] =
130+
kustmizationData?.items?.map((item) => {
131+
return {
132+
name: item.metadata.name,
133+
status:
134+
item.status.conditions.find((x) => x.type === 'Ready')?.status ===
135+
'True',
136+
statusUptadeTime: item.status.conditions.find((x) => x.type === 'Ready')
137+
?.lastTransitionTime,
138+
created: timeAgo.format(new Date(item.metadata.creationTimestamp)),
139+
};
140+
}) ?? [];
141+
50142
return (
51143
<>
52-
<Title level="H4">Git Repos</Title>
53-
<ConfiguredAnalyticstable
54-
columns={columns}
55-
isLoading={repoIsLoading}
56-
data={repoData ?? []}
57-
/>
58-
<Title level="H4">Kustomizations</Title>
59-
<ConfiguredAnalyticstable
60-
columns={columns}
61-
isLoading={kustomizationIsLoading}
62-
data={kustmizationData ?? []}
63-
/>
144+
{' '}
145+
<div className="crossplane-table-element">
146+
<Title level="H4">{t('FluxList.gitOpsTitle')}</Title>
147+
<ConfiguredAnalyticstable
148+
columns={gitReposColumns}
149+
isLoading={repoIsLoading}
150+
data={gitReposRows}
151+
/>
152+
</div>
153+
<div className="crossplane-table-element">
154+
<Title level="H4">{t('FluxList.kustomizationsTitle')}</Title>
155+
<ConfiguredAnalyticstable
156+
columns={kustomizationsColumns}
157+
isLoading={kustomizationIsLoading}
158+
data={kustomizationsRows}
159+
/>
160+
</div>
64161
</>
65162
);
66163
}
Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
11
import { Resource } from '../resource';
22

3-
export const FluxGitRepo: Resource<any> = {
3+
export type GitReposResponse = {
4+
items: [
5+
{
6+
spec: {
7+
package: string;
8+
};
9+
kind: string;
10+
metadata: {
11+
name: string;
12+
creationTimestamp: string;
13+
};
14+
status: {
15+
artifact: {
16+
revision: string;
17+
};
18+
conditions: [
19+
{
20+
status: string;
21+
type: string;
22+
lastTransitionTime: string;
23+
},
24+
];
25+
};
26+
},
27+
];
28+
};
29+
30+
export const FluxRequest: Resource<GitReposResponse> = {
431
path: '/apis/source.toolkit.fluxcd.io/v1/gitrepositories',
5-
jq: '[.items[]]',
632
};
Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
11
import { Resource } from '../resource';
22

3-
export const FluxKustomization: Resource<any> = {
3+
export type KustomizationsResponse = {
4+
items: [
5+
{
6+
spec: {
7+
package: string;
8+
};
9+
kind: string;
10+
metadata: {
11+
name: string;
12+
creationTimestamp: string;
13+
};
14+
status: {
15+
artifact: {
16+
revision: string;
17+
};
18+
conditions: [
19+
{
20+
status: string;
21+
type: string;
22+
lastTransitionTime: string;
23+
},
24+
];
25+
};
26+
},
27+
];
28+
};
29+
30+
export const FluxKustomization: Resource<KustomizationsResponse> = {
431
path: '/apis/kustomize.toolkit.fluxcd.io/v1/kustomizations',
5-
jq: '[.items[]]',
632
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export function shortenCommitHash(commitHash: string): string {
2+
const match = commitHash.match(/^([a-zA-Z0-9-_]+)@sha1:([a-f0-9]{40})/);
3+
4+
if (match && match[2]) {
5+
return `${match[1]}@${match[2].slice(0, 7)}`;
6+
}
7+
8+
return commitHash;
9+
}

0 commit comments

Comments
 (0)