[MM-48184] Disallow edit/remove server if it is imported from GPO (#2353)

* Disallow edit/remove server if it is imported from GPO

* Fix width issue of team dropdown
This commit is contained in:
Tasos Boulis
2022-11-04 17:58:21 +02:00
committed by GitHub
parent 935cf3a0cc
commit c319038704
5 changed files with 92 additions and 20 deletions

View File

@@ -57,4 +57,52 @@ describe('main/views/teamDropdownView', () => {
teamDropdownView.handleClose();
expect(teamDropdownView.view.setBounds).toBeCalledWith({width: 0, height: 0, x: expect.any(Number), y: expect.any(Number)});
});
describe('addGpoToTeams', () => {
it('should return teams with "isGPO": false when no config.registryTeams exist', () => {
const teamDropdownView = new TeamDropdownView(window, [], false, true);
const teams = [{
name: 'team-1',
url: 'https://mattermost.team-1.com',
}, {
name: 'team-2',
url: 'https://mattermost.team-2.com',
}];
const registryTeams = [];
expect(teamDropdownView.addGpoToTeams(teams, registryTeams)).toStrictEqual([{
name: 'team-1',
url: 'https://mattermost.team-1.com',
isGpo: false,
}, {
name: 'team-2',
url: 'https://mattermost.team-2.com',
isGpo: false,
}]);
});
it('should return teams with "isGPO": true if they exist in config.registryTeams', () => {
const teamDropdownView = new TeamDropdownView(window, [], false, true);
const teams = [{
name: 'team-1',
url: 'https://mattermost.team-1.com',
}, {
name: 'team-2',
url: 'https://mattermost.team-2.com',
}];
const registryTeams = [{
name: 'team-1',
url: 'https://mattermost.team-1.com',
}];
expect(teamDropdownView.addGpoToTeams(teams, registryTeams)).toStrictEqual([{
name: 'team-1',
url: 'https://mattermost.team-1.com',
isGpo: true,
}, {
name: 'team-2',
url: 'https://mattermost.team-2.com',
isGpo: false,
}]);
});
});
});

View File

