From 3f0394760add0af6bb80d11ee393b1988fd86867 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 16 Jul 2020 15:16:50 -0700 Subject: [PATCH] Added basic global search. BOD-30 --- .gitignore | 4 +- bodyshop_translations.babel | 89 +++++++++++ .../global-search/global-search.component.jsx | 143 ++++++++++++++++++ .../components/header/header.component.jsx | 5 + .../job-employee-assignments.container.jsx | 6 +- client/src/graphql/search.queries.js | 44 ++++++ client/src/translations/en_us/common.json | 6 + client/src/translations/es/common.json | 6 + client/src/translations/fr/common.json | 6 + .../down.yaml | 9 ++ .../up.yaml | 5 + hasura/migrations/metadata.yaml | 3 - 12 files changed, 320 insertions(+), 6 deletions(-) create mode 100644 client/src/components/global-search/global-search.component.jsx create mode 100644 client/src/graphql/search.queries.js create mode 100644 hasura/migrations/1594934537921_drop_function_public_search_owner/down.yaml create mode 100644 hasura/migrations/1594934537921_drop_function_public_search_owner/up.yaml diff --git a/.gitignore b/.gitignore index 7959f7300..c804ad1ef 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,9 @@ client/.env npm-debug.log* yarn-debug.log* yarn-error.log* - +client/npm-debug.log* +client/yarn-debug.log* +client/yarn-error.log* #Firebase Ignore # Logs diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index d0c55020b..7230abcb3 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -13748,6 +13748,95 @@ + + search + + + jobs + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + owners + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + payments + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + vehicles + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + shiftclock false diff --git a/client/src/components/global-search/global-search.component.jsx b/client/src/components/global-search/global-search.component.jsx new file mode 100644 index 000000000..95701af79 --- /dev/null +++ b/client/src/components/global-search/global-search.component.jsx @@ -0,0 +1,143 @@ +import React, { useState } from "react"; +import { useLazyQuery } from "@apollo/react-hooks"; +import { GLOBAL_SEARCH_QUERY } from "../../graphql/search.queries"; +import { Input, AutoComplete } from "antd"; +import { useTranslation } from "react-i18next"; +import CurrencyFormatter from "../../utils/CurrencyFormatter"; +import { Link } from "react-router-dom"; +export default function GlobalSearch() { + const { t } = useTranslation(); + + const [callSearch, { loading, error, data }] = useLazyQuery( + GLOBAL_SEARCH_QUERY + ); + + const handleSearch = (searchTerm) => { + if (searchTerm.length > 0) + callSearch({ variables: { search: searchTerm } }); + }; + + const renderTitle = (title) => { + return ( + + {title} + + more + + + ); + }; + + const options = data + ? [ + { + label: renderTitle(t("menus.header.search.jobs")), + options: data.search_jobs.map((job) => { + return { + value: job.ro_number, + label: ( + +
+ + + {job.ro_number + ? `${job.ro_number || ""} / ${job.est_number || ""}` + : `${job.est_number || ""}`} + + + + {`${ + job.ownr_fn || "" + } ${job.ownr_ln || ""} ${job.ownr_co_nm || ""}`} + {`${ + job.v_model_yr || "" + } ${job.v_make_desc || ""} ${ + job.v_model_desc || "" + }`} + {`${job.clm_no}`} + + {`${job.clm_total}`} + +
+ + ), + }; + }), + }, + { + label: renderTitle(t("menus.header.search.owners")), + options: data.search_owners.map((owner) => { + return { + value: `${owner.ownr_fn || ""} ${owner.ownr_ln || ""} ${ + owner.ownr_co_nm || "" + }`, + label: ( + +
+ {`${ + owner.ownr_fn || "" + } ${owner.ownr_ln || ""} ${owner.ownr_co_nm || ""}`} +
+ + ), + }; + }), + }, + { + label: renderTitle(t("menus.header.search.vehicles")), + options: data.search_vehicles.map((vehicle) => { + return { + value: `${vehicle.v_model_yr || ""} ${ + vehicle.v_make_desc || "" + } ${vehicle.v_model_desc || ""}`, + label: ( + +
+ {`${ + vehicle.v_model_yr || "" + } ${vehicle.v_make_desc || ""} ${ + vehicle.v_model_desc || "" + }`} +
+ + ), + }; + }), + }, + { + label: renderTitle(t("menus.header.search.payments")), + options: data.search_payments.map((payment) => { + return { + value: `${payment.job.ro_number} ${payment.payer} ${payment.amount}`, + label: ( + +
+ {`${payment.job.ro_number}`} + {`${payment.job.memo}`} + {`${payment.job.amount}`} + {`${payment.job.transactionid}`} +
+ + ), + }; + }), + }, + ] + : []; + + return ( +
+ + + +
+ ); +} diff --git a/client/src/components/header/header.component.jsx b/client/src/components/header/header.component.jsx index 9d5fdbc11..4514a19a9 100644 --- a/client/src/components/header/header.component.jsx +++ b/client/src/components/header/header.component.jsx @@ -22,6 +22,7 @@ import { selectCurrentUser, } from "../../redux/user/user.selectors"; import "./header.styles.scss"; +import GlobalSearch from "../global-search/global-search.component"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, @@ -95,7 +96,11 @@ function Header({ mode='horizontal' theme='dark' className='header-main-menu' + selectedKeys={["home"]} onClick={handleMenuClick}> + + + diff --git a/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx b/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx index eec5f0080..f99ed58a3 100644 --- a/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx +++ b/client/src/components/job-employee-assignments/job-employee-assignments.container.jsx @@ -62,9 +62,11 @@ const determineFieldName = (operation) => { switch (operation) { case "body": return "employee_body"; - break; + case "refinish": return "employee_refinish"; - break; + + default: + return null; } }; diff --git a/client/src/graphql/search.queries.js b/client/src/graphql/search.queries.js new file mode 100644 index 000000000..5bf83e27c --- /dev/null +++ b/client/src/graphql/search.queries.js @@ -0,0 +1,44 @@ +import gql from "graphql-tag"; + +export const GLOBAL_SEARCH_QUERY = gql` + query GLOBAL_SEARCH_QUERY($search: String) { + search_jobs(args: { search: $search }) { + id + ro_number + est_number + clm_total + clm_no + v_model_yr + v_model_desc + v_make_desc + v_color + plate_no + ownr_fn + ownr_ln + ownr_co_nm + } + search_owners(args: { search: $search }) { + id + ownr_fn + ownr_ln + ownr_co_nm + } + search_vehicles(args: { search: $search }) { + id + v_model_yr + v_model_desc + v_make_desc + v_color + } + search_payments(args: { search: $search }) { + id + amount + job { + ro_number + id + } + memo + transactionid + } + } +`; diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index 6c959ee4b..3d1648127 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -837,6 +837,12 @@ "productionlist": "Production - List", "schedule": "Schedule", "scoreboard": "Scoreboard", + "search": { + "jobs": "Jobs", + "owners": "Owners", + "payments": "Payments", + "vehicles": "Vehicles" + }, "shiftclock": "Shift Clock", "shop": "My Shop", "shop_config": "Configuration", diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index 4ddd5c446..8dfc73c29 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -837,6 +837,12 @@ "productionlist": "", "schedule": "Programar", "scoreboard": "", + "search": { + "jobs": "", + "owners": "", + "payments": "", + "vehicles": "" + }, "shiftclock": "", "shop": "Mi tienda", "shop_config": "Configuración", diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index 0946f8184..21465feec 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -837,6 +837,12 @@ "productionlist": "", "schedule": "Programme", "scoreboard": "", + "search": { + "jobs": "", + "owners": "", + "payments": "", + "vehicles": "" + }, "shiftclock": "", "shop": "Mon magasin", "shop_config": "Configuration", diff --git a/hasura/migrations/1594934537921_drop_function_public_search_owner/down.yaml b/hasura/migrations/1594934537921_drop_function_public_search_owner/down.yaml new file mode 100644 index 000000000..22e6a5b37 --- /dev/null +++ b/hasura/migrations/1594934537921_drop_function_public_search_owner/down.yaml @@ -0,0 +1,9 @@ +- args: + cascade: false + read_only: false + sql: "CREATE OR REPLACE FUNCTION public.search_owner(search text)\n RETURNS SETOF + owners\n LANGUAGE plpgsql\n STABLE\nAS $function$\r\n\r\nBEGIN\r\n if search + = '' then\r\n return query select * from owners ;\r\n else \r\n return + query SELECT\r\n *\r\nFROM\r\n owners\r\nWHERE\r\n search <% (ownr_fn) OR\r\n + \ search <% (ownr_ln) OR\r\n search <% (ownr_co_nm) ;\r\n end if;\r\n\r\n\tEND\r\n$function$;" + type: run_sql diff --git a/hasura/migrations/1594934537921_drop_function_public_search_owner/up.yaml b/hasura/migrations/1594934537921_drop_function_public_search_owner/up.yaml new file mode 100644 index 000000000..dacf4304c --- /dev/null +++ b/hasura/migrations/1594934537921_drop_function_public_search_owner/up.yaml @@ -0,0 +1,5 @@ +- args: + cascade: false + read_only: false + sql: DROP FUNCTION "public"."search_owner"("pg_catalog"."text"); + type: run_sql diff --git a/hasura/migrations/metadata.yaml b/hasura/migrations/metadata.yaml index 4e0a88851..37579cafc 100644 --- a/hasura/migrations/metadata.yaml +++ b/hasura/migrations/metadata.yaml @@ -4054,9 +4054,6 @@ functions: - function: schema: public name: search_jobs -- function: - schema: public - name: search_owner - function: schema: public name: search_owners