Renamed NavbarDropdown to SidebarHeaderDropdown and switched it to react-bootstrap (#4109)

Этот коммит содержится в:
Harrison Healey
2016-09-29 10:58:30 -04:00
коммит произвёл GitHub
родитель ac6ae23c8e
Коммит 53ba8ec9c2
7 изменённых файлов: 194 добавлений и 161 удалений

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

@@ -82,20 +82,20 @@ export default class AdminNavbarDropdown extends React.Component {
} }
return ( return (
<ul className='nav navbar-nav navbar-right'> <ul className='nav navbar-nav navbar-right admin-navbar-dropdown'>
<li <li
ref='dropdown' ref='dropdown'
className='dropdown' className='dropdown'
> >
<a <a
href='#' href='#'
className='dropdown-toggle' className='dropdown-toggle admin-navbar-dropdown__toggle'
data-toggle='dropdown' data-toggle='dropdown'
role='button' role='button'
aria-expanded='false' aria-expanded='false'
> >
<span <span
className='dropdown__icon' className='dropdown__icon admin-navbar-dropdown__icon'
dangerouslySetInnerHTML={{__html: Constants.MENU_ICON}} dangerouslySetInnerHTML={{__html: Constants.MENU_ICON}}
/> />
</a> </a>

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

@@ -1,24 +1,18 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information. // See License.txt for license information.
import NavbarDropdown from './navbar_dropdown.jsx'; import React from 'react';
import 'bootstrap';
import PreferenceStore from 'stores/preference_store.jsx';
import * as Utils from 'utils/utils.jsx';
import Client from 'client/web_client.jsx'; import Client from 'client/web_client.jsx';
import Constants from 'utils/constants.jsx'; import PreferenceStore from 'stores/preference_store.jsx';
import * as Utils from 'utils/utils.jsx';
const Preferences = Constants.Preferences;
const TutorialSteps = Constants.TutorialSteps;
import SidebarHeaderDropdown from './sidebar_header_dropdown.jsx';
import {Tooltip, OverlayTrigger} from 'react-bootstrap'; import {Tooltip, OverlayTrigger} from 'react-bootstrap';
import {Preferences, TutorialSteps} from 'utils/constants.jsx';
import {createMenuTip} from 'components/tutorial/tutorial_tip.jsx'; import {createMenuTip} from 'components/tutorial/tutorial_tip.jsx';
import React from 'react';
export default class SidebarHeader extends React.Component { export default class SidebarHeader extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
@@ -28,34 +22,31 @@ export default class SidebarHeader extends React.Component {
this.state = this.getStateFromStores(); this.state = this.getStateFromStores();
} }
componentDidMount() { componentDidMount() {
PreferenceStore.addChangeListener(this.onPreferenceChange); PreferenceStore.addChangeListener(this.onPreferenceChange);
} }
componentWillUnmount() { componentWillUnmount() {
PreferenceStore.removeChangeListener(this.onPreferenceChange); PreferenceStore.removeChangeListener(this.onPreferenceChange);
} }
getStateFromStores() { getStateFromStores() {
const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, this.props.currentUser.id, 999); const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, this.props.currentUser.id, 999);
return {showTutorialTip: tutorialStep === TutorialSteps.MENU_POPOVER && !Utils.isMobile()}; return {showTutorialTip: tutorialStep === TutorialSteps.MENU_POPOVER && !Utils.isMobile()};
} }
onPreferenceChange() { onPreferenceChange() {
this.setState(this.getStateFromStores()); this.setState(this.getStateFromStores());
} }
toggleDropdown(e) { toggleDropdown(e) {
e.preventDefault(); e.preventDefault();
if (this.refs.dropdown.blockToggle) {
this.refs.dropdown.blockToggle = false;
return;
}
const menu = document.querySelector('.team__header .dropdown-toggle');
const isOpen = menu.parentElement.classList.toggle('open');
menu.setAttribute('aria-expanded', isOpen);
if (!isOpen) { this.refs.dropdown.toggleDropdown();
document.querySelector('.sidebar--left .dropdown-menu').scrollTop = 0;
}
} }
render() { render() {
var me = this.props.currentUser; var me = this.props.currentUser;
var profilePicture = null; var profilePicture = null;
@@ -99,13 +90,12 @@ export default class SidebarHeader extends React.Component {
</OverlayTrigger> </OverlayTrigger>
</div> </div>
</a> </a>
<NavbarDropdown <SidebarHeaderDropdown
ref='dropdown' ref='dropdown'
teamType={this.props.teamType} teamType={this.props.teamType}
teamDisplayName={this.props.teamDisplayName} teamDisplayName={this.props.teamDisplayName}
teamName={this.props.teamName} teamName={this.props.teamName}
currentUser={this.props.currentUser} currentUser={this.props.currentUser}
toggleDropdown={this.toggleDropdown}
/> />
</div> </div>
); );

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

@@ -1,6 +1,8 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information. // See License.txt for license information.
import $ from 'jquery';
import ReactDOM from 'react-dom';
import * as Utils from 'utils/utils.jsx'; import * as Utils from 'utils/utils.jsx';
import * as GlobalActions from 'actions/global_actions.jsx'; import * as GlobalActions from 'actions/global_actions.jsx';
@@ -14,18 +16,35 @@ import UserSettingsModal from './user_settings/user_settings_modal.jsx';
import {Constants, WebrtcActionTypes} from 'utils/constants.jsx'; import {Constants, WebrtcActionTypes} from 'utils/constants.jsx';
import {Dropdown} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl'; import {FormattedMessage} from 'react-intl';
import {Link} from 'react-router/es6'; import {Link} from 'react-router/es6';
import React from 'react'; import React from 'react';
export default class NavbarDropdown extends React.Component { export default class SidebarHeaderDropdown extends React.Component {
static propTypes = {
teamType: React.PropTypes.string,
teamDisplayName: React.PropTypes.string,
teamName: React.PropTypes.string,
currentUser: React.PropTypes.object
};
static defaultProps = {
teamType: ''
};
constructor(props) { constructor(props) {
super(props); super(props);
this.blockToggle = false;
this.toggleDropdown = this.toggleDropdown.bind(this);
this.handleAboutModal = this.handleAboutModal.bind(this); this.handleAboutModal = this.handleAboutModal.bind(this);
this.aboutModalDismissed = this.aboutModalDismissed.bind(this); this.aboutModalDismissed = this.aboutModalDismissed.bind(this);
this.toggleAccountSettingsModal = this.toggleAccountSettingsModal.bind(this);
this.showInviteMemberModal = this.showInviteMemberModal.bind(this);
this.showGetTeamInviteLinkModal = this.showGetTeamInviteLinkModal.bind(this);
this.onTeamChange = this.onTeamChange.bind(this); this.onTeamChange = this.onTeamChange.bind(this);
this.openAccountSettings = this.openAccountSettings.bind(this); this.openAccountSettings = this.openAccountSettings.bind(this);
@@ -34,10 +53,9 @@ export default class NavbarDropdown extends React.Component {
this.handleClick = this.handleClick.bind(this); this.handleClick = this.handleClick.bind(this);
this.state = { this.state = {
showUserSettingsModal: false,
showAboutModal: false,
teams: TeamStore.getAll(), teams: TeamStore.getAll(),
teamMembers: TeamStore.getTeamMembers() teamMembers: TeamStore.getTeamMembers(),
showDropdown: false
}; };
} }
@@ -48,14 +66,50 @@ export default class NavbarDropdown extends React.Component {
} }
} }
toggleDropdown(e) {
if (e) {
e.preventDefault();
}
this.setState({showDropdown: !this.state.showDropdown});
}
handleAboutModal() { handleAboutModal() {
this.setState({showAboutModal: true}); this.setState({
showAboutModal: true,
showDropdown: false
});
} }
aboutModalDismissed() { aboutModalDismissed() {
this.setState({showAboutModal: false}); this.setState({showAboutModal: false});
} }
toggleAccountSettingsModal(e) {
e.preventDefault();
this.setState({
showUserSettingsModal: !this.state.showUserSettingsModal,
showDropdown: false
});
}
showInviteMemberModal(e) {
e.preventDefault();
this.setState({showDropdown: false});
GlobalActions.showInviteMemberModal();
}
showGetTeamInviteLinkModal(e) {
e.preventDefault();
this.setState({showDropdown: false});
GlobalActions.showGetTeamInviteLinkModal();
}
componentDidMount() { componentDidMount() {
TeamStore.addChangeListener(this.onTeamChange); TeamStore.addChangeListener(this.onTeamChange);
document.addEventListener('keydown', this.openAccountSettings); document.addEventListener('keydown', this.openAccountSettings);
@@ -69,14 +123,14 @@ export default class NavbarDropdown extends React.Component {
} }
componentWillUnmount() { componentWillUnmount() {
$(ReactDOM.findDOMNode(this.refs.dropdown)).off('hide.bs.dropdown');
TeamStore.removeChangeListener(this.onTeamChange); TeamStore.removeChangeListener(this.onTeamChange);
document.removeEventListener('keydown', this.openAccountSettings); document.removeEventListener('keydown', this.openAccountSettings);
} }
openAccountSettings(e) { openAccountSettings(e) {
if (Utils.cmdOrCtrlPressed(e) && e.shiftKey && e.keyCode === Constants.KeyCodes.A) { if (Utils.cmdOrCtrlPressed(e) && e.shiftKey && e.keyCode === Constants.KeyCodes.A) {
e.preventDefault(); this.toggleAccountSettingsModal(e);
this.setState({showUserSettingsModal: !this.state.showUserSettingsModal});
} }
} }
@@ -101,7 +155,7 @@ export default class NavbarDropdown extends React.Component {
} }
render() { render() {
const config = global.window.mm_config; const config = global.mm_config;
var teamLink = ''; var teamLink = '';
var inviteLink = ''; var inviteLink = '';
var manageLink = ''; var manageLink = '';
@@ -124,7 +178,7 @@ export default class NavbarDropdown extends React.Component {
<li> <li>
<a <a
href='#' href='#'
onClick={GlobalActions.showInviteMemberModal} onClick={this.showInviteMemberModal}
> >
<FormattedMessage <FormattedMessage
id='navbar_dropdown.inviteMember' id='navbar_dropdown.inviteMember'
@@ -139,7 +193,7 @@ export default class NavbarDropdown extends React.Component {
<li> <li>
<a <a
href='#' href='#'
onClick={GlobalActions.showGetTeamInviteLinkModal} onClick={this.showGetTeamInviteLinkModal}
> >
<FormattedMessage <FormattedMessage
id='navbar_dropdown.teamLink' id='navbar_dropdown.teamLink'
@@ -197,6 +251,7 @@ export default class NavbarDropdown extends React.Component {
<ToggleModalButton <ToggleModalButton
dialogType={TeamMembersModal} dialogType={TeamMembersModal}
dialogProps={{isAdmin}} dialogProps={{isAdmin}}
onClick={this.toggleDropdown}
> >
{membersName} {membersName}
</ToggleModalButton> </ToggleModalButton>
@@ -362,99 +417,82 @@ export default class NavbarDropdown extends React.Component {
} }
return ( return (
<ul className='nav navbar-nav navbar-right'> <Dropdown
<li open={this.state.showDropdown}
ref='dropdown' onClose={this.toggleDropdown}
className='dropdown' className='sidebar-header-dropdown'
pullRight={true}
>
<a
href='#'
className='sidebar-header-dropdown__toggle'
bsRole='toggle'
onClick={this.toggleDropdown}
> >
<a <span
href='#' className='sidebar-header-dropdown__icon'
className='dropdown-toggle' dangerouslySetInnerHTML={{__html: Constants.MENU_ICON}}
role='button' />
onClick={this.props.toggleDropdown} </a>
> <Dropdown.Menu>
<span <li>
className='dropdown__icon' <a
dangerouslySetInnerHTML={{__html: Constants.MENU_ICON}} href='#'
/> onClick={this.toggleAccountSettingsModal}
</a> >
<ul <FormattedMessage
className='dropdown-menu' id='navbar_dropdown.accountSettings'
role='menu' defaultMessage='Account Settings'
> />
<li> </a>
<a </li>
href='#' {inviteLink}
onClick={(e) => { {teamLink}
e.preventDefault(); <li>
this.setState({showUserSettingsModal: true}); <a
}} href='#'
> onClick={GlobalActions.emitUserLoggedOutEvent}
<FormattedMessage >
id='navbar_dropdown.accountSettings' <FormattedMessage
defaultMessage='Account Settings' id='navbar_dropdown.logout'
/> defaultMessage='Logout'
</a> />
</li> </a>
{inviteLink} </li>
{teamLink} <li className='divider'/>
<li> {integrationsLink}
<a {this.renderCustomEmojiLink()}
href='#' <li className='divider'/>
onClick={GlobalActions.emitUserLoggedOutEvent} {teamSettings}
> {manageLink}
<FormattedMessage {sysAdminLink}
id='navbar_dropdown.logout' {teams}
defaultMessage='Logout' <li className='divider'/>
/> {helpLink}
</a> {reportLink}
</li> <li>
<li className='divider'/> <a
{integrationsLink} href='#'
{this.renderCustomEmojiLink()} onClick={this.handleAboutModal}
<li className='divider'/> >
{teamSettings} <FormattedMessage
{manageLink} id='navbar_dropdown.about'
{sysAdminLink} defaultMessage='About Mattermost'
{teams} />
<li className='divider'/> </a>
{helpLink} </li>
{reportLink} {nativeAppDivider}
<li> {nativeAppLink}
<a <UserSettingsModal
href='#' show={this.state.showUserSettingsModal}
onClick={this.handleAboutModal} onModalDismissed={() => this.setState({showUserSettingsModal: false})}
> />
<FormattedMessage <AboutBuildModal
id='navbar_dropdown.about' show={this.state.showAboutModal}
defaultMessage='About Mattermost' onModalDismissed={this.aboutModalDismissed}
/> />
</a> </Dropdown.Menu>
</li> </Dropdown>
{nativeAppDivider}
{nativeAppLink}
<UserSettingsModal
show={this.state.showUserSettingsModal}
onModalDismissed={() => this.setState({showUserSettingsModal: false})}
/>
<AboutBuildModal
show={this.state.showAboutModal}
onModalDismissed={this.aboutModalDismissed}
/>
</ul>
</li>
</ul>
); );
} }
} }
NavbarDropdown.defaultProps = {
teamType: ''
};
NavbarDropdown.propTypes = {
teamType: React.PropTypes.string,
teamDisplayName: React.PropTypes.string,
teamName: React.PropTypes.string,
currentUser: React.PropTypes.object,
toggleDropdown: React.PropTypes.function
};

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

@@ -244,14 +244,16 @@
@include alpha-property(background, $black, .1); @include alpha-property(background, $black, .1);
} }
a {
text-decoration: none;
}
.user__name { .user__name {
color: $white; color: $white;
} }
.sidebar-header-dropdown {
.sidebar-header-dropdown__toggle {
@include opacity(1);
}
}
.navbar-right { .navbar-right {
.dropdown-toggle { .dropdown-toggle {
@include opacity(1); @include opacity(1);
@@ -259,16 +261,28 @@
} }
} }
.navbar-right { a {
text-decoration: none;
}
.sidebar-header-dropdown,
.admin-navbar-dropdown {
font-size: .85em; font-size: .85em;
position: absolute; position: absolute;
margin-right: -15px;
right: 22px; right: 22px;
top: 10px; top: 10px;
z-index: 5; z-index: 5;
.dropdown-toggle { .sidebar-header-dropdown__toggle,
.admin-navbar-dropdown__toggle {
@include opacity(.8); @include opacity(.8);
@include single-transition(all, .1s, linear); @include single-transition(all, .1s, linear);
background: none;
color: $white;
float: right;
font-size: 1em;
line-height: 1.8;
padding: 10px; padding: 10px;
} }
@@ -284,9 +298,14 @@
} }
} }
.dropdown__icon { .sidebar-header-dropdown__icon,
.admin-navbar-dropdown__icon {
fill: $white; fill: $white;
} }
.divider + .divider {
display: none;
}
} }
.user__picture { .user__picture {
@@ -330,22 +349,6 @@
font-weight: 400; font-weight: 400;
line-height: 18px; line-height: 18px;
} }
> .nav {
> li {
> a {
background: none;
float: right;
padding: 2px;
}
.dropdown-toggle {
color: $white;
font-size: 1em;
line-height: 1.8;
}
}
}
} }
.search__clear { .search__clear {

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

@@ -824,7 +824,7 @@
margin: 10px 0; margin: 10px 0;
} }
.navbar-right { .sidebar-header-dropdown {
display: none; display: none;
} }
} }

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

