diff options
author | Harrison Healey <harrisonmhealey@gmail.com> | 2016-07-05 11:58:18 -0400 |
---|---|---|
committer | Joram Wilander <jwawilander@gmail.com> | 2016-07-05 11:58:18 -0400 |
commit | dc2f2a800105b77e665ec2a00c6290f35b1a2ba3 (patch) | |
tree | 82f23c2e72a7c785f55c2d6c1c35c10c16994918 /webapp/components/backstage/components/backstage_list.jsx | |
parent | a65f1fc266f15eaa8f79541d4d11440c3d356bb6 (diff) | |
download | chat-dc2f2a800105b77e665ec2a00c6290f35b1a2ba3.tar.gz chat-dc2f2a800105b77e665ec2a00c6290f35b1a2ba3.tar.bz2 chat-dc2f2a800105b77e665ec2a00c6290f35b1a2ba3.zip |
PLT-3145 Custom Emojis (#3381)
* Reorganized Backstage code to use a view controller and separated it from integrations code
* Renamed InstalledIntegrations component to BackstageList
* Added EmojiList page
* Added AddEmoji page
* Added custom emoji to autocomplete and text formatter
* Moved system emoji to EmojiStore
* Stopped trying to get emoji before logging in
* Rerender posts when emojis change
* Fixed submit handler on backstage pages to properly support enter
* Removed debugging code
* Updated javascript driver
* Fixed unit tests
* Fixed backstage routes
* Added clientside validation to prevent users from creating an emoji with the same name as a system one
* Fixed AddEmoji page to properly redirect when an emoji is created successfully
* Fixed updating emoji list when an emoji is deleted
* Added type prop to BackstageList to properly support using a table for the list
* Added help text to EmojiList
* Fixed backstage on smaller screen sizes
* Disable custom emoji by default
* Improved restrictions on creating emojis
* Fixed non-admin users seeing the option to delete each other's emojis
* Fixing gofmt
* Fixed emoji unit tests
* Fixed trying to get emoji from the server when it's disabled
Diffstat (limited to 'webapp/components/backstage/components/backstage_list.jsx')
-rw-r--r-- | webapp/components/backstage/components/backstage_list.jsx | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/webapp/components/backstage/components/backstage_list.jsx b/webapp/components/backstage/components/backstage_list.jsx new file mode 100644 index 000000000..81b8ec4d9 --- /dev/null +++ b/webapp/components/backstage/components/backstage_list.jsx @@ -0,0 +1,108 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +import React from 'react'; + +import * as Utils from 'utils/utils.jsx'; + +import {Link} from 'react-router'; +import LoadingScreen from 'components/loading_screen.jsx'; + +export default class BackstageList extends React.Component { + static propTypes = { + children: React.PropTypes.node, + header: React.PropTypes.node.isRequired, + addLink: React.PropTypes.string, + addText: React.PropTypes.node, + emptyText: React.PropTypes.node, + loading: React.PropTypes.bool.isRequired, + searchPlaceholder: React.PropTypes.string + } + + static defaultProps = { + searchPlaceholder: Utils.localizeMessage('backstage.search', 'Search') + } + + constructor(props) { + super(props); + + this.updateFilter = this.updateFilter.bind(this); + + this.state = { + filter: '' + }; + } + + updateFilter(e) { + this.setState({ + filter: e.target.value + }); + } + + render() { + const filter = this.state.filter.toLowerCase(); + + let children; + if (this.props.loading) { + children = <LoadingScreen/>; + } else { + children = React.Children.map(this.props.children, (child) => { + return React.cloneElement(child, {filter}); + }); + + if (children.length === 0 && this.props.emptyText) { + children = ( + <span className='backstage-list__item backstage-list__empty'> + {this.props.emptyText} + </span> + ); + } + } + + let addLink = null; + if (this.props.addLink && this.props.addText) { + addLink = ( + <Link + className='add-link' + to={this.props.addLink} + > + <button + type='button' + className='btn btn-primary' + > + <span> + {this.props.addText} + </span> + </button> + </Link> + ); + } + + return ( + <div className='backstage-content'> + <div className='backstage-header'> + <h1> + {this.props.header} + </h1> + {addLink} + </div> + <div className='backstage-filters'> + <div className='backstage-filter__search'> + <i className='fa fa-search'></i> + <input + type='search' + className='form-control' + placeholder={this.props.searchPlaceholder} + value={this.state.filter} + onChange={this.updateFilter} + style={{flexGrow: 0, flexShrink: 0}} + /> + </div> + </div> + <div className='backstage-list'> + {children} + </div> + </div> + ); + } +} |