mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-11-09 23:40:05 +00:00
UI: Fix filter patterns in Add Ingestion form (#4490)
This commit is contained in:
parent
de3d734276
commit
d57c3343cf
@ -109,6 +109,9 @@ const AddIngestion = ({
|
|||||||
(data?.source.sourceConfig.config as ConfigClass)?.generateSampleData ??
|
(data?.source.sourceConfig.config as ConfigClass)?.generateSampleData ??
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
const [markDeletedTables, setMarkDeletedTables] = useState(
|
||||||
|
(data?.source.sourceConfig.config as ConfigClass)?.markDeletedTables ?? true
|
||||||
|
);
|
||||||
const [dashboardFilterPattern, setDashboardFilterPattern] =
|
const [dashboardFilterPattern, setDashboardFilterPattern] =
|
||||||
useState<FilterPattern>(
|
useState<FilterPattern>(
|
||||||
(data?.source.sourceConfig.config as ConfigClass)
|
(data?.source.sourceConfig.config as ConfigClass)
|
||||||
@ -299,6 +302,7 @@ const AddIngestion = ({
|
|||||||
enableDataProfiler: enableDataProfiler,
|
enableDataProfiler: enableDataProfiler,
|
||||||
generateSampleData: ingestSampleData,
|
generateSampleData: ingestSampleData,
|
||||||
includeViews: includeView,
|
includeViews: includeView,
|
||||||
|
markDeletedTables: markDeletedTables,
|
||||||
schemaFilterPattern: getFilterPatternData(schemaFilterPattern),
|
schemaFilterPattern: getFilterPatternData(schemaFilterPattern),
|
||||||
tableFilterPattern: getFilterPatternData(tableFilterPattern),
|
tableFilterPattern: getFilterPatternData(tableFilterPattern),
|
||||||
chartFilterPattern: getFilterPatternData(chartFilterPattern),
|
chartFilterPattern: getFilterPatternData(chartFilterPattern),
|
||||||
@ -344,7 +348,12 @@ const AddIngestion = ({
|
|||||||
onSuccessSave?.();
|
onSuccessSave?.();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => setTimeout(() => setSaveState('initial'), 500));
|
.catch(() => {
|
||||||
|
// ignore since error is displayed in toast in the parent promise
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => setSaveState('initial'), 500);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -421,6 +430,7 @@ const AddIngestion = ({
|
|||||||
handleIncludeView={() => setIncludeView((pre) => !pre)}
|
handleIncludeView={() => setIncludeView((pre) => !pre)}
|
||||||
handleIngestSampleData={() => setIngestSampleData((pre) => !pre)}
|
handleIngestSampleData={() => setIngestSampleData((pre) => !pre)}
|
||||||
handleIngestionName={(val) => setIngestionName(val)}
|
handleIngestionName={(val) => setIngestionName(val)}
|
||||||
|
handleMarkDeletedTables={() => setMarkDeletedTables((pre) => !pre)}
|
||||||
handleQueryLogDuration={(val) => setQueryLogDuration(val)}
|
handleQueryLogDuration={(val) => setQueryLogDuration(val)}
|
||||||
handleResultLimit={(val) => setResultLimit(val)}
|
handleResultLimit={(val) => setResultLimit(val)}
|
||||||
handleShowFilter={handleShowFilter}
|
handleShowFilter={handleShowFilter}
|
||||||
@ -428,6 +438,7 @@ const AddIngestion = ({
|
|||||||
includeView={includeView}
|
includeView={includeView}
|
||||||
ingestSampleData={ingestSampleData}
|
ingestSampleData={ingestSampleData}
|
||||||
ingestionName={ingestionName}
|
ingestionName={ingestionName}
|
||||||
|
markDeletedTables={markDeletedTables}
|
||||||
pipelineType={pipelineType}
|
pipelineType={pipelineType}
|
||||||
queryLogDuration={queryLogDuration}
|
queryLogDuration={queryLogDuration}
|
||||||
resultLimit={resultLimit}
|
resultLimit={resultLimit}
|
||||||
|
|||||||
@ -61,6 +61,7 @@ const mockConfigureIngestion: ConfigureIngestionProps = {
|
|||||||
stageFileLocation: '',
|
stageFileLocation: '',
|
||||||
enableDataProfiler: false,
|
enableDataProfiler: false,
|
||||||
ingestSampleData: false,
|
ingestSampleData: false,
|
||||||
|
markDeletedTables: false,
|
||||||
showDashboardFilter: false,
|
showDashboardFilter: false,
|
||||||
showSchemaFilter: false,
|
showSchemaFilter: false,
|
||||||
showTableFilter: false,
|
showTableFilter: false,
|
||||||
@ -74,6 +75,7 @@ const mockConfigureIngestion: ConfigureIngestionProps = {
|
|||||||
handleQueryLogDuration: jest.fn(),
|
handleQueryLogDuration: jest.fn(),
|
||||||
handleResultLimit: jest.fn(),
|
handleResultLimit: jest.fn(),
|
||||||
handleStageFileLocation: jest.fn(),
|
handleStageFileLocation: jest.fn(),
|
||||||
|
handleMarkDeletedTables: jest.fn(),
|
||||||
getIncludeValue: jest.fn(),
|
getIncludeValue: jest.fn(),
|
||||||
getExcludeValue: jest.fn(),
|
getExcludeValue: jest.fn(),
|
||||||
handleShowFilter: jest.fn(),
|
handleShowFilter: jest.fn(),
|
||||||
@ -108,6 +110,6 @@ describe('Test ConfigureIngestion component', () => {
|
|||||||
expect(backButton).toBeInTheDocument();
|
expect(backButton).toBeInTheDocument();
|
||||||
expect(nextButton).toBeInTheDocument();
|
expect(nextButton).toBeInTheDocument();
|
||||||
expect(filterPatternComponents.length).toBe(2);
|
expect(filterPatternComponents.length).toBe(2);
|
||||||
expect(toggleSwitchs.length).toBe(3);
|
expect(toggleSwitchs.length).toBe(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -38,6 +38,7 @@ const ConfigureIngestion = ({
|
|||||||
enableDataProfiler,
|
enableDataProfiler,
|
||||||
ingestSampleData,
|
ingestSampleData,
|
||||||
pipelineType,
|
pipelineType,
|
||||||
|
markDeletedTables,
|
||||||
showDashboardFilter,
|
showDashboardFilter,
|
||||||
showSchemaFilter,
|
showSchemaFilter,
|
||||||
showTableFilter,
|
showTableFilter,
|
||||||
@ -50,6 +51,7 @@ const ConfigureIngestion = ({
|
|||||||
getExcludeValue,
|
getExcludeValue,
|
||||||
getIncludeValue,
|
getIncludeValue,
|
||||||
handleIngestionName,
|
handleIngestionName,
|
||||||
|
handleMarkDeletedTables,
|
||||||
handleDescription,
|
handleDescription,
|
||||||
handleShowFilter,
|
handleShowFilter,
|
||||||
handleEnableDataProfiler,
|
handleEnableDataProfiler,
|
||||||
@ -187,8 +189,8 @@ const ConfigureIngestion = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<p className="tw-text-grey-muted tw-mt-3">
|
<p className="tw-text-grey-muted tw-mt-3">
|
||||||
Slowdown metadata extraction by calculate the metrics and
|
Enable Data Profiler to collect metrics and distribution of data
|
||||||
distribution of data in the table
|
in the table. This will however slowdown the metadata extraction.
|
||||||
</p>
|
</p>
|
||||||
{getSeparator('')}
|
{getSeparator('')}
|
||||||
</Field>
|
</Field>
|
||||||
@ -205,6 +207,20 @@ const ConfigureIngestion = ({
|
|||||||
</p>
|
</p>
|
||||||
{getSeparator('')}
|
{getSeparator('')}
|
||||||
</Field>
|
</Field>
|
||||||
|
<Field>
|
||||||
|
<div className="tw-flex tw-gap-1">
|
||||||
|
<label>Mark Deleted Tables</label>
|
||||||
|
<ToggleSwitchV1
|
||||||
|
checked={markDeletedTables}
|
||||||
|
handleCheck={handleMarkDeletedTables}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<p className="tw-text-grey-muted tw-mt-3">
|
||||||
|
Any deleted tables in the data source will be soft deleted in
|
||||||
|
OpenMetadata
|
||||||
|
</p>
|
||||||
|
{getSeparator('')}
|
||||||
|
</Field>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -59,6 +59,7 @@ export interface ConfigureIngestionProps {
|
|||||||
includeView: boolean;
|
includeView: boolean;
|
||||||
enableDataProfiler: boolean;
|
enableDataProfiler: boolean;
|
||||||
ingestSampleData: boolean;
|
ingestSampleData: boolean;
|
||||||
|
markDeletedTables: boolean;
|
||||||
pipelineType: PipelineType;
|
pipelineType: PipelineType;
|
||||||
showDashboardFilter: boolean;
|
showDashboardFilter: boolean;
|
||||||
showSchemaFilter: boolean;
|
showSchemaFilter: boolean;
|
||||||
@ -74,6 +75,7 @@ export interface ConfigureIngestionProps {
|
|||||||
handleIncludeView: () => void;
|
handleIncludeView: () => void;
|
||||||
handleEnableDataProfiler: () => void;
|
handleEnableDataProfiler: () => void;
|
||||||
handleIngestSampleData: () => void;
|
handleIngestSampleData: () => void;
|
||||||
|
handleMarkDeletedTables: () => void;
|
||||||
getIncludeValue: (value: string[], type: FilterPatternEnum) => void;
|
getIncludeValue: (value: string[], type: FilterPatternEnum) => void;
|
||||||
getExcludeValue: (value: string[], type: FilterPatternEnum) => void;
|
getExcludeValue: (value: string[], type: FilterPatternEnum) => void;
|
||||||
handleShowFilter: (value: boolean, type: FilterPatternEnum) => void;
|
handleShowFilter: (value: boolean, type: FilterPatternEnum) => void;
|
||||||
|
|||||||
@ -810,7 +810,7 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
|
|
||||||
{/* optional filed for snowflik */}
|
{/* optional field for snowflake */}
|
||||||
{selectService === DatabaseServiceType.Snowflake && (
|
{selectService === DatabaseServiceType.Snowflake && (
|
||||||
<div className="tw-mt-4 tw-grid tw-grid-cols-2 tw-gap-2">
|
<div className="tw-mt-4 tw-grid tw-grid-cols-2 tw-gap-2">
|
||||||
<div>
|
<div>
|
||||||
@ -1526,13 +1526,13 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const previousStepHandler = () => {
|
const previousStepHandler = () => {
|
||||||
let increamentCount = 1;
|
let incrementCount = 1;
|
||||||
|
|
||||||
if (activeStepperStep === 5 && !isIngestionEnable) {
|
if (activeStepperStep === 5 && !isIngestionEnable) {
|
||||||
increamentCount = 2;
|
incrementCount = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
setActiveStepperStep((pre) => (pre > 1 ? pre - increamentCount : pre));
|
setActiveStepperStep((pre) => (pre > 1 ? pre - incrementCount : pre));
|
||||||
};
|
};
|
||||||
|
|
||||||
const forwardStepHandler = (activeStep: number) => {
|
const forwardStepHandler = (activeStep: number) => {
|
||||||
@ -1598,13 +1598,13 @@ export const AddServiceModal: FunctionComponent<Props> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
setActiveStepperStep((pre) => {
|
setActiveStepperStep((pre) => {
|
||||||
let increamentCount = 1;
|
let incrementCount = 1;
|
||||||
|
|
||||||
if (activeStepperStep === 3 && !isIngestionEnable) {
|
if (activeStepperStep === 3 && !isIngestionEnable) {
|
||||||
increamentCount = 2;
|
incrementCount = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pre < steps.length && isValid ? pre + increamentCount : pre;
|
return pre < steps.length && isValid ? pre + incrementCount : pre;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { findAllByText, findByTestId, render } from '@testing-library/react';
|
import { findByTestId, render } from '@testing-library/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FilterPatternEnum } from '../../../enums/filterPattern.enum';
|
import { FilterPatternEnum } from '../../../enums/filterPattern.enum';
|
||||||
import FilterPattern from './FilterPattern';
|
import FilterPattern from './FilterPattern';
|
||||||
@ -46,14 +46,19 @@ describe('Test FilterPattern component', () => {
|
|||||||
container,
|
container,
|
||||||
`${mockFilterPatternProps.type}-filter-pattern-checkbox`
|
`${mockFilterPatternProps.type}-filter-pattern-checkbox`
|
||||||
);
|
);
|
||||||
const reactSelectMultiInputs = await findAllByText(
|
const includeFilterInput = await findByTestId(
|
||||||
container,
|
container,
|
||||||
'ReactSelectMultiInput.component'
|
'filter-pattern-includes-table'
|
||||||
|
);
|
||||||
|
const excludeFilterInput = await findByTestId(
|
||||||
|
container,
|
||||||
|
'filter-pattern-excludes-table'
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(filterPatternContainer).toBeInTheDocument();
|
expect(filterPatternContainer).toBeInTheDocument();
|
||||||
expect(checkbox).toBeInTheDocument();
|
expect(checkbox).toBeInTheDocument();
|
||||||
expect(fieldContainer).toBeInTheDocument();
|
expect(fieldContainer).toBeInTheDocument();
|
||||||
expect(reactSelectMultiInputs.length).toBe(2);
|
expect(includeFilterInput).toBeInTheDocument();
|
||||||
|
expect(excludeFilterInput).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -15,7 +15,6 @@ import { capitalize } from 'lodash';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { getSeparator } from '../../../utils/CommonUtils';
|
import { getSeparator } from '../../../utils/CommonUtils';
|
||||||
import { Field } from '../../Field/Field';
|
import { Field } from '../../Field/Field';
|
||||||
import ReactSelectMultiInput from '../react-select-component/ReactSelectMultiInput';
|
|
||||||
import { FilterPatternProps } from './filterPattern.interface';
|
import { FilterPatternProps } from './filterPattern.interface';
|
||||||
|
|
||||||
const FilterPattern = ({
|
const FilterPattern = ({
|
||||||
@ -28,6 +27,20 @@ const FilterPattern = ({
|
|||||||
getExcludeValue,
|
getExcludeValue,
|
||||||
type,
|
type,
|
||||||
}: FilterPatternProps) => {
|
}: FilterPatternProps) => {
|
||||||
|
const includeFilterChangeHandler = (
|
||||||
|
event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
|
||||||
|
) => {
|
||||||
|
const value = event.target.value ? event.target.value.split(',') : [];
|
||||||
|
getIncludeValue(value, type);
|
||||||
|
};
|
||||||
|
|
||||||
|
const excludeFilterChangeHandler = (
|
||||||
|
event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
|
||||||
|
) => {
|
||||||
|
const value = event.target.value ? event.target.value.split(',') : [];
|
||||||
|
getExcludeValue(value, type);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tw-mt-4" data-testid="filter-pattern-container">
|
<div className="tw-mt-4" data-testid="filter-pattern-container">
|
||||||
<div className="tw-flex tw-items-center">
|
<div className="tw-flex tw-items-center">
|
||||||
@ -49,18 +62,24 @@ const FilterPattern = ({
|
|||||||
<div data-testid="field-container">
|
<div data-testid="field-container">
|
||||||
<Field>
|
<Field>
|
||||||
<label className="tw-block tw-form-label">Include:</label>
|
<label className="tw-block tw-form-label">Include:</label>
|
||||||
<ReactSelectMultiInput
|
<input
|
||||||
getTagValue={(data) => getIncludeValue(data, type)}
|
className="tw-form-inputs tw-relative tw-px-2 tw-py-2"
|
||||||
initialData={includePattern}
|
data-testid={`filter-pattern-includes-${type}`}
|
||||||
placeholder="Type include filter pattern and hit enter"
|
placeholder="Enter a list of strings/regex patterns as a comma separated value"
|
||||||
|
type="text"
|
||||||
|
value={includePattern}
|
||||||
|
onChange={includeFilterChangeHandler}
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
<Field>
|
<Field>
|
||||||
<label className="tw-block tw-form-label">Exclude:</label>
|
<label className="tw-block tw-form-label">Exclude:</label>
|
||||||
<ReactSelectMultiInput
|
<input
|
||||||
getTagValue={(data) => getExcludeValue(data, type)}
|
className="tw-form-inputs tw-relative tw-px-2 tw-py-2"
|
||||||
initialData={excludePattern}
|
data-testid={`filter-pattern-excludes-${type}`}
|
||||||
placeholder="Type exclude filter pattern and hit enter"
|
placeholder="Enter a list of strings/regex patterns as a comma separated value"
|
||||||
|
type="text"
|
||||||
|
value={excludePattern}
|
||||||
|
onChange={excludeFilterChangeHandler}
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
{showSeparator && getSeparator('')}
|
{showSeparator && getSeparator('')}
|
||||||
|
|||||||
@ -107,9 +107,9 @@ const AddIngestionPage = () => {
|
|||||||
err,
|
err,
|
||||||
jsonData['api-error-messages']['create-ingestion-error']
|
jsonData['api-error-messages']['create-ingestion-error']
|
||||||
);
|
);
|
||||||
reject();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
reject();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user