@@ -197,12 +197,20 @@ export const SocketEvents = {
WEBRTC: 'webrtc' WEBRTC: 'webrtc'
}; };
export const TutorialSteps = {
INTRO_SCREENS: 0,
POST_POPOVER: 1,
CHANNEL_POPOVER: 2,
MENU_POPOVER: 3
};
export const Constants = { export const Constants = {
Preferences, Preferences,
SocketEvents, SocketEvents,
ActionTypes, ActionTypes,
WebrtcActionTypes, WebrtcActionTypes,
UserStatuses, UserStatuses,
TutorialSteps,
PayloadSources: keyMirror({ PayloadSources: keyMirror({
SERVER_ACTION: null, SERVER_ACTION: null,
@@ -614,12 +622,6 @@ export const Constants = {
Ubuntu: 'font--ubuntu' Ubuntu: 'font--ubuntu'
}, },
DEFAULT_FONT: 'Open Sans', DEFAULT_FONT: 'Open Sans',
TutorialSteps: {
INTRO_SCREENS: 0,
POST_POPOVER: 1,
CHANNEL_POPOVER: 2,
MENU_POPOVER: 3
},
KeyCodes: { KeyCodes: {
BACKSPACE: 8, BACKSPACE: 8,
TAB: 9, TAB: 9,

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

@@ -522,7 +522,7 @@ export function applyTheme(theme) {
if (theme.sidebarHeaderTextColor) { if (theme.sidebarHeaderTextColor) {
changeCss('.app__body .sidebar--left .team__header .header__info, .app__body .sidebar--menu .team__header .header__info, .app__body .post-list__timestamp > div', 'color:' + theme.sidebarHeaderTextColor, 1); changeCss('.app__body .sidebar--left .team__header .header__info, .app__body .sidebar--menu .team__header .header__info, .app__body .post-list__timestamp > div', 'color:' + theme.sidebarHeaderTextColor, 1);
changeCss('.app__body .sidebar--left .team__header .navbar-right .dropdown__icon, .app__body .sidebar--menu .team__header .navbar-right .dropdown__icon', 'fill:' + theme.sidebarHeaderTextColor, 1); changeCss('.app__body .sidebar-header-dropdown__icon', 'fill:' + theme.sidebarHeaderTextColor, 1);
changeCss('.app__body .sidebar--left .team__header .user__name, .app__body .sidebar--menu .team__header .user__name', 'color:' + changeOpacity(theme.sidebarHeaderTextColor, 0.8), 1); changeCss('.app__body .sidebar--left .team__header .user__name, .app__body .sidebar--menu .team__header .user__name', 'color:' + changeOpacity(theme.sidebarHeaderTextColor, 0.8), 1);
changeCss('.app__body .sidebar--left .team__header:hover .user__name, .app__body .sidebar--menu .team__header:hover .user__name', 'color:' + theme.sidebarHeaderTextColor, 1); changeCss('.app__body .sidebar--left .team__header:hover .user__name, .app__body .sidebar--menu .team__header:hover .user__name', 'color:' + theme.sidebarHeaderTextColor, 1);
changeCss('.app__body .modal .modal-header .modal-title, .app__body .modal .modal-header .modal-title .name, .app__body .modal .modal-header button.close', 'color:' + theme.sidebarHeaderTextColor, 1); changeCss('.app__body .modal .modal-header .modal-title, .app__body .modal .modal-header .modal-title .name, .app__body .modal .modal-header button.close', 'color:' + theme.sidebarHeaderTextColor, 1);