Skip to content

Commit 2600b09

Browse files
Persist enable modal status while in progress (opendatahub-io#84)
1 parent b1352d0 commit 2600b09

File tree

6 files changed

+67
-31
lines changed

6 files changed

+67
-31
lines changed

Diff for: frontend/src/__tests__/ExploreApplications.spec.tsx

+14-3
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,13 @@ describe('ExploreApplications', () => {
6565
});
6666

6767
it('should display available applications', () => {
68-
const wrapper = mount(<ExploreApplications />);
69-
68+
const wrapper = mount(
69+
<Provider store={store}>
70+
<Router>
71+
<ExploreApplications />
72+
</Router>
73+
</Provider>,
74+
);
7075
expect(wrapper.find('.odh-explore-apps__body').exists()).toBe(true);
7176
const cards = wrapper.find('.pf-m-selectable.odh-card');
7277
expect(cards.length).toBe(2);
@@ -76,7 +81,13 @@ describe('ExploreApplications', () => {
7681
});
7782

7883
it('should show the getting started panel on card click', () => {
79-
const wrapper = mount(<ExploreApplications />);
84+
const wrapper = mount(
85+
<Provider store={store}>
86+
<Router>
87+
<ExploreApplications />
88+
</Router>
89+
</Provider>,
90+
);
8091
expect(wrapper.find('.m-side-panel-open').exists()).toBe(false);
8192

8293
act(() => {

Diff for: frontend/src/components/OdhExploreCard.tsx

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import React from 'react';
22
import classNames from 'classnames';
33
import { Card, CardHeader, CardBody } from '@patternfly/react-core';
44
import { OdhApplication } from '../types';
5+
import { makeCardVisible } from '../utilities/utils';
6+
import EnableModal from '../pages/exploreApplication/EnableModal';
57
import BrandImage from './BrandImage';
68
import SupportedAppTitle from './SupportedAppTitle';
7-
import { makeCardVisible } from '../utilities/utils';
89

910
import './OdhCard.scss';
1011

@@ -13,13 +14,17 @@ type OdhExploreCardProps = {
1314
isSelected: boolean;
1415
onSelect: () => void;
1516
disableInfo?: boolean;
17+
enableOpen: boolean;
18+
onEnableClose: () => void;
1619
};
1720

1821
const OdhExploreCard: React.FC<OdhExploreCardProps> = ({
1922
odhApp,
2023
isSelected,
2124
onSelect,
2225
disableInfo = false,
26+
enableOpen,
27+
onEnableClose,
2328
}) => {
2429
const disabled = odhApp.spec.comingSoon || disableInfo;
2530
const cardClasses = classNames('odh-card', { 'm-disabled': disabled });
@@ -49,6 +54,7 @@ const OdhExploreCard: React.FC<OdhExploreCardProps> = ({
4954
</CardHeader>
5055
<SupportedAppTitle odhApp={odhApp} showProvider />
5156
<CardBody>{odhApp.spec.description}</CardBody>
57+
<EnableModal shown={enableOpen} onClose={onEnableClose} selectedApp={odhApp} />
5258
</Card>
5359
);
5460
};

Diff for: frontend/src/pages/exploreApplication/EnableModal.tsx

+31-9
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ import './EnableModal.scss';
2121

2222
type EnableModalProps = {
2323
selectedApp: OdhApplication;
24-
onClose: (success?: boolean) => void;
24+
shown: boolean;
25+
onClose: () => void;
2526
};
2627

27-
const EnableModal: React.FC<EnableModalProps> = ({ selectedApp, onClose }) => {
28+
const EnableModal: React.FC<EnableModalProps> = ({ selectedApp, shown, onClose }) => {
2829
const [postError, setPostError] = React.useState<string>('');
2930
const [validationInProgress, setValidationInProgress] = React.useState<boolean>(false);
3031
const [enableValues, setEnableValues] = React.useState<{ [key: string]: string }>({});
@@ -56,15 +57,33 @@ const EnableModal: React.FC<EnableModalProps> = ({ selectedApp, onClose }) => {
5657
React.useEffect(() => {
5758
if (validationInProgress && validationStatus === EnableApplicationStatus.SUCCESS) {
5859
setValidationInProgress(false);
59-
onClose(true);
60+
selectedApp.spec.isEnabled = true;
61+
onClose();
6062
}
6163
if (validationInProgress && validationStatus === EnableApplicationStatus.FAILED) {
6264
setValidationInProgress(false);
6365
setPostError(validationErrorMessage);
6466
}
65-
}, [onClose, validationErrorMessage, validationInProgress, validationStatus]);
67+
}, [onClose, selectedApp.spec, validationErrorMessage, validationInProgress, validationStatus]);
6668

67-
if (!selectedApp?.spec?.enable) {
69+
React.useEffect(() => {
70+
if (shown) {
71+
if (!validationInProgress) {
72+
setPostError('');
73+
}
74+
}
75+
// Only update when shown is updated to true
76+
// eslint-disable-next-line react-hooks/exhaustive-deps
77+
}, [shown]);
78+
79+
const handleClose = () => {
80+
if (!validationInProgress) {
81+
setEnableValues({});
82+
}
83+
onClose();
84+
};
85+
86+
if (!selectedApp?.spec?.enable || !shown) {
6887
return null;
6988
}
7089
const { enable } = selectedApp.spec;
@@ -76,7 +95,7 @@ const EnableModal: React.FC<EnableModalProps> = ({ selectedApp, onClose }) => {
7695
variant={ModalVariant.small}
7796
title={enable.title}
7897
isOpen
79-
onClose={() => onClose(false)}
98+
onClose={handleClose}
8099
actions={[
81100
<Button
82101
key="confirm"
@@ -86,7 +105,7 @@ const EnableModal: React.FC<EnableModalProps> = ({ selectedApp, onClose }) => {
86105
>
87106
{enable.actionLabel}
88107
</Button>,
89-
<Button key="cancel" variant="link" onClick={() => onClose()}>
108+
<Button key="cancel" variant="link" onClick={handleClose}>
90109
{validationInProgress ? 'Close' : 'Cancel'}
91110
</Button>,
92111
]}
@@ -113,10 +132,12 @@ const EnableModal: React.FC<EnableModalProps> = ({ selectedApp, onClose }) => {
113132
<Alert
114133
variantLabel="error"
115134
variant="danger"
116-
title={postError}
135+
title="Validation failed"
117136
aria-live="polite"
118137
isInline
119-
/>
138+
>
139+
{postError}
140+
</Alert>
120141
</FormAlert>
121142
) : null}
122143
{validationInProgress ? (
@@ -143,6 +164,7 @@ const EnableModal: React.FC<EnableModalProps> = ({ selectedApp, onClose }) => {
143164
inputType={enable.variables?.[key] as TextInputTypes}
144165
helperText={enable.variableHelpText?.[key] ?? ''}
145166
validationInProgress={validationInProgress}
167+
value={enableValues[key]}
146168
updateValue={(value: string) => updateEnableValue(key, value)}
147169
/>
148170
))}

Diff for: frontend/src/pages/exploreApplication/EnableVariable.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ type EnableVariableProps = {
1313
inputType: TextInputTypes;
1414
helperText?: string;
1515
validationInProgress: boolean;
16+
value: string;
1617
updateValue: (value: string) => void;
1718
};
1819

1920
const EnableVariable = React.forwardRef<HTMLInputElement, EnableVariableProps>(
20-
({ label, inputType, helperText, validationInProgress, updateValue }, ref) => {
21+
({ label, inputType, helperText, validationInProgress, value, updateValue }, ref) => {
2122
const [showPassword, setShowPassword] = React.useState<boolean>(false);
2223

2324
return (
@@ -30,7 +31,8 @@ const EnableVariable = React.forwardRef<HTMLInputElement, EnableVariableProps>(
3031
type={
3132
inputType === TextInputTypes.password && showPassword ? TextInputTypes.text : inputType
3233
}
33-
onChange={(value) => updateValue(value)}
34+
value={value || ''}
35+
onChange={(newValue) => updateValue(newValue)}
3436
/>
3537
{inputType === TextInputTypes.password ? (
3638
<Button

Diff for: frontend/src/pages/exploreApplication/ExploreApplications.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,17 @@ const ExploreApplicationsInner: React.FC<ExploreApplicationsInnerProps> = React.
3838
const bodyClasses = classNames('odh-explore-apps__body', {
3939
'm-side-panel-open': !!selectedComponent,
4040
});
41+
const [enableApp, setEnableApp] = React.useState<OdhApplication>();
42+
4143
return (
4244
<Drawer isExpanded={!dashboardConfig.disableInfo && !!selectedComponent} isInline>
4345
<DrawerContent
4446
panelContent={
45-
<GetStartedPanel onClose={() => updateSelection()} selectedApp={selectedComponent} />
47+
<GetStartedPanel
48+
onClose={() => updateSelection()}
49+
selectedApp={selectedComponent}
50+
onEnable={() => setEnableApp(selectedComponent)}
51+
/>
4652
}
4753
>
4854
<DrawerContentBody className={bodyClasses}>
@@ -64,6 +70,8 @@ const ExploreApplicationsInner: React.FC<ExploreApplicationsInnerProps> = React.
6470
isSelected={selectedComponent === c}
6571
onSelect={() => updateSelection(c.metadata.name)}
6672
disableInfo={dashboardConfig.disableInfo}
73+
enableOpen={c.metadata.name === enableApp?.metadata.name}
74+
onEnableClose={() => setEnableApp(undefined)}
6775
/>
6876
))}
6977
</Gallery>

Diff for: frontend/src/pages/exploreApplication/GetStartedPanel.tsx

+2-15
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,16 @@ import { OdhApplication } from '../../types';
2020
import { useWatchDashboardConfig } from '../../utilities/useWatchDashboardConfig';
2121
import { useGettingStarted } from '../../utilities/useGettingStarted';
2222
import MarkdownView from '../../components/MarkdownView';
23-
import EnableModal from './EnableModal';
2423

2524
import './GetStartedPanel.scss';
2625

2726
type GetStartedPanelProps = {
2827
selectedApp?: OdhApplication;
2928
onClose: () => void;
29+
onEnable: () => void;
3030
};
3131

32-
const GetStartedPanel: React.FC<GetStartedPanelProps> = ({ selectedApp, onClose }) => {
33-
const [enableOpen, setEnableOpen] = React.useState<boolean>(false);
32+
const GetStartedPanel: React.FC<GetStartedPanelProps> = ({ selectedApp, onClose, onEnable }) => {
3433
const appName = selectedApp?.metadata.name;
3534
const { odhGettingStarted, loaded, loadError } = useGettingStarted(appName);
3635
const { dashboardConfig } = useWatchDashboardConfig();
@@ -69,17 +68,6 @@ const GetStartedPanel: React.FC<GetStartedPanelProps> = ({ selectedApp, onClose
6968
return <MarkdownView markdown={odhGettingStarted?.markdown} />;
7069
};
7170

72-
const onEnableClose = (success?: boolean) => {
73-
if (success) {
74-
selectedApp.spec.isEnabled = true;
75-
}
76-
setEnableOpen(false);
77-
};
78-
79-
const onEnable = () => {
80-
setEnableOpen(true);
81-
};
82-
8371
const renderEnableButton = () => {
8472
if (!selectedApp.spec.enable || selectedApp.spec.isEnabled) {
8573
return null;
@@ -141,7 +129,6 @@ const GetStartedPanel: React.FC<GetStartedPanelProps> = ({ selectedApp, onClose
141129
{renderMarkdownContents()}
142130
</DrawerPanelBody>
143131
</DrawerPanelContent>
144-
{enableOpen ? <EnableModal onClose={onEnableClose} selectedApp={selectedApp} /> : null}
145132
</>
146133
);
147134
};

0 commit comments

Comments
 (0)