Fixed: Fixed service and services page issue and other miner fixes (#5669)

* Fixed service and services page issue and other miner fixes

* fixed failing unit test
This commit is contained in:
Shailesh Parmar 2022-06-27 22:32:24 +05:30 committed by GitHub
parent 3a1dfbdbcb
commit 9b588c998a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 116 additions and 74 deletions

View File

@ -1280,18 +1280,15 @@ const Entitylineage: FunctionComponent<EntityLineageProp> = ({
} }
}, [entityLineage]); }, [entityLineage]);
if (isLoading) { if (isLoading || (nodes.length === 0 && !deleted)) {
return <Loader />; return <Loader />;
} }
return deleted ? ( return deleted ? (
getDeletedLineagePlaceholder() getDeletedLineagePlaceholder()
) : ( ) : (
<Fragment>
<div <div
className={classNames( className={classNames('tw-relative tw-h-full tw--ml-4 tw--mr-7 tw--mt-4')}
'tw-relative tw-h-full tw--ml-4 tw--mr-7 tw--mt-4'
)}
data-testid="lineage-container"> data-testid="lineage-container">
<div className="tw-w-full tw-h-full" ref={reactFlowWrapper}> <div className="tw-w-full tw-h-full" ref={reactFlowWrapper}>
<ReactFlowProvider> <ReactFlowProvider>
@ -1333,7 +1330,6 @@ const Entitylineage: FunctionComponent<EntityLineageProp> = ({
<EntityLineageSidebar newAddedNode={newAddedNode} show={isEditMode} /> <EntityLineageSidebar newAddedNode={newAddedNode} show={isEditMode} />
{getConfirmationModal()} {getConfirmationModal()}
</div> </div>
</Fragment>
); );
}; };

View File

