diff options
-rw-r--r-- | api/templates/password_change_body.html | 2 | ||||
-rw-r--r-- | web/react/components/invite_member_modal.jsx | 8 | ||||
-rw-r--r-- | web/react/components/setting_item_max.jsx | 2 | ||||
-rw-r--r-- | web/react/components/settings_sidebar.jsx | 4 | ||||
-rw-r--r-- | web/react/components/team_settings_modal.jsx | 1 | ||||
-rw-r--r-- | web/react/components/user_settings/manage_incoming_hooks.jsx | 64 | ||||
-rw-r--r-- | web/react/components/user_settings/manage_outgoing_hooks.jsx | 97 | ||||
-rw-r--r-- | web/react/components/user_settings/user_settings_integrations.jsx | 2 | ||||
-rw-r--r-- | web/react/utils/utils.jsx | 7 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_base.scss | 9 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_post.scss | 11 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_responsive.scss | 11 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_settings.scss | 42 | ||||
-rw-r--r-- | web/sass-files/sass/partials/_webhooks.scss | 31 |
14 files changed, 192 insertions, 99 deletions
diff --git a/api/templates/password_change_body.html b/api/templates/password_change_body.html index 47a93fcb9..2e1df3ff2 100644 --- a/api/templates/password_change_body.html +++ b/api/templates/password_change_body.html @@ -18,7 +18,7 @@ <tr> <td style="border-bottom: 1px solid #ddd; padding: 0 0 20px;"> <h2 style="font-weight: normal; margin-top: 10px;">You updated your password</h2> - <p>You updated your password for {{.Props.TeamDisplayName}} on {{ .Props.TeamURL }} by {{.Props.Method}}.<br> If this change wasn't initiated by you, please reply to this email and let us know.</p> + <p>You updated your password for {{.Props.TeamDisplayName}} on {{ .Props.TeamURL }} by {{.Props.Method}}.<br>If this change wasn't initiated by you, please contact your system administrator.</p> </td> </tr> <tr> diff --git a/web/react/components/invite_member_modal.jsx b/web/react/components/invite_member_modal.jsx index 4986f88b6..86a4b04cf 100644 --- a/web/react/components/invite_member_modal.jsx +++ b/web/react/components/invite_member_modal.jsx @@ -260,6 +260,12 @@ export default class InviteMemberModal extends React.Component { var content = null; var sendButton = null; + + var sendButtonLabel = 'Send Invitation'; + if (this.state.inviteIds.length > 1) { + sendButtonLabel = 'Send Invitations'; + } + if (this.state.emailEnabled) { content = ( <div> @@ -281,7 +287,7 @@ export default class InviteMemberModal extends React.Component { onClick={this.handleSubmit} type='button' className='btn btn-primary' - >Send Invitations</button> + >{sendButtonLabel}</button> ); } else { var teamInviteLink = null; diff --git a/web/react/components/setting_item_max.jsx b/web/react/components/setting_item_max.jsx index 4f0fe3ed0..774f98a43 100644 --- a/web/react/components/setting_item_max.jsx +++ b/web/react/components/setting_item_max.jsx @@ -36,7 +36,7 @@ export default class SettingItemMax extends React.Component { if (this.props.width === 'full') { widthClass = 'col-sm-12'; } else { - widthClass = 'col-sm-9 col-sm-offset-3'; + widthClass = 'col-sm-10 col-sm-offset-2'; } return ( diff --git a/web/react/components/settings_sidebar.jsx b/web/react/components/settings_sidebar.jsx index 66568e1c8..4af46c35a 100644 --- a/web/react/components/settings_sidebar.jsx +++ b/web/react/components/settings_sidebar.jsx @@ -2,6 +2,10 @@ // See License.txt for license information. export default class SettingsSidebar extends React.Component { + componentDidUpdate() { + $('.settings-modal').find('.modal-body').scrollTop(0); + $('.settings-modal').find('.modal-body').perfectScrollbar('update'); + } constructor(props) { super(props); diff --git a/web/react/components/team_settings_modal.jsx b/web/react/components/team_settings_modal.jsx index b55373dba..5c5995020 100644 --- a/web/react/components/team_settings_modal.jsx +++ b/web/react/components/team_settings_modal.jsx @@ -19,6 +19,7 @@ export default class TeamSettingsModal extends React.Component { componentDidMount() { $('body').on('click', '.modal-back', function handleBackClick() { $(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', () => { setTimeout(() => { diff --git a/web/react/components/user_settings/manage_incoming_hooks.jsx b/web/react/components/user_settings/manage_incoming_hooks.jsx index 812169be4..6b8c09718 100644 --- a/web/react/components/user_settings/manage_incoming_hooks.jsx +++ b/web/react/components/user_settings/manage_incoming_hooks.jsx @@ -119,24 +119,23 @@ export default class ManageIncomingHooks extends React.Component { hooks.push( <div key={hook.id} - className='font--small' + className='webhook__item' > - <div className='padding-top x2 divider-light'></div> - <div className='padding-top x2'> - <strong>{'URL: '}</strong><span className='word-break--all'>{Utils.getWindowLocationOrigin() + '/hooks/' + hook.id}</span> + <div className='padding-top x2 webhook__url'> + <strong>{'URL: '}</strong> + <span className='word-break--all'>{Utils.getWindowLocationOrigin() + '/hooks/' + hook.id}</span> </div> <div className='padding-top'> <strong>{'Channel: '}</strong>{c.display_name} </div> - <div className='padding-top'> - <a - className={'text-danger'} - href='#' - onClick={this.removeHook.bind(this, hook.id)} - > - {'Remove'} - </a> - </div> + <a + className={'webhook__remove'} + href='#' + onClick={this.removeHook.bind(this, hook.id)} + > + <span aria-hidden='true'>{'×'}</span> + </a> + <div className='padding-top x2 divider-light'></div> </div> ); } @@ -148,35 +147,38 @@ export default class ManageIncomingHooks extends React.Component { } else if (hooks.length > 0) { displayHooks = hooks; } else { - displayHooks = <label>{': None'}</label>; + displayHooks = <div className='padding-top x2'>{'None'}</div>; } const existingHooks = ( - <div className='padding-top x2'> + <div className='webhooks__container'> <label className='control-label padding-top x2'>{'Existing incoming webhooks'}</label> - {displayHooks} + <div className='padding-top divider-light'></div> + <div className='webhooks__list'> + {displayHooks} + </div> </div> ); return ( <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.'} - <br/> - <br/> - <label className='control-label'>{'Add a new incoming webhook'}</label> - <div className='padding-top'> - <select - ref='channelName' - className='form-control' - value={this.state.channelId} - onChange={this.updateChannelId} - > - {options} - </select> - {serverError} - <div className='padding-top'> + <label className='control-label padding-top x2'>{'Add a new incoming webhook'}</label> + <div className='row padding-top'> + <div className='col-sm-10 padding-bottom'> + <select + ref='channelName' + className='form-control' + value={this.state.channelId} + onChange={this.updateChannelId} + > + {options} + </select> + {serverError} + </div> + <div className='col-sm-2 col-xs-4 no-padding--left padding-bottom'> <a - className={'btn btn-sm btn-primary' + disableButton} + className={'btn form-control no-padding btn-sm btn-primary' + disableButton} href='#' onClick={this.addNewHook} > diff --git a/web/react/components/user_settings/manage_outgoing_hooks.jsx b/web/react/components/user_settings/manage_outgoing_hooks.jsx index f6d6b515b..6e9b2205d 100644 --- a/web/react/components/user_settings/manage_outgoing_hooks.jsx +++ b/web/react/components/user_settings/manage_outgoing_hooks.jsx @@ -6,6 +6,7 @@ var Constants = require('../../utils/constants.jsx'); var ChannelStore = require('../../stores/channel_store.jsx'); var LoadingScreen = require('../loading_screen.jsx'); + export default class ManageOutgoingHooks extends React.Component { constructor() { super(); @@ -180,9 +181,8 @@ export default class ManageOutgoingHooks extends React.Component { hooks.push( <div key={hook.id} - className='font--small' + className='webhook__item' > - <div className='padding-top x2 divider-light'></div> <div className='padding-top x2'> <strong>{'URLs: '}</strong><span className='word-break--all'>{hook.callback_urls.join(', ')}</span> </div> @@ -199,15 +199,15 @@ export default class ManageOutgoingHooks extends React.Component { > {'Regen Token'} </a> - <span>{' - '}</span> <a - className='text-danger' + className='webhook__remove' href='#' onClick={this.removeHook.bind(this, hook.id)} > - {'Remove'} + <span aria-hidden='true'>{'×'}</span> </a> </div> + <div className='padding-top x2 divider-light'></div> </div> ); }); @@ -218,13 +218,16 @@ export default class ManageOutgoingHooks extends React.Component { } else if (hooks.length > 0) { displayHooks = hooks; } else { - displayHooks = <label>{': None'}</label>; + displayHooks = <div className='padding-top x2'>{'None'}</div>; } const existingHooks = ( - <div className='padding-top x2'> + <div className='webhooks__container'> <label className='control-label padding-top x2'>{'Existing outgoing webhooks'}</label> - {displayHooks} + <div className='padding-top divider-light'></div> + <div className='webhooks__list'> + {displayHooks} + </div> </div> ); @@ -234,41 +237,49 @@ export default class ManageOutgoingHooks extends React.Component { <div key='addOutgoingHook'> <label className='control-label'>{'Add a new outgoing webhook'}</label> <div className='padding-top'> - <strong>{'Channel:'}</strong> - <select - ref='channelName' - className='form-control' - value={this.state.channelId} - onChange={this.updateChannelId} - > - {options} - </select> - <span>{'Only public channels can be used'}</span> - <br/> - <br/> - <strong>{'Trigger Words:'}</strong> - <input - ref='triggerWords' - className='form-control' - value={this.state.triggerWords} - onChange={this.updateTriggerWords} - placeholder='Optional if channel selected' - /> - <span>{'Comma separated words to trigger on'}</span> - <br/> - <br/> - <strong>{'Callback URLs:'}</strong> - <textarea - ref='callbackURLs' - className='form-control no-resize' - value={this.state.callbackURLs} - resize={false} - rows={3} - onChange={this.updateCallbackURLs} - /> - <span>{'New line separated URLs that will receive the HTTP POST event'}</span> - {serverError} - <div className='padding-top'> + <div> + <label className='control-label'>{'Channel'}</label> + <div className='padding-top'> + <select + ref='channelName' + className='form-control' + value={this.state.channelId} + onChange={this.updateChannelId} + > + {options} + </select> + </div> + <div className='padding-top'>{'Only public channels can be used'}</div> + </div> + <div className='padding-top x2'> + <label className='control-label'>{'Trigger Words:'}</label> + <div className='padding-top'> + <input + ref='triggerWords' + className='form-control' + value={this.state.triggerWords} + onChange={this.updateTriggerWords} + placeholder='Optional if channel selected' + /> + </div> + <div className='padding-top'>{'Comma separated words to trigger on'}</div> + </div> + <div className='padding-top x2'> + <label className='control-label'>{'Callback URLs:'}</label> + <div className='padding-top'> + <textarea + ref='callbackURLs' + className='form-control no-resize' + value={this.state.callbackURLs} + resize={false} + rows={3} + onChange={this.updateCallbackURLs} + /> + </div> + <div className='padding-top'>{'New line separated URLs that will receive the HTTP POST event'}</div> + {serverError} + </div> + <div className='padding-top padding-bottom'> <a className={'btn btn-sm btn-primary'} href='#' diff --git a/web/react/components/user_settings/user_settings_integrations.jsx b/web/react/components/user_settings/user_settings_integrations.jsx index 83a6bf53a..4b1e5e532 100644 --- a/web/react/components/user_settings/user_settings_integrations.jsx +++ b/web/react/components/user_settings/user_settings_integrations.jsx @@ -43,7 +43,6 @@ export default class UserSettingsIntegrationsTab extends React.Component { incomingHooksSection = ( <SettingItemMax title='Incoming Webhooks' - width = 'full' inputs={inputs} updateSection={(e) => { this.updateSection(''); @@ -55,7 +54,6 @@ export default class UserSettingsIntegrationsTab extends React.Component { incomingHooksSection = ( <SettingItemMin title='Incoming Webhooks' - width = 'full' describe='Manage your incoming webhooks (Developer feature)' updateSection={() => { this.updateSection('incoming-hooks'); diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx index 3d0cee562..67a9d6983 100644 --- a/web/react/utils/utils.jsx +++ b/web/react/utils/utils.jsx @@ -431,6 +431,7 @@ export function applyTheme(theme) { if (theme.sidebarTextActiveColor) { changeCss('.sidebar--left .nav-pills__container li.active a, .sidebar--left .nav-pills__container li.active a:hover, .sidebar--left .nav-pills__container li.active a:focus, .settings-modal .nav-pills>li.active a, .settings-modal .nav-pills>li.active a:hover, .settings-modal .nav-pills>li.active a:active', 'color:' + theme.sidebarTextActiveColor, 2); + changeCss('.sidebar--left .nav li.active a, .sidebar--left .nav li.active a:hover, .sidebar--left .nav li.active a:focus', 'background:' + changeOpacity(theme.sidebarTextActiveColor, 0.1), 1); } if (theme.sidebarHeaderBg) { @@ -494,7 +495,7 @@ export function applyTheme(theme) { 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 #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.right>.arrow', 'border-right-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1); changeCss('.popover.left>.arrow', 'border-left-color:' + changeOpacity(theme.centerChannelColor, 0.25), 1); @@ -509,7 +510,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('.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('.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__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); @@ -521,7 +522,7 @@ export function applyTheme(theme) { changeCss('@media(max-width: 1800px){.inner__wrap.move--left .post.post--comment.same--root', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.07), 2); changeCss('.post:hover, .modal .more-table tbody>tr:hover td, .sidebar--right .sidebar--right__header, .settings-modal .settings-table .settings-content .section-min:hover', 'background:' + changeOpacity(theme.centerChannelColor, 0.07), 1); changeCss('.date-separator.hovered--before:after, .date-separator.hovered--after:before, .new-separator.hovered--after:before, .new-separator.hovered--before:after', 'background:' + changeOpacity(theme.centerChannelColor, 0.07), 1); - changeCss('.command-name:hover, .mentions-name:hover, .mentions-focus, .dropdown-menu>li>a:focus, .dropdown-menu>li>a:hover', 'background:' + changeOpacity(theme.centerChannelColor, 0.15), 1); + changeCss('.command-name:hover, .mentions-name:hover, .mentions-focus, .dropdown-menu>li>a:focus, .dropdown-menu>li>a:hover, .bot-indicator', 'background:' + changeOpacity(theme.centerChannelColor, 0.15), 1); changeCss('code', 'background:' + changeOpacity(theme.centerChannelColor, 0.1), 1); changeCss('.post.current--user:hover .post-body ', 'background: none;', 1); changeCss('.sidebar--right', 'color:' + theme.centerChannelColor, 2); diff --git a/web/sass-files/sass/partials/_base.scss b/web/sass-files/sass/partials/_base.scss index 6b2e79933..6399b8fd8 100644 --- a/web/sass-files/sass/partials/_base.scss +++ b/web/sass-files/sass/partials/_base.scss @@ -94,8 +94,11 @@ a:focus, a:hover { margin: 0; } -.text-danger { +.text-danger, a.text-danger { color: #E05F5D; + &:hover, &:focus { + color: #E05F5D; + } } .btn { @@ -112,6 +115,10 @@ a:focus, a:hover { &:focus { @include box-shadow(none); } + &.no-padding { + line-height: 32px; + padding: 0; + } &.no-resize { resize: none; } diff --git a/web/sass-files/sass/partials/_post.scss b/web/sass-files/sass/partials/_post.scss index db58d0347..f5fc1631f 100644 --- a/web/sass-files/sass/partials/_post.scss +++ b/web/sass-files/sass/partials/_post.scss @@ -569,9 +569,10 @@ body.ios { } .bot-indicator { - background-color: lightgrey; - border-radius:2px; - padding-left:2px; - padding-right:2px; - font-family:"Courier New" + font-family: inherit; + font-size: 11px; + padding: 2px 4px; + border-radius: 2px; + font-weight: 600; + margin: 0 0 0 -4px; } diff --git a/web/sass-files/sass/partials/_responsive.scss b/web/sass-files/sass/partials/_responsive.scss index f4e57eec5..2cd5560ef 100644 --- a/web/sass-files/sass/partials/_responsive.scss +++ b/web/sass-files/sass/partials/_responsive.scss @@ -284,6 +284,9 @@ height: auto; } } + .search-help-popover.visible { + visibility: hidden; + } .modal-direct-channels { .member-count { float: none; @@ -401,6 +404,9 @@ text-align: left; } } + .no-padding--left { + padding-left: 15px; + } } .settings-links { display: none; @@ -425,6 +431,11 @@ } } .settings-table { + .nav { + position: relative; + top: auto; + width: 100%; + } .settings-content { &.minimize-settings { padding: 0; diff --git a/web/sass-files/sass/partials/_settings.scss b/web/sass-files/sass/partials/_settings.scss index 9af045f98..c881f9073 100644 --- a/web/sass-files/sass/partials/_settings.scss +++ b/web/sass-files/sass/partials/_settings.scss @@ -1,5 +1,6 @@ @import "access-history"; @import "activity-log"; +@import "webhooks"; .user-settings { min-height:300px; @@ -29,6 +30,9 @@ li { list-style: none; } + label { + font-weight: 600; + } .settings-table { display: table; table-layout: fixed; @@ -37,6 +41,11 @@ display: table-cell; vertical-align: top; } + .nav { + position: fixed; + top: 57px; + width: 180px; + } .security-links { margin-right: 20px; .fa { @@ -129,10 +138,6 @@ } } - .font--small { - font-size: 13px; - } - .section-describe { @include opacity(0.7); white-space:pre; @@ -161,14 +166,29 @@ .setting-list-item { margin-top:7px; - .has-error { - color: #a94442; + } + .has-error { + color: #a94442; + } + .no-padding--left { + padding-left: 0; + } + .padding-top { + padding-top: 7px; + &.x2 { + padding-top: 14px; } - .padding-top { - padding-top: 7px; - &.x2 { - padding-top: 14px; - } + &.x3 { + padding-top: 21px; + } + } + .padding-bottom { + padding-bottom: 7px; + &.x2 { + padding-bottom: 14px; + } + &.x3 { + padding-bottom: 21px; } .control-label { font-weight: 600; diff --git a/web/sass-files/sass/partials/_webhooks.scss b/web/sass-files/sass/partials/_webhooks.scss new file mode 100644 index 000000000..b801ccf63 --- /dev/null +++ b/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; + } +}
\ No newline at end of file |