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