mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-14 09:05:58 +00:00
feat: Enhance QualityTab with search and filter options; refactor DataQualityTab and update styles
This commit is contained in:
parent
fae21c5a76
commit
ec8cf291f2
@ -89,11 +89,7 @@ const DataObservabilityTab = (props: TableProfilerProps) => {
|
|||||||
'background-color 0.2s ease-in, color 0.2s ease-in',
|
'background-color 0.2s ease-in, color 0.2s ease-in',
|
||||||
borderRadius: '6px',
|
borderRadius: '6px',
|
||||||
},
|
},
|
||||||
'.Mui-selected': {
|
'.Mui-selected, .MuiTab-root:hover': {
|
||||||
backgroundColor: `${theme.palette.primary.main} !important`,
|
|
||||||
color: `${theme.palette.primary.contrastText} !important`,
|
|
||||||
},
|
|
||||||
'.MuiTab-root:hover': {
|
|
||||||
backgroundColor: `${theme.palette.primary.main} !important`,
|
backgroundColor: `${theme.palette.primary.main} !important`,
|
||||||
color: `${theme.palette.primary.contrastText} !important`,
|
color: `${theme.palette.primary.contrastText} !important`,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -82,6 +82,7 @@ const DataQualityTab: React.FC<DataQualityTabProps> = ({
|
|||||||
fetchTestCases,
|
fetchTestCases,
|
||||||
isEditAllowed,
|
isEditAllowed,
|
||||||
tableHeader,
|
tableHeader,
|
||||||
|
removeTableBorder = false,
|
||||||
}: DataQualityTabProps) => {
|
}: DataQualityTabProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { getEntityPermissionByFqn } = usePermissionProvider();
|
const { getEntityPermissionByFqn } = usePermissionProvider();
|
||||||
@ -512,7 +513,8 @@ const DataQualityTab: React.FC<DataQualityTabProps> = ({
|
|||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
containerClassName={classNames('test-case-table-container', {
|
containerClassName={classNames('test-case-table-container', {
|
||||||
'custom-card-with-table': !isUndefined(tableHeader),
|
'custom-card-with-table':
|
||||||
|
!isUndefined(tableHeader) || removeTableBorder,
|
||||||
})}
|
})}
|
||||||
{...(pagingData && showPagination
|
{...(pagingData && showPagination
|
||||||
? {
|
? {
|
||||||
|
|||||||
@ -71,6 +71,7 @@ export interface DataQualityTabProps {
|
|||||||
fetchTestCases?: (params?: ListTestCaseParamsBySearch) => Promise<void>;
|
fetchTestCases?: (params?: ListTestCaseParamsBySearch) => Promise<void>;
|
||||||
isEditAllowed?: boolean;
|
isEditAllowed?: boolean;
|
||||||
tableHeader?: ReactNode;
|
tableHeader?: ReactNode;
|
||||||
|
removeTableBorder?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TestSummaryProps {
|
export interface TestSummaryProps {
|
||||||
|
|||||||
@ -10,9 +10,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { Grid, Stack } from '@mui/material';
|
import { Box, Grid, Stack, Tab, Tabs, useTheme } from '@mui/material';
|
||||||
import { Col, Form, Row, Select, Space, Tabs } from 'antd';
|
import { Col, Form, Row, Select, Space } from 'antd';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
import QueryString from 'qs';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useMemo, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
@ -66,6 +67,7 @@ export const QualityTab = () => {
|
|||||||
testCaseSummary,
|
testCaseSummary,
|
||||||
} = useTableProfiler();
|
} = useTableProfiler();
|
||||||
const { getResourceLimit } = useLimitStore();
|
const { getResourceLimit } = useLimitStore();
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
currentPage,
|
currentPage,
|
||||||
@ -91,6 +93,26 @@ export const QualityTab = () => {
|
|||||||
const location = useCustomLocation();
|
const location = useCustomLocation();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const searchData = useMemo(() => {
|
||||||
|
const param = location.search;
|
||||||
|
const searchData = QueryString.parse(
|
||||||
|
param.startsWith('?') ? param.substring(1) : param
|
||||||
|
);
|
||||||
|
|
||||||
|
return searchData as {
|
||||||
|
activeTab: TableProfilerTab;
|
||||||
|
activeColumnFqn: string;
|
||||||
|
qualityTab: string;
|
||||||
|
};
|
||||||
|
}, [location.search]);
|
||||||
|
|
||||||
|
const { qualityTab = EntityTabs.TEST_CASES } = searchData;
|
||||||
|
|
||||||
|
const isTestCaseTab = useMemo(
|
||||||
|
() => qualityTab === EntityTabs.TEST_CASES,
|
||||||
|
[qualityTab]
|
||||||
|
);
|
||||||
|
|
||||||
const [selectedTestCaseStatus, setSelectedTestCaseStatus] =
|
const [selectedTestCaseStatus, setSelectedTestCaseStatus] =
|
||||||
useState<TestCaseStatus>('' as TestCaseStatus);
|
useState<TestCaseStatus>('' as TestCaseStatus);
|
||||||
const [selectedTestType, setSelectedTestType] = useState(TestCaseType.all);
|
const [selectedTestType, setSelectedTestType] = useState(TestCaseType.all);
|
||||||
@ -235,69 +257,6 @@ export const QualityTab = () => {
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: EntityTabs.TEST_CASES,
|
key: EntityTabs.TEST_CASES,
|
||||||
children: (
|
|
||||||
<Row className="p-t-md">
|
|
||||||
<Col span={12}>
|
|
||||||
<Searchbar
|
|
||||||
placeholder={t('label.search-entity', {
|
|
||||||
entity: t('label.test-case-lowercase'),
|
|
||||||
})}
|
|
||||||
searchValue={searchValue}
|
|
||||||
onSearch={handleSearchTestCase}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col span={12}>
|
|
||||||
<Form layout="inline">
|
|
||||||
<Space align="center" className="w-full justify-end">
|
|
||||||
<Form.Item className="m-0 w-40" label={t('label.type')}>
|
|
||||||
<Select
|
|
||||||
options={TEST_CASE_TYPE_OPTION}
|
|
||||||
value={selectedTestType}
|
|
||||||
onChange={handleTestCaseTypeChange}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item className="m-0 w-40" label={t('label.status')}>
|
|
||||||
<Select
|
|
||||||
options={TEST_CASE_STATUS_OPTION}
|
|
||||||
value={selectedTestCaseStatus}
|
|
||||||
onChange={handleTestCaseStatusChange}
|
|
||||||
/>
|
|
||||||
</Form.Item>
|
|
||||||
</Space>
|
|
||||||
</Form>
|
|
||||||
</Col>
|
|
||||||
<Col span={24}>
|
|
||||||
<DataQualityTab
|
|
||||||
afterDeleteAction={async (...params) => {
|
|
||||||
await fetchAllTests(...params); // Update current count when Create / Delete operation performed
|
|
||||||
params?.length &&
|
|
||||||
(await getResourceLimit('dataQuality', true, true));
|
|
||||||
}}
|
|
||||||
breadcrumbData={tableBreadcrumb}
|
|
||||||
fetchTestCases={handleSortTestCase}
|
|
||||||
isEditAllowed={editTest}
|
|
||||||
isLoading={isTestsLoading}
|
|
||||||
showTableColumn={false}
|
|
||||||
testCases={allTestCases}
|
|
||||||
onTestCaseResultUpdate={onTestCaseUpdate}
|
|
||||||
onTestUpdate={onTestCaseUpdate}
|
|
||||||
/>
|
|
||||||
</Col>
|
|
||||||
<Col span={24}>
|
|
||||||
{showPagination && (
|
|
||||||
<NextPrevious
|
|
||||||
isNumberBased
|
|
||||||
currentPage={currentPage}
|
|
||||||
isLoading={isTestsLoading}
|
|
||||||
pageSize={pageSize}
|
|
||||||
paging={paging}
|
|
||||||
pagingHandler={handleTestCasePageChange}
|
|
||||||
onShowSizeChange={handlePageSizeChange}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: (
|
label: (
|
||||||
@ -308,7 +267,6 @@ export const QualityTab = () => {
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: EntityTabs.PIPELINE,
|
key: EntityTabs.PIPELINE,
|
||||||
children: <TestSuitePipelineTab testSuite={testSuite} />,
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@ -324,11 +282,11 @@ export const QualityTab = () => {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleTabChange = () => {
|
const handleTabChange = (_: React.SyntheticEvent, tab: string) => {
|
||||||
navigate(
|
navigate(
|
||||||
{
|
{
|
||||||
pathname: location.pathname,
|
pathname: location.pathname,
|
||||||
search: location.search,
|
search: QueryString.stringify({ ...searchData, qualityTab: tab }),
|
||||||
},
|
},
|
||||||
{ state: undefined, replace: true }
|
{ state: undefined, replace: true }
|
||||||
);
|
);
|
||||||
@ -360,7 +318,132 @@ export const QualityTab = () => {
|
|||||||
))}
|
))}
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Tabs className="tabs-new" items={tabs} onChange={handleTabChange} />
|
<Box
|
||||||
|
sx={{
|
||||||
|
border: `1px solid ${theme.palette.grey['200']}`,
|
||||||
|
borderRadius: '10px',
|
||||||
|
}}>
|
||||||
|
<Box
|
||||||
|
alignItems="center"
|
||||||
|
display="flex"
|
||||||
|
justifyContent="space-between"
|
||||||
|
p={4}>
|
||||||
|
<Box display="flex" gap={5} width="100%">
|
||||||
|
<Tabs
|
||||||
|
sx={{
|
||||||
|
width: 'max-content',
|
||||||
|
minHeight: 'unset',
|
||||||
|
display: 'inline-flex',
|
||||||
|
'.MuiTab-root': {
|
||||||
|
color: theme.palette.grey['700'],
|
||||||
|
transition:
|
||||||
|
'background-color 0.2s ease-in, color 0.2s ease-in',
|
||||||
|
borderRadius: '6px',
|
||||||
|
},
|
||||||
|
'.Mui-selected, .MuiTab-root:hover': {
|
||||||
|
backgroundColor: `${theme.palette.grey['50']}`,
|
||||||
|
color: `${theme.palette.grey['800']}`,
|
||||||
|
},
|
||||||
|
'MuiTabs-root': {
|
||||||
|
minHeight: 'unset',
|
||||||
|
},
|
||||||
|
'.MuiTabs-indicator': {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
'.MuiTabs-scroller': {
|
||||||
|
padding: '0px',
|
||||||
|
height: 'unset',
|
||||||
|
},
|
||||||
|
'.MuiTab-root:not(:first-of-type)': {
|
||||||
|
marginLeft: '0px',
|
||||||
|
borderLeft: `1px solid ${theme.palette.grey['200']}`,
|
||||||
|
borderTopLeftRadius: 0,
|
||||||
|
borderBottomLeftRadius: 0,
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
value={qualityTab}
|
||||||
|
onChange={handleTabChange}>
|
||||||
|
{tabs.map(({ label, key }) => (
|
||||||
|
<Tab key={key} label={label} value={key} />
|
||||||
|
))}
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
{isTestCaseTab && (
|
||||||
|
<Box width={400}>
|
||||||
|
<Searchbar
|
||||||
|
removeMargin
|
||||||
|
placeholder={t('label.search-entity', {
|
||||||
|
entity: t('label.test-case-lowercase'),
|
||||||
|
})}
|
||||||
|
searchValue={searchValue}
|
||||||
|
onSearch={handleSearchTestCase}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{isTestCaseTab && (
|
||||||
|
<Form layout="inline">
|
||||||
|
<Space align="center" className="w-full justify-end">
|
||||||
|
<Form.Item className="m-0 w-40" label={t('label.type')}>
|
||||||
|
<Select
|
||||||
|
options={TEST_CASE_TYPE_OPTION}
|
||||||
|
value={selectedTestType}
|
||||||
|
onChange={handleTestCaseTypeChange}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item className="m-0 w-40" label={t('label.status')}>
|
||||||
|
<Select
|
||||||
|
options={TEST_CASE_STATUS_OPTION}
|
||||||
|
value={selectedTestCaseStatus}
|
||||||
|
onChange={handleTestCaseStatusChange}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Space>
|
||||||
|
</Form>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{isTestCaseTab && (
|
||||||
|
<Row>
|
||||||
|
<Col span={24}>
|
||||||
|
<DataQualityTab
|
||||||
|
removeTableBorder
|
||||||
|
afterDeleteAction={async (...params) => {
|
||||||
|
await fetchAllTests(...params); // Update current count when Create / Delete operation performed
|
||||||
|
params?.length &&
|
||||||
|
(await getResourceLimit('dataQuality', true, true));
|
||||||
|
}}
|
||||||
|
breadcrumbData={tableBreadcrumb}
|
||||||
|
fetchTestCases={handleSortTestCase}
|
||||||
|
isEditAllowed={editTest}
|
||||||
|
isLoading={isTestsLoading}
|
||||||
|
showTableColumn={false}
|
||||||
|
testCases={allTestCases}
|
||||||
|
onTestCaseResultUpdate={onTestCaseUpdate}
|
||||||
|
onTestUpdate={onTestCaseUpdate}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
<Col span={24}>
|
||||||
|
{showPagination && (
|
||||||
|
<NextPrevious
|
||||||
|
isNumberBased
|
||||||
|
currentPage={currentPage}
|
||||||
|
isLoading={isTestsLoading}
|
||||||
|
pageSize={pageSize}
|
||||||
|
paging={paging}
|
||||||
|
pagingHandler={handleTestCasePageChange}
|
||||||
|
onShowSizeChange={handlePageSizeChange}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{qualityTab === EntityTabs.PIPELINE && (
|
||||||
|
<TestSuitePipelineTab testSuite={testSuite} />
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user