Skip to content

Commit 6de4f77

Browse files
authored
fix(cherry-pick-3.1): handle missing resources on UI (#24357)
Signed-off-by: Peter Jiang <peterjiang823@gmail.com>
1 parent ed9149b commit 6de4f77

1 file changed

Lines changed: 81 additions & 71 deletions

File tree

ui/src/app/applications/components/utils.tsx

Lines changed: 81 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -548,65 +548,73 @@ export const deletePopup = async (
548548
};
549549

550550
export async function getResourceActionsMenuItems(resource: ResourceTreeNode, metadata: models.ObjectMeta, apis: ContextApis): Promise<ActionMenuItem[]> {
551-
return services.applications.getResourceActions(metadata.name, metadata.namespace, resource).then(actions => {
552-
return actions.map(action => ({
553-
title: action.displayName ?? action.name,
554-
disabled: !!action.disabled,
555-
iconClassName: action.iconClass,
556-
action: async () => {
557-
const confirmed = false;
558-
const title = action.params ? `Enter input parameters for action: ${action.name}` : `Perform ${action.name} action?`;
559-
await apis.popup.prompt(
560-
title,
561-
api => (
562-
<div>
563-
{!action.params && (
564-
<div className='argo-form-row'>
565-
<div> Are you sure you want to perform {action.name} action?</div>
566-
</div>
567-
)}
568-
{action.params &&
569-
action.params.map((param, index) => (
570-
<div className='argo-form-row' key={index}>
571-
<FormField label={param.name} field={param.name} formApi={api} component={Text} />
551+
// Don't call API for missing resources
552+
if (!resource.uid) {
553+
return [];
554+
}
555+
556+
return services.applications
557+
.getResourceActions(metadata.name, metadata.namespace, resource)
558+
.then(actions => {
559+
return actions.map(action => ({
560+
title: action.displayName ?? action.name,
561+
disabled: !!action.disabled,
562+
iconClassName: action.iconClass,
563+
action: async () => {
564+
const confirmed = false;
565+
const title = action.params ? `Enter input parameters for action: ${action.name}` : `Perform ${action.name} action?`;
566+
await apis.popup.prompt(
567+
title,
568+
api => (
569+
<div>
570+
{!action.params && (
571+
<div className='argo-form-row'>
572+
<div> Are you sure you want to perform {action.name} action?</div>
572573
</div>
573-
))}
574-
</div>
575-
),
576-
{
577-
submit: async (vals, _, close) => {
578-
try {
579-
const resourceActionParameters = action.params
580-
? action.params.map(param => ({
581-
name: param.name,
582-
value: vals[param.name] || param.default,
583-
type: param.type,
584-
default: param.default
585-
}))
586-
: [];
587-
await services.applications.runResourceAction(metadata.name, metadata.namespace, resource, action.name, resourceActionParameters);
588-
close();
589-
} catch (e) {
590-
apis.notifications.show({
591-
content: <ErrorNotification title='Unable to execute resource action' e={e} />,
592-
type: NotificationType.Error
593-
});
574+
)}
575+
{action.params &&
576+
action.params.map((param, index) => (
577+
<div className='argo-form-row' key={index}>
578+
<FormField label={param.name} field={param.name} formApi={api} component={Text} />
579+
</div>
580+
))}
581+
</div>
582+
),
583+
{
584+
submit: async (vals, _, close) => {
585+
try {
586+
const resourceActionParameters = action.params
587+
? action.params.map(param => ({
588+
name: param.name,
589+
value: vals[param.name] || param.default,
590+
type: param.type,
591+
default: param.default
592+
}))
593+
: [];
594+
await services.applications.runResourceAction(metadata.name, metadata.namespace, resource, action.name, resourceActionParameters);
595+
close();
596+
} catch (e) {
597+
apis.notifications.show({
598+
content: <ErrorNotification title='Unable to execute resource action' e={e} />,
599+
type: NotificationType.Error
600+
});
601+
}
594602
}
595-
}
596-
},
597-
null,
598-
null,
599-
action.params
600-
? action.params.reduce((acc, res) => {
601-
acc[res.name] = res.default;
602-
return acc;
603-
}, {} as any)
604-
: {}
605-
);
606-
return confirmed;
607-
}
608-
}));
609-
});
603+
},
604+
null,
605+
null,
606+
action.params
607+
? action.params.reduce((acc, res) => {
608+
acc[res.name] = res.default;
609+
return acc;
610+
}, {} as any)
611+
: {}
612+
);
613+
return confirmed;
614+
}
615+
}));
616+
})
617+
.catch(() => [] as ActionMenuItem[]);
610618
}
611619

612620
function getActionItems(
@@ -694,20 +702,22 @@ function getActionItems(
694702

695703
const resourceActions = getResourceActionsMenuItems(resource, application.metadata, apis);
696704

697-
const links = services.applications
698-
.getResourceLinks(application.metadata.name, application.metadata.namespace, resource)
699-
.then(data => {
700-
return (data.items || []).map(
701-
link =>
702-
({
703-
title: link.title,
704-
iconClassName: `fa fa-fw ${link.iconClass ? link.iconClass : 'fa-external-link'}`,
705-
action: () => window.open(link.url, '_blank'),
706-
tooltip: link.description
707-
}) as MenuItem
708-
);
709-
})
710-
.catch(() => [] as MenuItem[]);
705+
const links = !resource.uid
706+
? Promise.resolve([])
707+
: services.applications
708+
.getResourceLinks(application.metadata.name, application.metadata.namespace, resource)
709+
.then(data => {
710+
return (data.items || []).map(
711+
link =>
712+
({
713+
title: link.title,
714+
iconClassName: `fa fa-fw ${link.iconClass ? link.iconClass : 'fa-external-link'}`,
715+
action: () => window.open(link.url, '_blank'),
716+
tooltip: link.description
717+
}) as MenuItem
718+
);
719+
})
720+
.catch(() => [] as MenuItem[]);
711721

712722
return combineLatest(
713723
from([items]), // this resolves immediately

0 commit comments

Comments
 (0)