Add channel management permissions to mobile channel dropdown and clean up logic a bit (#3505)
Этот коммит содержится в:
коммит произвёл
enahum
родитель
ccbf06dca9
Коммит
292705acdf
@@ -64,6 +64,7 @@ export default class Navbar extends React.Component {
|
|||||||
state.showChannelSwitchModal = false;
|
state.showChannelSwitchModal = false;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
getStateFromStores() {
|
getStateFromStores() {
|
||||||
return {
|
return {
|
||||||
channel: ChannelStore.getCurrent(),
|
channel: ChannelStore.getCurrent(),
|
||||||
@@ -73,9 +74,11 @@ export default class Navbar extends React.Component {
|
|||||||
currentUser: UserStore.getCurrentUser()
|
currentUser: UserStore.getCurrentUser()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
isStateValid() {
|
isStateValid() {
|
||||||
return this.state.channel && this.state.member && this.state.users && this.state.currentUser;
|
return this.state.channel && this.state.member && this.state.users && this.state.currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
ChannelStore.addChangeListener(this.onChange);
|
ChannelStore.addChangeListener(this.onChange);
|
||||||
ChannelStore.addExtraInfoChangeListener(this.onChange);
|
ChannelStore.addExtraInfoChangeListener(this.onChange);
|
||||||
@@ -83,15 +86,18 @@ export default class Navbar extends React.Component {
|
|||||||
$('.inner-wrap').click(this.hideSidebars);
|
$('.inner-wrap').click(this.hideSidebars);
|
||||||
document.addEventListener('keydown', this.showChannelSwitchModal);
|
document.addEventListener('keydown', this.showChannelSwitchModal);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
ChannelStore.removeChangeListener(this.onChange);
|
ChannelStore.removeChangeListener(this.onChange);
|
||||||
ChannelStore.removeExtraInfoChangeListener(this.onChange);
|
ChannelStore.removeExtraInfoChangeListener(this.onChange);
|
||||||
UserStore.removeStatusesChangeListener(this.onChange);
|
UserStore.removeStatusesChangeListener(this.onChange);
|
||||||
document.removeEventListener('keydown', this.showChannelSwitchModal);
|
document.removeEventListener('keydown', this.showChannelSwitchModal);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit(e) {
|
handleSubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLeave() {
|
handleLeave() {
|
||||||
Client.leaveChannel(this.state.channel.id,
|
Client.leaveChannel(this.state.channel.id,
|
||||||
() => {
|
() => {
|
||||||
@@ -103,6 +109,7 @@ export default class Navbar extends React.Component {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
hideSidebars(e) {
|
hideSidebars(e) {
|
||||||
var windowWidth = $(window).outerWidth();
|
var windowWidth = $(window).outerWidth();
|
||||||
if (windowWidth <= 768) {
|
if (windowWidth <= 768) {
|
||||||
@@ -124,22 +131,27 @@ export default class Navbar extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleLeftSidebar() {
|
toggleLeftSidebar() {
|
||||||
$('.app__body .inner-wrap').toggleClass('move--right');
|
$('.app__body .inner-wrap').toggleClass('move--right');
|
||||||
$('.app__body .sidebar--left').toggleClass('move--right');
|
$('.app__body .sidebar--left').toggleClass('move--right');
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleRightSidebar() {
|
toggleRightSidebar() {
|
||||||
$('.app__body .inner-wrap').toggleClass('move--left-small');
|
$('.app__body .inner-wrap').toggleClass('move--left-small');
|
||||||
$('.app__body .sidebar--menu').toggleClass('move--left');
|
$('.app__body .sidebar--menu').toggleClass('move--left');
|
||||||
}
|
}
|
||||||
|
|
||||||
showSearch() {
|
showSearch() {
|
||||||
AppDispatcher.handleServerAction({
|
AppDispatcher.handleServerAction({
|
||||||
type: ActionTypes.SHOW_SEARCH
|
type: ActionTypes.SHOW_SEARCH
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onChange() {
|
onChange() {
|
||||||
this.setState(this.getStateFromStores());
|
this.setState(this.getStateFromStores());
|
||||||
}
|
}
|
||||||
|
|
||||||
showEditChannelHeaderModal() {
|
showEditChannelHeaderModal() {
|
||||||
// this can't be done using a ToggleModalButton because we can't use one inside an OverlayTrigger
|
// this can't be done using a ToggleModalButton because we can't use one inside an OverlayTrigger
|
||||||
if (this.refs.headerOverlay) {
|
if (this.refs.headerOverlay) {
|
||||||
@@ -150,6 +162,7 @@ export default class Navbar extends React.Component {
|
|||||||
showEditChannelHeaderModal: true
|
showEditChannelHeaderModal: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showRenameChannelModal(e) {
|
showRenameChannelModal(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
@@ -157,11 +170,13 @@ export default class Navbar extends React.Component {
|
|||||||
showRenameChannelModal: true
|
showRenameChannelModal: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hideRenameChannelModal() {
|
hideRenameChannelModal() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showRenameChannelModal: false
|
showRenameChannelModal: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showChannelSwitchModal(e) {
|
showChannelSwitchModal(e) {
|
||||||
if (Utils.cmdOrCtrlPressed(e) && e.keyCode === Constants.KeyCodes.K) {
|
if (Utils.cmdOrCtrlPressed(e) && e.keyCode === Constants.KeyCodes.K) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -170,12 +185,38 @@ export default class Navbar extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hideChannelSwitchModal() {
|
hideChannelSwitchModal() {
|
||||||
this.setState({
|
this.setState({
|
||||||
showChannelSwitchModal: false
|
showChannelSwitchModal: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
createDropdown(channel, channelTitle, isAdmin, isDirect, popoverContent) {
|
|
||||||
|
showManagementOptions(channel, isAdmin, isSystemAdmin) {
|
||||||
|
if (global.window.mm_license.IsLicensed !== 'true') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel.type === Constants.OPEN_CHANNEL) {
|
||||||
|
if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (global.window.mm_config.RestrictPublicChannelManagement === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (channel.type === Constants.PRIVATE_CHANNEL) {
|
||||||
|
if (global.window.mm_config.RestrictPrivateChannelManagement === Constants.PERMISSIONS_SYSTEM_ADMIN && !isSystemAdmin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (global.window.mm_config.RestrictPrivateChannelManagement === Constants.PERMISSIONS_TEAM_ADMIN && !isAdmin) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
createDropdown(channel, channelTitle, isAdmin, isSystemAdmin, isDirect, popoverContent) {
|
||||||
if (channel) {
|
if (channel) {
|
||||||
let channelTerm = (
|
let channelTerm = (
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
@@ -192,160 +233,81 @@ export default class Navbar extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewInfoOption = (
|
let viewInfoOption;
|
||||||
<li role='presentation'>
|
let addMembersOption;
|
||||||
<ToggleModalButton
|
let manageMembersOption;
|
||||||
role='menuitem'
|
let setChannelHeaderOption;
|
||||||
dialogType={ChannelInfoModal}
|
let setChannelPurposeOption;
|
||||||
dialogProps={{channel}}
|
let notificationPreferenceOption;
|
||||||
>
|
let renameChannelOption;
|
||||||
<FormattedMessage
|
let deleteChannelOption;
|
||||||
id='navbar.viewInfo'
|
let leaveChannelOption;
|
||||||
defaultMessage='View Info'
|
|
||||||
/>
|
|
||||||
</ToggleModalButton>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
|
|
||||||
var setChannelHeaderOption = (
|
if (isDirect) {
|
||||||
<li role='presentation'>
|
setChannelHeaderOption = (
|
||||||
<a
|
|
||||||
role='menuitem'
|
|
||||||
href='#'
|
|
||||||
onClick={this.showEditChannelHeaderModal}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='channel_header.setHeader'
|
|
||||||
defaultMessage='Set {term} Header...'
|
|
||||||
values={{
|
|
||||||
term: (channelTerm)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
|
|
||||||
var setChannelPurposeOption = null;
|
|
||||||
if (!isDirect) {
|
|
||||||
setChannelPurposeOption = (
|
|
||||||
<li role='presentation'>
|
<li role='presentation'>
|
||||||
<a
|
<a
|
||||||
role='menuitem'
|
role='menuitem'
|
||||||
href='#'
|
href='#'
|
||||||
onClick={() => this.setState({showEditChannelPurposeModal: true})}
|
onClick={this.showEditChannelHeaderModal}
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='channel_header.setPurpose'
|
id='channel_header.channelHeader'
|
||||||
defaultMessage='Set {term} Purpose...'
|
defaultMessage='Set Channel Header...'
|
||||||
values={{
|
|
||||||
term: (channelTerm)
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
|
viewInfoOption = (
|
||||||
var addMembersOption;
|
|
||||||
var leaveChannelOption;
|
|
||||||
if (!isDirect && !ChannelStore.isDefault(channel)) {
|
|
||||||
addMembersOption = (
|
|
||||||
<li role='presentation'>
|
<li role='presentation'>
|
||||||
<ToggleModalButton
|
<ToggleModalButton
|
||||||
role='menuitem'
|
role='menuitem'
|
||||||
dialogType={ChannelInviteModal}
|
dialogType={ChannelInfoModal}
|
||||||
dialogProps={{channel, currentUser: this.state.currentUser}}
|
dialogProps={{channel}}
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='navbar.addMembers'
|
id='navbar.viewInfo'
|
||||||
defaultMessage='Add Members'
|
defaultMessage='View Info'
|
||||||
/>
|
/>
|
||||||
</ToggleModalButton>
|
</ToggleModalButton>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|
||||||
const canLeave = channel.type === Constants.PRIVATE_CHANNEL ? this.state.userCount > 1 : true;
|
|
||||||
if (canLeave) {
|
|
||||||
leaveChannelOption = (
|
|
||||||
<li role='presentation'>
|
|
||||||
<a
|
|
||||||
role='menuitem'
|
|
||||||
href='#'
|
|
||||||
onClick={this.handleLeave}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='channel_header.leave'
|
|
||||||
defaultMessage='Leave {term}'
|
|
||||||
values={{
|
|
||||||
term: (channelTerm)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var manageMembersOption;
|
|
||||||
var renameChannelOption;
|
|
||||||
var deleteChannelOption;
|
|
||||||
if (!isDirect && isAdmin) {
|
|
||||||
if (!ChannelStore.isDefault(channel)) {
|
if (!ChannelStore.isDefault(channel)) {
|
||||||
manageMembersOption = (
|
addMembersOption = (
|
||||||
<li role='presentation'>
|
|
||||||
<a
|
|
||||||
role='menuitem'
|
|
||||||
href='#'
|
|
||||||
onClick={() => this.setState({showMembersModal: true})}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='navbar.manageMembers'
|
|
||||||
defaultMessage='Manage Members'
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
|
|
||||||
deleteChannelOption = (
|
|
||||||
<li role='presentation'>
|
<li role='presentation'>
|
||||||
<ToggleModalButton
|
<ToggleModalButton
|
||||||
role='menuitem'
|
role='menuitem'
|
||||||
dialogType={DeleteChannelModal}
|
dialogType={ChannelInviteModal}
|
||||||
dialogProps={{channel}}
|
dialogProps={{channel, currentUser: this.state.currentUser}}
|
||||||
>
|
>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='channel_header.delete'
|
id='navbar.addMembers'
|
||||||
defaultMessage='Delete {term}...'
|
defaultMessage='Add Members'
|
||||||
values={{
|
|
||||||
term: (channelTerm)
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</ToggleModalButton>
|
</ToggleModalButton>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (isAdmin) {
|
||||||
|
manageMembersOption = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={() => this.setState({showMembersModal: true})}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='navbar.manageMembers'
|
||||||
|
defaultMessage='Manage Members'
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renameChannelOption = (
|
|
||||||
<li role='presentation'>
|
|
||||||
<a
|
|
||||||
role='menuitem'
|
|
||||||
href='#'
|
|
||||||
onClick={this.showRenameChannelModal}
|
|
||||||
>
|
|
||||||
<FormattedMessage
|
|
||||||
id='channel_header.rename'
|
|
||||||
defaultMessage='Rename {term}...'
|
|
||||||
values={{
|
|
||||||
term: (channelTerm)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
var notificationPreferenceOption;
|
|
||||||
if (!isDirect) {
|
|
||||||
notificationPreferenceOption = (
|
notificationPreferenceOption = (
|
||||||
<li role='presentation'>
|
<li role='presentation'>
|
||||||
<ToggleModalButton
|
<ToggleModalButton
|
||||||
@@ -364,6 +326,105 @@ export default class Navbar extends React.Component {
|
|||||||
</ToggleModalButton>
|
</ToggleModalButton>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (this.showManagementOptions(channel, isAdmin, isSystemAdmin)) {
|
||||||
|
setChannelHeaderOption = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={this.showEditChannelHeaderModal}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_header.setHeader'
|
||||||
|
defaultMessage='Set {term} Header...'
|
||||||
|
values={{
|
||||||
|
term: (channelTerm)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
|
||||||
|
setChannelPurposeOption = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={() => this.setState({showEditChannelPurposeModal: true})}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_header.setPurpose'
|
||||||
|
defaultMessage='Set {term} Purpose...'
|
||||||
|
values={{
|
||||||
|
term: (channelTerm)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
|
||||||
|
renameChannelOption = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={this.showRenameChannelModal}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_header.rename'
|
||||||
|
defaultMessage='Rename {term}...'
|
||||||
|
values={{
|
||||||
|
term: (channelTerm)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.showManagementOptions(channel, isAdmin, isSystemAdmin) || this.state.userCount === 1) {
|
||||||
|
if (!ChannelStore.isDefault(channel)) {
|
||||||
|
deleteChannelOption = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<ToggleModalButton
|
||||||
|
role='menuitem'
|
||||||
|
dialogType={DeleteChannelModal}
|
||||||
|
dialogProps={{channel}}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_header.delete'
|
||||||
|
defaultMessage='Delete {term}...'
|
||||||
|
values={{
|
||||||
|
term: (channelTerm)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ToggleModalButton>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const canLeave = channel.type === Constants.PRIVATE_CHANNEL ? this.state.userCount > 1 : true;
|
||||||
|
if (!ChannelStore.isDefault(channel) && canLeave) {
|
||||||
|
leaveChannelOption = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={this.handleLeave}
|
||||||
|
>
|
||||||
|
<FormattedMessage
|
||||||
|
id='channel_header.leave'
|
||||||
|
defaultMessage='Leave {term}'
|
||||||
|
values={{
|
||||||
|
term: (channelTerm)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -419,6 +480,7 @@ export default class Navbar extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
createCollapseButtons(currentId) {
|
createCollapseButtons(currentId) {
|
||||||
var buttons = [];
|
var buttons = [];
|
||||||
if (currentId == null) {
|
if (currentId == null) {
|
||||||
@@ -505,6 +567,7 @@ export default class Navbar extends React.Component {
|
|||||||
var channelTitle = this.props.teamDisplayName;
|
var channelTitle = this.props.teamDisplayName;
|
||||||
var popoverContent;
|
var popoverContent;
|
||||||
var isAdmin = false;
|
var isAdmin = false;
|
||||||
|
var isSystemAdmin = false;
|
||||||
var isDirect = false;
|
var isDirect = false;
|
||||||
|
|
||||||
var editChannelHeaderModal = null;
|
var editChannelHeaderModal = null;
|
||||||
@@ -527,7 +590,8 @@ export default class Navbar extends React.Component {
|
|||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
|
|
||||||
isAdmin = Utils.isAdmin(this.state.member.roles) || TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
isAdmin = TeamStore.isTeamAdminForCurrentTeam() || UserStore.isSystemAdminForCurrentUser();
|
||||||
|
isSystemAdmin = UserStore.isSystemAdminForCurrentUser();
|
||||||
|
|
||||||
if (channel.type === 'O') {
|
if (channel.type === 'O') {
|
||||||
channelTitle = channel.display_name;
|
channelTitle = channel.display_name;
|
||||||
@@ -632,7 +696,7 @@ export default class Navbar extends React.Component {
|
|||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
var channelMenuDropdown = this.createDropdown(channel, channelTitle, isAdmin, isDirect, popoverContent);
|
var channelMenuDropdown = this.createDropdown(channel, channelTitle, isAdmin, isSystemAdmin, isDirect, popoverContent);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user