mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-10-19 12:50:20 +00:00
Refactor(UI): Global settings Teams page refactoring and roles and policies update. (#7032)
* - Made organisation page default page for global settings page for teams option - Unnecessary actions for organisation removed * Added support for new permissions API in teams page * Replaced hard coded path with existing util function. * Worked on comments * Fixed minor bug and cypress test * fixed failing cypress tests
This commit is contained in:
parent
a39c4db8e7
commit
6547beeffc
@ -11,7 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { addNewTagToEntity } from '../../common/common';
|
import { searchEntity } from '../../common/common';
|
||||||
import { DELETE_TERM, NEW_GLOSSARY, NEW_GLOSSARY_TERMS, SEARCH_ENTITY_TABLE } from '../../constants/constants';
|
import { DELETE_TERM, NEW_GLOSSARY, NEW_GLOSSARY_TERMS, SEARCH_ENTITY_TABLE } from '../../constants/constants';
|
||||||
|
|
||||||
const createGlossaryTerm = (term) => {
|
const createGlossaryTerm = (term) => {
|
||||||
@ -227,6 +227,11 @@ describe('Glossary page should work properly', () => {
|
|||||||
.as('synonyms');
|
.as('synonyms');
|
||||||
cy.get('@synonyms').clear();
|
cy.get('@synonyms').clear();
|
||||||
cy.get('@synonyms').type(uSynonyms);
|
cy.get('@synonyms').type(uSynonyms);
|
||||||
|
|
||||||
|
cy.intercept({ method: 'PATCH', url: '/api/v1/glossaryTerms/*' }).as(
|
||||||
|
'getGlossary'
|
||||||
|
);
|
||||||
|
|
||||||
cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click();
|
cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click();
|
||||||
cy.wait(100);
|
cy.wait(100);
|
||||||
cy.get('[data-testid="synonyms-container"]')
|
cy.get('[data-testid="synonyms-container"]')
|
||||||
@ -237,6 +242,8 @@ describe('Glossary page should work properly', () => {
|
|||||||
cy.get('@synonyms-container').contains(synonym).should('be.visible');
|
cy.get('@synonyms-container').contains(synonym).should('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cy.wait('@getGlossary').its('response.statusCode').should('eq', 200);
|
||||||
|
|
||||||
// updating References
|
// updating References
|
||||||
cy.get('[data-testid="section-references"] [data-testid="add-button"]')
|
cy.get('[data-testid="section-references"] [data-testid="add-button"]')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
@ -316,6 +323,7 @@ describe('Glossary page should work properly', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('Assets Tab should work properly', () => {
|
it('Assets Tab should work properly', () => {
|
||||||
|
const glossary = NEW_GLOSSARY.name;
|
||||||
const term = NEW_GLOSSARY_TERMS.term_1.name;
|
const term = NEW_GLOSSARY_TERMS.term_1.name;
|
||||||
const entity = SEARCH_ENTITY_TABLE.table_3.term;
|
const entity = SEARCH_ENTITY_TABLE.table_3.term;
|
||||||
goToAssetsTab(term);
|
goToAssetsTab(term);
|
||||||
@ -323,7 +331,46 @@ describe('Glossary page should work properly', () => {
|
|||||||
.contains('No assets available.')
|
.contains('No assets available.')
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
|
|
||||||
addNewTagToEntity(entity, term);
|
searchEntity(entity);
|
||||||
|
cy.wait(500);
|
||||||
|
cy.get('[data-testid="table-link"]').first().contains(entity).click();
|
||||||
|
|
||||||
|
//Add tag to breadcrumb
|
||||||
|
cy.get('[data-testid="tag-container"] [data-testid="tags"]')
|
||||||
|
.eq(0)
|
||||||
|
.should('be.visible')
|
||||||
|
.click();
|
||||||
|
cy.get('[class*="-control"]').should('be.visible').type(term);
|
||||||
|
cy.wait(500);
|
||||||
|
cy.get('[id*="-option-0"]').should('be.visible').click();
|
||||||
|
cy.get(
|
||||||
|
'[data-testid="tags-wrapper"] [data-testid="tag-container"]'
|
||||||
|
).contains(term);
|
||||||
|
cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click();
|
||||||
|
cy.wait(1000);
|
||||||
|
|
||||||
|
cy.get('[data-testid="entity-tags"]')
|
||||||
|
.scrollIntoView()
|
||||||
|
.should('be.visible')
|
||||||
|
.contains(term);
|
||||||
|
|
||||||
|
//Add tag to schema table
|
||||||
|
cy.get('[data-testid="tag-container"] [data-testid="tags"]')
|
||||||
|
.eq(0)
|
||||||
|
.should('be.visible')
|
||||||
|
.click();
|
||||||
|
cy.get('[class*="-control"]').should('be.visible').type(term);
|
||||||
|
cy.wait(500);
|
||||||
|
cy.get('[id*="-option-0"]').should('be.visible').click();
|
||||||
|
cy.get(
|
||||||
|
'[data-testid="tags-wrapper"] [data-testid="tag-container"]'
|
||||||
|
).contains(term);
|
||||||
|
cy.get('[data-testid="saveAssociatedTag"]').should('be.visible').click();
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.get(`[data-testid="tag-${glossary}.${term}"]`)
|
||||||
|
.scrollIntoView()
|
||||||
|
.should('be.visible')
|
||||||
|
.contains(term);
|
||||||
|
|
||||||
cy.get('[data-testid="appbar-item-glossary"]')
|
cy.get('[data-testid="appbar-item-glossary"]')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
@ -353,34 +400,17 @@ describe('Glossary page should work properly', () => {
|
|||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
cy.get(':nth-child(1) > .css-xb97g8')
|
cy.get('[role="button"]').eq(0).should('be.visible').click();
|
||||||
.scrollIntoView()
|
cy.get('[role="button"]').eq(0).should('be.visible').click();
|
||||||
.should('be.visible')
|
|
||||||
.click();
|
|
||||||
cy.get(':nth-child(1) > .css-xb97g8')
|
|
||||||
.scrollIntoView()
|
|
||||||
.should('be.visible')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click();
|
cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click();
|
||||||
|
|
||||||
//Remove the added column tag from entity
|
//Remove the added column tag from entity
|
||||||
cy.get(
|
|
||||||
':nth-child(1) > :nth-child(5) span.tw-text-primary > [data-testid="tags"]'
|
|
||||||
)
|
|
||||||
.scrollIntoView()
|
|
||||||
.should('be.visible')
|
|
||||||
.click();
|
|
||||||
|
|
||||||
cy.get(':nth-child(1) > .css-xb97g8')
|
cy.get('[data-testid="remove"]').eq(0).should('be.visible').click();
|
||||||
.scrollIntoView()
|
|
||||||
.should('be.visible')
|
cy.wait(500);
|
||||||
.click();
|
cy.get('[data-testid="remove"]').eq(0).should('be.visible').click();
|
||||||
cy.get(':nth-child(1) > .css-xb97g8')
|
|
||||||
.scrollIntoView()
|
|
||||||
.should('be.visible')
|
|
||||||
.click();
|
|
||||||
cy.get('[data-testid="saveAssociatedTag"]').scrollIntoView().click();
|
|
||||||
|
|
||||||
cy.get('[data-testid="appbar-item-glossary"]')
|
cy.get('[data-testid="appbar-item-glossary"]')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
|
@ -16,12 +16,14 @@ import { ItemType } from 'antd/lib/menu/hooks/useItems';
|
|||||||
import { camelCase } from 'lodash';
|
import { camelCase } from 'lodash';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { useHistory, useParams } from 'react-router-dom';
|
import { useHistory, useParams } from 'react-router-dom';
|
||||||
|
import { GlobalSettingOptions } from '../../constants/globalSettings.constants';
|
||||||
|
import { TeamType } from '../../generated/entity/teams/team';
|
||||||
import {
|
import {
|
||||||
getGlobalSettingMenuItem,
|
getGlobalSettingMenuItem,
|
||||||
getGlobalSettingsMenuWithPermission,
|
getGlobalSettingsMenuWithPermission,
|
||||||
MenuList,
|
MenuList,
|
||||||
} from '../../utils/GlobalSettingsUtils';
|
} from '../../utils/GlobalSettingsUtils';
|
||||||
import { getSettingPath } from '../../utils/RouterUtils';
|
import { getSettingPath, getTeamsWithFqnPath } from '../../utils/RouterUtils';
|
||||||
import { usePermissionProvider } from '../PermissionProvider/PermissionProvider';
|
import { usePermissionProvider } from '../PermissionProvider/PermissionProvider';
|
||||||
|
|
||||||
const GlobalSettingLeftPanel = () => {
|
const GlobalSettingLeftPanel = () => {
|
||||||
@ -56,7 +58,11 @@ const GlobalSettingLeftPanel = () => {
|
|||||||
const onClick: MenuProps['onClick'] = (e) => {
|
const onClick: MenuProps['onClick'] = (e) => {
|
||||||
// As we are setting key as "category.option" and extracting here category and option
|
// As we are setting key as "category.option" and extracting here category and option
|
||||||
const [category, option] = e.key.split('.');
|
const [category, option] = e.key.split('.');
|
||||||
history.push(getSettingPath(category, option));
|
if (option === GlobalSettingOptions.TEAMS) {
|
||||||
|
history.push(getTeamsWithFqnPath(TeamType.Organization));
|
||||||
|
} else {
|
||||||
|
history.push(getSettingPath(category, option));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return menuItems.length ? (
|
return menuItems.length ? (
|
||||||
|
@ -15,6 +15,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|||||||
import {
|
import {
|
||||||
Button as ButtonAntd,
|
Button as ButtonAntd,
|
||||||
Col,
|
Col,
|
||||||
|
Empty,
|
||||||
Modal,
|
Modal,
|
||||||
Row,
|
Row,
|
||||||
Space,
|
Space,
|
||||||
@ -24,6 +25,7 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { ColumnsType } from 'antd/lib/table';
|
import { ColumnsType } from 'antd/lib/table';
|
||||||
|
import { AxiosError } from 'axios';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { compare } from 'fast-json-patch';
|
import { compare } from 'fast-json-patch';
|
||||||
import { cloneDeep, isEmpty, isUndefined, orderBy } from 'lodash';
|
import { cloneDeep, isEmpty, isUndefined, orderBy } from 'lodash';
|
||||||
@ -35,13 +37,15 @@ import {
|
|||||||
getTeamAndUserDetailsPath,
|
getTeamAndUserDetailsPath,
|
||||||
getUserPath,
|
getUserPath,
|
||||||
PAGE_SIZE,
|
PAGE_SIZE,
|
||||||
TITLE_FOR_NON_ADMIN_ACTION,
|
|
||||||
TITLE_FOR_NON_OWNER_ACTION,
|
|
||||||
} from '../../constants/constants';
|
} from '../../constants/constants';
|
||||||
import {
|
import {
|
||||||
GlobalSettingOptions,
|
GlobalSettingOptions,
|
||||||
GlobalSettingsMenuCategory,
|
GlobalSettingsMenuCategory,
|
||||||
} from '../../constants/globalSettings.constants';
|
} from '../../constants/globalSettings.constants';
|
||||||
|
import {
|
||||||
|
NO_PERMISSION_FOR_ACTION,
|
||||||
|
NO_PERMISSION_TO_VIEW,
|
||||||
|
} from '../../constants/HelperTextUtil';
|
||||||
import { EntityType } from '../../enums/entity.enum';
|
import { EntityType } from '../../enums/entity.enum';
|
||||||
import { OwnerType } from '../../enums/user.enum';
|
import { OwnerType } from '../../enums/user.enum';
|
||||||
import { Operation } from '../../generated/entity/policies/policy';
|
import { Operation } from '../../generated/entity/policies/policy';
|
||||||
@ -51,8 +55,8 @@ import {
|
|||||||
User,
|
User,
|
||||||
} from '../../generated/entity/teams/user';
|
} from '../../generated/entity/teams/user';
|
||||||
import { EntityReference } from '../../generated/type/entityReference';
|
import { EntityReference } from '../../generated/type/entityReference';
|
||||||
import { useAuth } from '../../hooks/authHooks';
|
|
||||||
import { TeamDetailsProp } from '../../interface/teamsAndUsers.interface';
|
import { TeamDetailsProp } from '../../interface/teamsAndUsers.interface';
|
||||||
|
import jsonData from '../../jsons/en';
|
||||||
import AddAttributeModal from '../../pages/RolesPage/AddAttributeModal/AddAttributeModal';
|
import AddAttributeModal from '../../pages/RolesPage/AddAttributeModal/AddAttributeModal';
|
||||||
import UserCard from '../../pages/teams/UserCard';
|
import UserCard from '../../pages/teams/UserCard';
|
||||||
import {
|
import {
|
||||||
@ -61,9 +65,10 @@ import {
|
|||||||
hasEditAccess,
|
hasEditAccess,
|
||||||
} from '../../utils/CommonUtils';
|
} from '../../utils/CommonUtils';
|
||||||
import { filterEntityAssets } from '../../utils/EntityUtils';
|
import { filterEntityAssets } from '../../utils/EntityUtils';
|
||||||
import { hasPemission } from '../../utils/PermissionsUtils';
|
import { checkPermission } from '../../utils/PermissionsUtils';
|
||||||
import { getSettingPath, getTeamsWithFqnPath } from '../../utils/RouterUtils';
|
import { getSettingPath, getTeamsWithFqnPath } from '../../utils/RouterUtils';
|
||||||
import SVGIcons, { Icons } from '../../utils/SvgUtils';
|
import SVGIcons, { Icons } from '../../utils/SvgUtils';
|
||||||
|
import { showErrorToast } from '../../utils/ToastUtils';
|
||||||
import { Button } from '../buttons/Button/Button';
|
import { Button } from '../buttons/Button/Button';
|
||||||
import Description from '../common/description/Description';
|
import Description from '../common/description/Description';
|
||||||
import Ellipses from '../common/Ellipses/Ellipses';
|
import Ellipses from '../common/Ellipses/Ellipses';
|
||||||
@ -71,14 +76,19 @@ import ManageButton from '../common/entityPageInfo/ManageButton/ManageButton';
|
|||||||
import EntitySummaryDetails from '../common/EntitySummaryDetails/EntitySummaryDetails';
|
import EntitySummaryDetails from '../common/EntitySummaryDetails/EntitySummaryDetails';
|
||||||
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
|
import ErrorPlaceHolder from '../common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
import NextPrevious from '../common/next-previous/NextPrevious';
|
import NextPrevious from '../common/next-previous/NextPrevious';
|
||||||
import NonAdminAction from '../common/non-admin-action/NonAdminAction';
|
|
||||||
import Searchbar from '../common/searchbar/Searchbar';
|
import Searchbar from '../common/searchbar/Searchbar';
|
||||||
import TabsPane from '../common/TabsPane/TabsPane';
|
import TabsPane from '../common/TabsPane/TabsPane';
|
||||||
import TitleBreadcrumb from '../common/title-breadcrumb/title-breadcrumb.component';
|
import TitleBreadcrumb from '../common/title-breadcrumb/title-breadcrumb.component';
|
||||||
import { TitleBreadcrumbProps } from '../common/title-breadcrumb/title-breadcrumb.interface';
|
import { TitleBreadcrumbProps } from '../common/title-breadcrumb/title-breadcrumb.interface';
|
||||||
import Loader from '../Loader/Loader';
|
import Loader from '../Loader/Loader';
|
||||||
import ConfirmationModal from '../Modals/ConfirmationModal/ConfirmationModal';
|
import ConfirmationModal from '../Modals/ConfirmationModal/ConfirmationModal';
|
||||||
|
import { usePermissionProvider } from '../PermissionProvider/PermissionProvider';
|
||||||
|
import {
|
||||||
|
OperationPermission,
|
||||||
|
ResourceEntity,
|
||||||
|
} from '../PermissionProvider/PermissionProvider.interface';
|
||||||
import ListEntities from './RolesAndPoliciesList';
|
import ListEntities from './RolesAndPoliciesList';
|
||||||
|
import { getTabs } from './TeamDetailsV1.utils';
|
||||||
import TeamHierarchy from './TeamHierarchy';
|
import TeamHierarchy from './TeamHierarchy';
|
||||||
import './teams.less';
|
import './teams.less';
|
||||||
interface AddAttribute {
|
interface AddAttribute {
|
||||||
@ -109,14 +119,13 @@ const TeamDetailsV1 = ({
|
|||||||
removeUserFromTeam,
|
removeUserFromTeam,
|
||||||
afterDeleteAction,
|
afterDeleteAction,
|
||||||
}: TeamDetailsProp) => {
|
}: TeamDetailsProp) => {
|
||||||
const isOrganization =
|
const isOrganization = currentTeam.name === TeamType.Organization;
|
||||||
currentTeam.name === TeamType.Organization.toLowerCase();
|
|
||||||
const DELETE_USER_INITIAL_STATE = {
|
const DELETE_USER_INITIAL_STATE = {
|
||||||
user: undefined,
|
user: undefined,
|
||||||
state: false,
|
state: false,
|
||||||
leave: false,
|
leave: false,
|
||||||
};
|
};
|
||||||
const { userPermissions } = useAuth();
|
const { permissions, getEntityPermission } = usePermissionProvider();
|
||||||
const [currentTab, setCurrentTab] = useState(1);
|
const [currentTab, setCurrentTab] = useState(1);
|
||||||
const [isHeadingEditing, setIsHeadingEditing] = useState(false);
|
const [isHeadingEditing, setIsHeadingEditing] = useState(false);
|
||||||
const [currentUser, setCurrentUser] = useState<User>();
|
const [currentUser, setCurrentUser] = useState<User>();
|
||||||
@ -138,6 +147,15 @@ const TeamDetailsV1 = ({
|
|||||||
attribute: 'defaultRoles' | 'policies';
|
attribute: 'defaultRoles' | 'policies';
|
||||||
record: EntityReference;
|
record: EntityReference;
|
||||||
}>();
|
}>();
|
||||||
|
const [entityPermissions, setEntityPermissions] =
|
||||||
|
useState<OperationPermission>({} as OperationPermission);
|
||||||
|
|
||||||
|
const createTeamPermission = useMemo(
|
||||||
|
() =>
|
||||||
|
!isEmpty(permissions) &&
|
||||||
|
checkPermission(Operation.Create, ResourceEntity.TEAM, permissions),
|
||||||
|
[permissions]
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if current team is the owner or not
|
* Check if current team is the owner or not
|
||||||
@ -162,39 +180,6 @@ const TeamDetailsV1 = ({
|
|||||||
setDeletingUser({ user, state: true, leave });
|
setDeletingUser({ user, state: true, leave });
|
||||||
};
|
};
|
||||||
|
|
||||||
const tabs = [
|
|
||||||
{
|
|
||||||
name: 'Teams',
|
|
||||||
isProtected: false,
|
|
||||||
position: 1,
|
|
||||||
count: currentTeam.children?.length || 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Users',
|
|
||||||
isProtected: false,
|
|
||||||
position: 2,
|
|
||||||
count: teamUserPagin?.total,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Assets',
|
|
||||||
isProtected: false,
|
|
||||||
position: 3,
|
|
||||||
count: filterEntityAssets(currentTeam?.owns || []).length,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Roles',
|
|
||||||
isProtected: false,
|
|
||||||
position: 4,
|
|
||||||
count: currentTeam?.defaultRoles?.length,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Policies',
|
|
||||||
isProtected: false,
|
|
||||||
position: 5,
|
|
||||||
count: currentTeam?.policies?.length,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const columns: ColumnsType<User> = useMemo(() => {
|
const columns: ColumnsType<User> = useMemo(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -230,8 +215,13 @@ const TeamDetailsV1 = ({
|
|||||||
align="center"
|
align="center"
|
||||||
className="tw-w-full tw-justify-center remove-icon"
|
className="tw-w-full tw-justify-center remove-icon"
|
||||||
size={8}>
|
size={8}>
|
||||||
<Tooltip placement="bottom" title="Remove">
|
<Tooltip
|
||||||
|
placement="bottomRight"
|
||||||
|
title={
|
||||||
|
entityPermissions?.EditAll ? 'Remove' : NO_PERMISSION_FOR_ACTION
|
||||||
|
}>
|
||||||
<ButtonAntd
|
<ButtonAntd
|
||||||
|
disabled={!entityPermissions?.EditAll}
|
||||||
icon={
|
icon={
|
||||||
<SVGIcons
|
<SVGIcons
|
||||||
alt="Remove"
|
alt="Remove"
|
||||||
@ -425,6 +415,25 @@ const TeamDetailsV1 = ({
|
|||||||
updateTeamHandler(updatedTeamData);
|
updateTeamHandler(updatedTeamData);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchPermissions = async () => {
|
||||||
|
try {
|
||||||
|
const perms = await getEntityPermission(
|
||||||
|
ResourceEntity.TEAM,
|
||||||
|
currentTeam.id
|
||||||
|
);
|
||||||
|
setEntityPermissions(perms);
|
||||||
|
} catch (error) {
|
||||||
|
showErrorToast(
|
||||||
|
error as AxiosError,
|
||||||
|
jsonData['api-error-messages']['fetch-user-permission-error']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
!isEmpty(currentTeam) && fetchPermissions();
|
||||||
|
}, [currentTeam]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (currentTeam) {
|
if (currentTeam) {
|
||||||
const perents =
|
const perents =
|
||||||
@ -493,22 +502,23 @@ const TeamDetailsV1 = ({
|
|||||||
|
|
||||||
{currentTeamUsers.length > 0 && isActionAllowed() && (
|
{currentTeamUsers.length > 0 && isActionAllowed() && (
|
||||||
<div>
|
<div>
|
||||||
<NonAdminAction
|
<Button
|
||||||
isOwner={isActionAllowed()}
|
className="tw-h-8 tw-px-2"
|
||||||
position="bottom"
|
data-testid="add-user"
|
||||||
title={TITLE_FOR_NON_OWNER_ACTION}>
|
disabled={!entityPermissions?.EditAll}
|
||||||
<Button
|
size="small"
|
||||||
className="tw-h-8 tw-px-2"
|
theme="primary"
|
||||||
data-testid="add-user"
|
title={
|
||||||
size="small"
|
entityPermissions?.EditAll
|
||||||
theme="primary"
|
? 'Add User'
|
||||||
variant="contained"
|
: NO_PERMISSION_FOR_ACTION
|
||||||
onClick={() => {
|
}
|
||||||
handleAddUser(true);
|
variant="contained"
|
||||||
}}>
|
onClick={() => {
|
||||||
Add User
|
handleAddUser(true);
|
||||||
</Button>
|
}}>
|
||||||
</NonAdminAction>
|
Add User
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -524,26 +534,22 @@ const TeamDetailsV1 = ({
|
|||||||
? `as ${teamUsersSearchText}.`
|
? `as ${teamUsersSearchText}.`
|
||||||
: `added yet.`}
|
: `added yet.`}
|
||||||
</p>
|
</p>
|
||||||
{isActionAllowed(
|
<p>Would like to start adding some?</p>
|
||||||
hasPemission(
|
<Button
|
||||||
Operation.EditUsers,
|
className="tw-h-8 tw-rounded tw-my-2"
|
||||||
EntityType.TEAM,
|
data-testid="add-new-user"
|
||||||
userPermissions
|
disabled={!entityPermissions?.EditAll}
|
||||||
)
|
size="small"
|
||||||
) ? (
|
theme="primary"
|
||||||
<>
|
title={
|
||||||
<p>Would like to start adding some?</p>
|
entityPermissions?.EditAll
|
||||||
<Button
|
? 'Add New User'
|
||||||
className="tw-h-8 tw-rounded tw-my-2"
|
: NO_PERMISSION_FOR_ACTION
|
||||||
data-testid="add-new-user"
|
}
|
||||||
size="small"
|
variant="contained"
|
||||||
theme="primary"
|
onClick={() => handleAddUser(true)}>
|
||||||
variant="contained"
|
Add new user
|
||||||
onClick={() => handleAddUser(true)}>
|
</Button>
|
||||||
Add new user
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
) : null}
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
@ -649,7 +655,7 @@ const TeamDetailsV1 = ({
|
|||||||
|
|
||||||
const getTeamHeading = () => {
|
const getTeamHeading = () => {
|
||||||
return (
|
return (
|
||||||
<div className="tw-heading tw-text-link tw-text-base tw-mb-0">
|
<div className="tw-heading tw-text-link tw-text-base tw-mb-2">
|
||||||
{isHeadingEditing ? (
|
{isHeadingEditing ? (
|
||||||
<div className="tw-flex tw-items-center tw-gap-1">
|
<div className="tw-flex tw-items-center tw-gap-1">
|
||||||
<input
|
<input
|
||||||
@ -690,21 +696,26 @@ const TeamDetailsV1 = ({
|
|||||||
</Ellipses>
|
</Ellipses>
|
||||||
{isActionAllowed() && (
|
{isActionAllowed() && (
|
||||||
<div className={classNames('tw-w-5 tw-min-w-max')}>
|
<div className={classNames('tw-w-5 tw-min-w-max')}>
|
||||||
<NonAdminAction
|
<Tooltip
|
||||||
position="right"
|
placement="bottomLeft"
|
||||||
title={TITLE_FOR_NON_ADMIN_ACTION}>
|
title={
|
||||||
|
entityPermissions?.EditDisplayName
|
||||||
|
? 'Edit Display Name'
|
||||||
|
: NO_PERMISSION_FOR_ACTION
|
||||||
|
}>
|
||||||
<button
|
<button
|
||||||
className="tw-ml-2 focus:tw-outline-none"
|
className="tw-ml-2 focus:tw-outline-none"
|
||||||
data-testid="edit-synonyms"
|
data-testid="edit-synonyms"
|
||||||
|
disabled={!entityPermissions?.EditDisplayName}
|
||||||
onClick={() => setIsHeadingEditing(true)}>
|
onClick={() => setIsHeadingEditing(true)}>
|
||||||
<SVGIcons
|
<SVGIcons
|
||||||
alt="edit"
|
alt="edit"
|
||||||
|
className="tw-mb-1"
|
||||||
icon="icon-edit"
|
icon="icon-edit"
|
||||||
title="Edit"
|
|
||||||
width="16px"
|
width="16px"
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
</NonAdminAction>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -713,7 +724,10 @@ const TeamDetailsV1 = ({
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
const viewPermission =
|
||||||
|
!isEmpty(entityPermissions) && entityPermissions.ViewAll;
|
||||||
|
|
||||||
|
return viewPermission ? (
|
||||||
<div
|
<div
|
||||||
className="tw-h-full tw-flex tw-flex-col tw-flex-grow"
|
className="tw-h-full tw-flex tw-flex-col tw-flex-grow"
|
||||||
data-testid="team-details-container">
|
data-testid="team-details-container">
|
||||||
@ -724,37 +738,43 @@ const TeamDetailsV1 = ({
|
|||||||
className="tw-flex tw-justify-between tw-items-center"
|
className="tw-flex tw-justify-between tw-items-center"
|
||||||
data-testid="header">
|
data-testid="header">
|
||||||
{getTeamHeading()}
|
{getTeamHeading()}
|
||||||
<Space align="center">
|
{!isOrganization && (
|
||||||
{!isUndefined(currentUser) &&
|
<Space align="center">
|
||||||
teamActionButton(
|
{!isUndefined(currentUser) &&
|
||||||
!isAlreadyJoinedTeam(currentTeam.id),
|
teamActionButton(
|
||||||
currentTeam.isJoinable || false
|
!isAlreadyJoinedTeam(currentTeam.id),
|
||||||
)}
|
currentTeam.isJoinable || false
|
||||||
<NonAdminAction
|
)}
|
||||||
position="bottom"
|
|
||||||
title={TITLE_FOR_NON_ADMIN_ACTION}>
|
|
||||||
<ManageButton
|
<ManageButton
|
||||||
afterDeleteAction={afterDeleteAction}
|
afterDeleteAction={afterDeleteAction}
|
||||||
buttonClassName="tw-p-4"
|
buttonClassName="tw-p-4"
|
||||||
|
disabled={!entityPermissions.EditAll}
|
||||||
entityId={currentTeam.id}
|
entityId={currentTeam.id}
|
||||||
entityName={
|
entityName={
|
||||||
currentTeam.fullyQualifiedName || currentTeam.name
|
currentTeam.fullyQualifiedName || currentTeam.name
|
||||||
}
|
}
|
||||||
entityType="team"
|
entityType="team"
|
||||||
|
title={
|
||||||
|
entityPermissions.EditAll
|
||||||
|
? 'Manage'
|
||||||
|
: NO_PERMISSION_FOR_ACTION
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</NonAdminAction>
|
</Space>
|
||||||
</Space>
|
)}
|
||||||
</div>
|
|
||||||
<div className="tw-mb-3">
|
|
||||||
<Switch
|
|
||||||
checked={currentTeam.isJoinable}
|
|
||||||
className="tw-mr-2"
|
|
||||||
size="small"
|
|
||||||
title="Open Group"
|
|
||||||
onChange={handleOpenToJoinToggle}
|
|
||||||
/>
|
|
||||||
<span>Open Group</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
{!isOrganization && (
|
||||||
|
<div className="tw-mb-3">
|
||||||
|
<Switch
|
||||||
|
checked={currentTeam.isJoinable}
|
||||||
|
className="tw-mr-2"
|
||||||
|
size="small"
|
||||||
|
title="Open Group"
|
||||||
|
onChange={handleOpenToJoinToggle}
|
||||||
|
/>
|
||||||
|
<span>Open Group</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<EntitySummaryDetails data={extraInfo} updateOwner={updateOwner} />
|
<EntitySummaryDetails data={extraInfo} updateOwner={updateOwner} />
|
||||||
<div
|
<div
|
||||||
className="tw-mb-3 tw--ml-5 tw-mt-2"
|
className="tw-mb-3 tw--ml-5 tw-mt-2"
|
||||||
@ -762,7 +782,7 @@ const TeamDetailsV1 = ({
|
|||||||
<Description
|
<Description
|
||||||
description={currentTeam?.description || ''}
|
description={currentTeam?.description || ''}
|
||||||
entityName={currentTeam?.displayName ?? currentTeam?.name}
|
entityName={currentTeam?.displayName ?? currentTeam?.name}
|
||||||
hasEditAccess={isOwner()}
|
hasEditAccess={entityPermissions.EditDescription}
|
||||||
isEdit={isDescriptionEditable}
|
isEdit={isDescriptionEditable}
|
||||||
onCancel={() => descriptionHandler(false)}
|
onCancel={() => descriptionHandler(false)}
|
||||||
onDescriptionEdit={() => descriptionHandler(true)}
|
onDescriptionEdit={() => descriptionHandler(true)}
|
||||||
@ -774,7 +794,7 @@ const TeamDetailsV1 = ({
|
|||||||
<TabsPane
|
<TabsPane
|
||||||
activeTab={currentTab}
|
activeTab={currentTab}
|
||||||
setActiveTab={(tab) => setCurrentTab(tab)}
|
setActiveTab={(tab) => setCurrentTab(tab)}
|
||||||
tabs={tabs}
|
tabs={getTabs(currentTeam, teamUserPagin, isOrganization)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<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">
|
||||||
@ -795,6 +815,12 @@ const TeamDetailsV1 = ({
|
|||||||
className="tw-w-full"
|
className="tw-w-full"
|
||||||
direction="vertical">
|
direction="vertical">
|
||||||
<ButtonAntd
|
<ButtonAntd
|
||||||
|
disabled={!createTeamPermission}
|
||||||
|
title={
|
||||||
|
createTeamPermission
|
||||||
|
? 'Add Team'
|
||||||
|
: NO_PERMISSION_FOR_ACTION
|
||||||
|
}
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={() => handleAddTeam(true)}>
|
onClick={() => handleAddTeam(true)}>
|
||||||
Add Team
|
Add Team
|
||||||
@ -819,6 +845,12 @@ const TeamDetailsV1 = ({
|
|||||||
direction="vertical">
|
direction="vertical">
|
||||||
<ButtonAntd
|
<ButtonAntd
|
||||||
data-testid="add-role"
|
data-testid="add-role"
|
||||||
|
disabled={!entityPermissions.EditAll}
|
||||||
|
title={
|
||||||
|
entityPermissions.EditAll
|
||||||
|
? 'Add Role'
|
||||||
|
: NO_PERMISSION_FOR_ACTION
|
||||||
|
}
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAddAttribute({
|
setAddAttribute({
|
||||||
@ -843,6 +875,12 @@ const TeamDetailsV1 = ({
|
|||||||
direction="vertical">
|
direction="vertical">
|
||||||
<ButtonAntd
|
<ButtonAntd
|
||||||
data-testid="add-policy"
|
data-testid="add-policy"
|
||||||
|
disabled={!entityPermissions.EditAll}
|
||||||
|
title={
|
||||||
|
entityPermissions.EditAll
|
||||||
|
? 'Add Policy'
|
||||||
|
: NO_PERMISSION_FOR_ACTION
|
||||||
|
}
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setAddAttribute({
|
setAddAttribute({
|
||||||
@ -868,18 +906,17 @@ const TeamDetailsV1 = ({
|
|||||||
<ErrorPlaceHolder>
|
<ErrorPlaceHolder>
|
||||||
<p className="tw-text-lg tw-text-center">No Teams Added.</p>
|
<p className="tw-text-lg tw-text-center">No Teams Added.</p>
|
||||||
<div className="tw-text-lg tw-text-center">
|
<div className="tw-text-lg tw-text-center">
|
||||||
<NonAdminAction
|
<Button
|
||||||
position="bottom"
|
disabled={!createTeamPermission}
|
||||||
title={TITLE_FOR_NON_ADMIN_ACTION}>
|
size="small"
|
||||||
<Button
|
theme="primary"
|
||||||
disabled={!isActionAllowed()}
|
title={
|
||||||
size="small"
|
createTeamPermission ? 'Add Team' : NO_PERMISSION_FOR_ACTION
|
||||||
theme="primary"
|
}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
onClick={() => handleAddTeam(true)}>
|
onClick={() => handleAddTeam(true)}>
|
||||||
Click here
|
Click here
|
||||||
</Button>
|
</Button>
|
||||||
</NonAdminAction>
|
|
||||||
{' to add new Team'}
|
{' to add new Team'}
|
||||||
</div>
|
</div>
|
||||||
</ErrorPlaceHolder>
|
</ErrorPlaceHolder>
|
||||||
@ -931,6 +968,12 @@ const TeamDetailsV1 = ({
|
|||||||
</Modal>
|
</Modal>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<Row align="middle" className="tw-h-full">
|
||||||
|
<Col span={24}>
|
||||||
|
<Empty description={NO_PERMISSION_TO_VIEW} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 Collate
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Team } from '../../generated/entity/teams/team';
|
||||||
|
import { Paging } from '../../generated/type/paging';
|
||||||
|
import { filterEntityAssets } from '../../utils/EntityUtils';
|
||||||
|
|
||||||
|
export const getTabs = (
|
||||||
|
currentTeam: Team,
|
||||||
|
teamUserPagin: Paging,
|
||||||
|
isOrganization: boolean
|
||||||
|
) => {
|
||||||
|
const commonTabs = [
|
||||||
|
{
|
||||||
|
name: 'Roles',
|
||||||
|
isProtected: false,
|
||||||
|
position: 4,
|
||||||
|
count: currentTeam?.defaultRoles?.length,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Policies',
|
||||||
|
isProtected: false,
|
||||||
|
position: 5,
|
||||||
|
count: currentTeam?.policies?.length,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isOrganization) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'Teams',
|
||||||
|
isProtected: false,
|
||||||
|
position: 1,
|
||||||
|
count: currentTeam.children?.length || 0,
|
||||||
|
},
|
||||||
|
...commonTabs,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'Teams',
|
||||||
|
isProtected: false,
|
||||||
|
position: 1,
|
||||||
|
count: currentTeam.children?.length || 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Users',
|
||||||
|
isProtected: false,
|
||||||
|
position: 2,
|
||||||
|
count: teamUserPagin?.total,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Assets',
|
||||||
|
isProtected: false,
|
||||||
|
position: 3,
|
||||||
|
count: filterEntityAssets(currentTeam?.owns || []).length,
|
||||||
|
},
|
||||||
|
...commonTabs,
|
||||||
|
];
|
||||||
|
};
|
@ -11,9 +11,21 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Button, Col, Row, Space, Switch } from 'antd';
|
import { Button, Col, Empty, Row, Space, Switch, Tooltip } from 'antd';
|
||||||
import React, { FC, useMemo } from 'react';
|
import { AxiosError } from 'axios';
|
||||||
|
import React, { FC, useEffect, useMemo, useState } from 'react';
|
||||||
|
import {
|
||||||
|
NO_PERMISSION_FOR_ACTION,
|
||||||
|
NO_PERMISSION_TO_VIEW,
|
||||||
|
} from '../../constants/HelperTextUtil';
|
||||||
import { Team } from '../../generated/entity/teams/team';
|
import { Team } from '../../generated/entity/teams/team';
|
||||||
|
import jsonData from '../../jsons/en';
|
||||||
|
import { showErrorToast } from '../../utils/ToastUtils';
|
||||||
|
import { usePermissionProvider } from '../PermissionProvider/PermissionProvider';
|
||||||
|
import {
|
||||||
|
OperationPermission,
|
||||||
|
ResourceEntity,
|
||||||
|
} from '../PermissionProvider/PermissionProvider.interface';
|
||||||
import TeamHierarchy from './TeamHierarchy';
|
import TeamHierarchy from './TeamHierarchy';
|
||||||
import './teams.less';
|
import './teams.less';
|
||||||
|
|
||||||
@ -36,6 +48,10 @@ const Teams: FC<TeamsProps> = ({
|
|||||||
onAddTeamClick,
|
onAddTeamClick,
|
||||||
onTeamExpand,
|
onTeamExpand,
|
||||||
}) => {
|
}) => {
|
||||||
|
const { getResourcePermission } = usePermissionProvider();
|
||||||
|
const [resourcePermissions, setResourcePermissions] =
|
||||||
|
useState<OperationPermission>();
|
||||||
|
|
||||||
const filteredData = useMemo(
|
const filteredData = useMemo(
|
||||||
() =>
|
() =>
|
||||||
data.filter(
|
data.filter(
|
||||||
@ -45,7 +61,23 @@ const Teams: FC<TeamsProps> = ({
|
|||||||
[data, showDeletedTeam]
|
[data, showDeletedTeam]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
const fetchPermissions = async () => {
|
||||||
|
try {
|
||||||
|
const perms = await getResourcePermission(ResourceEntity.TEAM);
|
||||||
|
setResourcePermissions(perms);
|
||||||
|
} catch (error) {
|
||||||
|
showErrorToast(
|
||||||
|
error as AxiosError,
|
||||||
|
jsonData['api-error-messages']['fetch-user-permission-error']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchPermissions();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return resourcePermissions?.ViewAll ? (
|
||||||
<Row className="team-list-container" gutter={[16, 16]}>
|
<Row className="team-list-container" gutter={[16, 16]}>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<Space align="center" className="tw-w-full tw-justify-end" size={16}>
|
<Space align="center" className="tw-w-full tw-justify-end" size={16}>
|
||||||
@ -57,15 +89,30 @@ const Teams: FC<TeamsProps> = ({
|
|||||||
/>
|
/>
|
||||||
<span>Deleted Teams</span>
|
<span>Deleted Teams</span>
|
||||||
</Space>
|
</Space>
|
||||||
<Button type="primary" onClick={() => onAddTeamClick(true)}>
|
<Tooltip
|
||||||
Add Team
|
placement="bottom"
|
||||||
</Button>
|
title={
|
||||||
|
resourcePermissions.Create ? 'Add Team' : NO_PERMISSION_FOR_ACTION
|
||||||
|
}>
|
||||||
|
<Button
|
||||||
|
disabled={!resourcePermissions.Create}
|
||||||
|
type="primary"
|
||||||
|
onClick={() => onAddTeamClick(true)}>
|
||||||
|
Add Team
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
</Space>
|
</Space>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<TeamHierarchy data={filteredData} onTeamExpand={onTeamExpand} />
|
<TeamHierarchy data={filteredData} onTeamExpand={onTeamExpand} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
) : (
|
||||||
|
<Row align="middle" className="tw-h-full">
|
||||||
|
<Col span={24}>
|
||||||
|
<Empty description={NO_PERMISSION_TO_VIEW} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,12 +25,14 @@ interface Props {
|
|||||||
allowSoftDelete?: boolean;
|
allowSoftDelete?: boolean;
|
||||||
afterDeleteAction?: () => void;
|
afterDeleteAction?: () => void;
|
||||||
buttonClassName?: string;
|
buttonClassName?: string;
|
||||||
|
disabled?: boolean;
|
||||||
entityName: string;
|
entityName: string;
|
||||||
entityId?: string;
|
entityId?: string;
|
||||||
entityType?: string;
|
entityType?: string;
|
||||||
entityFQN?: string;
|
entityFQN?: string;
|
||||||
isRecursiveDelete?: boolean;
|
isRecursiveDelete?: boolean;
|
||||||
deleteMessage?: string;
|
deleteMessage?: string;
|
||||||
|
title?: string;
|
||||||
onAnnouncementClick?: () => void;
|
onAnnouncementClick?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,10 +41,12 @@ const ManageButton: FC<Props> = ({
|
|||||||
afterDeleteAction,
|
afterDeleteAction,
|
||||||
buttonClassName,
|
buttonClassName,
|
||||||
deleteMessage,
|
deleteMessage,
|
||||||
|
disabled,
|
||||||
entityName,
|
entityName,
|
||||||
entityType,
|
entityType,
|
||||||
entityId,
|
entityId,
|
||||||
isRecursiveDelete,
|
isRecursiveDelete,
|
||||||
|
title,
|
||||||
onAnnouncementClick,
|
onAnnouncementClick,
|
||||||
}) => {
|
}) => {
|
||||||
const [showActions, setShowActions] = useState<boolean>(false);
|
const [showActions, setShowActions] = useState<boolean>(false);
|
||||||
@ -114,6 +118,7 @@ const ManageButton: FC<Props> = ({
|
|||||||
<>
|
<>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
align={{ targetOffset: [-12, 0] }}
|
align={{ targetOffset: [-12, 0] }}
|
||||||
|
disabled={disabled}
|
||||||
overlay={menu}
|
overlay={menu}
|
||||||
overlayStyle={{ width: '350px' }}
|
overlayStyle={{ width: '350px' }}
|
||||||
placement="bottomRight"
|
placement="bottomRight"
|
||||||
@ -126,7 +131,9 @@ const ManageButton: FC<Props> = ({
|
|||||||
buttonClassName
|
buttonClassName
|
||||||
)}
|
)}
|
||||||
data-testid="manage-button"
|
data-testid="manage-button"
|
||||||
|
disabled={disabled}
|
||||||
size="small"
|
size="small"
|
||||||
|
title={title ?? 'Manage'}
|
||||||
type="default"
|
type="default"
|
||||||
onClick={() => setShowActions(true)}>
|
onClick={() => setShowActions(true)}>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
GlobalSettingsMenuCategory,
|
GlobalSettingsMenuCategory,
|
||||||
} from '../constants/globalSettings.constants';
|
} from '../constants/globalSettings.constants';
|
||||||
import { Operation } from '../generated/entity/policies/policy';
|
import { Operation } from '../generated/entity/policies/policy';
|
||||||
|
import { TeamType } from '../generated/entity/teams/team';
|
||||||
import TeamsPage from '../pages/teams/TeamsPage';
|
import TeamsPage from '../pages/teams/TeamsPage';
|
||||||
import { checkPermission } from '../utils/PermissionsUtils';
|
import { checkPermission } from '../utils/PermissionsUtils';
|
||||||
import { getSettingCategoryPath, getSettingPath } from '../utils/RouterUtils';
|
import { getSettingCategoryPath, getSettingPath } from '../utils/RouterUtils';
|
||||||
@ -80,10 +81,10 @@ const GlobalSettingRouter = () => {
|
|||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path={getSettingPath()}>
|
<Route exact path={getSettingPath()}>
|
||||||
<Redirect
|
<Redirect
|
||||||
to={getSettingPath(
|
to={`${getSettingPath(
|
||||||
GlobalSettingsMenuCategory.MEMBERS,
|
GlobalSettingsMenuCategory.MEMBERS,
|
||||||
GlobalSettingOptions.TEAMS
|
GlobalSettingOptions.TEAMS
|
||||||
)}
|
)}/${TeamType.Organization}`}
|
||||||
/>
|
/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route
|
<Route
|
||||||
|
Loading…
x
Reference in New Issue
Block a user