Added ability to see/edit channel purpose in the client
Этот коммит содержится в:
@@ -11,6 +11,7 @@ const TextFormatting = require('../utils/text_formatting.jsx');
|
|||||||
const Utils = require('../utils/utils.jsx');
|
const Utils = require('../utils/utils.jsx');
|
||||||
const MessageWrapper = require('./message_wrapper.jsx');
|
const MessageWrapper = require('./message_wrapper.jsx');
|
||||||
const PopoverListMembers = require('./popover_list_members.jsx');
|
const PopoverListMembers = require('./popover_list_members.jsx');
|
||||||
|
const EditChannelPurposeModal = require('./edit_channel_purpose_modal.jsx');
|
||||||
|
|
||||||
const AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
|
const AppDispatcher = require('../dispatcher/app_dispatcher.jsx');
|
||||||
const Constants = require('../utils/constants.jsx');
|
const Constants = require('../utils/constants.jsx');
|
||||||
@@ -27,7 +28,9 @@ export default class ChannelHeader extends React.Component {
|
|||||||
this.handleLeave = this.handleLeave.bind(this);
|
this.handleLeave = this.handleLeave.bind(this);
|
||||||
this.searchMentions = this.searchMentions.bind(this);
|
this.searchMentions = this.searchMentions.bind(this);
|
||||||
|
|
||||||
this.state = this.getStateFromStores();
|
const state = this.getStateFromStores();
|
||||||
|
state.showEditChannelPurposeModal = false;
|
||||||
|
this.state = state;
|
||||||
}
|
}
|
||||||
getStateFromStores() {
|
getStateFromStores() {
|
||||||
return {
|
return {
|
||||||
@@ -232,6 +235,20 @@ export default class ChannelHeader extends React.Component {
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
dropdownContents.push(
|
||||||
|
<li
|
||||||
|
key='set_channel_purpose'
|
||||||
|
role='presentation'
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={() => this.setState({showEditChannelPurposeModal: true})}
|
||||||
|
>
|
||||||
|
Set {channelTerm} Purpose...
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
dropdownContents.push(
|
dropdownContents.push(
|
||||||
<li
|
<li
|
||||||
key='notification_preferences'
|
key='notification_preferences'
|
||||||
@@ -307,84 +324,91 @@ export default class ChannelHeader extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<table className='channel-header alt'>
|
<div>
|
||||||
<tbody>
|
<table className='channel-header alt'>
|
||||||
<tr>
|
<tbody>
|
||||||
<th>
|
<tr>
|
||||||
<div className='channel-header__info'>
|
<th>
|
||||||
<div className='dropdown'>
|
<div className='channel-header__info'>
|
||||||
|
<div className='dropdown'>
|
||||||
|
<a
|
||||||
|
href='#'
|
||||||
|
className='dropdown-toggle theme'
|
||||||
|
type='button'
|
||||||
|
id='channel_header_dropdown'
|
||||||
|
data-toggle='dropdown'
|
||||||
|
aria-expanded='true'
|
||||||
|
>
|
||||||
|
<strong className='heading'>{channelTitle} </strong>
|
||||||
|
<span className='glyphicon glyphicon-chevron-down header-dropdown__icon' />
|
||||||
|
</a>
|
||||||
|
<ul
|
||||||
|
className='dropdown-menu'
|
||||||
|
role='menu'
|
||||||
|
aria-labelledby='channel_header_dropdown'
|
||||||
|
>
|
||||||
|
{dropdownContents}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<OverlayTrigger
|
||||||
|
trigger={['hover', 'focus']}
|
||||||
|
placement='bottom'
|
||||||
|
overlay={popoverContent}
|
||||||
|
ref='headerOverlay'
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
onClick={TextFormatting.handleClick}
|
||||||
|
className='description'
|
||||||
|
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(channel.header, {singleline: true, mentionHighlight: false})}}
|
||||||
|
/>
|
||||||
|
</OverlayTrigger>
|
||||||
|
</div>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<PopoverListMembers
|
||||||
|
members={this.state.users}
|
||||||
|
channelId={channel.id}
|
||||||
|
/>
|
||||||
|
</th>
|
||||||
|
<th className='search-bar__container'><NavbarSearchBox /></th>
|
||||||
|
<th>
|
||||||
|
<div className='dropdown channel-header__links'>
|
||||||
<a
|
<a
|
||||||
href='#'
|
href='#'
|
||||||
className='dropdown-toggle theme'
|
className='dropdown-toggle theme'
|
||||||
type='button'
|
type='button'
|
||||||
id='channel_header_dropdown'
|
id='channel_header_right_dropdown'
|
||||||
data-toggle='dropdown'
|
data-toggle='dropdown'
|
||||||
aria-expanded='true'
|
aria-expanded='true'
|
||||||
>
|
>
|
||||||
<strong className='heading'>{channelTitle} </strong>
|
<span dangerouslySetInnerHTML={{__html: Constants.MENU_ICON}} />
|
||||||
<span className='glyphicon glyphicon-chevron-down header-dropdown__icon' />
|
|
||||||
</a>
|
</a>
|
||||||
<ul
|
<ul
|
||||||
className='dropdown-menu'
|
className='dropdown-menu dropdown-menu-right'
|
||||||
role='menu'
|
role='menu'
|
||||||
aria-labelledby='channel_header_dropdown'
|
aria-labelledby='channel_header_right_dropdown'
|
||||||
>
|
>
|
||||||
{dropdownContents}
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={this.searchMentions}
|
||||||
|
>
|
||||||
|
Recent Mentions
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<OverlayTrigger
|
</th>
|
||||||
trigger={['hover', 'focus']}
|
</tr>
|
||||||
placement='bottom'
|
</tbody>
|
||||||
overlay={popoverContent}
|
</table>
|
||||||
ref='headerOverlay'
|
<EditChannelPurposeModal
|
||||||
>
|
show={this.state.showEditChannelPurposeModal}
|
||||||
<div
|
onModalDismissed={() => this.setState({showEditChannelPurposeModal: false})}
|
||||||
onClick={TextFormatting.handleClick}
|
channel={channel}
|
||||||
className='description'
|
/>
|
||||||
dangerouslySetInnerHTML={{__html: TextFormatting.formatText(channel.header, {singleline: true, mentionHighlight: false})}}
|
</div>
|
||||||
/>
|
|
||||||
</OverlayTrigger>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
<th>
|
|
||||||
<PopoverListMembers
|
|
||||||
members={this.state.users}
|
|
||||||
channelId={channel.id}
|
|
||||||
/>
|
|
||||||
</th>
|
|
||||||
<th className='search-bar__container'><NavbarSearchBox /></th>
|
|
||||||
<th>
|
|
||||||
<div className='dropdown channel-header__links'>
|
|
||||||
<a
|
|
||||||
href='#'
|
|
||||||
className='dropdown-toggle theme'
|
|
||||||
type='button'
|
|
||||||
id='channel_header_right_dropdown'
|
|
||||||
data-toggle='dropdown'
|
|
||||||
aria-expanded='true'
|
|
||||||
>
|
|
||||||
<span dangerouslySetInnerHTML={{__html: Constants.MENU_ICON}} />
|
|
||||||
</a>
|
|
||||||
<ul
|
|
||||||
className='dropdown-menu dropdown-menu-right'
|
|
||||||
role='menu'
|
|
||||||
aria-labelledby='channel_header_right_dropdown'
|
|
||||||
>
|
|
||||||
<li role='presentation'>
|
|
||||||
<a
|
|
||||||
role='menuitem'
|
|
||||||
href='#'
|
|
||||||
onClick={this.searchMentions}
|
|
||||||
>
|
|
||||||
Recent Mentions
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
118
web/react/components/edit_channel_purpose_modal.jsx
Обычный файл
118
web/react/components/edit_channel_purpose_modal.jsx
Обычный файл
@@ -0,0 +1,118 @@
|
|||||||
|
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
const AsyncClient = require('../utils/async_client.jsx');
|
||||||
|
const Client = require('../utils/client.jsx');
|
||||||
|
const Modal = ReactBootstrap.Modal;
|
||||||
|
|
||||||
|
export default class EditChannelPurposeModal extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.handleHide = this.handleHide.bind(this);
|
||||||
|
this.handleSave = this.handleSave.bind(this);
|
||||||
|
|
||||||
|
this.state = {serverError: ''};
|
||||||
|
}
|
||||||
|
|
||||||
|
handleHide() {
|
||||||
|
this.setState({serverError: ''});
|
||||||
|
|
||||||
|
if (this.props.onModalDismissed) {
|
||||||
|
this.props.onModalDismissed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSave() {
|
||||||
|
if (!this.props.channel) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
channel_id: this.props.channel.id,
|
||||||
|
channel_purpose: ReactDOM.findDOMNode(this.refs.purpose).value.trim()
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.updateChannelPurpose(data,
|
||||||
|
() => {
|
||||||
|
AsyncClient.getChannel(this.props.channel.id);
|
||||||
|
|
||||||
|
this.handleHide();
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
if (err.message === 'Invalid channel_purpose parameter') {
|
||||||
|
this.setState({serverError: 'This channel purpose is too long, please enter a shorter one'});
|
||||||
|
} else {
|
||||||
|
this.setState({serverError: err.message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (!this.props.show) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let serverError = null;
|
||||||
|
if (this.state.serverError) {
|
||||||
|
serverError = (
|
||||||
|
<div className='form-group has-error'>
|
||||||
|
<br/>
|
||||||
|
<label className='control-label'>{this.state.serverError}</label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let title = <span>{'Edit Purpose'}</span>;
|
||||||
|
if (this.props.channel.display_name) {
|
||||||
|
title = <span>{'Edit Purpose for '}<span className='name'>{this.props.channel.display_name}</span></span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
className='modal-edit-channel-purpose'
|
||||||
|
show={this.props.show}
|
||||||
|
onHide={this.handleHide}
|
||||||
|
>
|
||||||
|
<Modal.Header closeButton={true}>
|
||||||
|
<Modal.Title>
|
||||||
|
{title}
|
||||||
|
</Modal.Title>
|
||||||
|
</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<textarea
|
||||||
|
ref='purpose'
|
||||||
|
className='form-control no-resize'
|
||||||
|
rows='6'
|
||||||
|
maxLength='128'
|
||||||
|
defaultValue={this.props.channel.purpose}
|
||||||
|
/>
|
||||||
|
{serverError}
|
||||||
|
</Modal.Body>
|
||||||
|
<Modal.Footer>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='btn btn-default'
|
||||||
|
onClick={this.handleHide}
|
||||||
|
>
|
||||||
|
{'Cancel'}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='btn btn-primary'
|
||||||
|
onClick={this.handleSave}
|
||||||
|
>
|
||||||
|
{'Save'}
|
||||||
|
</button>
|
||||||
|
</Modal.Footer>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EditChannelPurposeModal.propTypes = {
|
||||||
|
show: React.PropTypes.bool.isRequired,
|
||||||
|
channel: React.PropTypes.object,
|
||||||
|
onModalDismissed: React.PropTypes.func.isRequired
|
||||||
|
};
|
||||||
@@ -105,12 +105,11 @@ export default class MoreChannels extends React.Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Switch channel.header to channel.purpose once that has been added
|
|
||||||
return (
|
return (
|
||||||
<tr key={channel.id}>
|
<tr key={channel.id}>
|
||||||
<td>
|
<td>
|
||||||
<p className='more-name'>{channel.display_name}</p>
|
<p className='more-name'>{channel.display_name}</p>
|
||||||
<p className='more-header'>{channel.header}</p>
|
<p className='more-purpose'>{channel.purpose}</p>
|
||||||
</td>
|
</td>
|
||||||
<td className='td--action'>
|
<td className='td--action'>
|
||||||
{joinButton}
|
{joinButton}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ var ChannelStore = require('../stores/channel_store.jsx');
|
|||||||
var TeamStore = require('../stores/team_store.jsx');
|
var TeamStore = require('../stores/team_store.jsx');
|
||||||
var MessageWrapper = require('./message_wrapper.jsx');
|
var MessageWrapper = require('./message_wrapper.jsx');
|
||||||
var NotifyCounts = require('./notify_counts.jsx');
|
var NotifyCounts = require('./notify_counts.jsx');
|
||||||
|
const EditChannelPurposeModal = require('./edit_channel_purpose_modal.jsx');
|
||||||
const Utils = require('../utils/utils.jsx');
|
const Utils = require('../utils/utils.jsx');
|
||||||
|
|
||||||
var Constants = require('../utils/constants.jsx');
|
var Constants = require('../utils/constants.jsx');
|
||||||
@@ -26,7 +27,9 @@ export default class Navbar extends React.Component {
|
|||||||
this.createCollapseButtons = this.createCollapseButtons.bind(this);
|
this.createCollapseButtons = this.createCollapseButtons.bind(this);
|
||||||
this.createDropdown = this.createDropdown.bind(this);
|
this.createDropdown = this.createDropdown.bind(this);
|
||||||
|
|
||||||
this.state = this.getStateFromStores();
|
const state = this.getStateFromStores();
|
||||||
|
state.showEditChannelPurposeModal = false;
|
||||||
|
this.state = state;
|
||||||
}
|
}
|
||||||
getStateFromStores() {
|
getStateFromStores() {
|
||||||
return {
|
return {
|
||||||
@@ -122,6 +125,19 @@ export default class Navbar extends React.Component {
|
|||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
var setChannelPurposeOption = null;
|
||||||
|
if (!isDirect) {
|
||||||
|
setChannelPurposeOption = (
|
||||||
|
<li role='presentation'>
|
||||||
|
<a
|
||||||
|
role='menuitem'
|
||||||
|
href='#'
|
||||||
|
onClick={() => this.setState({showEditChannelPurposeModal: true})}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var addMembersOption;
|
var addMembersOption;
|
||||||
var leaveChannelOption;
|
var leaveChannelOption;
|
||||||
if (!isDirect && !ChannelStore.isDefault(channel)) {
|
if (!isDirect && !ChannelStore.isDefault(channel)) {
|
||||||
@@ -250,6 +266,7 @@ export default class Navbar extends React.Component {
|
|||||||
{addMembersOption}
|
{addMembersOption}
|
||||||
{manageMembersOption}
|
{manageMembersOption}
|
||||||
{setChannelHeaderOption}
|
{setChannelHeaderOption}
|
||||||
|
{setChannelPurposeOption}
|
||||||
{notificationPreferenceOption}
|
{notificationPreferenceOption}
|
||||||
{renameChannelOption}
|
{renameChannelOption}
|
||||||
{deleteChannelOption}
|
{deleteChannelOption}
|
||||||
@@ -392,17 +409,24 @@ export default class Navbar extends React.Component {
|
|||||||
var channelMenuDropdown = this.createDropdown(channel, channelTitle, isAdmin, isDirect, popoverContent);
|
var channelMenuDropdown = this.createDropdown(channel, channelTitle, isAdmin, isDirect, popoverContent);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav
|
<div>
|
||||||
className='navbar navbar-default navbar-fixed-top'
|
<nav
|
||||||
role='navigation'
|
className='navbar navbar-default navbar-fixed-top'
|
||||||
>
|
role='navigation'
|
||||||
<div className='container-fluid theme'>
|
>
|
||||||
<div className='navbar-header'>
|
<div className='container-fluid theme'>
|
||||||
{collapseButtons}
|
<div className='navbar-header'>
|
||||||
{channelMenuDropdown}
|
{collapseButtons}
|
||||||
|
{channelMenuDropdown}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
</nav>
|
<EditChannelPurposeModal
|
||||||
|
show={this.state.showEditChannelPurposeModal}
|
||||||
|
onModalDismissed={() => this.setState({showEditChannelPurposeModal: false})}
|
||||||
|
channel={channel}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export default class NewChannelFlow extends React.Component {
|
|||||||
flowState: SHOW_NEW_CHANNEL,
|
flowState: SHOW_NEW_CHANNEL,
|
||||||
channelDisplayName: '',
|
channelDisplayName: '',
|
||||||
channelName: '',
|
channelName: '',
|
||||||
channelHeader: '',
|
channelPurpose: '',
|
||||||
nameModified: false
|
nameModified: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ export default class NewChannelFlow extends React.Component {
|
|||||||
flowState: SHOW_NEW_CHANNEL,
|
flowState: SHOW_NEW_CHANNEL,
|
||||||
channelDisplayName: '',
|
channelDisplayName: '',
|
||||||
channelName: '',
|
channelName: '',
|
||||||
channelHeader: '',
|
channelPurpose: '',
|
||||||
nameModified: false
|
nameModified: false
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ export default class NewChannelFlow extends React.Component {
|
|||||||
|
|
||||||
const cu = UserStore.getCurrentUser();
|
const cu = UserStore.getCurrentUser();
|
||||||
channel.team_id = cu.team_id;
|
channel.team_id = cu.team_id;
|
||||||
channel.header = this.state.channelHeader;
|
channel.purpose = this.state.channelPurpose;
|
||||||
channel.type = this.state.channelType;
|
channel.type = this.state.channelType;
|
||||||
|
|
||||||
Client.createChannel(channel,
|
Client.createChannel(channel,
|
||||||
@@ -109,7 +109,7 @@ export default class NewChannelFlow extends React.Component {
|
|||||||
channelDataChanged(data) {
|
channelDataChanged(data) {
|
||||||
this.setState({
|
this.setState({
|
||||||
channelDisplayName: data.displayName,
|
channelDisplayName: data.displayName,
|
||||||
channelHeader: data.header
|
channelPurpose: data.purpose
|
||||||
});
|
});
|
||||||
if (!this.state.nameModified) {
|
if (!this.state.nameModified) {
|
||||||
this.setState({channelName: Utils.cleanUpUrlable(data.displayName.trim())});
|
this.setState({channelName: Utils.cleanUpUrlable(data.displayName.trim())});
|
||||||
@@ -119,7 +119,7 @@ export default class NewChannelFlow extends React.Component {
|
|||||||
const channelData = {
|
const channelData = {
|
||||||
name: this.state.channelName,
|
name: this.state.channelName,
|
||||||
displayName: this.state.channelDisplayName,
|
displayName: this.state.channelDisplayName,
|
||||||
header: this.state.channelHeader
|
purpose: this.state.channelPurpose
|
||||||
};
|
};
|
||||||
|
|
||||||
let showChannelModal = false;
|
let showChannelModal = false;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export default class NewChannelModal extends React.Component {
|
|||||||
handleChange() {
|
handleChange() {
|
||||||
const newData = {
|
const newData = {
|
||||||
displayName: ReactDOM.findDOMNode(this.refs.display_name).value,
|
displayName: ReactDOM.findDOMNode(this.refs.display_name).value,
|
||||||
header: ReactDOM.findDOMNode(this.refs.channel_header).value
|
purpose: ReactDOM.findDOMNode(this.refs.channel_purpose).value
|
||||||
};
|
};
|
||||||
this.props.onDataChanged(newData);
|
this.props.onDataChanged(newData);
|
||||||
}
|
}
|
||||||
@@ -136,22 +136,22 @@ export default class NewChannelModal extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<div className='form-group less'>
|
<div className='form-group less'>
|
||||||
<div className='col-sm-3'>
|
<div className='col-sm-3'>
|
||||||
<label className='form__label control-label'>{'Header'}</label>
|
<label className='form__label control-label'>{'Purpose'}</label>
|
||||||
<label className='form__label light'>{'(optional)'}</label>
|
<label className='form__label light'>{'(optional)'}</label>
|
||||||
</div>
|
</div>
|
||||||
<div className='col-sm-9'>
|
<div className='col-sm-9'>
|
||||||
<textarea
|
<textarea
|
||||||
className='form-control no-resize'
|
className='form-control no-resize'
|
||||||
ref='channel_header'
|
ref='channel_purpose'
|
||||||
rows='4'
|
rows='4'
|
||||||
placeholder='Header'
|
placeholder='Purpose'
|
||||||
maxLength='1024'
|
maxLength='128'
|
||||||
value={this.props.channelData.header}
|
value={this.props.channelData.purpose}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
tabIndex='2'
|
tabIndex='2'
|
||||||
/>
|
/>
|
||||||
<p className='input__help'>
|
<p className='input__help'>
|
||||||
{'This text is shown in the channel header and supports markdown formatting.'}
|
{`Describe how this ${channelTerm} should be used.`}
|
||||||
</p>
|
</p>
|
||||||
{serverError}
|
{serverError}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -592,6 +592,23 @@ export function updateChannelHeader(data, success, error) {
|
|||||||
track('api', 'api_channels_header');
|
track('api', 'api_channels_header');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateChannelPurpose(data, success, error) {
|
||||||
|
$.ajax({
|
||||||
|
url: '/api/v1/channels/update_purpose',
|
||||||
|
dataType: 'json',
|
||||||
|
contentType: 'application/json',
|
||||||
|
type: 'POST',
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
success,
|
||||||
|
error: function onError(xhr, status, err) {
|
||||||
|
var e = handleError('updateChannelPurpose', xhr, status, err);
|
||||||
|
error(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
track('api', 'api_channels_purpose');
|
||||||
|
}
|
||||||
|
|
||||||
export function updateNotifyProps(data, success, error) {
|
export function updateNotifyProps(data, success, error) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '/api/v1/channels/update_notify_props',
|
url: '/api/v1/channels/update_notify_props',
|
||||||
|
|||||||
@@ -377,7 +377,7 @@
|
|||||||
@include opacity(0.8);
|
@include opacity(0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-header {
|
.more-purpose {
|
||||||
@include opacity(0.7);
|
@include opacity(0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user