PLT-6139 (WebApp): Manage Private Channel Members (#5947)
Honour the policy setting for add/remove members from private channels in the WebApp UI.
Этот коммит содержится в:
коммит произвёл
Harrison Healey
родитель
6bf080393d
Коммит
6bb65ef420
@@ -34,6 +34,7 @@ export default class PolicySettings extends AdminSettings {
|
||||
config.TeamSettings.RestrictPrivateChannelManagement = this.state.restrictPrivateChannelManagement;
|
||||
config.TeamSettings.RestrictPublicChannelDeletion = this.state.restrictPublicChannelDeletion;
|
||||
config.TeamSettings.RestrictPrivateChannelDeletion = this.state.restrictPrivateChannelDeletion;
|
||||
config.TeamSettings.RestrictPrivateChannelManageMembers = this.state.restrictPrivateChannelManageMembers;
|
||||
|
||||
return config;
|
||||
}
|
||||
@@ -49,7 +50,8 @@ export default class PolicySettings extends AdminSettings {
|
||||
restrictPublicChannelManagement: config.TeamSettings.RestrictPublicChannelManagement,
|
||||
restrictPrivateChannelManagement: config.TeamSettings.RestrictPrivateChannelManagement,
|
||||
restrictPublicChannelDeletion: config.TeamSettings.RestrictPublicChannelDeletion,
|
||||
restrictPrivateChannelDeletion: config.TeamSettings.RestrictPrivateChannelDeletion
|
||||
restrictPrivateChannelDeletion: config.TeamSettings.RestrictPrivateChannelDeletion,
|
||||
restrictPrivateChannelManageMembers: config.TeamSettings.RestrictPrivateChannelManageMembers
|
||||
};
|
||||
}
|
||||
|
||||
@@ -214,6 +216,29 @@ export default class PolicySettings extends AdminSettings {
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<DropdownSetting
|
||||
id='restrictPrivateChannelManageMembers'
|
||||
values={[
|
||||
{value: Constants.PERMISSIONS_ALL, text: Utils.localizeMessage('admin.general.policy.permissionsAllChannel', 'All channel members')},
|
||||
{value: Constants.PERMISSIONS_CHANNEL_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsChannelAdmin', 'Channel, Team and System Admins')},
|
||||
{value: Constants.PERMISSIONS_TEAM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsAdmin', 'Team and System Admins')},
|
||||
{value: Constants.PERMISSIONS_SYSTEM_ADMIN, text: Utils.localizeMessage('admin.general.policy.permissionsSystemAdmin', 'System Admins')}
|
||||
]}
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='admin.general.policy.restrictPrivateChannelManageMembersTitle'
|
||||
defaultMessage='Enable managing of private group members for:'
|
||||
/>
|
||||
}
|
||||
value={this.state.restrictPrivateChannelManageMembers}
|
||||
onChange={this.handleChange}
|
||||
helpText={
|
||||
<FormattedMessage
|
||||
id='admin.general.policy.restrictPrivateChannelManageMembersDescription'
|
||||
defaultMessage='Set policy on who can add and remove members from private groups.'
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<DropdownSetting
|
||||
id='restrictPrivateChannelDeletion'
|
||||
values={[
|
||||
|
||||
@@ -269,6 +269,7 @@ export default class ChannelHeader extends React.Component {
|
||||
);
|
||||
let channelTitle = channel.display_name;
|
||||
const isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
||||
const isTeamAdmin = TeamStore.isTeamAdminForCurrentTeam();
|
||||
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
||||
const isChannelAdmin = ChannelStore.isChannelAdminForCurrentChannel();
|
||||
const isDirect = (this.state.channel.type === Constants.DM_CHANNEL);
|
||||
@@ -492,44 +493,65 @@ export default class ChannelHeader extends React.Component {
|
||||
/>
|
||||
);
|
||||
|
||||
dropdownContents.push(
|
||||
<li
|
||||
id='channelAddMembers'
|
||||
key='add_members'
|
||||
role='presentation'
|
||||
>
|
||||
<ToggleModalButton
|
||||
ref='channelInviteModalButton'
|
||||
role='menuitem'
|
||||
dialogType={ChannelInviteModal}
|
||||
dialogProps={{channel, currentUser: this.state.currentUser}}
|
||||
if (ChannelUtils.canManageMembers(channel, isSystemAdmin, isTeamAdmin, isChannelAdmin)) {
|
||||
dropdownContents.push(
|
||||
<li
|
||||
id='channelAddMembers'
|
||||
key='add_members'
|
||||
role='presentation'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='channel_header.addMembers'
|
||||
defaultMessage='Add Members'
|
||||
/>
|
||||
</ToggleModalButton>
|
||||
</li>
|
||||
);
|
||||
<ToggleModalButton
|
||||
ref='channelInviteModalButton'
|
||||
role='menuitem'
|
||||
dialogType={ChannelInviteModal}
|
||||
dialogProps={{channel, currentUser: this.state.currentUser}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='channel_header.addMembers'
|
||||
defaultMessage='Add Members'
|
||||
/>
|
||||
</ToggleModalButton>
|
||||
</li>
|
||||
);
|
||||
|
||||
dropdownContents.push(
|
||||
<li
|
||||
id='channelManageMembers'
|
||||
key='manage_members'
|
||||
role='presentation'
|
||||
>
|
||||
<a
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={() => this.setState({showMembersModal: true})}
|
||||
dropdownContents.push(
|
||||
<li
|
||||
id='channelManageMembers'
|
||||
key='manage_members'
|
||||
role='presentation'
|
||||
>
|
||||
<FormattedMessage
|
||||
id='channel_header.manageMembers'
|
||||
defaultMessage='Manage Members'
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
<a
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={() => this.setState({showMembersModal: true})}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='channel_header.manageMembers'
|
||||
defaultMessage='Manage Members'
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
} else {
|
||||
dropdownContents.push(
|
||||
<li
|
||||
id='channelViewMembers'
|
||||
key='view_members'
|
||||
role='presentation'
|
||||
>
|
||||
<a
|
||||
role='menuitem'
|
||||
href='#'
|
||||
onClick={() => this.setState({showMembersModal: true})}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='channel_header.viewMembers'
|
||||
defaultMessage='View Members'
|
||||
/>
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const deleteOption = (
|
||||
|
||||
@@ -9,6 +9,7 @@ import {removeUserFromChannel, makeUserChannelAdmin, makeUserChannelMember} from
|
||||
|
||||
import * as AsyncClient from 'utils/async_client.jsx';
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
import {canManageMembers} from 'utils/channel_utils.jsx';
|
||||
|
||||
import React from 'react';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
@@ -91,8 +92,7 @@ export default class ChannelMembersDropdown extends React.Component {
|
||||
|
||||
// Checks if the current user has the power to remove this member from the channel.
|
||||
canRemoveMember() {
|
||||
// TODO: This will be implemented as part of PLT-5047.
|
||||
return true;
|
||||
return canManageMembers(this.props.channel, UserStore.isSystemAdminForCurrentUser(), TeamStore.isTeamAdminForCurrentTeam(), ChannelStore.isChannelAdminForCurrentChannel());
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
|
||||
import MemberListChannel from './member_list_channel.jsx';
|
||||
|
||||
import TeamStore from 'stores/team_store.jsx';
|
||||
import UserStore from 'stores/user_store.jsx';
|
||||
import ChannelStore from 'stores/channel_store.jsx';
|
||||
|
||||
import {canManageMembers} from 'utils/channel_utils.jsx';
|
||||
|
||||
import React from 'react';
|
||||
import {Modal} from 'react-bootstrap';
|
||||
import {FormattedMessage} from 'react-intl';
|
||||
@@ -24,6 +30,30 @@ export default class ChannelMembersModal extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
||||
const isTeamAdmin = TeamStore.isTeamAdminForCurrentTeam();
|
||||
const isChannelAdmin = ChannelStore.isChannelAdminForCurrentChannel();
|
||||
|
||||
let addMembersButton = null;
|
||||
if (canManageMembers(this.state.channel, isSystemAdmin, isTeamAdmin, isChannelAdmin)) {
|
||||
addMembersButton = (
|
||||
<a
|
||||
id='showInviteModal'
|
||||
className='btn btn-md btn-primary'
|
||||
href='#'
|
||||
onClick={() => {
|
||||
this.props.showInviteModal();
|
||||
this.onHide();
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='channel_members_modal.addNew'
|
||||
defaultMessage=' Add New Members'
|
||||
/>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Modal
|
||||
@@ -40,20 +70,7 @@ export default class ChannelMembersModal extends React.Component {
|
||||
defaultMessage=' Members'
|
||||
/>
|
||||
</Modal.Title>
|
||||
<a
|
||||
id='showInviteModal'
|
||||
className='btn btn-md btn-primary'
|
||||
href='#'
|
||||
onClick={() => {
|
||||
this.props.showInviteModal();
|
||||
this.onHide();
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id='channel_members_modal.addNew'
|
||||
defaultMessage=' Add New Members'
|
||||
/>
|
||||
</a>
|
||||
{addMembersButton}
|
||||
</Modal.Header>
|
||||
<Modal.Body
|
||||
ref='modalBody'
|
||||
|
||||
@@ -17,6 +17,7 @@ import * as AsyncClient from 'utils/async_client.jsx';
|
||||
import Client from 'client/web_client.jsx';
|
||||
import * as Utils from 'utils/utils.jsx';
|
||||
import Constants from 'utils/constants.jsx';
|
||||
import {canManageMembers} from 'utils/channel_utils.jsx';
|
||||
|
||||
import $ from 'jquery';
|
||||
import React from 'react';
|
||||
@@ -86,10 +87,11 @@ export default class PopoverListMembers extends React.Component {
|
||||
const popoverHtml = [];
|
||||
const members = this.props.members;
|
||||
const teamMembers = UserStore.getProfilesUsernameMap();
|
||||
let isAdmin = false;
|
||||
const currentUserId = UserStore.getCurrentId();
|
||||
|
||||
isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
||||
const isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
||||
const isTeamAdmin = TeamStore.isTeamAdminForCurrentTeam();
|
||||
const isChannelAdmin = ChannelStore.isChannelAdminForCurrentChannel();
|
||||
|
||||
if (members && teamMembers) {
|
||||
members.sort((a, b) => {
|
||||
@@ -156,7 +158,7 @@ export default class PopoverListMembers extends React.Component {
|
||||
defaultMessage='Manage Members'
|
||||
/>
|
||||
);
|
||||
if (!isAdmin && ChannelStore.isDefault(this.props.channel)) {
|
||||
if (!canManageMembers(this.props.channel, isSystemAdmin, isTeamAdmin, isChannelAdmin) && !ChannelStore.isDefault(this.props.channel)) {
|
||||
membersName = (
|
||||
<FormattedMessage
|
||||
id='members_popover.viewMembers'
|
||||
@@ -217,7 +219,7 @@ export default class PopoverListMembers extends React.Component {
|
||||
teamMembersModal = (
|
||||
<TeamMembersModal
|
||||
onHide={() => this.setState({showTeamMembersModal: false})}
|
||||
isAdmin={isAdmin}
|
||||
isAdmin={isTeamAdmin || isSystemAdmin}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -331,10 +331,12 @@
|
||||
"admin.general.policy.restrictPrivateChannelCreationDescription": "Set policy on who can create private groups.",
|
||||
"admin.general.policy.restrictPrivateChannelCreationTitle": "Enable private group creation for:",
|
||||
"admin.general.policy.restrictPrivateChannelDeletionCommandLineToolLink": "command line tool",
|
||||
"admin.general.policy.restrictPrivateChannelDeletionDescription": "Set policy on who can delete private groups. Deleted groups can be recovered from the database using a {commandLineToolLink}.",
|
||||
"admin.general.policy.restrictPrivateChannelDeletionTitle": "Enable private group deletion for:",
|
||||
"admin.general.policy.restrictPrivateChannelManagementDescription": "Set policy on who can rename and set the header or purpose for private groups.",
|
||||
"admin.general.policy.restrictPrivateChannelManagementTitle": "Enable private group renaming for:",
|
||||
"admin.general.policy.restrictPrivateChannelDeletionDescription": "Set policy on who can delete private channels. Deleted channels can be recovered from the database using a {commandLineToolLink}.",
|
||||
"admin.general.policy.restrictPrivateChannelDeletionTitle": "Enable private channel deletion for:",
|
||||
"admin.general.policy.restrictPrivateChannelManagementDescription": "Set policy on who can rename and set the header or purpose for private channels.",
|
||||
"admin.general.policy.restrictPrivateChannelManagementTitle": "Enable private channel renaming for:",
|
||||
"admin.general.policy.restrictPrivateChannelManageMembersDescription": "Set policy on who can add and remove members from private channels.",
|
||||
"admin.general.policy.restrictPrivateChannelManageMembersTitle": "Enable managing of private channel members for:",
|
||||
"admin.general.policy.restrictPublicChannelCreationDescription": "Set policy on who can create public channels.",
|
||||
"admin.general.policy.restrictPublicChannelCreationTitle": "Enable public channel creation for:",
|
||||
"admin.general.policy.restrictPublicChannelDeletionCommandLineToolLink": "command line tool",
|
||||
|
||||
@@ -208,6 +208,26 @@ export function showDeleteOption(channel, isAdmin, isSystemAdmin, isChannelAdmin
|
||||
return true;
|
||||
}
|
||||
|
||||
export function canManageMembers(channel, isSystemAdmin, isTeamAdmin, isChannelAdmin) {
|
||||
if (global.window.mm_license.IsLicensed !== 'true') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (channel.type === Constants.PRIVATE_CHANNEL) {
|
||||
if (global.window.mm_config.RestrictPrivateChannelManageMembers === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (global.window.mm_config.RestrictPrivateChannelManageMembers === Constants.PERMISSIONS_TEAM_ADMIN && !isTeamAdmin && !isSystemAdmin) {
|
||||
return false;
|
||||
}
|
||||
if (global.window.mm_config.RestrictPrivateChannelManageMembers === Constants.PERMISSIONS_CHANNEL_ADMIN && !isChannelAdmin && !isTeamAdmin && !isSystemAdmin) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function buildGroupChannelName(channelId) {
|
||||
const profiles = UserStore.getProfileListInChannel(channelId, true);
|
||||
let displayName = '';
|
||||
|
||||
Ссылка в новой задаче
Block a user