Skip to content

Commit 27c4cf7

Browse files
authored
Merge pull request #223 from keithchong/9329-PartDandE-LinkToDetailsAndOtherChanges
Part d and e - link to details and other changes (#9329)
2 parents 0a14d06 + 58693cf commit 27c4cf7

10 files changed

Lines changed: 156 additions & 66 deletions

File tree

locales/en/plugin__gitops-plugin.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
"Delete {{x}}": "Delete {{x}}",
117117
"Edit {{x}}": "Edit {{x}}",
118118
"View in Argo CD": "View in Argo CD",
119+
"View Details": "View Details",
119120
"Edit Application": "Edit Application",
120121
"Delete Application": "Delete Application",
121122
"Show {{x}}": "Show {{x}}",
@@ -126,7 +127,6 @@
126127
"There is no health status for this resource": "There is no health status for this resource",
127128
"Sync Unknown": "Sync Unknown",
128129
"One or more resources are in Progressing state": "One or more resources are in Progressing state",
129-
"Go to application": "Go to application",
130130
"Step {{x}}": "Step {{x}}",
131131
"Step: unmatched": "Step: unmatched",
132132
"There is no history associated with the application.": "There is no history associated with the application.",
@@ -150,6 +150,7 @@
150150
"Applications": "Applications",
151151
"Edit ApplicationSet": "Edit ApplicationSet",
152152
"Delete ApplicationSet": "Delete ApplicationSet",
153+
"View Graph": "View Graph",
153154
"AppSet ownerReference Tree View": "AppSet ownerReference Tree View",
154155
"Progressive Sync Flow View": "Progressive Sync Flow View",
155156
"Expand or collapse all progressive sync step groups": "Expand or collapse all progressive sync step groups",

locales/ja/plugin__gitops-plugin.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
"Delete {{x}}": "Delete {{x}}",
117117
"Edit {{x}}": "Edit {{x}}",
118118
"View in Argo CD": "View in Argo CD",
119+
"View Details": "View Details",
119120
"Edit Application": "Edit Application",
120121
"Delete Application": "Delete Application",
121122
"Show {{x}}": "Show {{x}}",
@@ -126,7 +127,6 @@
126127
"There is no health status for this resource": "There is no health status for this resource",
127128
"Sync Unknown": "Sync Unknown",
128129
"One or more resources are in Progressing state": "One or more resources are in Progressing state",
129-
"Go to application": "Go to application",
130130
"Step {{x}}": "Step {{x}}",
131131
"Step: unmatched": "Step: unmatched",
132132
"There is no history associated with the application.": "There is no history associated with the application.",
@@ -150,6 +150,7 @@
150150
"Applications": "Applications",
151151
"Edit ApplicationSet": "Edit ApplicationSet",
152152
"Delete ApplicationSet": "Delete ApplicationSet",
153+
"View Graph": "View Graph",
153154
"AppSet ownerReference Tree View": "AppSet ownerReference Tree View",
154155
"Progressive Sync Flow View": "Progressive Sync Flow View",
155156
"Expand or collapse all progressive sync step groups": "Expand or collapse all progressive sync step groups",

locales/ko/plugin__gitops-plugin.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
"Delete {{x}}": "Delete {{x}}",
117117
"Edit {{x}}": "Edit {{x}}",
118118
"View in Argo CD": "View in Argo CD",
119+
"View Details": "View Details",
119120
"Edit Application": "Edit Application",
120121
"Delete Application": "Delete Application",
121122
"Show {{x}}": "Show {{x}}",
@@ -126,7 +127,6 @@
126127
"There is no health status for this resource": "There is no health status for this resource",
127128
"Sync Unknown": "Sync Unknown",
128129
"One or more resources are in Progressing state": "One or more resources are in Progressing state",
129-
"Go to application": "Go to application",
130130
"Step {{x}}": "Step {{x}}",
131131
"Step: unmatched": "Step: unmatched",
132132
"There is no history associated with the application.": "There is no history associated with the application.",
@@ -150,6 +150,7 @@
150150
"Applications": "Applications",
151151
"Edit ApplicationSet": "Edit ApplicationSet",
152152
"Delete ApplicationSet": "Delete ApplicationSet",
153+
"View Graph": "View Graph",
153154
"AppSet ownerReference Tree View": "AppSet ownerReference Tree View",
154155
"Progressive Sync Flow View": "Progressive Sync Flow View",
155156
"Expand or collapse all progressive sync step groups": "Expand or collapse all progressive sync step groups",

locales/zh/plugin__gitops-plugin.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
"Delete {{x}}": "Delete {{x}}",
117117
"Edit {{x}}": "Edit {{x}}",
118118
"View in Argo CD": "View in Argo CD",
119+
"View Details": "View Details",
119120
"Edit Application": "Edit Application",
120121
"Delete Application": "Delete Application",
121122
"Show {{x}}": "Show {{x}}",
@@ -126,7 +127,6 @@
126127
"There is no health status for this resource": "There is no health status for this resource",
127128
"Sync Unknown": "Sync Unknown",
128129
"One or more resources are in Progressing state": "One or more resources are in Progressing state",
129-
"Go to application": "Go to application",
130130
"Step {{x}}": "Step {{x}}",
131131
"Step: unmatched": "Step: unmatched",
132132
"There is no history associated with the application.": "There is no history associated with the application.",
@@ -150,6 +150,7 @@
150150
"Applications": "Applications",
151151
"Edit ApplicationSet": "Edit ApplicationSet",
152152
"Delete ApplicationSet": "Delete ApplicationSet",
153+
"View Graph": "View Graph",
153154
"AppSet ownerReference Tree View": "AppSet ownerReference Tree View",
154155
"Progressive Sync Flow View": "Progressive Sync Flow View",
155156
"Expand or collapse all progressive sync step groups": "Expand or collapse all progressive sync step groups",

src/gitops/components/application/graph/ApplicationGraphView.tsx

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,12 @@ import { GraphResourceMenuItem } from './hooks/GraphResourceMenuItems';
5959
import { ApplicationNode } from './nodes/ApplicationNode';
6060
import { ResourceGroupNode } from './nodes/ResourceGroupNode';
6161
import { ResourceNode } from './nodes/ResourceNode';
62-
import { getInitialEdges, getInitialNodes } from './graph-utils';
62+
import {
63+
getInitialEdges,
64+
getInitialNodes,
65+
getResourceMapKey,
66+
getResourcePathForResource,
67+
} from './graph-utils';
6368

6469
import './ApplicationGraphView.scss';
6570

@@ -122,7 +127,6 @@ const customComponentFactory =
122127
) {
123128
return <GraphResourceMenuItem key={label} graphElement={graphElement} label={label} />;
124129
}
125-
126130
// For other actions that don't need resource-specific hooks
127131
return (
128132
<ContextMenuItem
@@ -131,6 +135,9 @@ const customComponentFactory =
131135
if (label === t('View in Argo CD')) {
132136
window.open(hrefRef.current, '_blank');
133137
}
138+
if (label === t('View Details')) {
139+
navigate(graphElement.getData().resourcePath);
140+
}
134141
}}
135142
>
136143
{label}
@@ -146,26 +153,14 @@ const customComponentFactory =
146153
graphElement.getData().kind === 'AppProject' ||
147154
graphElement.getData().kind === 'Namespace'
148155
) {
149-
return createContextMenuItems2(graphElement, [
150-
t('Edit labels'),
151-
t('Edit annotations'),
152-
t('Edit {{x}}', {
153-
x: graphElement.getData().kind,
154-
}),
155-
'-',
156-
t('View in Argo CD'),
157-
]);
156+
return createContextMenuItems2(graphElement, [t('View Details'), t('View in Argo CD')]);
158157
} else {
159158
return createContextMenuItems2(graphElement, [
160-
t('Edit labels'),
161-
t('Edit annotations'),
162-
t('Edit {{x}}', {
163-
x: graphElement.getData().kind,
164-
}),
165159
t('Delete {{x}}', {
166160
x: graphElement.getData().kind,
167161
}),
168162
'-',
163+
t('View Details'),
169164
t('View in Argo CD'),
170165
]);
171166
}
@@ -362,13 +357,26 @@ export const ApplicationGraphView: React.FC<{
362357
return newController;
363358
}, []);
364359

