Allow admins to change the display name for the default channel
Этот коммит содержится в:
@@ -205,9 +205,11 @@ func updateChannel(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if oldChannel.Name == model.DEFAULT_CHANNEL {
|
if oldChannel.Name == model.DEFAULT_CHANNEL {
|
||||||
c.Err = model.NewAppError("updateChannel", "Cannot update the default channel "+model.DEFAULT_CHANNEL, "")
|
if (len(channel.Name) > 0 && channel.Name != oldChannel.Name) || (len(channel.Type) > 0 && channel.Type != oldChannel.Type) {
|
||||||
c.Err.StatusCode = http.StatusForbidden
|
c.Err = model.NewAppError("updateChannel", "Tried to perform an invalid update of the default channel "+model.DEFAULT_CHANNEL, "")
|
||||||
return
|
c.Err.StatusCode = http.StatusForbidden
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
oldChannel.Header = channel.Header
|
oldChannel.Header = channel.Header
|
||||||
|
|||||||
@@ -276,26 +276,27 @@ export default class ChannelHeader extends React.Component {
|
|||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!ChannelStore.isDefault(channel)) {
|
if (isAdmin) {
|
||||||
if (isAdmin) {
|
dropdownContents.push(
|
||||||
dropdownContents.push(
|
<li
|
||||||
<li
|
key='rename_channel'
|
||||||
key='rename_channel'
|
role='presentation'
|
||||||
role='presentation'
|
>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
data-toggle='modal'
|
||||||
|
data-target='#rename_channel'
|
||||||
|
data-display={channel.display_name}
|
||||||
|
data-name={channel.name}
|
||||||
|
data-channelid={channel.id}
|
||||||
>
|
>
|
||||||
<a
|
{'Rename '}{channelTerm}{'...'}
|
||||||
role='menuitem'
|
</a>
|
||||||
href='#'
|
</li>
|
||||||
data-toggle='modal'
|
);
|
||||||
data-target='#rename_channel'
|
|
||||||
data-display={channel.display_name}
|
if (!ChannelStore.isDefault(channel)) {
|
||||||
data-name={channel.name}
|
|
||||||
data-channelid={channel.id}
|
|
||||||
>
|
|
||||||
{'Rename '}{channelTerm}{'...'}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
dropdownContents.push(
|
dropdownContents.push(
|
||||||
<li
|
<li
|
||||||
key='delete_channel'
|
key='delete_channel'
|
||||||
@@ -314,7 +315,9 @@ export default class ChannelHeader extends React.Component {
|
|||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ChannelStore.isDefault(channel)) {
|
||||||
dropdownContents.push(
|
dropdownContents.push(
|
||||||
<li
|
<li
|
||||||
key='leave_channel'
|
key='leave_channel'
|
||||||
|
|||||||
@@ -178,18 +178,35 @@ export default class Navbar extends React.Component {
|
|||||||
var manageMembersOption;
|
var manageMembersOption;
|
||||||
var renameChannelOption;
|
var renameChannelOption;
|
||||||
var deleteChannelOption;
|
var deleteChannelOption;
|
||||||
if (!isDirect && isAdmin && !ChannelStore.isDefault(channel)) {
|
if (!isDirect && isAdmin) {
|
||||||
manageMembersOption = (
|
if (!ChannelStore.isDefault(channel)) {
|
||||||
<li role='presentation'>
|
manageMembersOption = (
|
||||||
<a
|
<li role='presentation'>
|
||||||
role='menuitem'
|
<a
|
||||||
href='#'
|
role='menuitem'
|
||||||
onClick={() => this.setState({showMembersModal: true})}
|
href='#'
|
||||||
>
|
onClick={() => this.setState({showMembersModal: true})}
|
||||||
{'Manage Members'}
|
>
|
||||||
</a>
|
{'Manage Members'}
|
||||||
</li>
|
</a>
|
||||||
);
|
</li>
|
||||||
|
);
|
||||||
|
|
||||||
|
deleteChannelOption = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
data-toggle='modal'
|
||||||
|
data-target='#delete_channel'
|
||||||
|
data-title={channel.display_name}
|
||||||
|
data-channelid={channel.id}
|
||||||
|
>
|
||||||
|
{'Delete Channel...'}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
renameChannelOption = (
|
renameChannelOption = (
|
||||||
<li role='presentation'>
|
<li role='presentation'>
|
||||||
@@ -206,21 +223,6 @@ export default class Navbar extends React.Component {
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|
||||||
deleteChannelOption = (
|
|
||||||
<li role='presentation'>
|
|
||||||
<a
|
|
||||||
role='menuitem'
|
|
||||||
href='#'
|
|
||||||
data-toggle='modal'
|
|
||||||
data-target='#delete_channel'
|
|
||||||
data-title={channel.display_name}
|
|
||||||
data-channelid={channel.id}
|
|
||||||
>
|
|
||||||
{'Delete Channel...'}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var notificationPreferenceOption;
|
var notificationPreferenceOption;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const Utils = require('../utils/utils.jsx');
|
|||||||
const Client = require('../utils/client.jsx');
|
const Client = require('../utils/client.jsx');
|
||||||
const AsyncClient = require('../utils/async_client.jsx');
|
const AsyncClient = require('../utils/async_client.jsx');
|
||||||
const ChannelStore = require('../stores/channel_store.jsx');
|
const ChannelStore = require('../stores/channel_store.jsx');
|
||||||
|
const Constants = require('../utils/constants.jsx');
|
||||||
|
|
||||||
export default class RenameChannelModal extends React.Component {
|
export default class RenameChannelModal extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -36,10 +37,10 @@ export default class RenameChannelModal extends React.Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let channel = ChannelStore.get(this.state.channelId);
|
const channel = ChannelStore.get(this.state.channelId);
|
||||||
const oldName = channel.name;
|
const oldName = channel.name;
|
||||||
const oldDisplayName = channel.displayName;
|
const oldDisplayName = channel.displayName;
|
||||||
let state = {serverError: ''};
|
const state = {serverError: ''};
|
||||||
|
|
||||||
channel.display_name = this.state.displayName.trim();
|
channel.display_name = this.state.displayName.trim();
|
||||||
if (!channel.display_name) {
|
if (!channel.display_name) {
|
||||||
@@ -60,7 +61,7 @@ export default class RenameChannelModal extends React.Component {
|
|||||||
state.nameError = 'This field must be less than 22 characters';
|
state.nameError = 'This field must be less than 22 characters';
|
||||||
state.invalid = true;
|
state.invalid = true;
|
||||||
} else {
|
} else {
|
||||||
let cleanedName = Utils.cleanUpUrlable(channel.name);
|
const cleanedName = Utils.cleanUpUrlable(channel.name);
|
||||||
if (cleanedName === channel.name) {
|
if (cleanedName === channel.name) {
|
||||||
state.nameError = '';
|
state.nameError = '';
|
||||||
} else {
|
} else {
|
||||||
@@ -76,7 +77,7 @@ export default class RenameChannelModal extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Client.updateChannel(channel,
|
Client.updateChannel(channel,
|
||||||
function handleUpdateSuccess() {
|
() => {
|
||||||
$(ReactDOM.findDOMNode(this.refs.modal)).modal('hide');
|
$(ReactDOM.findDOMNode(this.refs.modal)).modal('hide');
|
||||||
|
|
||||||
AsyncClient.getChannel(channel.id);
|
AsyncClient.getChannel(channel.id);
|
||||||
@@ -84,12 +85,12 @@ export default class RenameChannelModal extends React.Component {
|
|||||||
|
|
||||||
ReactDOM.findDOMNode(this.refs.displayName).value = '';
|
ReactDOM.findDOMNode(this.refs.displayName).value = '';
|
||||||
ReactDOM.findDOMNode(this.refs.channelName).value = '';
|
ReactDOM.findDOMNode(this.refs.channelName).value = '';
|
||||||
}.bind(this),
|
},
|
||||||
function handleUpdateError(err) {
|
(err) => {
|
||||||
state.serverError = err.message;
|
state.serverError = err.message;
|
||||||
state.invalid = true;
|
state.invalid = true;
|
||||||
this.setState(state);
|
this.setState(state);
|
||||||
}.bind(this)
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
onNameChange() {
|
onNameChange() {
|
||||||
@@ -99,10 +100,12 @@ export default class RenameChannelModal extends React.Component {
|
|||||||
this.setState({displayName: ReactDOM.findDOMNode(this.refs.displayName).value});
|
this.setState({displayName: ReactDOM.findDOMNode(this.refs.displayName).value});
|
||||||
}
|
}
|
||||||
displayNameKeyUp() {
|
displayNameKeyUp() {
|
||||||
const displayName = ReactDOM.findDOMNode(this.refs.displayName).value.trim();
|
if (this.state.channelName !== Constants.DEFAULT_CHANNEL) {
|
||||||
const channelName = Utils.cleanUpUrlable(displayName);
|
const displayName = ReactDOM.findDOMNode(this.refs.displayName).value.trim();
|
||||||
ReactDOM.findDOMNode(this.refs.channelName).value = channelName;
|
const channelName = Utils.cleanUpUrlable(displayName);
|
||||||
this.setState({channelName: channelName});
|
ReactDOM.findDOMNode(this.refs.channelName).value = channelName;
|
||||||
|
this.setState({channelName: channelName});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
handleClose() {
|
handleClose() {
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -150,6 +153,15 @@ export default class RenameChannelModal extends React.Component {
|
|||||||
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
|
serverError = <div className='form-group has-error'><label className='control-label'>{this.state.serverError}</label></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let handleInputLabel = 'Handle';
|
||||||
|
let handleInputClass = 'form-control';
|
||||||
|
let readOnlyHandleInput = false;
|
||||||
|
if (this.state.channelName === Constants.DEFAULT_CHANNEL) {
|
||||||
|
handleInputLabel += ' - Cannot be changed for the default channel';
|
||||||
|
handleInputClass += ' disabled-input';
|
||||||
|
readOnlyHandleInput = true;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className='modal fade'
|
className='modal fade'
|
||||||
@@ -167,15 +179,15 @@ export default class RenameChannelModal extends React.Component {
|
|||||||
className='close'
|
className='close'
|
||||||
data-dismiss='modal'
|
data-dismiss='modal'
|
||||||
>
|
>
|
||||||
<span aria-hidden='true'>×</span>
|
<span aria-hidden='true'>{'×'}</span>
|
||||||
<span className='sr-only'>Close</span>
|
<span className='sr-only'>{'Close'}</span>
|
||||||
</button>
|
</button>
|
||||||
<h4 className='modal-title'>Rename Channel</h4>
|
<h4 className='modal-title'>{'Rename Channel'}</h4>
|
||||||
</div>
|
</div>
|
||||||
<form role='form'>
|
<form role='form'>
|
||||||
<div className='modal-body'>
|
<div className='modal-body'>
|
||||||
<div className={displayNameClass}>
|
<div className={displayNameClass}>
|
||||||
<label className='control-label'>Display Name</label>
|
<label className='control-label'>{'Display Name'}</label>
|
||||||
<input
|
<input
|
||||||
onKeyUp={this.displayNameKeyUp}
|
onKeyUp={this.displayNameKeyUp}
|
||||||
onChange={this.onDisplayNameChange}
|
onChange={this.onDisplayNameChange}
|
||||||
@@ -190,15 +202,16 @@ export default class RenameChannelModal extends React.Component {
|
|||||||
{displayNameError}
|
{displayNameError}
|
||||||
</div>
|
</div>
|
||||||
<div className={nameClass}>
|
<div className={nameClass}>
|
||||||
<label className='control-label'>Handle</label>
|
<label className='control-label'>{handleInputLabel}</label>
|
||||||
<input
|
<input
|
||||||
onChange={this.onNameChange}
|
onChange={this.onNameChange}
|
||||||
type='text'
|
type='text'
|
||||||
className='form-control'
|
className={handleInputClass}
|
||||||
ref='channelName'
|
ref='channelName'
|
||||||
placeholder='lowercase alphanumeric's only'
|
placeholder='lowercase alphanumeric's only'
|
||||||
value={this.state.channelName}
|
value={this.state.channelName}
|
||||||
maxLength='64'
|
maxLength='64'
|
||||||
|
readOnly={readOnlyHandleInput}
|
||||||
/>
|
/>
|
||||||
{nameError}
|
{nameError}
|
||||||
</div>
|
</div>
|
||||||
@@ -210,14 +223,14 @@ export default class RenameChannelModal extends React.Component {
|
|||||||
className='btn btn-default'
|
className='btn btn-default'
|
||||||
data-dismiss='modal'
|
data-dismiss='modal'
|
||||||
>
|
>
|
||||||
Cancel
|
{'Cancel'}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={this.handleSubmit}
|
onClick={this.handleSubmit}
|
||||||
type='submit'
|
type='submit'
|
||||||
className='btn btn-primary'
|
className='btn btn-primary'
|
||||||
>
|
>
|
||||||
Save
|
{'Save'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -43,3 +43,7 @@
|
|||||||
margin: 10px 0 0;
|
margin: 10px 0 0;
|
||||||
color: #999;
|
color: #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.disabled-input {
|
||||||
|
background-color: #dddddd !important;
|
||||||
|
}
|
||||||
Ссылка в новой задаче
Block a user