Added vehicle search function + paginated vehicles page BOD-116

This commit is contained in:
Patrick Fic
2020-07-13 15:50:07 -07:00
parent 934dc1f647
commit d5026133e0
12 changed files with 215 additions and 28 deletions

View File

@@ -3,12 +3,11 @@ import { Button, Input, Table } from "antd";
import queryString from "query-string";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link, useLocation } from "react-router-dom";
import { Link, useHistory, useLocation } from "react-router-dom";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import PhoneFormatter from "../../utils/PhoneFormatter";
import { alphaSort } from "../../utils/sorters";
import StartChatButton from "../chat-open-button/chat-open-button.component";
import { useHistory } from "react-router-dom";
export default function JobsList({ refetch, loading, jobs, total }) {
const search = queryString.parse(useLocation().search);

View File

@@ -45,13 +45,6 @@ export function TechSider({ technician, techLogout }) {
>
<Link to={`/tech/jobclockin`}>{t("menus.tech.jobclockin")}</Link>
</Menu.Item>
<Menu.Item
key="4"
disabled={!!!technician}
icon={<Icon component={MdTimerOff} />}
>
<Link to={`/tech/clockout`}>{t("menus.tech.clockout")}</Link>
</Menu.Item>
<Menu.Item key="5" disabled={!!!technician} icon={<SearchOutlined />}>
<Link to={`/tech/list`}>{t("menus.tech.productionlist")}</Link>
</Menu.Item>

View File

@@ -1,11 +1,21 @@
import { SyncOutlined } from "@ant-design/icons";
import { Button, Input, Table } from "antd";
import queryString from "query-string";
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";
export default function VehiclesListComponent({ loading, vehicles, refetch }) {
export default function VehiclesListComponent({
loading,
vehicles,
total,
refetch,
}) {
const search = queryString.parse(useLocation().search);
const { page, sortcolumn, sortorder } = search;
const history = useHistory();
const [state, setState] = useState({
sortedInfo: {},
filteredInfo: { text: "" },
@@ -18,10 +28,6 @@ export default function VehiclesListComponent({ loading, vehicles, refetch }) {
title: t("vehicles.fields.v_vin"),
dataIndex: "v_vin",
key: "v_vin",
sorter: (a, b) => alphaSort(a.v_vin, b.v_vin),
sortOrder:
state.sortedInfo.columnKey === "v_vin" && state.sortedInfo.order,
render: (text, record) => (
<Link to={"/manage/vehicles/" + record.id}>{record.v_vin}</Link>
),
@@ -48,6 +54,10 @@ export default function VehiclesListComponent({ loading, vehicles, refetch }) {
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 (
@@ -55,26 +65,31 @@ export default function VehiclesListComponent({ loading, vehicles, refetch }) {
loading={loading}
title={() => {
return (
<div className='imex-table-header'>
<div className="imex-table-header">
<Button onClick={() => refetch()}>
<SyncOutlined />
</Button>
<Input.Search
className='imex-table-header__search'
className="imex-table-header__search"
placeholder={t("general.labels.search")}
onChange={(e) => {
//setSearchText(e.target.value);
onSearch={(value) => {
search.search = value;
history.push({ search: queryString.stringify(search) });
}}
//vale={searchText}
enterButton
/>
</div>
);
}}
size='small'
pagination={{ position: "top" }}
size="small"
pagination={{
position: "top",
pageSize: 25,
current: parseInt(page || 1),
total: total,
}}
columns={columns}
rowKey='id'
rowKey="id"
scroll={{ x: true }}
dataSource={vehicles}
onChange={handleTableChange}

View File

@@ -2,18 +2,40 @@ import React from "react";
import VehiclesListComponent from "./vehicles-list.component";
import { useQuery } from "@apollo/react-hooks";
import AlertComponent from "../alert/alert.component";
import { QUERY_ALL_VEHICLES } from "../../graphql/vehicles.queries";
import { QUERY_ALL_VEHICLES_PAGINATED } from "../../graphql/vehicles.queries";
import queryString from "query-string";
import { useLocation } from "react-router-dom";
export default function VehiclesListContainer() {
const { loading, error, data, refetch } = useQuery(QUERY_ALL_VEHICLES, {
fetchPolicy: "network-only"
});
const searchParams = queryString.parse(useLocation().search);
const { page, sortcolumn, sortorder, search } = searchParams;
const { loading, error, data, refetch } = useQuery(
QUERY_ALL_VEHICLES_PAGINATED,
{
variables: {
search: search || "",
offset: page ? (page - 1) * 25 : 0,
limit: 25,
order: [
{
[sortcolumn || "created_at"]: sortorder
? sortorder === "descend"
? "desc"
: "asc"
: "desc",
},
],
},
}
);
if (error) return <AlertComponent message={error.message} type="error" />;
return (
<VehiclesListComponent
loading={loading}
vehicles={data ? data.vehicles : null}
vehicles={data ? data.search_vehicles : null}
total={data ? data.search_vehicles_aggregate.aggregate.count : 0}
refetch={refetch}
/>
);

View File

@@ -71,6 +71,38 @@ export const QUERY_ALL_VEHICLES = gql`
}
`;
export const QUERY_ALL_VEHICLES_PAGINATED = gql`
query QUERY_ALL_VEHICLES(
$search: String
$offset: Int
$limit: Int
$order: [vehicles_order_by!]!
) {
search_vehicles(
args: { search: $search }
offset: $offset
limit: $limit
order_by: $order
) {
id
plate_no
plate_st
v_vin
v_model_yr
v_model_desc
v_make_desc
v_color
v_bstyle
updated_at
}
search_vehicles_aggregate(args: { search: $search }) {
aggregate {
count(distinct: true)
}
}
}
`;
export const SEARCH_VEHICLE_BY_VIN = gql`
query SEARCH_VEHICLE_BY_VIN($vin: String!) {
vehicles(where: { v_vin: { _ilike: $vin } }) {

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1,7 @@
- args:
cascade: true
read_only: false
sql: |-
CREATE INDEX idx_vehicles_vin ON vehicles USING GIN (v_vin gin_trgm_ops);
CREATE INDEX idx_vehicles_plateno ON vehicles USING GIN (plate_no gin_trgm_ops);
type: run_sql

View File

@@ -0,0 +1 @@
[]

View File

@@ -0,0 +1,13 @@
- args:
cascade: true
read_only: false
sql: "CREATE OR REPLACE FUNCTION public.search_vehicles(search text)\n RETURNS
SETOF vehicles\n LANGUAGE plpgsql\n STABLE\nAS $function$\n\nBEGIN\n if search
= '' then\n return query select * from vehicles ;\n else \n return query
SELECT\n *\nFROM\n vehicles\nWHERE\n search <% (v_vin) OR\n search <% (plate_no);\n
\ end if;\n\n\tEND\n$function$;"
type: run_sql
- args:
name: search_vehicles
schema: public
type: track_function

View File

@@ -0,0 +1,50 @@
- args:
role: user
table:
name: vehicles
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns:
- v_paint_codes
- db_v_code
- plate_no
- plate_st
- trim_color
- v_bstyle
- v_color
- v_cond
- v_engine
- v_makecode
- v_make_desc
- v_mldgcode
- v_model_desc
- v_model_yr
- v_options
- v_prod_dt
- v_stage
- v_tone
- v_trimcode
- v_type
- v_vin
- created_at
- updated_at
- id
- shopid
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: vehicles
schema: public
type: create_select_permission

View File

@@ -0,0 +1,50 @@
- args:
role: user
table:
name: vehicles
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: true
columns:
- v_paint_codes
- db_v_code
- plate_no
- plate_st
- trim_color
- v_bstyle
- v_color
- v_cond
- v_engine
- v_makecode
- v_make_desc
- v_mldgcode
- v_model_desc
- v_model_yr
- v_options
- v_prod_dt
- v_stage
- v_tone
- v_trimcode
- v_type
- v_vin
- created_at
- updated_at
- id
- shopid
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: vehicles
schema: public
type: create_select_permission

View File

@@ -3790,6 +3790,7 @@ tables:
_eq: X-Hasura-User-Id
- active:
_eq: true
allow_aggregations: true
update_permissions:
- role: user
permission:
@@ -3985,3 +3986,6 @@ functions:
- function:
schema: public
name: search_payments
- function:
schema: public
name: search_vehicles