14
README.MD
14
README.MD
@@ -1,12 +1,14 @@
|
||||
React App:
|
||||
React Hooks are used for Authentication ONLY to ensure the correct web token is passed.
|
||||
React App:
|
||||
|
||||
Yarn Dependency Management:
|
||||
To force upgrades for some packages: yarn upgrade-interactive --latest
|
||||
|
||||
GraphQL API:
|
||||
Hasura is hosted on another dyno. Several environmental variables are required, including disabling the console.
|
||||
ALL CHANGES MUST BE MADE USING LOCAL CONSOLE TO ENSURE DATABASE MIGRATION FILES ARE CREATED.
|
||||
Hasura is hosted on another dyno. Several environmental variables are required, including disabling the console.
|
||||
ALL CHANGES MUST BE MADE USING LOCAL CONSOLE TO ENSURE DATABASE MIGRATION FILES ARE CREATED.
|
||||
|
||||
To Start Hasura CLI:
|
||||
npx hasura console --admin-secret Dev-BodyShopAppBySnaptSoftware!
|
||||
|
||||
Migrating to Staging:
|
||||
npx hasura migrate apply --up 10 --endpoint https://bodyshop-staging-db.herokuapp.com/ --admin-secret Staging-BodyShopAppBySnaptSoftware!
|
||||
Migrating to Staging:
|
||||
npx hasura migrate apply --up 10 --endpoint https://bodyshop-staging-db.herokuapp.com/ --admin-secret Staging-BodyShopAppBySnaptSoftware!
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<babeledit_project be_version="2.6.1" version="1.2">
|
||||
<babeledit_project version="1.2" be_version="2.6.1">
|
||||
<!--
|
||||
|
||||
BabelEdit project file
|
||||
@@ -4038,6 +4038,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>customers</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>home</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -4080,6 +4101,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>owners</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>schedule</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -4101,6 +4143,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>vehicles</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>
|
||||
@@ -4605,9 +4668,56 @@
|
||||
<folder_node>
|
||||
<name>owners</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>errors</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>noaccess</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>
|
||||
<name>fields</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>allow_text_message</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>ownr_addr1</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -4629,6 +4739,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>ownr_addr2</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>ownr_city</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -4650,6 +4781,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>ownr_ctry</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>ownr_ea</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -4734,6 +4886,90 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>ownr_st</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>ownr_title</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>ownr_zip</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>preferred_contact</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>
|
||||
@@ -4762,6 +4998,32 @@
|
||||
</concept_node>
|
||||
</children>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
<name>successes</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>save</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>
|
||||
</folder_node>
|
||||
<folder_node>
|
||||
@@ -4903,6 +5165,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>manageroot</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>profile</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -4945,6 +5228,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>vehicledetail</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>
|
||||
@@ -5021,6 +5325,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>photourl</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>
|
||||
@@ -5028,6 +5353,74 @@
|
||||
<folder_node>
|
||||
<name>vehicles</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>errors</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>noaccess</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>validation</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>validationtitle</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>
|
||||
<name>fields</name>
|
||||
<children>
|
||||
@@ -5052,6 +5445,431 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>plate_st</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>trim_color</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>v_bstyle</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>v_color</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>v_cond</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>v_engine</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>v_make_desc</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>v_makecode</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>v_mldgcode</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>v_model_desc</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>v_model_yr</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>v_options</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>v_paint_codes</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>v_prod_dt</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>v_stage</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>v_tone</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>v_trimcode</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>v_type</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>v_vin</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>
|
||||
<name>successes</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>save</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>
|
||||
|
||||
@@ -4,39 +4,39 @@
|
||||
"private": true,
|
||||
"proxy": "https://localhost:5000",
|
||||
"dependencies": {
|
||||
"antd": "^3.26.0",
|
||||
"antd": "^3.26.8",
|
||||
"apollo-boost": "^0.4.4",
|
||||
"apollo-link-context": "^1.0.19",
|
||||
"apollo-link-error": "^1.1.12",
|
||||
"apollo-link-logger": "^1.2.3",
|
||||
"apollo-link-ws": "^1.0.19",
|
||||
"axios": "^0.19.1",
|
||||
"axios": "^0.19.2",
|
||||
"chart.js": "^2.9.3",
|
||||
"dotenv": "^8.2.0",
|
||||
"firebase": "^7.5.0",
|
||||
"graphql": "^14.5.8",
|
||||
"i18next": "^19.0.2",
|
||||
"node-sass": "^4.13.0",
|
||||
"firebase": "^7.8.1",
|
||||
"graphql": "^14.6.0",
|
||||
"i18next": "^19.1.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"react": "^16.12.0",
|
||||
"react-apollo": "^3.1.3",
|
||||
"react-big-calendar": "^0.23.0",
|
||||
"react-chartjs-2": "^2.8.0",
|
||||
"react-chartjs-2": "^2.9.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-i18next": "^11.2.7",
|
||||
"react-icons": "^3.8.0",
|
||||
"react-i18next": "^11.3.1",
|
||||
"react-icons": "^3.9.0",
|
||||
"react-image-file-resizer": "^0.2.1",
|
||||
"react-moment": "^0.9.7",
|
||||
"react-number-format": "^4.3.1",
|
||||
"react-redux": "^7.1.3",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-scripts": "3.2.0",
|
||||
"react-scripts": "3.3.1",
|
||||
"react-trello": "^2.2.3",
|
||||
"redux": "^4.0.5",
|
||||
"redux-logger": "^3.0.6",
|
||||
"redux-persist": "^6.0.0",
|
||||
"redux-saga": "^1.1.3",
|
||||
"reselect": "^4.0.0",
|
||||
"styled-components": "^4.4.1",
|
||||
"styled-components": "^5.0.1",
|
||||
"subscriptions-transport-ws": "^0.9.16"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"short_name": "Bodyshop",
|
||||
"short_name": "Bodyshop.app",
|
||||
"name": "Bodyshop Management System",
|
||||
"description": "The ultimate bodyshop management system",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
@@ -20,6 +21,6 @@
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#002366",
|
||||
"background_color": "#000000"
|
||||
"theme_color": "#fff",
|
||||
"background_color": "#fff"
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import PrivateRoute from "../utils/private-route";
|
||||
import "./App.css";
|
||||
|
||||
const LandingPage = lazy(() => import("../pages/landing/landing.page"));
|
||||
const ManagePage = lazy(() => import("../pages/manage/manage.page"));
|
||||
const ManagePage = lazy(() => import("../pages/manage/manage.page.container"));
|
||||
const SignInPage = lazy(() => import("../pages/sign-in/sign-in.page"));
|
||||
const Unauthorized = lazy(() =>
|
||||
import("../pages/unauthorized/unauthorized.component")
|
||||
@@ -28,8 +28,7 @@ const mapDispatchToProps = dispatch => ({
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(({ checkUserSession, currentUser, setBodyshop }) => {
|
||||
|
||||
)(({ checkUserSession, currentUser }) => {
|
||||
useEffect(() => {
|
||||
checkUserSession();
|
||||
return () => {};
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
import { Avatar, Col, Dropdown, Icon, Menu, Row } from "antd";
|
||||
import i18next from "i18next";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import UserImage from "../../assets/User.svg";
|
||||
import { setUserLanguage, signOutStart } from "../../redux/user/user.actions";
|
||||
import { selectCurrentUser } from "../../redux/user/user.selectors";
|
||||
import SignOut from "../sign-out/sign-out.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
currentUser: selectCurrentUser
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
signOutStart: () => dispatch(signOutStart()),
|
||||
setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(function CurrentUserDropdown({ currentUser, signOutStart, setUserLanguage }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleMenuClick = e => {
|
||||
if (e.item.props.actiontype === "lang-select") {
|
||||
i18next.changeLanguage(e.key, (err, t) => {
|
||||
if (err)
|
||||
return console.log("Error encountered when changing languages.", err);
|
||||
setUserLanguage(e.key);
|
||||
console.log("clicking");
|
||||
});
|
||||
}
|
||||
};
|
||||
const menu = (
|
||||
<Menu mode="vertical" onClick={handleMenuClick}>
|
||||
<Menu.Item>
|
||||
<SignOut signOutStart={signOutStart} />
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<Link to="/manage/profile"> {t("menus.currentuser.profile")}</Link>
|
||||
</Menu.Item>
|
||||
<Menu.SubMenu
|
||||
title={
|
||||
<span>
|
||||
<Icon type="global" />
|
||||
<span>{t("menus.currentuser.languageselector")}</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<Menu.Item actiontype="lang-select" key="en_us">
|
||||
{t("general.languages.english")}
|
||||
</Menu.Item>
|
||||
<Menu.Item actiontype="lang-select" key="fr">
|
||||
{t("general.languages.french")}
|
||||
</Menu.Item>
|
||||
<Menu.Item actiontype="lang-select" key="es">
|
||||
{t("general.languages.spanish")}
|
||||
</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
return (
|
||||
<Dropdown overlay={menu}>
|
||||
<Row>
|
||||
<Col span={8}>
|
||||
<Avatar size="large" alt="Avatar" src={UserImage} />
|
||||
</Col>
|
||||
<Col span={16} style={{ color: "white" }}>
|
||||
{currentUser.displayName || t("general.labels.unknown")}
|
||||
</Col>
|
||||
</Row>
|
||||
</Dropdown>
|
||||
);
|
||||
});
|
||||
@@ -4,7 +4,7 @@ import React from "react";
|
||||
export default function FooterComponent() {
|
||||
return (
|
||||
<Row>
|
||||
<Col span={8} offset={9}>
|
||||
<Col span={8} offset={8}>
|
||||
Copyright Snapt Software 2019. All rights reserved.
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@@ -5,9 +5,13 @@ function FormItemEmail(props, ref) {
|
||||
<Input
|
||||
{...props}
|
||||
addonAfter={
|
||||
<a href={`mailto:${props.email}`}>
|
||||
props.email ? (
|
||||
<a href={`mailto:${props.email}`}>
|
||||
<Icon type="mail" />
|
||||
</a>
|
||||
) : (
|
||||
<Icon type="mail" />
|
||||
</a>
|
||||
)
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Button } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
|
||||
export default function ResetForm({ resetFields }) {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<AlertComponent
|
||||
message={
|
||||
<div>
|
||||
{t("general.messages.unsavedchanges")}
|
||||
<Button onClick={() => resetFields()}>
|
||||
{t("general.actions.reset")}
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
closable
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
import React from "react";
|
||||
// import { Icon, Button, Input, AutoComplete } from "antd";
|
||||
|
||||
// const { Option } = AutoComplete;
|
||||
|
||||
// function onSelect(value) {
|
||||
// console.log("onSelect", value);
|
||||
// }
|
||||
|
||||
// function getRandomInt(max, min = 0) {
|
||||
// return Math.floor(Math.random() * (max - min + 1)) + min; // eslint-disable-line no-mixed-operators
|
||||
// }
|
||||
|
||||
// function searchResult(query) {
|
||||
// return new Array(getRandomInt(5))
|
||||
// .join(".")
|
||||
// .split(".")
|
||||
// .map((item, idx) => ({
|
||||
// query,
|
||||
// category: `${query}${idx}`,
|
||||
// count: getRandomInt(200, 100)
|
||||
// }));
|
||||
// }
|
||||
|
||||
// function renderOption(item) {
|
||||
// return (
|
||||
// <Option key={item.category} text={item.category}>
|
||||
// <div className='global-search-item'>
|
||||
// <span className='global-search-item-desc'>
|
||||
// Found {item.query} on
|
||||
// <a
|
||||
// href={`https://s.taobao.com/search?q=${item.query}`}
|
||||
// target='_blank'
|
||||
// rel='noopener noreferrer'>
|
||||
// {item.category}
|
||||
// </a>
|
||||
// </span>
|
||||
// <span className='global-search-item-count'>{item.count} results</span>
|
||||
// </div>
|
||||
// </Option>
|
||||
// );
|
||||
// }
|
||||
|
||||
export default class GlobalSearch extends React.Component {
|
||||
state = {
|
||||
dataSource: []
|
||||
};
|
||||
|
||||
// handleSearch = value => {
|
||||
// this.setState({
|
||||
// dataSource: value ? searchResult(value) : []
|
||||
// });
|
||||
// };
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div />
|
||||
// <div style={{ width: 300 }}>
|
||||
// <AutoComplete
|
||||
// size="large"
|
||||
// style={{ width: "100%" }}
|
||||
// dataSource={dataSource.map(renderOption)}
|
||||
// onSelect={onSelect}
|
||||
// onSearch={this.handleSearch}
|
||||
// placeholder="input here"
|
||||
// optionLabelProp="text"
|
||||
// >
|
||||
// <Input
|
||||
// suffix={
|
||||
// <Button style={{ marginRight: -12 }} size="large" type="primary">
|
||||
// <Icon type="search" />
|
||||
// </Button>
|
||||
// }
|
||||
// />
|
||||
// </AutoComplete>
|
||||
// </div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,35 @@
|
||||
import { Col, Icon, Menu, Row } from "antd";
|
||||
import { Avatar, Col, Icon, Menu, Row } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import CurrentUserDropdown from "../current-user-dropdown/current-user-dropdown.component";
|
||||
import GlobalSearch from "../global-search/global-search.component";
|
||||
import UserImage from "../../assets/User.svg";
|
||||
import { signOutStart } from "../../redux/user/user.actions";
|
||||
import ManageSignInButton from "../manage-sign-in-button/manage-sign-in-button.component";
|
||||
|
||||
export default ({ landingHeader, selectedNavItem }) => {
|
||||
export default ({
|
||||
landingHeader,
|
||||
selectedNavItem,
|
||||
logo,
|
||||
handleMenuClick,
|
||||
currentUser
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
//TODO Add
|
||||
return (
|
||||
<Row type="flex" justify="space-around">
|
||||
<Col span={16}>
|
||||
<Row type="flex" justify="space-around" align="middle">
|
||||
{logo ? (
|
||||
<Col span={4}>
|
||||
<img alt="Shop Logo" src={logo} style={{ height: "40px" }} />
|
||||
</Col>
|
||||
) : null}
|
||||
<Col span={14}>
|
||||
<Menu
|
||||
theme="dark"
|
||||
className="header"
|
||||
selectedKeys={selectedNavItem}
|
||||
mode="horizontal"
|
||||
onClick={handleMenuClick}
|
||||
>
|
||||
<Menu.Item>
|
||||
<GlobalSearch />
|
||||
</Menu.Item>
|
||||
|
||||
<Menu.Item key="home">
|
||||
<Link to="/manage">
|
||||
<Icon type="home" />
|
||||
@@ -49,16 +57,62 @@ export default ({ landingHeader, selectedNavItem }) => {
|
||||
</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
|
||||
{!landingHeader ? null : (
|
||||
<Menu.Item>
|
||||
<ManageSignInButton />
|
||||
<Menu.SubMenu title={t("menus.header.customers")}>
|
||||
<Menu.Item key="owners">
|
||||
<Link to="/manage/owners">
|
||||
<Icon type="team" />
|
||||
{t("menus.header.owners")}
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
)}
|
||||
<Menu.Item key="vehicles">
|
||||
<Link to="/manage/vehicles">
|
||||
<Icon type="car" />
|
||||
{t("menus.header.vehicles")}
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
|
||||
<Menu.SubMenu
|
||||
title={
|
||||
<div>
|
||||
<Avatar
|
||||
size="medium"
|
||||
alt="Avatar"
|
||||
src={currentUser.photoURL ? currentUser.photoURL : UserImage}
|
||||
style={{ margin: "10px" }}
|
||||
/>
|
||||
{currentUser.displayName || t("general.labels.unknown")}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Menu.Item onClick={signOutStart()}>
|
||||
{t("user.actions.signout")}
|
||||
</Menu.Item>
|
||||
<Menu.Item>
|
||||
<Link to="/manage/profile">{t("menus.currentuser.profile")}</Link>
|
||||
</Menu.Item>
|
||||
<Menu.SubMenu
|
||||
title={
|
||||
<span>
|
||||
<Icon type="global" />
|
||||
<span>{t("menus.currentuser.languageselector")}</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<Menu.Item actiontype="lang-select" key="en_us">
|
||||
{t("general.languages.english")}
|
||||
</Menu.Item>
|
||||
<Menu.Item actiontype="lang-select" key="fr">
|
||||
{t("general.languages.french")}
|
||||
</Menu.Item>
|
||||
<Menu.Item actiontype="lang-select" key="es">
|
||||
{t("general.languages.spanish")}
|
||||
</Menu.Item>
|
||||
</Menu.SubMenu>
|
||||
</Menu.SubMenu>
|
||||
</Menu>
|
||||
</Col>
|
||||
<Col span={6} offset={2}>
|
||||
{!landingHeader ? <CurrentUserDropdown /> : null}
|
||||
</Col>
|
||||
<Col span={4}>{!landingHeader ? null : <ManageSignInButton />}</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,8 +1,52 @@
|
||||
import React from "react";
|
||||
import HeaderComponent from "./header.component";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import i18next from "i18next";
|
||||
import { setUserLanguage, signOutStart } from "../../redux/user/user.actions";
|
||||
import {
|
||||
selectCurrentUser,
|
||||
selectBodyshop
|
||||
} from "../../redux/user/user.selectors";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
currentUser: selectCurrentUser,
|
||||
bodyshop: selectBodyshop
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
signOutStart: () => dispatch(signOutStart()),
|
||||
setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||
});
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(function HeaderContainer({
|
||||
landingHeader,
|
||||
currentUser,
|
||||
bodyshop,
|
||||
signOutStart,
|
||||
setUserLanguage
|
||||
}) {
|
||||
const handleMenuClick = e => {
|
||||
if (e.item.props.actiontype === "lang-select") {
|
||||
i18next.changeLanguage(e.key, (err, t) => {
|
||||
if (err)
|
||||
return console.log("Error encountered when changing languages.", err);
|
||||
setUserLanguage(e.key);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default ({ landingHeader, signedIn }) => {
|
||||
return (
|
||||
<HeaderComponent landingHeader={landingHeader} selectedNavItem={null} />
|
||||
<HeaderComponent
|
||||
handleMenuClick={handleMenuClick}
|
||||
signOutStart={signOutStart}
|
||||
landingHeader={landingHeader}
|
||||
selectedNavItem={null}
|
||||
currentUser={currentUser}
|
||||
logo={bodyshop ? bodyshop.logo_img_path : null}
|
||||
/>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -10,45 +10,45 @@ export default function JobDetailCardsInsuranceComponent({ loading, data }) {
|
||||
<CardTemplate loading={loading} title={t("jobs.labels.cards.insurance")}>
|
||||
{data ? (
|
||||
<span>
|
||||
<div>{data?.ins_co_nm || t("general.labels.unknown")}</div>
|
||||
<div>{data?.clm_no || t("general.labels.unknown")}</div>
|
||||
<div>{data.ins_co_nm || t("general.labels.unknown")}</div>
|
||||
<div>{data.clm_no || t("general.labels.unknown")}</div>
|
||||
<div>
|
||||
{t("jobs.labels.cards.filehandler")}
|
||||
{data?.ins_ea ? (
|
||||
{data.ins_ea ? (
|
||||
<a href={`mailto:${data.ins_ea}`}>
|
||||
<div>{`${data?.ins_ct_fn || ""} ${data?.ins_ct_ln || ""}`}</div>
|
||||
<div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div>
|
||||
</a>
|
||||
) : (
|
||||
<div>{`${data?.ins_ct_fn || ""} ${data?.ins_ct_ln || ""}`}</div>
|
||||
<div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div>
|
||||
)}
|
||||
{data?.ins_ph1 ? (
|
||||
<PhoneFormatter>{data?.ins_ph1}</PhoneFormatter>
|
||||
{data.ins_ph1 ? (
|
||||
<PhoneFormatter>{data.ins_ph1}</PhoneFormatter>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{t("jobs.labels.cards.appraiser")}
|
||||
{data?.est_ea ? (
|
||||
{data.est_ea ? (
|
||||
<a href={`mailto:${data.est_ea}`}>
|
||||
<div>{`${data?.ins_ct_fn || ""} ${data?.ins_ct_ln || ""}`}</div>
|
||||
<div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div>
|
||||
</a>
|
||||
) : (
|
||||
<div>{`${data?.ins_ct_fn || ""} ${data?.ins_ct_ln || ""}`}</div>
|
||||
<div>{`${data.ins_ct_fn || ""} ${data.ins_ct_ln || ""}`}</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{t("jobs.labels.cards.estimator")}
|
||||
{data?.est_ea ? (
|
||||
{data.est_ea ? (
|
||||
<a href={`mailto:${data.est_ea}`}>
|
||||
<div>{`${data?.est_ct_fn || ""} ${data?.est_ct_ln || ""}`}</div>
|
||||
<div>{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}</div>
|
||||
</a>
|
||||
) : (
|
||||
<div>{`${data?.est_ct_fn || ""} ${data?.est_ct_ln || ""}`}</div>
|
||||
<div>{`${data.est_ct_fn || ""} ${data.est_ct_ln || ""}`}</div>
|
||||
)}
|
||||
{data?.est_ph1 ? (
|
||||
<PhoneFormatter>{data?.est_ph1}</PhoneFormatter>
|
||||
) : null}
|
||||
{data.est_ph1 ? (
|
||||
<PhoneFormatter>{data.est_ph1}</PhoneFormatter>
|
||||
) : null}
|
||||
</div>
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
@@ -13,7 +13,7 @@ export default function JobDetailCardsNotesComponent({ loading, data }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<CardTemplate
|
||||
<CardTemplate
|
||||
loading={loading}
|
||||
title={t("jobs.labels.cards.notes")}
|
||||
extraLink={`/manage/jobs/${data.id}#notes`}>
|
||||
@@ -22,7 +22,7 @@ export default function JobDetailCardsNotesComponent({ loading, data }) {
|
||||
<List
|
||||
size='small'
|
||||
bordered
|
||||
dataSource={data?.notes}
|
||||
dataSource={data.notes}
|
||||
renderItem={item => (
|
||||
<List.Item>
|
||||
{item.critical ? (
|
||||
|
||||
@@ -9,7 +9,7 @@ export default function JobDetailCardsVehicleComponent({ loading, data }) {
|
||||
<CardTemplate
|
||||
loading={loading}
|
||||
title={t("jobs.labels.cards.vehicle")}
|
||||
extraLink={data?.vehicle ? `/manage/vehicles/${data?.vehicle?.id}` : null}
|
||||
extraLink={data.vehicle ? `/manage/vehicles/${data.vehicle.id}` : null}
|
||||
>
|
||||
{data ? (
|
||||
<span>
|
||||
|
||||
@@ -52,24 +52,28 @@ export default function JobLinesContainer({ jobId, form }) {
|
||||
? searchText
|
||||
? data.joblines.filter(
|
||||
jl =>
|
||||
jl.unq_seq
|
||||
?.toString()
|
||||
(jl.unq_seq || "")
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
jl.line_desc
|
||||
?.toLowerCase()
|
||||
(jl.line_desc || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
jl.part_type
|
||||
?.toLowerCase()
|
||||
(jl.part_type || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
jl.oem_partno
|
||||
?.toLowerCase()
|
||||
(jl.oem_partno || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
jl.op_code_desc
|
||||
?.toLowerCase()
|
||||
(jl.op_code_desc || "")
|
||||
.toLowerCase()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
jl.db_price?.toString().includes(searchText.toLowerCase()) ||
|
||||
jl.act_price?.toString().includes(searchText.toLowerCase())
|
||||
(jl.db_price || "")
|
||||
.toString()
|
||||
.includes(searchText.toLowerCase()) ||
|
||||
(jl.act_price || "")
|
||||
.toString()
|
||||
.includes(searchText.toLowerCase())
|
||||
)
|
||||
: data.joblines
|
||||
: null
|
||||
|
||||
@@ -41,9 +41,7 @@ export default connect(
|
||||
jobId={jobId}
|
||||
currentUser={currentUser}
|
||||
shopId={
|
||||
shopData.data?.bodyshops[0]?.id
|
||||
? shopData.data?.bodyshops[0]?.id
|
||||
: "error"
|
||||
shopData.data.bodyshops[0].id ? shopData.data.bodyshops[0].id : "error"
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -106,7 +106,7 @@ export default withRouter(function JobsList({
|
||||
ellipsis: true,
|
||||
render: (text, record) => {
|
||||
return record.vehicle ? (
|
||||
<Link to={"manage/vehicles/" + record.vehicle.id}>
|
||||
<Link to={"/manage/vehicles/" + record.vehicle.id}>
|
||||
{record.vehicle.v_model_yr} {record.vehicle.v_make_desc}{" "}
|
||||
{record.vehicle.v_model_desc}
|
||||
</Link>
|
||||
@@ -121,11 +121,11 @@ export default withRouter(function JobsList({
|
||||
key: "plate_no",
|
||||
width: "8%",
|
||||
ellipsis: true,
|
||||
sorter: (a, b) => alphaSort(a.vehicle?.plate_no, b.vehicle?.plate_no),
|
||||
sorter: (a, b) => alphaSort(a.vehicle.plate_no, b.vehicle.plate_no),
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "plate_no" && state.sortedInfo.order,
|
||||
render: (text, record) => {
|
||||
return record.vehicle?.plate_no ? (
|
||||
return record.vehicle.plate_no ? (
|
||||
<span>{record.vehicle.plate_no}</span>
|
||||
) : (
|
||||
t("general.labels.unknown")
|
||||
|
||||
@@ -8,7 +8,11 @@ export default function LoadingSpinner({ loading = true, message, ...props }) {
|
||||
spinning={loading}
|
||||
className="loading-spinner"
|
||||
size="large"
|
||||
//delay="500"
|
||||
style={{
|
||||
position: "relative",
|
||||
alignContent: "center"
|
||||
}}
|
||||
delay={200}
|
||||
tip={message ? message : null}
|
||||
>
|
||||
{props.children}
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
.loading-spinner {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ export default function NoteUpsertModalComponent({
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title={noteState?.id ? t("notes.actions.edit") : t("notes.actions.new")}
|
||||
title={noteState.id ? t("notes.actions.edit") : t("notes.actions.new")}
|
||||
visible={visible}
|
||||
okText={t("general.labels.save")}
|
||||
onOk={() => {
|
||||
@@ -22,7 +22,8 @@ export default function NoteUpsertModalComponent({
|
||||
}}
|
||||
onCancel={() => {
|
||||
changeVisibility(false);
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<div>
|
||||
{t("notes.fields.critical")}
|
||||
<Switch
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
import { Button, Col, Form, Input, Row, Switch } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
||||
import FormItemPhone from "../form-items-formatted/phone-form-item.component";
|
||||
import ResetForm from "../form-items-formatted/reset-form-item.component";
|
||||
|
||||
export default function OwnerDetailFormComponent({ form, owner }) {
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
isFieldsTouched,
|
||||
resetFields,
|
||||
getFieldDecorator,
|
||||
getFieldValue
|
||||
} = form;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isFieldsTouched() ? <ResetForm resetFields={resetFields} /> : null}
|
||||
<Button type="primary" key="submit" htmlType="submit">
|
||||
{t("general.labels.save")}
|
||||
</Button>
|
||||
<Row>
|
||||
<Col span={8}>
|
||||
<Form.Item label={t("owners.fields.ownr_ln")}>
|
||||
{getFieldDecorator("ownr_ln", {
|
||||
initialValue: owner.ownr_ln
|
||||
})(<Input name="ownr_ln" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_fn")}>
|
||||
{getFieldDecorator("ownr_fn", {
|
||||
initialValue: owner.ownr_fn
|
||||
})(<Input name="ownr_fn" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.allow_text_message")}>
|
||||
{getFieldDecorator("allow_text_message", {
|
||||
initialValue: owner.allow_text_message,
|
||||
valuePropName: "checked"
|
||||
})(<Switch name="allow_text_message" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_addr1")}>
|
||||
{getFieldDecorator("ownr_addr1", {
|
||||
initialValue: owner.ownr_addr1
|
||||
})(<Input name="ownr_addr1" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_addr2")}>
|
||||
{getFieldDecorator("ownr_addr2", {
|
||||
initialValue: owner.ownr_addr2
|
||||
})(<Input name="ownr_addr2" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_city")}>
|
||||
{getFieldDecorator("ownr_city", {
|
||||
initialValue: owner.ownr_city
|
||||
})(<Input name="ownr_city" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_ctry")}>
|
||||
{getFieldDecorator("ownr_ctry", {
|
||||
initialValue: owner.ownr_ctry
|
||||
})(<Input name="ownr_ctry" />)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
{" "}
|
||||
<Form.Item label={t("owners.fields.ownr_ea")}>
|
||||
{getFieldDecorator("ownr_ea", {
|
||||
initialValue: owner.ownr_ea,
|
||||
rules: [
|
||||
{
|
||||
type: "email",
|
||||
message: "This is not a valid email address."
|
||||
}
|
||||
]
|
||||
})(
|
||||
<FormItemEmail name="ownr_ea" email={getFieldValue("ownr_ea")} />
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_ph1")}>
|
||||
{getFieldDecorator("ownr_ph1", {
|
||||
initialValue: owner.ownr_ph1
|
||||
})(<FormItemPhone customInput={Input} name="ownr_ph1" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_st")}>
|
||||
{getFieldDecorator("ownr_st", {
|
||||
initialValue: owner.ownr_st
|
||||
})(<Input name="ownr_st" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_zip")}>
|
||||
{getFieldDecorator("ownr_zip", {
|
||||
initialValue: owner.ownr_zip
|
||||
})(<Input name="ownr_zip" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.preferred_contact")}>
|
||||
{getFieldDecorator("preferred_contact", {
|
||||
initialValue: owner.preferred_contact
|
||||
})(<Input name="preferred_contact" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("owners.fields.ownr_title")}>
|
||||
{getFieldDecorator("ownr_title", {
|
||||
initialValue: owner.ownr_title
|
||||
})(<Input name="ownr_title" />)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import { Form, notification } from "antd";
|
||||
import React from "react";
|
||||
import { useMutation } from "react-apollo";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UPDATE_OWNER } from "../../graphql/owners.queries";
|
||||
import OwnerDetailFormComponent from "./owner-detail-form.component";
|
||||
|
||||
function OwnerDetailFormContainer({ form, owner, refetch }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [updateOwner] = useMutation(UPDATE_OWNER);
|
||||
|
||||
const handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
|
||||
form.validateFieldsAndScroll((err, values) => {
|
||||
if (err) {
|
||||
notification["error"]({
|
||||
message: t("owners.errors.validationtitle"),
|
||||
description: t("owners.errors.validation")
|
||||
});
|
||||
}
|
||||
if (!err) {
|
||||
updateOwner({
|
||||
variables: { ownerId: owner.id, owner: values }
|
||||
}).then(r => {
|
||||
notification["success"]({
|
||||
message: t("owners.successes.save")
|
||||
});
|
||||
//TODO: Better way to reset the field decorators?
|
||||
if (refetch) refetch().then();
|
||||
form.resetFields();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={handleSubmit} autoComplete="off">
|
||||
<OwnerDetailFormComponent form={form} owner={owner} />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
export default Form.create({ name: "OwnerDetailFormContainer" })(
|
||||
OwnerDetailFormContainer
|
||||
);
|
||||
@@ -0,0 +1,59 @@
|
||||
import React from "react";
|
||||
import { Table } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
export default function OwnerDetailJobsComponent({ owner }) {
|
||||
const { t } = useTranslation();
|
||||
const columns = [
|
||||
{
|
||||
title: t("jobs.fields.ro_number"),
|
||||
dataIndex: "ro_number",
|
||||
key: "ro_number",
|
||||
ellipsis: true,
|
||||
render: (text, record) => (
|
||||
<Link to={`/manage/jobs/${record.id}`}>
|
||||
{record.ro_number ? record.ro_number : `EST ${record.est_number}`}
|
||||
</Link>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.vehicle"),
|
||||
dataIndex: "owner",
|
||||
key: "owner",
|
||||
render: (text, record) => (
|
||||
<Link to={`/manage/vehicles/${record.vehicle.id}`}>
|
||||
{`${record.vehicle.v_model_yr} ${record.vehicle.v_make_desc} ${record.vehicle.v_model_desc}`}
|
||||
</Link>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.clm_no"),
|
||||
dataIndex: "clm_no",
|
||||
key: "clm_no"
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.status"),
|
||||
dataIndex: "status",
|
||||
key: "status"
|
||||
},
|
||||
|
||||
{
|
||||
title: t("jobs.fields.clm_total"),
|
||||
dataIndex: "clm_total",
|
||||
key: "clm_total",
|
||||
render: (text, record) => (
|
||||
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Table
|
||||
pagination={{ position: "bottom" }}
|
||||
columns={columns.map(item => ({ ...item }))}
|
||||
rowKey="id"
|
||||
dataSource={owner.jobs}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -37,7 +37,10 @@ export default connect(
|
||||
}
|
||||
if (!err) {
|
||||
console.log("values", values);
|
||||
updateUserDetails({ displayName: values.displayname });
|
||||
updateUserDetails({
|
||||
displayName: values.displayname,
|
||||
photoURL: values.photoURL
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -59,6 +62,12 @@ export default connect(
|
||||
rules: [{ required: true }]
|
||||
})(<Input name="displayname" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("user.fields.photourl")}>
|
||||
{getFieldDecorator("photoURL", {
|
||||
initialValue: currentUser.photoURL
|
||||
})(<Input name="photoURL" />)}
|
||||
</Form.Item>
|
||||
|
||||
<Button
|
||||
type="primary"
|
||||
key="submit"
|
||||
|
||||
@@ -11,6 +11,7 @@ export default function ScheduleDayViewComponent({ data, day }) {
|
||||
<ScheduleCalendarWrapperComponent
|
||||
events={data}
|
||||
defaultView="day"
|
||||
views={["day"]}
|
||||
style={{ height: "40vh" }}
|
||||
defaultDate={new Date(day)}
|
||||
//onNavigate={e => console.log("e", e)}
|
||||
|
||||
@@ -27,23 +27,24 @@ export default connect(
|
||||
bodyshop,
|
||||
refetch
|
||||
}) {
|
||||
const existingAppointments = useQuery(QUERY_APPOINTMENTS_BY_JOBID, {
|
||||
variables: { jobid: jobId },
|
||||
fetchPolicy: "network-only",
|
||||
skip: !jobId
|
||||
});
|
||||
const [scheduleModalVisible, setscheduleModalVisible] = scheduleModalState;
|
||||
const [appData, setAppData] = useState({ jobid: jobId, start: null });
|
||||
const [insertAppointment] = useMutation(INSERT_APPOINTMENT);
|
||||
const [updateJobStatus] = useMutation(UPDATE_JOB_STATUS, {
|
||||
variables: {
|
||||
jobId: jobId,
|
||||
status: bodyshop.md_ro_statuses.default_scheduled
|
||||
status: bodyshop.md_ro_statuses.default_scheduled
|
||||
}
|
||||
});
|
||||
const [formData, setFormData] = useState({ notifyCustomer: false });
|
||||
const { t } = useTranslation();
|
||||
|
||||
const existingAppointments = useQuery(QUERY_APPOINTMENTS_BY_JOBID, {
|
||||
variables: { jobid: jobId },
|
||||
fetchPolicy: "network-only",
|
||||
skip: !scheduleModalVisible
|
||||
});
|
||||
|
||||
return (
|
||||
<ScheduleJobModalComponent
|
||||
existingAppointments={existingAppointments}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function SignoutComponent({ signOutStart }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return <div onClick={signOutStart}>{t("user.actions.signout")}</div>;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
import { Button, DatePicker, Form, Input, Row, Col } from "antd";
|
||||
import moment from "moment";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ResetForm from "../form-items-formatted/reset-form-item.component";
|
||||
export default function VehicleDetailFormComponent({ vehicle, form }) {
|
||||
const { t } = useTranslation();
|
||||
const { isFieldsTouched, resetFields, getFieldDecorator } = form;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isFieldsTouched() ? <ResetForm resetFields={resetFields} /> : null}
|
||||
<Button type="primary" key="submit" htmlType="submit">
|
||||
{t("general.labels.save")}
|
||||
</Button>
|
||||
<Row>
|
||||
<Col span={8}>
|
||||
<Form.Item label={t("vehicles.fields.v_vin")}>
|
||||
{getFieldDecorator("v_vin", {
|
||||
initialValue: vehicle.v_vin
|
||||
})(<Input name="v_vin" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.plate_no")}>
|
||||
{getFieldDecorator("plate_no", {
|
||||
initialValue: vehicle.plate_no
|
||||
})(<Input name="plate_no" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.plate_st")}>
|
||||
{getFieldDecorator("plate_st", {
|
||||
initialValue: vehicle.plate_st
|
||||
})(<Input name="plate_st" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_type")}>
|
||||
{getFieldDecorator("v_type", {
|
||||
initialValue: vehicle.v_type
|
||||
})(<Input name="v_type" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_trimcode")}>
|
||||
{getFieldDecorator("v_trimcode", {
|
||||
initialValue: vehicle.v_trimcode
|
||||
})(<Input name="v_trimcode" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_tone")}>
|
||||
{getFieldDecorator("v_tone", {
|
||||
initialValue: vehicle.v_tone
|
||||
})(<Input name="v_tone" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_bstyle")}>
|
||||
{getFieldDecorator("v_bstyle", {
|
||||
initialValue: vehicle.v_bstyle
|
||||
})(<Input name="v_bstyle" />)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Form.Item label={t("vehicles.fields.v_stage")}>
|
||||
{getFieldDecorator("v_stage", {
|
||||
initialValue: vehicle.v_stage
|
||||
})(<Input name="v_stage" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_prod_dt")}>
|
||||
{getFieldDecorator("v_prod_dt", {
|
||||
initialValue: vehicle.v_prod_dt ? moment(vehicle.v_prod_dt) : null
|
||||
})(<DatePicker name="v_prod_dt" />)}
|
||||
</Form.Item>
|
||||
{
|
||||
//TODO Add handling for paint code json
|
||||
}
|
||||
<Form.Item label={t("vehicles.fields.v_paint_codes")}>
|
||||
{getFieldDecorator("v_paint_codes", {
|
||||
initialValue: JSON.stringify(vehicle.v_paint_codes)
|
||||
})(<Input name="v_paint_codes" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_options")}>
|
||||
{getFieldDecorator("v_options", {
|
||||
initialValue: vehicle.v_options
|
||||
})(<Input name="v_options" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_model_yr")}>
|
||||
{getFieldDecorator("v_model_yr", {
|
||||
initialValue: vehicle.v_model_yr
|
||||
})(<Input name="v_model_yr" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_model_desc")}>
|
||||
{getFieldDecorator("v_model_desc", {
|
||||
initialValue: vehicle.v_model_desc
|
||||
})(<Input name="v_model_desc" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.trim_color")}>
|
||||
{getFieldDecorator("trim_color", {
|
||||
initialValue: vehicle.trim_color
|
||||
})(<Input name="trim_color" />)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col span={8}>
|
||||
<Form.Item label={t("vehicles.fields.v_mldgcode")}>
|
||||
{getFieldDecorator("v_mldgcode", {
|
||||
initialValue: vehicle.v_mldgcode
|
||||
})(<Input name="v_mldgcode" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_makecode")}>
|
||||
{getFieldDecorator("v_makecode", {
|
||||
initialValue: vehicle.v_makecode
|
||||
})(<Input name="v_makecode" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_make_desc")}>
|
||||
{getFieldDecorator("v_make_desc", {
|
||||
initialValue: vehicle.v_make_desc
|
||||
})(<Input name="v_make_desc" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_engine")}>
|
||||
{getFieldDecorator("v_engine", {
|
||||
initialValue: vehicle.v_engine
|
||||
})(<Input name="v_engine" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_cond")}>
|
||||
{getFieldDecorator("v_cond", {
|
||||
initialValue: vehicle.v_cond
|
||||
})(<Input name="v_cond" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={t("vehicles.fields.v_color")}>
|
||||
{getFieldDecorator("v_color", {
|
||||
initialValue: vehicle.v_color
|
||||
})(<Input name="v_color" />)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import React from "react";
|
||||
import { Form, notification } from "antd";
|
||||
import { useMutation } from "react-apollo";
|
||||
import VehicleDetailFormComponent from "./vehicle-detail-form.component";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UPDATE_VEHICLE } from "../../graphql/vehicles.queries";
|
||||
|
||||
function VehicleDetailFormContainer({ form, vehicle, refetch }) {
|
||||
const { t } = useTranslation();
|
||||
const [updateVehicle] = useMutation(UPDATE_VEHICLE);
|
||||
|
||||
const handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
|
||||
form.validateFieldsAndScroll((err, values) => {
|
||||
if (err) {
|
||||
notification["error"]({
|
||||
message: t("vehicles.errors.validationtitle"),
|
||||
description: t("vehicles.errors.validation")
|
||||
});
|
||||
}
|
||||
if (!err) {
|
||||
updateVehicle({
|
||||
variables: { vehId: vehicle.id, vehicle: values }
|
||||
}).then(r => {
|
||||
notification["success"]({
|
||||
message: t("vehicles.successes.save")
|
||||
});
|
||||
//TODO: Better way to reset the field decorators?
|
||||
if (refetch) refetch().then();
|
||||
form.resetFields();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Form onSubmit={handleSubmit} autoComplete="off">
|
||||
<VehicleDetailFormComponent form={form} vehicle={vehicle} />
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
export default Form.create({ name: "VehicleDetailFormContainer" })(
|
||||
VehicleDetailFormContainer
|
||||
);
|
||||
@@ -0,0 +1,59 @@
|
||||
import React from "react";
|
||||
import { Table } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Link } from "react-router-dom";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
export default function VehicleDetailJobsComponent({ vehicle }) {
|
||||
const { t } = useTranslation();
|
||||
const columns = [
|
||||
{
|
||||
title: t("jobs.fields.ro_number"),
|
||||
dataIndex: "ro_number",
|
||||
key: "ro_number",
|
||||
ellipsis: true,
|
||||
render: (text, record) => (
|
||||
<Link to={`/manage/jobs/${record.id}`}>
|
||||
{record.ro_number ? record.ro_number : `EST ${record.est_number}`}
|
||||
</Link>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.owner"),
|
||||
dataIndex: "owner",
|
||||
key: "owner",
|
||||
render: (text, record) => (
|
||||
<Link to={`/manage/owners/${record.owner.id}`}>
|
||||
{`${record.ownr_fn} ${record.ownr_ln}`}
|
||||
</Link>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.clm_no"),
|
||||
dataIndex: "clm_no",
|
||||
key: "clm_no"
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.status"),
|
||||
dataIndex: "status",
|
||||
key: "status"
|
||||
},
|
||||
|
||||
{
|
||||
title: t("jobs.fields.clm_total"),
|
||||
dataIndex: "clm_total",
|
||||
key: "clm_total",
|
||||
render: (text, record) => (
|
||||
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Table
|
||||
pagination={{ position: "bottom" }}
|
||||
columns={columns.map(item => ({ ...item }))}
|
||||
rowKey="id"
|
||||
dataSource={vehicle.jobs}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
export default WithInlineEdit = WrappedComponent => props => {
|
||||
const [editing, setEditing] = useState(false);
|
||||
const [modified, setModified] = useState(false);
|
||||
const [originalValue, setOriginalValue] = useState(null);
|
||||
|
||||
const toggleEdit = () => {
|
||||
setEditing(!editing);
|
||||
|
||||
if (editing) {
|
||||
this.input.focus();
|
||||
}
|
||||
};
|
||||
|
||||
return editing ? (
|
||||
<Form.Item style={{ margin: 0 }}>
|
||||
{form.getFieldDecorator(dataIndex, {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: `${title} is required.`
|
||||
}
|
||||
],
|
||||
initialValue: record[dataIndex]
|
||||
})(
|
||||
<Input
|
||||
ref={node => (this.input = node)}
|
||||
onPressEnter={this.save}
|
||||
onBlur={this.save}
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div
|
||||
className="editable-cell-value-wrap"
|
||||
style={{ paddingRight: 24 }}
|
||||
onClick={toggleEdit}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default WithInlineEdit;
|
||||
@@ -19,7 +19,7 @@ const errorLink = onError(
|
||||
}
|
||||
}
|
||||
if (networkError) {
|
||||
if (networkError?.message.includes("JWTExpired")) {
|
||||
if (networkError.message.includes("JWTExpired")) {
|
||||
expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,3 +18,50 @@ export const QUERY_SEARCH_OWNER_BY_IDX = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const QUERY_OWNER_BY_ID = gql`
|
||||
query QUERY_OWNER_BY_ID($id: uuid!) {
|
||||
owners_by_pk(id: $id) {
|
||||
id
|
||||
allow_text_message
|
||||
ownr_addr1
|
||||
ownr_addr2
|
||||
ownr_co_nm
|
||||
ownr_city
|
||||
ownr_ctry
|
||||
ownr_ea
|
||||
ownr_fn
|
||||
ownr_ph1
|
||||
ownr_ln
|
||||
ownr_ph2
|
||||
ownr_st
|
||||
ownr_title
|
||||
ownr_zip
|
||||
preferred_contact
|
||||
jobs {
|
||||
id
|
||||
ro_number
|
||||
est_number
|
||||
clm_no
|
||||
status
|
||||
clm_total
|
||||
vehicle {
|
||||
id
|
||||
v_model_yr
|
||||
v_model_desc
|
||||
v_make_desc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const UPDATE_OWNER = gql`
|
||||
mutation UPDATE_OWNER($ownerId: uuid!, $owner: owners_set_input!) {
|
||||
update_owners(where: { id: { _eq: $ownerId } }, _set: $owner) {
|
||||
returning {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
55
client/src/graphql/vehicles.queries.js
Normal file
55
client/src/graphql/vehicles.queries.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import { gql } from "apollo-boost";
|
||||
|
||||
export const QUERY_VEHICLE_BY_ID = gql`
|
||||
query QUERY_VEHICLE_BY_ID($id: uuid!) {
|
||||
vehicles_by_pk(id: $id) {
|
||||
created_at
|
||||
db_v_code
|
||||
id
|
||||
plate_no
|
||||
plate_st
|
||||
v_vin
|
||||
v_type
|
||||
v_trimcode
|
||||
v_tone
|
||||
v_stage
|
||||
v_prod_dt
|
||||
v_paint_codes
|
||||
v_options
|
||||
v_model_yr
|
||||
v_model_desc
|
||||
v_mldgcode
|
||||
v_makecode
|
||||
v_make_desc
|
||||
v_engine
|
||||
v_cond
|
||||
v_color
|
||||
v_bstyle
|
||||
updated_at
|
||||
trim_color
|
||||
jobs {
|
||||
id
|
||||
ro_number
|
||||
ownr_fn
|
||||
est_number
|
||||
ownr_ln
|
||||
owner {
|
||||
id
|
||||
}
|
||||
clm_no
|
||||
status
|
||||
clm_total
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const UPDATE_VEHICLE = gql`
|
||||
mutation UPDATE_VEHICLE($vehId: uuid!, $vehicle: vehicles_set_input!) {
|
||||
update_vehicles(where: { id: { _eq: $vehId } }, _set: $vehicle) {
|
||||
returning {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 8.0 KiB |
@@ -1,22 +1,18 @@
|
||||
import { Alert, Button, Form, Icon, Tabs } from "antd";
|
||||
import { Form, Icon, Tabs } from "antd";
|
||||
import React, { useContext } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
FaHardHat,
|
||||
FaInfo,
|
||||
FaRegStickyNote,
|
||||
FaShieldAlt
|
||||
} from "react-icons/fa";
|
||||
import { FaHardHat, FaInfo, FaRegStickyNote, FaShieldAlt } from "react-icons/fa";
|
||||
import ResetForm from "../../components/form-items-formatted/reset-form-item.component";
|
||||
import JobsLinesContainer from "../../components/job-detail-lines/job-lines.container";
|
||||
import JobsDetailClaims from "../../components/jobs-detail-claims/jobs-detail-claims.component";
|
||||
import JobsDetailDatesComponent from "../../components/jobs-detail-dates/jobs-detail-dates.component";
|
||||
import JobsDetailFinancials from "../../components/jobs-detail-financial/jobs-detail-financial.component";
|
||||
import JobsDetailHeader from "../../components/jobs-detail-header/jobs-detail-header.component";
|
||||
import JobsDetailInsurance from "../../components/jobs-detail-insurance/jobs-detail-insurance.component";
|
||||
import JobsDocumentsContainer from "../../components/jobs-documents/jobs-documents.container";
|
||||
import JobNotesContainer from "../../components/jobs-notes/jobs-notes.container";
|
||||
import JobDetailFormContext from "./jobs-detail.page.context";
|
||||
import JobsDetailDatesComponent from "../../components/jobs-detail-dates/jobs-detail-dates.component";
|
||||
import ScheduleJobModalContainer from "../../components/schedule-job-modal/schedule-job-modal.container";
|
||||
import JobDetailFormContext from "./jobs-detail.page.context";
|
||||
|
||||
export default function JobsDetailPage({
|
||||
job,
|
||||
@@ -60,19 +56,7 @@ export default function JobsDetailPage({
|
||||
updateJobStatus={updateJobStatus}
|
||||
/>
|
||||
|
||||
{isFieldsTouched() ? (
|
||||
<Alert
|
||||
message={
|
||||
<div>
|
||||
{t("general.messages.unsavedchanges")}
|
||||
<Button onClick={() => resetFields()}>
|
||||
{t("general.actions.reset")}
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
closable
|
||||
/>
|
||||
) : null}
|
||||
{isFieldsTouched() ? <ResetForm resetFields={resetFields} /> : null}
|
||||
|
||||
<Tabs defaultActiveKey="claimdetail">
|
||||
<Tabs.TabPane
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from 'react'
|
||||
import ManageRootPageComponent from './manage-root.page.component'
|
||||
|
||||
import React, { useEffect } from "react";
|
||||
import ManageRootPageComponent from "./manage-root.page.component";
|
||||
import { useTranslation } from "react-i18next";
|
||||
export default function ManageRootPageContainer() {
|
||||
return (
|
||||
<ManageRootPageComponent />
|
||||
)
|
||||
const { t } = useTranslation();
|
||||
useEffect(() => {
|
||||
document.title = t("titles.manageroot");
|
||||
}, [t]);
|
||||
|
||||
return <ManageRootPageComponent />;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,34 @@
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import ManagePage from "./manage.page";
|
||||
import { useQuery } from "react-apollo";
|
||||
import { QUERY_BODYSHOP } from "../../graphql/bodyshop.queries";
|
||||
import { setBodyshop } from "../../redux/user/user.actions";
|
||||
import { connect } from "react-redux";
|
||||
import { notification } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function ManagePageContainer() {
|
||||
return <ManagePage />;
|
||||
}
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
setBodyshop: bs => dispatch(setBodyshop(bs))
|
||||
});
|
||||
|
||||
export default connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)(function ManagePageContainer({ match, setBodyshop }) {
|
||||
const { error, data } = useQuery(QUERY_BODYSHOP, {
|
||||
fetchPolicy: "network-only"
|
||||
});
|
||||
const { t } = useTranslation();
|
||||
if (error) {
|
||||
notification["error"]({ message: t("bodyshop.errors.loading") });
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (data) setBodyshop(data.bodyshops[0]);
|
||||
return () => {
|
||||
//
|
||||
};
|
||||
}, [data, setBodyshop]);
|
||||
|
||||
return <ManagePage match={match} />;
|
||||
});
|
||||
|
||||
@@ -1,19 +1,12 @@
|
||||
import { BackTop, Layout, notification } from "antd";
|
||||
import { BackTop, Layout } from "antd";
|
||||
import React, { lazy, Suspense, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
//This page will handle all routing for the entire application.
|
||||
import { connect } from "react-redux";
|
||||
import { Route } from "react-router";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { useQuery } from "react-apollo";
|
||||
import { QUERY_BODYSHOP } from "../../graphql/bodyshop.queries";
|
||||
import ErrorBoundary from "../../components/error-boundary/error-boundary.component";
|
||||
import FooterComponent from "../../components/footer/footer.component";
|
||||
//Component Imports
|
||||
import HeaderContainer from "../../components/header/header.container";
|
||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||
//const WhiteBoardPage = lazy(() => import("../white-board/white-board.page"));
|
||||
import { setBodyshop } from "../../redux/user/user.actions";
|
||||
import "./manage.page.styles.scss";
|
||||
|
||||
const ManageRootPage = lazy(() =>
|
||||
@@ -36,29 +29,21 @@ const ChatWindowContainer = lazy(() =>
|
||||
const ScheduleContainer = lazy(() =>
|
||||
import("../schedule/schedule.page.container")
|
||||
);
|
||||
|
||||
const VehiclesContainer = lazy(() =>
|
||||
import("../vehicles/vehicles.page.container")
|
||||
);
|
||||
const VehiclesDetailContainer = lazy(() =>
|
||||
import("../vehicles-detail/vehicles-detail.page.container")
|
||||
);
|
||||
const OwnersContainer = lazy(() => import("../owners/owners.page.container"));
|
||||
const OwnersDetailContainer = lazy(() =>
|
||||
import("../owners-detail/owners-detail.page.container")
|
||||
);
|
||||
const { Header, Content, Footer } = Layout;
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
setBodyshop: bs => dispatch(setBodyshop(bs))
|
||||
});
|
||||
export default connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)(function Manage({ match, setBodyshop }) {
|
||||
export default function Manage({ match }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { error, data } = useQuery(QUERY_BODYSHOP, {
|
||||
fetchPolicy: "network-only"
|
||||
});
|
||||
|
||||
if (error) {
|
||||
notification["error"]({ message: t("bodyshop.errors.loading") });
|
||||
}
|
||||
if (data) {
|
||||
setBodyshop(data.bodyshops[0]);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
document.title = t("titles.app");
|
||||
}, [t]);
|
||||
@@ -97,7 +82,26 @@ export default connect(
|
||||
path={`${match.path}/profile`}
|
||||
component={ProfilePage}
|
||||
/>
|
||||
|
||||
<Route
|
||||
exact
|
||||
path={`${match.path}/vehicles`}
|
||||
component={VehiclesContainer}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={`${match.path}/vehicles/:vehId`}
|
||||
component={VehiclesDetailContainer}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={`${match.path}/owners`}
|
||||
component={OwnersContainer}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={`${match.path}/owners/:ownerId`}
|
||||
component={OwnersDetailContainer}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path={`${match.path}/schedule`}
|
||||
@@ -119,4 +123,4 @@ export default connect(
|
||||
<BackTop />
|
||||
</Layout>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
import OwnerDetailForm from "../../components/owner-detail-form/owner-detail-form.container";
|
||||
import OwnerDetailJobsComponent from "../../components/owner-detail-jobs/owner-detail-jobs.component";
|
||||
export default function OwnersDetailComponent({ owner, refetch }) {
|
||||
return (
|
||||
<div>
|
||||
<OwnerDetailForm owner={owner} refetch={refetch} />
|
||||
<OwnerDetailJobsComponent owner={owner} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
import OwnersDetailComponent from "./owners-detail.page.component";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useQuery } from "react-apollo";
|
||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||
import AlertComponent from "../../components/alert/alert.component";
|
||||
import { QUERY_OWNER_BY_ID } from "../../graphql/owners.queries";
|
||||
export default function OwnersDetailContainer({ match }) {
|
||||
const { ownerId } = match.params;
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { loading, data, error, refetch } = useQuery(QUERY_OWNER_BY_ID, {
|
||||
variables: { id: ownerId },
|
||||
fetchPolicy: "network-only"
|
||||
});
|
||||
|
||||
if (loading) return <LoadingSpinner />;
|
||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||
|
||||
if (data.owners_by_pk)
|
||||
return (
|
||||
<OwnersDetailComponent owner={data.owners_by_pk} refetch={refetch} />
|
||||
);
|
||||
else
|
||||
return (
|
||||
<AlertComponent message={t("owners.errors.noaccess")} type="error" />
|
||||
);
|
||||
}
|
||||
9
client/src/pages/owners/owners.page.component.jsx
Normal file
9
client/src/pages/owners/owners.page.component.jsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function OwnersPageComponent() {
|
||||
return (
|
||||
<div>
|
||||
Owners Page
|
||||
</div>
|
||||
)
|
||||
}
|
||||
8
client/src/pages/owners/owners.page.container.jsx
Normal file
8
client/src/pages/owners/owners.page.container.jsx
Normal file
@@ -0,0 +1,8 @@
|
||||
import React from 'react'
|
||||
import OwnersPageComponent from './owners.page.component'
|
||||
|
||||
export default function OwnersPageContainer() {
|
||||
return (
|
||||
<OwnersPageComponent />
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,11 @@
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import ProfilePage from "./profile.page";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
export default function ProfileContainerPage() {
|
||||
const { t } = useTranslation();
|
||||
useEffect(() => {
|
||||
document.title = t("titles.profile");
|
||||
}, [t]);
|
||||
|
||||
return <ProfilePage />;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Layout } from "antd";
|
||||
import ProfileSideBar from "../../components/profile-sidebar/profile-sidebar.component";
|
||||
import React, { useState } from "react";
|
||||
import ProfileContent from "../../components/profile-content/profile-content.component";
|
||||
import ProfileSideBar from "../../components/profile-sidebar/profile-sidebar.component";
|
||||
|
||||
export default function ProfilePage() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
document.title = t("titles.profile");
|
||||
}, [t]);
|
||||
|
||||
const [sidebarSelection, setSidebarSelection] = useState({ key: "profile" });
|
||||
return (
|
||||
<Layout>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import React from "react";
|
||||
import VehicleDetailFormContainer from "../../components/vehicle-detail-form/vehicle-detail-form.container";
|
||||
import VehicleDetailJobsComponent from "../../components/vehicle-detail-jobs/vehicle-detail-jobs.component";
|
||||
|
||||
export default function VehicleDetailComponent({ vehicle, refetch }) {
|
||||
return (
|
||||
<div>
|
||||
<VehicleDetailFormContainer vehicle={vehicle} refetch={refetch} />
|
||||
<VehicleDetailJobsComponent vehicle={vehicle} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import React, { useEffect } from "react";
|
||||
import VehicleDetailComponent from "./vehicles-detail.page.component";
|
||||
import { useQuery } from "react-apollo";
|
||||
import { QUERY_VEHICLE_BY_ID } from "../../graphql/vehicles.queries";
|
||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||
import AlertComponent from "../../components/alert/alert.component";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export default function VehicleDetailContainer({ match }) {
|
||||
const { vehId } = match.params;
|
||||
const { t } = useTranslation();
|
||||
const { loading, data, error, refetch } = useQuery(QUERY_VEHICLE_BY_ID, {
|
||||
variables: { id: vehId },
|
||||
fetchPolicy: "network-only"
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
document.title = t("titles.vehicledetail", {
|
||||
vehicle:
|
||||
data && data.vehicles_by_pk
|
||||
? `${data.vehicles_by_pk.v_model_yr} ${data.vehicles_by_pk.v_make_desc} ${data.vehicles_by_pk.v_model_desc}`
|
||||
: ""
|
||||
});
|
||||
}, [t, data]);
|
||||
|
||||
if (loading) return <LoadingSpinner />;
|
||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||
|
||||
if (data.vehicles_by_pk)
|
||||
return (
|
||||
<VehicleDetailComponent vehicle={data.vehicles_by_pk} refetch={refetch} />
|
||||
);
|
||||
else
|
||||
return (
|
||||
<AlertComponent message={t("vehicles.errors.noaccess")} type="error" />
|
||||
);
|
||||
}
|
||||
9
client/src/pages/vehicles/vehicles.page.component.jsx
Normal file
9
client/src/pages/vehicles/vehicles.page.component.jsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
|
||||
export default function VehiclesPageComponent() {
|
||||
return (
|
||||
<div>
|
||||
Vehiculos
|
||||
</div>
|
||||
)
|
||||
}
|
||||
6
client/src/pages/vehicles/vehicles.page.container.jsx
Normal file
6
client/src/pages/vehicles/vehicles.page.container.jsx
Normal file
@@ -0,0 +1,6 @@
|
||||
import React from "react";
|
||||
import VehiclesPageComponent from "./vehicles.page.component";
|
||||
|
||||
export default function VehiclesPageContainer() {
|
||||
return <VehiclesPageComponent />;
|
||||
}
|
||||
@@ -34,6 +34,7 @@ export function* signInWithEmail({ payload: { email, password } }) {
|
||||
uid: user.uid,
|
||||
email: user.email,
|
||||
displayName: user.displayName,
|
||||
photoURL: user.photoURL,
|
||||
authorized: true
|
||||
})
|
||||
);
|
||||
@@ -62,6 +63,7 @@ export function* isUserAuthenticated() {
|
||||
uid: user.uid,
|
||||
email: user.email,
|
||||
displayName: user.displayName,
|
||||
photoURL: user.photoURL,
|
||||
authorized: true
|
||||
})
|
||||
);
|
||||
|
||||
@@ -246,9 +246,12 @@
|
||||
"header": {
|
||||
"activejobs": "Active Jobs",
|
||||
"availablejobs": "Available Jobs",
|
||||
"customers": "Customers",
|
||||
"home": "Home",
|
||||
"jobs": "Jobs",
|
||||
"schedule": "Schedule"
|
||||
"owners": "Owners",
|
||||
"schedule": "Schedule",
|
||||
"vehicles": "Vehicles"
|
||||
},
|
||||
"jobsdetail": {
|
||||
"claimdetail": "Claim Details",
|
||||
@@ -288,16 +291,29 @@
|
||||
}
|
||||
},
|
||||
"owners": {
|
||||
"errors": {
|
||||
"noaccess": "The record does not exist or you do not have access to it. "
|
||||
},
|
||||
"fields": {
|
||||
"allow_text_message": "Permission to Text?",
|
||||
"ownr_addr1": "Address",
|
||||
"ownr_addr2": "Address 2",
|
||||
"ownr_city": "City",
|
||||
"ownr_ctry": "Country",
|
||||
"ownr_ea": "Email",
|
||||
"ownr_fn": "First Name",
|
||||
"ownr_ln": "Last Name",
|
||||
"ownr_ph1": "Phone 1"
|
||||
"ownr_ph1": "Phone 1",
|
||||
"ownr_st": "State/Province",
|
||||
"ownr_title": "Title",
|
||||
"ownr_zip": "Zip/Postal Code",
|
||||
"preferred_contact": "Preferred Contact Method"
|
||||
},
|
||||
"labels": {
|
||||
"existing_owners": "Existing Owners"
|
||||
},
|
||||
"successes": {
|
||||
"save": "Owner saved successfully."
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
@@ -311,8 +327,10 @@
|
||||
"jobsavailable": "Available Jobs | $t(titles.app)",
|
||||
"jobsdetail": "Job {{ro_number}} | $t(titles.app)",
|
||||
"jobsdocuments": "Job Documents {{ro_number}} | $t(titles.app)",
|
||||
"manageroot": "Home | $t(titles.app)",
|
||||
"profile": "My Profile | $t(titles.app)",
|
||||
"schedule": "Schedule | $t(titles.app)"
|
||||
"schedule": "Schedule | $t(titles.app)",
|
||||
"vehicledetail": "Vehicle Details {{vehicle}} | $t(titles.app)"
|
||||
},
|
||||
"user": {
|
||||
"actions": {
|
||||
@@ -320,12 +338,40 @@
|
||||
"updateprofile": "Update Profile"
|
||||
},
|
||||
"fields": {
|
||||
"displayname": "Display Name"
|
||||
"displayname": "Display Name",
|
||||
"photourl": "Avatar URL"
|
||||
}
|
||||
},
|
||||
"vehicles": {
|
||||
"errors": {
|
||||
"noaccess": "The vehicle does not exist or you do not have access to it.",
|
||||
"validation": "Please ensure all fields are entered correctly.",
|
||||
"validationtitle": "Validation Error"
|
||||
},
|
||||
"fields": {
|
||||
"plate_no": "License Plate"
|
||||
"plate_no": "License Plate",
|
||||
"plate_st": "Plate Jurisdiction",
|
||||
"trim_color": "Trim Color",
|
||||
"v_bstyle": "Body Style",
|
||||
"v_color": "Color",
|
||||
"v_cond": "Condition",
|
||||
"v_engine": "Engine",
|
||||
"v_make_desc": "Make",
|
||||
"v_makecode": "Make Code",
|
||||
"v_mldgcode": "Molding Code",
|
||||
"v_model_desc": "Model",
|
||||
"v_model_yr": "Year",
|
||||
"v_options": "Options",
|
||||
"v_paint_codes": "Paint Codes",
|
||||
"v_prod_dt": "Production Date",
|
||||
"v_stage": "Stage",
|
||||
"v_tone": "Tone",
|
||||
"v_trimcode": "Trim Code",
|
||||
"v_type": "Type",
|
||||
"v_vin": "Vehicle Identification Number"
|
||||
},
|
||||
"successes": {
|
||||
"save": "Vehicle saved successfully."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,9 +246,12 @@
|
||||
"header": {
|
||||
"activejobs": "Empleos activos",
|
||||
"availablejobs": "Trabajos disponibles",
|
||||
"customers": "Clientes",
|
||||
"home": "Casa",
|
||||
"jobs": "Trabajos",
|
||||
"schedule": "Programar"
|
||||
"owners": "propietarios",
|
||||
"schedule": "Programar",
|
||||
"vehicles": "Vehículos"
|
||||
},
|
||||
"jobsdetail": {
|
||||
"claimdetail": "Detalles de la reclamación",
|
||||
@@ -288,16 +291,29 @@
|
||||
}
|
||||
},
|
||||
"owners": {
|
||||
"errors": {
|
||||
"noaccess": "El registro no existe o no tiene acceso a él."
|
||||
},
|
||||
"fields": {
|
||||
"allow_text_message": "Permiso de texto?",
|
||||
"ownr_addr1": "Dirección",
|
||||
"ownr_addr2": "Dirección 2",
|
||||
"ownr_city": "ciudad",
|
||||
"ownr_ctry": "País",
|
||||
"ownr_ea": "Email",
|
||||
"ownr_fn": "Nombre de pila",
|
||||
"ownr_ln": "Apellido",
|
||||
"ownr_ph1": ""
|
||||
"ownr_ph1": "Teléfono 1",
|
||||
"ownr_st": "Provincia del estado",
|
||||
"ownr_title": "Título",
|
||||
"ownr_zip": "código postal",
|
||||
"preferred_contact": "Método de Contacto Preferido"
|
||||
},
|
||||
"labels": {
|
||||
"existing_owners": "Propietarios existentes"
|
||||
},
|
||||
"successes": {
|
||||
"save": "Propietario guardado con éxito."
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
@@ -311,8 +327,10 @@
|
||||
"jobsavailable": "Empleos disponibles | $t(titles.app)",
|
||||
"jobsdetail": "Trabajo {{ro_number}} | $t(titles.app)",
|
||||
"jobsdocuments": "Documentos de trabajo {{ro_number}} | $ t (títulos.app)",
|
||||
"manageroot": "Casa | $t(titles.app)",
|
||||
"profile": "Mi perfil | $t(titles.app)",
|
||||
"schedule": "Horario | $t(titles.app)"
|
||||
"schedule": "Horario | $t(titles.app)",
|
||||
"vehicledetail": "Detalles del vehículo {{vehicle}} | $t(titles.app)"
|
||||
},
|
||||
"user": {
|
||||
"actions": {
|
||||
@@ -320,12 +338,40 @@
|
||||
"updateprofile": "Actualización del perfil"
|
||||
},
|
||||
"fields": {
|
||||
"displayname": "Nombre para mostrar"
|
||||
"displayname": "Nombre para mostrar",
|
||||
"photourl": "URL de avatar"
|
||||
}
|
||||
},
|
||||
"vehicles": {
|
||||
"errors": {
|
||||
"noaccess": "El vehículo no existe o usted no tiene acceso a él.",
|
||||
"validation": "Asegúrese de que todos los campos se ingresen correctamente.",
|
||||
"validationtitle": "Error de validacion"
|
||||
},
|
||||
"fields": {
|
||||
"plate_no": "Placa"
|
||||
"plate_no": "Placa",
|
||||
"plate_st": "Jurisdicción de placas",
|
||||
"trim_color": "Recortar color",
|
||||
"v_bstyle": "Tipo de cuerpo",
|
||||
"v_color": "Color",
|
||||
"v_cond": "condición",
|
||||
"v_engine": "Motor",
|
||||
"v_make_desc": "Hacer",
|
||||
"v_makecode": "Hacer código",
|
||||
"v_mldgcode": "Código de moldeo",
|
||||
"v_model_desc": "Modelo",
|
||||
"v_model_yr": "año",
|
||||
"v_options": "Opciones",
|
||||
"v_paint_codes": "Códigos de pintura",
|
||||
"v_prod_dt": "Fecha de producción",
|
||||
"v_stage": "Escenario",
|
||||
"v_tone": "Tono",
|
||||
"v_trimcode": "Código de recorte",
|
||||
"v_type": "Tipo",
|
||||
"v_vin": "Número de identificación del vehículo"
|
||||
},
|
||||
"successes": {
|
||||
"save": "Vehículo guardado con éxito."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,9 +246,12 @@
|
||||
"header": {
|
||||
"activejobs": "Emplois actifs",
|
||||
"availablejobs": "Emplois disponibles",
|
||||
"customers": "Les clients",
|
||||
"home": "Accueil",
|
||||
"jobs": "Emplois",
|
||||
"schedule": "Programme"
|
||||
"owners": "Propriétaires",
|
||||
"schedule": "Programme",
|
||||
"vehicles": "Véhicules"
|
||||
},
|
||||
"jobsdetail": {
|
||||
"claimdetail": "Détails de la réclamation",
|
||||
@@ -288,16 +291,29 @@
|
||||
}
|
||||
},
|
||||
"owners": {
|
||||
"errors": {
|
||||
"noaccess": "L'enregistrement n'existe pas ou vous n'y avez pas accès."
|
||||
},
|
||||
"fields": {
|
||||
"allow_text_message": "Autorisation de texte?",
|
||||
"ownr_addr1": "Adresse",
|
||||
"ownr_addr2": "Adresse 2 ",
|
||||
"ownr_city": "Ville",
|
||||
"ownr_ctry": "Pays",
|
||||
"ownr_ea": "Email",
|
||||
"ownr_fn": "Prénom",
|
||||
"ownr_ln": "Nom de famille",
|
||||
"ownr_ph1": ""
|
||||
"ownr_ph1": "Téléphone 1",
|
||||
"ownr_st": "Etat / Province",
|
||||
"ownr_title": "Titre",
|
||||
"ownr_zip": "Zip / code postal",
|
||||
"preferred_contact": "Méthode de contact préférée"
|
||||
},
|
||||
"labels": {
|
||||
"existing_owners": "Propriétaires existants"
|
||||
},
|
||||
"successes": {
|
||||
"save": "Le propriétaire a bien enregistré."
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
@@ -311,8 +327,10 @@
|
||||
"jobsavailable": "Emplois disponibles | $t(titles.app)",
|
||||
"jobsdetail": "Travail {{ro_number}} | $t(titles.app)",
|
||||
"jobsdocuments": "Documents de travail {{ro_number}} | $ t (titres.app)",
|
||||
"manageroot": "Accueil | $t(titles.app)",
|
||||
"profile": "Mon profil | $t(titles.app)",
|
||||
"schedule": "Horaire | $t(titles.app)"
|
||||
"schedule": "Horaire | $t(titles.app)",
|
||||
"vehicledetail": "Détails du véhicule {{vehicle} | $t(titles.app)"
|
||||
},
|
||||
"user": {
|
||||
"actions": {
|
||||
@@ -320,12 +338,40 @@
|
||||
"updateprofile": "Mettre à jour le profil"
|
||||
},
|
||||
"fields": {
|
||||
"displayname": "Afficher un nom"
|
||||
"displayname": "Afficher un nom",
|
||||
"photourl": "URL de l'avatar"
|
||||
}
|
||||
},
|
||||
"vehicles": {
|
||||
"errors": {
|
||||
"noaccess": "Le véhicule n'existe pas ou vous n'y avez pas accès.",
|
||||
"validation": "Veuillez vous assurer que tous les champs sont correctement entrés.",
|
||||
"validationtitle": "Erreur de validation"
|
||||
},
|
||||
"fields": {
|
||||
"plate_no": "Plaque d'immatriculation"
|
||||
"plate_no": "Plaque d'immatriculation",
|
||||
"plate_st": "Juridiction de la plaque",
|
||||
"trim_color": "Couleur de garniture",
|
||||
"v_bstyle": "Style corporel",
|
||||
"v_color": "Couleur",
|
||||
"v_cond": "Etat",
|
||||
"v_engine": "moteur",
|
||||
"v_make_desc": "Faire",
|
||||
"v_makecode": "Faire du code",
|
||||
"v_mldgcode": "Code de moulage",
|
||||
"v_model_desc": "Modèle",
|
||||
"v_model_yr": "année",
|
||||
"v_options": "Les options",
|
||||
"v_paint_codes": "Codes de peinture",
|
||||
"v_prod_dt": "Date de production",
|
||||
"v_stage": "Étape",
|
||||
"v_tone": "ton",
|
||||
"v_trimcode": "Code de coupe",
|
||||
"v_type": "Type",
|
||||
"v_vin": "Plaque d'immatriculation"
|
||||
},
|
||||
"successes": {
|
||||
"save": "Le véhicule a été enregistré avec succès."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
3110
client/yarn.lock
3110
client/yarn.lock
File diff suppressed because it is too large
Load Diff
@@ -17,14 +17,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"apollo-cache-persist": "^0.1.1",
|
||||
"aws-sdk": "^2.603.0",
|
||||
"aws-sdk": "^2.613.0",
|
||||
"body-parser": "^1.18.3",
|
||||
"compression": "^1.7.4",
|
||||
"cors": "2.8.5",
|
||||
"dotenv": "7.0.0",
|
||||
"dotenv": "8.2.0",
|
||||
"express": "^4.16.4",
|
||||
"express-sslify": "^1.2.0",
|
||||
"firebase-tools": "^7.9.0"
|
||||
"firebase-tools": "^7.12.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"concurrently": "^4.0.1",
|
||||
|
||||
31
yarn.lock
31
yarn.lock
@@ -386,10 +386,10 @@ asynckit@^0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
|
||||
|
||||
aws-sdk@^2.603.0:
|
||||
version "2.603.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.603.0.tgz#0920756d2666f4fcfa7233841ef35cd04da81348"
|
||||
integrity sha512-+VlskUDLZLQDDlaVa0Tb02aEFEWcKkTfTew1SGYwce9hUrKcR33IX4e9kM6MyI7UeLQAl0v8dagTniP67UrTQw==
|
||||
aws-sdk@^2.613.0:
|
||||
version "2.613.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.613.0.tgz#f0d4c99f0df7ee8227d331dde19d5251b31a5da7"
|
||||
integrity sha512-FYLaVtC/AlrcnjsPw1JhAsKd6yapr918Mk0jAcw3yFZp1sI2V0Um+2pmijLFsV+nNRxFlCVJRhhFWB5GK6yALA==
|
||||
dependencies:
|
||||
buffer "4.9.1"
|
||||
events "1.1.1"
|
||||
@@ -1092,10 +1092,10 @@ dot-prop@^4.1.0:
|
||||
dependencies:
|
||||
is-obj "^1.0.0"
|
||||
|
||||
dotenv@7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-7.0.0.tgz#a2be3cd52736673206e8a85fb5210eea29628e7c"
|
||||
integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==
|
||||
dotenv@8.2.0:
|
||||
version "8.2.0"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
|
||||
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
|
||||
|
||||
dotenv@^6.1.0:
|
||||
version "6.2.0"
|
||||
@@ -1548,10 +1548,10 @@ find-up@^3.0.0:
|
||||
dependencies:
|
||||
locate-path "^3.0.0"
|
||||
|
||||
firebase-tools@^7.9.0:
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/firebase-tools/-/firebase-tools-7.9.0.tgz#32661980943f5ebbb2d82c126762c468ae0cff9c"
|
||||
integrity sha512-dYxuFflaPAkic2KQyPJ6spox8KzlQRb4Xyk6oVDorBV0YmBIJ3VQhJYbwSZwwDlbCmiPiMXNBM26JUifp09Qfw==
|
||||
firebase-tools@^7.12.1:
|
||||
version "7.12.1"
|
||||
resolved "https://registry.yarnpkg.com/firebase-tools/-/firebase-tools-7.12.1.tgz#af78bbc446ae46d722938bd8009c351d52ec01f3"
|
||||
integrity sha512-4cfHltsfUzKyt03OH9JUYrCPsq0OIZ9i54IzJRjJgs68NJDLrhUislBipw5Am0QgF8QDYpzz8wLTH56fNgmx8g==
|
||||
dependencies:
|
||||
"@google-cloud/pubsub" "^1.1.5"
|
||||
JSONStream "^1.2.1"
|
||||
@@ -1574,6 +1574,7 @@ firebase-tools@^7.9.0:
|
||||
fs-extra "^0.23.1"
|
||||
glob "^7.1.2"
|
||||
google-auto-auth "^0.7.2"
|
||||
google-gax "~1.12.0"
|
||||
inquirer "~6.3.1"
|
||||
jsonschema "^1.0.2"
|
||||
jsonwebtoken "^8.2.1"
|
||||
@@ -1587,7 +1588,7 @@ firebase-tools@^7.9.0:
|
||||
portfinder "^1.0.23"
|
||||
progress "^2.0.3"
|
||||
request "^2.87.0"
|
||||
semver "^5.0.3"
|
||||
semver "^5.7.1"
|
||||
superstatic "^6.0.1"
|
||||
tar "^4.3.0"
|
||||
tcp-port-used "^1.0.1"
|
||||
@@ -1843,7 +1844,7 @@ google-auto-auth@^0.7.2:
|
||||
google-auth-library "^0.10.0"
|
||||
request "^2.79.0"
|
||||
|
||||
google-gax@^1.7.5:
|
||||
google-gax@^1.7.5, google-gax@~1.12.0:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-1.12.0.tgz#f926f7e6abda245db38ecbebbbf58daaf3a8f687"
|
||||
integrity sha512-BeeoxVO6y9K20gUsexUwptutd0PfrTItrA02JWwwstlBIOAcvgFp86MHWufQsnrkPVhxBjHXq65aIkSejtJjDg==
|
||||
@@ -3508,7 +3509,7 @@ semver-diff@^2.0.0:
|
||||
dependencies:
|
||||
semver "^5.0.3"
|
||||
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.5.0, semver@^5.6.0:
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||
|
||||
Reference in New Issue
Block a user