surrsoft
10/11/2019 - 9:06 AM

AccessRequestsContainer.jsx

import React, { Component, Fragment } from 'react';
import { Link, withRouter } from 'react-router-dom';
import { compose, graphql } from 'react-apollo';
import {
  Avatar, Button, message, notification, Popconfirm, Table, Tag,
} from 'antd';
import queryString from 'querystring';
import { trim } from 'lodash';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import HeaderView from '../TableView/headerView';
import FilterView from '../TableView/filterView';
import SearchField from '../SearchField';
import CategoryFilter from '../CategoryFilter';
import { APPS_QUERY, CATEGORIES_QUERY, DELETE_APPLICATION_MUTATION, ACCESS_REQUEST_LIST } from '../../api/queries';
import { getImageUrl } from '../UploadDecorator';
import LogoPlaceholder from '../LogoPlaceholder';
import ProductType from '../ProductType';
import sideBarActions from '../../actions/sideBar';


const pageSizes = ['10', '20', '50'];
const stringApplicationRoute = '/accessrequests';
const buildQueryVars = ({ location: { search } }) => {
  const query = queryString.parse(trim(search, '?'));
  const {
    productType, category, page, onPage,
  } = query;
  const filter = {
    search: query.search || undefined,
    type: productType || undefined,
    categories: category ? [category] : undefined,
  };
  const intPerPage = parseInt(onPage, 10);
  const take = !Number.isNaN(intPerPage) && pageSizes.indexOf(onPage) > -1 ? intPerPage : undefined;
  const intPage = parseInt(page, 10);
  const currentPage = !Number.isNaN(intPage) && intPage > 1 ? intPage : 1;
  const skip = take ? (currentPage - 1) * take : (currentPage - 1) * 10;
  return { filter, skip, take };
};

@compose(
  graphql(ACCESS_REQUEST_LIST, {
    name: 'getApplications',
    options: props => ({
      variables: buildQueryVars(props),
      fetchPolicy: 'network-only',
    }),
  }),
  graphql(DELETE_APPLICATION_MUTATION, { name: 'deleteApplication' }),
  graphql(CATEGORIES_QUERY, { name: 'getCategoriesApplication' }),
)
@connect(
  state => ({ sideBar: state.sideBar }),
  dispatch => bindActionCreators(sideBarActions, dispatch),
)
@withRouter
class ApplicationsContainer extends Component {
  columns = [{
    title: '',
    dataIndex: 'logo',
    key: 'logo',
    type: 'logo',
    render: (logo) => {
      if (logo && logo.path !== null) {
        return (<Avatar src={getImageUrl(logo)} shape="square" />);
      }
      return (<LogoPlaceholder width={32} height={32} fontSize={9} />);
    },
  }, {
    title: 'Name',
    dataIndex: 'name',
    key: 'name',
    render: (text, record) => (
      <Link to={`${stringApplicationRoute}/${record.id}`}> {text} </Link>
    ),
  }, {
    title: 'Type',
    dataIndex: 'type',
    key: 'type',
    render: (item) => {
      if (item === 'Agent') {
        return 'Bot';
      }
      return 'App';
    },
  }, {
    title: 'Category',
    dataIndex: 'categories',
    key: 'categories',
    render: (items) => {
      if (items) {
        return items.map(item => (
          <Tag
            key={item.name}
            onClick={() => {
              this.handleCategoryChange(item.id);
            }}
            color="magenta"
          >{item.name}
          </Tag>
        ));
      }
      return '';
    },
  }, {
    title: '',
    dataIndex: 'action',
    width: 100,
    render: (text, record) => (
      <div>
        <Button
          shape="circle"
          size="small"
          icon="edit"
          title="Edit"
          htmlType="button"
          onClick={() => { this.handleEditApp(record); }}
        />
        {' '}
        <Popconfirm
          title="Are you sure delete this application?"
          onConfirm={() => { this.handleDeleteApp(record); }}
          okText="Yes"
          cancelText="No"
        >
          <Button
            type="danger"
            shape="circle"
            size="small"
            icon="delete"
            title="Delete"
            htmlType="button"
          />
        </Popconfirm>
      </div>
    ),
  }];

  componentWillMount() {
    const { setSideBarObj } = this.props;
    const clientMenuTemplate = {
      sideBarChildren: [
        {
          title: 'Categories',
          action: 'link',
          icon: 'tags',
          link: '/categories',
          key: 'categories',
        },
        {
          title: 'Add apps',
          icon: 'plus-circle-o',
          action: 'button',
          buttonAction: this.handleAddApplication,
          key: 'addApplication',
        },
      ],
    };
    setSideBarObj({ sideBarObj: clientMenuTemplate });
  }