@ -127,6 +127,29 @@ const mockEntityLineageProp = {
entityLineageHandler: jest.fn(), entityLineageHandler: jest.fn(),
}; };
const mockFlowData = {
node: [
{
id: 'a4b21449-b03b-4527-b482-148f52f92ff2',
sourcePosition: 'right',
targetPosition: 'left',
type: 'default',
className: 'leaf-node core',
data: {
label: 'dim_address etl',
isEditMode: false,
columns: {},
isExpanded: false,
},
position: {
x: 0,
y: 0,
},
},
],
edge: [],
};
jest.mock('../../utils/EntityLineageUtils', () => ({ jest.mock('../../utils/EntityLineageUtils', () => ({
dragHandle: jest.fn(), dragHandle: jest.fn(),
getDataLabel: jest getDataLabel: jest
@ -138,8 +161,8 @@ jest.mock('../../utils/EntityLineageUtils', () => ({
<p>Lineage data is not available for deleted entities.</p> <p>Lineage data is not available for deleted entities.</p>
), ),
getHeaderLabel: jest.fn().mockReturnValue(<p>Header label</p>), getHeaderLabel: jest.fn().mockReturnValue(<p>Header label</p>),
getLayoutedElementsV1: jest.fn().mockReturnValue([]), getLayoutedElementsV1: jest.fn().mockImplementation(() => mockFlowData),
getLineageDataV1: jest.fn().mockReturnValue([]), getLineageDataV1: jest.fn().mockImplementation(() => mockFlowData),
getModalBodyText: jest.fn(), getModalBodyText: jest.fn(),
onLoad: jest.fn(), onLoad: jest.fn(),
onNodeContextMenu: jest.fn(), onNodeContextMenu: jest.fn(),

View File

@ -66,6 +66,10 @@ const ServiceConfig = ({
}); });
}; };
const onCancel = () => {
history.goBack();
};
const getDynamicFields = () => { const getDynamicFields = () => {
return ( return (
<ConnectionConfigForm <ConnectionConfigForm
@ -79,6 +83,7 @@ const ServiceConfig = ({
serviceCategory={serviceCategory} serviceCategory={serviceCategory}
serviceType={serviceType} serviceType={serviceType}
status={status} status={status}
onCancel={onCancel}
onSave={handleOnSaveClick} onSave={handleOnSaveClick}
/> />
); );

View File

@ -606,9 +606,7 @@ const TeamDetails = ({
blurWithBodyBG blurWithBodyBG
description={currentTeam?.description || ''} description={currentTeam?.description || ''}
entityName={currentTeam?.displayName ?? currentTeam?.name} entityName={currentTeam?.displayName ?? currentTeam?.name}
hasEditAccess={isActionAllowed( hasEditAccess={isOwner()}
userPermissions[Operation.UpdateDescription]
)}
isEdit={isDescriptionEditable} isEdit={isDescriptionEditable}
onCancel={() => descriptionHandler(false)} onCancel={() => descriptionHandler(false)}
onDescriptionEdit={() => descriptionHandler(true)} onDescriptionEdit={() => descriptionHandler(true)}

View File

@ -17,6 +17,7 @@ import { EntityFieldThreads } from 'Models';
import React, { FC, Fragment } from 'react'; import React, { FC, Fragment } from 'react';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useAuthContext } from '../../../authentication/auth-provider/AuthProvider'; import { useAuthContext } from '../../../authentication/auth-provider/AuthProvider';
import { TITLE_FOR_UPDATE_DESCRIPTION } from '../../../constants/constants';
import { EntityType } from '../../../enums/entity.enum'; import { EntityType } from '../../../enums/entity.enum';
import { Operation } from '../../../generated/entity/policies/accessControl/rule'; import { Operation } from '../../../generated/entity/policies/accessControl/rule';
import { useAuth } from '../../../hooks/authHooks'; import { useAuth } from '../../../hooks/authHooks';
@ -28,6 +29,7 @@ import {
TASK_ENTITIES, TASK_ENTITIES,
} from '../../../utils/TasksUtils'; } from '../../../utils/TasksUtils';
import { ModalWithMarkdownEditor } from '../../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor'; import { ModalWithMarkdownEditor } from '../../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor';
import NonAdminAction from '../non-admin-action/NonAdminAction';
import PopOver from '../popover/PopOver'; import PopOver from '../popover/PopOver';
import RichTextEditorPreviewer from '../rich-text-editor/RichTextEditorPreviewer'; import RichTextEditorPreviewer from '../rich-text-editor/RichTextEditorPreviewer';
import { DescriptionProps } from './Description.interface'; import { DescriptionProps } from './Description.interface';
@ -68,16 +70,22 @@ const Description: FC<DescriptionProps> = ({
); );
}; };
const handleUpdate = () => { const checkPermission = () => {
const check = if (!isAuthDisabled && !isAdminUser) {
isAdminUser || if (!isUndefined(hasEditAccess)) {
hasEditAccess || return Boolean(hasEditAccess);
isAuthDisabled ||
userPermissions[Operation.UpdateDescription] ||
!TASK_ENTITIES.includes(entityType as EntityType);
if (check) {
onDescriptionEdit && onDescriptionEdit();
} else { } else {
return userPermissions[Operation.UpdateDescription];
}
}
return true;
};
const handleUpdate = () => {
if (checkPermission()) {
onDescriptionEdit && onDescriptionEdit();
} else if (TASK_ENTITIES.includes(entityType as EntityType)) {
handleUpdateDescription(); handleUpdateDescription();
} }
}; };
@ -151,12 +159,19 @@ const Description: FC<DescriptionProps> = ({
'tw-w-5 tw-min-w-max tw-flex', 'tw-w-5 tw-min-w-max tw-flex',
description?.trim() ? 'tw-pl-1' : '' description?.trim() ? 'tw-pl-1' : ''
)}> )}>
<NonAdminAction
isOwner={
checkPermission() ||
TASK_ENTITIES.includes(entityType as EntityType)
}
title={TITLE_FOR_UPDATE_DESCRIPTION}>
<button <button
className="focus:tw-outline-none tw-self-baseline" className="focus:tw-outline-none tw-self-baseline"
data-testid="edit-description" data-testid="edit-description"
onClick={handleUpdate}> onClick={handleUpdate}>
<SVGIcons alt="edit" icon="icon-edit" title="Edit" width="16px" /> <SVGIcons alt="edit" icon="icon-edit" title="Edit" width="16px" />
</button> </button>
</NonAdminAction>
<RequestDescriptionEl descriptionThread={thread} /> <RequestDescriptionEl descriptionThread={thread} />
<DescriptionThreadEl descriptionThread={thread} /> <DescriptionThreadEl descriptionThread={thread} />

View File

@ -83,7 +83,7 @@ const TitleBreadcrumb: FunctionComponent<TitleBreadcrumbProps> = ({
className={classes} className={classes}
style={{ style={{
maxWidth, maxWidth,
fontSize: '14px', fontSize: '16px',
}} }}
to={link.url}> to={link.url}>
{link.name} {link.name}

View File

@ -433,6 +433,9 @@ export const TITLE_FOR_NON_ADMIN_ACTION =
export const TITLE_FOR_UPDATE_OWNER = export const TITLE_FOR_UPDATE_OWNER =
'You do not have permissions to update the owner.'; 'You do not have permissions to update the owner.';
export const TITLE_FOR_UPDATE_DESCRIPTION =
'You do not have permissions to update the description.';
export const configOptions = { export const configOptions = {
headers: { 'Content-type': 'application/json-patch+json' }, headers: { 'Content-type': 'application/json-patch+json' },
}; };

View File

@ -175,6 +175,7 @@ const ServicePage: FunctionComponent = () => {
}, },
isProtected: !isAdminUser && !isAuthDisabled, isProtected: !isAdminUser && !isAuthDisabled,
isHidden: !isAdminUser && !isAuthDisabled,
position: 3, position: 3,
}, },
{ {
@ -925,6 +926,7 @@ const ServicePage: FunctionComponent = () => {
entityFqn={serviceFQN} entityFqn={serviceFQN}
entityName={serviceFQN} entityName={serviceFQN}
entityType={serviceCategory.slice(0, -1)} entityType={serviceCategory.slice(0, -1)}
hasEditAccess={isAdminUser || isAuthDisabled}
isEdit={isEdit} isEdit={isEdit}
onCancel={onCancel} onCancel={onCancel}
onDescriptionEdit={onDescriptionEdit} onDescriptionEdit={onDescriptionEdit}
@ -1033,7 +1035,7 @@ const ServicePage: FunctionComponent = () => {
</Button> </Button>
</div> </div>
<ServiceConnectionDetails <ServiceConnectionDetails
connectionDetails={connectionDetails as ConfigData} connectionDetails={connectionDetails || {}}
serviceCategory={serviceCategory} serviceCategory={serviceCategory}
serviceFQN={serviceDetails?.serviceType || ''} serviceFQN={serviceDetails?.serviceType || ''}
/> />

View File

@ -307,7 +307,7 @@ const ServicesPage = () => {
<span <span
className=" tw-ml-1 tw-font-normal tw-text-grey-body" className=" tw-ml-1 tw-font-normal tw-text-grey-body"
data-testid="dashboard-url"> data-testid="dashboard-url">
{getDashboardURL(dashboardService.connection.config)} {getDashboardURL(dashboardService.connection?.config)}
</span> </span>
</div> </div>
</> </>
@ -323,7 +323,7 @@ const ServicesPage = () => {
<span <span
className=" tw-ml-1 tw-font-normal tw-text-grey-body" className=" tw-ml-1 tw-font-normal tw-text-grey-body"
data-testid="pipeline-url"> data-testid="pipeline-url">
{pipelineService.connection.config?.hostPort} {pipelineService.connection?.config?.hostPort || '--'}
</span> </span>
</div> </div>
</> </>
@ -340,7 +340,7 @@ const ServicesPage = () => {
<span <span
className=" tw-ml-1 tw-font-normal tw-text-grey-body" className=" tw-ml-1 tw-font-normal tw-text-grey-body"
data-testid="pipeline-url"> data-testid="pipeline-url">
{mlmodel.connection.config?.registryUri} {mlmodel.connection?.config?.registryUri || '--'}
</span> </span>
</div> </div>
<div className="tw-mb-1 tw-truncate" data-testid="additional-field"> <div className="tw-mb-1 tw-truncate" data-testid="additional-field">
@ -348,7 +348,7 @@ const ServicesPage = () => {
<span <span
className=" tw-ml-1 tw-font-normal tw-text-grey-body" className=" tw-ml-1 tw-font-normal tw-text-grey-body"
data-testid="pipeline-url"> data-testid="pipeline-url">
{mlmodel.connection.config?.trackingUri} {mlmodel.connection?.config?.trackingUri || '--'}
</span> </span>
</div> </div>
</> </>
@ -508,7 +508,7 @@ const ServicesPage = () => {
<p className="tw-text-lg tw-text-center"> <p className="tw-text-lg tw-text-center">
{noServicesText(searchText)} {noServicesText(searchText)}
</p> </p>
<p className="tw-text-lg tw-text-center"> <div className="tw-text-lg tw-text-center">
<NonAdminAction <NonAdminAction
position="bottom" position="bottom"
title={TITLE_FOR_NON_ADMIN_ACTION}> title={TITLE_FOR_NON_ADMIN_ACTION}>
@ -522,7 +522,7 @@ const ServicesPage = () => {
</Button> </Button>
</NonAdminAction>{' '} </NonAdminAction>{' '}
to add new {servicesDisplayName[serviceName]} to add new {servicesDisplayName[serviceName]}
</p> </div>
</div> </div>
</div> </div>
); );