PLT-5050 (WebApp): Change channel member roles. (#5076)
Admins can now Promote/Demote channel members in the Channel Manage Membersmodal.
Этот коммит содержится в:
коммит произвёл
enahum
родитель
2554ae4a25
Коммит
e15ae2253a
@@ -125,6 +125,48 @@ export function removeUserFromChannel(channelId, userId, success, error) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function makeUserChannelAdmin(channelId, userId, success, error) {
|
||||||
|
Client.updateChannelMemberRoles(
|
||||||
|
channelId,
|
||||||
|
userId,
|
||||||
|
'channel_user channel_admin',
|
||||||
|
() => {
|
||||||
|
AsyncClient.getChannelMember(channelId, userId);
|
||||||
|
getChannelMembersForUserIds(channelId, [userId]);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
success();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
if (error) {
|
||||||
|
error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeUserChannelMember(channelId, userId, success, error) {
|
||||||
|
Client.updateChannelMemberRoles(
|
||||||
|
channelId,
|
||||||
|
userId,
|
||||||
|
'channel_user',
|
||||||
|
() => {
|
||||||
|
AsyncClient.getChannelMember(channelId, userId);
|
||||||
|
getChannelMembersForUserIds(channelId, [userId]);
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
success();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
if (error) {
|
||||||
|
error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function openDirectChannelToUser(user, success, error) {
|
export function openDirectChannelToUser(user, success, error) {
|
||||||
const channelName = Utils.getDirectChannelName(UserStore.getCurrentId(), user.id);
|
const channelName = Utils.getDirectChannelName(UserStore.getCurrentId(), user.id);
|
||||||
const channel = ChannelStore.getByName(channelName);
|
const channel = ChannelStore.getByName(channelName);
|
||||||
@@ -343,3 +385,33 @@ export function updateChannelHeader(channelId, header, success, error) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getChannelMembersForUserIds(channelId, userIds, success, error) {
|
||||||
|
Client.getChannelMembersByIds(
|
||||||
|
channelId,
|
||||||
|
userIds,
|
||||||
|
(data) => {
|
||||||
|
const memberMap = {};
|
||||||
|
for (let i = 0; i < data.length; i++) {
|
||||||
|
memberMap[data[i].user_id] = data[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
AppDispatcher.handleServerAction({
|
||||||
|
type: ActionTypes.RECEIVED_MEMBERS_IN_CHANNEL,
|
||||||
|
channel_id: channelId,
|
||||||
|
channel_members: memberMap
|
||||||
|
});
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
success(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
AsyncClient.dispatchError(err, 'getChannelMembersByIds');
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import TeamStore from 'stores/team_store.jsx';
|
|||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
import ChannelStore from 'stores/channel_store.jsx';
|
import ChannelStore from 'stores/channel_store.jsx';
|
||||||
|
|
||||||
|
import {getChannelMembersForUserIds} from 'actions/channel_actions.jsx';
|
||||||
import {loadStatusesForProfilesList, loadStatusesForProfilesMap} from 'actions/status_actions.jsx';
|
import {loadStatusesForProfilesList, loadStatusesForProfilesMap} from 'actions/status_actions.jsx';
|
||||||
|
|
||||||
import {getDirectChannelName} from 'utils/utils.jsx';
|
import {getDirectChannelName} from 'utils/utils.jsx';
|
||||||
@@ -180,7 +181,7 @@ export function loadChannelMembersForProfilesMap(profiles, channelId = ChannelSt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadChannelMembersForProfiles(list, channelId, success, error);
|
getChannelMembersForUserIds(channelId, list, success, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadTeamMembersAndChannelMembersForProfilesList(profiles, teamId = TeamStore.getCurrentId(), channelId = ChannelStore.getCurrentId(), success, error) {
|
export function loadTeamMembersAndChannelMembersForProfilesList(profiles, teamId = TeamStore.getCurrentId(), channelId = ChannelStore.getCurrentId(), success, error) {
|
||||||
@@ -207,37 +208,7 @@ export function loadChannelMembersForProfilesList(profiles, channelId = ChannelS
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadChannelMembersForProfiles(list, channelId, success, error);
|
getChannelMembersForUserIds(channelId, list, success, error);
|
||||||
}
|
|
||||||
|
|
||||||
function loadChannelMembersForProfiles(userIds, channelId, success, error) {
|
|
||||||
Client.getChannelMembersByIds(
|
|
||||||
channelId,
|
|
||||||
userIds,
|
|
||||||
(data) => {
|
|
||||||
const memberMap = {};
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
memberMap[data[i].user_id] = data[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
AppDispatcher.handleServerAction({
|
|
||||||
type: ActionTypes.RECEIVED_MEMBERS_IN_CHANNEL,
|
|
||||||
channel_id: channelId,
|
|
||||||
channel_members: memberMap
|
|
||||||
});
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
success(data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
(err) => {
|
|
||||||
AsyncClient.dispatchError(err, 'getChannelMembersByIds');
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
error(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateDMChannelsWithProfiles(userIds) {
|
function populateDMChannelsWithProfiles(userIds) {
|
||||||
|
|||||||
@@ -1530,6 +1530,21 @@ export default class Client {
|
|||||||
this.track('api', 'api_channels_remove_member');
|
this.track('api', 'api_channels_remove_member');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateChannelMemberRoles(channelId, userId, newRoles, success, error) {
|
||||||
|
var data = {
|
||||||
|
user_id: userId,
|
||||||
|
new_roles: newRoles
|
||||||
|
};
|
||||||
|
|
||||||
|
request.
|
||||||
|
post(`${this.getChannelNeededRoute(channelId)}/update_member_roles`).
|
||||||
|
set(this.defaultHeaders).
|
||||||
|
type('application/json').
|
||||||
|
accept('application/json').
|
||||||
|
send(data).
|
||||||
|
end(this.handleResponse.bind(this, 'updateChannelMemberRoles', success, error));
|
||||||
|
}
|
||||||
|
|
||||||
// Routes for Commands
|
// Routes for Commands
|
||||||
|
|
||||||
listCommands(success, error) {
|
listCommands(success, error) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import ChannelStore from 'stores/channel_store.jsx';
|
|||||||
import TeamStore from 'stores/team_store.jsx';
|
import TeamStore from 'stores/team_store.jsx';
|
||||||
import UserStore from 'stores/user_store.jsx';
|
import UserStore from 'stores/user_store.jsx';
|
||||||
|
|
||||||
import {removeUserFromChannel} from 'actions/channel_actions.jsx';
|
import {removeUserFromChannel, makeUserChannelAdmin, makeUserChannelMember} from 'actions/channel_actions.jsx';
|
||||||
|
|
||||||
import * as AsyncClient from 'utils/async_client.jsx';
|
import * as AsyncClient from 'utils/async_client.jsx';
|
||||||
import * as Utils from 'utils/utils.jsx';
|
import * as Utils from 'utils/utils.jsx';
|
||||||
@@ -18,6 +18,8 @@ export default class ChannelMembersDropdown extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.handleRemoveFromChannel = this.handleRemoveFromChannel.bind(this);
|
this.handleRemoveFromChannel = this.handleRemoveFromChannel.bind(this);
|
||||||
|
this.handleMakeChannelMember = this.handleMakeChannelMember.bind(this);
|
||||||
|
this.handleMakeChannelAdmin = this.handleMakeChannelAdmin.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
serverError: null,
|
serverError: null,
|
||||||
@@ -39,6 +41,32 @@ export default class ChannelMembersDropdown extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleMakeChannelMember() {
|
||||||
|
makeUserChannelMember(
|
||||||
|
this.props.channel.id,
|
||||||
|
this.props.user.id,
|
||||||
|
() => {
|
||||||
|
AsyncClient.getChannelStats(this.props.channel.id);
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
this.setState({serverError: err.message});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMakeChannelAdmin() {
|
||||||
|
makeUserChannelAdmin(
|
||||||
|
this.props.channel.id,
|
||||||
|
this.props.user.id,
|
||||||
|
() => {
|
||||||
|
AsyncClient.getChannelStats(this.props.channel.id);
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
this.setState({serverError: err.message});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Checks if the user this menu is for is a channel admin or not.
|
// Checks if the user this menu is for is a channel admin or not.
|
||||||
isChannelAdmin() {
|
isChannelAdmin() {
|
||||||
if (Utils.isChannelAdmin(this.props.channelMember.roles)) {
|
if (Utils.isChannelAdmin(this.props.channelMember.roles)) {
|
||||||
@@ -116,6 +144,42 @@ export default class ChannelMembersDropdown extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let makeChannelMember = null;
|
||||||
|
if (this.isChannelAdmin()) {
|
||||||
|
makeChannelMember = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={this.handleMakeChannelMember}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_members_dropdown.make_channel_member'
|
||||||
|
defaultMessage='Make Channel Member'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let makeChannelAdmin = null;
|
||||||
|
if (!this.isChannelAdmin()) {
|
||||||
|
makeChannelAdmin = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={this.handleMakeChannelAdmin}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_members_dropdown.make_channel_admin'
|
||||||
|
defaultMessage='Make Channel Admin'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='dropdown member-drop'>
|
<div className='dropdown member-drop'>
|
||||||
<a
|
<a
|
||||||
@@ -132,6 +196,8 @@ export default class ChannelMembersDropdown extends React.Component {
|
|||||||
className='dropdown-menu member-menu'
|
className='dropdown-menu member-menu'
|
||||||
role='menu'
|
role='menu'
|
||||||
>
|
>
|
||||||
|
{makeChannelMember}
|
||||||
|
{makeChannelAdmin}
|
||||||
{removeFromChannel}
|
{removeFromChannel}
|
||||||
</ul>
|
</ul>
|
||||||
{serverError}
|
{serverError}
|
||||||
|
|||||||
@@ -1094,6 +1094,8 @@
|
|||||||
"channel_loader.wrote": " wrote: ",
|
"channel_loader.wrote": " wrote: ",
|
||||||
"channel_members_dropdown.channel_admin": "Channel Admin",
|
"channel_members_dropdown.channel_admin": "Channel Admin",
|
||||||
"channel_members_dropdown.channel_member": "Channel Member",
|
"channel_members_dropdown.channel_member": "Channel Member",
|
||||||
|
"channel_members_dropdown.make_channel_admin": "Make Channel Admin",
|
||||||
|
"channel_members_dropdown.make_channel_member": "Make Channel Member",
|
||||||
"channel_members_dropdown.remove_from_channel": "Remove From Channel",
|
"channel_members_dropdown.remove_from_channel": "Remove From Channel",
|
||||||
"channel_members_dropdown.remove_member": "Remove Member",
|
"channel_members_dropdown.remove_member": "Remove Member",
|
||||||
"channel_members_modal.addNew": " Add New Members",
|
"channel_members_modal.addNew": " Add New Members",
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user