Skip to content

Commit 76f7689

Browse files
committed
add reset button to disconnected assisted installer ui
Signed-off-by: Elay Aharoni <elayaha@gmail.com>
1 parent bae0700 commit 76f7689

File tree

7 files changed

+137
-10
lines changed

7 files changed

+137
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
import { SingleClusterPage } from '@openshift-assisted/ui-lib/ocm';
1+
import { ModalDialogsContextProvider, SingleClusterPage } from '@openshift-assisted/ui-lib/ocm';
22
import { useParams } from 'react-router-dom-v5-compat';
3+
import ResetSingleClusterModal from './ResetSingleClusterModal';
34

45
const ClusterPage = () => {
56
const { clusterId } = useParams() as { clusterId: string };
6-
return <SingleClusterPage clusterId={clusterId} />;
7+
return (
8+
<ModalDialogsContextProvider>
9+
<ResetSingleClusterModal />
10+
<SingleClusterPage clusterId={clusterId} />
11+
</ModalDialogsContextProvider>
12+
);
713
};
814

915
export default ClusterPage;

Diff for: apps/assisted-disconnected-ui/src/components/CreateClusterWizard.tsx

+12-7
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ import {
66
OpenShiftVersionsContextProvider,
77
NewFeatureSupportLevelProvider,
88
NewClusterWizard,
9+
ModalDialogsContextProvider,
910
} from '@openshift-assisted/ui-lib/ocm';
1011
import { Alert, PageSection, PageSectionVariants } from '@patternfly/react-core';
1112
import { useNavigate } from 'react-router-dom-v5-compat';
13+
import ResetSingleClusterModal from './ResetSingleClusterModal';
1214

