Home Reference Source

application/components/tag.js

import React from 'react';
import Immutable from 'immutable';
import {connect} from 'react-redux';

import {browserHistory, Link} from 'react-router';
import RaisedButton from 'material-ui/RaisedButton';
import FontIcon from 'material-ui/FontIcon';
import IconAdd from 'material-ui/svg-icons/content/add';
import {Toolbar, ToolbarGroup, ToolbarSeparator, ToolbarTitle} from 'material-ui/Toolbar';
import Paper from 'material-ui/Paper';

import {
    tagsFetch,
    tagsRemove
} from './../redux/actions/tag-actions';

import {
    snackbarShowMessage
} from './../redux/actions/snackbar-actions';

import {
    alertShowMessage
} from './../redux/actions/alert-actions';

import TagTable from './tag/tag-table';

import LoadingIndicator from './common/loading-indicator';
import ReduxPaginator from './common/redux-paginator';
import DeleteButton from './common/delete-button';

import {parameterize} from './../util/strings';

import {Row, Col} from './flexbox';

import CurrentUser from './../current-user';

import request from './../util/request';
import {ENTER_KEY} from './../util/key-codes';

class Tag extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            selectedItems: []
        };
    }

    componentWillMount() {
        const page = (this.props.location && this.props.location.query.page)
            ? this.props.location.query.page
            : 1;

        const keyword = (this.props.location && this.props.location.query.keyword)
            ? decodeURIComponent(this.props.location.query.keyword)
            : null;

        let params = {page: page, limit: 40};
        if (keyword) {
            params['keyword'] = keyword;
        }

        const {dispatch} = this.props;
        dispatch(tagsFetch(params));
    }

    handlePagination(page) {
        if (this.props.tags.pagination.current == page) {
            return;
        }

        const keyword = (this.props.location && this.props.location.query.keyword)
            ? decodeURIComponent(this.props.location.query.keyword)
            : null;

        let params = {page: page, limit: 40};
        if (keyword) {
            params['keyword'] = keyword;
        }

        const {dispatch} = this.props;
        dispatch(tagsFetch(params));
    }

    handleKeyDown(e) {
        const val = e.target.value;
        if (e.keyCode !== ENTER_KEY) {
            return;
        }

        const {dispatch} = this.props;

        const q = request.setQuery({
            'keyword': encodeURIComponent(val),
            'page': 1
        });
        const this_url = request.getPath() + '?' + q;
        browserHistory.push(this_url);

        dispatch(tagsFetch({page: 1, limit: 40, keyword: val}));
    }

    handleSearchReset() {
        const {dispatch} = this.props;
        const q = request.setQuery({
            'keyword': '',
            'page': 1
        });
        const this_url = request.getPath() + '?' + q;
        browserHistory.push(this_url);

        dispatch(tagsFetch({page: 1}));
    }

    handleDelete() {
        const {dispatch} = this.props;
        dispatch(tagsRemove(this.state.selectedItems.join(',')))
            .then(() => {
                this.setState({'selectedItems': []});
                dispatch(snackbarShowMessage('Tags updated'));
            })
            .then(() => {
                const page = (this.props.location && this.props.location.query.page)
                    ? this.props.location.query.page
                    : 1;

                const keyword = (this.props.location && this.props.location.query.keyword)
                    ? decodeURIComponent(this.props.location.query.keyword)
                    : null;

                let params = {page: page, limit: 40};
                if (keyword) {
                    params['keyword'] = keyword;
                }

                const {dispatch} = this.props;
                dispatch(tagsFetch(params));
            })
            .catch(() => {
                this.setState({'selectedItems': []});
                dispatch(alertShowMessage({
                    title: 'Oops',
                    message: (
                        <p>Unable to remove tags, you may not have delete permission.</p>
                    )
                }));
            });
    }

    handleRowSelection(selected) {
        let selectedItems = [];

        if (!selected || selected == 'none') {
            this.setState({'selectedItems': []});
            return;
        }

        if (selected == 'all') {
            selectedItems = this.props.tags.items
                .map((tag) => tag.get('uuid'))
                .toList()
                .toJS();
        } else {
            selectedItems = selected.map((i) => this.props.tags.items.toList().get(i).get('uuid'));
        }

        this.setState({'selectedItems': selectedItems});
    }

    render() {

        if (this.props.tags.isFetching) {
            return <LoadingIndicator />;
        }

        return (
            <div className="tag-root">
                <Row>
                    <Col xs={12}>
                        <Paper className='toolbar'>
                            <Row middle='xs'>
                                <Col xs={3} autoBox={false}>
                                    <div className="box toolbar-search-wrap">
                                        <FontIcon className='mui-icons'>search</FontIcon>
                                        <input
                                            className="search"
                                            type="text"
                                            placeholder="Search Tags"
                                            onKeyDown={this.handleKeyDown.bind(this)}
                                            defaultValue={this.props.location.query.keyword ? decodeURIComponent(this.props.location.query.keyword) : ''}
                                            />
                                        <FontIcon className='mui-icons clear-search' onClick={this.handleSearchReset.bind(this)}>close</FontIcon>
                                    </div>
                                </Col>
                                <Col xs={4}>
                                    <DeleteButton
                                        disabled={this.state.selectedItems && this.state.selectedItems.length ? false : true}
                                        onDelete={this.handleDelete.bind(this)}
                                        />
                                    <RaisedButton
                                        containerElement={<Link to='/ceo/settings/tag/new' />}
                                        primary={true}
                                        icon={<IconAdd />}
                                        />
                                </Col>
                                <Col xs={5} end='xs'>
                                    <ReduxPaginator
                                        pagination={this.props.tags.pagination}
                                        onPaginate={this.handlePagination.bind(this)}
                                        />
                                </Col>
                            </Row>
                        </Paper>

                        <Paper className='padded clear-bottom'>
                            <TagTable
                                tags={this.props.tags}
                                onRowSelection={this.handleRowSelection.bind(this)}
                                />
                        </Paper>
                    </Col>
                </Row>
            </div>
        );
    }
}

const mapStateToProps = (state) => {
    return {
        tags: state.tags
    };
}

export default connect(mapStateToProps)(Tag);