@@ -5,7 +5,7 @@ import {BrowserView, BrowserWindow, ipcMain, IpcMainEvent} from 'electron';
import log from 'electron-log';
import {CombinedConfig, TeamWithTabs} from 'types/config';
import {CombinedConfig, Team, TeamWithTabs, TeamWithTabsAndGpo} from 'types/config';
import {
CLOSE_TEAMS_DROPDOWN,
@@ -25,7 +25,7 @@ import WindowManager from '../windows/windowManager';
export default class TeamDropdownView {
view: BrowserView;
bounds?: Electron.Rectangle;
teams: TeamWithTabs[];
teams: TeamWithTabsAndGpo[];
activeTeam?: string;
darkMode: boolean;
enableServerManagement?: boolean;
@@ -38,7 +38,7 @@ export default class TeamDropdownView {
isOpen: boolean;
constructor(window: BrowserWindow, teams: TeamWithTabs[], darkMode: boolean, enableServerManagement: boolean) {
this.teams = teams;
this.teams = this.addGpoToTeams(teams, []);
this.window = window;
this.darkMode = darkMode;
this.enableServerManagement = enableServerManagement;
@@ -71,7 +71,7 @@ export default class TeamDropdownView {
updateConfig = (event: IpcMainEvent, config: CombinedConfig) => {
log.silly('TeamDropdownView.config', {config});
this.teams = config.teams;
this.teams = this.addGpoToTeams(config.teams, config.registryTeams);
this.darkMode = config.darkMode;
this.enableServerManagement = config.enableServerManagement;
this.hasGPOTeams = config.registryTeams && config.registryTeams.length > 0;
@@ -162,4 +162,16 @@ export default class TeamDropdownView {
// @ts-ignore
this.view.webContents.destroy();
}
addGpoToTeams = (teams: TeamWithTabs[], registryTeams: Team[]): TeamWithTabsAndGpo[] => {
if (!registryTeams || registryTeams.length === 0) {
return teams.map((team) => ({...team, isGpo: false}));
}
return teams.map((team) => {
return {
...team,
isGpo: registryTeams.some((regTeam) => regTeam!.url === team!.url),
};
});
}
}

View File

@@ -1,6 +1,6 @@
@import url("fonts.css");
@import '~@mattermost/compass-icons/css/compass-icons.css';
body {
margin: 0;
background-color: transparent;
@@ -23,6 +23,7 @@ body {
border: 1px solid rgba(61, 60, 64, 0.16);
box-shadow: 0px 8px 24px rgba(0, 0, 0, 0.12);
border-radius: 4px;
min-width: 180px;
}
.TeamDropdown__droppable {
@@ -138,7 +139,7 @@ body {
> i.icon-plus {
margin-top: -2px;
&::before {
margin: 0;
}
@@ -151,7 +152,7 @@ body {
display: flex;
overflow: hidden;
margin-right: 36px;
&.dragging {
cursor: grabbing !important;
}
@@ -188,7 +189,7 @@ body {
border-radius: 8px;
flex: 0 0 8px;
}
.TeamDropdown__badge-count {
background: #F74343;
text-align: center;
@@ -276,11 +277,11 @@ body {
border-color: rgba(221, 221, 221, 0.08);
}
.TeamDropdown__button {
.TeamDropdown__button {
&:not(.anyDragging):hover {
background-color: rgba(221, 221, 221, 0.08);
}
&:focus {
background-color: rgba(1, 119, 231, 0.08);
}
@@ -288,7 +289,7 @@ body {
&:not(.active) i, i.icon-drag-vertical {
color: rgba(221, 221, 221, 0.56);
}
> .TeamDropdown__draggable-handle > span, &.addServer > span {
color: #DDD;
}

View File

@@ -7,7 +7,7 @@ import {FormattedMessage} from 'react-intl';
import classNames from 'classnames';
import {DragDropContext, Draggable, DraggingStyle, Droppable, DropResult, NotDraggingStyle} from 'react-beautiful-dnd';
import {Team, TeamWithTabs} from 'types/config';
import {Team, TeamWithTabs, TeamWithTabsAndGpo} from 'types/config';
import {
CLOSE_TEAMS_DROPDOWN,
@@ -27,8 +27,8 @@ import './css/dropdown.scss';
import IntlProvider from './intl_provider';
type State = {
teams?: TeamWithTabs[];
orderedTeams?: TeamWithTabs[];
teams?: TeamWithTabsAndGpo[];
orderedTeams?: TeamWithTabsAndGpo[];
activeTeam?: string;
darkMode?: boolean;
enableServerManagement?: boolean;
@@ -212,22 +212,32 @@ class TeamDropdown extends React.PureComponent<Record<string, never>, State> {
}
}
editServer = (team: string) => {
editServer = (teamName: string) => {
if (this.teamIsGpo(teamName)) {
return () => {};
}
return (event: React.MouseEvent<HTMLButtonElement>) => {
event.stopPropagation();
window.postMessage({type: SHOW_EDIT_SERVER_MODAL, data: {name: team}}, window.location.href);
window.postMessage({type: SHOW_EDIT_SERVER_MODAL, data: {name: teamName}}, window.location.href);
this.closeMenu();
};
}
removeServer = (team: string) => {
removeServer = (teamName: string) => {
if (this.teamIsGpo(teamName)) {
return () => {};
}
return (event: React.MouseEvent<HTMLButtonElement>) => {
event.stopPropagation();
window.postMessage({type: SHOW_REMOVE_SERVER_MODAL, data: {name: team}}, window.location.href);
window.postMessage({type: SHOW_REMOVE_SERVER_MODAL, data: {name: teamName}}, window.location.href);
this.closeMenu();
};
}
teamIsGpo = (teamName: string) => {
return this.state.orderedTeams?.some((team) => team.name === teamName && team.isGpo);
}
render() {
return (
<IntlProvider>
@@ -326,7 +336,7 @@ class TeamDropdown extends React.PureComponent<Record<string, never>, State> {
{this.isActiveTeam(team) ? <i className='icon-check'/> : <i className='icon-server-variant'/>}
<span>{team.name}</span>
</div>
<div className='TeamDropdown__indicators'>
{!team.isGpo && <div className='TeamDropdown__indicators'>
<button
className='TeamDropdown__button-edit'
onClick={this.editServer(team.name)}
@@ -342,7 +352,7 @@ class TeamDropdown extends React.PureComponent<Record<string, never>, State> {
{badgeDiv && <div className='TeamDropdown__badge'>
{badgeDiv}
</div>}
</div>
</div>}
</button>
)}
</Draggable>

View File

@@ -16,6 +16,7 @@ export type Team = {
export type TeamWithIndex = Team & {index: number};
export type TeamWithTabs = Team & {tabs: Tab[]};
export type TeamWithTabsAndGpo = TeamWithTabs & {isGpo?: boolean};
export type Config = ConfigV3;