mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-10 09:31:24 +00:00
fix(ui): revamp teams page added supported subscription webhooks (#13296)
* revamp teams page added supported subscription webhook * minor changes * minor changes * changes teams header page layout and subscription * minor changes * fix cypress and addressed comments * fix cypress for teams hierarchy (#13352) * fix sonar errors and users not showing in teams having space * code smell and bugs fixes * fix teams page cypress --------- Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com>
This commit is contained in:
parent
e879d512d3
commit
16a4033645
@ -37,7 +37,7 @@ export const BASE_WAIT_TIME = 20000;
|
|||||||
const ADMIN = 'admin';
|
const ADMIN = 'admin';
|
||||||
const RETRIES_COUNT = 4;
|
const RETRIES_COUNT = 4;
|
||||||
|
|
||||||
const TEAM_TYPES = ['BusinessUnit', 'Department', 'Division', 'Group'];
|
const TEAM_TYPES = ['Department', 'Division', 'Group'];
|
||||||
|
|
||||||
export const replaceAllSpacialCharWith_ = (text) => {
|
export const replaceAllSpacialCharWith_ = (text) => {
|
||||||
return text.replaceAll(/[&/\\#, +()$~%.'":*?<>{}]/g, '_');
|
return text.replaceAll(/[&/\\#, +()$~%.'":*?<>{}]/g, '_');
|
||||||
@ -53,8 +53,31 @@ export const checkServiceFieldSectionHighlighting = (field) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const checkTeamTypeOptions = () => {
|
const getTeamType = (currentTeam) => {
|
||||||
for (const teamType of TEAM_TYPES) {
|
switch (currentTeam) {
|
||||||
|
case 'BusinessUnit':
|
||||||
|
return {
|
||||||
|
childTeamType: 'Division',
|
||||||
|
teamTypeOptions: TEAM_TYPES,
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'Division':
|
||||||
|
return {
|
||||||
|
childTeamType: 'Department',
|
||||||
|
teamTypeOptions: TEAM_TYPES,
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'Department':
|
||||||
|
return {
|
||||||
|
childTeamType: 'Group',
|
||||||
|
teamTypeOptions: ['Department', 'Group'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkTeamTypeOptions = (type) => {
|
||||||
|
cy.log('check', type);
|
||||||
|
for (const teamType of getTeamType(type).teamTypeOptions) {
|
||||||
cy.get(`.ant-select-dropdown [title="${teamType}"]`)
|
cy.get(`.ant-select-dropdown [title="${teamType}"]`)
|
||||||
.should('exist')
|
.should('exist')
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
@ -961,12 +984,28 @@ export const addTeam = (TEAM_DETAILS, index) => {
|
|||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
checkTeamTypeOptions();
|
if (index > 0) {
|
||||||
|
cy.get('[data-testid="team-type"]')
|
||||||
|
.invoke('text')
|
||||||
|
.then((text) => {
|
||||||
|
cy.log(text);
|
||||||
|
checkTeamTypeOptions(text);
|
||||||
|
cy.log('check type', text);
|
||||||
|
cy.get(
|
||||||
|
`.ant-select-dropdown [title="${getTeamType(text).childTeamType}"]`
|
||||||
|
)
|
||||||
|
.should('exist')
|
||||||
|
.should('be.visible')
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
checkTeamTypeOptions('BusinessUnit');
|
||||||
|
|
||||||
cy.get(`.ant-select-dropdown [title="${TEAM_DETAILS.teamType}"]`)
|
cy.get(`.ant-select-dropdown [title='BusinessUnit']`)
|
||||||
.should('exist')
|
.should('exist')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
|
}
|
||||||
|
|
||||||
cy.get(descriptionBox)
|
cy.get(descriptionBox)
|
||||||
.should('exist')
|
.should('exist')
|
||||||
|
@ -24,12 +24,12 @@ import {
|
|||||||
verifyResponseStatusCode,
|
verifyResponseStatusCode,
|
||||||
} from '../../common/common';
|
} from '../../common/common';
|
||||||
|
|
||||||
const updateddescription = 'This is updated description';
|
const updatedDescription = 'This is updated description';
|
||||||
|
|
||||||
const teamName = 'team-group-test-430116' ?? `team-ct-test-${uuid()}`;
|
const teamName = 'team-group-test-430116' ?? `team-ct-test-${uuid()}`;
|
||||||
const TEAM_DETAILS = {
|
const TEAM_DETAILS = {
|
||||||
name: teamName,
|
name: teamName,
|
||||||
updatedname: `${teamName}-updated`,
|
updatedName: `${teamName}-updated`,
|
||||||
teamType: 'Group',
|
teamType: 'Group',
|
||||||
description: `This is ${teamName} description`,
|
description: `This is ${teamName} description`,
|
||||||
username: 'Aaron Johnson',
|
username: 'Aaron Johnson',
|
||||||
@ -125,10 +125,8 @@ describe('Teams flow should work properly', () => {
|
|||||||
.contains(TEAM_DETAILS.name)
|
.contains(TEAM_DETAILS.name)
|
||||||
.click();
|
.click();
|
||||||
verifyResponseStatusCode('@permissions', 200);
|
verifyResponseStatusCode('@permissions', 200);
|
||||||
cy.get('[data-testid="add-new-user"]')
|
cy.get('[data-testid="users"]').click();
|
||||||
.should('be.visible')
|
cy.get('[data-testid="add-new-user"]').scrollIntoView().click();
|
||||||
.scrollIntoView();
|
|
||||||
cy.get('[data-testid="add-new-user"]').click();
|
|
||||||
verifyResponseStatusCode('@getUsers', 200);
|
verifyResponseStatusCode('@getUsers', 200);
|
||||||
cy.get('[data-testid="selectable-list"] [data-testid="searchbar"]').type(
|
cy.get('[data-testid="selectable-list"] [data-testid="searchbar"]').type(
|
||||||
TEAM_DETAILS.username
|
TEAM_DETAILS.username
|
||||||
@ -154,6 +152,7 @@ describe('Teams flow should work properly', () => {
|
|||||||
cy.get(`[data-row-key="${TEAM_DETAILS.name}"]`)
|
cy.get(`[data-row-key="${TEAM_DETAILS.name}"]`)
|
||||||
.contains(TEAM_DETAILS.name)
|
.contains(TEAM_DETAILS.name)
|
||||||
.click();
|
.click();
|
||||||
|
cy.get('[data-testid="users"]').click();
|
||||||
verifyResponseStatusCode('@getUserDetails', 200);
|
verifyResponseStatusCode('@getUserDetails', 200);
|
||||||
verifyResponseStatusCode('@permissions', 200);
|
verifyResponseStatusCode('@permissions', 200);
|
||||||
cy.get('[data-testid="add-new-user"]').should('be.visible').click();
|
cy.get('[data-testid="add-new-user"]').should('be.visible').click();
|
||||||
@ -176,10 +175,15 @@ describe('Teams flow should work properly', () => {
|
|||||||
.contains(TEAM_DETAILS.name)
|
.contains(TEAM_DETAILS.name)
|
||||||
.click();
|
.click();
|
||||||
|
|
||||||
|
cy.get('[data-testid="users"]').click();
|
||||||
|
|
||||||
verifyResponseStatusCode('@getUsers', 200);
|
verifyResponseStatusCode('@getUsers', 200);
|
||||||
|
|
||||||
// Click on join teams button
|
// Click on join teams button
|
||||||
cy.get('[data-testid="join-teams"]').should('be.visible').click();
|
cy.get('[data-testid="join-teams"]')
|
||||||
|
.scrollIntoView()
|
||||||
|
.should('be.visible')
|
||||||
|
.click();
|
||||||
|
|
||||||
// Verify toast notification
|
// Verify toast notification
|
||||||
toastNotification('Team joined successfully!');
|
toastNotification('Team joined successfully!');
|
||||||
@ -201,14 +205,14 @@ describe('Teams flow should work properly', () => {
|
|||||||
|
|
||||||
verifyResponseStatusCode('@getSelectedTeam', 200);
|
verifyResponseStatusCode('@getSelectedTeam', 200);
|
||||||
// Click on edit display name
|
// Click on edit display name
|
||||||
cy.get('[data-testid="edit-synonyms"]').should('be.visible').click();
|
cy.get('[data-testid="edit-team-name"]').should('be.visible').click();
|
||||||
|
|
||||||
// Enter the updated team name
|
// Enter the updated team name
|
||||||
cy.get('[data-testid="synonyms"]')
|
cy.get('[data-testid="team-name-input"]')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.clear()
|
.clear()
|
||||||
.type(TEAM_DETAILS.updatedname);
|
.type(TEAM_DETAILS.updatedName);
|
||||||
|
|
||||||
// Save the updated display name
|
// Save the updated display name
|
||||||
cy.get('[data-testid="saveAssociatedTag"]')
|
cy.get('[data-testid="saveAssociatedTag"]')
|
||||||
@ -220,12 +224,12 @@ describe('Teams flow should work properly', () => {
|
|||||||
verifyResponseStatusCode('@getSelectedTeam', 200);
|
verifyResponseStatusCode('@getSelectedTeam', 200);
|
||||||
// Validate the updated display name
|
// Validate the updated display name
|
||||||
cy.get('[data-testid="team-heading"]').then(($el) => {
|
cy.get('[data-testid="team-heading"]').then(($el) => {
|
||||||
cy.wrap($el).should('have.text', TEAM_DETAILS.updatedname);
|
cy.wrap($el).should('have.text', TEAM_DETAILS.updatedName);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('[data-testid="inactive-link"]')
|
cy.get('[data-testid="inactive-link"]')
|
||||||
.should('be.visible')
|
.scrollIntoView()
|
||||||
.should('contain', TEAM_DETAILS.updatedname);
|
.should('contain', TEAM_DETAILS.updatedName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Update description for created team', () => {
|
it('Update description for created team', () => {
|
||||||
@ -245,12 +249,12 @@ describe('Teams flow should work properly', () => {
|
|||||||
// Validate the updated display name
|
// Validate the updated display name
|
||||||
cy.get('[data-testid="team-heading"]').should(
|
cy.get('[data-testid="team-heading"]').should(
|
||||||
'contain',
|
'contain',
|
||||||
`${TEAM_DETAILS.updatedname}`
|
`${TEAM_DETAILS.updatedName}`
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.get('[data-testid="inactive-link"]')
|
cy.get('[data-testid="inactive-link"]')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.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"]')
|
cy.get('[data-testid="edit-description"]')
|
||||||
@ -258,7 +262,7 @@ describe('Teams flow should work properly', () => {
|
|||||||
.click({ force: true });
|
.click({ force: true });
|
||||||
|
|
||||||
// Entering updated description
|
// Entering updated description
|
||||||
cy.get(descriptionBox).clear().type(updateddescription);
|
cy.get(descriptionBox).clear().type(updatedDescription);
|
||||||
|
|
||||||
cy.get('[data-testid="save"]').should('be.visible').click();
|
cy.get('[data-testid="save"]').should('be.visible').click();
|
||||||
verifyResponseStatusCode('@patchDescription', 200);
|
verifyResponseStatusCode('@patchDescription', 200);
|
||||||
@ -266,7 +270,7 @@ describe('Teams flow should work properly', () => {
|
|||||||
// Validating the updated description
|
// Validating the updated description
|
||||||
cy.get('[data-testid="description"] p').should(
|
cy.get('[data-testid="description"] p').should(
|
||||||
'contain',
|
'contain',
|
||||||
updateddescription
|
updatedDescription
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -287,7 +291,7 @@ describe('Teams flow should work properly', () => {
|
|||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.contains(TEAM_DETAILS.name);
|
.contains(TEAM_DETAILS.name);
|
||||||
// //Click on Leave team
|
// //Click on Leave team
|
||||||
cy.get('[data-testid="leave-team-button"]').should('be.visible').click();
|
cy.get('[data-testid="leave-team-button"]').click();
|
||||||
|
|
||||||
// //Click on confirm button
|
// //Click on confirm button
|
||||||
cy.get('[data-testid="save-button"]').should('be.visible').click();
|
cy.get('[data-testid="save-button"]').should('be.visible').click();
|
||||||
@ -312,8 +316,8 @@ describe('Teams flow should work properly', () => {
|
|||||||
verifyResponseStatusCode('@getSelectedTeam', 200);
|
verifyResponseStatusCode('@getSelectedTeam', 200);
|
||||||
cy.get('[data-testid="team-heading"]')
|
cy.get('[data-testid="team-heading"]')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.contains(TEAM_DETAILS.updatedname);
|
.contains(TEAM_DETAILS.updatedName);
|
||||||
cy.get('[data-testid="header"] [data-testid="manage-button"]')
|
cy.get('[data-testid="manage-button"]')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
@ -380,9 +384,9 @@ describe('Teams flow should work properly', () => {
|
|||||||
|
|
||||||
cy.get('[data-testid="team-heading"]')
|
cy.get('[data-testid="team-heading"]')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.contains(TEAM_DETAILS.updatedname);
|
.contains(TEAM_DETAILS.updatedName);
|
||||||
|
|
||||||
cy.get('[data-testid="header"] [data-testid="manage-button"]')
|
cy.get('[data-testid="manage-button"]')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
@ -436,7 +440,7 @@ describe('Teams flow should work properly', () => {
|
|||||||
.click();
|
.click();
|
||||||
|
|
||||||
verifyResponseStatusCode('@getSelectedTeam', 200);
|
verifyResponseStatusCode('@getSelectedTeam', 200);
|
||||||
cy.get('[data-testid="header"] [data-testid="manage-button"]')
|
cy.get('[data-testid="manage-button"]')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.click();
|
.click();
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
<svg viewBox="0 0 25 27" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_4154_24860)">
|
||||||
|
<path d="M5.67376 14.5249V6.05078H1.97121C0.88131 6.05078 0 6.93731 0 8.02721V25.5439C0 26.4252 1.06383 26.8633 1.6844 26.2427L5.7572 22.1699H17.355C18.4449 22.1699 19.3262 21.2886 19.3262 20.1987V16.4961H7.65019C6.56028 16.4961 5.67376 15.6148 5.67376 14.5249Z" fill="#00AC47"/>
|
||||||
|
<path d="M23.0288 0.460938H7.65017C6.56026 0.460938 5.67896 1.34225 5.67896 2.43215V6.05126H17.355C18.4449 6.05126 19.3262 6.93257 19.3262 8.02247V16.4914H23.0288C24.1187 16.4914 25 15.6101 25 14.5202V2.43215C25 1.34225 24.1187 0.460938 23.0288 0.460938Z" fill="#5BB974"/>
|
||||||
|
<path d="M17.355 6.05078H5.67371V14.5197C5.67371 15.6096 6.55502 16.4909 7.64492 16.4909H19.321V8.02721C19.3262 6.93731 18.4449 6.05078 17.355 6.05078Z" fill="#00832D"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_4154_24860">
|
||||||
|
<rect width="25" height="26.0743" fill="white" transform="translate(0 0.460938)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 991 B |
@ -0,0 +1,5 @@
|
|||||||
|
|
||||||
|
<svg viewBox="0 0 105 65" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M36.9019 2.53811C29.7245 1.986 15.3697 2.5371 15.3697 18.5493C15.3697 32.6833 21.995 36.9517 25.3076 37.3192V43.3924L10.4007 51.674C7.82417 53.1463 2.67114 57.416 2.67114 62.7162H25.3076L44.0794 52.7782V44.4966C36.9019 37.3192 35.2456 30.0108 35.2456 20.2038C35.2456 8.54045 41.3188 2.53811 52.9131 2.53811" stroke="currentColor" stroke-width="4" stroke-linecap="round"/>
|
||||||
|
<path d="M68.3725 2.53811C75.5499 1.986 89.9047 2.5371 89.9047 18.5493C89.9047 32.6833 83.2794 36.9517 79.9668 37.3192V43.3924L94.8737 51.674C97.4502 53.1463 102.603 57.416 102.603 62.7162H79.9668L61.195 52.7782V44.4966C68.3725 37.3192 70.0288 30.0108 70.0288 20.2038C70.0288 8.54045 63.9556 2.53811 52.3613 2.53811" stroke="currentColor" stroke-width="4" stroke-linecap="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 844 B |
File diff suppressed because it is too large
Load Diff
@ -138,7 +138,7 @@ const TeamHierarchy: FC<TeamHierarchyProps> = ({
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [data, onTeamExpand]);
|
}, [data, isFetchingAllTeamAdvancedDetails, onTeamExpand]);
|
||||||
|
|
||||||
const handleMoveRow = useCallback(
|
const handleMoveRow = useCallback(
|
||||||
async (dragRecord: Team, dropRecord: Team) => {
|
async (dragRecord: Team, dropRecord: Team) => {
|
||||||
|
@ -0,0 +1,357 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 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 { CheckOutlined, CloseOutlined } from '@ant-design/icons';
|
||||||
|
import { Button, Divider, Form, Input, Space, Tooltip, Typography } from 'antd';
|
||||||
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
import Icon from '@ant-design/icons/lib/components/Icon';
|
||||||
|
import { useAuthContext } from 'components/authentication/auth-provider/AuthProvider';
|
||||||
|
import { OwnerLabel } from 'components/common/OwnerLabel/OwnerLabel.component';
|
||||||
|
import { EMAIL_REG_EX } from 'constants/regex.constants';
|
||||||
|
import { useAuth } from 'hooks/authHooks';
|
||||||
|
import { isEmpty, last } from 'lodash';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { hasEditAccess } from 'utils/CommonUtils';
|
||||||
|
import { ReactComponent as EditIcon } from '../../../../assets/svg/edit-new.svg';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import TeamTypeSelect from 'components/common/TeamTypeSelect/TeamTypeSelect.component';
|
||||||
|
import { NO_DATA_PLACEHOLDER } from 'constants/constants';
|
||||||
|
import { Team, TeamType } from 'generated/entity/teams/team';
|
||||||
|
import { EntityReference } from 'generated/entity/type';
|
||||||
|
import { TeamsInfoProps } from '../team.interface';
|
||||||
|
|
||||||
|
const TeamsInfo = ({
|
||||||
|
parentTeams,
|
||||||
|
isGroupType,
|
||||||
|
childTeamsCount,
|
||||||
|
entityPermissions,
|
||||||
|
currentTeam,
|
||||||
|
updateTeamHandler,
|
||||||
|
}: TeamsInfoProps) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { isAdminUser } = useAuth();
|
||||||
|
const { isAuthDisabled } = useAuthContext();
|
||||||
|
|
||||||
|
const [isHeadingEditing, setIsHeadingEditing] = useState(false);
|
||||||
|
const [isEmailEdit, setIsEmailEdit] = useState<boolean>(false);
|
||||||
|
const [showTypeSelector, setShowTypeSelector] = useState(false);
|
||||||
|
const [heading, setHeading] = useState(
|
||||||
|
currentTeam ? currentTeam.displayName : ''
|
||||||
|
);
|
||||||
|
|
||||||
|
const { email, owner, teamType } = useMemo(() => currentTeam, [currentTeam]);
|
||||||
|
|
||||||
|
const { hasEditPermission, hasEditDisplayNamePermission, hasAccess } =
|
||||||
|
useMemo(
|
||||||
|
() => ({
|
||||||
|
hasEditPermission: entityPermissions.EditAll,
|
||||||
|
hasEditDisplayNamePermission:
|
||||||
|
entityPermissions.EditDisplayName || entityPermissions.EditAll,
|
||||||
|
hasAccess: isAuthDisabled || isAdminUser,
|
||||||
|
}),
|
||||||
|
|
||||||
|
[entityPermissions]
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if current team is the owner or not
|
||||||
|
* @returns - True true or false based on hasEditAccess response
|
||||||
|
*/
|
||||||
|
const isCurrentTeamOwner = useMemo(
|
||||||
|
() => hasEditAccess(owner?.type ?? '', owner?.id ?? ''),
|
||||||
|
[owner]
|
||||||
|
);
|
||||||
|
|
||||||
|
const onHeadingSave = async (): Promise<void> => {
|
||||||
|
if (heading && currentTeam) {
|
||||||
|
const updatedData: Team = {
|
||||||
|
...currentTeam,
|
||||||
|
displayName: heading,
|
||||||
|
};
|
||||||
|
|
||||||
|
await updateTeamHandler(updatedData);
|
||||||
|
}
|
||||||
|
setIsHeadingEditing(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onEmailSave = async (data: { email: string }) => {
|
||||||
|
if (currentTeam) {
|
||||||
|
const updatedData: Team = {
|
||||||
|
...currentTeam,
|
||||||
|
email: isEmpty(data.email) ? undefined : data.email,
|
||||||
|
};
|
||||||
|
|
||||||
|
await updateTeamHandler(updatedData);
|
||||||
|
}
|
||||||
|
setIsEmailEdit(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateOwner = useCallback(
|
||||||
|
async (owner?: EntityReference) => {
|
||||||
|
if (currentTeam) {
|
||||||
|
const updatedData: Team = {
|
||||||
|
...currentTeam,
|
||||||
|
owner,
|
||||||
|
};
|
||||||
|
|
||||||
|
await updateTeamHandler(updatedData);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[currentTeam]
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateTeamType = async (type: TeamType): Promise<void> => {
|
||||||
|
if (currentTeam) {
|
||||||
|
const updatedData: Team = {
|
||||||
|
...currentTeam,
|
||||||
|
teamType: type,
|
||||||
|
};
|
||||||
|
|
||||||
|
await updateTeamHandler(updatedData);
|
||||||
|
|
||||||
|
setShowTypeSelector(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const teamHeadingRender = useMemo(
|
||||||
|
() =>
|
||||||
|
isHeadingEditing ? (
|
||||||
|
<Space>
|
||||||
|
<Input
|
||||||
|
className="w-48"
|
||||||
|
data-testid="team-name-input"
|
||||||
|
placeholder={t('message.enter-comma-separated-field', {
|
||||||
|
field: t('label.term-lowercase'),
|
||||||
|
})}
|
||||||
|
type="text"
|
||||||
|
value={heading}
|
||||||
|
onChange={(e) => setHeading(e.target.value)}
|
||||||
|
/>
|
||||||
|
<Space data-testid="buttons" size={4}>
|
||||||
|
<Button
|
||||||
|
className="rounded-4 text-sm p-xss"
|
||||||
|
data-testid="cancelAssociatedTag"
|
||||||
|
type="primary"
|
||||||
|
onMouseDown={() => setIsHeadingEditing(false)}>
|
||||||
|
<CloseOutlined />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="rounded-4 text-sm p-xss"
|
||||||
|
data-testid="saveAssociatedTag"
|
||||||
|
type="primary"
|
||||||
|
onMouseDown={onHeadingSave}>
|
||||||
|
<CheckOutlined />
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</Space>
|
||||||
|
) : (
|
||||||
|
<Space align="baseline">
|
||||||
|
<Typography.Title
|
||||||
|
className="m-b-0 w-max-200"
|
||||||
|
data-testid="team-heading"
|
||||||
|
ellipsis={{ tooltip: true }}
|
||||||
|
level={5}>
|
||||||
|
{heading}
|
||||||
|
</Typography.Title>
|
||||||
|
{(hasAccess || isCurrentTeamOwner) && (
|
||||||
|
<Tooltip
|
||||||
|
placement="right"
|
||||||
|
title={
|
||||||
|
hasEditDisplayNamePermission
|
||||||
|
? t('label.edit-entity', {
|
||||||
|
entity: t('label.display-name'),
|
||||||
|
})
|
||||||
|
: t('message.no-permission-for-action')
|
||||||
|
}>
|
||||||
|
<Icon
|
||||||
|
className="align-middle"
|
||||||
|
component={EditIcon}
|
||||||
|
data-testid="edit-team-name"
|
||||||
|
disabled={!hasEditDisplayNamePermission}
|
||||||
|
style={{ fontSize: '16px' }}
|
||||||
|
onClick={() => setIsHeadingEditing(true)}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
[heading, isHeadingEditing, hasEditDisplayNamePermission]
|
||||||
|
);
|
||||||
|
|
||||||
|
const emailRender = useMemo(
|
||||||
|
() => (
|
||||||
|
<Space align="center" size={4}>
|
||||||
|
<Typography.Text className="text-grey-muted">{`${t(
|
||||||
|
'label.email'
|
||||||
|
)} :`}</Typography.Text>
|
||||||
|
{isEmailEdit ? (
|
||||||
|
<Form initialValues={{ email }} onFinish={onEmailSave}>
|
||||||
|
<Space align="baseline">
|
||||||
|
<Form.Item
|
||||||
|
className="m-b-0"
|
||||||
|
name="email"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
pattern: EMAIL_REG_EX,
|
||||||
|
type: 'email',
|
||||||
|
message: t('message.field-text-is-invalid', {
|
||||||
|
fieldText: t('label.email'),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<Input
|
||||||
|
className="w-48"
|
||||||
|
data-testid="email-input"
|
||||||
|
placeholder={t('label.enter-entity', {
|
||||||
|
entity: t('label.email-lowercase'),
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Space size={4}>
|
||||||
|
<Button
|
||||||
|
className="h-8 p-x-xss"
|
||||||
|
data-testid="cancel-edit-email"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => setIsEmailEdit(false)}>
|
||||||
|
<CloseOutlined />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
className="h-8 p-x-xss"
|
||||||
|
data-testid="save-edit-email"
|
||||||
|
htmlType="submit"
|
||||||
|
size="small"
|
||||||
|
type="primary">
|
||||||
|
<CheckOutlined />
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</Space>
|
||||||
|
</Form>
|
||||||
|
) : (
|
||||||
|
<Space align="center">
|
||||||
|
<Typography.Text className="font-medium" data-testid="email-value">
|
||||||
|
{email ?? NO_DATA_PLACEHOLDER}
|
||||||
|
</Typography.Text>
|
||||||
|
{hasEditPermission && (
|
||||||
|
<Tooltip
|
||||||
|
placement="right"
|
||||||
|
title={
|
||||||
|
hasEditPermission
|
||||||
|
? t('label.edit-entity', {
|
||||||
|
entity: t('label.email'),
|
||||||
|
})
|
||||||
|
: t('message.no-permission-for-action')
|
||||||
|
}>
|
||||||
|
<Icon
|
||||||
|
className="toolbar-button align-middle"
|
||||||
|
component={EditIcon}
|
||||||
|
data-testid="edit-email"
|
||||||
|
style={{ fontSize: '16px' }}
|
||||||
|
onClick={() => setIsEmailEdit(true)}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
[email, isEmailEdit, hasEditPermission]
|
||||||
|
);
|
||||||
|
|
||||||
|
const teamTypeElement = useMemo(() => {
|
||||||
|
if (teamType === TeamType.Organization) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space size={4}>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<Typography.Text className="text-grey-muted">
|
||||||
|
{`${t('label.type')} :`}
|
||||||
|
</Typography.Text>
|
||||||
|
{showTypeSelector ? (
|
||||||
|
<TeamTypeSelect
|
||||||
|
handleShowTypeSelector={setShowTypeSelector}
|
||||||
|
parentTeamType={
|
||||||
|
last(parentTeams)?.teamType ?? TeamType.Organization
|
||||||
|
}
|
||||||
|
showGroupOption={!childTeamsCount}
|
||||||
|
teamType={teamType ?? TeamType.Department}
|
||||||
|
updateTeamType={hasEditPermission ? updateTeamType : undefined}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Typography.Text className="font-medium" data-testid="team-type">
|
||||||
|
{teamType}
|
||||||
|
</Typography.Text>
|
||||||
|
|
||||||
|
{hasEditPermission && (
|
||||||
|
<Icon
|
||||||
|
className={classNames('vertical-middle m-l-xs', {
|
||||||
|
'opacity-50': isGroupType,
|
||||||
|
})}
|
||||||
|
data-testid="edit-team-type-icon"
|
||||||
|
title={
|
||||||
|
isGroupType
|
||||||
|
? t('message.group-team-type-change-message')
|
||||||
|
: t('label.edit-entity', {
|
||||||
|
entity: t('label.team-type'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onClick={
|
||||||
|
isGroupType ? undefined : () => setShowTypeSelector(true)
|
||||||
|
}>
|
||||||
|
<EditIcon />
|
||||||
|
</Icon>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
}, [
|
||||||
|
teamType,
|
||||||
|
parentTeams,
|
||||||
|
isGroupType,
|
||||||
|
childTeamsCount,
|
||||||
|
showTypeSelector,
|
||||||
|
hasEditPermission,
|
||||||
|
updateTeamType,
|
||||||
|
setShowTypeSelector,
|
||||||
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentTeam) {
|
||||||
|
setHeading(currentTeam.displayName ?? currentTeam.name);
|
||||||
|
}
|
||||||
|
}, [currentTeam]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space size={4}>
|
||||||
|
{teamHeadingRender}
|
||||||
|
<Divider type="vertical" />
|
||||||
|
<OwnerLabel
|
||||||
|
className="text-sm"
|
||||||
|
hasPermission={hasAccess}
|
||||||
|
owner={owner}
|
||||||
|
onUpdate={updateOwner}
|
||||||
|
/>
|
||||||
|
<Divider type="vertical" />
|
||||||
|
{emailRender}
|
||||||
|
{teamTypeElement}
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TeamsInfo;
|
@ -0,0 +1,187 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 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 { Form, Input, Modal, Select, Space, Typography } from 'antd';
|
||||||
|
import { DE_ACTIVE_COLOR, ICON_DIMENSION } from 'constants/constants';
|
||||||
|
import {
|
||||||
|
SUBSCRIPTION_WEBHOOK,
|
||||||
|
SUBSCRIPTION_WEBHOOK_OPTIONS,
|
||||||
|
} from 'constants/Teams.constants';
|
||||||
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { ReactComponent as EditIcon } from '../../../../assets/svg/edit-new.svg';
|
||||||
|
|
||||||
|
import { useForm } from 'antd/lib/form/Form';
|
||||||
|
import TagsV1 from 'components/Tag/TagsV1/TagsV1.component';
|
||||||
|
import { TAG_CONSTANT, TAG_START_WITH } from 'constants/Tag.constants';
|
||||||
|
import { Webhook } from 'generated/type/profile';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
|
import { getWebhookIcon } from 'utils/TeamUtils';
|
||||||
|
import { SubscriptionWebhook, TeamsSubscriptionProps } from '../team.interface';
|
||||||
|
|
||||||
|
const TeamsSubscription = ({
|
||||||
|
subscription,
|
||||||
|
hasEditPermission,
|
||||||
|
updateTeamSubscription,
|
||||||
|
}: TeamsSubscriptionProps) => {
|
||||||
|
const [form] = useForm();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [editSubscription, setEditSubscription] = useState<boolean>(false);
|
||||||
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const getWebhookIconByKey = useCallback((item: SUBSCRIPTION_WEBHOOK) => {
|
||||||
|
const Icon = getWebhookIcon(item);
|
||||||
|
|
||||||
|
return <Icon data-testid={`${item}-icon`} height={20} width={20} />;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Watchers
|
||||||
|
const webhooks: {
|
||||||
|
webhook: string;
|
||||||
|
endpoint: string;
|
||||||
|
}[] = Form.useWatch(['subscriptions'], form);
|
||||||
|
|
||||||
|
// Run time values needed for conditional rendering
|
||||||
|
const subscriptionOptions = useMemo(() => {
|
||||||
|
const exitingWebhook = webhooks?.map((f) => f?.webhook) ?? [];
|
||||||
|
|
||||||
|
return SUBSCRIPTION_WEBHOOK_OPTIONS.map((func) => ({
|
||||||
|
label: func.label,
|
||||||
|
value: func.value,
|
||||||
|
disabled: exitingWebhook.includes(func.value),
|
||||||
|
}));
|
||||||
|
}, [webhooks]);
|
||||||
|
|
||||||
|
const cellItem = useCallback(
|
||||||
|
(key: string, value: Webhook) => (
|
||||||
|
<Space align="start">
|
||||||
|
{getWebhookIconByKey(key as SUBSCRIPTION_WEBHOOK)}
|
||||||
|
<Typography.Text className="text-xs text-grey-muted">
|
||||||
|
{value.endpoint}
|
||||||
|
</Typography.Text>
|
||||||
|
</Space>
|
||||||
|
),
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const subscriptionRenderElement = useMemo(() => {
|
||||||
|
const webhook = Object.entries(subscription ?? {})?.[0];
|
||||||
|
|
||||||
|
return isEmpty(subscription) && hasEditPermission ? (
|
||||||
|
<div onClick={() => setEditSubscription(true)}>
|
||||||
|
<TagsV1 startWith={TAG_START_WITH.PLUS} tag={TAG_CONSTANT} />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
cellItem(webhook[0], webhook[1])
|
||||||
|
);
|
||||||
|
}, [subscription]);
|
||||||
|
|
||||||
|
const handleSave = async (values: SubscriptionWebhook) => {
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await updateTeamSubscription(values);
|
||||||
|
} catch {
|
||||||
|
// parent block will throw error
|
||||||
|
} finally {
|
||||||
|
setEditSubscription(false);
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (subscription) {
|
||||||
|
const data = Object.entries(subscription)[0];
|
||||||
|
form.setFieldsValue({
|
||||||
|
webhook: data[0],
|
||||||
|
endpoint: data[1].endpoint,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [subscription, editSubscription]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Space align="start" data-testid="teams-subscription">
|
||||||
|
<Typography.Text className="right-panel-label font-normal">
|
||||||
|
{`${t('label.subscription')} :`}
|
||||||
|
</Typography.Text>
|
||||||
|
{subscriptionRenderElement}
|
||||||
|
|
||||||
|
{!editSubscription && !isEmpty(subscription) && hasEditPermission && (
|
||||||
|
<EditIcon
|
||||||
|
className="cursor-pointer align-middle"
|
||||||
|
color={DE_ACTIVE_COLOR}
|
||||||
|
data-testid="edit-roles"
|
||||||
|
{...ICON_DIMENSION}
|
||||||
|
onClick={() => setEditSubscription(true)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{editSubscription && (
|
||||||
|
<Modal
|
||||||
|
centered
|
||||||
|
open
|
||||||
|
closable={false}
|
||||||
|
confirmLoading={isLoading}
|
||||||
|
maskClosable={false}
|
||||||
|
okButtonProps={{
|
||||||
|
form: 'subscription-form',
|
||||||
|
type: 'primary',
|
||||||
|
htmlType: 'submit',
|
||||||
|
}}
|
||||||
|
okText={t('label.confirm')}
|
||||||
|
title={t('label.add-entity', {
|
||||||
|
entity: t('label.subscription'),
|
||||||
|
})}
|
||||||
|
onCancel={() => setEditSubscription(false)}>
|
||||||
|
<Form
|
||||||
|
data-testid="subscription-modal"
|
||||||
|
form={form}
|
||||||
|
id="subscription-form"
|
||||||
|
layout="vertical"
|
||||||
|
onFinish={handleSave}>
|
||||||
|
<Form.Item label={t('label.webhook')} name="webhook">
|
||||||
|
<Select
|
||||||
|
options={subscriptionOptions}
|
||||||
|
placeholder={t('label.select-field', {
|
||||||
|
field: t('label.condition'),
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t('label.endpoint')}
|
||||||
|
name="endpoint"
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t('label.field-required-plural', {
|
||||||
|
field: t('label.endpoint'),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'url',
|
||||||
|
message: t('message.endpoint-should-be-valid'),
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<Input
|
||||||
|
placeholder={t('label.enter-entity-value', {
|
||||||
|
entity: t('label.endpoint'),
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default TeamsSubscription;
|
@ -214,7 +214,7 @@ export const UserTab = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row gutter={[16, 16]}>
|
<Row className="p-md" gutter={[16, 16]}>
|
||||||
<Col span={24}>
|
<Col span={24}>
|
||||||
<Row justify="space-between">
|
<Row justify="space-between">
|
||||||
<Col span={8}>
|
<Col span={8}>
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { OperationPermission } from 'components/PermissionProvider/PermissionProvider.interface';
|
||||||
|
import { MessagingProvider } from 'generated/type/profile';
|
||||||
import { Team } from '../../../generated/entity/teams/team';
|
import { Team } from '../../../generated/entity/teams/team';
|
||||||
|
|
||||||
export interface TeamHierarchyProps {
|
export interface TeamHierarchyProps {
|
||||||
@ -55,3 +57,23 @@ export enum TeamsPageTab {
|
|||||||
ROLES = 'roles',
|
ROLES = 'roles',
|
||||||
POLICIES = 'policies',
|
POLICIES = 'policies',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface TeamsInfoProps {
|
||||||
|
parentTeams: Team[];
|
||||||
|
isGroupType: boolean;
|
||||||
|
childTeamsCount: number;
|
||||||
|
currentTeam: Team;
|
||||||
|
entityPermissions: OperationPermission;
|
||||||
|
updateTeamHandler: (data: Team) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TeamsSubscriptionProps {
|
||||||
|
hasEditPermission: boolean;
|
||||||
|
subscription?: MessagingProvider;
|
||||||
|
updateTeamSubscription: (value: SubscriptionWebhook) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SubscriptionWebhook {
|
||||||
|
webhook: string;
|
||||||
|
endpoint: string;
|
||||||
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
@import url('../../../styles/variables.less');
|
@import url('../../../styles/variables.less');
|
||||||
|
|
||||||
.team-list-container {
|
.team-list-container {
|
||||||
|
padding: 20px;
|
||||||
.ant-btn {
|
.ant-btn {
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
@ -76,9 +77,47 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.teams-layout {
|
||||||
|
margin: -16px -16px 0 -16px;
|
||||||
|
|
||||||
|
.ant-card-head-title {
|
||||||
|
padding-top: 0;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.teams-profile {
|
||||||
|
background-color: @team-avatar-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
.teams-profile-container {
|
||||||
|
background: @user-profile-background;
|
||||||
|
|
||||||
|
.ant-card {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.teams-tabs-content-container {
|
||||||
|
width: 100%;
|
||||||
|
.teams-scroll-component {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100vh - 120px);
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-collapse-custom-collapse .site-collapse-custom-panel {
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
background: @user-profile-background;
|
||||||
|
border: 0px;
|
||||||
|
|
||||||
|
.ant-collapse-content-box {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.team-assets-right-panel {
|
.team-assets-right-panel {
|
||||||
margin-top: -24px;
|
|
||||||
margin-bottom: -24px;
|
|
||||||
.summary-panel-container {
|
.summary-panel-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border: 0;
|
border: 0;
|
||||||
|
@ -14,6 +14,7 @@ import Icon from '@ant-design/icons';
|
|||||||
import { Typography } from 'antd';
|
import { Typography } from 'antd';
|
||||||
import { ReactComponent as IconTeamsGrey } from 'assets/svg/teams-grey.svg';
|
import { ReactComponent as IconTeamsGrey } from 'assets/svg/teams-grey.svg';
|
||||||
import { ReactComponent as IconUser } from 'assets/svg/user.svg';
|
import { ReactComponent as IconUser } from 'assets/svg/user.svg';
|
||||||
|
import classNames from 'classnames';
|
||||||
import { getTeamAndUserDetailsPath, getUserPath } from 'constants/constants';
|
import { getTeamAndUserDetailsPath, getUserPath } from 'constants/constants';
|
||||||
import { OwnerType } from 'enums/user.enum';
|
import { OwnerType } from 'enums/user.enum';
|
||||||
import { EntityReference } from 'generated/entity/data/table';
|
import { EntityReference } from 'generated/entity/data/table';
|
||||||
@ -27,11 +28,13 @@ import { UserTeamSelectableList } from '../UserTeamSelectableList/UserTeamSelect
|
|||||||
|
|
||||||
export const OwnerLabel = ({
|
export const OwnerLabel = ({
|
||||||
owner,
|
owner,
|
||||||
|
className,
|
||||||
onUpdate,
|
onUpdate,
|
||||||
hasPermission,
|
hasPermission,
|
||||||
ownerDisplayName,
|
ownerDisplayName,
|
||||||
}: {
|
}: {
|
||||||
owner?: EntityReference;
|
owner?: EntityReference;
|
||||||
|
className?: string;
|
||||||
onUpdate?: (owner?: EntityReference) => void;
|
onUpdate?: (owner?: EntityReference) => void;
|
||||||
hasPermission?: boolean;
|
hasPermission?: boolean;
|
||||||
ownerDisplayName?: ReactNode;
|
ownerDisplayName?: ReactNode;
|
||||||
@ -74,7 +77,10 @@ export const OwnerLabel = ({
|
|||||||
|
|
||||||
{displayName ? (
|
{displayName ? (
|
||||||
<Link
|
<Link
|
||||||
className="text-primary font-medium text-xs no-underline"
|
className={classNames(
|
||||||
|
'text-primary font-medium text-xs no-underline',
|
||||||
|
className
|
||||||
|
)}
|
||||||
data-testid="owner-link"
|
data-testid="owner-link"
|
||||||
to={
|
to={
|
||||||
owner?.type === 'team'
|
owner?.type === 'team'
|
||||||
@ -85,7 +91,7 @@ export const OwnerLabel = ({
|
|||||||
</Link>
|
</Link>
|
||||||
) : (
|
) : (
|
||||||
<Typography.Text
|
<Typography.Text
|
||||||
className="font-medium text-xs"
|
className={classNames('font-medium text-xs', className)}
|
||||||
data-testid="owner-link">
|
data-testid="owner-link">
|
||||||
{t('label.no-entity', { entity: t('label.owner') })}
|
{t('label.no-entity', { entity: t('label.owner') })}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
|
@ -17,7 +17,6 @@ import React, { useMemo, useState } from 'react';
|
|||||||
import { getTeamOptionsFromType } from 'utils/TeamUtils';
|
import { getTeamOptionsFromType } from 'utils/TeamUtils';
|
||||||
import { TeamType } from '../../../generated/entity/teams/team';
|
import { TeamType } from '../../../generated/entity/teams/team';
|
||||||
import { TeamTypeSelectProps } from './TeamTypeSelect.interface';
|
import { TeamTypeSelectProps } from './TeamTypeSelect.interface';
|
||||||
import './TeamTypeSelect.style.less';
|
|
||||||
|
|
||||||
function TeamTypeSelect({
|
function TeamTypeSelect({
|
||||||
handleShowTypeSelector,
|
handleShowTypeSelector,
|
||||||
@ -63,17 +62,23 @@ function TeamTypeSelect({
|
|||||||
value={value}
|
value={value}
|
||||||
onSelect={handleSelect}
|
onSelect={handleSelect}
|
||||||
/>
|
/>
|
||||||
<Space className="edit-team-type-buttons" size={4}>
|
<Space className="m-l-xs" size={4}>
|
||||||
<Button
|
<Button
|
||||||
|
className="h-8 p-x-xss"
|
||||||
data-testid="cancel-btn"
|
data-testid="cancel-btn"
|
||||||
icon={<CloseOutlined />}
|
size="small"
|
||||||
onClick={handleCancel}
|
type="primary"
|
||||||
/>
|
onClick={handleCancel}>
|
||||||
|
<CloseOutlined />
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
className="h-8 p-x-xss"
|
||||||
data-testid="save-btn"
|
data-testid="save-btn"
|
||||||
icon={<CheckOutlined />}
|
size="small"
|
||||||
onClick={handleSubmit}
|
type="primary"
|
||||||
/>
|
onClick={handleSubmit}>
|
||||||
|
<CheckOutlined />
|
||||||
|
</Button>
|
||||||
</Space>
|
</Space>
|
||||||
</Space>
|
</Space>
|
||||||
);
|
);
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 url('../../../styles/variables.less');
|
|
||||||
|
|
||||||
.team-type-select {
|
|
||||||
.ant-select {
|
|
||||||
width: 150px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-team-type-buttons {
|
|
||||||
.ant-btn {
|
|
||||||
background-color: @primary-color;
|
|
||||||
color: white;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-team-icons {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -12,6 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import DraggableBodyRow from 'components/Team/TeamDetails/DraggableBodyRow';
|
import DraggableBodyRow from 'components/Team/TeamDetails/DraggableBodyRow';
|
||||||
|
import { t } from 'i18next';
|
||||||
|
|
||||||
export const DRAGGABLE_BODY_ROW = 'DraggableBodyRow';
|
export const DRAGGABLE_BODY_ROW = 'DraggableBodyRow';
|
||||||
|
|
||||||
@ -20,3 +21,25 @@ export const TABLE_CONSTANTS = {
|
|||||||
row: DraggableBodyRow,
|
row: DraggableBodyRow,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export enum SUBSCRIPTION_WEBHOOK {
|
||||||
|
MS_TEAMS = 'msTeams',
|
||||||
|
SLACK = 'slack',
|
||||||
|
G_CHAT = 'gChat',
|
||||||
|
GENERIC = 'generic',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const SUBSCRIPTION_WEBHOOK_OPTIONS = [
|
||||||
|
{
|
||||||
|
label: t('label.ms-team-plural'),
|
||||||
|
value: SUBSCRIPTION_WEBHOOK.MS_TEAMS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('label.slack'),
|
||||||
|
value: SUBSCRIPTION_WEBHOOK.SLACK,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('label.g-chat'),
|
||||||
|
value: SUBSCRIPTION_WEBHOOK.G_CHAT,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
@ -102,7 +102,6 @@ export interface TeamDetailsProp {
|
|||||||
teamUsersSearchText: string;
|
teamUsersSearchText: string;
|
||||||
isDescriptionEditable: boolean;
|
isDescriptionEditable: boolean;
|
||||||
isTeamMemberLoading: number;
|
isTeamMemberLoading: number;
|
||||||
hasAccess: boolean;
|
|
||||||
isFetchingAdvancedDetails: boolean;
|
isFetchingAdvancedDetails: boolean;
|
||||||
isFetchingAllTeamAdvancedDetails: boolean;
|
isFetchingAllTeamAdvancedDetails: boolean;
|
||||||
entityPermissions: OperationPermission;
|
entityPermissions: OperationPermission;
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
"enter": "Eingeben",
|
"enter": "Eingeben",
|
||||||
"enter-entity": "{{entity}} eingeben",
|
"enter-entity": "{{entity}} eingeben",
|
||||||
"enter-entity-name": "Geben Sie einen Namen für {{entity}} ein",
|
"enter-entity-name": "Geben Sie einen Namen für {{entity}} ein",
|
||||||
|
"enter-entity-value": "Enter {{entity}} Value",
|
||||||
"enter-field-description": "Geben Sie eine Beschreibung für {{field}} ein",
|
"enter-field-description": "Geben Sie eine Beschreibung für {{field}} ein",
|
||||||
"enter-property-value": "Geben Sie einen Wert für die Eigenschaft ein",
|
"enter-property-value": "Geben Sie einen Wert für die Eigenschaft ein",
|
||||||
"enter-type-password": "{{type}}-Passwort eingeben",
|
"enter-type-password": "{{type}}-Passwort eingeben",
|
||||||
@ -382,6 +383,7 @@
|
|||||||
"feature-plural": "funktionen",
|
"feature-plural": "funktionen",
|
||||||
"feature-plural-used": "verwendete funktionen",
|
"feature-plural-used": "verwendete funktionen",
|
||||||
"february": "Februar",
|
"february": "Februar",
|
||||||
|
"feed-filter-plural": "Feed filters",
|
||||||
"feed-lowercase": "feed",
|
"feed-lowercase": "feed",
|
||||||
"feed-plural": "feeds",
|
"feed-plural": "feeds",
|
||||||
"field": "Feld",
|
"field": "Feld",
|
||||||
@ -903,6 +905,7 @@
|
|||||||
"sub-domain-plural": "Subdomains",
|
"sub-domain-plural": "Subdomains",
|
||||||
"sub-team-plural": "Unter-Teams",
|
"sub-team-plural": "Unter-Teams",
|
||||||
"submit": "Einreichen",
|
"submit": "Einreichen",
|
||||||
|
"subscription": "Subscription",
|
||||||
"success": "Erfolg",
|
"success": "Erfolg",
|
||||||
"successfully-lowercase": "erfolgreich",
|
"successfully-lowercase": "erfolgreich",
|
||||||
"successfully-uploaded": "Erfolgreich hochgeladen",
|
"successfully-uploaded": "Erfolgreich hochgeladen",
|
||||||
@ -1129,6 +1132,7 @@
|
|||||||
"connection-test-warning": "Der Test der Verbindung war teilweise erfolgreich: Einige Schritte hatten Fehler, es werden nur teilweise Metadaten übernommen.",
|
"connection-test-warning": "Der Test der Verbindung war teilweise erfolgreich: Einige Schritte hatten Fehler, es werden nur teilweise Metadaten übernommen.",
|
||||||
"copied-to-clipboard": "In die Zwischenablage kopiert",
|
"copied-to-clipboard": "In die Zwischenablage kopiert",
|
||||||
"copy-to-clipboard": "Link in die Zwischenablage kopiert",
|
"copy-to-clipboard": "Link in die Zwischenablage kopiert",
|
||||||
|
"create-new-domain-guide": "A data mesh is a decentralized data architecture that organizes data by a specific business domain following the concepts of domain-oriented design. Teams take ownership of both operational and analytical data that belongs to the domain. Based on the Data Contract, consumers are provided with Data as a Product. It is powered by Domain-agnostic self-serve data infrastructure. There are three types of domains: Consumer-aligned, Aggregate, and Source-aligned. Domains have Enabling Teams for consulting.",
|
||||||
"create-new-glossary-guide": "Ein Glossar ist ein kontrolliertes Vokabular, das verwendet wird, um die Konzepte und Terminologie in einer Organisation zu definieren. Glossare können spezifisch für einen bestimmten Bereich sein (z. B. Business Glossar, Technisches Glossar). Im Glossar können die Standardbegriffe und Konzepte definiert werden, zusammen mit Synonymen und verwandten Begriffen. Es kann festgelegt werden, wie und von wem Begriffe im Glossar hinzugefügt werden können.",
|
"create-new-glossary-guide": "Ein Glossar ist ein kontrolliertes Vokabular, das verwendet wird, um die Konzepte und Terminologie in einer Organisation zu definieren. Glossare können spezifisch für einen bestimmten Bereich sein (z. B. Business Glossar, Technisches Glossar). Im Glossar können die Standardbegriffe und Konzepte definiert werden, zusammen mit Synonymen und verwandten Begriffen. Es kann festgelegt werden, wie und von wem Begriffe im Glossar hinzugefügt werden können.",
|
||||||
"create-or-update-email-account-for-bot": "Die Änderung der Kontaktemail aktualisiert oder erstellt einen neuen Bot-Benutzer.",
|
"create-or-update-email-account-for-bot": "Die Änderung der Kontaktemail aktualisiert oder erstellt einen neuen Bot-Benutzer.",
|
||||||
"created-this-task-lowercase": "hat diese Aufgabe erstellt",
|
"created-this-task-lowercase": "hat diese Aufgabe erstellt",
|
||||||
@ -1215,6 +1219,9 @@
|
|||||||
"error-while-fetching-access-token": "Fehler beim Abrufen des Zugriffstokens.",
|
"error-while-fetching-access-token": "Fehler beim Abrufen des Zugriffstokens.",
|
||||||
"export-entity-help": "Laden Sie alle Ihre {{entity}} als CSV-Datei herunter und teilen Sie sie mit Ihrem Team.",
|
"export-entity-help": "Laden Sie alle Ihre {{entity}} als CSV-Datei herunter und teilen Sie sie mit Ihrem Team.",
|
||||||
"failed-status-for-entity-deploy": "<0>{{entity}}</0> wurde {{entityStatus}}, aber das Bereitstellen ist fehlgeschlagen.",
|
"failed-status-for-entity-deploy": "<0>{{entity}}</0> wurde {{entityStatus}}, aber das Bereitstellen ist fehlgeschlagen.",
|
||||||
|
"feed-filter-all": "Feeds for all the data assets that you own and follow",
|
||||||
|
"feed-filter-following": "Feeds for all the data assets that you follow",
|
||||||
|
"feed-filter-owner": "Feeds for all the data assets that you own",
|
||||||
"fetch-dbt-files": "Hier sind die verfügbaren Quellen zum Abrufen von dbt-Katalog- und Manifestdateien.",
|
"fetch-dbt-files": "Hier sind die verfügbaren Quellen zum Abrufen von dbt-Katalog- und Manifestdateien.",
|
||||||
"fetch-pipeline-status-error": "Fehler beim Abrufen des Pipeline-Status.",
|
"fetch-pipeline-status-error": "Fehler beim Abrufen des Pipeline-Status.",
|
||||||
"field-ca-certs-description": "Der Zertifikatpfad muss in der Konfiguration hinzugefügt werden. Der Pfad sollte lokal im Ingestion-Container sein.",
|
"field-ca-certs-description": "Der Zertifikatpfad muss in der Konfiguration hinzugefügt werden. Der Pfad sollte lokal im Ingestion-Container sein.",
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
"enter": "Enter",
|
"enter": "Enter",
|
||||||
"enter-entity": "Enter {{entity}}",
|
"enter-entity": "Enter {{entity}}",
|
||||||
"enter-entity-name": "Enter {{entity}} name",
|
"enter-entity-name": "Enter {{entity}} name",
|
||||||
|
"enter-entity-value": "Enter {{entity}} Value",
|
||||||
"enter-field-description": "Enter {{field}} description",
|
"enter-field-description": "Enter {{field}} description",
|
||||||
"enter-property-value": "Enter Property Value",
|
"enter-property-value": "Enter Property Value",
|
||||||
"enter-type-password": "Enter {{type}} Password",
|
"enter-type-password": "Enter {{type}} Password",
|
||||||
@ -904,6 +905,7 @@
|
|||||||
"sub-domain-plural": "Sub Domains",
|
"sub-domain-plural": "Sub Domains",
|
||||||
"sub-team-plural": "Sub Teams",
|
"sub-team-plural": "Sub Teams",
|
||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
|
"subscription": "Subscription",
|
||||||
"success": "Success",
|
"success": "Success",
|
||||||
"successfully-lowercase": "successfully",
|
"successfully-lowercase": "successfully",
|
||||||
"successfully-uploaded": "Successfully Uploaded",
|
"successfully-uploaded": "Successfully Uploaded",
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
"enter": "Entrar",
|
"enter": "Entrar",
|
||||||
"enter-entity": "Ingrese {{entity}}",
|
"enter-entity": "Ingrese {{entity}}",
|
||||||
"enter-entity-name": "Ingrese el nombre de {{entity}}",
|
"enter-entity-name": "Ingrese el nombre de {{entity}}",
|
||||||
|
"enter-entity-value": "Enter {{entity}} Value",
|
||||||
"enter-field-description": "Ingrese la descripción de {{field}}",
|
"enter-field-description": "Ingrese la descripción de {{field}}",
|
||||||
"enter-property-value": "Ingrese el valor de la propiedad",
|
"enter-property-value": "Ingrese el valor de la propiedad",
|
||||||
"enter-type-password": "Ingrese la contraseña de {{type}}",
|
"enter-type-password": "Ingrese la contraseña de {{type}}",
|
||||||
@ -904,6 +905,7 @@
|
|||||||
"sub-domain-plural": "Sub Domains",
|
"sub-domain-plural": "Sub Domains",
|
||||||
"sub-team-plural": "Sub Equipos",
|
"sub-team-plural": "Sub Equipos",
|
||||||
"submit": "Enviar",
|
"submit": "Enviar",
|
||||||
|
"subscription": "Subscription",
|
||||||
"success": "Éxito",
|
"success": "Éxito",
|
||||||
"successfully-lowercase": "successfully",
|
"successfully-lowercase": "successfully",
|
||||||
"successfully-uploaded": "Cargado Exitosamente",
|
"successfully-uploaded": "Cargado Exitosamente",
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
"enter": "Entrer",
|
"enter": "Entrer",
|
||||||
"enter-entity": "Entrer {{entity}}",
|
"enter-entity": "Entrer {{entity}}",
|
||||||
"enter-entity-name": "Entrer un nom pour {{entity}}",
|
"enter-entity-name": "Entrer un nom pour {{entity}}",
|
||||||
|
"enter-entity-value": "Enter {{entity}} Value",
|
||||||
"enter-field-description": "Entrer une description pour {{field}}",
|
"enter-field-description": "Entrer une description pour {{field}}",
|
||||||
"enter-property-value": "Entrer une valeur pour la propriété",
|
"enter-property-value": "Entrer une valeur pour la propriété",
|
||||||
"enter-type-password": "Entrer un mot de passe {{type}}",
|
"enter-type-password": "Entrer un mot de passe {{type}}",
|
||||||
@ -904,6 +905,7 @@
|
|||||||
"sub-domain-plural": "Sous-Domaines",
|
"sub-domain-plural": "Sous-Domaines",
|
||||||
"sub-team-plural": "Sous-Équipes",
|
"sub-team-plural": "Sous-Équipes",
|
||||||
"submit": "Soumettre",
|
"submit": "Soumettre",
|
||||||
|
"subscription": "Subscription",
|
||||||
"success": "Succès",
|
"success": "Succès",
|
||||||
"successfully-lowercase": "avec succès",
|
"successfully-lowercase": "avec succès",
|
||||||
"successfully-uploaded": "Téléchargé avec succès",
|
"successfully-uploaded": "Téléchargé avec succès",
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
"enter": "入力",
|
"enter": "入力",
|
||||||
"enter-entity": "{{entity}}を入力",
|
"enter-entity": "{{entity}}を入力",
|
||||||
"enter-entity-name": "{{entity}}の名前を入力",
|
"enter-entity-name": "{{entity}}の名前を入力",
|
||||||
|
"enter-entity-value": "Enter {{entity}} Value",
|
||||||
"enter-field-description": "{{field}}の説明を入力",
|
"enter-field-description": "{{field}}の説明を入力",
|
||||||
"enter-property-value": "プロパティの値を入力",
|
"enter-property-value": "プロパティの値を入力",
|
||||||
"enter-type-password": "{{type}} のパスワードを入力",
|
"enter-type-password": "{{type}} のパスワードを入力",
|
||||||
@ -904,6 +905,7 @@
|
|||||||
"sub-domain-plural": "Sub Domains",
|
"sub-domain-plural": "Sub Domains",
|
||||||
"sub-team-plural": "サブチーム",
|
"sub-team-plural": "サブチーム",
|
||||||
"submit": "Submit",
|
"submit": "Submit",
|
||||||
|
"subscription": "Subscription",
|
||||||
"success": "成功",
|
"success": "成功",
|
||||||
"successfully-lowercase": "successfully",
|
"successfully-lowercase": "successfully",
|
||||||
"successfully-uploaded": "アップロード成功",
|
"successfully-uploaded": "アップロード成功",
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
"enter": "Enter",
|
"enter": "Enter",
|
||||||
"enter-entity": "Introduzir {{entity}}",
|
"enter-entity": "Introduzir {{entity}}",
|
||||||
"enter-entity-name": "Introduzir nome da {{entity}}",
|
"enter-entity-name": "Introduzir nome da {{entity}}",
|
||||||
|
"enter-entity-value": "Enter {{entity}} Value",
|
||||||
"enter-field-description": "Introduzir descrição do {{entity}}",
|
"enter-field-description": "Introduzir descrição do {{entity}}",
|
||||||
"enter-property-value": "Introduzir valor da propriedade",
|
"enter-property-value": "Introduzir valor da propriedade",
|
||||||
"enter-type-password": "Introduzir {{type}} da senha",
|
"enter-type-password": "Introduzir {{type}} da senha",
|
||||||
@ -904,6 +905,7 @@
|
|||||||
"sub-domain-plural": "Sub Domains",
|
"sub-domain-plural": "Sub Domains",
|
||||||
"sub-team-plural": "Sub-equipes",
|
"sub-team-plural": "Sub-equipes",
|
||||||
"submit": "Enviar",
|
"submit": "Enviar",
|
||||||
|
"subscription": "Subscription",
|
||||||
"success": "Sucesso",
|
"success": "Sucesso",
|
||||||
"successfully-lowercase": "successfully",
|
"successfully-lowercase": "successfully",
|
||||||
"successfully-uploaded": "Enviado com sucesso",
|
"successfully-uploaded": "Enviado com sucesso",
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
"enter": "Введите",
|
"enter": "Введите",
|
||||||
"enter-entity": "Введите {{entity}}",
|
"enter-entity": "Введите {{entity}}",
|
||||||
"enter-entity-name": "Введите имя {{entity}}",
|
"enter-entity-name": "Введите имя {{entity}}",
|
||||||
|
"enter-entity-value": "Enter {{entity}} Value",
|
||||||
"enter-field-description": "Введите описание {{field}}",
|
"enter-field-description": "Введите описание {{field}}",
|
||||||
"enter-property-value": "Введите значение свойства",
|
"enter-property-value": "Введите значение свойства",
|
||||||
"enter-type-password": "Введите {{type}} пароль",
|
"enter-type-password": "Введите {{type}} пароль",
|
||||||
@ -904,6 +905,7 @@
|
|||||||
"sub-domain-plural": "Sub Domains",
|
"sub-domain-plural": "Sub Domains",
|
||||||
"sub-team-plural": "Подгруппы",
|
"sub-team-plural": "Подгруппы",
|
||||||
"submit": "Подтвердить",
|
"submit": "Подтвердить",
|
||||||
|
"subscription": "Subscription",
|
||||||
"success": "Успешно",
|
"success": "Успешно",
|
||||||
"successfully-lowercase": "successfully",
|
"successfully-lowercase": "successfully",
|
||||||
"successfully-uploaded": "Успешно загружено",
|
"successfully-uploaded": "Успешно загружено",
|
||||||
|
@ -345,6 +345,7 @@
|
|||||||
"enter": "输入",
|
"enter": "输入",
|
||||||
"enter-entity": "输入{{entity}}",
|
"enter-entity": "输入{{entity}}",
|
||||||
"enter-entity-name": "输入{{entity}}的名称",
|
"enter-entity-name": "输入{{entity}}的名称",
|
||||||
|
"enter-entity-value": "Enter {{entity}} Value",
|
||||||
"enter-field-description": "输入{{field}}的描述",
|
"enter-field-description": "输入{{field}}的描述",
|
||||||
"enter-property-value": "输入属性值",
|
"enter-property-value": "输入属性值",
|
||||||
"enter-type-password": "输入{{type}}密码",
|
"enter-type-password": "输入{{type}}密码",
|
||||||
@ -904,6 +905,7 @@
|
|||||||
"sub-domain-plural": "子域",
|
"sub-domain-plural": "子域",
|
||||||
"sub-team-plural": "子团队",
|
"sub-team-plural": "子团队",
|
||||||
"submit": "提交",
|
"submit": "提交",
|
||||||
|
"subscription": "Subscription",
|
||||||
"success": "成功",
|
"success": "成功",
|
||||||
"successfully-lowercase": "successfully",
|
"successfully-lowercase": "successfully",
|
||||||
"successfully-uploaded": "上传成功",
|
"successfully-uploaded": "上传成功",
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { useAuthContext } from 'components/authentication/auth-provider/AuthProvider';
|
|
||||||
import ErrorPlaceHolder from 'components/common/error-with-placeholder/ErrorPlaceHolder';
|
import ErrorPlaceHolder from 'components/common/error-with-placeholder/ErrorPlaceHolder';
|
||||||
import { PagingHandlerParams } from 'components/common/next-previous/NextPrevious.interface';
|
import { PagingHandlerParams } from 'components/common/next-previous/NextPrevious.interface';
|
||||||
import Loader from 'components/Loader/Loader';
|
import Loader from 'components/Loader/Loader';
|
||||||
@ -39,7 +38,7 @@ import {
|
|||||||
patchTeamDetail,
|
patchTeamDetail,
|
||||||
} from 'rest/teamsAPI';
|
} from 'rest/teamsAPI';
|
||||||
import { getUsers, updateUserDetail } from 'rest/userAPI';
|
import { getUsers, updateUserDetail } from 'rest/userAPI';
|
||||||
import { getEncodedFqn } from 'utils/StringsUtils';
|
import { getDecodedFqn, getEncodedFqn } from 'utils/StringsUtils';
|
||||||
import AppState from '../../AppState';
|
import AppState from '../../AppState';
|
||||||
import {
|
import {
|
||||||
INITIAL_PAGING_VALUE,
|
INITIAL_PAGING_VALUE,
|
||||||
@ -52,7 +51,6 @@ import { EntityReference } from '../../generated/entity/data/table';
|
|||||||
import { Team } from '../../generated/entity/teams/team';
|
import { Team } from '../../generated/entity/teams/team';
|
||||||
import { User } from '../../generated/entity/teams/user';
|
import { User } from '../../generated/entity/teams/user';
|
||||||
import { Paging } from '../../generated/type/paging';
|
import { Paging } from '../../generated/type/paging';
|
||||||
import { useAuth } from '../../hooks/authHooks';
|
|
||||||
import { SearchResponse } from '../../interface/search.interface';
|
import { SearchResponse } from '../../interface/search.interface';
|
||||||
import { formatUsersResponse } from '../../utils/APIUtils';
|
import { formatUsersResponse } from '../../utils/APIUtils';
|
||||||
import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils';
|
import { DEFAULT_ENTITY_PERMISSION } from '../../utils/PermissionsUtils';
|
||||||
@ -64,8 +62,6 @@ const TeamsPage = () => {
|
|||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { getEntityPermissionByFqn } = usePermissionProvider();
|
const { getEntityPermissionByFqn } = usePermissionProvider();
|
||||||
const { isAdminUser } = useAuth();
|
|
||||||
const { isAuthDisabled } = useAuthContext();
|
|
||||||
const { fqn } = useParams<{ fqn: string }>();
|
const { fqn } = useParams<{ fqn: string }>();
|
||||||
const [currentFqn, setCurrentFqn] = useState<string>('');
|
const [currentFqn, setCurrentFqn] = useState<string>('');
|
||||||
const [allTeam, setAllTeam] = useState<Team[]>([]);
|
const [allTeam, setAllTeam] = useState<Team[]>([]);
|
||||||
@ -223,7 +219,7 @@ const TeamsPage = () => {
|
|||||||
getUsers({
|
getUsers({
|
||||||
fields: 'teams,roles',
|
fields: 'teams,roles',
|
||||||
limit: PAGE_SIZE_BASE,
|
limit: PAGE_SIZE_BASE,
|
||||||
team,
|
team: getDecodedFqn(team),
|
||||||
...paging,
|
...paging,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
@ -285,7 +281,11 @@ const TeamsPage = () => {
|
|||||||
const fetchTeamBasicDetails = async (name: string, loadPage = false) => {
|
const fetchTeamBasicDetails = async (name: string, loadPage = false) => {
|
||||||
setIsPageLoading(loadPage);
|
setIsPageLoading(loadPage);
|
||||||
try {
|
try {
|
||||||
const data = await getTeamByName(name, ['owner', 'parents'], 'all');
|
const data = await getTeamByName(
|
||||||
|
name,
|
||||||
|
['owner', 'parents', 'profile'],
|
||||||
|
'all'
|
||||||
|
);
|
||||||
|
|
||||||
setSelectedTeam(data);
|
setSelectedTeam(data);
|
||||||
if (!isEmpty(data.parents) && data.parents?.[0].name) {
|
if (!isEmpty(data.parents) && data.parents?.[0].name) {
|
||||||
@ -621,7 +621,6 @@ const TeamsPage = () => {
|
|||||||
handleJoinTeamClick={handleJoinTeamClick}
|
handleJoinTeamClick={handleJoinTeamClick}
|
||||||
handleLeaveTeamClick={handleLeaveTeamClick}
|
handleLeaveTeamClick={handleLeaveTeamClick}
|
||||||
handleTeamUsersSearchAction={handleUsersSearchAction}
|
handleTeamUsersSearchAction={handleUsersSearchAction}
|
||||||
hasAccess={isAuthDisabled || isAdminUser}
|
|
||||||
isDescriptionEditable={isDescriptionEditable}
|
isDescriptionEditable={isDescriptionEditable}
|
||||||
isFetchingAdvancedDetails={isFetchingAdvancedDetails}
|
isFetchingAdvancedDetails={isFetchingAdvancedDetails}
|
||||||
isFetchingAllTeamAdvancedDetails={isFetchAllTeamAdvancedDetails}
|
isFetchingAllTeamAdvancedDetails={isFetchAllTeamAdvancedDetails}
|
||||||
|
@ -175,6 +175,12 @@ a[href].link-text-grey,
|
|||||||
border-color: @warning-color;
|
border-color: @warning-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Line height
|
||||||
|
|
||||||
|
.line-height-0 {
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.line-height-16 {
|
.line-height-16 {
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ pre {
|
|||||||
}
|
}
|
||||||
.text-sm {
|
.text-sm {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
line-height: 1rem /* 16px */;
|
||||||
}
|
}
|
||||||
.text-md {
|
.text-md {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
@ -84,7 +84,7 @@
|
|||||||
@tag-background-color: rgba(0, 0, 0, 0.03);
|
@tag-background-color: rgba(0, 0, 0, 0.03);
|
||||||
@trigger-btn-hover-bg: #efefef;
|
@trigger-btn-hover-bg: #efefef;
|
||||||
@text-highlighter: #ffc34e40;
|
@text-highlighter: #ffc34e40;
|
||||||
|
@team-avatar-bg: #0950c51a;
|
||||||
@navbar-height: 64px;
|
@navbar-height: 64px;
|
||||||
@sidebar-width: 60px;
|
@sidebar-width: 60px;
|
||||||
|
|
||||||
|
@ -21,6 +21,11 @@ import {
|
|||||||
} from '../generated/entity/teams/team';
|
} from '../generated/entity/teams/team';
|
||||||
import { getEntityIdArray } from './CommonUtils';
|
import { getEntityIdArray } from './CommonUtils';
|
||||||
|
|
||||||
|
import { SUBSCRIPTION_WEBHOOK } from 'constants/Teams.constants';
|
||||||
|
import { ReactComponent as GChatIcon } from '../assets/svg/gchat.svg';
|
||||||
|
import { ReactComponent as MsTeamsIcon } from '../assets/svg/ms-teams.svg';
|
||||||
|
import { ReactComponent as SlackIcon } from '../assets/svg/slack.svg';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To get filtered list of non-deleted(active) users
|
* To get filtered list of non-deleted(active) users
|
||||||
* @param users List of users
|
* @param users List of users
|
||||||
@ -86,6 +91,23 @@ export const getMovedTeamData = (team: Team, parents: string[]): CreateTeam => {
|
|||||||
} as CreateTeam;
|
} as CreateTeam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To get webhook svg icon
|
||||||
|
* @param item webhook key
|
||||||
|
* @returns SvgComponent
|
||||||
|
*/
|
||||||
|
export const getWebhookIcon = (item: SUBSCRIPTION_WEBHOOK): SvgComponent => {
|
||||||
|
switch (item) {
|
||||||
|
case SUBSCRIPTION_WEBHOOK.SLACK:
|
||||||
|
return SlackIcon;
|
||||||
|
|
||||||
|
case SUBSCRIPTION_WEBHOOK.G_CHAT:
|
||||||
|
return GChatIcon;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return MsTeamsIcon;
|
||||||
|
}
|
||||||
|
};
|
||||||
export const getTeamOptionsFromType = (parentType: TeamType) => {
|
export const getTeamOptionsFromType = (parentType: TeamType) => {
|
||||||
switch (parentType) {
|
switch (parentType) {
|
||||||
case TeamType.Organization:
|
case TeamType.Organization:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user