From c3190387045aedbb6ec18def9cf19efd68a75246 Mon Sep 17 00:00:00 2001 From: Tasos Boulis Date: Fri, 4 Nov 2022 17:58:21 +0200 Subject: [PATCH] [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 --- src/main/views/teamDropdownView.test.js | 48 +++++++++++++++++++++++++ src/main/views/teamDropdownView.ts | 20 ++++++++--- src/renderer/css/dropdown.scss | 15 ++++---- src/renderer/dropdown.tsx | 28 ++++++++++----- src/types/config.ts | 1 + 5 files changed, 92 insertions(+), 20 deletions(-) diff --git a/src/main/views/teamDropdownView.test.js b/src/main/views/teamDropdownView.test.js index 2f238a86..213f5fa1 100644 --- a/src/main/views/teamDropdownView.test.js +++ b/src/main/views/teamDropdownView.test.js @@ -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, + }]); + }); + }); }); diff --git a/src/main/views/teamDropdownView.ts b/src/main/views/teamDropdownView.ts index b293c8e2..ce267f57 100644 --- a/src/main/views/teamDropdownView.ts +++ b/src/main/views/teamDropdownView.ts @@ -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), + }; + }); + } } diff --git a/src/renderer/css/dropdown.scss b/src/renderer/css/dropdown.scss index 7215afa8..fd2f898b 100644 --- a/src/renderer/css/dropdown.scss +++ b/src/renderer/css/dropdown.scss @@ -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; } diff --git a/src/renderer/dropdown.tsx b/src/renderer/dropdown.tsx index cab23f4d..893b0d0f 100644 --- a/src/renderer/dropdown.tsx +++ b/src/renderer/dropdown.tsx @@ -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, State> { } } - editServer = (team: string) => { + editServer = (teamName: string) => { + if (this.teamIsGpo(teamName)) { + return () => {}; + } return (event: React.MouseEvent) => { 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) => { 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 ( @@ -326,7 +336,7 @@ class TeamDropdown extends React.PureComponent, State> { {this.isActiveTeam(team) ? : } {team.name} -
+ {!team.isGpo &&
+
} )} diff --git a/src/types/config.ts b/src/types/config.ts index f0a643ea..34225dc0 100644 --- a/src/types/config.ts +++ b/src/types/config.ts @@ -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;