Files
bodyshop/client/src/pages/phonebook/phonebook.page.component.jsx

205 lines
6.2 KiB
JavaScript

import { SyncOutlined } from "@ant-design/icons";
import { useQuery } from "@apollo/client/react";
import { Button, Card, Input, Space, Table, Typography } from "antd";
import _ from "lodash";
import queryString from "query-string";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { useLocation, useNavigate } 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";
import { pageLimit } from "../../utils/config";
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 = useNavigate();
const { loading, error, data, refetch } = useQuery(QUERY_PHONEBOOK_PAGINATED, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
variables: {
search: search || "",
offset: page ? (page - 1) * pageLimit : 0,
limit: pageLimit,
order: [
{
[sortcolumn || "lastname"]: sortorder ? (sortorder === "descend" ? "desc" : "asc") : "asc"
}
]
}
});
const { t } = useTranslation();
if (error) return <AlertComponent title={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({ 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) => <ChatOpenButton phone={text} />
},
{
title: t("phonebook.fields.phone2"),
dataIndex: "phone2",
key: "phone2",
render: (text) => <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({ search: queryString.stringify(searchParams) });
};
const handleOnRowClick = (record) => {
if (record) {
searchParams.phonebookentry = record.id;
history({ search: queryString.stringify(searchParams) });
} else {
delete searchParams.phonebookentry;
history({ 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({ search: queryString.stringify(searchParams) });
}}
>
{t("general.actions.clear")}
</Button>
</>
)}
<Button disabled={hasNoAccess} onClick={handleNewPhonebook}>
{t("phonebook.actions.new")}
</Button>
<Button onClick={() => refetch()} icon={<SyncOutlined />} />
<Input.Search
placeholder={searchParams.search || t("general.labels.search")}
onSearch={(value) => {
searchParams.search = value;
searchParams.page = 1;
history({ search: queryString.stringify(searchParams) });
}}
/>
</Space>
}
>
<Table
loading={loading}
pagination={{
placement: "top",
pageSize: pageLimit,
current: parseInt(page || 1, 10),
total: data && data.search_phonebook_aggregate.aggregate.count
}}
columns={columns}
rowKey="id"
dataSource={data?.search_phonebook}
//scroll={{ x: true }}
onChange={handleTableChange}
rowSelection={{
onSelect: handleOnRowClick,
type: "radio",
selectedRowKeys: [phonebookentry]
}}
onRow={(record) => {
return {
onClick: () => {
handleOnRowClick(record);
}
};
}}
/>
</Card>
);
}
export default connect(mapStateToProps, null)(PhonebookPageComponent);