diff --git a/web-console/e2e-tests/component/load-data/config/partition.ts b/web-console/e2e-tests/component/load-data/config/partition.ts index 3139484d1ba..2e168507b39 100644 --- a/web-console/e2e-tests/component/load-data/config/partition.ts +++ b/web-console/e2e-tests/component/load-data/config/partition.ts @@ -57,7 +57,11 @@ export class HashedPartitionsSpec implements PartitionsSpec { readonly type: string; static async read(page: playwright.Page): Promise { - const numShards = await getLabeledInputAsNumber(page, HashedPartitionsSpec.NUM_SHARDS); + // The shards control may not be visible in that case this is not an error, it is simply not set (null) + let numShards: number | null = null; + try { + numShards = await getLabeledInputAsNumber(page, HashedPartitionsSpec.NUM_SHARDS); + } catch {} return new HashedPartitionsSpec({ numShards }); } diff --git a/web-console/src/components/auto-form/auto-form.spec.tsx b/web-console/src/components/auto-form/auto-form.spec.tsx index c2391300a21..11dd6797723 100644 --- a/web-console/src/components/auto-form/auto-form.spec.tsx +++ b/web-console/src/components/auto-form/auto-form.spec.tsx @@ -50,7 +50,8 @@ describe('AutoForm', () => { }, { name: 'testNotDefined', type: 'string', defined: false }, - { name: 'testAdvanced', type: 'string', hideInMore: true }, + { name: 'testHide', type: 'string', hide: true }, + { name: 'testHideInMore', type: 'string', hideInMore: true }, ]} model={String} onChange={() => {}} diff --git a/web-console/src/components/auto-form/auto-form.tsx b/web-console/src/components/auto-form/auto-form.tsx index 5c8e0f63156..ee67720486a 100644 --- a/web-console/src/components/auto-form/auto-form.tsx +++ b/web-console/src/components/auto-form/auto-form.tsx @@ -56,6 +56,7 @@ export interface Field { disabled?: Functor; defined?: Functor; required?: Functor; + hide?: Functor; hideInMore?: Functor; valueAdjustment?: (value: any) => any; adjustment?: (model: M) => M; @@ -456,10 +457,15 @@ export class AutoForm> extends React.PureComponent let shouldShowMore = false; const shownFields = fields.filter(field => { if (AutoForm.evaluateFunctor(field.defined, model, true)) { + if (AutoForm.evaluateFunctor(field.hide, model, false)) { + return false; + } + if (AutoForm.evaluateFunctor(field.hideInMore, model, false)) { shouldShowMore = true; return showMore; } + return true; } else { return false; diff --git a/web-console/src/components/json-input/json-input.tsx b/web-console/src/components/json-input/json-input.tsx index dcf9a269da5..9ebd5e5f4b4 100644 --- a/web-console/src/components/json-input/json-input.tsx +++ b/web-console/src/components/json-input/json-input.tsx @@ -67,6 +67,7 @@ interface InternalValue { interface JsonInputProps { value: any; onChange: (value: any) => void; + onError?: (error: Error) => void; placeholder?: string; focus?: boolean; width?: string; @@ -75,7 +76,7 @@ interface JsonInputProps { } export const JsonInput = React.memo(function JsonInput(props: JsonInputProps) { - const { onChange, placeholder, focus, width, height, value, issueWithValue } = props; + const { onChange, onError, placeholder, focus, width, height, value, issueWithValue } = props; const [internalValue, setInternalValue] = useState(() => ({ value, stringified: stringifyJson(value), @@ -120,7 +121,9 @@ export const JsonInput = React.memo(function JsonInput(props: JsonInputProps) { stringified: inputJson, }); - if (!error) { + if (error) { + onError?.(error); + } else { onChange(value); } diff --git a/web-console/src/dialogs/compaction-dialog/__snapshots__/compaction-dialog.spec.tsx.snap b/web-console/src/dialogs/compaction-dialog/__snapshots__/compaction-dialog.spec.tsx.snap index ba969a43086..c7e89303c9d 100644 --- a/web-console/src/dialogs/compaction-dialog/__snapshots__/compaction-dialog.spec.tsx.snap +++ b/web-console/src/dialogs/compaction-dialog/__snapshots__/compaction-dialog.spec.tsx.snap @@ -86,6 +86,28 @@ exports[`CompactionDialog matches snapshot with compactionConfig (dynamic partit

, "name": "tuningConfig.partitionsSpec.targetRowsPerSegment", + "placeholder": "(defaults to 500000)", + "type": "number", + "zeroMeansUndefined": true, + }, + Object { + "defined": [Function], + "info": +

+ Target number of rows to include in a partition, should be a number that targets segments of 500MB~1GB. +

+

+ + maxRowsPerSegment + + is an alias for + + targetRowsPerSegment + + . Only one of these properties can be used. +

+
, + "name": "tuningConfig.partitionsSpec.maxRowsPerSegment", "type": "number", "zeroMeansUndefined": true, }, @@ -335,6 +357,28 @@ exports[`CompactionDialog matches snapshot with compactionConfig (hashed partiti

, "name": "tuningConfig.partitionsSpec.targetRowsPerSegment", + "placeholder": "(defaults to 500000)", + "type": "number", + "zeroMeansUndefined": true, + }, + Object { + "defined": [Function], + "info": +

+ Target number of rows to include in a partition, should be a number that targets segments of 500MB~1GB. +

+

+ + maxRowsPerSegment + + is an alias for + + targetRowsPerSegment + + . Only one of these properties can be used. +

+
, + "name": "tuningConfig.partitionsSpec.maxRowsPerSegment", "type": "number", "zeroMeansUndefined": true, }, @@ -584,6 +628,28 @@ exports[`CompactionDialog matches snapshot with compactionConfig (single_dim par

, "name": "tuningConfig.partitionsSpec.targetRowsPerSegment", + "placeholder": "(defaults to 500000)", + "type": "number", + "zeroMeansUndefined": true, + }, + Object { + "defined": [Function], + "info": +

+ Target number of rows to include in a partition, should be a number that targets segments of 500MB~1GB. +

+

+ + maxRowsPerSegment + + is an alias for + + targetRowsPerSegment + + . Only one of these properties can be used. +

+
, + "name": "tuningConfig.partitionsSpec.maxRowsPerSegment", "type": "number", "zeroMeansUndefined": true, }, @@ -833,6 +899,28 @@ exports[`CompactionDialog matches snapshot without compactionConfig 1`] = `

, "name": "tuningConfig.partitionsSpec.targetRowsPerSegment", + "placeholder": "(defaults to 500000)", + "type": "number", + "zeroMeansUndefined": true, + }, + Object { + "defined": [Function], + "info": +

+ Target number of rows to include in a partition, should be a number that targets segments of 500MB~1GB. +

+

+ + maxRowsPerSegment + + is an alias for + + targetRowsPerSegment + + . Only one of these properties can be used. +

+
, + "name": "tuningConfig.partitionsSpec.maxRowsPerSegment", "type": "number", "zeroMeansUndefined": true, }, diff --git a/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx b/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx index 8c96e9765f9..d63501b1b0b 100644 --- a/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx +++ b/web-console/src/dialogs/compaction-dialog/compaction-dialog.tsx @@ -42,12 +42,10 @@ export const CompactionDialog = React.memo(function CompactionDialog(props: Comp tuningConfig: { partitionsSpec: { type: 'dynamic' } }, }, ); + const [jsonError, setJsonError] = useState(); const issueWithCurrentConfig = AutoForm.issueWithModel(currentConfig, COMPACTION_CONFIG_FIELDS); - function handleSubmit() { - if (issueWithCurrentConfig) return; - onSave(currentConfig); - } + const disableSubmit = Boolean(jsonError || issueWithCurrentConfig); return ( { + setCurrentConfig(v); + setJsonError(undefined); + }} + onError={setJsonError} issueWithValue={value => AutoForm.issueWithModel(value, COMPACTION_CONFIG_FIELDS)} height="100%" /> @@ -81,8 +83,8 @@ export const CompactionDialog = React.memo(function CompactionDialog(props: Comp