360+
const resourcePaths = React.useMemo(() => {
361+
const map = new Map<string, string>();
362+
resources.forEach((resource) => {
363+
const mapKey = getResourceMapKey(resource);
364+
if (resource.health?.status !== HealthStatus.MISSING) {
365+
map.set(mapKey, getResourcePathForResource(resource, allK8sModels));
366+
} else {
367+
map.set(mapKey, '');
368+
}
369+
});
370+
return map;
371+
}, [resources, allK8sModels]);
365372
const initialNodes = getInitialNodes(
366373
application,
367374
resources,
368375
allK8sModels,
369376
groupNodeState,
370377
groupNodeStates,
371378
resourceNodeLayout,
379+
resourcePaths,
372380
);
373381
const initialEdges = getInitialEdges(application, initialNodes, groupNodeState);
374382
const nodes = [...initialNodes];

src/gitops/components/application/graph/graph-utils.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ import {
77
kindToAbbr,
88
NODE_DIAMETER,
99
} from '@gitops/components/graph/utils';
10-
import { ApplicationKind, ApplicationResourceStatus } from '@gitops/models/ApplicationModel';
10+
import {
11+
ApplicationKind,
12+
ApplicationModel,
13+
ApplicationResourceStatus,
14+
} from '@gitops/models/ApplicationModel';
1115
import { HealthStatus, SyncStatus } from '@gitops/utils/constants';
16+
import { resourcePathFromModel } from '@gitops/utils/utils';
1217
import { K8sModel } from '@openshift-console/dynamic-plugin-sdk';
1318
import {
1419
EdgeStyle,
@@ -247,6 +252,27 @@ const createGroupResourceNode = (
247252
return groupResourceNodeMap;
248253
};
249254

255+
export const getResourceMapKey = (resource: ApplicationResourceStatus): string => {
256+
return `${resource.group}-${resource.version}-${resource.kind}-${resource.namespace}-${resource.name}`;
257+
};
258+
259+
export const getResourcePathForResource = (
260+
resource: ApplicationResourceStatus,
261+
allK8sModels: { [key: string]: K8sModel },
262+
): string => {
263+
if (resource.kind === ApplicationModel.kind) {
264+
return (
265+
resourcePathFromModel(ApplicationModel as K8sModel, resource.name, resource.namespace) +
266+
'/resources'
267+
);
268+
}
269+
const k8sModel = allK8sModels[resource.kind];
270+
if (!k8sModel) {
271+
return '';
272+
}
273+
return resourcePathFromModel(k8sModel, resource.name, resource.namespace);
274+
};
275+
250276
// Application Graph Nodes
251277
export const getInitialNodes = (
252278
application: ApplicationKind,
@@ -255,6 +281,7 @@ export const getInitialNodes = (
255281
showGroupNodes: boolean,
256282
groupNodeStates: string[],
257283
resourceNodeLayout: boolean,
284+
resourcePaths: Map<string, string>,
258285
) => {
259286
// This contains all the nodes we want to add to the graph view
260287
const initialNodes: NodeModel[] = [];
@@ -281,6 +308,8 @@ export const getInitialNodes = (
281308
const key = resource.kind + 's';
282309
const resourceGroupExpandState = groupNodeStates.includes(key);
283310

311+
const resourcePath = resourcePaths.get(getResourceMapKey(resource));
312+
284313
if (showGroupNodes && resources.filter((res) => res.kind === resource.kind).length > 1) {
285314
groupResourceNodeMap = createGroupResourceNode(
286315
kind,
@@ -316,6 +345,7 @@ export const getInitialNodes = (
316345
group: resource.group,
317346
kind: resource.kind,
318347
resourceNodeLayout: resourceNodeLayout,
348+
resourcePath: resourcePath,
319349
version: resource.version,
320350
namespace: resource.namespace,
321351
indent: 100,

src/gitops/components/application/graph/nodes/ResourceNode.tsx

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
* Resource Node for Argo CD Resources
33
*/
44
import * as React from 'react';
5-
import { useLocation } from 'react-router-dom-v5-compat';
5+
import { Link } from 'react-router-dom-v5-compat';
66
import { observer } from 'mobx-react';
77

88
import SvgTextWithOverflow from '@gitops/components/graph/SvgTextWithOverflow';
99
import { ApplicationModel } from '@gitops/models/ApplicationModel';
1010
import { HealthStatus } from '@gitops/utils/constants';
1111
import { t } from '@gitops/utils/hooks/useGitOpsTranslation';
12+
import { resourcePathFromModel } from '@gitops/utils/utils';
13+
import { K8sModel, useK8sModel } from '@openshift-console/dynamic-plugin-sdk';
1214
import {
1315
BadgeLocation,
1416
DefaultNode,
@@ -33,16 +35,25 @@ interface CustomNodeProps {
3335
export const ResourceNode: React.FC<CustomNodeProps & WithSelectionProps & WithContextMenuProps> =
3436
observer(({ element, onContextMenu, contextMenuOpen, onSelect, selected }) => {
3537
const data = element.getData();
36-
const kind = data.icon as string;
38+
const kind = data.kind as string;
3739
const resourceNodeLayout = data.resourceNodeLayout as boolean;
38-
const location = useLocation();
3940
const truncatedBadge = data.badge.length > 3 ? data.badge.slice(0, 3) : data.badge;
4041
let dx = 8;
4142
if (truncatedBadge.length === 1) {
4243
dx = 17;
4344
} else if (truncatedBadge.length === 2) {
4445
dx = 12;
4546
}
47+
const [k8sModel] = useK8sModel({
48+
group: data.group,
49+
version: data.version,
50+
kind: data.kind,
51+
});
52+
const resourcePath =
53+
data.kind === ApplicationModel.kind
54+
? resourcePathFromModel(ApplicationModel as K8sModel, data.name, data.namespace) +
55+
'/resources'
56+
: resourcePathFromModel(k8sModel as K8sModel, data.name, data.namespace);
4657
const transform = resourceNodeLayout ? `scale(0.6) translate(8, 6)` : '';
4758
return (
4859
<DefaultNode
@@ -105,32 +116,27 @@ export const ResourceNode: React.FC<CustomNodeProps & WithSelectionProps & WithC
105116
/>
106117
)}
107118
<SyncStatusSvgIcon status={data.syncStatus} x={71} y={28} width={16} height={16} />
119+
{data.resourceHealthStatus !== HealthStatus.MISSING && (
120+
<foreignObject
121+
x={90}
122+
y={25}
123+
width={20}
124+
height={20}
125+
color="var(--pf-topology__node__background--Stroke)"
126+
>
127+
<Link
128+
to={resourcePath}
129+
title={''}
130+
className="co-resource-item__resource-name"
131+
data-test-id={data.name}
132+
data-test={data.name}
133+
>
134+
<i className="fa fa-external-link-alt" />
135+
</Link>
136+
</foreignObject>
137+
)}
108138
{kind === ApplicationModel.kind && (
109139
<>
110-
<foreignObject
111-
x={90}
112-
y={25}
113-
width={100}
114-
height={20}
115-
color="var(--pf-topology__node__background--Stroke)"
116-
>
117-
<a
118-
href={
119-
location.pathname +
120-
'/../../../argoproj.io~v1alpha1~Application/' +
121-
data.name +
122-
'/resources'
123-
}
124-
target={undefined}
125-
rel={undefined}
126-
onClick={(e) => {
127-
e.stopPropagation();
128-
}}
129-
title={t('Go to application')}
130-
>
131-
<i className="fa fa-external-link-alt" />
132-
</a>
133-
</foreignObject>
134140
{data.step && (
135141
<svg transform={`translate(55, 29)`}>
136142
<text x="70" y="12">

0 commit comments

Comments
 (0)