  getProductCategories() {
    const { getCategoriesApplication: { categories } } = this.props;
    return categories || [];
  }

  getTableData() {
    console.log('!!-!!-!!NN -> getTableData() {10/11/19-11:38 AM-169}'); //del
    console.log('!!-!!-!! this.props {191011114045}\n', this.props); //del
    const { getApplications: { accessRequests, countAccessRequests } } = this.props;
    return { applications: accessRequests || [], countAccessRequests };
  }

  handleDeleteApp = (app) => {
    const { deleteApplication } = this.props;
    deleteApplication({ variables: { id: app.id } })
      .then(() => {
        message.success('Application Deleted Successfully!');
        const { getApplications } = this.props;
        getApplications.refetch();
      })
      .catch((err) => {
        notification.error({ message: 'Application Delete Error', description: err.message });
      });
  };

  handleEditApp = (app) => {
    const { history } = this.props;
    history.push({
      pathname: `${stringApplicationRoute}/${app.id}/edit`,
    });
  };

  handleCategoryChange = (productCategory) => {
    this.fetchDataWithParameters({ category: productCategory, page: '' });
  };

  handleTypeChange = (productType) => {
    this.fetchDataWithParameters({ productType, page: '' });
  };

  handleSearch = (searchValue) => {
    this.fetchDataWithParameters({ search: searchValue });
  };

  handlePagination = (pagination) => {
    const { location } = this.props;
    const { take } = buildQueryVars({ location });
    const params = {
      onPage: pagination.pageSize === 10 ? undefined : pagination.pageSize,
      page: (pagination.pageSize !== take && take !== undefined) || pagination.current === 1
        ? undefined : pagination.current,
    };
    this.fetchDataWithParameters(params);
  };

  handleAddApplication = () => {
    const { history } = this.props;
    history.push({
      pathname: `${stringApplicationRoute}/add`,
    });
  };

  fetchDataWithParameters = (updated) => {
    const { history, location } = this.props;
    const query = buildQueryVars({ location });
    const params = {
      search: query.filter.search,
      category: query.filter.categories ? query.filter.categories[0] : undefined,
      productType: query.filter.type,
      page: (query.skip !== 0) ? query.skip : undefined,
      onPage: query.take,
      ...updated,
    };
    const keys = Object.keys(params);
    keys.forEach((key) => {
      if (params[key] === undefined || params[key] === '') {
        delete params[key];
      }
    });
    history.push({
      pathname: stringApplicationRoute,
      search: queryString.stringify(params),
    });
  };

  render() {
    const { location } = this.props;
    const { filter, skip, take } = buildQueryVars({ location });
    const { type, categories, search } = filter;
    const category = categories ? categories[0] : '';
    const productType = type || '';
    const searchValue = search || '';
    const currentTake = take || 10;
    const { applications, countApplications } = this.getTableData();
    const pagination = {
      current: (skip / currentTake + 1) || 1,
      pageSize: currentTake,
      total: countApplications,
      showSizeChanger: true,
      pageSizeOptions: pageSizes,
      position: 'bottom',
    };
    return (
      <div className="main_content">
        <HeaderView
          title="Access Requests"
          count={pagination.total}
          actions={(
            <>
              <SearchField
                value={searchValue}
                onChange={this.handleSearch}
                placeholder="Search"
              />
              <Button
                style={{ marginLeft: '16px' }}
                type="primary"
                htmlType="button"
                icon="plus-circle-o"
                onClick={this.handleAddApplication}
              > Add app
              </Button>
            </>
          )
          }
        >
          <FilterView
            myStyle={{ marginBottom: '0' }}
            filters={(
              <Fragment>
                <ProductType
                  type={productType}
                  onTypeChange={this.handleTypeChange}
                />
                <CategoryFilter
                  categories={this.getProductCategories()}
                  productCategory={category}
                  handleCategoryChange={this.handleCategoryChange}
                />
              </Fragment>)}
          />
        </HeaderView>
        <Table
          rowKey="id"
          size="middle"
          columns={this.columns}
          dataSource={applications}
          pagination={pagination}
          onChange={this.handlePagination}
          className="userList"
        />
      </div>
    );
  }
}

export default ApplicationsContainer;