From 9a0674f5d75ecf05074f183a40d521f692f19634 Mon Sep 17 00:00:00 2001 From: Patrick Fic Date: Thu, 19 Sep 2024 12:58:13 -0700 Subject: [PATCH] IO-2950 Add subscription using view instead of variable. --- .../production-board-kanban.container.jsx | 17 ++-- .../production-list-table.container.jsx | 9 +- client/src/graphql/jobs.queries.js | 90 +++++++++++++++++++ .../production-board.component.jsx | 24 ++++- .../production-list.component.jsx | 24 ++++- hasura/metadata/tables.yaml | 89 ++++++++++++++++++ .../1726773072213_run_sql_migration/down.sql | 11 +++ .../1726773072213_run_sql_migration/up.sql | 9 ++ .../1726773316245_run_sql_migration/down.sql | 8 ++ .../1726773316245_run_sql_migration/up.sql | 6 ++ .../1726773326353_run_sql_migration/down.sql | 8 ++ .../1726773326353_run_sql_migration/up.sql | 6 ++ .../1726775434726_run_sql_migration/down.sql | 3 + .../1726775434726_run_sql_migration/up.sql | 1 + .../down.sql | 2 + .../up.sql | 1 + 16 files changed, 296 insertions(+), 12 deletions(-) create mode 100644 hasura/migrations/1726773072213_run_sql_migration/down.sql create mode 100644 hasura/migrations/1726773072213_run_sql_migration/up.sql create mode 100644 hasura/migrations/1726773316245_run_sql_migration/down.sql create mode 100644 hasura/migrations/1726773316245_run_sql_migration/up.sql create mode 100644 hasura/migrations/1726773326353_run_sql_migration/down.sql create mode 100644 hasura/migrations/1726773326353_run_sql_migration/up.sql create mode 100644 hasura/migrations/1726775434726_run_sql_migration/down.sql create mode 100644 hasura/migrations/1726775434726_run_sql_migration/up.sql create mode 100644 hasura/migrations/1726775487038_drop_index_idx_jobs_inproduction_true_cast/down.sql create mode 100644 hasura/migrations/1726775487038_drop_index_idx_jobs_inproduction_true_cast/up.sql diff --git a/client/src/components/production-board-kanban/production-board-kanban.container.jsx b/client/src/components/production-board-kanban/production-board-kanban.container.jsx index a0b8cc984..364ee2d53 100644 --- a/client/src/components/production-board-kanban/production-board-kanban.container.jsx +++ b/client/src/components/production-board-kanban/production-board-kanban.container.jsx @@ -2,7 +2,11 @@ import React, { useEffect, useMemo } from "react"; import { useQuery, useSubscription } from "@apollo/client"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; -import { QUERY_JOBS_IN_PRODUCTION, SUBSCRIPTION_JOBS_IN_PRODUCTION } from "../../graphql/jobs.queries"; +import { + QUERY_JOBS_IN_PRODUCTION, + SUBSCRIPTION_JOBS_IN_PRODUCTION, + SUBSCRIPTION_JOBS_IN_PRODUCTION_VIEW +} from "../../graphql/jobs.queries"; import { QUERY_KANBAN_SETTINGS } from "../../graphql/user.queries"; import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors"; import ProductionBoardKanbanComponent from "./production-board-kanban.component"; @@ -12,7 +16,7 @@ const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser }); -function ProductionBoardKanbanContainer({ bodyshop, currentUser }) { +function ProductionBoardKanbanContainer({ bodyshop, currentUser, subscriptionType = "direct" }) { const combinedStatuses = useMemo( () => [ ...bodyshop.md_ro_statuses.production_statuses, @@ -28,9 +32,12 @@ function ProductionBoardKanbanContainer({ bodyshop, currentUser }) { onError: (error) => console.error(`Error fetching jobs in production: ${error.message}`) }); - const { data: updatedJobs } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION, { - onError: (error) => console.error(`Error subscribing to jobs in production: ${error.message}`) - }); + const { data: updatedJobs } = useSubscription( + subscriptionType !== "view" ? SUBSCRIPTION_JOBS_IN_PRODUCTION_VIEW : SUBSCRIPTION_JOBS_IN_PRODUCTION, + { + onError: (error) => console.error(`Error subscribing to jobs in production: ${error.message}`) + } + ); const { loading: associationSettingsLoading, data: associationSettings } = useQuery(QUERY_KANBAN_SETTINGS, { variables: { email: currentUser.email }, diff --git a/client/src/components/production-list-table/production-list-table.container.jsx b/client/src/components/production-list-table/production-list-table.container.jsx index 29ddf015a..153089ddb 100644 --- a/client/src/components/production-list-table/production-list-table.container.jsx +++ b/client/src/components/production-list-table/production-list-table.container.jsx @@ -4,12 +4,13 @@ import { QUERY_EXACT_JOB_IN_PRODUCTION, QUERY_EXACT_JOBS_IN_PRODUCTION, QUERY_JOBS_IN_PRODUCTION, - SUBSCRIPTION_JOBS_IN_PRODUCTION + SUBSCRIPTION_JOBS_IN_PRODUCTION, + SUBSCRIPTION_JOBS_IN_PRODUCTION_VIEW } from "../../graphql/jobs.queries"; import ProductionListTable from "./production-list-table.component"; import _ from "lodash"; -export default function ProductionListTableContainer() { +export default function ProductionListTableContainer({ subscriptionType = "direct" }) { const { refetch, loading, data } = useQuery(QUERY_JOBS_IN_PRODUCTION, { pollInterval: 3600000, fetchPolicy: "network-only", @@ -17,7 +18,9 @@ export default function ProductionListTableContainer() { }); const client = useApolloClient(); const [joblist, setJoblist] = useState([]); - const { data: updatedJobs } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION); + const { data: updatedJobs } = useSubscription( + subscriptionType !== "view" ? SUBSCRIPTION_JOBS_IN_PRODUCTION_VIEW : SUBSCRIPTION_JOBS_IN_PRODUCTION + ); useEffect(() => { if (!(data && data.jobs)) return; diff --git a/client/src/graphql/jobs.queries.js b/client/src/graphql/jobs.queries.js index 90169eccc..03a1800d3 100644 --- a/client/src/graphql/jobs.queries.js +++ b/client/src/graphql/jobs.queries.js @@ -2461,6 +2461,14 @@ export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql` } } `; +export const SUBSCRIPTION_JOBS_IN_PRODUCTION_VIEW = gql` + subscription SUBSCRIPTION_JOBS_IN_PRODUCTION_VIEW { + jobs: jobs_inproduction { + id + updated_at + } + } +`; export const QUERY_JOBS_IN_PRODUCTION = gql` query QUERY_JOBS_IN_PRODUCTION { @@ -2543,3 +2551,85 @@ export const QUERY_JOBS_IN_PRODUCTION = gql` } } `; + +export const QUERY_JOBS_IN_PRODUCTION_VIEW = gql` + query QUERY_JOBS_IN_PRODUCTION { + jobs: jobs_inproduction { + tasks_aggregate(where: { completed: { _eq: false }, deleted: { _eq: false } }) { + aggregate { + count + } + } + id + updated_at + comment + status + category + iouparent + ro_number + ownerid + ownr_fn + ownr_ln + ownr_co_nm + v_model_yr + v_model_desc + clm_no + v_make_desc + v_color + vehicleid + plate_no + actual_in + scheduled_completion + scheduled_delivery + date_last_contacted + date_next_contact + ins_co_nm + clm_total + ownr_ph1 + ownr_ph2 + special_coverage_policy + owner_owing + production_vars + kanbanparent + alt_transport + employee_body + employee_refinish + employee_prep + employee_csr + est_ct_fn + est_ct_ln + suspended + job_totals + date_repairstarted + joblines_status { + part_type + status + count + } + labhrs: joblines_aggregate(where: { _and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }] }) { + aggregate { + sum { + mod_lb_hrs + } + } + } + larhrs: joblines_aggregate(where: { _and: [{ mod_lbr_ty: { _eq: "LAR" } }, { removed: { _eq: false } }] }) { + aggregate { + sum { + mod_lb_hrs + } + } + } + subletLines: joblines( + where: { _and: { part_type: { _in: ["PAS", "PASL"] }, removed: { _eq: false } } } + order_by: { line_no: asc } + ) { + id + line_desc + sublet_ignored + sublet_completed + jobid + } + } + } +`; diff --git a/client/src/pages/production-board/production-board.component.jsx b/client/src/pages/production-board/production-board.component.jsx index 9b69da414..e5dfe7dff 100644 --- a/client/src/pages/production-board/production-board.component.jsx +++ b/client/src/pages/production-board/production-board.component.jsx @@ -1,6 +1,26 @@ import React from "react"; import ProductionBoardKanbanContainer from "../../components/production-board-kanban/production-board-kanban.container"; +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +import { useSplitTreatments } from "@splitsoftware/splitio-react"; +const mapStateToProps = createStructuredSelector({ + //currentUser: selectCurrentUser + bodyshop: selectBodyshop +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) +}); +export default connect(mapStateToProps, mapDispatchToProps)(ProductionBoardComponent); -export default function ProductionBoardComponent() { - return ; +export function ProductionBoardComponent({ bodyshop }) { + const { + treatments: { Production_Use_View } + } = useSplitTreatments({ + attributes: {}, + names: ["Production_Use_View"], + splitKey: bodyshop && bodyshop.imexshopid + }); + + return ; } diff --git a/client/src/pages/production-list/production-list.component.jsx b/client/src/pages/production-list/production-list.component.jsx index 01dd29d51..177108f6d 100644 --- a/client/src/pages/production-list/production-list.component.jsx +++ b/client/src/pages/production-list/production-list.component.jsx @@ -2,11 +2,31 @@ import React from "react"; import NoteUpsertModal from "../../components/note-upsert-modal/note-upsert-modal.container"; import ProductionListTable from "../../components/production-list-table/production-list-table.container"; -export default function ProductionListComponent() { +import { connect } from "react-redux"; +import { createStructuredSelector } from "reselect"; +import { selectBodyshop } from "../../redux/user/user.selectors"; +import { useSplitTreatments } from "@splitsoftware/splitio-react"; +const mapStateToProps = createStructuredSelector({ + bodyshop: selectBodyshop +}); +const mapDispatchToProps = (dispatch) => ({ + //setUserLanguage: language => dispatch(setUserLanguage(language)) +}); +export default connect(mapStateToProps, mapDispatchToProps)(ProductionListComponent); + +export function ProductionListComponent({ bodyshop }) { + const { + treatments: { Production_Use_View } + } = useSplitTreatments({ + attributes: {}, + names: ["Production_Use_View"], + splitKey: bodyshop && bodyshop.imexshopid + }); + return ( <> - + ); } diff --git a/hasura/metadata/tables.yaml b/hasura/metadata/tables.yaml index 7ab9621df..70be46ad0 100644 --- a/hasura/metadata/tables.yaml +++ b/hasura/metadata/tables.yaml @@ -918,6 +918,7 @@ - bill_tax_rates - cdk_configuration - cdk_dealerid + - chatterid - city - claimscorpid - convenient_company @@ -939,6 +940,7 @@ - inhousevendorid - insurance_vendor_id - intakechecklist + - intellipay_config - jc_hourly_rates - jobsizelimit - last_name_first @@ -1040,6 +1042,7 @@ - inhousevendorid - insurance_vendor_id - intakechecklist + - intellipay_config - jc_hourly_rates - last_name_first - localmediaserverhttp @@ -4240,6 +4243,63 @@ - active: _eq: true event_triggers: + - name: job_modified + definition: + enable_manual: false + update: + columns: + - clm_no + - v_make_desc + - date_next_contact + - status + - employee_csr + - employee_prep + - clm_total + - suspended + - employee_body + - ro_number + - actual_in + - ownr_co_nm + - v_model_yr + - comment + - job_totals + - v_vin + - ownr_fn + - scheduled_completion + - special_coverage_policy + - v_color + - ca_gst_registrant + - scheduled_delivery + - actual_delivery + - actual_completion + - kanbanparent + - est_ct_fn + - employee_refinish + - ownr_ph1 + - date_last_contacted + - alt_transport + - inproduction + - est_ct_ln + - production_vars + - category + - v_model_desc + - date_invoiced + - est_co_nm + - ownr_ln + retry_conf: + interval_sec: 10 + num_retries: 0 + timeout_sec: 60 + webhook_from_env: HASURA_API_URL + headers: + - name: event-secret + value_from_env: EVENT_SECRET + request_transform: + method: POST + query_params: {} + template_engine: Kriti + url: '{{$base_url}}/job/job-updated' + version: 2 - name: job_status_transition definition: enable_manual: true @@ -4299,6 +4359,35 @@ template_engine: Kriti url: '{{$base_url}}/opensearch' version: 2 +- table: + name: jobs_inproduction + schema: public + object_relationships: + - name: bodyshop + using: + manual_configuration: + column_mapping: + shopid: id + insertion_order: null + remote_table: + name: bodyshops + schema: public + select_permissions: + - role: user + permission: + columns: + - id + - shopid + - updated_at + filter: + bodyshop: + associations: + _and: + - user: + authid: + _eq: X-Hasura-User-Id + - active: + _eq: true - table: name: masterdata schema: public diff --git a/hasura/migrations/1726773072213_run_sql_migration/down.sql b/hasura/migrations/1726773072213_run_sql_migration/down.sql new file mode 100644 index 000000000..4f5681185 --- /dev/null +++ b/hasura/migrations/1726773072213_run_sql_migration/down.sql @@ -0,0 +1,11 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- CREATE +-- OR REPLACE VIEW "public"."jobs_inproduction" AS +-- SELECT +-- j.id, +-- j.updated_at +-- FROM +-- jobs j +-- WHERE +-- j.inproduction=true; diff --git a/hasura/migrations/1726773072213_run_sql_migration/up.sql b/hasura/migrations/1726773072213_run_sql_migration/up.sql new file mode 100644 index 000000000..317afef83 --- /dev/null +++ b/hasura/migrations/1726773072213_run_sql_migration/up.sql @@ -0,0 +1,9 @@ +CREATE +OR REPLACE VIEW "public"."jobs_inproduction" AS +SELECT + j.id, + j.updated_at +FROM + jobs j +WHERE +j.inproduction=true; diff --git a/hasura/migrations/1726773316245_run_sql_migration/down.sql b/hasura/migrations/1726773316245_run_sql_migration/down.sql new file mode 100644 index 000000000..153bb816b --- /dev/null +++ b/hasura/migrations/1726773316245_run_sql_migration/down.sql @@ -0,0 +1,8 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- CREATE OR REPLACE VIEW "public"."jobs_inproduction" AS +-- SELECT j.id, +-- j.updated_at, +-- j.shopid +-- FROM jobs j +-- WHERE (j.inproduction = true); diff --git a/hasura/migrations/1726773316245_run_sql_migration/up.sql b/hasura/migrations/1726773316245_run_sql_migration/up.sql new file mode 100644 index 000000000..8bc73f558 --- /dev/null +++ b/hasura/migrations/1726773316245_run_sql_migration/up.sql @@ -0,0 +1,6 @@ +CREATE OR REPLACE VIEW "public"."jobs_inproduction" AS + SELECT j.id, + j.updated_at, + j.shopid + FROM jobs j + WHERE (j.inproduction = true); diff --git a/hasura/migrations/1726773326353_run_sql_migration/down.sql b/hasura/migrations/1726773326353_run_sql_migration/down.sql new file mode 100644 index 000000000..153bb816b --- /dev/null +++ b/hasura/migrations/1726773326353_run_sql_migration/down.sql @@ -0,0 +1,8 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- CREATE OR REPLACE VIEW "public"."jobs_inproduction" AS +-- SELECT j.id, +-- j.updated_at, +-- j.shopid +-- FROM jobs j +-- WHERE (j.inproduction = true); diff --git a/hasura/migrations/1726773326353_run_sql_migration/up.sql b/hasura/migrations/1726773326353_run_sql_migration/up.sql new file mode 100644 index 000000000..8bc73f558 --- /dev/null +++ b/hasura/migrations/1726773326353_run_sql_migration/up.sql @@ -0,0 +1,6 @@ +CREATE OR REPLACE VIEW "public"."jobs_inproduction" AS + SELECT j.id, + j.updated_at, + j.shopid + FROM jobs j + WHERE (j.inproduction = true); diff --git a/hasura/migrations/1726775434726_run_sql_migration/down.sql b/hasura/migrations/1726775434726_run_sql_migration/down.sql new file mode 100644 index 000000000..16ca01c42 --- /dev/null +++ b/hasura/migrations/1726775434726_run_sql_migration/down.sql @@ -0,0 +1,3 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- CREATE INDEX idx_jobs_inproduction_true_cast ON jobs(inproduction) WHERE inproduction = ('true') :: boolean; diff --git a/hasura/migrations/1726775434726_run_sql_migration/up.sql b/hasura/migrations/1726775434726_run_sql_migration/up.sql new file mode 100644 index 000000000..a6f352908 --- /dev/null +++ b/hasura/migrations/1726775434726_run_sql_migration/up.sql @@ -0,0 +1 @@ +CREATE INDEX idx_jobs_inproduction_true_cast ON jobs(inproduction) WHERE inproduction = ('true') :: boolean; diff --git a/hasura/migrations/1726775487038_drop_index_idx_jobs_inproduction_true_cast/down.sql b/hasura/migrations/1726775487038_drop_index_idx_jobs_inproduction_true_cast/down.sql new file mode 100644 index 000000000..a5f6e49ae --- /dev/null +++ b/hasura/migrations/1726775487038_drop_index_idx_jobs_inproduction_true_cast/down.sql @@ -0,0 +1,2 @@ +CREATE INDEX "idx_jobs_inproduction_true_cast" on + "public"."jobs" using btree ("inproduction"); diff --git a/hasura/migrations/1726775487038_drop_index_idx_jobs_inproduction_true_cast/up.sql b/hasura/migrations/1726775487038_drop_index_idx_jobs_inproduction_true_cast/up.sql new file mode 100644 index 000000000..d0163192a --- /dev/null +++ b/hasura/migrations/1726775487038_drop_index_idx_jobs_inproduction_true_cast/up.sql @@ -0,0 +1 @@ +DROP INDEX IF EXISTS "public"."idx_jobs_inproduction_true_cast";