mirror of https://github.com/apache/druid.git
Web console: make supervisor reset really scary in the UI (#9253)
* make supervisor reset really scary * change warnings * add text
This commit is contained in:
parent
556a3861ed
commit
7e53f23f07
|
@ -0,0 +1,41 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`warning checklist matches snapshot 1`] = `
|
||||
<div
|
||||
class="warning-checklist"
|
||||
>
|
||||
<label
|
||||
class="bp3-control bp3-checkbox"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="bp3-control-indicator"
|
||||
/>
|
||||
Check A
|
||||
</label>
|
||||
<label
|
||||
class="bp3-control bp3-checkbox"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="bp3-control-indicator"
|
||||
/>
|
||||
Check B
|
||||
</label>
|
||||
<label
|
||||
class="bp3-control bp3-checkbox"
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="bp3-control-indicator"
|
||||
/>
|
||||
I am totes sure
|
||||
</label>
|
||||
</div>
|
||||
`;
|
|
@ -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 = (
|
||||
<WarningChecklist checks={['Check A', 'Check B', 'I am totes sure']} onChange={() => {}} />
|
||||
);
|
||||
|
||||
const { container } = render(warningChecklist);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -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<Record<string, boolean>>({});
|
||||
|
||||
function doCheck(check: string) {
|
||||
const newChecked = Object.assign({}, checked);
|
||||
newChecked[check] = !newChecked[check];
|
||||
setChecked(newChecked);
|
||||
|
||||
onChange(checks.every(check => newChecked[check]));
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="warning-checklist">
|
||||
{checks.map((check, i) => {
|
||||
return <Checkbox key={i} label={check} onChange={() => doCheck(check)} />;
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
});
|
|
@ -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 && <Icon icon={icon} />}
|
||||
<div className={Classes.ALERT_CONTENTS}>{children}</div>
|
||||
<div className={Classes.ALERT_CONTENTS}>
|
||||
{children}
|
||||
{warningChecks && (
|
||||
<WarningChecklist checks={warningChecks} onChange={setAllWarningsChecked} />
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
@ -121,7 +133,7 @@ export const AsyncActionDialog = React.memo(function AsyncActionDialog(
|
|||
intent={intent}
|
||||
text={confirmButtonText}
|
||||
onClick={handleConfirm}
|
||||
disabled={confirmButtonDisabled}
|
||||
disabled={confirmButtonDisabled || needsMoreChecks}
|
||||
/>
|
||||
<Button text={cancelButtonText || 'Cancel'} onClick={onClose} />
|
||||
</>
|
||||
|
|
|
@ -418,7 +418,7 @@ ORDER BY "rank" DESC, "created_time" DESC`;
|
|||
},
|
||||
{
|
||||
icon: IconNames.STEP_BACKWARD,
|
||||
title: 'Reset',
|
||||
title: 'Hard reset',
|
||||
intent: Intent.DANGER,
|
||||
onAction: () => this.setState({ resetSupervisorId: id }),
|
||||
},
|
||||
|
@ -503,9 +503,9 @@ ORDER BY "rank" DESC, "created_time" DESC`;
|
|||
);
|
||||
return resp.data;
|
||||
}}
|
||||
confirmButtonText="Reset supervisor"
|
||||
successText="Supervisor has been reset"
|
||||
failText="Could not reset supervisor"
|
||||
confirmButtonText="Hard reset supervisor"
|
||||
successText="Supervisor has been hard reset"
|
||||
failText="Could not hard reset supervisor"
|
||||
intent={Intent.DANGER}
|
||||
onClose={() => {
|
||||
this.setState({ resetSupervisorId: undefined });
|
||||
|
@ -513,9 +513,17 @@ ORDER BY "rank" DESC, "created_time" DESC`;
|
|||
onSuccess={() => {
|
||||
this.supervisorQueryManager.rerunLastQuery();
|
||||
}}
|
||||
warningChecks={[
|
||||
`I understand that resetting ${resetSupervisorId} will clear checkpoints and therefore lead to data loss or duplication.`,
|
||||
'I understand that this operation cannot be undone.',
|
||||
]}
|
||||
>
|
||||
<p>{`Are you sure you want to reset supervisor '${resetSupervisorId}'?`}</p>
|
||||
<p>Resetting a supervisor will lead to data loss or data duplication.</p>
|
||||
<p>{`Are you sure you want to hard reset supervisor '${resetSupervisorId}'?`}</p>
|
||||
<p>Hard resetting a supervisor will lead to data loss or data duplication.</p>
|
||||
<p>
|
||||
The reason for using this operation is to recover from a state in which the supervisor
|
||||
ceases operating due to missing offsets.
|
||||
</p>
|
||||
</AsyncActionDialog>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue