mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-24 23:34:51 +00:00
UI : Added add placeholder for settings tables no data (#7237)
* Added add placeholder for settings tables no data * added dataset id in errorplaceholder * minor fixes * cypress fixes * cypress fix * fix cypress issue * fix teams and user cypress issue * unit test changes
This commit is contained in:
parent
58c439e900
commit
c6f03dcfc0
@ -564,6 +564,8 @@ export const addCustomPropertiesForEntity = (entityType, customType, value) => {
|
|||||||
cy.get('[data-testid="create-custom-field"]').scrollIntoView().click();
|
cy.get('[data-testid="create-custom-field"]').scrollIntoView().click();
|
||||||
|
|
||||||
//Check if the property got added
|
//Check if the property got added
|
||||||
|
cy.intercept('/api/v1/metadata/types/name/*?fields=customProperties').as("customProperties");
|
||||||
|
cy.wait("@customProperties");
|
||||||
cy.get('[data-testid="data-row"]').should('contain', propertyName);
|
cy.get('[data-testid="data-row"]').should('contain', propertyName);
|
||||||
|
|
||||||
//Navigating to home page
|
//Navigating to home page
|
||||||
@ -683,5 +685,37 @@ export const deleteCreatedProperty = (propertyName) => {
|
|||||||
cy.get('[data-testid="save-button"]').should('be.visible').click();
|
cy.get('[data-testid="save-button"]').should('be.visible').click();
|
||||||
|
|
||||||
//Checking if property got deleted successfully
|
//Checking if property got deleted successfully
|
||||||
cy.get('[data-testid="table-body"]').should('not.contain', propertyName);
|
cy.get('[data-testid="add-field-button"]').should('be.visible');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateOwner = () => {
|
||||||
|
cy.get('[data-testid="avatar"]').should('be.visible').click();
|
||||||
|
cy.get('[data-testid="user-name"]')
|
||||||
|
.should('exist')
|
||||||
|
.invoke('text')
|
||||||
|
.then((text) => {
|
||||||
|
cy.get('[data-testid="hiden-layer"]').should('exist').click();
|
||||||
|
|
||||||
|
//Clicking on edit owner button
|
||||||
|
cy.get('[data-testid="edit-Owner-icon"]').should('be.visible').click();
|
||||||
|
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
//Clicking on users tab
|
||||||
|
cy.get('button[data-testid="dropdown-tab"]')
|
||||||
|
.should('exist')
|
||||||
|
.should('be.visible')
|
||||||
|
.contains('Users')
|
||||||
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-testid="list-item"]').first()
|
||||||
|
.should('contain', text.trim())
|
||||||
|
.click();
|
||||||
|
|
||||||
|
//Asserting the added name
|
||||||
|
cy.get('[data-testid="owner-link"]').should(
|
||||||
|
'contain',
|
||||||
|
text.trim()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@ -259,15 +259,25 @@ describe('Roles page should work properly', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Check if last policy is not removed', () => {
|
it('Check if last policy is not removed', () => {
|
||||||
|
cy.intercept({ method: 'GET', url: `/api/v1/roles/name/${roleName}*` }).as(
|
||||||
|
'getSelectedRole'
|
||||||
|
);
|
||||||
|
|
||||||
cy.get('[data-testid="role-name"]')
|
cy.get('[data-testid="role-name"]')
|
||||||
.contains(roleName)
|
.contains(roleName)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
//Asserting navigation
|
//Asserting navigation
|
||||||
cy.get('[data-testid="inactive-link"]')
|
cy.get('[data-testid="inactive-link"]')
|
||||||
.should('contain', roleName)
|
.should('contain', roleName)
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
|
|
||||||
|
cy.wait('@getSelectedRole').its('response.statusCode').should('eq', 200);
|
||||||
|
|
||||||
|
cy.intercept({ method: 'PATCH', url: '/api/v1/roles/*' }).as(
|
||||||
|
'checkDeletedRole'
|
||||||
|
);
|
||||||
//Removing second policy from the role
|
//Removing second policy from the role
|
||||||
removePolicyFromRole(policies.dataStewardPolicy);
|
removePolicyFromRole(policies.dataStewardPolicy);
|
||||||
|
|
||||||
@ -277,6 +287,8 @@ describe('Roles page should work properly', () => {
|
|||||||
policies.dataStewardPolicy
|
policies.dataStewardPolicy
|
||||||
);
|
);
|
||||||
|
|
||||||
|
cy.wait('@checkDeletedRole').its('response.statusCode').should('eq', 200);
|
||||||
|
|
||||||
//Removing the last policy and validating the error message
|
//Removing the last policy and validating the error message
|
||||||
removePolicyFromRole(policies.dataConsumerPolicy);
|
removePolicyFromRole(policies.dataConsumerPolicy);
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { toastNotification, uuid } from '../../common/common';
|
import { toastNotification, updateOwner, uuid } from '../../common/common';
|
||||||
|
|
||||||
const orgName = 'Organization';
|
const orgName = 'Organization';
|
||||||
const updateddescription = 'This is updated description';
|
const updateddescription = 'This is updated description';
|
||||||
@ -85,31 +85,10 @@ describe('Teams flow should work properly', () => {
|
|||||||
it('Add owner to created team', () => {
|
it('Add owner to created team', () => {
|
||||||
//Clicking on created team
|
//Clicking on created team
|
||||||
cy.get('table').find('.ant-table-row').contains(TEAM_DETAILS.name).click();
|
cy.get('table').find('.ant-table-row').contains(TEAM_DETAILS.name).click();
|
||||||
|
updateOwner()
|
||||||
//Clicking on edit owner button
|
|
||||||
cy.get('[data-testid="edit-Owner-icon"]').should('be.visible').click();
|
|
||||||
|
|
||||||
cy.wait(1000);
|
|
||||||
|
|
||||||
//Clicking on users tab
|
|
||||||
cy.get('button[data-testid="dropdown-tab"]')
|
|
||||||
.should('exist')
|
|
||||||
.should('be.visible')
|
|
||||||
.contains('Users')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('[data-testid="list-item"]')
|
|
||||||
.should('contain', TEAM_DETAILS.ownername)
|
|
||||||
.click();
|
|
||||||
|
|
||||||
//Asserting the added name
|
|
||||||
cy.get('[data-testid="owner-link"]').should(
|
|
||||||
'contain',
|
|
||||||
TEAM_DETAILS.ownername
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Add user to created team', () => {
|
it('Add user to created team', () => {
|
||||||
//Click on created team
|
//Click on created team
|
||||||
cy.get('table').find('.ant-table-row').contains(TEAM_DETAILS.name).click();
|
cy.get('table').find('.ant-table-row').contains(TEAM_DETAILS.name).click();
|
||||||
|
|
||||||
@ -119,14 +98,15 @@ describe('Teams flow should work properly', () => {
|
|||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
cy.get('[data-testid="add-new-user"]')
|
cy.get('[data-testid="add-user"]')
|
||||||
|
.scrollIntoView()
|
||||||
.should('exist')
|
.should('exist')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.get('[data-testid="searchbar"]').eq(1).type(TEAM_DETAILS.ownername);
|
cy.get('[data-testid="searchbar"]').type(TEAM_DETAILS.ownername);
|
||||||
|
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
|
|
||||||
@ -163,15 +143,13 @@ describe('Teams flow should work properly', () => {
|
|||||||
// TODO: Remove cy.wait and wait for API to be completed before querying for new element
|
// TODO: Remove cy.wait and wait for API to be completed before querying for new element
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
//
|
|
||||||
//Verify if user is removed
|
//Verify if user is removed
|
||||||
cy.get('[data-testid="searchbar"]')
|
cy.get('[data-testid="Users"]')
|
||||||
|
.should('exist')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.type(TEAM_DETAILS.ownername);
|
.click();
|
||||||
|
|
||||||
cy.get('.ant-table-cell')
|
cy.get('[data-testid="add-user"]').should('not.contain', TEAM_DETAILS.ownername);
|
||||||
.should('be.visible')
|
|
||||||
.should('not.contain', TEAM_DETAILS.ownername);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Join team should work properly', () => {
|
it('Join team should work properly', () => {
|
||||||
@ -215,7 +193,7 @@ describe('Teams flow should work properly', () => {
|
|||||||
.should('contain', TEAM_DETAILS.updatedname);
|
.should('contain', TEAM_DETAILS.updatedname);
|
||||||
|
|
||||||
//Click on edit description button
|
//Click on edit description button
|
||||||
cy.get('[data-testid="edit-description"]').should('be.visible').click();
|
cy.get('[data-testid="edit-description"] > [data-testid="image"]').should('be.visible').click();
|
||||||
|
|
||||||
//Entering updated description
|
//Entering updated description
|
||||||
cy.get('.toastui-editor-md-container > .toastui-editor > .ProseMirror')
|
cy.get('.toastui-editor-md-container > .toastui-editor > .ProseMirror')
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Col, Empty, Row } from 'antd';
|
import { Col, Row } from 'antd';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { isEmpty, isEqual, isNil, isUndefined } from 'lodash';
|
import { isEmpty, isEqual, isNil, isUndefined } from 'lodash';
|
||||||
import { ColumnJoins, EntityTags, ExtraInfo } from 'Models';
|
import { ColumnJoins, EntityTags, ExtraInfo } from 'Models';
|
||||||
@ -56,6 +56,7 @@ import { CustomPropertyTable } from '../common/CustomPropertyTable/CustomPropert
|
|||||||
import { CustomPropertyProps } from '../common/CustomPropertyTable/CustomPropertyTable.interface';
|
import { CustomPropertyProps } from '../common/CustomPropertyTable/CustomPropertyTable.interface';
|
||||||
import Description from '../common/description/Description';
|
import Description from '../common/description/Description';
|
||||||
import EntityPageInfo from '../common/entityPageInfo/EntityPageInfo';
|
import EntityPageInfo from '../common/entityPageInfo/EntityPageInfo';
|
||||||
|
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
import TabsPane from '../common/TabsPane/TabsPane';
|
import TabsPane from '../common/TabsPane/TabsPane';
|
||||||
import PageContainer from '../containers/PageContainer';
|
import PageContainer from '../containers/PageContainer';
|
||||||
import EntityLineageComponent from '../EntityLineage/EntityLineage.component';
|
import EntityLineageComponent from '../EntityLineage/EntityLineage.component';
|
||||||
@ -730,10 +731,10 @@ const DatasetDetails: React.FC<DatasetDetailsProps> = ({
|
|||||||
</Col>
|
</Col>
|
||||||
) : (
|
) : (
|
||||||
<Col
|
<Col
|
||||||
className="tw-flex tw-justify-center tw-font-medium tw-items-center tw-border tw-border-main tw-rounded-md tw-p-8 tw-col-span-3"
|
className="tw-flex tw-justify-center tw-font-medium tw-items-center tw-p-8 tw-col-span-3"
|
||||||
span={24}>
|
span={24}>
|
||||||
<div data-testid="no-queries">
|
<div data-testid="no-queries">
|
||||||
<Empty description={<p>No queries data available</p>} />
|
<ErrorPlaceHolder heading="queries" />
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -61,6 +61,10 @@ jest.mock('../common/rich-text-editor/RichTextEditorPreviewer', () => {
|
|||||||
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
return jest.fn().mockReturnValue(<p>RichTextEditorPreviewer</p>);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jest.mock('../common/error-with-placeholder/ErrorPlaceHolder', () => {
|
||||||
|
return jest.fn().mockReturnValue(<p data-testid="error">ErrorPlaceHolder</p>);
|
||||||
|
});
|
||||||
|
|
||||||
const mockUserTeam = [
|
const mockUserTeam = [
|
||||||
{
|
{
|
||||||
description: 'description',
|
description: 'description',
|
||||||
|
|||||||
@ -98,6 +98,17 @@ interface AddAttribute {
|
|||||||
selectedData: EntityReference[];
|
selectedData: EntityReference[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PlaceholderProps {
|
||||||
|
title?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
label?: string;
|
||||||
|
onClick?: () => void;
|
||||||
|
heading?: string;
|
||||||
|
description?: React.ReactNode;
|
||||||
|
button?: React.ReactNode;
|
||||||
|
datatestid?: string;
|
||||||
|
}
|
||||||
|
|
||||||
const TeamDetailsV1 = ({
|
const TeamDetailsV1 = ({
|
||||||
hasAccess,
|
hasAccess,
|
||||||
currentTeam,
|
currentTeam,
|
||||||
@ -196,6 +207,45 @@ const TeamDetailsV1 = ({
|
|||||||
setDeletingUser({ user, state: true, leave });
|
setDeletingUser({ user, state: true, leave });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchErrorPlaceHolder = useMemo(
|
||||||
|
() =>
|
||||||
|
({
|
||||||
|
title,
|
||||||
|
disabled,
|
||||||
|
label,
|
||||||
|
onClick,
|
||||||
|
heading,
|
||||||
|
description,
|
||||||
|
button,
|
||||||
|
datatestid,
|
||||||
|
}: PlaceholderProps) => {
|
||||||
|
return (
|
||||||
|
<ErrorPlaceHolder
|
||||||
|
buttons={
|
||||||
|
button ? (
|
||||||
|
button
|
||||||
|
) : (
|
||||||
|
<ButtonAntd
|
||||||
|
ghost
|
||||||
|
data-testid={datatestid}
|
||||||
|
disabled={disabled}
|
||||||
|
size="small"
|
||||||
|
title={title}
|
||||||
|
type="primary"
|
||||||
|
onClick={onClick}>
|
||||||
|
{label}
|
||||||
|
</ButtonAntd>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
description={description}
|
||||||
|
heading={heading}
|
||||||
|
type="ADD_DATA"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
const columns: ColumnsType<User> = useMemo(() => {
|
const columns: ColumnsType<User> = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
...commonUserDetailColumns,
|
...commonUserDetailColumns,
|
||||||
@ -555,45 +605,12 @@ const TeamDetailsV1 = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="tw-flex tw-justify-between tw-items-center tw-mb-3">
|
{isEmpty(currentTeamUsers) &&
|
||||||
<div className="tw-w-4/12">
|
!teamUsersSearchText &&
|
||||||
<Searchbar
|
!isTeamMemberLoading ? (
|
||||||
removeMargin
|
fetchErrorPlaceHolder({
|
||||||
placeholder="Search for user..."
|
description: (
|
||||||
searchValue={teamUsersSearchText}
|
<div className="tw-mb-2">
|
||||||
typingInterval={500}
|
|
||||||
onSearch={handleTeamUsersSearchAction}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{currentTeamUsers.length > 0 && isActionAllowed() && (
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
className="tw-h-8 tw-px-2"
|
|
||||||
data-testid="add-user"
|
|
||||||
disabled={!entityPermissions.EditAll}
|
|
||||||
size="small"
|
|
||||||
theme="primary"
|
|
||||||
title={
|
|
||||||
entityPermissions.EditAll
|
|
||||||
? 'Add User'
|
|
||||||
: NO_PERMISSION_FOR_ACTION
|
|
||||||
}
|
|
||||||
variant="contained"
|
|
||||||
onClick={() => {
|
|
||||||
handleAddUser(true);
|
|
||||||
}}>
|
|
||||||
Add User
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
{isTeamMemberLoading ? (
|
|
||||||
<Loader />
|
|
||||||
) : (
|
|
||||||
<div>
|
|
||||||
{currentTeamUsers.length <= 0 ? (
|
|
||||||
<div className="tw-flex tw-flex-col tw-items-center tw-place-content-center tw-mt-40 tw-gap-1">
|
|
||||||
<p>
|
<p>
|
||||||
There are no users{' '}
|
There are no users{' '}
|
||||||
{teamUsersSearchText
|
{teamUsersSearchText
|
||||||
@ -601,44 +618,79 @@ const TeamDetailsV1 = ({
|
|||||||
: `added yet.`}
|
: `added yet.`}
|
||||||
</p>
|
</p>
|
||||||
<p>Would like to start adding some?</p>
|
<p>Would like to start adding some?</p>
|
||||||
<Button
|
|
||||||
className="tw-h-8 tw-rounded tw-my-2"
|
|
||||||
data-testid="add-new-user"
|
|
||||||
disabled={!entityPermissions.EditAll}
|
|
||||||
size="small"
|
|
||||||
theme="primary"
|
|
||||||
title={
|
|
||||||
entityPermissions.EditAll
|
|
||||||
? 'Add New User'
|
|
||||||
: NO_PERMISSION_FOR_ACTION
|
|
||||||
}
|
|
||||||
variant="contained"
|
|
||||||
onClick={() => handleAddUser(true)}>
|
|
||||||
Add new user
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
),
|
||||||
<Fragment>
|
disabled: !entityPermissions.EditAll,
|
||||||
<Table
|
title: entityPermissions.EditAll
|
||||||
className="teams-list-table"
|
? 'Add New User'
|
||||||
columns={columns}
|
: NO_PERMISSION_FOR_ACTION,
|
||||||
dataSource={sortedUser}
|
|
||||||
pagination={false}
|
onClick: () => handleAddUser(true),
|
||||||
size="small"
|
label: 'Add new user',
|
||||||
|
datatestid: 'add-user',
|
||||||
|
})
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="tw-flex tw-justify-between tw-items-center tw-mb-3">
|
||||||
|
<div className="tw-w-4/12">
|
||||||
|
<Searchbar
|
||||||
|
removeMargin
|
||||||
|
placeholder="Search for user..."
|
||||||
|
searchValue={teamUsersSearchText}
|
||||||
|
typingInterval={500}
|
||||||
|
onSearch={handleTeamUsersSearchAction}
|
||||||
/>
|
/>
|
||||||
{teamUserPagin.total > PAGE_SIZE_MEDIUM && (
|
</div>
|
||||||
<NextPrevious
|
|
||||||
currentPage={currentTeamUserPage}
|
{currentTeamUsers.length > 0 && isActionAllowed() && (
|
||||||
isNumberBased={Boolean(teamUsersSearchText)}
|
<div>
|
||||||
pageSize={PAGE_SIZE_MEDIUM}
|
<Button
|
||||||
paging={teamUserPagin}
|
className="tw-h-8 tw-px-2"
|
||||||
pagingHandler={teamUserPaginHandler}
|
data-testid="add-user"
|
||||||
totalCount={teamUserPagin.total}
|
disabled={!entityPermissions.EditAll}
|
||||||
|
size="small"
|
||||||
|
theme="primary"
|
||||||
|
title={
|
||||||
|
entityPermissions.EditAll
|
||||||
|
? 'Add User'
|
||||||
|
: NO_PERMISSION_FOR_ACTION
|
||||||
|
}
|
||||||
|
variant="contained"
|
||||||
|
onClick={() => {
|
||||||
|
handleAddUser(true);
|
||||||
|
}}>
|
||||||
|
Add User
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isTeamMemberLoading ? (
|
||||||
|
<Loader />
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<Fragment>
|
||||||
|
<Table
|
||||||
|
className="teams-list-table"
|
||||||
|
columns={columns}
|
||||||
|
dataSource={sortedUser}
|
||||||
|
pagination={false}
|
||||||
|
size="small"
|
||||||
/>
|
/>
|
||||||
)}
|
{teamUserPagin.total > PAGE_SIZE_MEDIUM && (
|
||||||
</Fragment>
|
<NextPrevious
|
||||||
|
currentPage={currentTeamUserPage}
|
||||||
|
isNumberBased={Boolean(teamUsersSearchText)}
|
||||||
|
pageSize={PAGE_SIZE_MEDIUM}
|
||||||
|
paging={teamUserPagin}
|
||||||
|
pagingHandler={teamUserPaginHandler}
|
||||||
|
totalCount={teamUserPagin.total}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -652,21 +704,21 @@ const TeamDetailsV1 = ({
|
|||||||
const ownData = filterEntityAssets(currentTeam?.owns || []);
|
const ownData = filterEntityAssets(currentTeam?.owns || []);
|
||||||
|
|
||||||
if (ownData.length <= 0) {
|
if (ownData.length <= 0) {
|
||||||
return (
|
return fetchErrorPlaceHolder({
|
||||||
<div className="tw-flex tw-flex-col tw-items-center tw-place-content-center tw-mt-40 tw-gap-1">
|
description: (
|
||||||
<p>Your team does not have any assets</p>
|
<div className="tw-mb-4">
|
||||||
<p>Would like to start adding some?</p>
|
<p>Your team does not have any assets</p>
|
||||||
|
<p>Would like to start adding some?</p>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
button: (
|
||||||
<Link to="/explore">
|
<Link to="/explore">
|
||||||
<Button
|
<ButtonAntd ghost size="small" type="primary">
|
||||||
className="tw-h-8 tw-rounded tw-mb-2 tw-text-white"
|
|
||||||
size="small"
|
|
||||||
theme="primary"
|
|
||||||
variant="contained">
|
|
||||||
Explore
|
Explore
|
||||||
</Button>
|
</ButtonAntd>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
),
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -884,109 +936,153 @@ const TeamDetailsV1 = ({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="tw-flex-grow tw-flex tw-flex-col tw-pt-4">
|
<div className="tw-flex-grow tw-flex tw-flex-col tw-pt-4">
|
||||||
{currentTab === 1 && (
|
{currentTab === 1 &&
|
||||||
<Row className="team-list-container" gutter={[16, 16]}>
|
(isEmpty(table) && !searchTerm ? (
|
||||||
<Col span={8}>
|
fetchErrorPlaceHolder({
|
||||||
<Searchbar
|
title: createTeamPermission
|
||||||
removeMargin
|
? 'Add Team'
|
||||||
placeholder="Search for team..."
|
: NO_PERMISSION_FOR_ACTION,
|
||||||
searchValue={searchTerm}
|
label: 'Add Team',
|
||||||
typingInterval={500}
|
onClick: () => handleAddTeam(true),
|
||||||
onSearch={handleTeamSearch}
|
disabled: !createTeamPermission,
|
||||||
/>
|
heading: 'Team',
|
||||||
</Col>
|
})
|
||||||
<Col span={16}>
|
) : (
|
||||||
<Space
|
<Row className="team-list-container" gutter={[16, 16]}>
|
||||||
align="end"
|
<Col span={8}>
|
||||||
className="tw-w-full"
|
<Searchbar
|
||||||
direction="vertical">
|
removeMargin
|
||||||
<ButtonAntd
|
placeholder="Search for team..."
|
||||||
disabled={!createTeamPermission}
|
searchValue={searchTerm}
|
||||||
title={
|
typingInterval={500}
|
||||||
createTeamPermission
|
onSearch={handleTeamSearch}
|
||||||
? 'Add Team'
|
/>
|
||||||
: NO_PERMISSION_FOR_ACTION
|
</Col>
|
||||||
}
|
<Col span={16}>
|
||||||
type="primary"
|
<Space
|
||||||
onClick={() => handleAddTeam(true)}>
|
align="end"
|
||||||
Add Team
|
className="tw-w-full"
|
||||||
</ButtonAntd>
|
direction="vertical">
|
||||||
</Space>
|
<ButtonAntd
|
||||||
</Col>
|
disabled={!createTeamPermission}
|
||||||
<Col span={24}>
|
title={
|
||||||
<TeamHierarchy
|
createTeamPermission
|
||||||
data={table as Team[]}
|
? 'Add Team'
|
||||||
onTeamExpand={onTeamExpand}
|
: NO_PERMISSION_FOR_ACTION
|
||||||
/>
|
}
|
||||||
</Col>
|
type="primary"
|
||||||
</Row>
|
onClick={() => handleAddTeam(true)}>
|
||||||
)}
|
Add Team
|
||||||
|
</ButtonAntd>
|
||||||
|
</Space>
|
||||||
|
</Col>
|
||||||
|
<Col span={24}>
|
||||||
|
<TeamHierarchy
|
||||||
|
data={table as Team[]}
|
||||||
|
onTeamExpand={onTeamExpand}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
))}
|
||||||
|
|
||||||
{currentTab === 2 && getUserCards()}
|
{currentTab === 2 && getUserCards()}
|
||||||
|
|
||||||
{currentTab === 3 && getDatasetCards()}
|
{currentTab === 3 && getDatasetCards()}
|
||||||
|
|
||||||
{currentTab === 4 && (
|
{currentTab === 4 &&
|
||||||
<Space
|
(isEmpty(currentTeam.defaultRoles || []) ? (
|
||||||
className="tw-w-full roles-and-policy"
|
fetchErrorPlaceHolder({
|
||||||
direction="vertical">
|
title: entityPermissions.EditAll
|
||||||
<ButtonAntd
|
? 'Add Role'
|
||||||
data-testid="add-role"
|
: NO_PERMISSION_FOR_ACTION,
|
||||||
disabled={!entityPermissions.EditAll}
|
label: 'Add Role',
|
||||||
title={
|
onClick: () =>
|
||||||
entityPermissions.EditAll
|
|
||||||
? 'Add Role'
|
|
||||||
: NO_PERMISSION_FOR_ACTION
|
|
||||||
}
|
|
||||||
type="primary"
|
|
||||||
onClick={() =>
|
|
||||||
setAddAttribute({
|
setAddAttribute({
|
||||||
type: EntityType.ROLE,
|
type: EntityType.ROLE,
|
||||||
selectedData: currentTeam.defaultRoles || [],
|
selectedData: currentTeam.defaultRoles || [],
|
||||||
})
|
}),
|
||||||
}>
|
disabled: !entityPermissions.EditAll,
|
||||||
Add Role
|
heading: 'Role',
|
||||||
</ButtonAntd>
|
datatestid: 'add-role',
|
||||||
<ListEntities
|
})
|
||||||
hasAccess={entityPermissions.EditAll}
|
) : (
|
||||||
list={currentTeam.defaultRoles || []}
|
<Space
|
||||||
type={EntityType.ROLE}
|
className="tw-w-full roles-and-policy"
|
||||||
onDelete={(record) =>
|
direction="vertical">
|
||||||
setEntity({ record, attribute: 'defaultRoles' })
|
<ButtonAntd
|
||||||
}
|
data-testid="add-role"
|
||||||
/>
|
disabled={!entityPermissions.EditAll}
|
||||||
</Space>
|
title={
|
||||||
)}
|
entityPermissions.EditAll
|
||||||
{currentTab === 5 && (
|
? 'Add Role'
|
||||||
<Space
|
: NO_PERMISSION_FOR_ACTION
|
||||||
className="tw-w-full roles-and-policy"
|
}
|
||||||
direction="vertical">
|
type="primary"
|
||||||
<ButtonAntd
|
onClick={() =>
|
||||||
data-testid="add-policy"
|
setAddAttribute({
|
||||||
disabled={!entityPermissions.EditAll}
|
type: EntityType.ROLE,
|
||||||
title={
|
selectedData: currentTeam.defaultRoles || [],
|
||||||
entityPermissions.EditAll
|
})
|
||||||
? 'Add Policy'
|
}>
|
||||||
: NO_PERMISSION_FOR_ACTION
|
Add Role
|
||||||
}
|
</ButtonAntd>
|
||||||
type="primary"
|
<ListEntities
|
||||||
onClick={() =>
|
hasAccess={entityPermissions.EditAll}
|
||||||
|
list={currentTeam.defaultRoles || []}
|
||||||
|
type={EntityType.ROLE}
|
||||||
|
onDelete={(record) =>
|
||||||
|
setEntity({ record, attribute: 'defaultRoles' })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
))}
|
||||||
|
{currentTab === 5 &&
|
||||||
|
(isEmpty(currentTeam.policies) ? (
|
||||||
|
fetchErrorPlaceHolder({
|
||||||
|
title: entityPermissions.EditAll
|
||||||
|
? 'Add Policy'
|
||||||
|
: NO_PERMISSION_FOR_ACTION,
|
||||||
|
label: 'Add Policy',
|
||||||
|
datatestid: 'add-policy',
|
||||||
|
onClick: () =>
|
||||||
setAddAttribute({
|
setAddAttribute({
|
||||||
type: EntityType.POLICY,
|
type: EntityType.POLICY,
|
||||||
selectedData: currentTeam.policies || [],
|
selectedData: currentTeam.policies || [],
|
||||||
})
|
}),
|
||||||
}>
|
disabled: !entityPermissions.EditAll,
|
||||||
Add Policy
|
heading: 'Policies',
|
||||||
</ButtonAntd>
|
})
|
||||||
<ListEntities
|
) : (
|
||||||
hasAccess={entityPermissions.EditAll}
|
<Space
|
||||||
list={currentTeam.policies || []}
|
className="tw-w-full roles-and-policy"
|
||||||
type={EntityType.POLICY}
|
direction="vertical">
|
||||||
onDelete={(record) =>
|
<ButtonAntd
|
||||||
setEntity({ record, attribute: 'policies' })
|
data-testid="add-policy"
|
||||||
}
|
disabled={!entityPermissions.EditAll}
|
||||||
/>
|
title={
|
||||||
</Space>
|
entityPermissions.EditAll
|
||||||
)}
|
? 'Add Policy'
|
||||||
|
: NO_PERMISSION_FOR_ACTION
|
||||||
|
}
|
||||||
|
type="primary"
|
||||||
|
onClick={() =>
|
||||||
|
setAddAttribute({
|
||||||
|
type: EntityType.POLICY,
|
||||||
|
selectedData: currentTeam.policies || [],
|
||||||
|
})
|
||||||
|
}>
|
||||||
|
Add Policy
|
||||||
|
</ButtonAntd>
|
||||||
|
<ListEntities
|
||||||
|
hasAccess={entityPermissions.EditAll}
|
||||||
|
list={currentTeam.policies || []}
|
||||||
|
type={EntityType.POLICY}
|
||||||
|
onDelete={(record) =>
|
||||||
|
setEntity({ record, attribute: 'policies' })
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Space>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
import { Button, Col, Modal, Row, Space, Switch, Table, Tooltip } from 'antd';
|
import { Button, Col, Modal, Row, Space, Switch, Table, Tooltip } from 'antd';
|
||||||
import { ColumnsType } from 'antd/lib/table';
|
import { ColumnsType } from 'antd/lib/table';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { isUndefined } from 'lodash';
|
import { isEmpty, isUndefined } from 'lodash';
|
||||||
import React, { FC, useMemo, useState } from 'react';
|
import React, { FC, useMemo, useState } from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { updateUser } from '../../axiosAPIs/userAPI';
|
import { updateUser } from '../../axiosAPIs/userAPI';
|
||||||
@ -33,6 +33,7 @@ import { checkPermission } from '../../utils/PermissionsUtils';
|
|||||||
import SVGIcons, { Icons } from '../../utils/SvgUtils';
|
import SVGIcons, { Icons } from '../../utils/SvgUtils';
|
||||||
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
|
import { showErrorToast, showSuccessToast } from '../../utils/ToastUtils';
|
||||||
import DeleteWidgetModal from '../common/DeleteWidget/DeleteWidgetModal';
|
import DeleteWidgetModal from '../common/DeleteWidget/DeleteWidgetModal';
|
||||||
|
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
import NextPrevious from '../common/next-previous/NextPrevious';
|
import NextPrevious from '../common/next-previous/NextPrevious';
|
||||||
import Searchbar from '../common/searchbar/Searchbar';
|
import Searchbar from '../common/searchbar/Searchbar';
|
||||||
import Loader from '../Loader/Loader';
|
import Loader from '../Loader/Loader';
|
||||||
@ -178,6 +179,46 @@ const UserListV1: FC<UserListV1Props> = ({
|
|||||||
];
|
];
|
||||||
}, [showRestore]);
|
}, [showRestore]);
|
||||||
|
|
||||||
|
const fetchErrorPlaceHolder = useMemo(
|
||||||
|
() => (type: string) => {
|
||||||
|
return (
|
||||||
|
<Row>
|
||||||
|
<Col className="w-full tw-flex tw-justify-end">
|
||||||
|
<span>
|
||||||
|
<Switch
|
||||||
|
checked={showDeletedUser}
|
||||||
|
size="small"
|
||||||
|
onClick={onShowDeletedUserChange}
|
||||||
|
/>
|
||||||
|
<span className="tw-ml-2">Deleted Users</span>
|
||||||
|
</span>
|
||||||
|
</Col>
|
||||||
|
<Col span={24}>
|
||||||
|
<ErrorPlaceHolder
|
||||||
|
buttons={
|
||||||
|
<Button
|
||||||
|
ghost
|
||||||
|
// data-testid="add-user"
|
||||||
|
disabled={!createPermission}
|
||||||
|
type="primary"
|
||||||
|
onClick={handleAddNewUser}>
|
||||||
|
Add User
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
heading="User"
|
||||||
|
type={type}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isEmpty(data) && !showDeletedUser && !isDataLoading && !searchTerm) {
|
||||||
|
return fetchErrorPlaceHolder('ADD_DATA');
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row className="user-listing" gutter={[16, 16]}>
|
<Row className="user-listing" gutter={[16, 16]}>
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
|
|||||||
@ -180,7 +180,9 @@ const Appbar: React.FC = (): JSX.Element => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tw-max-w-xs" data-testid="greeting-text">
|
<div className="tw-max-w-xs" data-testid="greeting-text">
|
||||||
<Link to={getUserPath(currentUser?.name as string)}>
|
<Link
|
||||||
|
data-testid="user-name"
|
||||||
|
to={getUserPath(currentUser?.name as string)}>
|
||||||
{' '}
|
{' '}
|
||||||
<Ellipses
|
<Ellipses
|
||||||
tooltip
|
tooltip
|
||||||
|
|||||||
@ -25,9 +25,17 @@ type Props = {
|
|||||||
doc?: string;
|
doc?: string;
|
||||||
buttons?: React.ReactNode;
|
buttons?: React.ReactNode;
|
||||||
buttonId?: string;
|
buttonId?: string;
|
||||||
|
description?: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ErrorPlaceHolder = ({ doc, type, children, heading, buttons }: Props) => {
|
const ErrorPlaceHolder = ({
|
||||||
|
doc,
|
||||||
|
type,
|
||||||
|
children,
|
||||||
|
heading,
|
||||||
|
buttons,
|
||||||
|
description,
|
||||||
|
}: Props) => {
|
||||||
const { Paragraph, Link } = Typography;
|
const { Paragraph, Link } = Typography;
|
||||||
|
|
||||||
return type === 'ADD_DATA' ? (
|
return type === 'ADD_DATA' ? (
|
||||||
@ -36,19 +44,25 @@ const ErrorPlaceHolder = ({ doc, type, children, heading, buttons }: Props) => {
|
|||||||
{' '}
|
{' '}
|
||||||
<img data-testid="no-data-image" src={AddPlaceHolder} width="100" />
|
<img data-testid="no-data-image" src={AddPlaceHolder} width="100" />
|
||||||
</div>
|
</div>
|
||||||
<div className="tw-flex tw-flex-col tw-items-center tw-mt-9 tw-text-base tw-font-medium">
|
<div className="tw-flex tw-flex-col tw-items-center tw-mt-10 tw-text-base tw-font-medium">
|
||||||
<Paragraph style={{ marginBottom: '4px' }}>
|
{description ? (
|
||||||
{' '}
|
description
|
||||||
Adding a new {heading} is easy, just give it a spin!
|
) : (
|
||||||
</Paragraph>
|
<>
|
||||||
<Paragraph>
|
<Paragraph style={{ marginBottom: '4px' }}>
|
||||||
{' '}
|
{' '}
|
||||||
Still need help? Refer to our{' '}
|
Adding a new {heading} is easy, just give it a spin!
|
||||||
<Link href={doc} target="_blank">
|
</Paragraph>
|
||||||
docs
|
<Paragraph>
|
||||||
</Link>{' '}
|
{' '}
|
||||||
for more information.
|
Still need help? Refer to our{' '}
|
||||||
</Paragraph>
|
<Link href={doc} target="_blank">
|
||||||
|
docs
|
||||||
|
</Link>{' '}
|
||||||
|
for more information.
|
||||||
|
</Paragraph>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="tw-text-lg tw-text-center">{buttons}</div>
|
<div className="tw-text-lg tw-text-center">{buttons}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -27,6 +27,7 @@ const AnchorDropDownList = ({ dropDownList, setIsOpen }: DropDownListProp) => {
|
|||||||
<>
|
<>
|
||||||
<button
|
<button
|
||||||
className="tw-z-10 tw-fixed tw-inset-0 tw-h-full tw-w-full tw-bg-black tw-opacity-0"
|
className="tw-z-10 tw-fixed tw-inset-0 tw-h-full tw-w-full tw-bg-black tw-opacity-0"
|
||||||
|
data-testid="hiden-layer"
|
||||||
onClick={() => setIsOpen && setIsOpen(false)}
|
onClick={() => setIsOpen && setIsOpen(false)}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -11,10 +11,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Col, Empty, Row, Tooltip } from 'antd';
|
import { Button as ButtonAntd, Col, Empty, Row, Tooltip } from 'antd';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { compare } from 'fast-json-patch';
|
import { compare } from 'fast-json-patch';
|
||||||
import { isUndefined } from 'lodash';
|
import { isEmpty, isUndefined } from 'lodash';
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { useHistory, useParams } from 'react-router-dom';
|
import { useHistory, useParams } from 'react-router-dom';
|
||||||
import { getTypeByFQN, updateType } from '../../axiosAPIs/metadataTypeAPI';
|
import { getTypeByFQN, updateType } from '../../axiosAPIs/metadataTypeAPI';
|
||||||
@ -185,29 +185,52 @@ const CustomEntityDetailV1 = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{activeTab === 1 && (
|
{activeTab === 1 &&
|
||||||
<div data-testid="entity-custom-fields">
|
(isEmpty(selectedEntityTypeDetail.customProperties) ? (
|
||||||
<div className="tw-flex tw-justify-end">
|
<div data-testid="entity-custom-fields">
|
||||||
<Tooltip
|
<ErrorPlaceHolder
|
||||||
title={editPermission ? 'Add' : NO_PERMISSION_FOR_ACTION}>
|
buttons={
|
||||||
<Button
|
<Tooltip
|
||||||
className="tw-mb-4 tw-py-1 tw-px-2 tw-rounded"
|
title={editPermission ? 'Add' : NO_PERMISSION_FOR_ACTION}>
|
||||||
data-testid="add-field-button"
|
<ButtonAntd
|
||||||
disabled={!editPermission}
|
ghost
|
||||||
size="custom"
|
data-testid="add-field-button"
|
||||||
theme="primary"
|
disabled={!editPermission}
|
||||||
onClick={() => handleAddProperty()}>
|
type="primary"
|
||||||
Add Property
|
onClick={() => handleAddProperty()}>
|
||||||
</Button>
|
Add Property
|
||||||
</Tooltip>
|
</ButtonAntd>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
heading="Property"
|
||||||
|
type="ADD_DATA"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<CustomPropertyTable
|
) : (
|
||||||
customProperties={selectedEntityTypeDetail.customProperties || []}
|
<div data-testid="entity-custom-fields">
|
||||||
hasAccess={editPermission}
|
<div className="tw-flex tw-justify-end">
|
||||||
updateEntityType={updateEntityType}
|
<Tooltip
|
||||||
/>
|
title={editPermission ? 'Add' : NO_PERMISSION_FOR_ACTION}>
|
||||||
</div>
|
<Button
|
||||||
)}
|
className="tw-mb-4 tw-py-1 tw-px-2 tw-rounded"
|
||||||
|
data-testid="add-field-button"
|
||||||
|
disabled={!editPermission}
|
||||||
|
size="custom"
|
||||||
|
theme="primary"
|
||||||
|
onClick={() => handleAddProperty()}>
|
||||||
|
Add Property
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
<CustomPropertyTable
|
||||||
|
customProperties={
|
||||||
|
selectedEntityTypeDetail.customProperties || []
|
||||||
|
}
|
||||||
|
hasAccess={editPermission}
|
||||||
|
updateEntityType={updateEntityType}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { isEmpty } from 'lodash';
|
|||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { getPolicies } from '../../../axiosAPIs/rolesAPIV1';
|
import { getPolicies } from '../../../axiosAPIs/rolesAPIV1';
|
||||||
|
import ErrorPlaceHolder from '../../../components/common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
import NextPrevious from '../../../components/common/next-previous/NextPrevious';
|
import NextPrevious from '../../../components/common/next-previous/NextPrevious';
|
||||||
import Loader from '../../../components/Loader/Loader';
|
import Loader from '../../../components/Loader/Loader';
|
||||||
import { usePermissionProvider } from '../../../components/PermissionProvider/PermissionProvider';
|
import { usePermissionProvider } from '../../../components/PermissionProvider/PermissionProvider';
|
||||||
@ -82,8 +83,32 @@ const PoliciesListPage = () => {
|
|||||||
fetchPolicies();
|
fetchPolicies();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const fetchErrorPlaceHolder = useMemo(
|
||||||
|
() => () => {
|
||||||
|
return (
|
||||||
|
<ErrorPlaceHolder
|
||||||
|
buttons={
|
||||||
|
<Button
|
||||||
|
ghost
|
||||||
|
data-testid="add-policy"
|
||||||
|
disabled={!addPolicyPermission}
|
||||||
|
type="primary"
|
||||||
|
onClick={handleAddPolicy}>
|
||||||
|
Add Policy
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
heading="Policy"
|
||||||
|
type="ADD_DATA"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
return isLoading ? (
|
return isLoading ? (
|
||||||
<Loader />
|
<Loader />
|
||||||
|
) : isEmpty(policies) ? (
|
||||||
|
fetchErrorPlaceHolder()
|
||||||
) : (
|
) : (
|
||||||
<Row className="policies-list-container" gutter={[16, 16]}>
|
<Row className="policies-list-container" gutter={[16, 16]}>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { isEmpty } from 'lodash';
|
|||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { getRoles } from '../../../axiosAPIs/rolesAPIV1';
|
import { getRoles } from '../../../axiosAPIs/rolesAPIV1';
|
||||||
|
import ErrorPlaceHolder from '../../../components/common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
import NextPrevious from '../../../components/common/next-previous/NextPrevious';
|
import NextPrevious from '../../../components/common/next-previous/NextPrevious';
|
||||||
import Loader from '../../../components/Loader/Loader';
|
import Loader from '../../../components/Loader/Loader';
|
||||||
import { usePermissionProvider } from '../../../components/PermissionProvider/PermissionProvider';
|
import { usePermissionProvider } from '../../../components/PermissionProvider/PermissionProvider';
|
||||||
@ -85,8 +86,32 @@ const RolesListPage = () => {
|
|||||||
fetchRoles();
|
fetchRoles();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const fetchErrorPlaceHolder = useMemo(
|
||||||
|
() => () => {
|
||||||
|
return (
|
||||||
|
<ErrorPlaceHolder
|
||||||
|
buttons={
|
||||||
|
<Button
|
||||||
|
ghost
|
||||||
|
data-testid="add-role"
|
||||||
|
disabled={!addRolePermission}
|
||||||
|
type="primary"
|
||||||
|
onClick={handleAddRole}>
|
||||||
|
Add Role
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
heading="Role"
|
||||||
|
type="ADD_DATA"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
return isLoading ? (
|
return isLoading ? (
|
||||||
<Loader />
|
<Loader />
|
||||||
|
) : isEmpty(roles) ? (
|
||||||
|
fetchErrorPlaceHolder()
|
||||||
) : (
|
) : (
|
||||||
<Row
|
<Row
|
||||||
className="roles-list-container"
|
className="roles-list-container"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user