From 7e53f23f07b4d284f6219dfd5e87225b249d9931 Mon Sep 17 00:00:00 2001 From: Vadim Ogievetsky Date: Tue, 4 Feb 2020 15:33:52 -0800 Subject: [PATCH] Web console: make supervisor reset really scary in the UI (#9253) * make supervisor reset really scary * change warnings * add text --- .../warning-checklist.spec.tsx.snap | 41 +++++++++++++++++ .../warning-checklist.spec.tsx | 33 +++++++++++++ .../warning-checklist/warning-checklist.tsx | 46 +++++++++++++++++++ .../async-action-dialog.tsx | 16 ++++++- .../views/ingestion-view/ingestion-view.tsx | 20 +++++--- 5 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 web-console/src/components/warning-checklist/__snapshots__/warning-checklist.spec.tsx.snap create mode 100644 web-console/src/components/warning-checklist/warning-checklist.spec.tsx create mode 100644 web-console/src/components/warning-checklist/warning-checklist.tsx diff --git a/web-console/src/components/warning-checklist/__snapshots__/warning-checklist.spec.tsx.snap b/web-console/src/components/warning-checklist/__snapshots__/warning-checklist.spec.tsx.snap new file mode 100644 index 00000000000..afadb07f381 --- /dev/null +++ b/web-console/src/components/warning-checklist/__snapshots__/warning-checklist.spec.tsx.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`warning checklist matches snapshot 1`] = ` +
+ + + +
+`; diff --git a/web-console/src/components/warning-checklist/warning-checklist.spec.tsx b/web-console/src/components/warning-checklist/warning-checklist.spec.tsx new file mode 100644 index 00000000000..6a7c95759fe --- /dev/null +++ b/web-console/src/components/warning-checklist/warning-checklist.spec.tsx @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { render } from '@testing-library/react'; +import React from 'react'; + +import { WarningChecklist } from './warning-checklist'; + +describe('warning checklist', () => { + it('matches snapshot', () => { + const warningChecklist = ( + {}} /> + ); + + const { container } = render(warningChecklist); + expect(container.firstChild).toMatchSnapshot(); + }); +}); diff --git a/web-console/src/components/warning-checklist/warning-checklist.tsx b/web-console/src/components/warning-checklist/warning-checklist.tsx new file mode 100644 index 00000000000..cef323f30cf --- /dev/null +++ b/web-console/src/components/warning-checklist/warning-checklist.tsx @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Checkbox } from '@blueprintjs/core'; +import React, { useState } from 'react'; + +export interface WarningChecklistProps { + checks: string[]; + onChange: (allChecked: boolean) => void; +} + +export const WarningChecklist = React.memo(function WarningChecklist(props: WarningChecklistProps) { + const { checks, onChange } = props; + const [checked, setChecked] = useState>({}); + + function doCheck(check: string) { + const newChecked = Object.assign({}, checked); + newChecked[check] = !newChecked[check]; + setChecked(newChecked); + + onChange(checks.every(check => newChecked[check])); + } + + return ( +
+ {checks.map((check, i) => { + return doCheck(check)} />; + })} +
+ ); +}); diff --git a/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx b/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx index 162c53be993..7e07d467a70 100644 --- a/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx +++ b/web-console/src/dialogs/async-action-dialog/async-action-dialog.tsx @@ -30,6 +30,7 @@ import { IconNames } from '@blueprintjs/icons'; import classNames from 'classnames'; import React, { ReactNode, useState } from 'react'; +import { WarningChecklist } from '../../components/warning-checklist/warning-checklist'; import { AppToaster } from '../../singletons/toaster'; import './async-action-dialog.scss'; @@ -46,6 +47,7 @@ export interface AsyncActionDialogProps { intent?: Intent; successText: string; failText: string; + warningChecks?: string[]; children?: ReactNode; } @@ -64,11 +66,16 @@ export const AsyncActionDialog = React.memo(function AsyncActionDialog( confirmButtonText, confirmButtonDisabled, cancelButtonText, + warningChecks, children, } = props; const [working, setWorking] = useState(false); + const [allWarningsChecked, setAllWarningsChecked] = useState(false); + const needsMoreChecks = Boolean(warningChecks && !allWarningsChecked); async function handleConfirm() { + if (needsMoreChecks) return; + setWorking(true); try { await action(); @@ -108,7 +115,12 @@ export const AsyncActionDialog = React.memo(function AsyncActionDialog( ) : ( <> {icon && } -
{children}
+
+ {children} + {warningChecks && ( + + )} +
)} @@ -121,7 +133,7 @@ export const AsyncActionDialog = React.memo(function AsyncActionDialog( intent={intent} text={confirmButtonText} onClick={handleConfirm} - disabled={confirmButtonDisabled} + disabled={confirmButtonDisabled || needsMoreChecks} />