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;