Этот коммит содержится в:
Asaad Mahmood
2015-10-23 19:59:32 +05:00
родитель 546583dea2
Коммит db4273d357
10 изменённых файлов: 172 добавлений и 90 удалений

Просмотреть файл

@@ -2,6 +2,10 @@
// See License.txt for license information. // See License.txt for license information.
export default class SettingsSidebar extends React.Component { export default class SettingsSidebar extends React.Component {
componentDidUpdate() {
$('.settings-modal').find('.modal-body').scrollTop(0);
$('.settings-modal').find('.modal-body').perfectScrollbar('update');
}
constructor(props) { constructor(props) {
super(props); super(props);

Просмотреть файл

@@ -19,6 +19,7 @@ export default class TeamSettingsModal extends React.Component {
componentDidMount() { componentDidMount() {
$('body').on('click', '.modal-back', function handleBackClick() { $('body').on('click', '.modal-back', function handleBackClick() {
$(this).closest('.modal-dialog').removeClass('display--content'); $(this).closest('.modal-dialog').removeClass('display--content');
$(this).closest('.modal-dialog').find('.settings-table .nav li.active').removeClass('active');
}); });
$('body').on('click', '.modal-header .close', () => { $('body').on('click', '.modal-header .close', () => {
setTimeout(() => { setTimeout(() => {

Просмотреть файл

@@ -119,24 +119,23 @@ export default class ManageIncomingHooks extends React.Component {
hooks.push( hooks.push(
<div <div
key={hook.id} key={hook.id}
className='font--small' className='webhook__item'
> >
<div className='padding-top x2 divider-light'></div> <div className='padding-top x2 webhook__url'>
<div className='padding-top x2'> <strong>{'URL: '}</strong>
<strong>{'URL: '}</strong><span className='word-break--all'>{Utils.getWindowLocationOrigin() + '/hooks/' + hook.id}</span> <span className='word-break--all'>{Utils.getWindowLocationOrigin() + '/hooks/' + hook.id}</span>
</div> </div>
<div className='padding-top'> <div className='padding-top'>
<strong>{'Channel: '}</strong>{c.display_name} <strong>{'Channel: '}</strong>{c.display_name}
</div> </div>
<div className='padding-top'>
<a <a
className={'text-danger'} className={'webhook__remove'}
href='#' href='#'
onClick={this.removeHook.bind(this, hook.id)} onClick={this.removeHook.bind(this, hook.id)}
> >
{'Remove'} <span aria-hidden='true'>{'×'}</span>
</a> </a>
</div> <div className='padding-top x2 divider-light'></div>
</div> </div>
); );
} }
@@ -148,23 +147,25 @@ export default class ManageIncomingHooks extends React.Component {
} else if (hooks.length > 0) { } else if (hooks.length > 0) {
displayHooks = hooks; displayHooks = hooks;
} else { } else {
displayHooks = <label>{': None'}</label>; displayHooks = <div className='padding-top x2'>{'None'}</div>;
} }
const existingHooks = ( const existingHooks = (
<div className='padding-top x2'> <div className='webhooks__container'>
<label className='control-label padding-top x2'>{'Existing incoming webhooks'}</label> <label className='control-label padding-top x2'>{'Existing incoming webhooks'}</label>
<div className='padding-top divider-light'></div>
<div className='webhooks__list'>
{displayHooks} {displayHooks}
</div> </div>
</div>
); );
return ( return (
<div key='addIncomingHook'> <div key='addIncomingHook'>
{'Create webhook URLs for use in external integrations. Please see '}<a href='http://mattermost.org/webhooks'>{'http://mattermost.org/webhooks'}</a> {' to learn more.'} {'Create webhook URLs for use in external integrations. Please see '}<a href='http://mattermost.org/webhooks'>{'http://mattermost.org/webhooks'}</a> {' to learn more.'}
<br/> <label className='control-label padding-top x2'>{'Add a new incoming webhook'}</label>
<br/> <div className='row padding-top'>
<label className='control-label'>{'Add a new incoming webhook'}</label> <div className='col-sm-10 padding-bottom'>
<div className='padding-top'>
<select <select
ref='channelName' ref='channelName'
className='form-control' className='form-control'
@@ -174,9 +175,10 @@ export default class ManageIncomingHooks extends React.Component {
{options} {options}
</select> </select>
{serverError} {serverError}
<div className='padding-top'> </div>
<div className='col-sm-2 col-xs-4 no-padding--left padding-bottom'>
<a <a
className={'btn btn-sm btn-primary' + disableButton} className={'btn form-control no-padding btn-sm btn-primary' + disableButton}
href='#' href='#'
onClick={this.addNewHook} onClick={this.addNewHook}
> >

Просмотреть файл

@@ -6,6 +6,7 @@ var Constants = require('../../utils/constants.jsx');
var ChannelStore = require('../../stores/channel_store.jsx'); var ChannelStore = require('../../stores/channel_store.jsx');
var LoadingScreen = require('../loading_screen.jsx'); var LoadingScreen = require('../loading_screen.jsx');
export default class ManageOutgoingHooks extends React.Component { export default class ManageOutgoingHooks extends React.Component {
constructor() { constructor() {
super(); super();
@@ -180,9 +181,8 @@ export default class ManageOutgoingHooks extends React.Component {
hooks.push( hooks.push(
<div <div
key={hook.id} key={hook.id}
className='font--small' className='webhook__item'
> >
<div className='padding-top x2 divider-light'></div>
<div className='padding-top x2'> <div className='padding-top x2'>
<strong>{'URLs: '}</strong><span className='word-break--all'>{hook.callback_urls.join(', ')}</span> <strong>{'URLs: '}</strong><span className='word-break--all'>{hook.callback_urls.join(', ')}</span>
</div> </div>
@@ -199,15 +199,15 @@ export default class ManageOutgoingHooks extends React.Component {
> >
{'Regen Token'} {'Regen Token'}
</a> </a>
<span>{' - '}</span>
<a <a
className='text-danger' className='webhook__remove'
href='#' href='#'
onClick={this.removeHook.bind(this, hook.id)} onClick={this.removeHook.bind(this, hook.id)}
> >
{'Remove'} <span aria-hidden='true'>{'×'}</span>
</a> </a>
</div> </div>
<div className='padding-top x2 divider-light'></div>
</div> </div>
); );
}); });
@@ -218,14 +218,17 @@ export default class ManageOutgoingHooks extends React.Component {
} else if (hooks.length > 0) { } else if (hooks.length > 0) {
displayHooks = hooks; displayHooks = hooks;
} else { } else {
displayHooks = <label>{': None'}</label>; displayHooks = <div className='padding-top x2'>{'None'}</div>;
} }
const existingHooks = ( const existingHooks = (
<div className='padding-top x2'> <div className='webhooks__container'>
<label className='control-label padding-top x2'>{'Existing outgoing webhooks'}</label> <label className='control-label padding-top x2'>{'Existing outgoing webhooks'}</label>
<div className='padding-top divider-light'></div>
<div className='webhooks__list'>
{displayHooks} {displayHooks}
</div> </div>
</div>
); );
const disableButton = (this.state.channelId === '' && this.state.triggerWords === '') || this.state.callbackURLs === ''; const disableButton = (this.state.channelId === '' && this.state.triggerWords === '') || this.state.callbackURLs === '';
@@ -234,7 +237,9 @@ export default class ManageOutgoingHooks extends React.Component {
<div key='addOutgoingHook'> <div key='addOutgoingHook'>
<label className='control-label'>{'Add a new outgoing webhook'}</label> <label className='control-label'>{'Add a new outgoing webhook'}</label>
<div className='padding-top'> <div className='padding-top'>
<strong>{'Channel:'}</strong> <div>
<label className='control-label'>{'Channel'}</label>
<div className='padding-top'>
<select <select
ref='channelName' ref='channelName'
className='form-control' className='form-control'
@@ -243,10 +248,12 @@ export default class ManageOutgoingHooks extends React.Component {
> >
{options} {options}
</select> </select>
<span>{'Only public channels can be used'}</span> </div>
<br/> <div className='padding-top'>{'Only public channels can be used'}</div>
<br/> </div>
<strong>{'Trigger Words:'}</strong> <div className='padding-top x2'>
<label className='control-label'>{'Trigger Words:'}</label>
<div className='padding-top'>
<input <input
ref='triggerWords' ref='triggerWords'
className='form-control' className='form-control'
@@ -254,10 +261,12 @@ export default class ManageOutgoingHooks extends React.Component {
onChange={this.updateTriggerWords} onChange={this.updateTriggerWords}
placeholder='Optional if channel selected' placeholder='Optional if channel selected'
/> />
<span>{'Comma separated words to trigger on'}</span> </div>
<br/> <div className='padding-top'>{'Comma separated words to trigger on'}</div>
<br/> </div>
<strong>{'Callback URLs:'}</strong> <div className='padding-top x2'>
<label className='control-label'>{'Callback URLs:'}</label>
<div className='padding-top'>
<textarea <textarea
ref='callbackURLs' ref='callbackURLs'
className='form-control no-resize' className='form-control no-resize'
@@ -266,9 +275,11 @@ export default class ManageOutgoingHooks extends React.Component {
rows={3} rows={3}
onChange={this.updateCallbackURLs} onChange={this.updateCallbackURLs}
/> />
<span>{'New line separated URLs that will receive the HTTP POST event'}</span> </div>
<div className='padding-top'>{'New line separated URLs that will receive the HTTP POST event'}</div>
{serverError} {serverError}
<div className='padding-top'> </div>
<div className='padding-top padding-bottom'>
<a <a
className={'btn btn-sm btn-primary'} className={'btn btn-sm btn-primary'}
href='#' href='#'

Просмотреть файл

@@ -43,7 +43,6 @@ export default class UserSettingsIntegrationsTab extends React.Component {
incomingHooksSection = ( incomingHooksSection = (
<SettingItemMax <SettingItemMax
title='Incoming Webhooks' title='Incoming Webhooks'
width = 'full'
inputs={inputs} inputs={inputs}
updateSection={(e) => { updateSection={(e) => {
this.updateSection(''); this.updateSection('');
@@ -55,7 +54,6 @@ export default class UserSettingsIntegrationsTab extends React.Component {
incomingHooksSection = ( incomingHooksSection = (
<SettingItemMin <SettingItemMin
title='Incoming Webhooks' title='Incoming Webhooks'
width = 'full'
describe='Manage your incoming webhooks (Developer feature)' describe='Manage your incoming webhooks (Developer feature)'
updateSection={() => { updateSection={() => {
this.updateSection('incoming-hooks'); this.updateSection('incoming-hooks');

Просмотреть файл

@@ -494,7 +494,7 @@ export function applyTheme(theme) {
changeCss('.markdown__table tbody tr:nth-child(2n)', 'background:' + changeOpacity(theme.centerChannelColor, 0.07), 1); changeCss('.markdown__table tbody tr:nth-child(2n)', 'background:' + changeOpacity(theme.centerChannelColor, 0.07), 1);
changeCss('.channel-header__info>div.dropdown .header-dropdown__icon', 'color:' + changeOpacity(theme.centerChannelColor, 0.8), 1); changeCss('.channel-header__info>div.dropdown .header-dropdown__icon', 'color:' + changeOpacity(theme.centerChannelColor, 0.8), 1);
changeCss('.channel-header #member_popover', 'color:' + changeOpacity(theme.centerChannelColor, 0.8), 1); changeCss('.channel-header #member_popover', 'color:' + changeOpacity(theme.centerChannelColor, 0.8), 1);
changeCss('.custom-textarea, .custom-textarea:focus, .preview-container .preview-div, .post-image__column .post-image__details, .sidebar--right .sidebar-right__body, .markdown__table th, .markdown__table td, .command-box, .modal .modal-content, .settings-modal .settings-table .settings-content .divider-light, .dropdown-menu, .modal .modal-header, .popover, .mentions--top .mentions-box', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); changeCss('.custom-textarea, .custom-textarea:focus, .preview-container .preview-div, .post-image__column .post-image__details, .sidebar--right .sidebar-right__body, .markdown__table th, .markdown__table td, .command-box, .modal .modal-content, .settings-modal .settings-table .settings-content .divider-light, .webhooks__container, .dropdown-menu, .modal .modal-header, .popover, .mentions--top .mentions-box', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
changeCss('.popover.bottom>.arrow', 'border-bottom-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1); changeCss('.popover.bottom>.arrow', 'border-bottom-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1);
changeCss('.popover.right>.arrow', 'border-right-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1); changeCss('.popover.right>.arrow', 'border-right-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1);
changeCss('.popover.left>.arrow', 'border-left-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1); changeCss('.popover.left>.arrow', 'border-left-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1);
@@ -509,7 +509,7 @@ export function applyTheme(theme) {
changeCss('@media(max-width: 768px){.search-bar__container .search__form .search-bar', 'background:' + changeOpacity(theme.centerChannelColor, 0.2) + '; color: inherit;', 1); changeCss('@media(max-width: 768px){.search-bar__container .search__form .search-bar', 'background:' + changeOpacity(theme.centerChannelColor, 0.2) + '; color: inherit;', 1);
changeCss('.input-group-addon, .search-bar__container .search__form, .form-control', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); changeCss('.input-group-addon, .search-bar__container .search__form, .form-control', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
changeCss('.form-control:focus', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.3), 1); changeCss('.form-control:focus', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.3), 1);
changeCss('.channel-intro .channel-intro__content', 'background:' + changeOpacity(theme.centerChannelColor, 0.05), 1); changeCss('.channel-intro .channel-intro__content, .webhooks__container', 'background:' + changeOpacity(theme.centerChannelColor, 0.05), 1);
changeCss('.date-separator .separator__text', 'color:' + theme.centerChannelColor, 2); changeCss('.date-separator .separator__text', 'color:' + theme.centerChannelColor, 2);
changeCss('.date-separator .separator__hr, .modal-footer, .modal .custom-textarea, .post-right__container .post.post--root hr, .search-item-container', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1); changeCss('.date-separator .separator__hr, .modal-footer, .modal .custom-textarea, .post-right__container .post.post--root hr, .search-item-container', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
changeCss('.modal .custom-textarea:focus', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.3), 1); changeCss('.modal .custom-textarea:focus', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.3), 1);

Просмотреть файл

@@ -94,8 +94,11 @@ a:focus, a:hover {
margin: 0; margin: 0;
} }
.text-danger { .text-danger, a.text-danger {
color: #E05F5D; color: #E05F5D;
&:hover, &:focus {
color: #E05F5D;
}
} }
.btn { .btn {
@@ -112,6 +115,10 @@ a:focus, a:hover {
&:focus { &:focus {
@include box-shadow(none); @include box-shadow(none);
} }
&.no-padding {
line-height: 32px;
padding: 0;
}
&.no-resize { &.no-resize {
resize: none; resize: none;
} }

Просмотреть файл

@@ -401,6 +401,9 @@
text-align: left; text-align: left;
} }
} }
.no-padding--left {
padding-left: 15px;
}
} }
.settings-links { .settings-links {
display: none; display: none;
@@ -425,6 +428,11 @@
} }
} }
.settings-table { .settings-table {
.nav {
position: relative;
top: auto;
width: 100%;
}
.settings-content { .settings-content {
&.minimize-settings { &.minimize-settings {
padding: 0; padding: 0;

Просмотреть файл

@@ -1,5 +1,6 @@
@import "access-history"; @import "access-history";
@import "activity-log"; @import "activity-log";
@import "webhooks";
.user-settings { .user-settings {
min-height:300px; min-height:300px;
@@ -29,6 +30,9 @@
li { li {
list-style: none; list-style: none;
} }
label {
font-weight: 600;
}
.settings-table { .settings-table {
display: table; display: table;
table-layout: fixed; table-layout: fixed;
@@ -37,6 +41,11 @@
display: table-cell; display: table-cell;
vertical-align: top; vertical-align: top;
} }
.nav {
position: fixed;
top: 55px;
width: 180px;
}
.security-links { .security-links {
margin-right: 20px; margin-right: 20px;
.fa { .fa {
@@ -129,10 +138,6 @@
} }
} }
.font--small {
font-size: 13px;
}
.section-describe { .section-describe {
@include opacity(0.7); @include opacity(0.7);
white-space:pre; white-space:pre;
@@ -161,14 +166,29 @@
.setting-list-item { .setting-list-item {
margin-top:7px; margin-top:7px;
}
.has-error { .has-error {
color: #a94442; color: #a94442;
} }
.no-padding--left {
padding-left: 0;
}
.padding-top { .padding-top {
padding-top: 7px; padding-top: 7px;
&.x2 { &.x2 {
padding-top: 14px; padding-top: 14px;
} }
&.x3 {
padding-top: 21px;
}
}
.padding-bottom {
padding-bottom: 7px;
&.x2 {
padding-bottom: 14px;
}
&.x3 {
padding-bottom: 21px;
} }
.control-label { .control-label {
font-weight: 600; font-weight: 600;

31
web/sass-files/sass/partials/_webhooks.scss Обычный файл
Просмотреть файл

@@ -0,0 +1,31 @@
.webhooks__container {
background: rgba(black, 0.1);
border: 1px solid;
@include border-radius(3px);
padding: 0 13px 15px;
margin-top: 10px;
}
.webhook__item {
font-size: 13px;
position: relative;
&:last-child {
.divider-light:last-child {
display: none;
}
}
.webhook__remove {
position: absolute;
right: -7px;
top: 8px;
width: 30px;
height: 30px;
font-size: 22px;
font-weight: bold;
text-align: center;
text-decoration: none;
color: #E05F5D;
}
.webhook__url {
padding-right: 20px;
}
}