Files
bodyshop/client/src/pages/phonebook/phonebook.page.component.jsx
2022-05-19 10:46:36 -07:00

218 lines
6.4 KiB
JavaScript

import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import _ from "lodash";
import queryString from "query-string";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useHistory, useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import AlertComponent from "../../components/alert/alert.component";
import { QUERY_PHONEBOOK_PAGINATED } from "../../graphql/phonebook.queries";
import {
selectAuthLevel,
selectBodyshop,
} from "../../redux/user/user.selectors";
import ChatOpenButton from "../../components/chat-open-button/chat-open-button.component";
import { alphaSort } from "../../utils/sorters";
import { HasRbacAccess } from "../../components/rbac-wrapper/rbac-wrapper.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
authLevel: selectAuthLevel,
});
export function PhonebookPageComponent({ bodyshop, authLevel }) {
const searchParams = queryString.parse(useLocation().search);
const { page, sortcolumn, sortorder, search, phonebookentry } = searchParams;
const history = useHistory();
const { loading, error, data, refetch } = useQuery(
QUERY_PHONEBOOK_PAGINATED,
{
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
search: search || "",
offset: page ? (page - 1) * 25 : 0,
limit: 25,
order: [
{
[sortcolumn || "lastname"]: sortorder
? sortorder === "descend"
? "desc"
: "asc"
: "asc",
},
],
},
}
);
const { t } = useTranslation();
if (error) return <AlertComponent message={error.message} type="error" />;
const handleTableChange = (pagination, filters, sorter) => {
searchParams.page = pagination.current;
searchParams.sortcolumn = sorter.columnKey;
searchParams.sortorder = sorter.order;
if (filters.status) {
searchParams.statusFilters = JSON.stringify(
_.flattenDeep(filters.status)
);
} else {
delete searchParams.statusFilters;
}
history.push({ search: queryString.stringify(searchParams) });
};
const columns = [
{
title: t("phonebook.fields.firstname"),
dataIndex: "firstname",
key: "firstname",
sorter: (a, b) => alphaSort(a.firstname, b.firstname),
sortOrder: sortcolumn === "firstname" && sortorder,
},
{
title: t("phonebook.fields.lastname"),
dataIndex: "lastname",
key: "lastname",
sorter: (a, b) => alphaSort(a.lastname, b.lastname),
sortOrder: sortcolumn === "lastname" && sortorder,
},
{
title: t("phonebook.fields.company"),
dataIndex: "company",
key: "company",
sorter: (a, b) => alphaSort(a.company, b.company),
sortOrder: sortcolumn === "company" && sortorder,
},
{
title: t("phonebook.fields.category"),
dataIndex: "category",
key: "category",
sorter: (a, b) => alphaSort(a.category, b.category),
sortOrder: sortcolumn === "category" && sortorder,
},
{
title: t("phonebook.fields.email"),
dataIndex: "email",
key: "email",
},
{
title: t("phonebook.fields.phone1"),
dataIndex: "phone1",
key: "phone1",
render: (text, record) => <ChatOpenButton phone={text} />,
},
{
title: t("phonebook.fields.phone2"),
dataIndex: "phone2",
key: "phone2",
render: (text, record) => <ChatOpenButton phone={text} />,
},
{
title: t("phonebook.fields.address1"),
dataIndex: "address1",
key: "address1",
},
{
title: t("phonebook.fields.city"),
dataIndex: "city",
key: "city",
},
];
const handleNewPhonebook = () => {
searchParams.phonebookentry = "new";
history.push({ search: queryString.stringify(searchParams) });
};
const handleOnRowClick = (record) => {
if (record) {
searchParams.phonebookentry = record.id;
history.push({ search: queryString.stringify(searchParams) });
} else {
delete searchParams.phonebookentry;
history.push({ search: queryString.stringify(searchParams) });
}
};
const hasNoAccess = !HasRbacAccess({
bodyshop,
authLevel,
action: "phonebook:edit",
});
return (
<Card
extra={
<Space wrap>
{searchParams.search && (
<>
<Typography.Title level={4}>
{t("general.labels.searchresults", {
search: searchParams.search,
})}
</Typography.Title>
<Button
onClick={() => {
delete searchParams.search;
searchParams.page = 1;
history.push({ search: queryString.stringify(searchParams) });
}}
>
{t("general.actions.clear")}
</Button>
</>
)}
<Button disabled={hasNoAccess} onClick={handleNewPhonebook}>
{t("phonebook.actions.new")}
</Button>
<Button onClick={() => refetch()}>
<SyncOutlined />
</Button>
<Input.Search
placeholder={searchParams.search || t("general.labels.search")}
onSearch={(value) => {
searchParams.search = value;
history.push({ search: queryString.stringify(searchParams) });
}}
/>
</Space>
}
>
<Table
loading={loading}
pagination={{
position: "top",
pageSize: 25,
current: parseInt(page || 1),
total: data && data.search_phonebook_aggregate.aggregate.count,
}}
columns={columns}
rowKey="id"
dataSource={data && data.search_phonebook}
//scroll={{ x: true }}
onChange={handleTableChange}
rowSelection={{
onSelect: handleOnRowClick,
type: "radio",
selectedRowKeys: [phonebookentry],
}}
onRow={(record, rowIndex) => {
return {
onClick: (event) => {
handleOnRowClick(record);
},
};
}}
/>
</Card>
);
}
export default connect(mapStateToProps, null)(PhonebookPageComponent);