1315
const CreateClusterWizard = () => {
1416
const [clusterId, isLoading, error] = useCluster();
@@ -31,13 +33,16 @@ const CreateClusterWizard = () => {
3133

3234
return (
3335
<AlertsContextProvider>
34-
<ClusterWizardContextProvider>
35-
<OpenShiftVersionsContextProvider>
36-
<NewFeatureSupportLevelProvider loadingUi={<ClusterLoading />}>
37-
<NewClusterWizard />
38-
</NewFeatureSupportLevelProvider>
39-
</OpenShiftVersionsContextProvider>
40-
</ClusterWizardContextProvider>
36+
<ModalDialogsContextProvider>
37+
<ClusterWizardContextProvider>
38+
<OpenShiftVersionsContextProvider>
39+
<NewFeatureSupportLevelProvider loadingUi={<ClusterLoading />}>
40+
<NewClusterWizard />
41+
<ResetSingleClusterModal />
42+
</NewFeatureSupportLevelProvider>
43+
</OpenShiftVersionsContextProvider>
44+
</ClusterWizardContextProvider>
45+
</ModalDialogsContextProvider>
4146
</AlertsContextProvider>
4247
);
4348
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import React from 'react';
2+
import {
3+
Button,
4+
Modal,
5+
ModalVariant,
6+
ButtonVariant,
7+
Text,
8+
TextContent,
9+
} from '@patternfly/react-core';
10+
import { useModalDialogsContext, ClustersService } from '@openshift-assisted/ui-lib/ocm';
11+
import { getApiErrorMessage, handleApiError, ErrorState } from '@openshift-assisted/ui-lib/common';
12+
import { useNavigate } from 'react-router-dom-v5-compat';
13+
14+
const ResetSingleClusterModal: React.FC = () => {
15+
const navigate = useNavigate();
16+
const [error, setError] = React.useState<{ title: string; message: string } | null>(null);
17+
const { resetSingleClusterDialog } = useModalDialogsContext();
18+
const { data, isOpen, close: onClose } = resetSingleClusterDialog;
19+
const cluster = data?.cluster;
20+
21+
console.log('resetSingleClusterDialog', useModalDialogsContext());
22+
23+
const handleClose = () => {
24+
setError(null);
25+
onClose();
26+
};
27+
28+
const handleResetAsync = async () => {
29+
try {
30+
await ClustersService.remove(cluster.id);
31+
navigate(`/`);
32+
} catch (e) {
33+
handleApiError(e, () => {
34+
setError({
35+
title: 'Failed to reset cluster installation',
36+
message: getApiErrorMessage(e),
37+
});
38+
});
39+
}
40+
};
41+
42+
const getModalContent = () => {
43+
if (error) {
44+
return <ErrorState title={error.title} content={error.message} />;
45+
}
46+
47+
return (
48+
<TextContent>
49+
<Text component="p">
50+
This will reset the installation and return to the cluster configuration. Some hosts may
51+
need to be re-registered by rebooting into the Discovery ISO.
52+
</Text>
53+
54+
<Text component="p">Are you sure you want to reset the cluster?</Text>
55+
</TextContent>
56+
);
57+
};
58+
59+
const actions = [
60+
<Button key="reset" variant={ButtonVariant.danger} onClick={() => void handleResetAsync()}>
61+
Reset Cluster
62+
</Button>,
63+
];
64+
65+
actions.push(
66+
<Button key="cancel" variant={ButtonVariant.link} onClick={handleClose}>
67+
Cancel
68+
</Button>,
69+
);
70+
71+
return (
72+
<Modal
73+
title="Reset Single Cluster Installation"
74+
isOpen={isOpen}
75+
variant={ModalVariant.small}
76+
actions={actions}
77+
onClose={handleClose}
78+
>
79+
{getModalContent()}
80+
</Modal>
81+
);
82+
};
83+
84+
export default ResetSingleClusterModal;

Diff for: libs/locales/lib/en/translation.json

+1
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@
706706
"ai:Report a bug": "Report a bug",
707707
"ai:Required field": "Required field",
708708
"ai:Required.": "Required.",
709+
"ai:Reset": "Reset",
709710
"ai:Reset host": "Reset host",
710711
"ai:Resetting": "Resetting",
711712
"ai:Returning to the infrastructure environment": "Returning to the infrastructure environment",

Diff for: libs/ui-lib/lib/common/components/ui/WizardFooter.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export type WizardFooterGenericProps = {
2020
onNext?: () => void;
2121
onBack?: () => void;
2222
onCancel?: () => void;
23+
onReset?: () => void;
2324
isNextDisabled?: boolean;
2425
isBackDisabled?: boolean;
2526
isSubmitting?: boolean;
@@ -41,6 +42,7 @@ export const WizardFooter: React.FC<WizardFooterProps> = ({
4142
onNext,
4243
onBack,
4344
onCancel,
45+
onReset,
4446
isNextDisabled,
4547
isBackDisabled,
4648
leftExtraActions,
@@ -95,6 +97,13 @@ export const WizardFooter: React.FC<WizardFooterProps> = ({
9597
</Button>
9698
</ActionListItem>
9799
)}
100+
{onReset && cluster && (
101+
<ActionListItem>
102+
<Button variant={ButtonVariant.link} name="reset" onClick={onReset}>
103+
{t('ai:Reset')}
104+
</Button>
105+
</ActionListItem>
106+
)}
98107
{isSubmitting && (
99108
<ActionListItem>
100109
<Text component={TextVariants.small}>

Diff for: libs/ui-lib/lib/ocm/components/clusterWizard/ClusterWizardFooter.tsx

+15
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { useTranslation } from '../../../common/hooks/use-translation-wrapper';
1616
import { onFetchEvents } from '../fetching/fetchEvents';
1717
import { Cluster } from '@openshift-assisted/types/assisted-installer-service';
1818
import { useFeature } from '../../hooks/use-feature';
19+
import { useModalDialogsContext } from '../hosts/ModalDialogsContext';
1920

2021
type ClusterValidationSectionProps = {
2122
cluster?: Cluster;
@@ -84,9 +85,18 @@ const ClusterWizardFooter = ({
8485
const { alerts } = useAlerts();
8586
const navigate = useNavigate();
8687
const isSingleClusterFeatureEnabled = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
88+
const { currentStepId } = useClusterWizardContext();
89+
const { resetSingleClusterDialog } = useModalDialogsContext();
90+
91+
console.log('ClusterWizardFooter', useModalDialogsContext());
8792

8893
const handleCancel = React.useCallback(() => navigate('/cluster-list'), [navigate]);
8994

95+
const handleReset = React.useCallback(() => {
96+
console.log('handleReset');
97+
resetSingleClusterDialog.open({ cluster });
98+
}, [resetSingleClusterDialog, cluster]);
99+
90100
const alertsSection = alerts.length ? <Alerts /> : undefined;
91101

92102
const errorsSection = (
@@ -103,6 +113,11 @@ const ClusterWizardFooter = ({
103113
alerts={alertsSection}
104114
errors={errorsSection}
105115
onCancel={isSingleClusterFeatureEnabled ? undefined : onCancel || handleCancel}
116+
onReset={
117+
isSingleClusterFeatureEnabled && currentStepId !== 'cluster-details'
118+
? handleReset
119+
: undefined
120+
}
106121
leftExtraActions={additionalActions}
107122
cluster={cluster}
108123
onFetchEvents={onFetchEvents}

Diff for: libs/ui-lib/lib/ocm/components/hosts/ModalDialogsContext.tsx

+8-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ type MassDeleteHostDialogProps = {
4040
reloadCluster: VoidFunction;
4141
};
4242

43+
type ResetSingleClusterDialogProps = {
44+
cluster?: Cluster;
45+
};
46+
4347
type ModalDialogsDataTypes = {
4448
eventsDialog: HostIdAndHostname;
4549
editHostDialog: EditHostProps;
@@ -53,6 +57,7 @@ type ModalDialogsDataTypes = {
5357
UpdateDay2ApiVipDialog: void;
5458
massUpdateHostnameDialog: MassUpdateHostnameDialogProps;
5559
massDeleteHostDialog: MassDeleteHostDialogProps;
60+
resetSingleClusterDialog: ResetSingleClusterDialogProps;
5661
};
5762

5863
type DialogId =
@@ -67,7 +72,8 @@ type DialogId =
6772
| 'day2DiscoveryImageDialog'
6873
| 'UpdateDay2ApiVipDialog'
6974
| 'massUpdateHostnameDialog'
70-
| 'massDeleteHostDialog';
75+
| 'massDeleteHostDialog'
76+
| 'resetSingleClusterDialog';
7177

7278
export type ModalDialogsContextType = {
7379
[key in DialogId]: {
@@ -91,6 +97,7 @@ const dialogIds: DialogId[] = [
9197
'UpdateDay2ApiVipDialog',
9298
'massUpdateHostnameDialog',
9399
'massDeleteHostDialog',
100+
'resetSingleClusterDialog',
94101
];
95102

96103
const ModalDialogsContext = React.createContext<ModalDialogsContextType | undefined>(undefined);

0 commit comments

Comments
 (0)