Added saving of CSI survey + error handling BOD-98

This commit is contained in:
Patrick Fic
2020-05-22 15:50:36 -07:00
parent f7cc4cffa4
commit d36219368a
15 changed files with 372 additions and 80 deletions

View File

@@ -3807,6 +3807,53 @@
<folder_node> <folder_node>
<name>csi</name> <name>csi</name>
<children> <children>
<folder_node>
<name>errors</name>
<children>
<concept_node>
<name>notfoundsubtitle</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>notfoundtitle</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
<folder_node> <folder_node>
<name>labels</name> <name>labels</name>
<children> <children>
@@ -3833,6 +3880,53 @@
</concept_node> </concept_node>
</children> </children>
</folder_node> </folder_node>
<folder_node>
<name>successes</name>
<children>
<concept_node>
<name>submitted</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>submittedsub</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
</children> </children>
</folder_node> </folder_node>
<folder_node> <folder_node>

View File

@@ -14,3 +14,10 @@ export const QUERY_SURVEY = gql`
} }
} }
`; `;
export const COMPLETE_SURVEY = gql`
mutation COMPLETE_SURVEY($surveyId: uuid!, $survey: csi_set_input) {
update_csi(where: { id: { _eq: $surveyId } }, _set: $survey) {
affected_rows
}
}
`;

View File

@@ -1,29 +1,73 @@
import { useQuery } from "@apollo/react-hooks"; import { useQuery, useMutation } from "@apollo/react-hooks";
import { Form, Layout, Typography, Button } from "antd"; import { Form, Layout, Typography, Button, Result } from "antd";
import React from "react"; import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import AlertComponent from "../../components/alert/alert.component"; import AlertComponent from "../../components/alert/alert.component";
import ConfigFormComponents from "../../components/config-form-components/config-form-components.component"; import ConfigFormComponents from "../../components/config-form-components/config-form-components.component";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component"; import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
import { QUERY_SURVEY } from "../../graphql/csi.queries"; import { QUERY_SURVEY, COMPLETE_SURVEY } from "../../graphql/csi.queries";
export default function CsiContainerPage() { export default function CsiContainerPage() {
const { surveyId } = useParams(); const { surveyId } = useParams();
const [form] = Form.useForm(); const [form] = Form.useForm();
const [submitting, setSubmitting] = useState({
loading: false,
submitted: false,
});
const { loading, error, data } = useQuery(QUERY_SURVEY, { const { loading, error, data } = useQuery(QUERY_SURVEY, {
variables: { surveyId }, variables: { surveyId },
}); });
const { t } = useTranslation();
if (loading) return <LoadingSpinner />;
if (error) return <AlertComponent message={error.message} type='error' />;
const handleFinish = (values) => { const { t } = useTranslation();
console.log("values", values); const [completeSurvey] = useMutation(COMPLETE_SURVEY);
if (loading) return <LoadingSpinner />;
if (error || !!!data.csi_by_pk)
return (
<div>
<Result
status='error'
title={t("csi.errors.notfoundtitle")}
subTitle={t("csi.errors.notfoundsubtitle")}>
{error ? (
<div>ERROR: {error.graphQLErrors.map((e) => e.message)}</div>
) : null}
</Result>
</div>
);
const handleFinish = async (values) => {
setSubmitting({ ...submitting, loading: true });
const result = await completeSurvey({
variables: {
surveyId,
survey: {
response: values,
valid: false,
completedon: new Date(),
},
},
});
if (!!!result.errors) {
setSubmitting({ ...submitting, loading: false, submitted: true });
} else {
setSubmitting({
...submitting,
loading: false,
error: JSON.stringify(result.errors),
});
}
}; };
//const { relateddata } = data.csi_by_pk; const {
const { bodyshop, job, csiquestion } = relateddata; relateddata: { bodyshop, job },
csiquestion: { config: csiquestions },
} = data.csi_by_pk;
return ( return (
<Layout <Layout
style={{ height: "100vh", display: "flex", flexDirection: "column" }}> style={{ height: "100vh", display: "flex", flexDirection: "column" }}>
@@ -33,7 +77,7 @@ export default function CsiContainerPage() {
flexDirection: "column", flexDirection: "column",
alignItems: "center", alignItems: "center",
}}> }}>
<div style={{ display: "flex", alignItems: "center" }}> <div style={{ display: "flex", alignItems: "center", margin: "2em" }}>
{bodyshop.logo_img_path ? ( {bodyshop.logo_img_path ? (
<img src={bodyshop.logo_img_path} alt='Logo' /> <img src={bodyshop.logo_img_path} alt='Logo' />
) : null} ) : null}
@@ -49,80 +93,52 @@ export default function CsiContainerPage() {
<Typography.Title>{t("csi.labels.title")}</Typography.Title> <Typography.Title>{t("csi.labels.title")}</Typography.Title>
<strong>{`Hi ${job.ownr_fn || ""}!`}</strong> <strong>{`Hi ${job.ownr_fn || ""}!`}</strong>
<Typography.Paragraph> <Typography.Paragraph>
At {bodyshop.shopname || ""}, we value our customer's feedback. We At {bodyshop.shopname || ""}, we value your feedback. We would love to
would love to hear what you have to say. Please fill out the form hear what you have to say. Please fill out the form below.
below.
</Typography.Paragraph> </Typography.Paragraph>
</div> </div>
<Layout.Content {submitting.error ? (
style={{ backgroundColor: "#fff", margin: "2em 4em", padding: "2em" }}> <AlertComponent message={submitting.error} type='error' />
<Form form={form} onFinish={handleFinish}> ) : null}
<ConfigFormComponents componentList={csiquestion} />
<Button type='primary' htmlType='submit'> {submitting.submitted ? (
{t("general.actions.submit")} <Layout.Content
</Button> style={{
</Form> backgroundColor: "#fff",
</Layout.Content> margin: "2em 4em",
padding: "2em",
overflowY: "auto",
}}>
<Result
status='success'
title={t("csi.successes.submitted")}
subTitle={t("csi.successes.submittedsub")}
/>
</Layout.Content>
) : (
<Layout.Content
style={{
backgroundColor: "#fff",
margin: "2em 4em",
padding: "2em",
overflowY: "auto",
}}>
<Form form={form} onFinish={handleFinish}>
<ConfigFormComponents componentList={csiquestions} />
<Button
loading={submitting.loading}
type='primary'
htmlType='submit'>
{t("general.actions.submit")}
</Button>
</Form>
</Layout.Content>
)}
<Layout.Footer> <Layout.Footer>
Copyright ImEX.Online. Survey ID: {surveyId} Copyright ImEX.Online. Survey ID: {surveyId}
</Layout.Footer> </Layout.Footer>
</Layout> </Layout>
); );
} }
const relateddata = {
bodyshop: {
logo_img_path: "https://via.placeholder.com/150",
shopname: "Kavia Test Autobody",
address1: "123 Fake St",
address2: "Unit #100",
city: "Vancouver",
state: "BC",
zip_post: "V6B 1M9",
country: "Canada",
email: "snaptsoft@gmail.com",
},
job: {
id: "1234",
ro_number: "RO102384",
ownr_fn: "Patrick",
v_make_desc: "Toyota",
v_model_desc: "Camry",
v_model_yr: "2019",
},
csiquestion: [
{
name: "item1",
type: "checkbox",
label: "Checklist Item 1",
required: true,
},
{
name: "item2",
type: "slider",
label: "Checklist Item 2",
min: 0,
max: 5,
required: true,
},
{
name: "item3",
type: "textarea",
label: "Checklist Item 3",
required: true,
},
{
name: "item4",
type: "text",
label: "Checklist Item 4",
required: true,
},
{
name: "item5",
type: "rate",
label: "Checklist Item 4",
required: true,
},
],
};

View File

@@ -250,8 +250,16 @@
} }
}, },
"csi": { "csi": {
"errors": {
"notfoundsubtitle": "We were unable to find a survey using the link you provided. Please ensure the URL is correct or reach out to your shop for more help.",
"notfoundtitle": "No survey found."
},
"labels": { "labels": {
"title": "Customer Satisfaction Survey" "title": "Customer Satisfaction Survey"
},
"successes": {
"submitted": "Your responses have been submitted successfully.",
"submittedsub": "Your input is highly appreciated."
} }
}, },
"documents": { "documents": {

View File

@@ -250,8 +250,16 @@
} }
}, },
"csi": { "csi": {
"errors": {
"notfoundsubtitle": "",
"notfoundtitle": ""
},
"labels": { "labels": {
"title": "" "title": ""
},
"successes": {
"submitted": "",
"submittedsub": ""
} }
}, },
"documents": { "documents": {

View File

@@ -250,8 +250,16 @@
} }
}, },
"csi": { "csi": {
"errors": {
"notfoundsubtitle": "",
"notfoundtitle": ""
},
"labels": { "labels": {
"title": "" "title": ""
},
"successes": {
"submitted": "",
"submittedsub": ""
} }
}, },
"documents": { "documents": {

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."csi" DROP COLUMN "completed";
type: run_sql

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."csi" ADD COLUMN "completed" timestamptz NULL;
type: run_sql

View File

@@ -0,0 +1,11 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."csi" ALTER COLUMN "completed" TYPE timestamp with time
zone;
type: run_sql
- args:
cascade: false
read_only: false
sql: alter table "public"."csi" rename column "completedon" to "completed";
type: run_sql

View File

@@ -0,0 +1,10 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."csi" ALTER COLUMN "completed" TYPE timestamptz;
type: run_sql
- args:
cascade: false
read_only: false
sql: alter table "public"."csi" rename column "completed" to "completedon";
type: run_sql

View File

@@ -0,0 +1,34 @@
- args:
role: user
table:
name: csi
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns:
- bodyshopid
- created_at
- id
- jobid
- relateddata
- response
- updated_at
- valid
- validuntil
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: csi
schema: public
type: create_select_permission

View File

@@ -0,0 +1,36 @@
- args:
role: user
table:
name: csi
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns:
- bodyshopid
- completedon
- created_at
- id
- jobid
- questionset
- relateddata
- response
- updated_at
- valid
- validuntil
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: csi
schema: public
type: create_select_permission

View File

@@ -0,0 +1,22 @@
- args:
role: anonymous
table:
name: csi
schema: public
type: drop_update_permission
- args:
permission:
columns:
- response
filter:
valid:
_eq: true
localPresets:
- key: ""
value: ""
set: {}
role: anonymous
table:
name: csi
schema: public
type: create_update_permission

View File

@@ -0,0 +1,24 @@
- args:
role: anonymous
table:
name: csi
schema: public
type: drop_update_permission
- args:
permission:
columns:
- completedon
- response
- valid
filter:
valid:
_eq: true
localPresets:
- key: ""
value: ""
set: {}
role: anonymous
table:
name: csi
schema: public
type: create_update_permission

View File

@@ -933,9 +933,11 @@ tables:
permission: permission:
columns: columns:
- bodyshopid - bodyshopid
- completedon
- created_at - created_at
- id - id
- jobid - jobid
- questionset
- relateddata - relateddata
- response - response
- updated_at - updated_at
@@ -954,7 +956,9 @@ tables:
- role: anonymous - role: anonymous
permission: permission:
columns: columns:
- completedon
- response - response
- valid
filter: filter:
valid: valid:
_eq: true _eq: true