Skip to content

Commit 940c0c5

Browse files
linter issues + adding command to package.json
1 parent 9669463 commit 940c0c5

File tree

8 files changed

+54
-171
lines changed

8 files changed

+54
-171
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"start": "node server.js",
1212
"build": "tsc && vite build",
1313
"lint": "eslint ./src --report-unused-disable-directives --max-warnings 0",
14+
"lint:fix": "eslint ./src --fix",
1415
"preview": "vite preview",
1516
"test:vi": "vitest",
1617
"test:cy": "cypress run --component --browser chrome",

src/components/Graphs/CustomNode.tsx

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,9 @@ import { CustomNodeProps } from './types';
77
import styles from './CustomNode.module.css';
88

99
const CustomNode: React.FC<CustomNodeProps> = ({ data }) => (
10-
<div
11-
className={styles.nodeContainer}
12-
style={{ fontFamily: ThemingParameters.sapFontFamily }}
13-
>
14-
<Handle
15-
type="target"
16-
position={Position.Top}
17-
style={{ visibility: 'hidden' }}
18-
/>
19-
<Handle
20-
type="source"
21-
position={Position.Bottom}
22-
style={{ visibility: 'hidden' }}
23-
/>
10+
<div className={styles.nodeContainer} style={{ fontFamily: ThemingParameters.sapFontFamily }}>
11+
<Handle type="target" position={Position.Top} style={{ visibility: 'hidden' }} />
12+
<Handle type="source" position={Position.Bottom} style={{ visibility: 'hidden' }} />
2413
<div className={styles.nodeContent}>
2514
<StatusIcon status={data.status} />
2615
<div className={styles.nodeTextContainer}>

src/components/Graphs/Graph.tsx

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,14 @@ import {
1313
import styles from './Graph.module.css';
1414
import dagre from 'dagre';
1515
import 'reactflow/dist/style.css';
16-
import {
17-
useApiResource,
18-
useProvidersConfigResource,
19-
} from '../../lib/api/useApiResource';
16+
import { useApiResource, useProvidersConfigResource } from '../../lib/api/useApiResource';
2017
import { ManagedResourcesRequest } from '../../lib/api/types/crossplane/listManagedResources';
2118
import { resourcesInterval } from '../../lib/shared/constants';
2219
import { ThemingParameters } from '@ui5/webcomponents-react-base';
2320
import { NodeData, ManagedResourceGroup, ManagedResourceItem } from './types';
2421
import CustomNode from './CustomNode';
2522
import { Legend } from './Legend';
26-
import {
27-
extractRefs,
28-
generateColorMap,
29-
getStatusFromConditions,
30-
resolveProviderType,
31-
} from './graphUtils';
23+
import { extractRefs, generateColorMap, getStatusFromConditions, resolveProviderType } from './graphUtils';
3224

3325
const nodeWidth = 250;
3426
const nodeHeight = 60;
@@ -48,8 +40,7 @@ function buildGraph(
4840

4941
const nodeMap: Record<string, Node<NodeData>> = {};
5042
treeData.forEach((n) => {
51-
const colorKey =
52-
colorBy === 'source' ? n.providerType : n.providerConfigName;
43+
const colorKey = colorBy === 'source' ? n.providerType : n.providerConfigName;
5344
const node: Node<NodeData> = {
5445
id: n.id,
5546
type: 'custom',
@@ -105,14 +96,12 @@ function buildGraph(
10596
}
10697

10798
const Graph: React.FC = () => {
108-
const { data: managedResources, error: managedResourcesError } =
109-
useApiResource(ManagedResourcesRequest, {
110-
refreshInterval: resourcesInterval,
111-
});
112-
const { data: providerConfigsList, error: providerConfigsError } =
113-
useProvidersConfigResource({
114-
refreshInterval: resourcesInterval,
115-
});
99+
const { data: managedResources, error: managedResourcesError } = useApiResource(ManagedResourcesRequest, {
100+
refreshInterval: resourcesInterval,
101+
});
102+
const { data: providerConfigsList, error: providerConfigsError } = useProvidersConfigResource({
103+
refreshInterval: resourcesInterval,
104+
});
116105
const [nodes, setNodes] = useNodesState<NodeData>([]);
117106
const [edges, setEdges] = useEdgesState<Edge[]>([]);
118107
const [colorBy, setColorBy] = useState<'provider' | 'source'>('provider');
@@ -124,12 +113,8 @@ const Graph: React.FC = () => {
124113
group.items?.forEach((item: ManagedResourceItem) => {
125114
const id = item?.metadata?.name;
126115
const kind = item?.kind;
127-
const providerConfigName =
128-
item?.spec?.providerConfigRef?.name ?? 'unknown';
129-
const providerType = resolveProviderType(
130-
providerConfigName,
131-
providerConfigsList,
132-
);
116+
const providerConfigName = item?.spec?.providerConfigRef?.name ?? 'unknown';
117+
const providerType = resolveProviderType(providerConfigName, providerConfigsList);
133118
const status = getStatusFromConditions(item?.status?.conditions);
134119

135120
const {
@@ -188,10 +173,7 @@ const Graph: React.FC = () => {
188173
return Array.from(allNodesMap.values());
189174
}, [managedResources, providerConfigsList]);
190175

191-
const colorMap = useMemo(
192-
() => generateColorMap(treeData, colorBy),
193-
[treeData, colorBy],
194-
);
176+
const colorMap = useMemo(() => generateColorMap(treeData, colorBy), [treeData, colorBy]);
195177

196178
useEffect(() => {
197179
if (!treeData.length) return;
@@ -201,21 +183,15 @@ const Graph: React.FC = () => {
201183
}, [treeData, colorBy, colorMap, setNodes, setEdges]);
202184

203185
if (managedResourcesError || providerConfigsError) {
204-
return (
205-
<div className={`${styles.centeredMessage} ${styles.errorMessage}`}>
206-
Error loading graph data.
207-
</div>
208-
);
186+
return <div className={`${styles.centeredMessage} ${styles.errorMessage}`}>Error loading graph data.</div>;
209187
}
210188

211189
if (!managedResources || !providerConfigsList) {
212190
return <div className={styles.centeredMessage}>Loading graph data...</div>;
213191
}
214192

215193
if (treeData.length === 0) {
216-
return (
217-
<div className={styles.centeredMessage}>No resources to display.</div>
218-
);
194+
return <div className={styles.centeredMessage}>No resources to display.</div>;
219195
}
220196

221197
return (
@@ -280,11 +256,7 @@ const Graph: React.FC = () => {
280256
<Background />
281257
</ReactFlow>
282258
</div>
283-
<Legend
284-
nodes={nodes.map((n) => n.data as NodeData)}
285-
colorBy={colorBy}
286-
generateColorMap={generateColorMap}
287-
/>
259+
<Legend nodes={nodes.map((n) => n.data as NodeData)} colorBy={colorBy} generateColorMap={generateColorMap} />
288260
</div>
289261
);
290262
};

src/components/Graphs/Legend.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,17 @@ interface LegendProps {
66
nodes: NodeData[];
77
colorBy: string;
88
providers?: ProviderConfigItem[];
9-
generateColorMap: (
10-
items: NodeData[],
11-
colorBy: string,
12-
) => Record<string, string>;
9+
generateColorMap: (items: NodeData[], colorBy: string) => Record<string, string>;
1310
}
1411

15-
export const Legend: React.FC<LegendProps> = ({
16-
nodes,
17-
colorBy,
18-
generateColorMap,
19-
}) => {
12+
export const Legend: React.FC<LegendProps> = ({ nodes, colorBy, generateColorMap }) => {
2013
const colorMap = generateColorMap(nodes, colorBy);
2114
return (
2215
<div className={styles.legendContainer}>
2316
<h4 className={styles.legendTitle}>Legend:</h4>
2417
{Object.entries(colorMap).map(([key, color]) => (
2518
<div key={key} className={styles.legendRow}>
26-
<div
27-
className={styles.legendColorBox}
28-
style={{ backgroundColor: color }}
29-
/>
19+
<div className={styles.legendColorBox} style={{ backgroundColor: color }} />
3020
<span>{key === 'default' ? 'default' : key}</span>
3121
</div>
3222
))}

src/components/Graphs/graphUtils.spec.ts

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,31 @@
11
import { describe, it, expect } from 'vitest';
2-
import {
3-
getStatusFromConditions,
4-
resolveProviderType,
5-
generateColorMap,
6-
} from './graphUtils';
2+
import { getStatusFromConditions, resolveProviderType, generateColorMap } from './graphUtils';
73

84
describe('getStatusFromConditions', () => {
95
it('returns OK if Ready is True', () => {
10-
expect(
11-
getStatusFromConditions([
12-
{ type: 'Ready', status: 'True', lastTransitionTime: '2024-01-01' },
13-
]),
14-
).toBe('OK');
6+
expect(getStatusFromConditions([{ type: 'Ready', status: 'True', lastTransitionTime: '2024-01-01' }])).toBe('OK');
157
});
168

179
it('returns OK if Healthy is True', () => {
18-
expect(
19-
getStatusFromConditions([
20-
{ type: 'Healthy', status: 'True', lastTransitionTime: '2024-01-01' },
21-
]),
22-
).toBe('OK');
10+
expect(getStatusFromConditions([{ type: 'Healthy', status: 'True', lastTransitionTime: '2024-01-01' }])).toBe('OK');
2311
});
2412

2513
it('returns ERROR if Ready is False', () => {
26-
expect(
27-
getStatusFromConditions([
28-
{ type: 'Ready', status: 'False', lastTransitionTime: '2024-01-01' },
29-
]),
30-
).toBe('ERROR');
14+
expect(getStatusFromConditions([{ type: 'Ready', status: 'False', lastTransitionTime: '2024-01-01' }])).toBe(
15+
'ERROR',
16+
);
3117
});
3218

3319
it('returns ERROR if Healthy is False', () => {
34-
expect(
35-
getStatusFromConditions([
36-
{ type: 'Healthy', status: 'False', lastTransitionTime: '2024-01-01' },
37-
]),
38-
).toBe('ERROR');
20+
expect(getStatusFromConditions([{ type: 'Healthy', status: 'False', lastTransitionTime: '2024-01-01' }])).toBe(
21+
'ERROR',
22+
);
3923
});
4024

4125
it('returns ERROR if no relevant condition exists', () => {
42-
expect(
43-
getStatusFromConditions([
44-
{ type: 'Other', status: 'True', lastTransitionTime: '2024-01-01' },
45-
]),
46-
).toBe('ERROR');
26+
expect(getStatusFromConditions([{ type: 'Other', status: 'True', lastTransitionTime: '2024-01-01' }])).toBe(
27+
'ERROR',
28+
);
4729
});
4830

4931
it('returns ERROR for undefined or empty input', () => {
@@ -80,9 +62,7 @@ describe('resolveProviderType', () => {
8062
});
8163

8264
it('returns configName if not found', () => {
83-
const configs = [
84-
{ items: [{ metadata: { name: 'foo' }, apiVersion: 'btp/v1' }] },
85-
];
65+
const configs = [{ items: [{ metadata: { name: 'foo' }, apiVersion: 'btp/v1' }] }];
8666
expect(resolveProviderType('notfound', configs)).toBe('notfound');
8767
});
8868

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,18 @@
1-
import {
2-
Condition,
3-
ManagedResourceItem,
4-
NodeData,
5-
ProviderConfig,
6-
} from './types';
1+
import { Condition, ManagedResourceItem, NodeData, ProviderConfig } from './types';
72

83
export type StatusType = 'ERROR' | 'OK';
94

10-
export const getStatusFromConditions = (
11-
conditions?: Condition[],
12-
): StatusType => {
5+
export const getStatusFromConditions = (conditions?: Condition[]): StatusType => {
136
if (!conditions || !Array.isArray(conditions)) return 'ERROR';
14-
const relevant = conditions.find(
15-
(c) => c.type === 'Ready' || c.type === 'Healthy',
16-
);
7+
const relevant = conditions.find((c) => c.type === 'Ready' || c.type === 'Healthy');
178
return relevant?.status === 'True' ? 'OK' : 'ERROR';
189
};
1910

20-
export const resolveProviderType = (
21-
configName?: string,
22-
providerConfigsList?: ProviderConfig[],
23-
): string => {
11+
export const resolveProviderType = (configName?: string, providerConfigsList?: ProviderConfig[]): string => {
2412
if (!configName) return 'unknown';
2513

2614
for (const configList of providerConfigsList || []) {
27-
const match = configList.items?.find(
28-
(item) => item.metadata?.name === configName,
29-
);
15+
const match = configList.items?.find((item) => item.metadata?.name === configName);
3016

3117
if (match) {
3218
const apiVersion = match.apiVersion?.toLowerCase() || '';
@@ -41,10 +27,7 @@ export const resolveProviderType = (
4127
return configName;
4228
};
4329

44-
export const generateColorMap = (
45-
items: NodeData[],
46-
colorBy: string,
47-
): Record<string, string> => {
30+
export const generateColorMap = (items: NodeData[], colorBy: string): Record<string, string> => {
4831
const colors = [
4932
'#1abc9c',
5033
'#9b59b6',
@@ -63,9 +46,7 @@ export const generateColorMap = (
6346
const keys =
6447
colorBy === 'source'
6548
? Array.from(new Set(items.map((i) => i.providerType).filter(Boolean)))
66-
: Array.from(
67-
new Set(items.map((i) => i.providerConfigName).filter(Boolean)),
68-
);
49+
: Array.from(new Set(items.map((i) => i.providerConfigName).filter(Boolean)));
6950

7051
const map: Record<string, string> = {};
7152
keys.forEach((key, i) => {
@@ -86,15 +67,11 @@ export function extractRefs(item: ManagedResourceItem) {
8667
globalAccountRef: item?.spec?.forProvider?.globalAccountRef?.name,
8768
orgRoleRef: item?.spec?.forProvider?.orgRoleRef?.name,
8869
spaceMembersRef: item?.spec?.forProvider?.spaceMembersRef?.name,
89-
cloudFoundryEnvironmentRef:
90-
item?.spec?.forProvider?.cloudFoundryEnvironmentRef?.name,
70+
cloudFoundryEnvironmentRef: item?.spec?.forProvider?.cloudFoundryEnvironmentRef?.name,
9171
kymaEnvironmentRef: item?.spec?.forProvider?.kymaEnvironmentRef?.name,
9272
roleCollectionRef: item?.spec?.forProvider?.roleCollectionRef?.name,
93-
roleCollectionAssignmentRef:
94-
item?.spec?.forProvider?.roleCollectionAssignmentRef?.name,
95-
subaccountTrustConfigurationRef:
96-
item?.spec?.forProvider?.subaccountTrustConfigurationRef?.name,
97-
globalaccountTrustConfigurationRef:
98-
item?.spec?.forProvider?.globalaccountTrustConfigurationRef?.name,
73+
roleCollectionAssignmentRef: item?.spec?.forProvider?.roleCollectionAssignmentRef?.name,
74+
subaccountTrustConfigurationRef: item?.spec?.forProvider?.subaccountTrustConfigurationRef?.name,
75+
globalaccountTrustConfigurationRef: item?.spec?.forProvider?.globalaccountTrustConfigurationRef?.name,
9976
};
10077
}

src/components/Yaml/YamlViewButton.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import styles from './YamlViewer.module.css';
44
import { useTranslation } from 'react-i18next';
55
import YamlViewer from './YamlViewer.tsx';
66
import { stringify } from 'yaml';
7-
import {
8-
removeManagedFieldsProperty,
9-
Resource,
10-
} from '../../utils/removeManagedFieldsProperty.ts';
7+
import { removeManagedFieldsProperty, Resource } from '../../utils/removeManagedFieldsProperty.ts';
118
import { YamlIcon } from './YamlIcon.tsx';
129
import { YamlViewDialog } from './YamlViewDialog.tsx';
1310

0 commit comments

Comments
 (0)