diff --git a/client/src/components/contracts-list/contracts-list.component.jsx b/client/src/components/contracts-list/contracts-list.component.jsx
index 3a0ee8eaf..c7c0b261f 100644
--- a/client/src/components/contracts-list/contracts-list.component.jsx
+++ b/client/src/components/contracts-list/contracts-list.component.jsx
@@ -1,15 +1,21 @@
-import { Table } from "antd";
+import { Table, Button, Input } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
-import { Link } from "react-router-dom";
+import { Link, useHistory, useLocation } from "react-router-dom";
import { alphaSort } from "../../utils/sorters";
-import { DateFormatter } from "../../utils/DateFormatter";
+import { DateFormatter, DateTimeFormatter } from "../../utils/DateFormatter";
+import queryString from "query-string";
+import { SyncOutlined } from "@ant-design/icons";
+import TimeTicketsDatesSelector from "../ticket-tickets-dates-selector/time-tickets-dates-selector.component";
-export default function ContractsList({ loading, contracts }) {
+export default function ContractsList({ loading, contracts, refetch, total }) {
const [state, setState] = useState({
sortedInfo: {},
- filteredInfo: { text: "" }
+ filteredInfo: { text: "" },
});
+ const history = useHistory();
+ const search = queryString.parse(useLocation().search);
+ const { page } = search;
const { t } = useTranslation();
@@ -26,21 +32,17 @@ export default function ContractsList({ loading, contracts }) {
{record.agreementnumber || ""}
- )
+ ),
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "job.ro_number",
key: "job.ro_number",
- sorter: (a, b) => alphaSort(a.job.ro_number, b.job.ro_number),
- sortOrder:
- state.sortedInfo.columnKey === "job.ro_number" &&
- state.sortedInfo.order,
render: (text, record) => (
{record.job.ro_number || ""}
- )
+ ),
},
{
title: t("contracts.fields.driver"),
@@ -50,7 +52,7 @@ export default function ContractsList({ loading, contracts }) {
sortOrder:
state.sortedInfo.columnKey === "driver_ln" && state.sortedInfo.order,
render: (text, record) =>
- `${record.driver_fn || ""} ${record.driver_ln || ""}`
+ `${record.driver_fn || ""} ${record.driver_ln || ""}`,
},
{
title: t("contracts.fields.status"),
@@ -59,7 +61,7 @@ export default function ContractsList({ loading, contracts }) {
sorter: (a, b) => alphaSort(a.status, b.status),
sortOrder:
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
- render: (text, record) => t(record.status)
+ render: (text, record) => t(record.status),
},
{
title: t("contracts.fields.start"),
@@ -68,7 +70,9 @@ export default function ContractsList({ loading, contracts }) {
sorter: (a, b) => alphaSort(a.start, b.start),
sortOrder:
state.sortedInfo.columnKey === "start" && state.sortedInfo.order,
- render: (text, record) => {record.start}
+ render: (text, record) => (
+ {record.start}
+ ),
},
{
title: t("contracts.fields.scheduledreturn"),
@@ -79,21 +83,61 @@ export default function ContractsList({ loading, contracts }) {
state.sortedInfo.columnKey === "scheduledreturn" &&
state.sortedInfo.order,
render: (text, record) => (
- {record.scheduledreturn}
- )
- }
+ {record.scheduledreturn}
+ ),
+ },
+ {
+ title: t("contracts.fields.actualreturn"),
+ dataIndex: "actualreturn",
+ key: "actualreturn",
+ sorter: (a, b) => alphaSort(a.actualreturn, b.actualreturn),
+ sortOrder:
+ state.sortedInfo.columnKey === "actualreturn" && state.sortedInfo.order,
+ render: (text, record) => (
+ {record.actualreturn}
+ ),
+ },
];
const handleTableChange = (pagination, filters, sorter) => {
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
+ search.page = pagination.current;
+ search.sortcolumn = sorter.columnKey;
+ search.sortorder = sorter.order;
+ history.push({ search: queryString.stringify(search) });
};
return (
(
+
+
+
+
+
+
+ {
+ search.search = value;
+ history.push({ search: queryString.stringify(search) });
+ }}
+ />
+
+
+ )}
size="small"
- pagination={{ position: "top" }}
- columns={columns.map(item => ({ ...item }))}
+ scroll={{ x: "50%", y: "40rem" }}
+ pagination={{
+ position: "top",
+ pageSize: 25,
+ current: parseInt(page || 1),
+ total: total,
+ }}
+ columns={columns}
rowKey="id"
dataSource={contracts}
onChange={handleTableChange}
diff --git a/client/src/components/ticket-tickets-dates-selector/time-tickets-dates-selector.component.jsx b/client/src/components/ticket-tickets-dates-selector/time-tickets-dates-selector.component.jsx
index 261d9623f..65fe93ae9 100644
--- a/client/src/components/ticket-tickets-dates-selector/time-tickets-dates-selector.component.jsx
+++ b/client/src/components/ticket-tickets-dates-selector/time-tickets-dates-selector.component.jsx
@@ -10,13 +10,22 @@ export default function TimeTicketsDatesSelector() {
const history = useHistory();
const handleChange = (dates) => {
- const [start, end] = dates;
+ if (dates) {
+ const [start, end] = dates;
- if (!!start && !!end) {
+ if (!!start && !!end) {
+ history.push({
+ search: queryString.stringify({
+ start: start.format("YYYY-MM-DD"),
+ end: end.format("YYYY-MM-DD"),
+ }),
+ });
+ }
+ } else {
history.push({
search: queryString.stringify({
- start: start.format("YYYY-MM-DD"),
- end: end.format("YYYY-MM-DD"),
+ start: null,
+ end: null,
}),
});
}
diff --git a/client/src/graphql/cccontracts.queries.js b/client/src/graphql/cccontracts.queries.js
index a8c23eb95..ebd6656b0 100644
--- a/client/src/graphql/cccontracts.queries.js
+++ b/client/src/graphql/cccontracts.queries.js
@@ -97,9 +97,20 @@ export const QUERY_CONTRACT_BY_PK = gql`
}
`;
-export const QUERY_ACTIVE_CONTRACTS = gql`
- query QUERY_ACTIVE_CONTRACTS {
- cccontracts(where: { status: { _neq: "contracts.status.returned" } }) {
+export const QUERY_ACTIVE_CONTRACTS_PAGINATED = gql`
+ query QUERY_ACTIVE_CONTRACTS_PAGINATED(
+ $offset: Int
+ $limit: Int
+ $order: [cccontracts_order_by!]!
+ $start: timestamptz
+ $end: timestamptz
+ ) {
+ cccontracts(
+ offset: $offset
+ limit: $limit
+ order_by: $order
+ where: { actualreturn: { _lte: $end }, start: { _gte: $start } }
+ ) {
agreementnumber
courtesycarid
driver_fn
@@ -116,6 +127,7 @@ export const QUERY_ACTIVE_CONTRACTS = gql`
ownr_co_nm
}
scheduledreturn
+ actualreturn
start
status
courtesycar {
@@ -127,5 +139,10 @@ export const QUERY_ACTIVE_CONTRACTS = gql`
plate
}
}
+ cccontracts_aggregate {
+ aggregate {
+ count(distinct: true)
+ }
+ }
}
`;
diff --git a/client/src/pages/contracts/contracts.page.component.jsx b/client/src/pages/contracts/contracts.page.component.jsx
index a881401eb..8185728bb 100644
--- a/client/src/pages/contracts/contracts.page.component.jsx
+++ b/client/src/pages/contracts/contracts.page.component.jsx
@@ -1,10 +1,20 @@
import React from "react";
import ContractsList from "../../components/contracts-list/contracts-list.component";
-export default function ContractsPageComponent({ loading, data }) {
+export default function ContractsPageComponent({
+ loading,
+ data,
+ refetch,
+ total,
+}) {
return (
-
+
);
}
diff --git a/client/src/pages/contracts/contracts.page.container.jsx b/client/src/pages/contracts/contracts.page.container.jsx
index 9de40784d..ee50d0d5f 100644
--- a/client/src/pages/contracts/contracts.page.container.jsx
+++ b/client/src/pages/contracts/contracts.page.container.jsx
@@ -3,15 +3,41 @@ import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import AlertComponent from "../../components/alert/alert.component";
-import { QUERY_ACTIVE_CONTRACTS } from "../../graphql/cccontracts.queries";
+import { QUERY_ACTIVE_CONTRACTS_PAGINATED } from "../../graphql/cccontracts.queries";
import { setBreadcrumbs } from "../../redux/application/application.actions";
import ContractsPageComponent from "./contracts.page.component";
+import queryString from "query-string";
+import { useLocation } from "react-router-dom";
+import moment from "moment";
const mapDispatchToProps = (dispatch) => ({
setBreadcrumbs: (breadcrumbs) => dispatch(setBreadcrumbs(breadcrumbs)),
});
export function ContractsPageContainer({ setBreadcrumbs }) {
- const { loading, error, data } = useQuery(QUERY_ACTIVE_CONTRACTS);
+ const searchParams = queryString.parse(useLocation().search);
+ const { page, sortcolumn, sortorder, start, end } = searchParams;
+
+ const { loading, error, data, refetch } = useQuery(
+ QUERY_ACTIVE_CONTRACTS_PAGINATED,
+ {
+ variables: {
+ //search: search || "",
+ start: start ? moment(start) : null,
+ end: end ? moment(end) : null,
+ offset: page ? (page - 1) * 25 : 0,
+ limit: 25,
+ order: [
+ {
+ [sortcolumn || "start"]: sortorder
+ ? sortorder === "descend"
+ ? "desc"
+ : "asc"
+ : "desc",
+ },
+ ],
+ },
+ }
+ );
const { t } = useTranslation();
useEffect(() => {
document.title = t("titles.contracts");
@@ -30,7 +56,9 @@ export function ContractsPageContainer({ setBreadcrumbs }) {
);
diff --git a/hasura/migrations/1596043759608_update_permission_user_public_table_cccontracts/down.yaml b/hasura/migrations/1596043759608_update_permission_user_public_table_cccontracts/down.yaml
new file mode 100644
index 000000000..4540f23c1
--- /dev/null
+++ b/hasura/migrations/1596043759608_update_permission_user_public_table_cccontracts/down.yaml
@@ -0,0 +1,54 @@
+- args:
+ role: user
+ table:
+ name: cccontracts
+ schema: public
+ type: drop_select_permission
+- args:
+ permission:
+ allow_aggregations: false
+ columns:
+ - actualreturn
+ - agreementnumber
+ - cc_cardholder
+ - cc_expiry
+ - cc_num
+ - contract_date
+ - courtesycarid
+ - created_at
+ - driver_addr1
+ - driver_addr2
+ - driver_city
+ - driver_dlexpiry
+ - driver_dlnumber
+ - driver_dlst
+ - driver_dob
+ - driver_fn
+ - driver_ln
+ - driver_ph1
+ - driver_state
+ - driver_zip
+ - id
+ - jobid
+ - kmend
+ - kmstart
+ - scheduledreturn
+ - start
+ - status
+ - updated_at
+ computed_fields: []
+ filter:
+ courtesycar:
+ bodyshop:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ role: user
+ table:
+ name: cccontracts
+ schema: public
+ type: create_select_permission
diff --git a/hasura/migrations/1596043759608_update_permission_user_public_table_cccontracts/up.yaml b/hasura/migrations/1596043759608_update_permission_user_public_table_cccontracts/up.yaml
new file mode 100644
index 000000000..7c8f665fe
--- /dev/null
+++ b/hasura/migrations/1596043759608_update_permission_user_public_table_cccontracts/up.yaml
@@ -0,0 +1,54 @@
+- args:
+ role: user
+ table:
+ name: cccontracts
+ schema: public
+ type: drop_select_permission
+- args:
+ permission:
+ allow_aggregations: true
+ columns:
+ - actualreturn
+ - agreementnumber
+ - cc_cardholder
+ - cc_expiry
+ - cc_num
+ - contract_date
+ - courtesycarid
+ - created_at
+ - driver_addr1
+ - driver_addr2
+ - driver_city
+ - driver_dlexpiry
+ - driver_dlnumber
+ - driver_dlst
+ - driver_dob
+ - driver_fn
+ - driver_ln
+ - driver_ph1
+ - driver_state
+ - driver_zip
+ - id
+ - jobid
+ - kmend
+ - kmstart
+ - scheduledreturn
+ - start
+ - status
+ - updated_at
+ computed_fields: []
+ filter:
+ courtesycar:
+ bodyshop:
+ associations:
+ _and:
+ - user:
+ authid:
+ _eq: X-Hasura-User-Id
+ - active:
+ _eq: true
+ role: user
+ table:
+ name: cccontracts
+ schema: public
+ type: create_select_permission
diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml
index f4eda9655..b34ec5777 100644
--- a/hasura/migrations/metadata.yaml
+++ b/hasura/migrations/metadata.yaml
@@ -634,6 +634,7 @@ tables:
_eq: X-Hasura-User-Id
- active:
_eq: true
+ allow_aggregations: true
update_permissions:
- role: user
permission: