diff --git a/web-console/script/create-sql-docs.js b/web-console/script/create-sql-docs.js index 71ac809915c..6e76041d201 100755 --- a/web-console/script/create-sql-docs.js +++ b/web-console/script/create-sql-docs.js @@ -23,7 +23,7 @@ const fs = require('fs-extra'); const readfile = '../docs/querying/sql.md'; const writefile = 'lib/sql-docs.js'; -const MINIMUM_EXPECTED_NUMBER_OF_FUNCTIONS = 134; +const MINIMUM_EXPECTED_NUMBER_OF_FUNCTIONS = 152; const MINIMUM_EXPECTED_NUMBER_OF_DATA_TYPES = 14; function unwrapMarkdownLinks(str) { @@ -41,7 +41,7 @@ const readDoc = async () => { const functionDocs = []; const dataTypeDocs = []; for (let line of lines) { - const functionMatch = line.match(/^\|`(\w+)\(([^|]*)\)`\|([^|]+)\|(?:([^|]+)\|)?$/); + const functionMatch = line.match(/^\|\s*`(\w+)\(([^|]*)\)`\s*\|([^|]+)\|(?:([^|]+)\|)?$/); if (functionMatch) { functionDocs.push([ functionMatch[1], diff --git a/web-console/src/components/auto-form/auto-form.tsx b/web-console/src/components/auto-form/auto-form.tsx index f2f13a2820f..af4f82b902d 100644 --- a/web-console/src/components/auto-form/auto-form.tsx +++ b/web-console/src/components/auto-form/auto-form.tsx @@ -20,7 +20,7 @@ import { Button, ButtonGroup, FormGroup, Intent, NumericInput } from '@blueprint import { IconNames } from '@blueprintjs/icons'; import React from 'react'; -import { deepDelete, deepGet, deepSet } from '../../utils'; +import { deepDelete, deepGet, deepSet, durationSanitizer } from '../../utils'; import { ArrayInput } from '../array-input/array-input'; import { FormGroupWithInfo } from '../form-group-with-info/form-group-with-info'; import { IntervalInput } from '../interval-input/interval-input'; @@ -281,15 +281,16 @@ export class AutoForm> extends React.PureComponent ); } - private renderStringInput(field: Field, sanitize?: (str: string) => string): JSX.Element { + private renderStringInput(field: Field, sanitizer?: (str: string) => string): JSX.Element { const { model, large, onFinalize } = this.props; const { required, defaultValue, modelValue } = AutoForm.computeFieldValues(model, field); return ( { - if (sanitize && typeof v === 'string') v = sanitize(v); this.fieldChange(field, v); }} onBlur={() => { @@ -397,9 +398,7 @@ export class AutoForm> extends React.PureComponent case 'string': return this.renderStringInput(field); case 'duration': - return this.renderStringInput(field, (str: string) => - str.toUpperCase().replace(/[^0-9PYMDTHS.,]/g, ''), - ); + return this.renderStringInput(field, durationSanitizer); case 'boolean': return this.renderBooleanInput(field); case 'string-array': diff --git a/web-console/src/components/form-group-with-info/__snapshots__/form-group-with-info.spec.tsx.snap b/web-console/src/components/form-group-with-info/__snapshots__/form-group-with-info.spec.tsx.snap index 1d954642954..5e3f725b524 100644 --- a/web-console/src/components/form-group-with-info/__snapshots__/form-group-with-info.spec.tsx.snap +++ b/web-console/src/components/form-group-with-info/__snapshots__/form-group-with-info.spec.tsx.snap @@ -13,7 +13,7 @@ exports[`form group with info matches snapshot 1`] = ` class="bp3-text-muted" > .bp3-popover2-target { + & > .info-popover { position: absolute; right: 0; top: 5px; diff --git a/web-console/src/components/form-group-with-info/form-group-with-info.tsx b/web-console/src/components/form-group-with-info/form-group-with-info.tsx index c6113b21a8d..1130e7fa7e0 100644 --- a/web-console/src/components/form-group-with-info/form-group-with-info.tsx +++ b/web-console/src/components/form-group-with-info/form-group-with-info.tsx @@ -36,7 +36,7 @@ export const FormGroupWithInfo = React.memo(function FormGroupWithInfo( const { label, info, inlineInfo, children } = props; const popover = ( - + ); diff --git a/web-console/src/components/formatted-input-group/__snapshots__/formatted-input-group.spec.tsx.snap b/web-console/src/components/formatted-input-group/__snapshots__/formatted-input-group.spec.tsx.snap deleted file mode 100644 index 672f5726649..00000000000 --- a/web-console/src/components/formatted-input-group/__snapshots__/formatted-input-group.spec.tsx.snap +++ /dev/null @@ -1,25 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`FormattedInputGroup matches snapshot on undefined value 1`] = ` -
- -
-`; - -exports[`FormattedInputGroup matches snapshot with escaped value 1`] = ` -
- -
-`; diff --git a/web-console/src/components/formatted-input-group/formatted-input-group.tsx b/web-console/src/components/formatted-input-group/formatted-input-group.tsx deleted file mode 100644 index 5622906bfb3..00000000000 --- a/web-console/src/components/formatted-input-group/formatted-input-group.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 { InputGroup, InputGroupProps2 } from '@blueprintjs/core'; -import classNames from 'classnames'; -import React, { useState } from 'react'; - -import { Formatter } from '../../utils'; - -export interface FormattedInputGroupProps extends InputGroupProps2 { - formatter: Formatter; - onValueChange: (newValue: undefined | string) => void; -} - -export const FormattedInputGroup = React.memo(function FormattedInputGroup( - props: FormattedInputGroupProps, -) { - const { className, formatter, value, defaultValue, onValueChange, onBlur, ...rest } = props; - - const [intermediateValue, setIntermediateValue] = useState(); - - return ( - { - const rawValue = e.target.value; - setIntermediateValue(rawValue); - - let parsedValue: string | undefined; - try { - parsedValue = formatter.parse(rawValue); - } catch { - return; - } - onValueChange(parsedValue); - }} - onBlur={e => { - setIntermediateValue(undefined); - onBlur?.(e); - }} - {...rest} - /> - ); -}); diff --git a/web-console/src/components/formatted-input/__snapshots__/formatted-input.spec.tsx.snap b/web-console/src/components/formatted-input/__snapshots__/formatted-input.spec.tsx.snap new file mode 100644 index 00000000000..27b677dd0bf --- /dev/null +++ b/web-console/src/components/formatted-input/__snapshots__/formatted-input.spec.tsx.snap @@ -0,0 +1,33 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`FormattedInput matches snapshot on undefined value 1`] = ` +
+
+ +
+
+`; + +exports[`FormattedInput matches snapshot with escaped value 1`] = ` +
+
+ +
+
+`; diff --git a/web-console/src/components/formatted-input/formatted-input.scss b/web-console/src/components/formatted-input/formatted-input.scss new file mode 100644 index 00000000000..4369df8b5b1 --- /dev/null +++ b/web-console/src/components/formatted-input/formatted-input.scss @@ -0,0 +1,29 @@ +/* + * 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. + */ + +.formatted-input { + position: relative; + + & > .bp3-popover2-target { + position: absolute; + width: 0; + right: 0; + top: 0; + bottom: 0; + } +} diff --git a/web-console/src/components/formatted-input-group/formatted-input-group.spec.tsx b/web-console/src/components/formatted-input/formatted-input.spec.tsx similarity index 87% rename from web-console/src/components/formatted-input-group/formatted-input-group.spec.tsx rename to web-console/src/components/formatted-input/formatted-input.spec.tsx index dfa6739ee8d..da74ec71115 100644 --- a/web-console/src/components/formatted-input-group/formatted-input-group.spec.tsx +++ b/web-console/src/components/formatted-input/formatted-input.spec.tsx @@ -21,12 +21,12 @@ import React from 'react'; import { JSON_STRING_FORMATTER } from '../../utils'; -import { FormattedInputGroup } from './formatted-input-group'; +import { FormattedInput } from './formatted-input'; -describe('FormattedInputGroup', () => { +describe('FormattedInput', () => { it('matches snapshot on undefined value', () => { const suggestibleInput = ( - {}} formatter={JSON_STRING_FORMATTER} /> + {}} formatter={JSON_STRING_FORMATTER} /> ); const { container } = render(suggestibleInput); @@ -35,7 +35,7 @@ describe('FormattedInputGroup', () => { it('matches snapshot with escaped value', () => { const suggestibleInput = ( - {}} formatter={JSON_STRING_FORMATTER} diff --git a/web-console/src/components/formatted-input/formatted-input.tsx b/web-console/src/components/formatted-input/formatted-input.tsx new file mode 100644 index 00000000000..fb3c0a7bd4a --- /dev/null +++ b/web-console/src/components/formatted-input/formatted-input.tsx @@ -0,0 +1,107 @@ +/* + * 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 { InputGroup, InputGroupProps2, Intent } from '@blueprintjs/core'; +import { Tooltip2 } from '@blueprintjs/popover2'; +import classNames from 'classnames'; +import React, { useState } from 'react'; + +import { Formatter } from '../../utils'; + +import './formatted-input.scss'; + +export interface FormattedInputProps extends InputGroupProps2 { + formatter: Formatter; + onValueChange: (newValue: undefined | string) => void; + sanitizer?: (rawValue: string) => string; + issueWithValue?: (value: any) => string | undefined; +} + +export const FormattedInput = React.memo(function FormattedInput(props: FormattedInputProps) { + const { + className, + formatter, + sanitizer, + issueWithValue, + value, + defaultValue, + onValueChange, + onFocus, + onBlur, + intent, + ...rest + } = props; + + const [intermediateValue, setIntermediateValue] = useState(); + const [isFocused, setIsFocused] = useState(false); + + const issue: string | undefined = issueWithValue?.(value); + const showIssue = Boolean(!isFocused && issue); + + return ( +
+ { + let rawValue = e.target.value; + if (sanitizer) rawValue = sanitizer(rawValue); + setIntermediateValue(rawValue); + + let parsedValue: string | undefined; + try { + parsedValue = formatter.parse(rawValue); + } catch { + return; + } + onValueChange(parsedValue); + }} + onFocus={e => { + setIsFocused(true); + onFocus?.(e); + }} + onBlur={e => { + setIntermediateValue(undefined); + setIsFocused(false); + onBlur?.(e); + }} + intent={showIssue ? Intent.DANGER : intent} + {...rest} + /> + {showIssue && ( + +
+ + )} +
+ ); +}); diff --git a/web-console/src/components/index.ts b/web-console/src/components/index.ts index 7b412960c5b..fdefa7cc34b 100644 --- a/web-console/src/components/index.ts +++ b/web-console/src/components/index.ts @@ -25,7 +25,7 @@ export * from './center-message/center-message'; export * from './clearable-input/clearable-input'; export * from './external-link/external-link'; export * from './form-json-selector/form-json-selector'; -export * from './formatted-input-group/formatted-input-group'; +export * from './formatted-input/formatted-input'; export * from './header-bar/header-bar'; export * from './highlight-text/highlight-text'; export * from './json-collapse/json-collapse'; diff --git a/web-console/src/components/rule-editor/rule-editor.tsx b/web-console/src/components/rule-editor/rule-editor.tsx index c062e63e682..c2546d62c62 100644 --- a/web-console/src/components/rule-editor/rule-editor.tsx +++ b/web-console/src/components/rule-editor/rule-editor.tsx @@ -30,6 +30,7 @@ import { import { IconNames } from '@blueprintjs/icons'; import React, { useState } from 'react'; +import { durationSanitizer } from '../../utils'; import { Rule, RuleUtil } from '../../utils/load-rule'; import { SuggestibleInput } from '../suggestible-input/suggestible-input'; @@ -175,10 +176,9 @@ export const RuleEditor = React.memo(function RuleEditor(props: RuleEditorProps) {RuleUtil.hasPeriod(rule) && ( { if (typeof period === 'undefined') return; - // Ensure the period is upper case and does not contain anytihng but the allowed chars - period = period.toUpperCase().replace(/[^PYMDTHS0-9]/g, ''); onChange(RuleUtil.changePeriod(rule, period)); }} placeholder={PERIOD_SUGGESTIONS[0]} diff --git a/web-console/src/components/suggestible-input/__snapshots__/suggestible-input.spec.tsx.snap b/web-console/src/components/suggestible-input/__snapshots__/suggestible-input.spec.tsx.snap index 5686c8a7203..6db0dccc214 100644 --- a/web-console/src/components/suggestible-input/__snapshots__/suggestible-input.spec.tsx.snap +++ b/web-console/src/components/suggestible-input/__snapshots__/suggestible-input.spec.tsx.snap @@ -2,90 +2,98 @@ exports[`SuggestibleInput matches snapshot 1`] = `
- - + - + + + caret-down + + + + + + - +
`; exports[`SuggestibleInput matches snapshot with escaped value 1`] = `
- - + - + + + caret-down + + + + + + - +
`; diff --git a/web-console/src/components/suggestible-input/suggestible-input.tsx b/web-console/src/components/suggestible-input/suggestible-input.tsx index 710bc134ec2..6723bea53fb 100644 --- a/web-console/src/components/suggestible-input/suggestible-input.tsx +++ b/web-console/src/components/suggestible-input/suggestible-input.tsx @@ -23,10 +23,7 @@ import classNames from 'classnames'; import React, { useRef } from 'react'; import { JSON_STRING_FORMATTER } from '../../utils'; -import { - FormattedInputGroup, - FormattedInputGroupProps, -} from '../formatted-input-group/formatted-input-group'; +import { FormattedInput, FormattedInputProps } from '../formatted-input/formatted-input'; export interface SuggestionGroup { group: string; @@ -35,7 +32,7 @@ export interface SuggestionGroup { export type Suggestion = undefined | string | SuggestionGroup; -export interface SuggestibleInputProps extends Omit { +export interface SuggestibleInputProps extends Omit { onFinalize?: () => void; suggestions?: Suggestion[]; } @@ -60,7 +57,7 @@ export const SuggestibleInput = React.memo(function SuggestibleInput(props: Sugg } return ( - } value="test" @@ -86,7 +87,7 @@ exports[`LookupEditDialog matches snapshot 1`] = ` }, Object { "defined": [Function], - "label": "Globally cached lookup type", + "label": "Extraction type", "name": "extractionNamespace.type", "placeholder": "uri", "required": true, @@ -98,7 +99,27 @@ exports[`LookupEditDialog matches snapshot 1`] = ` }, Object { "defined": [Function], - "info": "A URI which specifies a directory (or other searchable resource) in which to search for files", + "info":

+ A URI which specifies a directory (or other searchable resource) in which to search for files specified as a + + file + + , + + hdfs + + , + + s3 + + , or + + + gs + + path prefix. +

, + "issueWithValue": [Function], "label": "URI prefix", "name": "extractionNamespace.uriPrefix", "placeholder": "s3://bucket/some/key/prefix/", @@ -109,12 +130,30 @@ exports[`LookupEditDialog matches snapshot 1`] = ` "defined": [Function], "info":

- URI for the file of interest, specified as a file, hdfs, or s3 path + URI for the file of interest, specified as a + + file + + , + + hdfs + + , + + + s3 + + , or + + gs + + path

The URI prefix option is strictly better than URI and should be used instead

, + "issueWithValue": [Function], "label": "URI (deprecated)", "name": "extractionNamespace.uri", "placeholder": "s3://bucket/some/key/prefix/lookups-01.gz", @@ -154,10 +193,22 @@ exports[`LookupEditDialog matches snapshot 1`] = ` ], "type": "string", }, + Object { + "defaultValue": " ", + "defined": [Function], + "name": "extractionNamespace.namespaceParseSpec.delimiter", + "suggestions": Array [ + " ", + ";", + "|", + "#", + ], + "type": "string", + }, Object { "defaultValue": 0, "defined": [Function], - "info": "Number of header rows to be skipped. The default number of header rows to be skipped is 0.", + "info": "Number of header rows to be skipped.", "name": "extractionNamespace.namespaceParseSpec.skipHeaderRows", "type": "number", }, @@ -172,7 +223,7 @@ exports[`LookupEditDialog matches snapshot 1`] = ` "defined": [Function], "info": "The list of columns in the csv file", "name": "extractionNamespace.namespaceParseSpec.columns", - "placeholder": "[\\"key\\", \\"value\\"]", + "placeholder": "key, value", "required": [Function], "type": "string-array", }, @@ -190,18 +241,6 @@ exports[`LookupEditDialog matches snapshot 1`] = ` "placeholder": "(optional - defaults to the second column)", "type": "string", }, - Object { - "defined": [Function], - "name": "extractionNamespace.namespaceParseSpec.delimiter", - "placeholder": "(optional)", - "type": "string", - }, - Object { - "defined": [Function], - "name": "extractionNamespace.namespaceParseSpec.listDelimiter", - "placeholder": "(optional)", - "type": "string", - }, Object { "defined": [Function], "name": "extractionNamespace.namespaceParseSpec.keyFieldName", @@ -217,15 +256,9 @@ exports[`LookupEditDialog matches snapshot 1`] = ` "type": "string", }, Object { - "defaultValue": "0", "defined": [Function], - "info": "Period between polling for updates", - "name": "extractionNamespace.pollPeriod", - "type": "string", - }, - Object { - "defined": [Function], - "info": "Defines the connectURI value on the The connector config to used", + "info": "Defines the connectURI for connecting to the database", + "issueWithValue": [Function], "label": "Connect URI", "name": "extractionNamespace.connectorConfig.connectURI", "required": true, @@ -243,12 +276,6 @@ exports[`LookupEditDialog matches snapshot 1`] = ` "name": "extractionNamespace.connectorConfig.password", "type": "string", }, - Object { - "defined": [Function], - "info": "Should tables be created", - "name": "extractionNamespace.connectorConfig.createTables", - "type": "boolean", - }, Object { "defined": [Function], "info": @@ -264,7 +291,7 @@ exports[`LookupEditDialog matches snapshot 1`] = `

, "name": "extractionNamespace.table", - "placeholder": "some_lookup_table", + "placeholder": "lookup_table", "required": true, "type": "string", }, @@ -283,7 +310,7 @@ exports[`LookupEditDialog matches snapshot 1`] = `

, "name": "extractionNamespace.keyColumn", - "placeholder": "my_key_value", + "placeholder": "key_column", "required": true, "type": "string", }, @@ -302,28 +329,10 @@ exports[`LookupEditDialog matches snapshot 1`] = `

, "name": "extractionNamespace.valueColumn", - "placeholder": "my_column_value", + "placeholder": "value_column", "required": true, "type": "string", }, - Object { - "defined": [Function], - "info": -

- The filter to be used when selecting lookups, this is used to create a where clause on lookup population. This will become the expression filter in the SQL query: -

-

- SELECT keyColumn, valueColumn, tsColumn? FROM namespace.table WHERE - - - filter - -

-
, - "name": "extractionNamespace.filter", - "placeholder": "(optional)", - "type": "string", - }, Object { "defined": [Function], "info": @@ -340,9 +349,42 @@ exports[`LookupEditDialog matches snapshot 1`] = ` , "label": "Timestamp column", "name": "extractionNamespace.tsColumn", - "placeholder": "(optional)", + "placeholder": "timestamp_column (optional)", "type": "string", }, + Object { + "defined": [Function], + "info": +

+ The filter to be used when selecting lookups, this is used to create a where clause on lookup population. This will become the expression filter in the SQL query: +

+

+ SELECT keyColumn, valueColumn, tsColumn? FROM namespace.table WHERE + + + filter + +

+
, + "name": "extractionNamespace.filter", + "placeholder": "for_lookup = 1 (optional)", + "type": "string", + }, + Object { + "defined": [Function], + "info": "Period between polling for updates", + "name": "extractionNamespace.pollPeriod", + "required": true, + "suggestions": Array [ + "PT1M", + "PT10M", + "PT30M", + "PT1H", + "PT6H", + "P1D", + ], + "type": "duration", + }, Object { "defaultValue": 0, "defined": [Function], diff --git a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx index 561b1f0ceaf..882a454502a 100644 --- a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx +++ b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.spec.tsx @@ -28,7 +28,7 @@ describe('LookupEditDialog', () => { onClose={() => {}} onSubmit={() => {}} onChange={() => {}} - lookupName="test" + lookupId="test" lookupTier="test" lookupVersion="test" lookupSpec={{ type: 'map', map: { a: 1 } }} diff --git a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.tsx b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.tsx index ffd4e49a62c..fb70c6c72a4 100644 --- a/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.tsx +++ b/web-console/src/dialogs/lookup-edit-dialog/lookup-edit-dialog.tsx @@ -36,10 +36,10 @@ export interface LookupEditDialogProps { onClose: () => void; onSubmit: (updateLookupVersion: boolean) => void; onChange: ( - field: 'name' | 'tier' | 'version' | 'spec', + field: 'id' | 'tier' | 'version' | 'spec', value: string | Partial, ) => void; - lookupName: string; + lookupId: string; lookupTier: string; lookupVersion: string; lookupSpec: Partial; @@ -53,7 +53,7 @@ export const LookupEditDialog = React.memo(function LookupEditDialog(props: Look onSubmit, lookupSpec, lookupTier, - lookupName, + lookupId, lookupVersion, onChange, isEdit, @@ -64,7 +64,7 @@ export const LookupEditDialog = React.memo(function LookupEditDialog(props: Look const [jsonError, setJsonError] = useState(); const disableSubmit = Boolean( - jsonError || isLookupInvalid(lookupName, lookupVersion, lookupTier, lookupSpec), + jsonError || isLookupInvalid(lookupId, lookupVersion, lookupTier, lookupSpec), ); return ( @@ -73,13 +73,14 @@ export const LookupEditDialog = React.memo(function LookupEditDialog(props: Look isOpen onClose={onClose} title={isEdit ? 'Edit lookup' : 'Add lookup'} + canEscapeKeyClose={false} >
onChange('name', e.target.value)} - intent={lookupName ? Intent.NONE : Intent.PRIMARY} + value={lookupId} + onChange={(e: any) => onChange('id', e.target.value)} + intent={lookupId ? Intent.NONE : Intent.PRIMARY} disabled={isEdit} placeholder="Enter the lookup name" /> @@ -112,7 +113,7 @@ export const LookupEditDialog = React.memo(function LookupEditDialog(props: Look rightElement={
diff --git a/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap b/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap index 98840963b3d..9de130d09f3 100644 --- a/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap +++ b/web-console/src/dialogs/retention-dialog/__snapshots__/retention-dialog.spec.tsx.snap @@ -232,47 +232,51 @@ exports[`retention dialog matches snapshot 1`] = `
- - + - + + + caret-down + + + + + + - +