Web console: don't crash if cookies are totally disabled (#13013)

* fix local storage detection

* fix numeric input dialog
This commit is contained in:
Vadim Ogievetsky 2022-09-01 16:10:23 -07:00 committed by GitHub
parent 85d2a6d879
commit 0ae515bd3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 19 deletions

View File

@ -27,7 +27,7 @@ export async function createBrowser(): Promise<playwright.Browser> {
const headless = process.env['DRUID_E2E_TEST_HEADLESS'] || TRUE;
const debug = headless !== TRUE;
const launchOptions: any = {
args: [`--window-size=${WIDTH},${HEIGHT + PADDING}`],
args: [`--window-size=${WIDTH},${HEIGHT + PADDING}`, `--disable-local-storage`],
};
if (debug) {
launchOptions.headless = false;

View File

@ -26,6 +26,7 @@ interface NumericInputDialogProps {
message?: JSX.Element;
minValue?: number;
initValue: number;
integer?: boolean;
onSubmit(value: number): void;
onClose(): void;
}
@ -33,9 +34,19 @@ interface NumericInputDialogProps {
export const NumericInputDialog = React.memo(function NumericInputDialog(
props: NumericInputDialogProps,
) {
const { title, message, minValue, initValue, onSubmit, onClose } = props;
const { title, message, minValue, initValue, integer, onSubmit, onClose } = props;
const effectiveMinValue = minValue ?? DEFAULT_MIN_VALUE;
const [value, setValue] = useState<number>(initValue);
const [valueString, setValueString] = useState<string>(String(initValue));
function done() {
let value = Math.max(Number(valueString) || 0, effectiveMinValue);
if (integer) {
value = Math.round(value);
}
onSubmit(value);
onClose();
}
return (
<Dialog
@ -48,30 +59,41 @@ export const NumericInputDialog = React.memo(function NumericInputDialog(
<div className={Classes.DIALOG_BODY}>
{message}
<NumericInput
value={value}
onValueChange={(v: number) => {
if (isNaN(v)) return;
setValue(Math.max(v, DEFAULT_MIN_VALUE));
value={valueString}
onValueChange={(_, v) => {
// Constrain to only simple numeric characters
v = v.replace(/[^\d\-.]/, '');
if (integer) {
// If in integer mode throw away the decimal point
v = v.replace(/\./, '');
}
if (effectiveMinValue >= 0) {
// If in non-negative mode throw away the minus
v = v.replace(/-/, '');
}
setValueString(v);
}}
min={minValue ?? DEFAULT_MIN_VALUE}
onKeyDown={(e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key !== 'Enter') return;
done();
}}
min={effectiveMinValue}
stepSize={1}
minorStepSize={null}
majorStepSize={10}
fill
autoFocus
selectAllOnFocus
allowNumericCharactersOnly
/>
</div>
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button text="Close" onClick={onClose} />
<Button
text="OK"
intent={Intent.PRIMARY}
onClick={() => {
onSubmit(value);
onClose();
}}
/>
<Button text="OK" intent={Intent.PRIMARY} onClick={done} />
</div>
</div>
</Dialog>

View File

@ -18,6 +18,14 @@
import * as JSONBig from 'json-bigint-native';
function noLocalStorage(): boolean {
try {
return typeof localStorage === 'undefined';
} catch {
return true;
}
}
export const LocalStorageKeys = {
CAPABILITIES_OVERRIDE: 'capabilities-override' as const,
INGESTION_SPEC: 'ingestion-spec' as const,
@ -65,7 +73,7 @@ function prependNamespace(key: string): string {
}
export function localStorageSet(key: LocalStorageKeys, value: string): void {
if (typeof localStorage === 'undefined') return;
if (noLocalStorage()) return;
try {
localStorage.setItem(prependNamespace(key), value);
} catch (e) {
@ -78,7 +86,7 @@ export function localStorageSetJson(key: LocalStorageKeys, value: any): void {
}
export function localStorageGet(key: LocalStorageKeys): string | undefined {
if (typeof localStorage === 'undefined') return;
if (noLocalStorage()) return;
try {
return localStorage.getItem(prependNamespace(key)) || localStorage.getItem(key) || undefined;
} catch (e) {
@ -98,7 +106,7 @@ export function localStorageGetJson(key: LocalStorageKeys): any {
}
export function localStorageRemove(key: LocalStorageKeys): void {
if (typeof localStorage === 'undefined') return;
if (noLocalStorage()) return;
try {
localStorage.removeItem(prependNamespace(key));
} catch (e) {

View File

@ -103,6 +103,7 @@ export const MaxTasksButton = function MaxTasksButton(props: MaxTasksButtonProps
</>
}
minValue={2}
integer
initValue={maxNumTasks}
onSubmit={p => {
changeQueryContext(changeMaxNumTasks(queryContext, p));