Skip to content

Commit e897daa

Browse files
committed
[ML] Improving model snapshot revert UI experience
1 parent f7fdda5 commit e897daa

File tree

2 files changed

+47
-28
lines changed

2 files changed

+47
-28
lines changed

x-pack/plugins/ml/public/application/components/model_snapshots/model_snapshots_table.tsx

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,24 @@ export const ModelSnapshotTable: FC<Props> = ({ job, refreshJobList }) => {
5050
const [closeJobModalVisible, setCloseJobModalVisible] = useState<ModelSnapshot | null>(null);
5151
const [combinedJobState, setCombinedJobState] = useState<COMBINED_JOB_STATE | null>(null);
5252

53+
let unmounted = false;
5354
useEffect(() => {
5455
loadModelSnapshots();
56+
return () => {
57+
unmounted = true;
58+
};
5559
}, []);
5660

57-
const loadModelSnapshots = useCallback(async () => {
61+
async function loadModelSnapshots() {
62+
if (unmounted === true) {
63+
// table refresh can be triggered a while after a snapshot revert has been triggered.
64+
// ensure the table is still visible before attempted to refresh it.
65+
return;
66+
}
5867
const { model_snapshots: ms } = await ml.getModelSnapshots(job.job_id);
5968
setSnapshots(ms);
6069
setSnapshotsLoaded(true);
61-
}, [job]);
70+
}
6271

6372
const checkJobIsClosed = useCallback(
6473
async (snapshot: ModelSnapshot) => {
@@ -107,13 +116,14 @@ export const ModelSnapshotTable: FC<Props> = ({ job, refreshJobList }) => {
107116
}
108117
}, []);
109118

110-
const closeRevertFlyout = useCallback((reload: boolean) => {
119+
const closeRevertFlyout = useCallback(() => {
111120
setRevertSnapshot(null);
112-
if (reload) {
113-
loadModelSnapshots();
114-
// wait half a second before refreshing the jobs list
115-
setTimeout(refreshJobList, 500);
116-
}
121+
}, []);
122+
123+
const refresh = useCallback(() => {
124+
loadModelSnapshots();
125+
// wait half a second before refreshing the jobs list
126+
setTimeout(refreshJobList, 500);
117127
}, []);
118128

119129
const columns: Array<EuiBasicTableColumn<any>> = [
@@ -231,6 +241,7 @@ export const ModelSnapshotTable: FC<Props> = ({ job, refreshJobList }) => {
231241
snapshots={snapshots}
232242
job={job}
233243
closeFlyout={closeRevertFlyout}
244+
refresh={refresh}
234245
/>
235246
)}
236247

x-pack/plugins/ml/public/application/components/model_snapshots/revert_model_snapshot_flyout/revert_model_snapshot_flyout.tsx

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,17 @@ interface Props {
5353
snapshot: ModelSnapshot;
5454
snapshots: ModelSnapshot[];
5555
job: CombinedJobWithStats;
56-
closeFlyout(reload: boolean): void;
56+
closeFlyout(): void;
57+
refresh(): void;
5758
}
5859

59-
export const RevertModelSnapshotFlyout: FC<Props> = ({ snapshot, snapshots, job, closeFlyout }) => {
60+
export const RevertModelSnapshotFlyout: FC<Props> = ({
61+
snapshot,
62+
snapshots,
63+
job,
64+
closeFlyout,
65+
refresh,
66+
}) => {
6067
const { toasts } = useNotifications();
6168
const { loadAnomalyDataForJob, loadEventRateForJob } = useMemo(
6269
() => chartLoaderProvider(mlResultsService),
@@ -110,13 +117,6 @@ export const RevertModelSnapshotFlyout: FC<Props> = ({ snapshot, snapshots, job,
110117
setChartReady(true);
111118
}, [job]);
112119

113-
function closeWithReload() {
114-
closeFlyout(true);
115-
}
116-
function closeWithoutReload() {
117-
closeFlyout(false);
118-
}
119-
120120
function showRevertModal() {
121121
setRevertModalVisible(true);
122122
}
@@ -138,15 +138,18 @@ export const RevertModelSnapshotFlyout: FC<Props> = ({ snapshot, snapshots, job,
138138
}))
139139
: undefined;
140140

141-
await ml.jobs.revertModelSnapshot(
142-
job.job_id,
143-
currentSnapshot.snapshot_id,
144-
replay,
145-
end,
146-
events
147-
);
141+
ml.jobs
142+
.revertModelSnapshot(job.job_id, currentSnapshot.snapshot_id, replay, end, events)
143+
.then(() => {
144+
toasts.addSuccess(
145+
i18n.translate('xpack.ml.revertModelSnapshotFlyout.revertSuccessTitle', {
146+
defaultMessage: 'Model snapshot revert successful',
147+
})
148+
);
149+
refresh();
150+
});
148151
hideRevertModal();
149-
closeWithReload();
152+
closeFlyout();
150153
} catch (error) {
151154
setApplying(false);
152155
toasts.addError(new Error(error.body.message), {
@@ -166,7 +169,7 @@ export const RevertModelSnapshotFlyout: FC<Props> = ({ snapshot, snapshots, job,
166169

167170
return (
168171
<>
169-
<EuiFlyout onClose={closeWithoutReload} hideCloseButton size="m">
172+
<EuiFlyout onClose={closeFlyout} hideCloseButton size="m">
170173
<EuiFlyoutHeader hasBorder>
171174
<EuiTitle size="s">
172175
<h5>
@@ -347,7 +350,7 @@ export const RevertModelSnapshotFlyout: FC<Props> = ({ snapshot, snapshots, job,
347350
<EuiFlyoutFooter>
348351
<EuiFlexGroup justifyContent="spaceBetween">
349352
<EuiFlexItem grow={false}>
350-
<EuiButtonEmpty iconType="cross" onClick={closeWithoutReload} flush="left">
353+
<EuiButtonEmpty iconType="cross" onClick={closeFlyout} flush="left">
351354
<FormattedMessage
352355
id="xpack.ml.newJob.wizard.revertModelSnapshotFlyout.closeButton"
353356
defaultMessage="Close"
@@ -395,7 +398,12 @@ export const RevertModelSnapshotFlyout: FC<Props> = ({ snapshot, snapshots, job,
395398
confirmButtonDisabled={applying}
396399
buttonColor="danger"
397400
defaultFocusedButton="confirm"
398-
/>
401+
>
402+
<FormattedMessage
403+
id="xpack.ml.newJob.wizard.revertModelSnapshotFlyout.modalBody"
404+
defaultMessage="The snapshot revert will be carried out in the background and may take some time."
405+
/>
406+
</EuiConfirmModal>
399407
</EuiOverlayMask>
400408
)}
401409
</>

0 commit comments

Comments
 (0)