PLT-3466 E10: Add announcement bar feature (#6509)

* E10 - Add announcement bar feature

* Updates per feedback

* Add component tests and snapshots

* Update snapshots

* Updating color picker UI (#6543)

* Add class to body tag when banner is not dismissable and clean up localstorage items when banner changes

* Fixing links (#6544)

* Updating UI for fixed error bar (#6552)

* Truncating text on fixed banner (#6561)

* Plt 3466 - Error bar link states (#6577)

* Updating error bar hover state

* Updating error bar link states
Этот коммит содержится в:
Joram Wilander
2017-06-05 12:49:38 -04:00
коммит произвёл GitHub
родитель 0f3bd85b8d
Коммит abd0466a42
28 изменённых файлов: 651 добавлений и 57 удалений

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

@@ -1,12 +1,11 @@
import PropTypes from 'prop-types';
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import PropTypes from 'prop-types';
import 'bootstrap';
import ErrorBar from 'components/error_bar.jsx';
import AnnouncementBar from 'components/announcement_bar';
import AdminStore from 'stores/admin_store.jsx';
import * as AsyncClient from 'utils/async_client.jsx';
@@ -52,7 +51,7 @@ export default class AdminConsole extends React.Component {
if (config && Object.keys(config).length === 0 && config.constructor === 'Object') {
return (
<div className='admin-console__wrapper'>
<ErrorBar/>
<AnnouncementBar/>
<div className='admin-console'/>
</div>
);
@@ -64,7 +63,7 @@ export default class AdminConsole extends React.Component {
});
return (
<div className='admin-console__wrapper'>
<ErrorBar/>
<AnnouncementBar/>
<div className='admin-console'>
<AdminSidebar/>
{children}

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

@@ -0,0 +1,119 @@
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import Setting from './setting.jsx';
import React from 'react';
import PropTypes from 'prop-types';
import {ChromePicker} from 'react-color';
export default class ColorSetting extends React.PureComponent {
static propTypes = {
/*
* The unique identifer for the admin console setting
*/
id: PropTypes.string.isRequired,
/*
* The text/jsx display name for the setting
*/
label: PropTypes.node.isRequired,
/*
* The text/jsx help text to display underneath the setting
*/
helpText: PropTypes.node,
/*
* The hex color value
*/
value: PropTypes.string.isRequired,
/*
* Function called when the input changes
*/
onChange: PropTypes.func,
/*
* Set to disable the setting
*/
disabled: PropTypes.bool
}
constructor(props) {
super(props);
this.state = {
showPicker: false
};
}
componentDidMount() {
document.addEventListener('click', this.closePicker);
}
componentWillUnmount() {
document.removeEventListener('click', this.closePicker);
}
handleChange = (color) => {
this.props.onChange(this.props.id, color.hex);
}
togglePicker = () => {
if (this.props.disabled) {
this.setState({showPicker: false});
}
this.setState({showPicker: !this.state.showPicker});
}
closePicker = (e) => {
if (!e.target.closest('.picker-' + this.props.id)) {
this.setState({showPicker: false});
}
}
onTextInput = (e) => {
this.props.onChange(this.props.id, e.target.value);
}
render() {
let picker;
if (this.state.showPicker) {
picker = (
<div className={'color-picker__popover picker-' + this.props.id}>
<ChromePicker
color={this.props.value}
onChange={this.handleChange}
/>
</div>
);
}
return (
<Setting
label={this.props.label}
helpText={this.props.helpText}
inputId={this.props.id}
>
<div className='input-group color-picker colorpicker-element'>
<input
type='text'
className='form-control'
value={this.props.value}
onChange={this.onTextInput}
disabled={this.props.disabled}
/>
<span
className={'input-group-addon picker-' + this.props.id}
onClick={this.togglePicker}
>
<i style={{backgroundColor: this.props.value}}/>
</span>
{picker}
</div>
</Setting>
);
}
}

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

@@ -8,6 +8,9 @@ import SettingsGroup from './settings_group.jsx';
import DropdownSetting from './dropdown_setting.jsx';
import RadioSetting from './radio_setting.jsx';
import PostEditSetting from './post_edit_setting.jsx';
import BooleanSetting from './boolean_setting.jsx';
import TextSetting from './text_setting.jsx';
import ColorSetting from './color_setting.jsx';
import Constants from 'utils/constants.jsx';
import * as Utils from 'utils/utils.jsx';
@@ -35,6 +38,11 @@ export default class PolicySettings extends AdminSettings {
config.TeamSettings.RestrictPublicChannelDeletion = this.state.restrictPublicChannelDeletion;
config.TeamSettings.RestrictPrivateChannelDeletion = this.state.restrictPrivateChannelDeletion;
config.TeamSettings.RestrictPrivateChannelManageMembers = this.state.restrictPrivateChannelManageMembers;
config.AnnouncementSettings.EnableBanner = this.state.enableBanner;
config.AnnouncementSettings.BannerText = this.state.bannerText;
config.AnnouncementSettings.BannerColor = this.state.bannerColor;
config.AnnouncementSettings.BannerTextColor = this.state.bannerTextColor;
config.AnnouncementSettings.AllowBannerDismissal = this.state.allowBannerDismissal;
return config;
}
@@ -51,7 +59,12 @@ export default class PolicySettings extends AdminSettings {
restrictPrivateChannelManagement: config.TeamSettings.RestrictPrivateChannelManagement,
restrictPublicChannelDeletion: config.TeamSettings.RestrictPublicChannelDeletion,
restrictPrivateChannelDeletion: config.TeamSettings.RestrictPrivateChannelDeletion,
restrictPrivateChannelManageMembers: config.TeamSettings.RestrictPrivateChannelManageMembers
restrictPrivateChannelManageMembers: config.TeamSettings.RestrictPrivateChannelManageMembers,
enableBanner: config.AnnouncementSettings.EnableBanner,
bannerText: config.AnnouncementSettings.BannerText,
bannerColor: config.AnnouncementSettings.BannerColor,
bannerTextColor: config.AnnouncementSettings.BannerTextColor,
allowBannerDismissal: config.AnnouncementSettings.AllowBannerDismissal
};
}
@@ -317,6 +330,83 @@ export default class PolicySettings extends AdminSettings {
/>
}
/>
<BooleanSetting
id='enableBanner'
label={
<FormattedMessage
id='admin.general.policy.enableBannerTitle'
defaultMessage='Enable Announcement Banner:'
/>
}
helpText={
<FormattedMessage
id='admin.general.policy.enableBannerDesc'
defaultMessage='Enable an announcement banner across all teams.'
/>
}
value={this.state.enableBanner}
onChange={this.handleChange}
/>
<TextSetting
id='bannerText'
label={
<FormattedMessage
id='admin.general.policy.bannerTextTitle'
defaultMessage='Banner Text:'
/>
}
helpText={
<FormattedMessage
id='admin.general.policy.bannerTextDesc'
defaultMessage='Text that will appear in the announcement banner.'
/>
}
value={this.state.bannerText}
onChange={this.handleChange}
disabled={!this.state.enableBanner}
/>
<ColorSetting
id='bannerColor'
label={
<FormattedMessage
id='admin.general.policy.bannerColorTitle'
defaultMessage='Banner Color:'
/>
}
value={this.state.bannerColor}
onChange={this.handleChange}
disabled={!this.state.enableBanner}
/>
<ColorSetting
id='bannerTextColor'
label={
<FormattedMessage
id='admin.general.policy.bannerTextColorTitle'
defaultMessage='Banner Text Color:'
/>
}
value={this.state.bannerTextColor}
onChange={this.handleChange}
disabled={!this.state.enableBanner}
/>
<BooleanSetting
id='allowBannerDismissal'
label={
<FormattedMessage
id='admin.general.policy.allowBannerDismissalTitle'
defaultMessage='Allow Banner Dismissal:'
/>
}
helpText={
<FormattedMessage
id='admin.general.policy.allowBannerDismissalDesc'
defaultMessage='When true, users can dismiss the banner until its next update. When false, the banner is permanently visible until it is turned off by the System Admin.'
/>
}
value={this.state.allowBannerDismissal}
onChange={this.handleChange}
disabled={!this.state.enableBanner}
/>
</SettingsGroup>
);
}