Fix #5091 Make "Data Quality" column on Table schema page optional to hide (#7260)

* Fix #5091 Make "Data Quality" column on Table schema page optional to hide

* Fix unit test

* Improve checks
This commit is contained in:
Sachin Chaurasiya 2022-09-06 21:59:40 +05:30 committed by GitHub
parent 84aede2eaf
commit be553eb017
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 128 additions and 59 deletions

View File

@ -176,13 +176,15 @@ const BotListV1 = ({
<ErrorPlaceHolder
buttons={
<div className="tw-text-lg tw-text-center">
<Tooltip
title={createPermission ? 'Add Bot' : NO_PERMISSION_FOR_ACTION}>
<Button
ghost
title="Add Team"
disabled={!createPermission}
type="primary"
onClick={handleAddBotClick}>
Add Bot
</Button>
</Tooltip>
</div>
}
doc={BOTS_DOCS}

View File

@ -48,11 +48,7 @@ import { getEntityFeedLink } from '../../utils/EntityUtils';
import { getDefaultValue } from '../../utils/FeedElementUtils';
import { getEntityFieldThreadCounts } from '../../utils/FeedUtils';
import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils';
import {
getTableTestsValue,
getTagsWithoutTier,
getUsagePercentile,
} from '../../utils/TableUtils';
import { getTagsWithoutTier, getUsagePercentile } from '../../utils/TableUtils';
import { showErrorToast } from '../../utils/ToastUtils';
import ActivityFeedList from '../ActivityFeed/ActivityFeedList/ActivityFeedList';
import ActivityThreadPanel from '../ActivityFeed/ActivityThreadPanel/ActivityThreadPanel';
@ -125,7 +121,6 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
postFeedHandler,
feedCount,
entityFieldThreadCount,
tableTestCase,
createThread,
qualityTestFormHandler,
deletePostHandler,
@ -408,7 +403,6 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
key: 'Rows',
value: prepareTableRowInfo(),
},
{ key: 'Tests', value: getTableTestsValue(tableTestCase) },
];
const onDescriptionEdit = (): void => {
@ -745,9 +739,7 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
)}
{activeTab === 5 && (
<TableProfilerV1
hasEditAccess={
tablePermissions.EditAll || tablePermissions.EditDataProfile
}
permissions={tablePermissions}
table={tableDetails}
onAddTestClick={qualityTestFormHandler}
/>

View File

@ -833,20 +833,6 @@ const EntityTable = ({
return renderCell(TABLE_HEADERS_V1.dataTypeDisplay, record, index);
},
},
{
title: 'Data Quality',
dataIndex: 'columnTests',
key: 'columnTests',
accessor: 'columnTests',
width: 200,
render: (
_: Array<unknown>,
record: ModifiedTableColumn,
index: number
) => {
return renderCell(TABLE_HEADERS_V1.columnTests, record, index);
},
},
{
title: 'Description',
dataIndex: 'description',

View File

@ -10,7 +10,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Button, Col, Form, Radio, Row, Select, Space } from 'antd';
import { Button, Col, Form, Radio, Row, Select, Space, Tooltip } from 'antd';
import { RadioChangeEvent } from 'antd/lib/radio';
import { AxiosError } from 'axios';
import { EntityTags, ExtraInfo } from 'Models';
@ -25,6 +25,7 @@ import {
getTableTabPath,
getTeamAndUserDetailsPath,
} from '../../constants/constants';
import { NO_PERMISSION_FOR_ACTION } from '../../constants/HelperTextUtil';
import { PROFILER_FILTER_RANGE } from '../../constants/profiler.constant';
import { EntityType, FqnPart } from '../../enums/entity.enum';
import { ServiceCategory } from '../../enums/service.enum';
@ -480,9 +481,19 @@ const ProfilerDashboard: React.FC<ProfilerDashboardProps> = ({
onChange={handleTimeRangeChange}
/>
)}
<Button type="primary" onClick={handleAddTestClick}>
<Tooltip
title={
permission.EditAll || permission.EditTests
? 'Add Test'
: NO_PERMISSION_FOR_ACTION
}>
<Button
disabled={!(permission.EditAll || permission.EditTests)}
type="primary"
onClick={handleAddTestClick}>
Add Test
</Button>
</Tooltip>
</Space>
</Row>
</Col>

View File

@ -14,6 +14,7 @@
import { Column, Table } from '../../generated/entity/data/table';
import { TestCase } from '../../generated/tests/testCase';
import { DatasetTestModeType } from '../../interface/dataQuality.interface';
import { OperationPermission } from '../PermissionProvider/PermissionProvider.interface';
export interface TableProfilerProps {
onAddTestClick: (
@ -22,7 +23,7 @@ export interface TableProfilerProps {
columnName?: string
) => void;
table: Table;
hasEditAccess: boolean;
permissions: OperationPermission;
}
export type TableTestsType = {

View File

@ -21,6 +21,7 @@ import {
} from '@testing-library/react';
import React from 'react';
import { MOCK_TABLE, TEST_CASE } from '../../mocks/TableData.mock';
import { OperationPermission } from '../PermissionProvider/PermissionProvider.interface';
import { TableProfilerProps } from './TableProfiler.interface';
// internal imports
import TableProfilerV1 from './TableProfilerV1';
@ -60,7 +61,28 @@ jest.mock('../../axiosAPIs/testAPI', () => ({
const mockProps: TableProfilerProps = {
table: MOCK_TABLE,
hasEditAccess: true,
permissions: {
Create: true,
Delete: true,
EditAll: true,
EditCustomFields: true,
EditDataProfile: true,
EditDescription: true,
EditDisplayName: true,
EditLineage: true,
EditOwner: true,
EditQueries: true,
EditSampleData: true,
EditTags: true,
EditTests: true,
EditTier: true,
ViewAll: true,
ViewDataProfile: true,
ViewQueries: true,
ViewSampleData: true,
ViewTests: true,
ViewUsage: true,
} as OperationPermission,
onAddTestClick: jest.fn(),
};

View File

@ -57,9 +57,9 @@ import './tableProfiler.less';
const TableProfilerV1: FC<TableProfilerProps> = ({
table,
onAddTestClick,
hasEditAccess,
permissions,
}) => {
const { profile, columns } = table;
const { profile, columns = [] } = table;
const history = useHistory();
const [settingModalVisible, setSettingModalVisible] = useState(false);
const [columnTests, setColumnTests] = useState<TestCase[]>([]);
@ -71,6 +71,10 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
ProfilerDashboardTab.SUMMARY
);
const viewTest = permissions.ViewAll || permissions.ViewTests;
const viewProfiler = permissions.ViewAll || permissions.ViewDataProfile;
const editTest = permissions.EditAll || permissions.EditTests;
const handleSettingModal = (value: boolean) => {
setSettingModalVisible(value);
};
@ -106,11 +110,18 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
];
}, [profile, tableTests]);
const tabOptions = useMemo(() => {
return Object.values(ProfilerDashboardTab).filter(
(value) => value !== ProfilerDashboardTab.PROFILER
);
}, []);
const tabOptions = [
{
label: ProfilerDashboardTab.SUMMARY,
value: ProfilerDashboardTab.SUMMARY,
disabled: !viewProfiler,
},
{
label: ProfilerDashboardTab.DATA_QUALITY,
value: ProfilerDashboardTab.DATA_QUALITY,
disabled: !viewTest,
},
];
const handleTabChange = (e: RadioChangeEvent) => {
const value = e.target.value as ProfilerDashboardTab;
@ -158,8 +169,9 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
};
useEffect(() => {
if (isEmpty(table)) return;
if (!isEmpty(table) && viewTest) {
fetchAllTests();
}
}, [table]);
return (
@ -177,11 +189,10 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
/>
<Space>
<Tooltip
title={hasEditAccess ? 'Add Test' : NO_PERMISSION_FOR_ACTION}>
<Tooltip title={editTest ? 'Add Test' : NO_PERMISSION_FOR_ACTION}>
<Link
to={
hasEditAccess
editTest
? getAddDataQualityTableTestPath(
ProfilerDashboardType.TABLE,
`${table.fullyQualifiedName}`
@ -191,18 +202,17 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
<Button
className="tw-rounded"
data-testid="profiler-add-table-test-btn"
disabled={!hasEditAccess}
disabled={!editTest}
type="primary">
Add Test
</Button>
</Link>
</Tooltip>
<Tooltip
title={hasEditAccess ? 'Settings' : NO_PERMISSION_FOR_ACTION}>
<Tooltip title={editTest ? 'Settings' : NO_PERMISSION_FOR_ACTION}>
<Button
className="profiler-setting-btn tw-border tw-border-primary tw-rounded tw-text-primary"
data-testid="profiler-setting-btn"
disabled={!hasEditAccess}
disabled={!editTest}
icon={<SVGIcons alt="setting" icon={Icons.SETTINGS_PRIMERY} />}
type="default"
onClick={() => handleSettingModal(true)}>
@ -258,7 +268,7 @@ const TableProfilerV1: FC<TableProfilerProps> = ({
...col,
key: col.name,
}))}
hasEditAccess={hasEditAccess}
hasEditAccess={editTest}
onAddTestClick={onAddTestClick}
/>

View File

@ -13,6 +13,7 @@
import { AxiosError } from 'axios';
import { compare } from 'fast-json-patch';
import { isEmpty } from 'lodash';
import moment from 'moment';
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
@ -25,6 +26,11 @@ import { getListTestCase } from '../../axiosAPIs/testAPI';
import ErrorPlaceHolder from '../../components/common/error-with-placeholder/ErrorPlaceHolder';
import PageContainerV1 from '../../components/containers/PageContainerV1';
import Loader from '../../components/Loader/Loader';
import { usePermissionProvider } from '../../components/PermissionProvider/PermissionProvider';
import {
OperationPermission,
ResourceEntity,
} from '../../components/PermissionProvider/PermissionProvider.interface';
import ProfilerDashboard from '../../components/ProfilerDashboard/ProfilerDashboard';
import { API_RES_MAX_SIZE } from '../../constants/constants';
import { ProfilerDashboardType } from '../../enums/table.enum';
@ -35,6 +41,7 @@ import {
getNameFromFQN,
getTableFQNFromColumnFQN,
} from '../../utils/CommonUtils';
import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils';
import { generateEntityLink } from '../../utils/TableUtils';
import { showErrorToast } from '../../utils/ToastUtils';
@ -47,6 +54,27 @@ const ProfilerDashboardPage = () => {
const [error, setError] = useState(false);
const [testCases, setTestCases] = useState<TestCase[]>([]);
const [tablePermissions, setTablePermissions] = useState<OperationPermission>(
DEFAULT_ENTITY_PERMISSION
);
const { getEntityPermission } = usePermissionProvider();
const fetchResourcePermission = async () => {
try {
const tablePermission = await getEntityPermission(
ResourceEntity.TABLE,
table.id
);
setTablePermissions(tablePermission);
} catch (error) {
showErrorToast(
jsonData['api-error-messages']['fetch-entity-permissions-error']
);
}
};
const fetchProfilerData = async (fqn: string, days = 3) => {
try {
const startTs = moment().subtract(days, 'days').unix();
@ -98,11 +126,6 @@ const ProfilerDashboardPage = () => {
}`;
const data = await getTableDetailsByFQN(fqn, field);
setTable(data ?? ({} as Table));
if (isColumnView) {
fetchProfilerData(entityTypeFQN);
} else {
fetchTestCases(generateEntityLink(entityTypeFQN));
}
} catch (error) {
showErrorToast(
error as AxiosError,
@ -127,6 +150,16 @@ const ProfilerDashboardPage = () => {
}
};
const getProfilerDashboard = (permission: OperationPermission) => {
if (isColumnView && (permission.ViewAll || permission.ViewDataProfile)) {
fetchProfilerData(entityTypeFQN);
} else {
if (permission.ViewAll || permission.ViewTests) {
fetchTestCases(generateEntityLink(entityTypeFQN));
}
}
};
useEffect(() => {
if (entityTypeFQN) {
fetchTableEntity();
@ -136,6 +169,18 @@ const ProfilerDashboardPage = () => {
}
}, [entityTypeFQN]);
useEffect(() => {
if (!isEmpty(table)) {
fetchResourcePermission();
}
}, [table]);
useEffect(() => {
if (!isEmpty(table)) {
getProfilerDashboard(tablePermissions);
}
}, [table, tablePermissions]);
if (isLoading) {
return <Loader />;
}