Skip to content

Instantly share code, notes, and snippets.

@konstantin24121
Created May 1, 2018 08:38
Show Gist options
  • Select an option

  • Save konstantin24121/cd1784015ef03c770004652c743c3816 to your computer and use it in GitHub Desktop.

Select an option

Save konstantin24121/cd1784015ef03c770004652c743c3816 to your computer and use it in GitHub Desktop.

Revisions

  1. konstantin24121 created this gist May 1, 2018.
    144 changes: 144 additions & 0 deletions UserPanel.jsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,144 @@
    import React from 'react';
    import PropTypes from 'prop-types';
    import { connect } from 'react-redux';
    import { withRouter } from 'react-router-dom';
    import * as routes from 'config/routes';

    import { ACTIONS as authActions } from 'redux/modules/auth';
    import { ACTIONS as sitesActions, TYPES as SITES_TYPES } from 'redux/modules/sites';

    import { Dropdown, Menu, Avatar, Select, Tooltip } from 'antd';
    import { Icon, Link, Indent } from 'components';

    import { Root, User, selectStyles } from './UserPanelStyled';

    const { Item } = Menu;
    const { Option } = Select;

    class UserPanel extends React.Component {
    componentWillMount() {
    this.props.fetchSites();
    }

    componentWillReceiveProps(nextProps) {
    const { location } = nextProps;
    if (location.state && location.state.action === SITES_TYPES.setActiveSite) {
    this.props.setActiveSite(location.state.siteId);
    }
    }

    handleRedirectAndChangeSite = (siteId) => {
    const { history } = this.props;
    history.push(routes.MAIN_PAGE.route, { action: SITES_TYPES.setActiveSite, siteId });
    }

    handleEvent = ({ key }) => {
    this.props[key]();
    }

    renderMenu() {
    return (
    <Menu onClick={this.handleEvent}>
    <Item key="logout">
    <Link>
    <Icon type="logout" /> Выйти
    </Link>
    </Item>
    </Menu>
    );
    }

    renderSiteSelect = () => {
    const { sitesIsLoading, sitesFetchError, sitesList, activeSite } = this.props;
    const disableSelect = sitesIsLoading || sitesFetchError;
    const value = !disableSelect ? activeSite : undefined;
    const emptyList = sitesList.length === 0;
    let placeholder = null;
    if (sitesIsLoading) {
    placeholder = <Icon type="loading" />;
    } else if (sitesFetchError) {
    placeholder = (
    <Tooltip title="Ошибка загрузки списка сайтов">
    <Icon type="exclamation-circle" color="error" />
    </Tooltip>
    );
    } else if (emptyList) {
    placeholder = 'Нет сайтов';
    }
    const options = sitesList.map(({
    id, url,
    }) => (
    <Option key={id} value={id} title="">
    <Tooltip title={url} placement="left">{url}</Tooltip>
    </Option>
    ));

    return (
    <Select
    defaultActiveFirstOption
    placeholder={placeholder}
    disabled={disableSelect || emptyList}
    showArrow={!disableSelect}
    value={emptyList ? undefined : value}
    style={selectStyles}
    onChange={this.handleRedirectAndChangeSite}
    >
    {options}
    </Select>
    );
    }

    render() {
    const { isAuthenticated, userName } = this.props;
    if (!isAuthenticated) return null;
    const menu = this.renderMenu();
    return (
    <Root>
    {this.renderSiteSelect()}
    <Indent left={2} lineHeight={0}>
    <Dropdown overlay={menu} trigger={['click']}>
    <Link>
    <User>
    <Indent right={1} lineHeight={0}>
    <Avatar icon="user" size="small" />
    </Indent>
    {userName}
    </User>
    </Link>
    </Dropdown>
    </Indent>
    </Root>
    );
    }
    }

    UserPanel.propTypes = {
    location: PropTypes.object.isRequired,
    history: PropTypes.object.isRequired,
    isAuthenticated: PropTypes.bool.isRequired,
    userName: PropTypes.string.isRequired,
    sitesIsLoading: PropTypes.bool.isRequired,
    sitesFetchError: PropTypes.bool.isRequired,
    sitesList: PropTypes.array,
    activeSite: PropTypes.number,
    logout: PropTypes.func.isRequired,
    fetchSites: PropTypes.func.isRequired,
    setActiveSite: PropTypes.func.isRequired,
    };

    const mapStateToProps = (state) => ({
    isAuthenticated: state.auth.isAuthenticated,
    userName: state.user.userName,
    sitesIsLoading: state.sites.isLoading,
    sitesFetchError: state.sites.isError,
    sitesList: state.sites.list,
    activeSite: state.sites.activeId,
    });

    const actions = {
    logout: authActions.logout,
    fetchSites: sitesActions.fetchSites,
    setActiveSite: sitesActions.setActiveSite,
    };

    export default withRouter(connect(mapStateToProps, actions)(UserPanel));
    22 changes: 22 additions & 0 deletions UserPanelStyled.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    import styled, { css } from 'styled-components';

    export const Root = styled.div`
    display: flex;
    justify-content: flex-end;
    align-items: center;
    `;

    const selectStyles = () => ({
    width: 170,
    });

    const applyUserStyles = ({ theme }) => css`
    font-size: ${theme.fontSizeBase};
    color: ${theme.textColor};
    `;

    export const User = styled.div`
    display: flex;
    align-items: center;
    ${applyUserStyles}
    `;