summaryrefslogtreecommitdiffstats
path: root/web/react
diff options
context:
space:
mode:
Diffstat (limited to 'web/react')
-rw-r--r--web/react/components/audit_table.jsx66
-rw-r--r--web/react/components/post_info.jsx9
-rw-r--r--web/react/components/user_settings/custom_theme_chooser.jsx113
-rw-r--r--web/react/components/user_settings/user_settings_theme.jsx2
-rw-r--r--web/react/utils/constants.jsx25
-rw-r--r--web/react/utils/utils.jsx4
6 files changed, 194 insertions, 25 deletions
diff --git a/web/react/components/audit_table.jsx b/web/react/components/audit_table.jsx
index 49892ff98..31d04f19b 100644
--- a/web/react/components/audit_table.jsx
+++ b/web/react/components/audit_table.jsx
@@ -183,6 +183,26 @@ const holders = defineMessages({
loginFailure: {
id: 'audit_table.loginFailure',
defaultMessage: ' (Login failure)'
+ },
+ attemptedLicenseAdd: {
+ id: 'audit_table.attemptedLicenseAdd',
+ defaultMessage: 'Attempted to add new license'
+ },
+ successfullLicenseAdd: {
+ id: 'audit_table.successfullLicenseAdd',
+ defaultMessage: 'Successfully added new license'
+ },
+ failedExpiredLicenseAdd: {
+ id: 'audit_table.failedExpiredLicenseAdd',
+ defaultMessage: 'Failed to add a new license as it has either expired or not yet been started'
+ },
+ failedInvalidLicenseAdd: {
+ id: 'audit_table.failedInvalidLicenseAdd',
+ defaultMessage: 'Failed to add an invalid license'
+ },
+ licenseRemoved: {
+ id: 'audit_table.licenseRemoved',
+ defaultMessage: 'Successfully removed a license'
}
});
@@ -327,17 +347,17 @@ export function formatAuditInfo(audit, formatMessage) {
switch (actionURL) {
case '/channels/create':
- auditDesc = formatMessage(holders.channelCreated, {channelName: channelName});
+ auditDesc = formatMessage(holders.channelCreated, {channelName});
break;
case '/channels/create_direct':
auditDesc = formatMessage(holders.establishedDM, {username: Utils.getDirectTeammate(channelObj.id).username});
break;
case '/channels/update':
- auditDesc = formatMessage(holders.nameUpdated, {channelName: channelName});
+ auditDesc = formatMessage(holders.nameUpdated, {channelName});
break;
case '/channels/update_desc': // support the old path
case '/channels/update_header':
- auditDesc = formatMessage(holders.headerUpdated, {channelName: channelName});
+ auditDesc = formatMessage(holders.headerUpdated, {channelName});
break;
default: {
let userIdField = [];
@@ -356,9 +376,9 @@ export function formatAuditInfo(audit, formatMessage) {
if (/\/channels\/[A-Za-z0-9]+\/delete/.test(actionURL)) {
auditDesc = formatMessage(holders.channelDeleted, {url: channelURL});
} else if (/\/channels\/[A-Za-z0-9]+\/add/.test(actionURL)) {
- auditDesc = formatMessage(holders.userAdded, {username: username, channelName: channelName});
+ auditDesc = formatMessage(holders.userAdded, {username, channelName});
} else if (/\/channels\/[A-Za-z0-9]+\/remove/.test(actionURL)) {
- auditDesc = formatMessage(holders.userRemoved, {username: username, channelName: channelName});
+ auditDesc = formatMessage(holders.userRemoved, {username, channelName});
}
break;
@@ -495,25 +515,25 @@ export function formatAuditInfo(audit, formatMessage) {
break;
}
} else if (actionURL.indexOf('/hooks') === 0) {
- const webhookInfo = audit.extra_info.split(' ');
+ const webhookInfo = audit.extra_info;
switch (actionURL) {
case '/hooks/incoming/create':
- if (webhookInfo[0] === 'attempt') {
+ if (webhookInfo === 'attempt') {
auditDesc = formatMessage(holders.attemptedWebhookCreate);
- } else if (webhookInfo[0] === 'success') {
+ } else if (webhookInfo === 'success') {
auditDesc = formatMessage(holders.succcessfullWebhookCreate);
- } else if (webhookInfo[0] === 'fail - bad channel permissions') {
+ } else if (webhookInfo === 'fail - bad channel permissions') {
auditDesc = formatMessage(holders.failedWebhookCreate);
}
break;
case '/hooks/incoming/delete':
- if (webhookInfo[0] === 'attempt') {
+ if (webhookInfo === 'attempt') {
auditDesc = formatMessage(holders.attemptedWebhookDelete);
- } else if (webhookInfo[0] === 'success') {
+ } else if (webhookInfo === 'success') {
auditDesc = formatMessage(holders.successfullWebhookDelete);
- } else if (webhookInfo[0] === 'fail - inappropriate conditions') {
+ } else if (webhookInfo === 'fail - inappropriate conditions') {
auditDesc = formatMessage(holders.failedWebhookDelete);
}
@@ -521,6 +541,28 @@ export function formatAuditInfo(audit, formatMessage) {
default:
break;
}
+ } else if (actionURL.indexOf('/license') === 0) {
+ const licenseInfo = audit.extra_info;
+
+ switch (actionURL) {
+ case '/license/add':
+ if (licenseInfo === 'attempt') {
+ auditDesc = formatMessage(holders.attemptedLicenseAdd);
+ } else if (licenseInfo === 'success') {
+ auditDesc = formatMessage(holders.successfullLicenseAdd);
+ } else if (licenseInfo === 'failed - expired or non-started license') {
+ auditDesc = formatMessage(holders.failedExpiredLicenseAdd);
+ } else if (licenseInfo === 'failed - invalid license') {
+ auditDesc = formatMessage(holders.failedInvalidLicenseAdd);
+ }
+
+ break;
+ case '/license/remove':
+ auditDesc = formatMessage(holders.licenseRemoved);
+ break;
+ default:
+ break;
+ }
} else {
switch (actionURL) {
case '/logout':
diff --git a/web/react/components/post_info.jsx b/web/react/components/post_info.jsx
index c44223b1f..d1d516816 100644
--- a/web/react/components/post_info.jsx
+++ b/web/react/components/post_info.jsx
@@ -14,9 +14,17 @@ export default class PostInfo extends React.Component {
constructor(props) {
super(props);
+ this.dropdownPosition = this.dropdownPosition.bind(this);
this.handlePermalink = this.handlePermalink.bind(this);
this.removePost = this.removePost.bind(this);
}
+ dropdownPosition(e) {
+ var position = $('#post-list').height() - $(e.target).offset().top;
+ var dropdown = $(e.target).next('.dropdown-menu');
+ if (position < dropdown.height()) {
+ dropdown.addClass('bottom');
+ }
+ }
createDropdown() {
var post = this.props.post;
var isOwner = UserStore.getCurrentId() === post.user_id;
@@ -133,6 +141,7 @@ export default class PostInfo extends React.Component {
type='button'
data-toggle='dropdown'
aria-expanded='false'
+ onClick={this.dropdownPosition}
/>
<ul
className='dropdown-menu'
diff --git a/web/react/components/user_settings/custom_theme_chooser.jsx b/web/react/components/user_settings/custom_theme_chooser.jsx
index 2d88a3650..1e724bb6e 100644
--- a/web/react/components/user_settings/custom_theme_chooser.jsx
+++ b/web/react/components/user_settings/custom_theme_chooser.jsx
@@ -102,6 +102,7 @@ class CustomThemeChooser extends React.Component {
this.onPickerChange = this.onPickerChange.bind(this);
this.onInputChange = this.onInputChange.bind(this);
this.pasteBoxChange = this.pasteBoxChange.bind(this);
+ this.toggleContent = this.toggleContent.bind(this);
this.state = {};
}
@@ -153,11 +154,23 @@ class CustomThemeChooser extends React.Component {
this.props.updateTheme(theme);
}
+ toggleContent(e) {
+ e.stopPropagation();
+ if ($(e.target).hasClass('theme-elements__header')) {
+ $(e.target).next().slideToggle();
+ $(e.target).toggleClass('open');
+ } else {
+ $(e.target).closest('.theme-elements__header').next().slideToggle();
+ $(e.target).closest('.theme-elements__header').toggleClass('open');
+ }
+ }
render() {
const {formatMessage} = this.props.intl;
const theme = this.props.theme;
- const elements = [];
+ const sidebarElements = [];
+ const centerChannelElements = [];
+ const linkAndButtonElements = [];
let colors = '';
Constants.THEME_ELEMENTS.forEach((element, index) => {
if (element.id === 'codeTheme') {
@@ -187,9 +200,9 @@ class CustomThemeChooser extends React.Component {
</Popover>
);
- elements.push(
+ centerChannelElements.push(
<div
- className='col-sm-4 form-group'
+ className='col-sm-6 form-group'
key={'custom-theme-key' + index}
>
<label className='custom-label'>{formatMessage(messages[element.id])}</label>
@@ -219,10 +232,54 @@ class CustomThemeChooser extends React.Component {
</div>
</div>
);
+ } else if (element.group === 'centerChannelElements') {
+ centerChannelElements.push(
+ <div
+ className='col-sm-6 form-group element'
+ key={'custom-theme-key' + index}
+ >
+ <label className='custom-label'>{formatMessage(messages[element.id])}</label>
+ <div
+ className='input-group color-picker'
+ id={element.id}
+ >
+ <input
+ className='form-control'
+ type='text'
+ value={theme[element.id]}
+ onChange={this.onInputChange}
+ />
+ <span className='input-group-addon'><i></i></span>
+ </div>
+ </div>
+ );
+ } else if (element.group === 'sidebarElements') {
+ sidebarElements.push(
+ <div
+ className='col-sm-6 form-group element'
+ key={'custom-theme-key' + index}
+ >
+ <label className='custom-label'>{formatMessage(messages[element.id])}</label>
+ <div
+ className='input-group color-picker'
+ id={element.id}
+ >
+ <input
+ className='form-control'
+ type='text'
+ value={theme[element.id]}
+ onChange={this.onInputChange}
+ />
+ <span className='input-group-addon'><i></i></span>
+ </div>
+ </div>
+ );
+
+ colors += theme[element.id] + ',';
} else {
- elements.push(
+ linkAndButtonElements.push(
<div
- className='col-sm-4 form-group element'
+ className='col-sm-6 form-group element'
key={'custom-theme-key' + index}
>
<label className='custom-label'>{formatMessage(messages[element.id])}</label>
@@ -265,9 +322,51 @@ class CustomThemeChooser extends React.Component {
);
return (
- <div className='appearance-section'>
+ <div className='appearance-section padding-top'>
+ <div className='theme-elements row'>
+ <div
+ className='theme-elements__header'
+ onClick={this.toggleContent}
+ >
+ {'Sidebar Styles'}
+ <div className='header__icon'>
+ <i className='fa fa-plus'></i>
+ <i className='fa fa-minus'></i>
+ </div>
+ </div>
+ <div className='theme-elements__body'>
+ {sidebarElements}
+ </div>
+ </div>
+ <div className='theme-elements row'>
+ <div
+ className='theme-elements__header'
+ onClick={this.toggleContent}
+ >
+ {'Center Channel Styles'}
+ <div className='header__icon'>
+ <i className='fa fa-plus'></i>
+ <i className='fa fa-minus'></i>
+ </div>
+ </div>
+ <div className='theme-elements__body'>
+ {centerChannelElements}
+ </div>
+ </div>
<div className='theme-elements row form-group'>
- {elements}
+ <div
+ className='theme-elements__header'
+ onClick={this.toggleContent}
+ >
+ {'Link and Button Styles'}
+ <div className='header__icon'>
+ <i className='fa fa-plus'></i>
+ <i className='fa fa-minus'></i>
+ </div>
+ </div>
+ <div className='theme-elements__body'>
+ {linkAndButtonElements}
+ </div>
</div>
<div className='row'>
{pasteBox}
diff --git a/web/react/components/user_settings/user_settings_theme.jsx b/web/react/components/user_settings/user_settings_theme.jsx
index 34c688db1..74975d115 100644
--- a/web/react/components/user_settings/user_settings_theme.jsx
+++ b/web/react/components/user_settings/user_settings_theme.jsx
@@ -182,7 +182,6 @@ export default class ThemeSetting extends React.Component {
if (displayCustom) {
custom = (
<div key='customThemeChooser'>
- <br/>
<CustomThemeChooser
theme={this.state.theme}
updateTheme={this.updateTheme}
@@ -241,7 +240,6 @@ export default class ThemeSetting extends React.Component {
defaultMessage='Custom Theme'
/>
</label>
- <br/>
</div>
);
diff --git a/web/react/utils/constants.jsx b/web/react/utils/constants.jsx
index 428549d57..766a86686 100644
--- a/web/react/utils/constants.jsx
+++ b/web/react/utils/constants.jsx
@@ -189,8 +189,8 @@ export default {
sidebarHeaderTextColor: '#FFFFFF',
onlineIndicator: '#7DBE00',
awayIndicator: '#DCBD4E',
- mentionBj: '#136197',
- mentionColor: '#bfcde8',
+ mentionBj: '#FBFBFB',
+ mentionColor: '#2071A7',
centerChannelBg: '#f2f4f8',
centerChannelColor: '#333333',
newMessageSeparator: '#FF8800',
@@ -276,86 +276,107 @@ export default {
},
THEME_ELEMENTS: [
{
+ group: 'sidebarElements',
id: 'sidebarBg',
uiName: 'Sidebar BG'
},
{
+ group: 'sidebarElements',
id: 'sidebarText',
uiName: 'Sidebar Text'
},
{
+ group: 'sidebarElements',
id: 'sidebarHeaderBg',
uiName: 'Sidebar Header BG'
},
{
+ group: 'sidebarElements',
id: 'sidebarHeaderTextColor',
uiName: 'Sidebar Header Text'
},
{
+ group: 'sidebarElements',
id: 'sidebarUnreadText',
uiName: 'Sidebar Unread Text'
},
{
+ group: 'sidebarElements',
id: 'sidebarTextHoverBg',
uiName: 'Sidebar Text Hover BG'
},
{
+ group: 'sidebarElements',
id: 'sidebarTextActiveBorder',
uiName: 'Sidebar Text Active Border'
},
{
+ group: 'sidebarElements',
id: 'sidebarTextActiveColor',
uiName: 'Sidebar Text Active Color'
},
{
+ group: 'sidebarElements',
id: 'onlineIndicator',
uiName: 'Online Indicator'
},
{
+ group: 'sidebarElements',
id: 'awayIndicator',
uiName: 'Away Indicator'
},
{
+ group: 'sidebarElements',
id: 'mentionBj',
uiName: 'Mention Jewel BG'
},
{
+ group: 'sidebarElements',
id: 'mentionColor',
uiName: 'Mention Jewel Text'
},
{
+ group: 'centerChannelElements',
id: 'centerChannelBg',
uiName: 'Center Channel BG'
},
{
+ group: 'centerChannelElements',
id: 'centerChannelColor',
uiName: 'Center Channel Text'
},
{
+ group: 'centerChannelElements',
id: 'newMessageSeparator',
uiName: 'New Message Separator'
},
{
+ group: 'linkAndButtonElements',
id: 'linkColor',
uiName: 'Link Color'
},
{
+ group: 'linkAndButtonElements',
id: 'buttonBg',
uiName: 'Button BG'
},
{
+ group: 'linkAndButtonElements',
id: 'buttonColor',
uiName: 'Button Text'
},
{
+ group: 'centerChannelElements',
id: 'mentionHighlightBg',
uiName: 'Mention Highlight BG'
},
{
+ group: 'centerChannelElements',
id: 'mentionHighlightLink',
uiName: 'Mention Highlight Link'
},
{
+ group: 'centerChannelElements',
id: 'codeTheme',
uiName: 'Code Theme',
themes: [
diff --git a/web/react/utils/utils.jsx b/web/react/utils/utils.jsx
index e310dc108..2b946d81f 100644
--- a/web/react/utils/utils.jsx
+++ b/web/react/utils/utils.jsx
@@ -747,7 +747,7 @@ export function applyTheme(theme) {
changeCss('.date-separator .separator__hr, .modal-footer, .modal .custom-textarea', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
changeCss('.search-item-container, .post-right__container .post.post--root', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.1), 1);
changeCss('.modal .custom-textarea:focus', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.3), 1);
- changeCss('.channel-intro, .settings-modal .settings-table .settings-content .divider-dark, hr, .settings-modal .settings-table .settings-links', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
+ changeCss('.channel-intro, .settings-modal .settings-table .settings-content .divider-dark, hr, .settings-modal .settings-table .settings-links, .settings-modal .settings-table .settings-content .appearance-section .theme-elements__header', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.2), 1);
changeCss('.post.current--user .post__body, .post.post--comment.other--root.current--user .post-comment, pre, .post-right__container .post.post--root', 'background:' + changeOpacity(theme.centerChannelColor, 0.07), 1);
changeCss('.post.current--user .post__body, .post.post--comment.other--root.current--user .post-comment, .post.same--root.post--comment .post__body, .modal .more-table tbody>tr td, .member-div:first-child, .member-div, .access-history__table .access__report, .activity-log__table', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.1), 2);
changeCss('@media(max-width: 1800px){.inner__wrap.move--left .post.post--comment.same--root', 'border-color:' + changeOpacity(theme.centerChannelColor, 0.07), 2);
@@ -757,7 +757,7 @@ export function applyTheme(theme) {
changeCss('code', 'background:' + changeOpacity(theme.centerChannelColor, 0.1), 1);
changeCss('@media(min-width: 960px){.post.current--user:hover .post__body ', 'background: none;', 1);
changeCss('.sidebar--right', 'color:' + theme.centerChannelColor, 2);
- changeCss('.search-help-popover .search-autocomplete__item:hover', 'background:' + changeOpacity(theme.centerChannelColor, 0.05), 1);
+ changeCss('.search-help-popover .search-autocomplete__item:hover, .settings-modal .settings-table .settings-content .appearance-section .theme-elements__body', 'background:' + changeOpacity(theme.centerChannelColor, 0.05), 1);
changeCss('.search-help-popover .search-autocomplete__item.selected', 'background:' + changeOpacity(theme.centerChannelColor, 0.15), 1);
}