Merge pull request #10 from snaptsoft/dev-patrick

Dev patrick
This commit is contained in:
2020-02-12 19:41:52 -08:00
committed by GitHub
154 changed files with 9699 additions and 2545 deletions

View File

@@ -1,4 +1,4 @@
<babeledit_project version="1.2" be_version="2.6.1">
<babeledit_project be_version="2.6.1" version="1.2">
<!--
BabelEdit project file
@@ -18,6 +18,63 @@
<folder_node>
<name>translation</name>
<children>
<folder_node>
<name>allocations</name>
<children>
<folder_node>
<name>actions</name>
<children>
<concept_node>
<name>assign</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>employee</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>
<name>appointments</name>
<children>
@@ -66,6 +123,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>new</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>reschedule</name>
<definition_loaded>false</definition_loaded>
@@ -157,6 +235,32 @@
</concept_node>
</children>
</folder_node>
<folder_node>
<name>fields</name>
<children>
<concept_node>
<name>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>
</children>
</folder_node>
<folder_node>
<name>labels</name>
<children>
@@ -618,12 +722,415 @@
</folder_node>
</children>
</folder_node>
<folder_node>
<name>employees</name>
<children>
<folder_node>
<name>actions</name>
<children>
<concept_node>
<name>new</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>errors</name>
<children>
<concept_node>
<name>delete</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>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>
<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>
<concept_node>
<name>active</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>base_rate</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>cost_center</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>employee_number</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>first_name</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>flat_rate</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>hire_date</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>last_name</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>termination_date</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>delete</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>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>
<name>general</name>
<children>
<folder_node>
<name>actions</name>
<children>
<concept_node>
<name>delete</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>edit</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>reset</name>
<definition_loaded>false</definition_loaded>
@@ -645,6 +1152,27 @@
</translation>
</translations>
</concept_node>
<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>
<folder_node>
@@ -671,6 +1199,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>barcode</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>in</name>
<definition_loaded>false</definition_loaded>
@@ -914,6 +1463,32 @@
</concept_node>
</children>
</folder_node>
<folder_node>
<name>validation</name>
<children>
<concept_node>
<name>required</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>
@@ -985,6 +1560,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>mod_lb_hrs</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>oem_partno</name>
<definition_loaded>false</definition_loaded>
@@ -3703,6 +4299,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>existing_jobs</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>lines</name>
<definition_loaded>false</definition_loaded>
@@ -3745,6 +4362,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>override_header</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>parts</name>
<definition_loaded>false</definition_loaded>
@@ -3939,6 +4577,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>supplemented</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>
@@ -4143,6 +4802,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>shop</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>vehicles</name>
<definition_loaded>false</definition_loaded>
@@ -4697,6 +5377,27 @@
<folder_node>
<name>fields</name>
<children>
<concept_node>
<name>address</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>allow_text_message</name>
<definition_loaded>false</definition_loaded>
@@ -4718,6 +5419,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>name</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>
@@ -4975,6 +5697,27 @@
<folder_node>
<name>labels</name>
<children>
<concept_node>
<name>create_new</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>existing_owners</name>
<definition_loaded>false</definition_loaded>
@@ -5186,6 +5929,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>profile</name>
<definition_loaded>false</definition_loaded>
@@ -5228,6 +5992,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>shop</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>vehicledetail</name>
<definition_loaded>false</definition_loaded>
@@ -5249,6 +6034,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>
@@ -5424,6 +6230,27 @@
<folder_node>
<name>fields</name>
<children>
<concept_node>
<name>description</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>plate_no</name>
<definition_loaded>false</definition_loaded>

View File

@@ -19,6 +19,7 @@
"node-sass": "^4.13.1",
"react": "^16.12.0",
"react-apollo": "^3.1.3",
"react-barcode": "^1.4.0",
"react-big-calendar": "^0.23.0",
"react-chartjs-2": "^2.9.0",
"react-dom": "^16.12.0",
@@ -30,7 +31,6 @@
"react-redux": "^7.1.3",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.1",
"react-trello": "^2.2.3",
"redux": "^4.0.5",
"redux-logger": "^3.0.6",
"redux-persist": "^6.0.0",

View File

@@ -0,0 +1,787 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1668"
height="1160"
id="svg2"
version="1.1"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="unfolded_car.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.71043165"
inkscape:cx="463.20424"
inkscape:cy="602.99002"
inkscape:document-units="px"
inkscape:current-layer="primary"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-global="false"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="car"
inkscape:label="CAR"
transform="translate(253.99998,-253.99995)"
style="display:inline">
<g
id="g4113"
transform="translate(-13.779768,3.524026)">
<path
sodipodi:nodetypes="csssscccsssscsccscccsscccssc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3070"
d="M 748.57143,752.85714 C 790,737.14285 888.57143,741.42857 940,740 c 51.42857,-1.42857 160.4745,10.23062 201.4286,27.14286 40.9958,16.92944 134.7843,67.65586 151.4285,72.85714 22.8572,7.14286 41.4286,7.14286 80,20 38.5715,12.85714 25.7143,32.85714 25.7143,32.85714 l -30,-4.28571 -5.7562,52.92008 c 0,0 37.1848,1.36563 41.4705,15.65135 4.2857,14.28571 5.7143,31.42857 -2.8571,41.42857 -8.5715,9.99997 -14.2857,-1.42857 -18.5715,12.85717 -4.2857,14.2857 -2.8571,28.5714 -27.1428,27.1428 -24.2857,-1.4285 -98.5715,0 -98.5715,0 0,0 -15.7142,-108.5714 -98.5714,-105.71426 -82.8571,2.85715 -95.7143,105.71426 -95.7143,105.71426 H 562.85714 c 0,0 -5.71428,-104.28569 -97.14286,-105.71426 -91.42857,-1.42857 -98.57142,105.71426 -98.57142,105.71426 H 301.42857 L 282.85714,1000 c -0.51524,0 -26.24328,-10e-6 -21.42857,-17.14285 4.65143,-16.56149 -4.28571,-41.42858 17.14286,-41.42858 21.42857,0 47.14286,1.42857 47.14286,1.42857 L 341.42857,898.57143 300,895.71429 c 0,0 34.28571,-24.28572 118.57143,-32.85715 84.28571,-8.57143 157.14286,-8.57143 192.85714,-31.42857 35.71429,-22.85714 137.14286,-78.57143 137.14286,-78.57143 z"
style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3846"
d="m 282.85714,1000 h 92.85715"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3850"
d="M 555.71429,1000 H 1072.8571"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3852"
d="m 1245.7143,1000 h 151.4286"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="csccc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3884"
d="M 618.57143,847.14286 C 634.28572,828.57143 741.94515,765.61839 770,758.57143 c 29.50156,-7.41035 103.00398,-7.14286 103.00398,-7.14286 l -7.14285,95.71429 z"
style="fill:#f0ffeb;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3888"
d="m 658.57143,817.14286 v 28.57143"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3892"
d="m 898.69729,752.83617 -4.28572,94.32767 h 207.16383 c -11.3076,-20.75266 -46.6124,-74.9056 -72.8572,-88.57143 -14.2857,-10 -82.87805,-4.32767 -130.02091,-5.75624 z"
style="fill:#f0ffeb;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscsc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3896"
d="m 1065.7143,760 c 0,0 80,84.28571 85.7143,87.14286 5.7143,2.85714 115.7143,1.42857 115.7143,1.42857 0,0 -77.1429,-47.14286 -102.8572,-58.57143 -25.7143,-11.42857 -90,-31.42857 -98.5714,-30 z"
style="fill:#f0ffeb;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3900"
d="m 599.63544,837.66076 c -14.07595,30.96709 -18.29873,71.78734 -18.29873,94.30886 0,22.52152 4.22279,91.49368 22.52152,105.56958"
style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3900-6"
d="m 632.78482,993.12906 c -1.40759,5.63038 -4.04683,81.90444 -6.51012,106.93324 -3.67029,18.7146 -4.98821,51.2184 -6.15823,87.3149 0,22.5215 7.03798,80.2329 12.66836,105.5696"
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3920"
d="m 357.52911,998.12658 c 0,0 15.48355,-85.86329 106.97722,-85.86329 91.49367,0 109.7924,87.27089 109.7924,87.27089"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3920-5"
d="m 800.28863,1253.5341 c 0,0 15.48355,-85.8633 106.97722,-85.8633 91.49364,0 109.79245,87.2709 109.79245,87.2709"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3940"
d="M 323.74684,943.23038 H 387.0886"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cssc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3942"
d="m 1033.1747,746.16708 c 18.2988,12.66836 56.3038,50.67343 92.9012,104.16203 36.5975,53.48861 8.4456,59.11899 -18.2987,74.60254 -26.7443,15.48354 -49.2658,42.22784 -67.5645,112.60755"
style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3944"
d="M 1112.7747,1196.0455 H 983.27594"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3946"
d="M 540.51646,941.82278 H 1085.2557"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path3948"
d="m 1062.7342,791.21013 v 54.8962"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
rx="2.9330556"
ry="7.3789682"
y="1144.9166"
x="558.65344"
height="14.541238"
width="41.285542"
id="rect3950"
style="display:inline;fill:#e6e6e6;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
rx="2.9330556"
ry="7.3789682"
y="1144.9166"
x="816.24335"
height="14.541238"
width="41.285542"
id="rect3950-4"
style="display:inline;fill:#e6e6e6;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
ry="7.691968"
rx="1.6302098"
y="1146.318"
x="259.53336"
height="11.738417"
width="18.776392"
id="rect4014"
style="fill:#ffcb00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g4451"
transform="translate(-13.779768,15.524026)">
<path
inkscape:transform-center-x="-1.6185511"
transform="translate(-37.23036,423.94932)"
d="m 99.997791,388.63797 -11.711946,16.12011 -18.950327,-6.15733 0,-19.92556 18.950327,-6.15733 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="true"
sodipodi:arg2="0.62831853"
sodipodi:arg1="0"
sodipodi:r2="13.712585"
sodipodi:r1="16.949688"
sodipodi:cy="388.63797"
sodipodi:cx="83.048103"
sodipodi:sides="5"
id="path4141"
style="fill:none;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:type="star" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4143"
d="m 31.741795,745.02273 315.301265,-111.2"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4145"
d="M 30.3342,888.59742 345.63546,1004.0202"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccssccccc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path4165"
d="m 595.41266,378.78481 140.75949,38.00506 c 0,0 -8.44557,49.22222 -8.44557,71.9633 0,20.14574 0,124.39619 0,147.62151 0,30.96708 8.44557,78.82532 8.44557,78.82532 l -140.7595,33.78228 c 0,0 -17.24303,-61.90221 -17.24303,-92.90127 0.38411,-33.80191 1.75909,-154.79945 2.1114,-185.80253 -1.4076,-30.96709 15.13164,-91.49367 15.13164,-91.49367 z"
style="fill:#f0ffeb;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="csccsc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path4175"
d="m 736.17216,416.78987 c 0,0 94.30885,5.63038 152.02025,5.63038 106.97721,0 201.28609,-5.63038 201.28609,-5.63038 m -1.4076,297.00254 c 0,0 -77.4177,-5.63039 -199.87849,-5.63039 -68.97215,0 -152.02026,7.03798 -152.02026,7.03798"
style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
ry="34.43626"
rx="31.189682"
y="729.20502"
x="528.6228"
height="181.57974"
width="106.97722"
id="rect4177"
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0"
id="path4135-9"
d="M 345.77724,632.78476 H 51.589892 l -14.07595,102.75443 -7.03797,11.26076 v 142.16709 l 7.03797,14.07595 15.48355,101.34681 H 341.55445"
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="csscccssccc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path4203"
d="m 1086.6633,416.78987 c 0,0 -12.6684,47.85823 -12.6684,73.19494 0,25.33671 0,121.05316 0,146.38987 0,25.33671 12.6684,77.41773 12.6684,77.41773 l 205.5089,38.00505 108.3848,10e-6 c 0,0 14.0759,-81.64051 14.0759,-115.42279 0,-33.78227 0,-109.7924 0,-147.79746 0,-38.00507 -14.0759,-109.79241 -14.0759,-109.79241 h -108.3848 z"
style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="csscsccsc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path4205"
d="m 1097.9241,435.08861 c 0,0 -8.4456,40.82025 -8.4456,56.3038 0,15.48354 0,125.27594 0,144.98227 0,19.70633 7.038,57.7114 7.038,57.7114 0,0 94.3088,26.7443 123.8683,26.7443 29.5595,0 42.2279,0 42.2279,0 V 408.3443 c 0,0 -22.5216,0 -47.8583,0 -25.3367,0 -116.8303,26.74431 -116.8303,26.74431 z"
style="fill:#f0ffeb;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path4207"
d="m 1292.1722,378.78481 c 0,0 30.967,40.82025 30.967,111.2 0,70.37975 0,81.64051 0,146.38987 0,64.74937 -30.967,116.83038 -30.967,116.83038"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path4209"
d="m 578.52152,489.98481 32.37468,-32.37468 v -40.82026 112.6076"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path4209-7"
d="m 323.81774,865.03792 32.37468,-32.37468 v -40.82026 112.6076"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path4209-76"
d="m 1005.0937,787.62021 -32.37469,-32.37468 v -40.82026 112.6076"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cssc"
transform="translate(-253.99998,253.99995)"
inkscape:connector-curvature="0"
id="path4243"
d="m 595.41266,378.78481 c 0,0 -42.22785,78.82532 -42.22785,111.2 0,32.37468 0,105.56962 0,146.38987 0,40.82026 42.22785,114.01519 42.22785,114.01519"
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -106.79241,740.91638 1.4076,-91.49367 c 0,0 5.630382,-23.92911 -25.33671,-25.3367 -30.96709,-1.4076 -26.74431,2.81518 -26.74431,2.81518 l 1.40759,415.24051 c 0,0 9.85317,0 28.1519,0 28.151917,0 22.52153,-22.5216 22.52153,-22.5216 l -1e-5,-95.71637 c -12.67694,0 -11.26075,-9.61416 -11.26075,-16.89115 0,-16.94968 -10e-6,-136.5367 -10e-6,-149.20506 0.45035,-18.89009 9.85317,-16.89114 9.85317,-16.89114 z"
id="path4245"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccsccsccccc" />
<path
style="fill:none;stroke:#000000;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -155.98734,646.16195 h 49.26582"
id="path4247"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -155.13671,1020.4303 h 49.26582"
id="path4247-2"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -156.69114,705.05816 h 49.26582"
id="path4247-1"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -153.87595,964.87082 h 49.26582"
id="path4247-0"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M -147.09621,703.82272 V 964.22778"
id="path4281-1"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M -137.24304,705.38727 V 965.79233"
id="path4281-8"
inkscape:connector-curvature="0" />
<g
id="g4428"
transform="translate(-13.779768,15.524026)">
<path
sodipodi:nodetypes="csssscccsssscsccscccsscccssc"
inkscape:connector-curvature="0"
id="path3070-9"
d="m 494.57145,641.6137 c 41.42857,15.71429 140,11.42857 191.42857,12.85714 51.42857,1.42857 160.4745,-10.23062 201.4286,-27.14286 40.9958,-16.92944 134.78428,-67.65586 151.42848,-72.85714 22.8572,-7.14286 41.4286,-7.14286 80,-20 38.5715,-12.85714 25.7143,-32.85714 25.7143,-32.85714 l -30,4.28571 -5.7562,-52.92008 c 0,0 37.1848,-1.36563 41.4705,-15.65135 4.2857,-14.28571 5.7143,-31.42857 -2.8571,-41.42857 -8.5715,-9.99997 -14.2857,1.42857 -18.5715,-12.85717 -4.2857,-14.2857 -2.8571,-28.5714 -27.1428,-27.1428 -24.2857,1.4285 -98.5715,0 -98.5715,0 0,0 -15.71418,108.5714 -98.57138,105.71426 -82.8571,-2.85715 -95.7143,-105.71426 -95.7143,-105.71426 H 308.85716 c 0,0 -5.71428,104.28569 -97.14286,105.71426 -91.42857,1.42857 -98.57142,-105.71426 -98.57142,-105.71426 H 47.428587 l -18.57143,38.5714 c -0.51524,0 -26.243277,10e-6 -21.428567,17.14285 4.65143,16.56149 -4.28571,41.42858 17.14286,41.42858 21.428567,0 47.142857,-1.42857 47.142857,-1.42857 l 15.71428,44.28571 -41.42857,2.85714 c 0,0 34.28571,24.28572 118.571433,32.85715 84.28571,8.57143 157.14286,8.57143 192.85714,31.42857 35.71429,22.85714 137.14286,78.57143 137.14286,78.57143 z"
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3846-2"
d="M 28.857157,394.47084 H 121.71431"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3850-6"
d="M 301.71431,394.47084 H 818.85712"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3852-6"
d="M 991.71432,394.47084 H 1143.1429"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="csccc"
inkscape:connector-curvature="0"
id="path3884-4"
d="m 364.57145,547.32798 c 15.71429,18.57143 123.37372,81.52447 151.42857,88.57143 29.50156,7.41035 103.00398,7.14286 103.00398,7.14286 l -7.14285,-95.71429 z"
style="display:inline;fill:#f0ffeb;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3888-9"
d="M 404.57145,577.32798 V 548.75655"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path3892-5"
d="M 644.69731,641.63467 640.41159,547.307 h 207.16383 c -11.3076,20.75266 -46.6124,74.9056 -72.8572,88.57143 -14.2857,10 -82.87805,4.32767 -130.02091,5.75624 z"
style="display:inline;fill:#f0ffeb;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path3896-0"
d="m 811.71432,634.47084 c 0,0 80,-84.28571 85.7143,-87.14286 5.7143,-2.85714 115.71428,-1.42857 115.71428,-1.42857 0,0 -77.14288,47.14286 -102.85718,58.57143 -25.7143,11.42857 -90,31.42857 -98.5714,30 z"
style="display:inline;fill:#f0ffeb;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path3900-4"
d="m 345.63546,556.81008 c -14.07595,-30.96709 -18.29873,-71.78734 -18.29873,-94.30886 0,-22.52152 4.22279,-91.49368 22.52152,-105.56958"
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path3900-6-8"
d="m 632.78482,655.34173 c -1.40759,-5.63038 -4.04683,-81.90444 -6.51012,-106.93324 -3.67029,-18.7146 -4.98821,-51.2184 -6.15823,-87.3149 0,-22.5215 7.03798,-80.2329 12.66836,-105.5696"
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3920-7"
d="m 103.52913,396.34426 c 0,0 15.48355,85.86329 106.97722,85.86329 91.49367,0 109.7924,-87.27089 109.7924,-87.27089"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3920-5-1"
d="m 800.28863,394.93669 c 0,0 15.48355,85.8633 106.97722,85.8633 91.49364,0 109.79245,-87.2709 109.79245,-87.2709"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3940-7"
d="M 69.746857,451.24046 H 133.08862"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cssc"
inkscape:connector-curvature="0"
id="path3942-2"
d="m 779.17472,648.30376 c 18.2988,-12.66836 56.3038,-50.67343 92.9012,-104.16203 36.5975,-53.48861 8.4456,-59.11899 -18.2987,-74.60254 -26.7443,-15.48354 -49.2658,-42.22784 -67.5645,-112.60755"
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path3944-7"
d="M 1112.7747,452.42529 H 983.27594"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3946-2"
d="M 286.51648,452.64806 H 831.25572"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path3948-2"
d="m 808.73422,603.26071 v -54.8962"
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
transform="scale(1,-1)"
rx="2.9330556"
ry="7.3789682"
y="-503.55417"
x="558.65344"
height="14.541238"
width="41.285542"
id="rect3950-6"
style="display:inline;fill:#e6e6e6;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
transform="scale(1,-1)"
rx="2.9330556"
ry="7.3789682"
y="-503.55417"
x="816.24329"
height="14.541238"
width="41.285542"
id="rect3950-4-1"
style="display:inline;fill:#e6e6e6;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
transform="scale(1,-1)"
ry="7.691968"
rx="1.6302098"
y="-502.1528"
x="259.53333"
height="11.738417"
width="18.776392"
id="rect4014-0"
style="display:inline;fill:#ffcb00;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
transform="translate(941.34179,284.00501)"
id="path4335"
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
cx="59.118988"
cy="211.28101"
r="16.89114" />
</g>
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M -126.57469,704.93158 V 965.33664"
id="path4281-8-0"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffc0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -153.87595,992.4894 v -26.0405 h 22.52152 22.52152 v 26.0405 26.0405 h -22.52152 -22.52152 z"
id="path4361"
inkscape:connector-curvature="0" />
<path
style="fill:#ffffc0;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -153.87595,675.78054 v -27.4481 h 22.52152 22.52152 v 27.4481 27.4481 h -22.52152 -22.52152 z"
id="path4363"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -157.39494,624.37968 c 0,0 -4.22278,-12.66836 -18.29873,-12.66836 -14.07595,0 -14.07595,8.44557 -14.07595,8.44557 v 423.68601 c 0,0 1.40759,9.8532 14.07595,9.8532 12.66835,0 18.29873,-9.8532 18.29873,-9.8532"
id="path4377"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccsc" />
<path
style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -191.17722,624.37967 c 0,0 -35.18987,-1.40759 -35.18987,21.11393 0,22.52152 0,349.08354 0,371.605 0,22.5215 36.59747,25.3367 36.59747,25.3367"
id="path4381"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssc" />
<rect
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4467"
width="16.891144"
height="35.189873"
x="-216.51393"
y="648.30878"
rx="7.7417746"
ry="6.2843671" />
<rect
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4467-6"
width="16.891144"
height="35.189873"
x="-216.51393"
y="985.57465"
rx="7.7417746"
ry="6.2843671" />
<rect
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4487"
width="30.967089"
height="377.23544"
x="-62.939251"
y="645.49365" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1200.9342,633.85815 v 73.19494 h 67.5645 v -83.0481 l -25.3367,-14.07595 z"
id="path4499"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1200.9342,963.23538 h 67.5645 v 78.82532 l -23.9291,14.0759 -43.6354,-18.2988 z"
id="path4501"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 1200.9342,692.97714 V 977.31132"
id="path4503"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 1268.4987,693.56955 V 977.90373"
id="path4505"
inkscape:connector-curvature="0" />
<rect
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4534"
width="14.075921"
height="147.79749"
x="1216.5645"
y="759.50879" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 1224.1949,758.1012 V 704.61259"
id="path4536"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 1224.1949,961.97968 V 908.49107"
id="path4536-0"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 1254.5696,707.42778 V 963.61006"
id="path4556"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1268.757,624.97209 c 0,0 4.2228,-12.66836 18.2987,-12.66836 14.076,0 14.076,8.44557 14.076,8.44557 v 423.686 c 0,0 -1.4076,9.8532 -14.076,9.8532 -12.6683,0 -18.2987,-9.8532 -18.2987,-9.8532"
id="path4377-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csccsc" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1302.5393,624.97208 c 0,0 35.1898,-1.40759 35.1898,21.11393 0,22.52152 0,349.08354 0,371.60499 0,22.5215 -36.5974,25.3367 -36.5974,25.3367"
id="path4381-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssc" />
<rect
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4467-5"
width="16.891144"
height="35.189873"
x="-1329.876"
y="648.90118"
rx="7.7417746"
ry="6.2843671"
transform="scale(-1,1)" />
<rect
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4467-6-5"
width="16.891144"
height="35.189873"
x="-1329.876"
y="986.16711"
rx="7.7417746"
ry="6.2843671"
transform="scale(-1,1)" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1199.6734,632.82525 67.5645,74.60253"
id="path4585"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1199.6734,708.02018 67.5645,-73.19493"
id="path4587"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1199.8962,962.97968 67.5645,74.60252"
id="path4585-9"
inkscape:connector-curvature="0" />
<path
style="display:inline;fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1199.8962,1038.1746 67.5645,-73.19492"
id="path4587-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<circle
style="fill:#c8c8c8;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4610"
transform="translate(78.488602,1074.6683)"
cx="119.64557"
cy="202.83545"
r="76.010124" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4612"
transform="translate(94.675942,1204.8708)"
cx="103.45823"
cy="72.632912"
r="44.339241" />
<circle
style="fill:#c8c8c8;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4610-9"
transform="translate(78.488602,187.66068)"
cx="119.64557"
cy="202.83545"
r="76.010124" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4612-4"
transform="translate(94.675942,317.86322)"
cx="103.45823"
cy="72.632912"
r="44.339241" />
<circle
style="fill:#c8c8c8;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4610-5"
transform="translate(773.02535,187.66068)"
cx="119.64557"
cy="202.83545"
r="76.010124" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4612-1"
transform="translate(789.21269,317.86322)"
cx="103.45823"
cy="72.632912"
r="44.339241" />
<circle
style="fill:#c8c8c8;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4610-4"
transform="translate(773.02535,1074.6683)"
cx="119.64557"
cy="202.83545"
r="76.010124" />
<circle
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4612-3"
transform="translate(789.21269,1204.8708)"
cx="103.45823"
cy="72.632912"
r="44.339241" />
<path
style="fill:none;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1338.5088,829.07334 h 40.8203"
id="path3083"
inkscape:connector-curvature="0" />
<circle
style="fill:#3c3c3c;fill-opacity:1;stroke:#000000;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path3853"
transform="translate(1441.2633,600.30879)"
cx="-59.118988"
cy="229.57974"
r="4.222785" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 778.06325,845.37208 -38.7088,-38.70886"
id="path3855"
inkscape:connector-curvature="0" />
<g
id="g3952"
transform="translate(-13.779768,15.524026)">
<circle
transform="translate(-79.458203,449.80248)"
id="path3857"
style="fill:#3c3c3c;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
cx="-81.640511"
cy="188.75949"
r="4.222785" />
<circle
transform="translate(-79.458203,569.9172)"
id="path3857-2"
style="display:inline;fill:#3c3c3c;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
cx="-81.640511"
cy="188.75949"
r="4.222785" />
<circle
transform="translate(-79.458203,690.03203)"
id="path3857-3"
style="display:inline;fill:#3c3c3c;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
cx="-81.640511"
cy="188.75949"
r="4.222785" />
<circle
transform="translate(-79.458203,810.14679)"
id="path3857-7"
style="display:inline;fill:#3c3c3c;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
cx="-81.640511"
cy="188.75949"
r="4.222785" />
</g>
<g
id="g3946"
transform="translate(-13.779768,17.524026)">
<circle
transform="translate(1381.6254,448.24805)"
id="path3857-97"
style="display:inline;fill:#3c3c3c;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
cx="-81.640511"
cy="188.75949"
r="4.222785" />
<circle
transform="translate(1381.6254,568.36277)"
id="path3857-2-3"
style="display:inline;fill:#3c3c3c;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
cx="-81.640511"
cy="188.75949"
r="4.222785" />
<circle
transform="translate(1381.6254,688.4776)"
id="path3857-3-6"
style="display:inline;fill:#3c3c3c;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
cx="-81.640511"
cy="188.75949"
r="4.222785" />
<circle
transform="translate(1381.6254,808.59236)"
id="path3857-7-1"
style="display:inline;fill:#3c3c3c;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
cx="-81.640511"
cy="188.75949"
r="4.222785" />
</g>
</g>
<g
inkscape:groupmode="layer"
id="primary"
inkscape:label="primary">
<circle
style="fill:#a02c2c"
id="01"
cx="320.93164"
cy="-388.63797"
r="66.15696"
transform="scale(1,-1)"
inkscape:label="01" />
<circle
style="fill:#a02c2c"
id="02"
cx="320.93164"
cy="-757.42786"
r="66.15696"
transform="scale(1,-1)"
inkscape:label="01" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 43 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,144 @@
<svg id="svg166" version="1.1" viewBox="0 0 1668 1160" xmlns="http://www.w3.org/2000/svg">
<g id="g158" transform="translate(254 -254)">
<g id="g34" transform="translate(-13.78 3.524)" stroke="#000">
<path id="path10" d="m494.57 1006.9c41.429-15.714 140-11.427 191.43-12.857 51.429-1.429 160.48 10.23 201.43 27.143 40.995 16.93 134.78 67.656 151.43 72.857 22.857 7.143 41.429 7.143 80 20 38.572 12.857 25.714 32.857 25.714 32.857l-30-4.286-5.756 52.92s37.185 1.366 41.47 15.652c4.286 14.286 5.715 31.428-2.856 41.428-8.572 10-14.286-1.428-18.572 12.858-4.286 14.285-2.857 28.571-27.143 27.142-24.285-1.428-98.571 0-98.571 0s-15.714-108.57-98.573-105.71c-82.857 2.857-95.714 105.71-95.714 105.71h-500s-5.714-104.28-97.143-105.71c-91.428-1.428-98.571 105.71-98.571 105.71h-65.713l-18.572-38.571c-0.515 0-26.243 0-21.428-17.143 4.651-16.561-4.286-41.428 17.142-41.428 21.429 0 47.143 1.428 47.143 1.428l15.715-44.286-41.429-2.857s34.286-24.285 118.57-32.857c84.286-8.571 157.14-8.571 192.86-31.428 35.714-22.858 137.14-78.572 137.14-78.572z" fill="none" stroke-width="5"/>
<path id="path12" d="m28.857 1254h92.857m180 0h517.14m172.86 0h151.43" fill="none" stroke-width="2"/>
<path id="path14" d="m364.57 1101.1c15.715-18.572 123.37-81.525 151.43-88.572 29.502-7.41 103-7.142 103-7.142l-7.143 95.714z" fill="#f0ffeb" stroke-width="5"/>
<path id="path16" d="m404.57 1071.1v28.571" fill="none" stroke-width="2"/>
<path id="path18" d="m644.7 1006.8-4.285 94.328h207.16c-11.307-20.753-46.612-74.906-72.857-88.572-14.285-10-82.878-4.327-130.02-5.756zm167.02 7.164s80 84.286 85.715 87.143c5.714 2.857 115.71 1.428 115.71 1.428s-77.143-47.141-102.86-58.571c-25.715-11.429-90-31.429-98.572-30z" fill="#f0ffeb" stroke-width="5"/>
<g fill="none">
<path id="path20" d="m345.64 1091.7c-14.075 30.968-18.298 71.788-18.298 94.31 0 22.521 4.223 91.493 22.521 105.57m282.93-298.41c-1.408 5.63-4.047 81.903-6.51 106.93-3.67 18.715-4.989 51.219-6.159 87.315 0 22.522 7.038 80.233 12.669 105.57" stroke-width="5"/>
<path id="path22" d="m103.53 1252.1s15.483-85.864 106.98-85.864c91.494 0 109.79 87.271 109.79 87.271m479.99 0s15.483-85.863 106.98-85.863c91.493 0 109.79 87.27 109.79 87.27m-947.31-57.711h63.342" stroke-width="2"/>
<path id="path24" d="m779.18 1000.2c18.299 12.668 56.304 50.673 92.9 104.16 36.598 53.489 8.447 59.12-18.298 74.603-26.744 15.483-49.266 42.227-67.564 112.61" stroke-width="5"/>
<path id="path26" d="m1112.8 1196h-129.5m-696.76-0.222h544.74m-22.522-150.61v54.896" stroke-width="2"/>
</g>
<g stroke-width="2">
<rect id="rect28" x="558.65" y="1144.9" width="41.286" height="14.541" rx="2.933" ry="7.379" fill="#e6e6e6"/>
<rect id="rect30" x="816.24" y="1144.9" width="41.286" height="14.541" rx="2.933" ry="7.379" fill="#e6e6e6"/>
<rect id="rect32" x="259.53" y="1146.3" width="18.776" height="11.738" rx="1.63" ry="7.692" fill="#ffcb00"/>
</g>
</g>
<g id="g54" transform="translate(-13.78 15.524)" stroke="#000">
<path id="path36" d="m62.767 812.59-11.712 16.12-18.95-6.157v-19.925l18.95-6.158z" fill="none" stroke-width="5"/>
<path id="path38" d="m31.742 745.02 315.3-111.2m-316.71 254.77 315.3 115.42" fill="none" stroke-width="2"/>
<path id="path40" d="m341.41 632.78 140.76 38.005s-8.446 49.222-8.446 71.963v147.62c0 30.967 8.445 78.825 8.445 78.825l-140.76 33.782s-17.242-61.902-17.242-92.901l2.111-185.8c-1.408-30.967 15.132-91.493 15.132-91.493z" fill="#f0ffeb" stroke-width="5"/>
<g fill="none">
<path id="path42" d="m482.17 670.79s94.309 5.63 152.02 5.63c106.98 0 201.29-5.63 201.29-5.63m-1.408 297s-77.418-5.63-199.88-5.63c-68.972 0-152.02 7.038-152.02 7.038" stroke-width="5"/>
<rect id="rect44" x="528.62" y="729.2" width="106.98" height="181.58" rx="31.19" ry="34.436" stroke-width="2"/>
<path id="path46" d="m345.78 632.78h-294.19l-14.076 102.75-7.038 11.26v142.17l7.038 14.076 15.483 101.35h288.56m491.11-333.6s-12.668 47.858-12.668 73.195v146.39c0 25.336 12.668 77.417 12.668 77.417l205.51 38.005h108.38s14.076-81.64 14.076-115.42v-147.8c0-38.005-14.076-109.79-14.076-109.79h-108.38z" stroke-width="5"/>
</g>
<path id="path48" d="m843.92 689.09s-8.445 40.82-8.445 56.303v144.98c0 19.706 7.038 57.711 7.038 57.711s94.308 26.744 123.87 26.744h42.228v-312.49h-47.859c-25.336 0-116.83 26.745-116.83 26.745z" fill="#f0ffeb" stroke-width="5"/>
<path id="path50" d="m1038.2 632.78s30.967 40.82 30.967 111.2v146.39c0 64.749-30.967 116.83-30.967 116.83m-713.65-263.22 32.374-32.375v-40.82 112.61m-33.078 81.641 32.374-32.375v-40.82 112.61m648.9-116.83-32.375-32.374v-40.82 112.61" fill="none" stroke-width="2"/>
<path id="path52" d="m341.41 632.78s-42.228 78.825-42.228 111.2v146.39c0 40.82 42.228 114.02 42.228 114.02" fill="none" stroke-width="2"/>
</g>
<g fill="none" stroke="#000">
<path id="path56" d="m-106.79 740.92 1.407-91.493s5.63-23.93-25.337-25.337c-30.967-1.408-26.744 2.815-26.744 2.815l1.408 415.24h28.152c28.152 0 22.521-22.52 22.521-22.52v-95.717c-12.677 0-11.26-9.614-11.26-16.891v-149.2c0.45-18.89 9.853-16.892 9.853-16.892z" stroke-width="5"/>
<path id="path58" d="m-155.99 646.16h49.265m-48.415 374.27h49.266m-50.82-315.37h49.266m-46.451 259.81h49.266" stroke-width="2.2"/>
<path id="path60" d="m-147.1 703.82v260.4m9.853-258.84v260.4" stroke-width="2"/>
</g>
<g id="g88" transform="translate(-13.78 15.524)" stroke="#000">
<path id="path62" d="m494.57 641.61c41.429 15.714 140 11.428 191.43 12.856s160.48-10.23 201.43-27.143c40.995-16.93 134.78-67.656 151.43-72.857 22.857-7.143 41.429-7.143 80-20 38.572-12.857 25.714-32.857 25.714-32.857l-30 4.285-5.756-52.92s37.185-1.365 41.47-15.651c4.286-14.286 5.715-31.429-2.856-41.429-8.572-10-14.286 1.429-18.572-12.857-4.286-14.285-2.857-28.571-27.143-27.143-24.285 1.429-98.571 0-98.571 0s-15.714 108.57-98.572 105.72c-82.857-2.857-95.714-105.72-95.714-105.72h-500s-5.714 104.29-97.143 105.72c-91.428 1.428-98.571-105.72-98.571-105.72h-65.714l-18.572 38.572c-0.515 0-26.243 0-21.428 17.143 4.651 16.561-4.286 41.428 17.142 41.428 21.429 0 47.143-1.428 47.143-1.428l15.715 44.285-41.429 2.859s34.286 24.285 118.57 32.857c84.286 8.571 157.14 8.571 192.86 31.428 35.714 22.857 137.14 78.572 137.14 78.572z" fill="none" stroke-width="5"/>
<path id="path64" d="m28.857 394.47h92.857m180 0h517.14m172.86 0h151.43" fill="none" stroke-width="2"/>
<path id="path66" d="m364.57 547.33c15.715 18.571 123.37 81.524 151.43 88.571 29.502 7.41 103 7.143 103 7.143l-7.143-95.714z" fill="#f0ffeb" stroke-width="5"/>
<path id="path68" d="m404.57 577.33v-28.571" fill="none" stroke-width="2"/>
<path id="path70" d="m644.7 641.64-4.285-94.328h207.16c-11.307 20.753-46.612 74.906-72.857 88.571-14.285 10-82.878 4.328-130.02 5.757zm167.02-7.165s80-84.285 85.715-87.142c5.714-2.857 115.71-1.429 115.71-1.429s-77.143 47.143-102.86 58.572c-25.715 11.428-90 31.428-98.572 30z" fill="#f0ffeb" stroke-width="5"/>
<g fill="none">
<path id="path72" d="m345.64 556.81c-14.075-30.967-18.298-71.787-18.298-94.309 0-22.521 4.223-91.493 22.521-105.57m282.93 298.41c-1.408-5.63-4.047-81.905-6.51-106.93-3.67-18.714-4.989-51.218-6.159-87.314 0-22.522 7.038-80.233 12.669-105.57" stroke-width="5"/>
<path id="path74" d="m103.53 396.34s15.483 85.864 106.98 85.864c91.494 0 109.79-87.271 109.79-87.271m479.99 0s15.483 85.863 106.98 85.863c91.493 0 109.79-87.27 109.79-87.27m-947.31 57.71h63.342" stroke-width="2"/>
<path id="path76" d="m779.18 648.3c18.299-12.669 56.304-50.674 92.9-104.16 36.598-53.489 8.447-59.12-18.298-74.603-26.744-15.483-49.266-42.228-67.564-112.61" stroke-width="5"/>
<path id="path78" d="m1112.8 452.42h-129.5m-696.76 0.223h544.74m-22.522 150.61v-54.895" stroke-width="2"/>
</g>
<g stroke-width="2">
<rect id="rect80" transform="scale(1 -1)" x="558.65" y="-503.55" width="41.286" height="14.541" rx="2.933" ry="7.379" fill="#e6e6e6"/>
<rect id="rect82" transform="scale(1 -1)" x="816.24" y="-503.55" width="41.286" height="14.541" rx="2.933" ry="7.379" fill="#e6e6e6"/>
<rect id="rect84" transform="scale(1 -1)" x="259.53" y="-502.15" width="18.776" height="11.738" rx="1.63" ry="7.692" fill="#ffcb00"/>
<circle id="circle86" transform="translate(941.34 284)" cx="59.119" cy="211.28" r="16.891" fill="#fff"/>
</g>
</g>
<path id="path90" d="m-126.58 704.93v260.4" fill="none" stroke="#000" stroke-width="2"/>
<path id="path92" d="m-153.88 992.49v-26.041h45.043v52.08h-45.043zm0-316.71v-27.448h45.043v54.898h-45.043z" fill="#ffffc0"/>
<g fill="none" stroke="#000">
<path id="path94" d="m-157.4 624.38s-4.223-12.669-18.299-12.669-14.076 8.446-14.076 8.446v423.69s1.408 9.853 14.076 9.853c12.669 0 18.3-9.853 18.3-9.853" stroke-width="5"/>
<path id="path96" d="m-191.18 624.38s-35.19-1.408-35.19 21.114v371.6c0 22.521 36.597 25.336 36.597 25.336" stroke-width="5"/>
<g stroke-width="2">
<rect id="rect98" x="-216.51" y="648.31" width="16.891" height="35.19" rx="7.742" ry="6.284"/>
<rect id="rect100" x="-216.51" y="985.58" width="16.891" height="35.19" rx="7.742" ry="6.284"/>
<path id="path102" d="m-62.939 645.49h30.967v377.24h-30.967z"/>
</g>
<path id="path104" d="m1200.9 633.86v73.195h67.565v-83.048l-25.337-14.076zm0 329.38h67.565v78.826l-23.93 14.076-43.635-18.3zm0-270.26v284.33m67.565-283.74v284.33" stroke-width="5"/>
<path id="path106" d="m1216.6 759.51h14.076v147.8h-14.076zm7.631-1.408v-53.488m0 257.37v-53.49m30.375-201.06v256.18" stroke-width="2"/>
<path id="path108" d="m1268.8 624.97s4.223-12.668 18.299-12.668 14.076 8.445 14.076 8.445v423.69s-1.408 9.853-14.076 9.853c-12.669 0-18.299-9.853-18.299-9.853m33.783-419.46s35.19-1.408 35.19 21.114v371.6c0 22.521-36.598 25.337-36.598 25.337" stroke-width="5"/>
<g stroke-width="2">
<rect id="rect110" transform="scale(-1 1)" x="-1329.9" y="648.9" width="16.891" height="35.19" rx="7.742" ry="6.284"/>
<rect id="rect112" transform="scale(-1 1)" x="-1329.9" y="986.17" width="16.891" height="35.19" rx="7.742" ry="6.284"/>
<path id="path114" d="m1199.7 632.82 67.565 74.603m-67.565 0.592 67.565-73.195m-67.342 328.16 67.565 74.602m-67.565 0.593 67.565-73.195"/>
</g>
</g>
<g stroke="#000">
<g stroke-width="2">
<circle id="circle116" transform="translate(78.489 1074.7)" cx="119.65" cy="202.84" r="76.01" fill="#c8c8c8"/>
<circle id="circle118" transform="translate(94.676 1204.9)" cx="103.46" cy="72.633" r="44.339" fill="#fff"/>
<circle id="circle120" transform="translate(78.489 187.66)" cx="119.65" cy="202.84" r="76.01" fill="#c8c8c8"/>
<circle id="circle122" transform="translate(94.676 317.86)" cx="103.46" cy="72.633" r="44.339" fill="#fff"/>
<circle id="circle124" transform="translate(773.02 187.66)" cx="119.65" cy="202.84" r="76.01" fill="#c8c8c8"/>
<circle id="circle126" transform="translate(789.21 317.86)" cx="103.46" cy="72.633" r="44.339" fill="#fff"/>
<circle id="circle128" transform="translate(773.02 1074.7)" cx="119.65" cy="202.84" r="76.01" fill="#c8c8c8"/>
<circle id="circle130" transform="translate(789.21 1204.9)" cx="103.46" cy="72.633" r="44.339" fill="#fff"/>
</g>
<path id="path132" d="m1338.5 829.07h40.82" fill="none" stroke-width="5"/>
<circle id="circle134" transform="translate(1441.3 600.31)" cx="-59.119" cy="229.58" r="4.223" fill="#3c3c3c" stroke-width="5"/>
<g stroke-width="2">
<path id="path136" d="m778.06 845.37-38.709-38.709" fill="none"/>
<g id="g146" transform="translate(-13.78 15.524)" fill="#3c3c3c">
<circle id="circle138" transform="translate(-79.458 449.8)" cx="-81.641" cy="188.76" r="4.223"/>
<circle id="circle140" transform="translate(-79.458 569.92)" cx="-81.641" cy="188.76" r="4.223"/>
<circle id="circle142" transform="translate(-79.458 690.03)" cx="-81.641" cy="188.76" r="4.223"/>
<circle id="circle144" transform="translate(-79.458 810.15)" cx="-81.641" cy="188.76" r="4.223"/>
</g>
<g id="g156" transform="translate(-13.78 17.524)" fill="#3c3c3c">
<circle id="circle148" transform="translate(1381.6 448.25)" cx="-81.641" cy="188.76" r="4.223"/>
<circle id="circle150" transform="translate(1381.6 568.36)" cx="-81.641" cy="188.76" r="4.223"/>
<circle id="circle152" transform="translate(1381.6 688.48)" cx="-81.641" cy="188.76" r="4.223"/>
<circle id="circle154" transform="translate(1381.6 808.59)" cx="-81.641" cy="188.76" r="4.223"/>
</g>
</g>
</g>
</g>
<g id="layer2" fill="#d00000">
<circle id="p02" cx="503.65" cy="248.75" r="61.935" />
<circle id="p03" cx="863.41" cy="248.75" r="61.935"/>
<circle id="p04" cx="1181.5" cy="248.75" r="61.935"/>
<circle id="p05" cx="1378.4" cy="151.16" r="61.935"/>
<circle id="p06" cx="1535.1" cy="581.37" r="61.935"/>
<circle id="p07" cx="1378.4" cy="997.9" r="61.935"/>
<circle id="p08" cx="1181.5" cy="914.24" r="61.935"/>
<circle id="p09" transform="scale(1,-1)" cx="863.41" cy="-914.24" r="61.935"/>
<circle id="p10" cx="503.65" cy="914.24" r="61.935"/>
<circle id="p11" cx="297.77" cy="997.9" r="61.935"/>
<circle id="p12" cx="93.269" cy="581.37" r="61.935"/>
<circle id="p25" cx="424.31" cy="581.37" r="61.935"/>
<circle id="p27" cx="972.84" cy="581.37" r="61.935"/>
<circle id="p01" cx="297.77" cy="151.16" r="61.935"/>
<circle id="p26" cx="1339.4" cy="581.37" r="61.935"/>
</g>
<g id="g4994" fill="#ffef00">
<circle id="s02" cx="503.65" cy="248.75" r="61.935"/>
<circle id="s03" cx="863.41" cy="248.75" r="61.935"/>
<circle id="s04" cx="1181.5" cy="248.75" r="61.935"/>
<circle id="s05" cx="1378.4" cy="151.16" r="61.935"/>
<circle id="s06" cx="1535.1" cy="581.37" r="61.935"/>
<circle id="s07" cx="1378.4" cy="997.9" r="61.935"/>
<circle id="s08" cx="1181.5" cy="914.24" r="61.935"/>
<circle id="s09" transform="scale(1,-1)" cx="863.41" cy="-914.24" r="61.935"/>
<circle id="s10" cx="503.65" cy="914.24" r="61.935"/>
<circle id="s11" cx="297.77" cy="997.9" r="61.935"/>
<circle id="s12" cx="93.269" cy="581.37" r="61.935"/>
<circle id="s25" cx="424.31" cy="581.37" r="61.935"/>
<circle id="s27" cx="972.84" cy="581.37" r="61.935"/>
<circle id="s01" cx="297.77" cy="151.16" r="61.935"/>
<circle id="s26" cx="1339.4" cy="581.37" r="61.935"/>
</g>
<g id="layer3">
<text id="p15" opacity="0" x="382.62802" y="1034.3463" fill="#fd0000" font-family="sans-serif" font-size="1696.9px" letter-spacing="0px" stroke-width="17.676" word-spacing="0px" style="line-height:5.25" xml:space="preserve"><tspan id="tspan4997" x="382.62802" y="1034.3463" fill="#fd0000" stroke-width="17.676">x</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,76 @@
import { Select, Button, Popover, InputNumber } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
export default connect(
mapStateToProps,
null
)(function AllocationsAssignmentComponent({
bodyshop,
handleAssignment,
assignment,
setAssignment,
visibilityState,
maxHours
}) {
const { t } = useTranslation();
const onChange = e => {
console.log("e", e);
setAssignment({ ...assignment, employeeid: e });
};
const [visibility, setVisibility] = visibilityState;
const popContent = (
<div>
<Select
showSearch
style={{ width: 200 }}
placeholder="Select a person"
optionFilterProp="children"
onChange={onChange}
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
{bodyshop.employees.map(emp => (
<Select.Option value={emp.id} key={emp.id}>
{`${emp.first_name} ${emp.last_name}`}
</Select.Option>
))}
</Select>
<InputNumber
defaultValue={assignment.hours}
placeholder={t("joblines.fields.mod_lb_hrs")}
max={parseFloat(maxHours)}
min={0}
onChange={e => setAssignment({ ...assignment, hours: e })}
/>
<Button
type="primary"
disabled={!assignment.employeeid}
onClick={handleAssignment}
>
Assign
</Button>
<Button onClick={() => setVisibility(false)}>Close</Button>
</div>
);
return (
<Popover content={popContent} visible={visibility}>
<Button onClick={() => setVisibility(true)}>
{t("allocations.actions.assign")}
</Button>
</Popover>
);
});

View File

@@ -0,0 +1,38 @@
import React, { useState } from "react";
import AllocationsAssignmentComponent from "./allocations-assignment.component";
import { useMutation } from "react-apollo";
import { INSERT_ALLOCATION } from "../../graphql/allocations.queries";
import { useTranslation } from "react-i18next";
import { notification } from "antd";
export default function AllocationsAssignmentContainer({ jobLineId, hours }) {
const visibilityState = useState(false);
const { t } = useTranslation();
const [assignment, setAssignment] = useState({
joblineid: jobLineId,
hours: parseFloat(hours),
employeeid: null
});
const [insertAllocation] = useMutation(INSERT_ALLOCATION);
const handleAssignment = () => {
insertAllocation({ variables: { alloc: { ...assignment } } }).then(r => {
notification["success"]({
message: t("employees.successes.save")
});
//TODO: Better way to reset the field decorators?
visibilityState[1](false);
//refetch().then(r => form.resetFields());
});
};
return (
<AllocationsAssignmentComponent
handleAssignment={handleAssignment}
maxHours={hours}
assignment={assignment}
setAssignment={setAssignment}
visibilityState={visibilityState}
/>
);
}

View File

@@ -0,0 +1,22 @@
import { Tag, Popover } from "antd";
import React from "react";
import Barcode from "react-barcode";
import { useTranslation } from "react-i18next";
export default function BarcodePopupComponent({ value }) {
const { t } = useTranslation();
return (
<div>
<Popover
content={
<Barcode
value={value}
background="transparent"
displayValue={false}
/>
}
>
<Tag>{t("general.labels.barcode")}</Tag>
</Popover>
</div>
);
}

View File

@@ -1,5 +1,10 @@
import React from "react";
import { Drawer } from "antd";
export default function ChatWindowComponent({ ...drawerProps }) {
return <Drawer {...drawerProps}>Chat Windows and more</Drawer>;
export default function ChatWindowComponent({ toggleChatVisible }) {
return (
<div style={{ height: "300px" }}>
<button onClick={() => toggleChatVisible()}>hide</button> This is a chat
window!
</div>
);
}

View File

@@ -1,4 +1,3 @@
import { Layout } from "antd";
import React from "react";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
@@ -18,17 +17,8 @@ export default connect(
mapStateToProps,
mapDispatchToProps
)(function ChatWindowContainer({ chatVisible, toggleChatVisible }) {
return (
<Layout.Sider
collapsible
defaultCollapsed
theme="light"
collapsedWidth={0}
width={300}
collapsed={!chatVisible}
onCollapse={(collapsed, type) => toggleChatVisible()}
>
<ChatWindowComponent mask={false} maskClosable={false} zIndex={0} />
</Layout.Sider>
);
if (chatVisible)
return <ChatWindowComponent toggleChatVisible={toggleChatVisible} />;
return <div onClick={() => toggleChatVisible()}>Chat</div>;
});

View File

@@ -72,6 +72,12 @@ export default ({
</Menu.Item>
</Menu.SubMenu>
<Menu.Item key="shop">
<Link to="/manage/shop">
{t("menus.header.shop")}
</Link>
</Menu.Item>
<Menu.SubMenu
title={
<div>

View File

@@ -0,0 +1,735 @@
import React from "react";
export default ({ dmg1, dmg2 }) => (
<svg
id='svg166'
version='1.1'
viewBox='0 0 1668 1160'
xmlns='http://www.w3.org/2000/svg'>
<g id='g158' transform='translate(254 -254)'>
<g id='g34' transform='translate(-13.78 3.524)' stroke='#000'>
<path
id='path10'
d='m494.57 1006.9c41.429-15.714 140-11.427 191.43-12.857 51.429-1.429 160.48 10.23 201.43 27.143 40.995 16.93 134.78 67.656 151.43 72.857 22.857 7.143 41.429 7.143 80 20 38.572 12.857 25.714 32.857 25.714 32.857l-30-4.286-5.756 52.92s37.185 1.366 41.47 15.652c4.286 14.286 5.715 31.428-2.856 41.428-8.572 10-14.286-1.428-18.572 12.858-4.286 14.285-2.857 28.571-27.143 27.142-24.285-1.428-98.571 0-98.571 0s-15.714-108.57-98.573-105.71c-82.857 2.857-95.714 105.71-95.714 105.71h-500s-5.714-104.28-97.143-105.71c-91.428-1.428-98.571 105.71-98.571 105.71h-65.713l-18.572-38.571c-0.515 0-26.243 0-21.428-17.143 4.651-16.561-4.286-41.428 17.142-41.428 21.429 0 47.143 1.428 47.143 1.428l15.715-44.286-41.429-2.857s34.286-24.285 118.57-32.857c84.286-8.571 157.14-8.571 192.86-31.428 35.714-22.858 137.14-78.572 137.14-78.572z'
fill='none'
strokeWidth='5'
/>
<path
id='path12'
d='m28.857 1254h92.857m180 0h517.14m172.86 0h151.43'
fill='none'
strokeWidth='2'
/>
<path
id='path14'
d='m364.57 1101.1c15.715-18.572 123.37-81.525 151.43-88.572 29.502-7.41 103-7.142 103-7.142l-7.143 95.714z'
fill='#f0ffeb'
strokeWidth='5'
/>
<path
id='path16'
d='m404.57 1071.1v28.571'
fill='none'
strokeWidth='2'
/>
<path
id='path18'
d='m644.7 1006.8-4.285 94.328h207.16c-11.307-20.753-46.612-74.906-72.857-88.572-14.285-10-82.878-4.327-130.02-5.756zm167.02 7.164s80 84.286 85.715 87.143c5.714 2.857 115.71 1.428 115.71 1.428s-77.143-47.141-102.86-58.571c-25.715-11.429-90-31.429-98.572-30z'
fill='#f0ffeb'
strokeWidth='5'
/>
<g fill='none'>
<path
id='path20'
d='m345.64 1091.7c-14.075 30.968-18.298 71.788-18.298 94.31 0 22.521 4.223 91.493 22.521 105.57m282.93-298.41c-1.408 5.63-4.047 81.903-6.51 106.93-3.67 18.715-4.989 51.219-6.159 87.315 0 22.522 7.038 80.233 12.669 105.57'
strokeWidth='5'
/>
<path
id='path22'
d='m103.53 1252.1s15.483-85.864 106.98-85.864c91.494 0 109.79 87.271 109.79 87.271m479.99 0s15.483-85.863 106.98-85.863c91.493 0 109.79 87.27 109.79 87.27m-947.31-57.711h63.342'
strokeWidth='2'
/>
<path
id='path24'
d='m779.18 1000.2c18.299 12.668 56.304 50.673 92.9 104.16 36.598 53.489 8.447 59.12-18.298 74.603-26.744 15.483-49.266 42.227-67.564 112.61'
strokeWidth='5'
/>
<path
id='path26'
d='m1112.8 1196h-129.5m-696.76-0.222h544.74m-22.522-150.61v54.896'
strokeWidth='2'
/>
</g>
<g strokeWidth='2'>
<rect
id='rect28'
x='558.65'
y='1144.9'
width='41.286'
height='14.541'
rx='2.933'
ry='7.379'
fill='#e6e6e6'
/>
<rect
id='rect30'
x='816.24'
y='1144.9'
width='41.286'
height='14.541'
rx='2.933'
ry='7.379'
fill='#e6e6e6'
/>
<rect
id='rect32'
x='259.53'
y='1146.3'
width='18.776'
height='11.738'
rx='1.63'
ry='7.692'
fill='#ffcb00'
/>
</g>
</g>
<g id='g54' transform='translate(-13.78 15.524)' stroke='#000'>
<path
id='path36'
d='m62.767 812.59-11.712 16.12-18.95-6.157v-19.925l18.95-6.158z'
fill='none'
strokeWidth='5'
/>
<path
id='path38'
d='m31.742 745.02 315.3-111.2m-316.71 254.77 315.3 115.42'
fill='none'
strokeWidth='2'
/>
<path
id='path40'
d='m341.41 632.78 140.76 38.005s-8.446 49.222-8.446 71.963v147.62c0 30.967 8.445 78.825 8.445 78.825l-140.76 33.782s-17.242-61.902-17.242-92.901l2.111-185.8c-1.408-30.967 15.132-91.493 15.132-91.493z'
fill='#f0ffeb'
strokeWidth='5'
/>
<g fill='none'>
<path
id='path42'
d='m482.17 670.79s94.309 5.63 152.02 5.63c106.98 0 201.29-5.63 201.29-5.63m-1.408 297s-77.418-5.63-199.88-5.63c-68.972 0-152.02 7.038-152.02 7.038'
strokeWidth='5'
/>
<rect
id='rect44'
x='528.62'
y='729.2'
width='106.98'
height='181.58'
rx='31.19'
ry='34.436'
strokeWidth='2'
/>
<path
id='path46'
d='m345.78 632.78h-294.19l-14.076 102.75-7.038 11.26v142.17l7.038 14.076 15.483 101.35h288.56m491.11-333.6s-12.668 47.858-12.668 73.195v146.39c0 25.336 12.668 77.417 12.668 77.417l205.51 38.005h108.38s14.076-81.64 14.076-115.42v-147.8c0-38.005-14.076-109.79-14.076-109.79h-108.38z'
strokeWidth='5'
/>
</g>
<path
id='path48'
d='m843.92 689.09s-8.445 40.82-8.445 56.303v144.98c0 19.706 7.038 57.711 7.038 57.711s94.308 26.744 123.87 26.744h42.228v-312.49h-47.859c-25.336 0-116.83 26.745-116.83 26.745z'
fill='#f0ffeb'
strokeWidth='5'
/>
<path
id='path50'
d='m1038.2 632.78s30.967 40.82 30.967 111.2v146.39c0 64.749-30.967 116.83-30.967 116.83m-713.65-263.22 32.374-32.375v-40.82 112.61m-33.078 81.641 32.374-32.375v-40.82 112.61m648.9-116.83-32.375-32.374v-40.82 112.61'
fill='none'
strokeWidth='2'
/>
<path
id='path52'
d='m341.41 632.78s-42.228 78.825-42.228 111.2v146.39c0 40.82 42.228 114.02 42.228 114.02'
fill='none'
strokeWidth='2'
/>
</g>
<g fill='none' stroke='#000'>
<path
id='path56'
d='m-106.79 740.92 1.407-91.493s5.63-23.93-25.337-25.337c-30.967-1.408-26.744 2.815-26.744 2.815l1.408 415.24h28.152c28.152 0 22.521-22.52 22.521-22.52v-95.717c-12.677 0-11.26-9.614-11.26-16.891v-149.2c0.45-18.89 9.853-16.892 9.853-16.892z'
strokeWidth='5'
/>
<path
id='path58'
d='m-155.99 646.16h49.265m-48.415 374.27h49.266m-50.82-315.37h49.266m-46.451 259.81h49.266'
strokeWidth='2.2'
/>
<path
id='path60'
d='m-147.1 703.82v260.4m9.853-258.84v260.4'
strokeWidth='2'
/>
</g>
<g id='g88' transform='translate(-13.78 15.524)' stroke='#000'>
<path
id='path62'
d='m494.57 641.61c41.429 15.714 140 11.428 191.43 12.856s160.48-10.23 201.43-27.143c40.995-16.93 134.78-67.656 151.43-72.857 22.857-7.143 41.429-7.143 80-20 38.572-12.857 25.714-32.857 25.714-32.857l-30 4.285-5.756-52.92s37.185-1.365 41.47-15.651c4.286-14.286 5.715-31.429-2.856-41.429-8.572-10-14.286 1.429-18.572-12.857-4.286-14.285-2.857-28.571-27.143-27.143-24.285 1.429-98.571 0-98.571 0s-15.714 108.57-98.572 105.72c-82.857-2.857-95.714-105.72-95.714-105.72h-500s-5.714 104.29-97.143 105.72c-91.428 1.428-98.571-105.72-98.571-105.72h-65.714l-18.572 38.572c-0.515 0-26.243 0-21.428 17.143 4.651 16.561-4.286 41.428 17.142 41.428 21.429 0 47.143-1.428 47.143-1.428l15.715 44.285-41.429 2.859s34.286 24.285 118.57 32.857c84.286 8.571 157.14 8.571 192.86 31.428 35.714 22.857 137.14 78.572 137.14 78.572z'
fill='none'
strokeWidth='5'
/>
<path
id='path64'
d='m28.857 394.47h92.857m180 0h517.14m172.86 0h151.43'
fill='none'
strokeWidth='2'
/>
<path
id='path66'
d='m364.57 547.33c15.715 18.571 123.37 81.524 151.43 88.571 29.502 7.41 103 7.143 103 7.143l-7.143-95.714z'
fill='#f0ffeb'
strokeWidth='5'
/>
<path
id='path68'
d='m404.57 577.33v-28.571'
fill='none'
strokeWidth='2'
/>
<path
id='path70'
d='m644.7 641.64-4.285-94.328h207.16c-11.307 20.753-46.612 74.906-72.857 88.571-14.285 10-82.878 4.328-130.02 5.757zm167.02-7.165s80-84.285 85.715-87.142c5.714-2.857 115.71-1.429 115.71-1.429s-77.143 47.143-102.86 58.572c-25.715 11.428-90 31.428-98.572 30z'
fill='#f0ffeb'
strokeWidth='5'
/>
<g fill='none'>
<path
id='path72'
d='m345.64 556.81c-14.075-30.967-18.298-71.787-18.298-94.309 0-22.521 4.223-91.493 22.521-105.57m282.93 298.41c-1.408-5.63-4.047-81.905-6.51-106.93-3.67-18.714-4.989-51.218-6.159-87.314 0-22.522 7.038-80.233 12.669-105.57'
strokeWidth='5'
/>
<path
id='path74'
d='m103.53 396.34s15.483 85.864 106.98 85.864c91.494 0 109.79-87.271 109.79-87.271m479.99 0s15.483 85.863 106.98 85.863c91.493 0 109.79-87.27 109.79-87.27m-947.31 57.71h63.342'
strokeWidth='2'
/>
<path
id='path76'
d='m779.18 648.3c18.299-12.669 56.304-50.674 92.9-104.16 36.598-53.489 8.447-59.12-18.298-74.603-26.744-15.483-49.266-42.228-67.564-112.61'
strokeWidth='5'
/>
<path
id='path78'
d='m1112.8 452.42h-129.5m-696.76 0.223h544.74m-22.522 150.61v-54.895'
strokeWidth='2'
/>
</g>
<g strokeWidth='2'>
<rect
id='rect80'
transform='scale(1 -1)'
x='558.65'
y='-503.55'
width='41.286'
height='14.541'
rx='2.933'
ry='7.379'
fill='#e6e6e6'
/>
<rect
id='rect82'
transform='scale(1 -1)'
x='816.24'
y='-503.55'
width='41.286'
height='14.541'
rx='2.933'
ry='7.379'
fill='#e6e6e6'
/>
<rect
id='rect84'
transform='scale(1 -1)'
x='259.53'
y='-502.15'
width='18.776'
height='11.738'
rx='1.63'
ry='7.692'
fill='#ffcb00'
/>
<circle
id='circle86'
transform='translate(941.34 284)'
cx='59.119'
cy='211.28'
r='16.891'
fill='#fff'
/>
</g>
</g>
<path
id='path90'
d='m-126.58 704.93v260.4'
fill='none'
stroke='#000'
strokeWidth='2'
/>
<path
id='path92'
d='m-153.88 992.49v-26.041h45.043v52.08h-45.043zm0-316.71v-27.448h45.043v54.898h-45.043z'
fill='#ffffc0'
/>
<g fill='none' stroke='#000'>
<path
id='path94'
d='m-157.4 624.38s-4.223-12.669-18.299-12.669-14.076 8.446-14.076 8.446v423.69s1.408 9.853 14.076 9.853c12.669 0 18.3-9.853 18.3-9.853'
strokeWidth='5'
/>
<path
id='path96'
d='m-191.18 624.38s-35.19-1.408-35.19 21.114v371.6c0 22.521 36.597 25.336 36.597 25.336'
strokeWidth='5'
/>
<g strokeWidth='2'>
<rect
id='rect98'
x='-216.51'
y='648.31'
width='16.891'
height='35.19'
rx='7.742'
ry='6.284'
/>
<rect
id='rect100'
x='-216.51'
y='985.58'
width='16.891'
height='35.19'
rx='7.742'
ry='6.284'
/>
<path id='path102' d='m-62.939 645.49h30.967v377.24h-30.967z' />
</g>
<path
id='path104'
d='m1200.9 633.86v73.195h67.565v-83.048l-25.337-14.076zm0 329.38h67.565v78.826l-23.93 14.076-43.635-18.3zm0-270.26v284.33m67.565-283.74v284.33'
strokeWidth='5'
/>
<path
id='path106'
d='m1216.6 759.51h14.076v147.8h-14.076zm7.631-1.408v-53.488m0 257.37v-53.49m30.375-201.06v256.18'
strokeWidth='2'
/>
<path
id='path108'
d='m1268.8 624.97s4.223-12.668 18.299-12.668 14.076 8.445 14.076 8.445v423.69s-1.408 9.853-14.076 9.853c-12.669 0-18.299-9.853-18.299-9.853m33.783-419.46s35.19-1.408 35.19 21.114v371.6c0 22.521-36.598 25.337-36.598 25.337'
strokeWidth='5'
/>
<g strokeWidth='2'>
<rect
id='rect110'
transform='scale(-1 1)'
x='-1329.9'
y='648.9'
width='16.891'
height='35.19'
rx='7.742'
ry='6.284'
/>
<rect
id='rect112'
transform='scale(-1 1)'
x='-1329.9'
y='986.17'
width='16.891'
height='35.19'
rx='7.742'
ry='6.284'
/>
<path
id='path114'
d='m1199.7 632.82 67.565 74.603m-67.565 0.592 67.565-73.195m-67.342 328.16 67.565 74.602m-67.565 0.593 67.565-73.195'
/>
</g>
</g>
<g stroke='#000'>
<g strokeWidth='2'>
<circle
id='circle116'
transform='translate(78.489 1074.7)'
cx='119.65'
cy='202.84'
r='76.01'
fill='#c8c8c8'
/>
<circle
id='circle118'
transform='translate(94.676 1204.9)'
cx='103.46'
cy='72.633'
r='44.339'
fill='#fff'
/>
<circle
id='circle120'
transform='translate(78.489 187.66)'
cx='119.65'
cy='202.84'
r='76.01'
fill='#c8c8c8'
/>
<circle
id='circle122'
transform='translate(94.676 317.86)'
cx='103.46'
cy='72.633'
r='44.339'
fill='#fff'
/>
<circle
id='circle124'
transform='translate(773.02 187.66)'
cx='119.65'
cy='202.84'
r='76.01'
fill='#c8c8c8'
/>
<circle
id='circle126'
transform='translate(789.21 317.86)'
cx='103.46'
cy='72.633'
r='44.339'
fill='#fff'
/>
<circle
id='circle128'
transform='translate(773.02 1074.7)'
cx='119.65'
cy='202.84'
r='76.01'
fill='#c8c8c8'
/>
<circle
id='circle130'
transform='translate(789.21 1204.9)'
cx='103.46'
cy='72.633'
r='44.339'
fill='#fff'
/>
</g>
<path
id='path132'
d='m1338.5 829.07h40.82'
fill='none'
strokeWidth='5'
/>
<circle
id='circle134'
transform='translate(1441.3 600.31)'
cx='-59.119'
cy='229.58'
r='4.223'
fill='#3c3c3c'
strokeWidth='5'
/>
<g strokeWidth='2'>
<path id='path136' d='m778.06 845.37-38.709-38.709' fill='none' />
<g id='g146' transform='translate(-13.78 15.524)' fill='#3c3c3c'>
<circle
id='circle138'
transform='translate(-79.458 449.8)'
cx='-81.641'
cy='188.76'
r='4.223'
/>
<circle
id='circle140'
transform='translate(-79.458 569.92)'
cx='-81.641'
cy='188.76'
r='4.223'
/>
<circle
id='circle142'
transform='translate(-79.458 690.03)'
cx='-81.641'
cy='188.76'
r='4.223'
/>
<circle
id='circle144'
transform='translate(-79.458 810.15)'
cx='-81.641'
cy='188.76'
r='4.223'
/>
</g>
<g id='g156' transform='translate(-13.78 17.524)' fill='#3c3c3c'>
<circle
id='circle148'
transform='translate(1381.6 448.25)'
cx='-81.641'
cy='188.76'
r='4.223'
/>
<circle
id='circle150'
transform='translate(1381.6 568.36)'
cx='-81.641'
cy='188.76'
r='4.223'
/>
<circle
id='circle152'
transform='translate(1381.6 688.48)'
cx='-81.641'
cy='188.76'
r='4.223'
/>
<circle
id='circle154'
transform='translate(1381.6 808.59)'
cx='-81.641'
cy='188.76'
r='4.223'
/>
</g>
</g>
</g>
</g>
<g id='layer2' fill='#d00000'>
<circle
id='p02'
cx='503.65'
cy='248.75'
r='61.935'
opacity={dmg1 === "02" ? 100 : 0}
/>
<circle
id='p03'
cx='863.41'
cy='248.75'
r='61.935'
opacity={dmg1 === "03" ? 100 : 0}
/>
<circle
id='p04'
cx='1181.5'
cy='248.75'
r='61.935'
opacity={dmg1 === "04" ? 100 : 0}
/>
<circle
id='p05'
cx='1378.4'
cy='151.16'
r='61.935'
opacity={dmg1 === "05" ? 100 : 0}
/>
<circle
id='p06'
cx='1535.1'
cy='581.37'
r='61.935'
opacity={dmg1 === "06" ? 100 : 0}
/>
<circle
id='p07'
cx='1378.4'
cy='997.9'
r='61.935'
opacity={dmg1 === "07" ? 100 : 0}
/>
<circle
id='p08'
cx='1181.5'
cy='914.24'
r='61.935'
opacity={dmg1 === "08" ? 100 : 0}
/>
<circle
id='p09'
transform='scale(1,-1)'
cx='863.41'
cy='-914.24'
r='61.935'
opacity={dmg1 === "09" ? 100 : 0}
/>
<circle
id='p10'
cx='503.65'
cy='914.24'
r='61.935'
opacity={dmg1 === "10" ? 100 : 0}
/>
<circle
id='p11'
cx='297.77'
cy='997.9'
r='61.935'
opacity={dmg1 === "11" ? 100 : 0}
/>
<circle
id='p12'
cx='93.269'
cy='581.37'
r='61.935'
opacity={dmg1 === "12" ? 100 : 0}
/>
<circle
id='p25'
cx='424.31'
cy='581.37'
r='61.935'
opacity={dmg1 === "25" ? 100 : 0}
/>
<circle
id='p27'
cx='972.84'
cy='581.37'
r='61.935'
opacity={dmg1 === "27" ? 100 : 0}
/>
<circle
id='p01'
cx='297.77'
cy='151.16'
r='61.935'
opacity={dmg1 === "01" ? 100 : 0}
/>
<circle
id='p26'
cx='1339.4'
cy='581.37'
r='61.935'
opacity={dmg1 === "26" ? 100 : 0}
/>
</g>
<g id='g4994' fill='#ffef00'>
<circle
id='s02'
cx='503.65'
cy='248.75'
r='61.935'
opacity={dmg2 === "02" ? 100 : 0}
/>
<circle
id='s03'
cx='863.41'
cy='248.75'
r='61.935'
opacity={dmg2 === "03" ? 100 : 0}
/>
<circle
id='s04'
cx='1181.5'
cy='248.75'
r='61.935'
opacity={dmg2 === "04" ? 100 : 0}
/>
<circle
id='s05'
cx='1378.4'
cy='151.16'
r='61.935'
opacity={dmg2 === "05" ? 100 : 0}
/>
<circle
id='s06'
cx='1535.1'
cy='581.37'
r='61.935'
opacity={dmg2 === "06" ? 100 : 0}
/>
<circle
id='s07'
cx='1378.4'
cy='997.9'
r='61.935'
opacity={dmg2 === "07" ? 100 : 0}
/>
<circle
id='s08'
cx='1181.5'
cy='914.24'
r='61.935'
opacity={dmg2 === "08" ? 100 : 0}
/>
<circle
id='s09'
transform='scale(1,-1)'
cx='863.41'
cy='-914.24'
r='61.935'
opacity={dmg2 === "09" ? 100 : 0}
/>
<circle
id='s10'
cx='503.65'
cy='914.24'
r='61.935'
opacity={dmg2 === "10" ? 100 : 0}
/>
<circle
id='s11'
cx='297.77'
cy='997.9'
r='61.935'
opacity={dmg2 === "11" ? 100 : 0}
/>
<circle
id='s12'
cx='93.269'
cy='581.37'
r='61.935'
opacity={dmg2 === "12" ? 100 : 0}
/>
<circle
id='s25'
cx='424.31'
cy='581.37'
r='61.935'
opacity={dmg2 === "25" ? 100 : 0}
/>
<circle
id='s27'
cx='972.84'
cy='581.37'
r='61.935'
opacity={dmg2 === "27" ? 100 : 0}
/>
<circle
id='s01'
cx='297.77'
cy='151.16'
r='61.935'
opacity={dmg2 === "01" ? 100 : 0}
/>
<circle
id='s26'
cx='1339.4'
cy='581.37'
r='61.935'
opacity={dmg2 === "26" ? 100 : 0}
/>
{
// <text
// id='p15'
// opacity='0'
// x='382.62802'
// y='1034.3463'
// fill='#fd0000'
// fontFamily='sans-serif'
// fontSize='1696.9px'
// letterSpacing='0px'
// strokeWidth='17.676'
// wordSpacing='0px'
// style='line-height:5.25'>
// x
// </text>
}
</g>
</svg>
);

View File

@@ -1,18 +1,14 @@
import React from "react";
import { useTranslation } from "react-i18next";
import CardTemplate from "./job-detail-cards.template.component";
import UnfoldedCar from "../../assets/unfolded_car.svg";
import Car from "../job-damage-visual/job-damage-visual.component";
export default function JobDetailCardsDamageComponent({ loading, data }) {
const { t } = useTranslation();
const { area_of_damage } = data;
return (
<CardTemplate loading={loading} title={t("jobs.labels.cards.damage")}>
{data ? (
<span>
<img src={UnfoldedCar} alt='Damaged Area' width={200} height={200} />
</span>
) : null}
<Car dmg1={area_of_damage.impact1} dmg2={area_of_damage.impact2} />
</CardTemplate>
);
}

View File

@@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import { alphaSort } from "../../utils/sorters";
//import EditableCell from "./job-lines-cell.component";
import AllocationsAssignmentContainer from "../allocations-assignment/allocations-assignment.container";
export default function JobLinesComponent({
jobLines,
@@ -97,6 +98,38 @@ export default function JobLinesComponent({
render: (text, record) => (
<CurrencyFormatter>{record.act_price}</CurrencyFormatter>
)
},
{
title: t("joblines.fields.mod_lb_hrs"),
dataIndex: "mod_lb_hrs",
key: "mod_lb_hrs",
sorter: (a, b) => a.mod_lb_hrs - b.mod_lb_hrs,
sortOrder:
state.sortedInfo.columnKey === "mod_lb_hrs" && state.sortedInfo.order
},
{
title: t("allocations.fields.employee"),
dataIndex: "employee",
key: "employee",
sorter: (a, b) => a.act_price - b.act_price, //TODO Fix employee sorting.
sortOrder:
state.sortedInfo.columnKey === "employee" && state.sortedInfo.order,
render: (text, record) => (
<span>
{record.allocations && record.allocations.length > 0
? record.allocations.map(item => (
<div
key={item.id}
>{`${item.employee.first_name} ${item.employee.last_name} (${item.hours})`}</div>
))
: null}
<AllocationsAssignmentContainer
key={record.id}
jobLineId={record.id}
hours={record.mod_lb_hrs}
/>
</span>
)
}
];

View File

@@ -4,6 +4,8 @@ import { useTranslation } from "react-i18next";
import { DateTimeFormatter } from "../../utils/DateFormatter";
import { alphaSort } from "../../utils/sorters";
import OwnerFindModalContainer from "../owner-find-modal/owner-find-modal.container";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
export default function JobsAvailableComponent({
loading,
data,
@@ -77,7 +79,10 @@ export default function JobsAvailableComponent({
key: "clm_amt",
sorter: (a, b) => a.clm_amt - b.clm_amt,
sortOrder:
state.sortedInfo.columnKey === "clm_amt" && state.sortedInfo.order
state.sortedInfo.columnKey === "clm_amt" && state.sortedInfo.order,
render: (text, record) => (
<CurrencyFormatter>{record.clm_amt}</CurrencyFormatter>
)
//width: "12%",
//ellipsis: true
},
@@ -141,7 +146,8 @@ export default function JobsAvailableComponent({
estData.data.available_jobs_by_pk &&
estData.data.available_jobs_by_pk.est_data &&
estData.data.available_jobs_by_pk.est_data.owner &&
estData.data.available_jobs_by_pk.est_data.owner.data
estData.data.available_jobs_by_pk.est_data.owner.data &&
!estData.data.available_jobs_by_pk.issupplement
? estData.data.available_jobs_by_pk.est_data.owner.data
: null;
@@ -164,7 +170,7 @@ export default function JobsAvailableComponent({
return (
<div>
<Input.Search
placeholder="Search..."
placeholder="Search...//TODO Implement Search"
onSearch={value => {
console.log(value);
}}

View File

@@ -29,14 +29,7 @@ export default withRouter(function JobsAvailableContainer({
const onModalOk = () => {
setModalVisible(false);
console.log("selectedOwner", selectedOwner);
setInsertLoading(true);
console.log(
"logitest",
estData.data &&
estData.data.available_jobs_by_pk &&
estData.data.available_jobs_by_pk.est_data
);
if (
!(

View File

@@ -3,13 +3,25 @@ import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { alphaSort } from "../../utils/sorters";
import { DateTimeFormatter } from "../../utils/DateFormatter";
import JobsFindModalContainer from "../jobs-find-modal/jobs-find-modal.container";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
export default function JobsAvailableSupplementComponent({
loading,
data,
refetch,
deleteJob,
updateJob,
onModalOk,
onModalCancel,
modalVisible,
setModalVisible,
selectedJob,
setSelectedJob,
deleteAllNewJobs,
estDataLazyLoad
loadEstData,
estData,
importOptionsState
}) {
const { t } = useTranslation();
@@ -81,7 +93,10 @@ export default function JobsAvailableSupplementComponent({
key: "clm_amt",
sorter: (a, b) => a.clm_amt - b.clm_amt,
sortOrder:
state.sortedInfo.columnKey === "clm_amt" && state.sortedInfo.order
state.sortedInfo.columnKey === "clm_amt" && state.sortedInfo.order,
render: (text, record) => (
<CurrencyFormatter>{record.clm_amt}</CurrencyFormatter>
)
//width: "12%",
//ellipsis: true
},
@@ -127,7 +142,8 @@ export default function JobsAvailableSupplementComponent({
</Button>
<Button
onClick={() => {
alert("Add");
loadEstData({ variables: { id: record.id } });
setModalVisible(true);
}}
>
<Icon type="plus" />
@@ -140,54 +156,66 @@ export default function JobsAvailableSupplementComponent({
];
return (
<Table
loading={loading}
title={() => {
return (
<div>
<Input.Search
placeholder="Search..."
onSearch={value => {
console.log(value);
}}
enterButton
/>
<Button
onClick={() => {
refetch();
}}
>
<Icon type="sync" />
</Button>
<Button
onClick={() => {
deleteAllNewJobs()
.then(r => {
notification["success"]({
message: t("jobs.successes.all_deleted", {
count: r.data.delete_available_jobs.affected_rows
})
<div>
<JobsFindModalContainer
loading={estData.loading}
error={estData.error}
selectedJob={selectedJob}
setSelectedJob={setSelectedJob}
importOptionsState={importOptionsState}
visible={modalVisible}
onOk={onModalOk}
onCancel={onModalCancel}
/>
<Table
loading={loading}
title={() => {
return (
<div>
<Input.Search
placeholder="Search..."
onSearch={value => {
console.log(value);
}}
enterButton
/>
<Button
onClick={() => {
refetch();
}}
>
<Icon type="sync" />
</Button>
<Button
onClick={() => {
deleteAllNewJobs()
.then(r => {
notification["success"]({
message: t("jobs.successes.all_deleted", {
count: r.data.delete_available_jobs.affected_rows
})
});
refetch();
})
.catch(r => {
notification["error"]({
message: t("jobs.errors.deleted") + " " + r.message
});
});
refetch();
})
.catch(r => {
notification["error"]({
message: t("jobs.errors.deleted") + " " + r.message
});
});
}}
>
Delete All
</Button>
</div>
);
}}
size="small"
pagination={{ position: "top" }}
columns={columns.map(item => ({ ...item }))}
rowKey="id"
dataSource={data && data.available_jobs}
onChange={handleTableChange}
/>
}}
>
Delete All
</Button>
</div>
);
}}
size="small"
pagination={{ position: "top" }}
columns={columns.map(item => ({ ...item }))}
rowKey="id"
dataSource={data && data.available_jobs}
onChange={handleTableChange}
/>
</div>
);
}

View File

@@ -1,12 +1,21 @@
import React from "react";
import { notification } from "antd";
import React, { useState } from "react";
import { useMutation, useQuery } from "react-apollo";
import { DELETE_ALL_AVAILABLE_SUPPLEMENT_JOBS, QUERY_AVAILABLE_SUPPLEMENT_JOBS } from "../../graphql/available-jobs.queries";
import { useTranslation } from "react-i18next";
import { withRouter } from "react-router-dom";
import {
DELETE_ALL_AVAILABLE_SUPPLEMENT_JOBS,
QUERY_AVAILABLE_SUPPLEMENT_JOBS
} from "../../graphql/available-jobs.queries";
import { UPDATE_JOB } from "../../graphql/jobs.queries";
import AlertComponent from "../alert/alert.component";
import JobsAvailableSupplementComponent from "./jobs-available-supplement.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
export default function JobsAvailableSupplementContainer({
export default withRouter(function JobsAvailableSupplementContainer({
deleteJob,
estDataLazyLoad
estDataLazyLoad,
history
}) {
const { loading, error, data, refetch } = useQuery(
QUERY_AVAILABLE_SUPPLEMENT_JOBS,
@@ -14,17 +23,107 @@ export default function JobsAvailableSupplementContainer({
fetchPolicy: "network-only"
}
);
const { t } = useTranslation();
const [deleteAllNewJobs] = useMutation(DELETE_ALL_AVAILABLE_SUPPLEMENT_JOBS);
const [modalVisible, setModalVisible] = useState(false);
const [selectedJob, setSelectedJob] = useState(null);
const [insertLoading, setInsertLoading] = useState(false);
const [updateJob] = useMutation(UPDATE_JOB);
const [loadEstData, estData] = estDataLazyLoad;
const importOptionsState = useState({ overrideHeaders: false });
const importOptions = importOptionsState[0];
const onModalOk = () => {
setModalVisible(false);
setInsertLoading(true);
if (
!(
estData.data &&
estData.data.available_jobs_by_pk &&
estData.data.available_jobs_by_pk.est_data
)
) {
//We don't have the right data. Error!
setInsertLoading(false);
notification["error"]({
message: t("jobs.errors.creating", { error: "No job data present." })
});
} else {
//create upsert job
let supp = estData.data.available_jobs_by_pk.est_data;
delete supp.joblines;
delete supp.owner;
delete supp.vehicle;
if (!importOptions.overrideHeaders) {
delete supp["ins_ea"];
//Strip out the header options
}
updateJob({
variables: {
jobId: selectedJob,
job: supp
}
})
.then(r => {
notification["success"]({
message: t("jobs.successes.supplemented"),
onClick: () => {
history.push(
`/manage/jobs/${r.data.update_jobs.returning[0].id}`
);
}
});
//Job has been inserted. Clean up the available jobs record.
deleteJob({
variables: { id: estData.data.available_jobs_by_pk.id }
}).then(r => {
refetch();
setInsertLoading(false);
});
})
.catch(r => {
//error while inserting
notification["error"]({
message: t("jobs.errors.creating", { error: r.message })
});
refetch();
setInsertLoading(false);
});
}
};
const onModalCancel = () => {
setModalVisible(false);
setSelectedJob(null);
};
if (error) return <AlertComponent type="error" message={error.message} />;
return (
<JobsAvailableSupplementComponent
loading={loading}
data={data}
refetch={refetch}
deleteJob={deleteJob}
deleteAllNewJobs={deleteAllNewJobs}
estDataLazyLoad={estDataLazyLoad}
/>
<LoadingSpinner
loading={insertLoading}
message={t("jobs.labels.creating_new_job")}
>
<JobsAvailableSupplementComponent
loading={loading}
data={data}
refetch={refetch}
deleteJob={deleteJob}
updateJob={updateJob}
onModalOk={onModalOk}
onModalCancel={onModalCancel}
modalVisible={modalVisible}
setModalVisible={setModalVisible}
selectedJob={selectedJob}
setSelectedJob={setSelectedJob}
deleteAllNewJobs={deleteAllNewJobs}
loadEstData={loadEstData}
estData={estData}
importOptionsState={importOptionsState}
/>
</LoadingSpinner>
);
}
});

View File

@@ -20,6 +20,7 @@ import { createStructuredSelector } from "reselect";
import CarImage from "../../assets/car.svg";
import { selectBodyshop } from "../../redux/user/user.selectors";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
import BarcodePopup from "../barcode-popup/barcode-popup.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
@@ -49,32 +50,6 @@ export default connect(
</div>
);
const tombstoneSubtitle = (
<div>
<Tag color="red">
{job.owner ? (
<Link to={`/manage/owners/${job.owner.id}`}>
{`${job.ownr_co_nm || ""}${job.ownr_fn || ""} ${job.ownr_ln || ""}`}
</Link>
) : (
t("jobs.errors.noowner")
)}
</Tag>
<Tag color="green">
{job.vehicle ? (
<Link to={`/manage/vehicles/${job.vehicle.id}`}>
{job.vehicle.v_model_yr || t("general.labels.na")}{" "}
{job.vehicle.v_make_desc || t("general.labels.na")}{" "}
{job.vehicle.v_model_desc || t("general.labels.na")} |{" "}
{job.vehicle.plate_no || t("general.labels.na")} |{" "}
{job.vehicle.v_vin || t("general.labels.na")}
</Link>
) : null}
</Tag>
</div>
);
const statusmenu = (
<Menu
onClick={e => {
@@ -137,10 +112,32 @@ export default connect(
border: "1px solid rgb(235, 237, 240)"
}}
title={tombstoneTitle}
subTitle={tombstoneSubtitle}
//subTitle={tombstoneSubtitle}
tags={
<span key="job-status">
{job.status ? <Tag color="blue">{job.status}</Tag> : null}
<Tag color="red">
{job.owner ? (
<Link to={`/manage/owners/${job.owner.id}`}>
{`${job.ownr_co_nm || ""}${job.ownr_fn || ""} ${job.ownr_ln ||
""}`}
</Link>
) : (
t("jobs.errors.noowner")
)}
</Tag>
<Tag color="green">
{job.vehicle ? (
<Link to={`/manage/vehicles/${job.vehicle.id}`}>
{job.vehicle.v_model_yr || t("general.labels.na")}{" "}
{job.vehicle.v_make_desc || t("general.labels.na")}{" "}
{job.vehicle.v_model_desc || t("general.labels.na")} |{" "}
{job.vehicle.plate_no || t("general.labels.na")} |{" "}
{job.vehicle.v_vin || t("general.labels.na")}
</Link>
) : null}
</Tag>
<BarcodePopup value={job.id} />
</span>
}
extra={menuExtra}

View File

@@ -0,0 +1,172 @@
import { Checkbox, Divider, Table } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import PhoneFormatter from "../../utils/PhoneFormatter";
export default function JobsFindModalComponent({
selectedJob,
setSelectedJob,
jobsList,
jobsListLoading,
importOptionsState
}) {
const { t } = useTranslation();
const [importOptions, setImportOptions] = importOptionsState;
const columns = [
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
width: "8%",
render: (text, record) => (
<span>
<Link to={"/manage/jobs/" + record.id}>
{record.ro_number ? record.ro_number : "EST-" + record.est_number}
</Link>
</span>
)
},
{
title: t("jobs.fields.owner"),
dataIndex: "owner",
key: "owner",
ellipsis: true,
width: "25%",
render: (text, record) => {
return record.owner ? (
<Link to={"/manage/owners/" + record.owner.id}>
{record.ownr_fn} {record.ownr_ln}
</Link>
) : (
// t("jobs.errors.noowner")
<span>{`${record.ownr_fn} ${record.ownr_ln}`}</span>
);
}
},
{
title: t("jobs.fields.ownr_ph1"),
dataIndex: "ownr_ph1",
key: "ownr_ph1",
width: "12%",
ellipsis: true,
render: (text, record) => {
return record.ownr_ph1 ? (
<PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>
) : (
t("general.labels.unknown")
);
}
},
{
title: t("jobs.fields.status"),
dataIndex: "status",
key: "status",
width: "10%",
ellipsis: true,
render: (text, record) => {
return record.status || t("general.labels.na");
}
},
{
title: t("jobs.fields.vehicle"),
dataIndex: "vehicle",
key: "vehicle",
width: "15%",
ellipsis: true,
render: (text, record) => {
return record.vehicle ? (
<Link to={"/manage/vehicles/" + record.vehicle.id}>
{record.vehicle.v_model_yr} {record.vehicle.v_make_desc}{" "}
{record.vehicle.v_model_desc}
</Link>
) : (
t("jobs.errors.novehicle")
);
}
},
{
title: t("vehicles.fields.plate_no"),
dataIndex: "plate_no",
key: "plate_no",
width: "8%",
ellipsis: true,
render: (text, record) => {
return record.vehicle.plate_no ? (
<span>{record.vehicle.plate_no}</span>
) : (
t("general.labels.unknown")
);
}
},
{
title: t("jobs.fields.clm_no"),
dataIndex: "clm_no",
key: "clm_no",
width: "12%",
ellipsis: true,
render: (text, record) => {
return record.clm_no ? (
<span>{record.clm_no}</span>
) : (
t("general.labels.unknown")
);
}
}
];
const handleOnRowClick = record => {
if (record) {
if (record.id) {
setSelectedJob(record.id);
return;
}
}
setSelectedJob(null);
};
return (
<div>
<Table
title={() => t("jobs.labels.existing_jobs")}
size="small"
pagination={{ position: "bottom" }}
columns={columns.map(item => ({ ...item }))}
rowKey="id"
loading={jobsListLoading}
dataSource={jobsList}
rowSelection={{
onSelect: props => {
setSelectedJob(props.id);
},
type: "radio",
selectedRowKeys: [selectedJob]
}}
onRow={(record, rowIndex) => {
return {
onClick: event => {
handleOnRowClick(record);
}
};
}}
/>
<Divider />
<Checkbox
defaultChecked={importOptions.overrideHeader}
onChange={e =>
setImportOptions({
...importOptions,
overrideHeader: e.target.checked
})
}
>
{t("jobs.labels.override_header")}
</Checkbox>
</div>
);
}

View File

@@ -0,0 +1,46 @@
import { Modal } from "antd";
import React from "react";
import { useQuery } from "react-apollo";
import { useTranslation } from "react-i18next";
import { QUERY_ALL_OPEN_JOBS } from "../../graphql/jobs.queries";
import AlertComponent from "../alert/alert.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import JobsFindModalComponent from "./jobs-find-modal.component";
export default function JobsFindModalContainer({
loading,
error,
selectedJob,
setSelectedJob,
importOptionsState,
...modalProps
}) {
const { t } = useTranslation();
const jobsList = useQuery(QUERY_ALL_OPEN_JOBS, {
fetchPolicy: "network-only"
});
return (
<Modal
title={t("jobs.labels.existing_jobs")}
width={"80%"}
okButtonProps={{ disabled: selectedJob ? false : true }}
{...modalProps}
>
{loading ? <LoadingSpinner /> : null}
{error ? <AlertComponent message={error.message} type="error" /> : null}
{true ? (
<JobsFindModalComponent
selectedJob={selectedJob}
setSelectedJob={setSelectedJob}
importOptionsState={importOptionsState}
jobsListLoading={jobsList.loading}
jobsList={
jobsList.data && jobsList.data.jobs ? jobsList.data.jobs : null
}
/>
) : null}
</Modal>
);
}

View File

@@ -118,7 +118,8 @@ export default function OwnerFindModalComponent({
checked={selectedOwner ? false : true}
onClick={() => setSelectedOwner(null)}
>
Create a new Owner record for this job.
{t("owners.labels.create_new")}
</Checkbox>
</div>
);

View File

@@ -0,0 +1,89 @@
import { Input, Table } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import PhoneFormatter from "../../utils/PhoneFormatter";
import { alphaSort } from "../../utils/sorters";
export default function OwnersListComponent({ loading, owners, refetch }) {
const [state, setState] = useState({
sortedInfo: {},
filteredInfo: { text: "" }
});
const { t } = useTranslation();
const columns = [
{
title: t("owners.fields.name"),
dataIndex: "name",
key: "name",
// onFilter: (value, record) => record.ro_number.includes(value),
// filteredValue: state.filteredInfo.text || null,
sorter: (a, b) => alphaSort(a.ownr_ln, b.ownr_ln),
sortOrder:
state.sortedInfo.columnKey === "name" && state.sortedInfo.order,
render: (text, record) => (
<Link to={"/manage/owners/" + record.id}>
{`${record.ownr_fn} ${record.ownr_ln}`}
</Link>
)
},
{
title: t("owners.fields.ownr_ph1"),
dataIndex: "ownr_ph1",
key: "ownr_ph1",
sorter: (a, b) => alphaSort(a.ownr_ph1, b.ownr_ph1),
sortOrder:
state.sortedInfo.columnKey === "ownr_ph1" && state.sortedInfo.order,
render: (text, record) => {
return <PhoneFormatter>{record.ownr_ph1}</PhoneFormatter>;
}
},
{
title: t("owners.fields.ownr_ea"),
dataIndex: "ownr_ea",
key: "ownr_ea"
},
{
title: t("owners.fields.address"),
dataIndex: "address",
key: "address",
render: (text, record) => {
return (
<div>{`${record.ownr_addr1 || ""} ${record.ownr_addr2 ||
""} ${record.ownr_city || ""} ${record.ownr_st ||
""} ${record.ownr_zip || ""}`}</div>
);
}
}
];
const handleTableChange = (pagination, filters, sorter) => {
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
};
//TODO Implement searching & pagination
return (
<Table
loading={loading}
title={() => {
return (
<Input.Search
placeholder="Search..."
onSearch={value => {
console.log(value);
}}
enterButton
/>
);
}}
size="small"
pagination={{ position: "top" }}
columns={columns.map(item => ({ ...item }))}
rowKey="id"
dataSource={owners}
onChange={handleTableChange}
/>
);
}

View File

@@ -0,0 +1,20 @@
import React from "react";
import { useQuery } from "react-apollo";
import { QUERY_ALL_OWNERS } from "../../graphql/owners.queries";
import AlertComponent from "../alert/alert.component";
import OwnersListComponent from "./owners-list.component";
export default function OwnersListContainer() {
const { loading, error, data, refetch } = useQuery(QUERY_ALL_OWNERS, {
fetchPolicy: "network-only"
});
if (error) return <AlertComponent message={error.message} type="error" />;
return (
<OwnersListComponent
loading={loading}
owners={data ? data.owners : null}
refetch={refetch}
/>
);
}

View File

@@ -0,0 +1,67 @@
import { Checkbox, Col, DatePicker, Modal, Row, TimePicker, Input } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import ScheduleDayViewContainer from "../schedule-day-view/schedule-day-view.container";
export default function ScheduleJobModalComponent({
appData,
setAppData,
formData,
setFormData,
...props
}) {
const { t } = useTranslation();
//TODO: Existing appointments list only refreshes sometimes after modal close. May have to do with the container class.
return (
<Modal
{...props}
width={"80%"}
maskClosable={false}
destroyOnClose={true}
okButtonProps={{ disabled: appData.start ? false : true }}
>
<Row>
<Col span={14}>
<Row>
Manual Job Selection Scheduled Time
<Input
placeholder={t("appointments.fields.title")}
onChange={e => {
setAppData({ ...appData, title: e.target.value });
}}
/>
<DatePicker
value={appData.start}
onChange={e => {
setAppData({ ...appData, start: e });
}}
/>
<TimePicker
value={appData.start}
format={"HH:mm"}
minuteStep={15}
onChange={e => {
setAppData({ ...appData, start: e });
}}
/>
</Row>
{
//TODO: Build out notifications.
}
<Checkbox
defaultChecked={formData.notifyCustomer}
onChange={e =>
setFormData({ ...formData, notifyCustomer: e.target.checked })
}
>
{t("jobs.labels.appointmentconfirmation")}
</Checkbox>
</Col>
<Col span={10}>
<ScheduleDayViewContainer day={appData.start} />
</Col>
</Row>
</Modal>
);
}

View File

@@ -0,0 +1,74 @@
import { notification } from "antd";
import moment from "moment";
import React, { useState } from "react";
import { useMutation } from "react-apollo";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { INSERT_APPOINTMENT } from "../../graphql/appointments.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import ScheduleAppointmentModalComponent from "./schedule-appointment-modal.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
export default connect(
mapStateToProps,
null
)(function ScheduleAppointmentModalContainer({
scheduleModalState,
jobId,
bodyshop,
refetch
}) {
const [scheduleModalVisible, setscheduleModalVisible] = scheduleModalState;
const [appData, setAppData] = useState({
jobid: jobId,
bodyshopid: bodyshop.id,
isintake: false,
start: null
});
const [insertAppointment] = useMutation(INSERT_APPOINTMENT);
const [formData, setFormData] = useState({ notifyCustomer: false });
const { t } = useTranslation();
return (
<ScheduleAppointmentModalComponent
appData={appData}
setAppData={setAppData}
formData={formData}
setFormData={setFormData}
//Spreadable Modal Props
visible={scheduleModalVisible}
onCancel={() => setscheduleModalVisible(false)}
onOk={() => {
//TODO: Customize the amount of minutes it will add.
insertAppointment({
variables: {
app: { ...appData, end: moment(appData.start).add(60, "minutes") }
}
})
.then(r => {
notification["success"]({
message: t("appointments.successes.created")
});
if (formData.notifyCustomer) {
//TODO: Implement customer reminder on scheduling.
alert("Chosed to notify the customer somehow!");
}
setscheduleModalVisible(false);
if (refetch) refetch();
})
.catch(error => {
notification["error"]({
message: t("appointments.errors.saving", {
message: error.message
})
});
});
}}
/>
);
});

View File

@@ -1,13 +1,46 @@
import React from "react";
//import "react-big-calendar/lib/css/react-big-calendar.css";
import ScheduleCalendarWrapperComponent from "../schedule-calendar-wrapper/scheduler-calendar-wrapper.component";
import { Button, Icon } from "antd";
import { useTranslation } from "react-i18next";
import ScheduleAppointmentModalContainer from "../schedule-appointment-modal/schedule-appointment-modal.container";
export default function ScheduleCalendarComponent({
data,
refetch,
scheduleModalState
}) {
const { t } = useTranslation();
export default function ScheduleCalendarComponent({ data, refetch }) {
return (
<ScheduleCalendarWrapperComponent
data={data}
defaultView="week"
refetch={refetch}
/>
<div>
<Button
onClick={() => {
refetch();
}}
>
<Icon type="sync" />
</Button>
<Button
onClick={() => {
scheduleModalState[1](true);
}}
>
{t("appointments.actions.new")}
</Button>
<ScheduleAppointmentModalContainer
scheduleModalState={scheduleModalState}
jobId={null}
refetch={refetch}
/>
<ScheduleCalendarWrapperComponent
data={data}
defaultView="week"
refetch={refetch}
/>
</div>
);
}

View File

@@ -1,4 +1,4 @@
import React from "react";
import React, { useState } from "react";
import { useQuery } from "react-apollo";
import ScheduleCalendarComponent from "./schedule-calendar.component";
import { QUERY_ALL_ACTIVE_APPOINTMENTS } from "../../graphql/appointments.queries";
@@ -12,6 +12,7 @@ export default function ScheduleCalendarContainer() {
fetchPolicy: "network-only"
}
);
const scheduleModalState = useState(false);
if (loading) return <LoadingSpinner />;
if (error) return <AlertComponent message={error.message} type="error" />;
@@ -27,6 +28,7 @@ export default function ScheduleCalendarContainer() {
return (
<ScheduleCalendarComponent
scheduleModalState={scheduleModalState}
refetch={refetch}
data={data ? normalizedData : null}
/>

View File

@@ -9,22 +9,53 @@ export default function ScheduleEventComponent({ event, handleCancel }) {
const { t } = useTranslation();
const popoverContent = (
<div>
<div>{`${t("jobs.fields.ro_number")}: ${event.job.ro_number}`}</div>
<div>
{t("jobs.fields.clm_total")}:
<CurrencyFormatter>{event.job.clm_total}</CurrencyFormatter>
</div>
<div>{`${t("jobs.fields.clm_no")}: ${event.job.clm_no}`}</div>
<div>
{t("jobs.fields.ownr_ea")}:{event.job.ownr_ea}
</div>
<div>
{t("jobs.fields.ownr_ph1")}:
<PhoneFormatter>{event.job.ownr_ph1}</PhoneFormatter>
</div>
<Link to={`/manage/jobs/${event.job.id}`}>
<Button>{t("appointments.actions.viewjob")}</Button>
</Link>
{!event.isintake ? (
<strong>{event.title}</strong>
) : (
<div>
<strong>{`${(event.job && event.job.ownr_fn) || ""} ${(event.job &&
event.job.ownr_ln) ||
""}`}</strong>
<span style={{ margin: 4 }}>
{`${(event.job && event.job.vehicle.v_model_yr) ||
""} ${(event.job && event.job.vehicle.v_make_desc) ||
""} ${(event.job && event.job.vehicle.v_model_desc) || ""}`}
</span>
</div>
)}
{event.job ? (
<div>
<div>{`${t("jobs.fields.ro_number")}: ${(event.job &&
event.job.ro_number) ||
""}`}</div>
<div>
{t("jobs.fields.clm_total")}:
<CurrencyFormatter>
{(event.job && event.job.clm_total) || ""}
</CurrencyFormatter>
</div>
<div>{`${t("jobs.fields.clm_no")}: ${(event.job &&
event.job.clm_no) ||
""}`}</div>
<div>
{t("jobs.fields.ownr_ea")}:{(event.job && event.job.ownr_ea) || ""}
</div>
<div>
{t("jobs.fields.ownr_ph1")}:
<PhoneFormatter>
{(event.job && event.job.ownr_ph1) || ""}
</PhoneFormatter>
</div>
</div>
) : null}
{
//TODO Add phone 1 MessagingActionTypes.
}
{event.job ? (
<Link to={`/manage/jobs/${event.job && event.job.id}`}>
<Button>{t("appointments.actions.viewjob")}</Button>
</Link>
) : null}
<Button onClick={() => handleCancel(event.id)}>
{t("appointments.actions.cancel")}
</Button>
@@ -34,24 +65,36 @@ export default function ScheduleEventComponent({ event, handleCancel }) {
}
{t("appointments.actions.reschedule")}
</Button>
<Button>
{
//TODO: Add intake func.
}
{t("appointments.actions.intake")}
</Button>
{event.isintake ? (
<Button>
{
//TODO: Add intake func.
}
{t("appointments.actions.intake")}
</Button>
) : null}
</div>
);
return (
<Popover content={popoverContent}>
<div>
<strong>{`${event.job.ownr_fn || ""} ${event.job.ownr_ln ||
""}`}</strong>
<span style={{ margin: 4 }}>
{`${event.job.vehicle.v_model_yr || ""} ${event.job.vehicle
.v_make_desc || ""} ${event.job.vehicle.v_model_desc || ""}`}
</span>
{event.isintake ? (
<div>
<strong>{`${(event.job && event.job.ownr_fn) || ""} ${(event.job &&
event.job.ownr_ln) ||
""}`}</strong>
<span style={{ margin: 4 }}>
{`${(event.job && event.job.vehicle.v_model_yr) ||
""} ${(event.job && event.job.vehicle.v_make_desc) ||
""} ${(event.job && event.job.vehicle.v_model_desc) || ""}`}
</span>
</div>
) : (
<div>
<strong>{`${event.title || ""}`}</strong>
</div>
)}
</div>
</Popover>
);

View File

@@ -28,12 +28,16 @@ export default connect(
refetch
}) {
const [scheduleModalVisible, setscheduleModalVisible] = scheduleModalState;
const [appData, setAppData] = useState({ jobid: jobId, start: null });
const [appData, setAppData] = useState({
jobid: jobId,
start: null,
bodyshopid: bodyshop.id
});
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 });

View File

@@ -0,0 +1,112 @@
import { Button, DatePicker, Form, Input, InputNumber, Switch } from "antd";
import moment from "moment";
import React from "react";
import { useTranslation } from "react-i18next";
export default function ShopEmployeesFormComponent({
form,
selectedEmployee,
handleSubmit
}) {
const { t } = useTranslation();
const { getFieldDecorator } = form;
if (!selectedEmployee) return "//TODO No employee selected.";
return (
<Form onSubmit={handleSubmit} autoComplete={"off"}>
<Button type="primary" htmlType="submit">
{t("general.actions.save")}
</Button>
<Form.Item label={t("employees.fields.first_name")}>
{getFieldDecorator("first_name", {
initialValue: selectedEmployee.first_name,
rules: [
{
required: true,
message: t("general.validation.required")
}
]
})(<Input name="first_name" />)}
</Form.Item>
<Form.Item label={t("employees.fields.last_name")}>
{getFieldDecorator("last_name", {
initialValue: selectedEmployee.last_name,
rules: [
{
required: true,
message: t("general.validation.required")
}
]
})(<Input name="last_name" />)}
</Form.Item>
<Form.Item label={t("employees.fields.employee_number")}>
{getFieldDecorator("employee_number", {
initialValue: selectedEmployee.employee_number,
rules: [
{
required: true,
message: t("general.validation.required")
}
]
})(<Input name="employee_number" />)}
</Form.Item>
<Form.Item label={t("employees.fields.active")}>
{getFieldDecorator("active", {
initialValue: selectedEmployee.active,
valuePropName: "checked"
})(<Switch name="active" />)}
</Form.Item>
<Form.Item label={t("employees.fields.flat_rate")}>
{getFieldDecorator("flat_rate", {
initialValue: selectedEmployee.flat_rate,
valuePropName: "checked"
})(<Switch name="active" />)}
</Form.Item>
<Form.Item label={t("employees.fields.hire_date")}>
{getFieldDecorator("hire_date", {
initialValue: selectedEmployee.hire_date
? moment(selectedEmployee.hire_date)
: null,
rules: [
{
required: true,
message: t("general.validation.required")
}
]
})(<DatePicker name="hire_date" />)}
</Form.Item>
<Form.Item label={t("employees.fields.termination_date")}>
{getFieldDecorator("termination_date", {
initialValue: selectedEmployee.termination_date
? moment(selectedEmployee.termination_date)
: null
})(<DatePicker name="termination_date" />)}
</Form.Item>
{
//TODO Make this a picklist.
}
<Form.Item label={t("employees.fields.cost_center")}>
{getFieldDecorator("cost_center", {
initialValue: selectedEmployee.cost_center,
rules: [
{
required: true,
message: t("general.validation.required")
}
]
})(<Input name="cost_center" />)}
</Form.Item>
<Form.Item label={t("employees.fields.base_rate")}>
{getFieldDecorator("base_rate", {
initialValue: selectedEmployee.base_rate,
rules: [
{
required: true,
message: t("general.validation.required")
}
]
})(<InputNumber name="base_rate" />)}
</Form.Item>
</Form>
);
}

View File

@@ -0,0 +1,52 @@
import { Button, List } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import CurrencyFormatter from "../../utils/CurrencyFormatter";
export default function ShopEmployeesListComponent({
loading,
employees,
setSelectedEmployee,
handleDelete
}) {
const { t } = useTranslation();
return (
<div>
<Button
type="primary"
onClick={() => {
setSelectedEmployee({});
}}
>
{t("employees.actions.new")}
</Button>
<List
loading={loading}
itemLayout="horizontal"
dataSource={employees}
renderItem={item => (
<List.Item
actions={[
<Button key="edit" onClick={() => setSelectedEmployee(item)}>
{t("general.actions.edit")}
</Button>,
<Button key="delete" onClick={() => handleDelete(item.id)}>
{t("general.actions.delete")}
</Button>
]}
>
<List.Item.Meta
title={`${item.first_name || ""} ${item.last_name ||
""} | ${item.employee_number || ""}`}
description={
<span>
{item.cost_center} @{" "}
<CurrencyFormatter>{item.base_rate}</CurrencyFormatter>
</span>
}
/>
</List.Item>
)}
/>
</div>
);
}

View File

@@ -0,0 +1,34 @@
import { Col, Row } from "antd";
import React from "react";
import ShopEmployeesFormComponent from "./shop-employees-form.component";
import ShopEmployeesListComponent from "./shop-employees-list.component";
export default function ShopEmployeeComponent({
form,
loading,
employees,
employeeState,
handleSubmit,
handleDelete
}) {
const [selectedEmployee, setSelectedEmployee] = employeeState;
return (
<Row>
<Col span={6}>
<ShopEmployeesListComponent
employees={employees}
loading={loading}
setSelectedEmployee={setSelectedEmployee}
handleDelete={handleDelete}
/>
</Col>
<Col span={18}>
<ShopEmployeesFormComponent
handleSubmit={handleSubmit}
form={form}
selectedEmployee={selectedEmployee}
/>
</Col>
</Row>
);
}

View File

@@ -0,0 +1,112 @@
import { Form, notification } from "antd";
import React, { useState } from "react";
import { useMutation, useQuery } from "react-apollo";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { DELETE_EMPLOYEE, INSERT_EMPLOYEES, QUERY_EMPLOYEES, UPDATE_EMPLOYEE } from "../../graphql/employees.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
import AlertComponent from "../alert/alert.component";
import ShopEmployeeComponent from "./shop-employees.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop
});
function ShopEmployeesContainer({ form, bodyshop }) {
const { t } = useTranslation();
const employeeState = useState(null);
const { loading, error, data, refetch } = useQuery(QUERY_EMPLOYEES, {
fetchPolicy: "network-only"
});
const [updateEmployee] = useMutation(UPDATE_EMPLOYEE);
const [insertEmployees] = useMutation(INSERT_EMPLOYEES);
const [deleteEmployee] = useMutation(DELETE_EMPLOYEE);
const handleDelete = id => {
deleteEmployee({ variables: { id: id } })
.then(r => {
notification["success"]({
message: t("employees.successes.delete")
});
//TODO: Better way to reset the field decorators?
employeeState[1](null);
refetch().then(r => form.resetFields());
})
.catch(error => {
notification["error"]({
message: t("employees.errors.delete")
});
});
};
const handleSubmit = e => {
e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (err) {
notification["error"]({
message: t("employees.errors.validationtitle"),
description: t("employees.errors.validation")
});
}
if (!err) {
if (employeeState[0].id) {
//Update a record.
updateEmployee({
variables: { id: employeeState[0].id, employee: values }
})
.then(r => {
notification["success"]({
message: t("employees.successes.save")
});
//TODO: Better way to reset the field decorators?
employeeState[1](null);
refetch().then(r => form.resetFields());
})
.catch(error => {
notification["error"]({
message: t("employees.errors.save")
});
});
} else {
//New record, insert it.
insertEmployees({
variables: { employees: [{ ...values, shopid: bodyshop.id }] }
}).then(r => {
notification["success"]({
message: t("employees.successes.save")
});
//TODO: Better way to reset the field decorators?
employeeState[1](null);
refetch()
.then(r => form.resetFields())
.catch(error => {
notification["error"]({
message: t("employees.errors.save")
});
});
});
}
}
});
};
if (error) return <AlertComponent message={error.message} type="error" />;
return (
<ShopEmployeeComponent
handleSubmit={handleSubmit}
handleDelete={handleDelete}
form={form}
loading={loading}
employeeState={employeeState}
employees={data ? data.employees : []}
/>
);
}
export default connect(
mapStateToProps,
null
)(Form.create({ name: "ShopEmployeesContainer" })(ShopEmployeesContainer));

View File

@@ -0,0 +1,76 @@
import { Input, Table } from "antd";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import { alphaSort } from "../../utils/sorters";
export default function VehiclesListComponent({ loading, vehicles, refetch }) {
const [state, setState] = useState({
sortedInfo: {},
filteredInfo: { text: "" }
});
const { t } = useTranslation();
const columns = [
{
title: t("vehicles.fields.v_vin"),
dataIndex: "v_vin",
key: "v_vin",
// onFilter: (value, record) => record.ro_number.includes(value),
// filteredValue: state.filteredInfo.text || null,
sorter: (a, b) => alphaSort(a.v_vin, b.v_vin),
sortOrder:
state.sortedInfo.columnKey === "v_vin" && state.sortedInfo.order,
render: (text, record) => (
<Link to={"/manage/vehicles/" + record.id}>{record.v_vin}</Link>
)
},
{
title: t("vehicles.fields.description"),
dataIndex: "description",
key: "description",
render: (text, record) => {
return (
<span>{`${record.v_model_yr} ${record.v_make_desc} ${record.v_model_desc} ${record.v_color}`}</span>
);
}
},
{
title: t("vehicles.fields.plate_no"),
dataIndex: "plate",
key: "plate",
render: (text, record) => {
return <span>{`${record.plate_st} | ${record.plate_no}`}</span>;
}
}
];
const handleTableChange = (pagination, filters, sorter) => {
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
};
//TODO Implement searching & pagination
return (
<Table
loading={loading}
title={() => {
return (
<Input.Search
placeholder="Search..."
onSearch={value => {
console.log(value);
}}
enterButton
/>
);
}}
size="small"
pagination={{ position: "top" }}
columns={columns.map(item => ({ ...item }))}
rowKey="id"
dataSource={vehicles}
onChange={handleTableChange}
/>
);
}

View File

@@ -0,0 +1,20 @@
import React from "react";
import VehiclesListComponent from "./vehicles-list.component";
import { useQuery } from "react-apollo";
import AlertComponent from "../alert/alert.component";
import { QUERY_ALL_VEHICLES } from "../../graphql/vehicles.queries";
export default function VehiclesListContainer() {
const { loading, error, data, refetch } = useQuery(QUERY_ALL_VEHICLES, {
fetchPolicy: "network-only"
});
if (error) return <AlertComponent message={error.message} type="error" />;
return (
<VehiclesListComponent
loading={loading}
vehicles={data ? data.vehicles : null}
refetch={refetch}
/>
);
}

View File

@@ -1,117 +0,0 @@
import React from "react";
import { Link } from "react-router-dom";
import { Menu, Dropdown, Card, Icon, Avatar, Row, Col } from "antd";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
import Moment from "react-moment";
import CarImage from "../../assets/car.svg";
//The following styled div is required because of a smooth-dnd style used by react-trello to prevent wrapping of columns.
const WrappedSpan = styled.span`
white-space: normal;
`;
export default function WhiteBoardCard({ metadata }) {
// const {
// onClick,
// className,
// name,
// cardStyle,
// body,
// dueOn,
// cardColor,
// subTitle,
// tagStyle,
// escalationText,
// tags,
// showDeleteButton,
// onDelete
// } = this.props;
const { t } = useTranslation();
const menu = (
<Menu>
<Menu.Item key='images'>
<Icon type='file-image' />
{t("jobs.actions.viewJobImages")}
</Menu.Item>
<Menu.Item key='printing'>
<Icon type='printer' />
{t("jobs.actions.printCenter")}
</Menu.Item>
<Menu.Item key='notes'>
<Icon type='edit' />
{t("jobs.actions.notes")}
</Menu.Item>
<Menu.Item key='postinvoices'>
<Icon type='shopping-cart' />
{t("jobs.actions.postInvoices")}
</Menu.Item>
<Menu.Item key='receiveparts'>
<Icon type='inbox' />
{t("jobs.actions.receiveParts")}
</Menu.Item>
<Menu.Item key='partstatus'>
<Icon type='tool' />
{t("jobs.actions.partStatus")}
</Menu.Item>
</Menu>
);
return (
<div>
<Card
title={
(metadata.ro_number || metadata.est_number) +
" | " +
(metadata.owner?.first_name || "") +
" " +
(metadata.owner?.last_name || "")
}
style={{ width: 300, marginTop: 10 }}
bodyStyle={{ padding: 10 }}
actions={[
<Link to={`/manage/jobs/${metadata.id}`}>
<Icon type='eye' key='view' />
</Link>,
<Icon type='message' key='message' />,
<Dropdown overlay={menu} trigger={["click"]}>
<Icon type='ellipsis' />
</Dropdown>
]}>
<Row>
<Col span={6}>
<Avatar size='large' alt='Vehicle Image' src={CarImage} />
</Col>
<Col span={18}>
<Row>
<WrappedSpan>
{metadata.vehicle?.v_model_yr || t("general.labels.na")}{" "}
{metadata.vehicle?.v_make_desc || t("general.labels.na")}{" "}
{metadata.vehicle?.v_model_desc || t("general.labels.na")}
</WrappedSpan>
</Row>
{metadata.vehicle?.v_vin ? (
<Row>
<WrappedSpan>
VIN: {metadata.vehicle?.v_vin || t("general.labels.na")}
</WrappedSpan>
</Row>
) : null}
</Col>
</Row>
<Row>
<Col span={12}>
{t("general.labels.in")}:
<Moment format='MM/DD/YYYY'>{metadata.actual_in}</Moment>
</Col>
<Col span={12}>
{t("general.labels.out")}:
<Moment format='MM/DD/YYYY'>{metadata.scheduled_completion}</Moment>
</Col>
</Row>
</Card>
</div>
);
}

View File

@@ -1,23 +0,0 @@
import React from "react";
import Board from "react-trello";
import WhiteBoardCard from "../white-board-card/white-board-card.component";
export default function WhiteBoardKanBan({ data, eventBus }) {
const setEventBus = handle => {
eventBus = handle;
};
return (
<Board
tagStyle={{ fontSize: "80%" }}
data={data}
style={{ backgroundColor: "none" }}
laneDraggable={false}
eventBusHandle={setEventBus}
components={{ Card: WhiteBoardCard }}
onCardClick={(cardId, metadata) =>
alert(`Card with id:${cardId} clicked. Has metadata.id: ${metadata.id}`)
}
/>
);
}

View File

@@ -1,46 +0,0 @@
import React from "react";
import { useSubscription } from "@apollo/react-hooks";
import { SUBSCRIPTION_JOBS_IN_PRODUCTION } from "../../graphql/jobs.queries";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
import Alert from "../../components/alert/alert.component";
import WhiteBoardKanBan from "./white-board-kanban.component";
export default function WhiteBoardKanBanContainer() {
const { loading, error, data } = useSubscription(
SUBSCRIPTION_JOBS_IN_PRODUCTION,
{
fetchPolicy: "network-only"
}
);
if (loading) return <LoadingSpinner />;
if (error) return <Alert message={error.message} />;
let eventBus;
let i = data.job_status.reduce((acc, value) => {
//Create a lane object for each row.
let newLane = {
id: value.name,
title: value.name,
label: "0",
cards: value.jobs.reduce((acc, value) => {
acc.push({
id: value.id,
title: value.ro_number,
description: value.est_number,
label: value.id,
metadata: value
});
return acc;
}, [])
};
acc.push(newLane);
return acc;
}, []);
let laneData = {
lanes: i
};
return <WhiteBoardKanBan eventBus={eventBus} data={laneData} />;
}

View File

@@ -1,24 +0,0 @@
import React from "react";
import { Menu, Icon } from "antd";
export default function WhiteBoardLeftSiderComponent({visible}) {
return (
<Menu theme="dark" mode="inline" defaultSelectedKeys={["4"]}>
<Menu.Item key="1">
<Icon type="user" />
<span className="nav-text">nav 1</span>
</Menu.Item>
<Menu.Item key="2">
<Icon type="video-camera" />
<span className="nav-text">nav 2</span>
</Menu.Item>
<Menu.Item key="3">
<Icon type="upload" />
<span className="nav-text">nav 3</span>
</Menu.Item>
<Menu.Item key="4">
<Icon type="user" />
<span className="nav-text">nav 4</span>
</Menu.Item>
</Menu>
);
}

View File

@@ -1,7 +0,0 @@
import React from "react";
import WhiteBoardLeftSiderComponent from "./white-board-left-sider.component";
export default function WhiteBoardPageContainer() {
return <WhiteBoardLeftSiderComponent />;
}

View File

@@ -0,0 +1,11 @@
import { gql } from "apollo-boost";
export const INSERT_ALLOCATION = gql`
mutation INSERT_ALLOCATION($alloc: [allocations_insert_input!]!) {
insert_allocations(objects: $alloc) {
returning {
id
}
}
}
`;

View File

@@ -25,8 +25,6 @@ const errorLink = onError(
}
if (expired) {
//User access token has expired
//props.history.push("/network-error");
console.log("We need a new token!");
console.log("Old Token", window.localStorage.getItem("token"));
// Let's refresh token through async request
@@ -35,15 +33,15 @@ const errorLink = onError(
console.log("Got the new token.", token);
window.localStorage.setItem("token", token);
const oldHeaders = operation.getContext().headers;
operation.setContext({
headers: {
...oldHeaders,
authorization: token ? `Bearer ${token}` : ""
}
});
console.log("forward", forward);
console.log("operation", operation);
// const oldHeaders = operation.getContext().headers;
// operation.setContext({
// headers: {
// ...oldHeaders,
// authorization: token ? `Bearer ${token}` : ""
// }
// });
// console.log("forward", forward);
// console.log("operation", operation);
return forward(operation).subscribe();
// return new Observable(observer => {

View File

@@ -6,6 +6,8 @@ export const QUERY_ALL_ACTIVE_APPOINTMENTS = gql`
start
id
end
title
isintake
job {
ro_number
ownr_ln
@@ -38,10 +40,14 @@ export const INSERT_APPOINTMENT = gql`
export const QUERY_APPOINTMENT_BY_DATE = gql`
query QUERY_APPOINTMENT_BY_DATE($start: timestamptz, $end: timestamptz) {
appointments(where: { start: { _lte: $end, _gte: $start } }) {
appointments(
where: { start: { _lte: $end, _gte: $start }, canceled: { _eq: false } }
) {
start
id
end
title
isintake
job {
ro_number
ownr_ln
@@ -81,6 +87,7 @@ export const QUERY_APPOINTMENTS_BY_JOBID = gql`
start
id
end
isintake
arrived
canceled
created_at

View File

@@ -75,6 +75,7 @@ export const QUERY_AVAILABLE_NEW_JOBS_EST_DATA_BY_PK = gql`
query QUERY_AVAILABLE_NEW_JOBS_EST_DATA_BY_PK($id: uuid!) {
available_jobs_by_pk(id: $id) {
id
issupplement
est_data
}
}

View File

@@ -20,6 +20,13 @@ export const QUERY_BODYSHOP = gql`
updated_at
zip_post
region_config
employees {
id
first_name
last_name
employee_number
cost_center
}
}
}
`;

View File

@@ -0,0 +1,48 @@
import { gql } from "apollo-boost";
export const QUERY_EMPLOYEES = gql`
query QUERY_EMPLOYEES {
employees {
last_name
id
first_name
employee_number
active
termination_date
hire_date
flat_rate
cost_center
base_rate
}
}
`;
export const INSERT_EMPLOYEES = gql`
mutation INSERT_EMPLOYEES($employees: [employees_insert_input!]!) {
insert_employees(objects: $employees) {
returning {
id
}
}
}
`;
export const UPDATE_EMPLOYEE = gql`
mutation UPDATE_EMPLOYEE($id: uuid!, $employee: employees_set_input) {
update_employees(where: { id: { _eq: $id } }, _set: $employee) {
returning {
id
}
}
}
`;
export const DELETE_EMPLOYEE = gql`
mutation DELETE_EMPLOYEE($id: uuid!) {
delete_employees(where: { id: { _eq: $id } }) {
returning {
id
}
}
}
`;

View File

@@ -18,6 +18,15 @@ export const GET_JOB_LINES_BY_PK = gql`
lbr_op
lbr_amt
op_code_desc
allocations {
id
hours
employee {
id
first_name
last_name
}
}
}
}
`;

View File

@@ -120,6 +120,7 @@ export const GET_JOB_BY_PK = gql`
ins_co_id
policy_no
loss_date
clm_no
area_of_damage
ins_co_nm
ins_addr1
@@ -256,6 +257,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
est_ct_ln
clm_no
status
area_of_damage
ro_number
scheduled_completion
scheduled_in

View File

@@ -65,3 +65,28 @@ export const UPDATE_OWNER = gql`
}
}
`;
export const QUERY_ALL_OWNERS = gql`
query QUERY_ALL_OWNERS {
owners {
id
allow_text_message
created_at
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
updated_at
}
}
`;

View File

@@ -53,3 +53,20 @@ export const UPDATE_VEHICLE = gql`
}
}
`;
export const QUERY_ALL_VEHICLES = gql`
query QUERY_ALL_VEHICLES {
vehicles {
id
plate_no
plate_st
v_vin
v_model_yr
v_model_desc
v_make_desc
v_color
v_bstyle
updated_at
}
}
`;

View File

@@ -1,11 +1,10 @@
import React, { useEffect, useState } from "react";
import { useQuery } from "@apollo/react-hooks";
import AlertComponent from "../../components/alert/alert.component";
import { Col } from "antd";
import { QUERY_ALL_OPEN_JOBS } from "../../graphql/jobs.queries";
import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import JobsList from "../../components/jobs-list/jobs-list.component";
import AlertComponent from "../../components/alert/alert.component";
import JobDetailCards from "../../components/job-detail-cards/job-detail-cards.component";
import JobsList from "../../components/jobs-list/jobs-list.component";
import { QUERY_ALL_OPEN_JOBS } from "../../graphql/jobs.queries";
//TODO: Implement pagination for this.
export default function JobsPage({ match, location }) {
@@ -21,9 +20,9 @@ export default function JobsPage({ match, location }) {
const { hash } = location;
const [selectedJob, setSelectedJob] = useState(hash ? hash.substr(1) : null);
if (error) return <AlertComponent message={error.message} type='error' />;
if (error) return <AlertComponent message={error.message} type="error" />;
return (
<Col span={22} offset={1}>
<div>
<JobsList
loading={loading}
selectedJob={selectedJob}
@@ -31,6 +30,6 @@ export default function JobsPage({ match, location }) {
jobs={data ? data.jobs : null}
/>
<JobDetailCards selectedJob={selectedJob} />
</Col>
</div>
);
}

View File

@@ -1,20 +1,28 @@
import { notification } from "antd";
import React, { useEffect } from "react";
import ManagePage from "./manage.page";
import { useQuery } from "react-apollo";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
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";
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
import ManagePage from "./manage.page";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
bodyshop: selectBodyshop
});
const mapDispatchToProps = dispatch => ({
setBodyshop: bs => dispatch(setBodyshop(bs))
});
export default connect(
null,
mapStateToProps,
mapDispatchToProps
)(function ManagePageContainer({ match, setBodyshop }) {
)(function ManagePageContainer({ match, setBodyshop, bodyshop }) {
const { error, data } = useQuery(QUERY_BODYSHOP, {
fetchPolicy: "network-only"
});
@@ -30,5 +38,7 @@ export default connect(
};
}, [data, setBodyshop]);
//TODO Translate later.
if (!bodyshop) return <LoadingSpinner message="Loading bodyshop data." />;
return <ManagePage match={match} />;
});

View File

@@ -39,6 +39,8 @@ const OwnersContainer = lazy(() => import("../owners/owners.page.container"));
const OwnersDetailContainer = lazy(() =>
import("../owners-detail/owners-detail.page.container")
);
const ShopPage = lazy(() => import("../shop/shop.page.component"));
const { Header, Content, Footer } = Layout;
export default function Manage({ match }) {
@@ -54,9 +56,10 @@ export default function Manage({ match }) {
<HeaderContainer />
</Header>
<Layout>
<ChatWindowContainer />
<Content className="content-container" style={{ margin: "0px" }}>
<Content
className="content-container"
style={{ padding: "0em 4em 4em" }}
>
<ErrorBoundary>
<Suspense
fallback={
@@ -113,12 +116,20 @@ export default function Manage({ match }) {
path={`${match.path}/available`}
component={JobsAvailablePage}
/>
<Route exact path={`${match.path}/shop/`} component={ShopPage} />
</Suspense>
</ErrorBoundary>
</Content>
</Layout>
<Footer>
<FooterComponent />
{
// <Affix offsetBottom={20}>
// <ChatWindowContainer />
// </Affix>
}
<ChatWindowContainer />
</Footer>
<BackTop />
</Layout>

View File

@@ -1,9 +1,6 @@
import React from 'react'
import React from "react";
import OwnersListContainer from "../../components/owners-list/owners-list.container";
export default function OwnersPageComponent() {
return (
<div>
Owners Page
</div>
)
return <OwnersListContainer />;
}

View File

@@ -1,8 +1,12 @@
import React from 'react'
import OwnersPageComponent from './owners.page.component'
import React, { useEffect } from "react";
import OwnersPageComponent from "./owners.page.component";
import { useTranslation } from "react-i18next";
export default function OwnersPageContainer() {
return (
<OwnersPageComponent />
)
const { t } = useTranslation();
useEffect(() => {
document.title = t("titles.owners");
}, [t]);
return <OwnersPageComponent />;
}

View File

@@ -0,0 +1,25 @@
import { Tabs } from "antd";
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
import ShopEmployeesContainer from "../../components/shop-employees/shop-employees.container";
export default function ShopPage() {
const { t } = useTranslation();
useEffect(() => {
document.title = t("titles.shop");
}, [t]);
return (
<Tabs>
<Tabs.TabPane tab="Shop Info" key="info">
Shop INfo
</Tabs.TabPane>
<Tabs.TabPane tab="Employees" key="employees">
<ShopEmployeesContainer />
</Tabs.TabPane>
<Tabs.TabPane tab="Licensing" key="licensing">
Licensing
</Tabs.TabPane>
</Tabs>
);
}

View File

@@ -1,9 +1,6 @@
import React from 'react'
import React from "react";
import VehiclesListContainer from "../../components/vehicles-list/vehicles-list.container";
export default function VehiclesPageComponent() {
return (
<div>
Vehiculos
</div>
)
return <VehiclesListContainer />;
}

View File

@@ -1,6 +1,10 @@
import React from "react";
import React, { useEffect } from "react";
import VehiclesPageComponent from "./vehicles.page.component";
import { useTranslation } from "react-i18next";
export default function VehiclesPageContainer() {
const { t } = useTranslation();
useEffect(() => {
document.title = t("titles.vehicles");
}, [t]);
return <VehiclesPageComponent />;
}

View File

@@ -1,30 +0,0 @@
import React from "react";
import WhiteBoardLeftSiderContainer from "../../components/white-board-left-sider/white-board-left-sider.container";
import WhiteBoardKanBanContainer from "../../components/white-board-kanban/white-board-kanban.container";
import { Layout } from "antd";
export default function WhiteBoardPage({ whiteBoardLeftSiderVisible }) {
const { Sider, Content } = Layout;
return (
<Layout>
<Sider
collapsible={true}
breakpoint="lg"
collapsedWidth="0"
onBreakpoint={broken => {
//console.log(broken);
}}
onCollapse={(collapsed, type) => {
//console.log(collapsed, type);
}}
>
<WhiteBoardLeftSiderContainer />
</Sider>
<Content>
<WhiteBoardKanBanContainer />
</Content>
</Layout>
);
}

View File

@@ -1,9 +1,18 @@
{
"translation": {
"allocations": {
"actions": {
"assign": "Assign"
},
"fields": {
"employee": "Allocated To"
}
},
"appointments": {
"actions": {
"cancel": "Cancel",
"intake": "Intake",
"new": "New Appointment",
"reschedule": "Reschedule",
"viewjob": "View Job"
},
@@ -11,6 +20,9 @@
"canceling": "Error canceling appointment.",
"saving": "Error scheduling appointment. {{message}}"
},
"fields": {
"title": "Title"
},
"labels": {
"arrivedon": "Arrived on: ",
"cancelledappointment": "Canceled appointment for: ",
@@ -55,12 +67,42 @@
"insert": "Uploaded document successfully. "
}
},
"employees": {
"actions": {
"new": "New Employee"
},
"errors": {
"delete": "Error encountered while deleting employee.",
"save": "Error encountered saving employee.",
"validation": "Please check all fields.",
"validationtitle": "Unable to save employee."
},
"fields": {
"active": "Active?",
"base_rate": "Base Rate",
"cost_center": "Cost Center",
"employee_number": "Employee Number",
"first_name": "First Name",
"flat_rate": "Flat Rate (Disabled is Straight Time)",
"hire_date": "Hire Date",
"last_name": "Last Name",
"termination_date": "Termination Date"
},
"successes": {
"delete": "Employee deleted successfully.",
"save": "Employee saved successfully."
}
},
"general": {
"actions": {
"reset": "Reset to original."
"delete": "Delete",
"edit": "Edit",
"reset": "Reset to original.",
"save": "Save"
},
"labels": {
"actions": "Actions",
"barcode": "Barcode",
"in": "In",
"loading": "Loading...",
"loadingapp": "Loading Bodyshop.app",
@@ -76,6 +118,9 @@
},
"messages": {
"unsavedchanges": "You have unsaved changes."
},
"validation": {
"required": "This field is required. "
}
},
"joblines": {
@@ -83,6 +128,7 @@
"act_price": "Actual Price",
"db_price": "Database Price",
"line_desc": "Line Description",
"mod_lb_hrs": "Labor Hours",
"oem_partno": "OEM Part #",
"part_type": "Part Type",
"unq_seq": "Seq #"
@@ -223,8 +269,10 @@
},
"creating_new_job": "Creating new job...",
"documents": "Documents",
"existing_jobs": "Existing Jobs",
"lines": "Estimate Lines",
"notes": "Notes",
"override_header": "Override estimate header on import?",
"parts": "Parts",
"rates": "Rates",
"vehicle_info": "Vehicle"
@@ -235,7 +283,8 @@
"created": "Job created successfully. Click to view.",
"deleted": "Job deleted successfully.",
"save": "Job saved successfully.",
"savetitle": "Record saved successfully."
"savetitle": "Record saved successfully.",
"supplemented": "Job supplemented successfully. "
}
},
"menus": {
@@ -251,6 +300,7 @@
"jobs": "Jobs",
"owners": "Owners",
"schedule": "Schedule",
"shop": "My Shop",
"vehicles": "Vehicles"
},
"jobsdetail": {
@@ -295,7 +345,9 @@
"noaccess": "The record does not exist or you do not have access to it. "
},
"fields": {
"address": "Address",
"allow_text_message": "Permission to Text?",
"name": "Name",
"ownr_addr1": "Address",
"ownr_addr2": "Address 2",
"ownr_city": "City",
@@ -310,6 +362,7 @@
"preferred_contact": "Preferred Contact Method"
},
"labels": {
"create_new": "Create a new owner record.",
"existing_owners": "Existing Owners"
},
"successes": {
@@ -328,9 +381,12 @@
"jobsdetail": "Job {{ro_number}} | $t(titles.app)",
"jobsdocuments": "Job Documents {{ro_number}} | $t(titles.app)",
"manageroot": "Home | $t(titles.app)",
"owners": "All Owners | $t(titles.app)",
"profile": "My Profile | $t(titles.app)",
"schedule": "Schedule | $t(titles.app)",
"vehicledetail": "Vehicle Details {{vehicle}} | $t(titles.app)"
"shop": "My Shop | $t(titles.app)",
"vehicledetail": "Vehicle Details {{vehicle}} | $t(titles.app)",
"vehicles": "All Vehicles | $t(titles.app)"
},
"user": {
"actions": {
@@ -349,6 +405,7 @@
"validationtitle": "Validation Error"
},
"fields": {
"description": "Vehicle Description",
"plate_no": "License Plate",
"plate_st": "Plate Jurisdiction",
"trim_color": "Trim Color",

View File

@@ -1,9 +1,18 @@
{
"translation": {
"allocations": {
"actions": {
"assign": "Asignar"
},
"fields": {
"employee": "Asignado a"
}
},
"appointments": {
"actions": {
"cancel": "Cancelar",
"intake": "Consumo",
"new": "Nueva cita",
"reschedule": "Reprogramar",
"viewjob": "Ver trabajo"
},
@@ -11,6 +20,9 @@
"canceling": "Error al cancelar la cita.",
"saving": "Error al programar la cita. {{message}}"
},
"fields": {
"title": "Título"
},
"labels": {
"arrivedon": "Llegado el:",
"cancelledappointment": "Cita cancelada para:",
@@ -55,12 +67,42 @@
"insert": "Documento cargado con éxito."
}
},
"employees": {
"actions": {
"new": "Nuevo empleado"
},
"errors": {
"delete": "Se encontró un error al eliminar al empleado.",
"save": "Se encontró un error al salvar al empleado.",
"validation": "Por favor verifique todos los campos.",
"validationtitle": "No se puede salvar al empleado."
},
"fields": {
"active": "¿Activo?",
"base_rate": "Tasa básica",
"cost_center": "Centro de costos",
"employee_number": "Numero de empleado",
"first_name": "Nombre de pila",
"flat_rate": "Tarifa plana (deshabilitado es tiempo recto)",
"hire_date": "Fecha de contratación",
"last_name": "Apellido",
"termination_date": "Fecha de conclusión"
},
"successes": {
"delete": "Empleado eliminado con éxito.",
"save": "Empleado guardado con éxito."
}
},
"general": {
"actions": {
"reset": "Restablecer a original."
"delete": "Borrar",
"edit": "Editar",
"reset": "Restablecer a original.",
"save": "Salvar"
},
"labels": {
"actions": "Comportamiento",
"barcode": "código de barras",
"in": "en",
"loading": "Cargando...",
"loadingapp": "Cargando Bodyshop.app",
@@ -76,6 +118,9 @@
},
"messages": {
"unsavedchanges": "Usted tiene cambios no guardados."
},
"validation": {
"required": "Este campo es requerido."
}
},
"joblines": {
@@ -83,6 +128,7 @@
"act_price": "Precio actual",
"db_price": "Precio de base de datos",
"line_desc": "Descripción de línea",
"mod_lb_hrs": "Horas laborales",
"oem_partno": "OEM parte #",
"part_type": "Tipo de parte",
"unq_seq": "Seq #"
@@ -223,8 +269,10 @@
},
"creating_new_job": "Creando nuevo trabajo ...",
"documents": "documentos",
"existing_jobs": "Empleos existentes",
"lines": "Líneas estimadas",
"notes": "Notas",
"override_header": "¿Anular encabezado estimado al importar?",
"parts": "Partes",
"rates": "Tarifas",
"vehicle_info": "Vehículo"
@@ -235,7 +283,8 @@
"created": "Trabajo creado con éxito. Click para ver.",
"deleted": "Trabajo eliminado con éxito.",
"save": "Trabajo guardado con éxito.",
"savetitle": "Registro guardado con éxito."
"savetitle": "Registro guardado con éxito.",
"supplemented": "Trabajo complementado con éxito."
}
},
"menus": {
@@ -251,6 +300,7 @@
"jobs": "Trabajos",
"owners": "propietarios",
"schedule": "Programar",
"shop": "Mi tienda",
"vehicles": "Vehículos"
},
"jobsdetail": {
@@ -295,7 +345,9 @@
"noaccess": "El registro no existe o no tiene acceso a él."
},
"fields": {
"address": "Dirección",
"allow_text_message": "Permiso de texto?",
"name": "Nombre",
"ownr_addr1": "Dirección",
"ownr_addr2": "Dirección 2",
"ownr_city": "ciudad",
@@ -310,6 +362,7 @@
"preferred_contact": "Método de Contacto Preferido"
},
"labels": {
"create_new": "Crea un nuevo registro de propietario.",
"existing_owners": "Propietarios existentes"
},
"successes": {
@@ -328,9 +381,12 @@
"jobsdetail": "Trabajo {{ro_number}} | $t(titles.app)",
"jobsdocuments": "Documentos de trabajo {{ro_number}} | $ t (títulos.app)",
"manageroot": "Casa | $t(titles.app)",
"owners": "Todos los propietarios | $t(titles.app)",
"profile": "Mi perfil | $t(titles.app)",
"schedule": "Horario | $t(titles.app)",
"vehicledetail": "Detalles del vehículo {{vehicle}} | $t(titles.app)"
"shop": "Mi tienda | $t(titles.app)",
"vehicledetail": "Detalles del vehículo {{vehicle}} | $t(titles.app)",
"vehicles": "Todos los vehiculos | $t(titles.app)"
},
"user": {
"actions": {
@@ -349,6 +405,7 @@
"validationtitle": "Error de validacion"
},
"fields": {
"description": "Descripcion del vehiculo",
"plate_no": "Placa",
"plate_st": "Jurisdicción de placas",
"trim_color": "Recortar color",

View File

@@ -1,9 +1,18 @@
{
"translation": {
"allocations": {
"actions": {
"assign": "Attribuer"
},
"fields": {
"employee": "Alloué à"
}
},
"appointments": {
"actions": {
"cancel": "annuler",
"intake": "Admission",
"new": "Nouveau rendez-vous",
"reschedule": "Replanifier",
"viewjob": "Voir le travail"
},
@@ -11,6 +20,9 @@
"canceling": "Erreur lors de l'annulation du rendez-vous.",
"saving": "Erreur lors de la planification du rendez-vous. {{message}}"
},
"fields": {
"title": "Titre"
},
"labels": {
"arrivedon": "Arrivé le:",
"cancelledappointment": "Rendez-vous annulé pour:",
@@ -55,12 +67,42 @@
"insert": "Document téléchargé avec succès."
}
},
"employees": {
"actions": {
"new": "Nouvel employé"
},
"errors": {
"delete": "Erreur rencontrée lors de la suppression de l'employé.",
"save": "Une erreur s'est produite lors de l'enregistrement de l'employé.",
"validation": "Veuillez cocher tous les champs.",
"validationtitle": "Impossible d'enregistrer l'employé."
},
"fields": {
"active": "Actif?",
"base_rate": "Taux de base",
"cost_center": "Centre de coûts",
"employee_number": "Numéro d'employé",
"first_name": "Prénom",
"flat_rate": "Taux fixe (désactivé est le temps normal)",
"hire_date": "Date d'embauche",
"last_name": "Nom de famille",
"termination_date": "Date de résiliation"
},
"successes": {
"delete": "L'employé a bien été supprimé.",
"save": "L'employé a enregistré avec succès."
}
},
"general": {
"actions": {
"reset": "Rétablir l'original."
"delete": "Effacer",
"edit": "modifier",
"reset": "Rétablir l'original.",
"save": "sauvegarder"
},
"labels": {
"actions": "actes",
"barcode": "code à barre",
"in": "dans",
"loading": "Chargement...",
"loadingapp": "Chargement de Bodyshop.app",
@@ -76,6 +118,9 @@
},
"messages": {
"unsavedchanges": "Vous avez des changements non enregistrés."
},
"validation": {
"required": "Ce champ est requis."
}
},
"joblines": {
@@ -83,6 +128,7 @@
"act_price": "Prix actuel",
"db_price": "Prix de la base de données",
"line_desc": "Description de la ligne",
"mod_lb_hrs": "Heures de travail",
"oem_partno": "Pièce OEM #",
"part_type": "Type de pièce",
"unq_seq": "Seq #"
@@ -223,8 +269,10 @@
},
"creating_new_job": "Création d'un nouvel emploi ...",
"documents": "Les documents",
"existing_jobs": "Emplois existants",
"lines": "Estimer les lignes",
"notes": "Remarques",
"override_header": "Remplacer l'en-tête d'estimation à l'importation?",
"parts": "les pièces",
"rates": "Les taux",
"vehicle_info": "Véhicule"
@@ -235,7 +283,8 @@
"created": "Le travail a été créé avec succès. Clique pour voir.",
"deleted": "Le travail a bien été supprimé.",
"save": "Le travail a été enregistré avec succès.",
"savetitle": "Enregistrement enregistré avec succès."
"savetitle": "Enregistrement enregistré avec succès.",
"supplemented": "Travail complété avec succès."
}
},
"menus": {
@@ -251,6 +300,7 @@
"jobs": "Emplois",
"owners": "Propriétaires",
"schedule": "Programme",
"shop": "Mon magasin",
"vehicles": "Véhicules"
},
"jobsdetail": {
@@ -295,7 +345,9 @@
"noaccess": "L'enregistrement n'existe pas ou vous n'y avez pas accès."
},
"fields": {
"address": "Adresse",
"allow_text_message": "Autorisation de texte?",
"name": "Prénom",
"ownr_addr1": "Adresse",
"ownr_addr2": "Adresse 2 ",
"ownr_city": "Ville",
@@ -310,6 +362,7 @@
"preferred_contact": "Méthode de contact préférée"
},
"labels": {
"create_new": "Créez un nouvel enregistrement de propriétaire.",
"existing_owners": "Propriétaires existants"
},
"successes": {
@@ -328,9 +381,12 @@
"jobsdetail": "Travail {{ro_number}} | $t(titles.app)",
"jobsdocuments": "Documents de travail {{ro_number}} | $ t (titres.app)",
"manageroot": "Accueil | $t(titles.app)",
"owners": "Tous les propriétaires | $t(titles.app)",
"profile": "Mon profil | $t(titles.app)",
"schedule": "Horaire | $t(titles.app)",
"vehicledetail": "Détails du véhicule {{vehicle} | $t(titles.app)"
"shop": "Mon magasin | $t(titles.app)",
"vehicledetail": "Détails du véhicule {{vehicle} | $t(titles.app)",
"vehicles": "Tous les véhicules | $t(titles.app)"
},
"user": {
"actions": {
@@ -349,6 +405,7 @@
"validationtitle": "Erreur de validation"
},
"fields": {
"description": "Description du véhicule",
"plate_no": "Plaque d'immatriculation",
"plate_st": "Juridiction de la plaque",
"trim_color": "Couleur de garniture",

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" DROP COLUMN "hire_date";
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" ADD COLUMN "hire_date" date NULL;
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" DROP COLUMN "termination_date";
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" ADD COLUMN "termination_date" date NULL;
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" DROP COLUMN "base_rate";
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" ADD COLUMN "base_rate" numeric NULL;
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" DROP COLUMN "cost_center";
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" ADD COLUMN "cost_center" text NOT NULL;
type: run_sql

View File

@@ -0,0 +1,10 @@
- args:
sql: ALTER TABLE ONLY "public"."employees" ALTER COLUMN "base_rate" SET DEFAULT
0;
type: run_sql
- args:
sql: ALTER TABLE "public"."employees" ALTER COLUMN "base_rate" DROP NOT NULL;
type: run_sql
- args:
sql: COMMENT ON COLUMN "public"."employees"."base_rate" IS E'null'
type: run_sql

View File

@@ -0,0 +1,10 @@
- args:
sql: ALTER TABLE ONLY "public"."employees" ALTER COLUMN "base_rate" SET DEFAULT
0;
type: run_sql
- args:
sql: ALTER TABLE "public"."employees" ALTER COLUMN "base_rate" SET NOT NULL;
type: run_sql
- args:
sql: COMMENT ON COLUMN "public"."employees"."base_rate" IS E''
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" DROP COLUMN "pay_type";
type: run_sql

View File

@@ -0,0 +1,4 @@
- args:
sql: ALTER TABLE "public"."employees" ADD COLUMN "pay_type" integer NOT NULL DEFAULT
0;
type: run_sql

View File

@@ -0,0 +1,9 @@
- args:
sql: ALTER TABLE "public"."employees" ADD COLUMN "pay_type" int4
type: run_sql
- args:
sql: ALTER TABLE "public"."employees" ALTER COLUMN "pay_type" DROP NOT NULL
type: run_sql
- args:
sql: ALTER TABLE "public"."employees" ALTER COLUMN "pay_type" SET DEFAULT 0
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" DROP COLUMN "pay_type" CASCADE
type: run_sql

View File

@@ -0,0 +1,3 @@
- args:
sql: ALTER TABLE "public"."employees" DROP COLUMN "flat_rate";
type: run_sql

View File

@@ -0,0 +1,4 @@
- args:
sql: ALTER TABLE "public"."employees" ADD COLUMN "flat_rate" boolean NOT NULL
DEFAULT false;
type: run_sql

View File

@@ -0,0 +1,35 @@
- args:
role: user
table:
name: employees
schema: public
type: drop_insert_permission
- args:
permission:
check:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- active
- employee_number
- first_name
- last_name
- created_at
- updated_at
- id
- shopid
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: employees
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,40 @@
- args:
role: user
table:
name: employees
schema: public
type: drop_insert_permission
- args:
permission:
check:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- id
- created_at
- updated_at
- first_name
- last_name
- employee_number
- shopid
- active
- hire_date
- termination_date
- base_rate
- cost_center
- flat_rate
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: employees
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,33 @@
- args:
role: user
table:
name: employees
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns:
- active
- employee_number
- first_name
- last_name
- created_at
- updated_at
- id
- shopid
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: employees
schema: public
type: create_select_permission

View File

@@ -0,0 +1,38 @@
- args:
role: user
table:
name: employees
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: false
columns:
- active
- flat_rate
- hire_date
- termination_date
- base_rate
- cost_center
- employee_number
- first_name
- last_name
- created_at
- updated_at
- id
- shopid
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: employees
schema: public
type: create_select_permission

View File

@@ -0,0 +1,35 @@
- args:
role: user
table:
name: employees
schema: public
type: drop_update_permission
- args:
permission:
columns:
- active
- employee_number
- first_name
- last_name
- created_at
- updated_at
- id
- shopid
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: employees
schema: public
type: create_update_permission

View File

@@ -0,0 +1,40 @@
- args:
role: user
table:
name: employees
schema: public
type: drop_update_permission
- args:
permission:
columns:
- active
- flat_rate
- hire_date
- termination_date
- base_rate
- cost_center
- employee_number
- first_name
- last_name
- created_at
- updated_at
- id
- shopid
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: employees
schema: public
type: create_update_permission

View File

@@ -0,0 +1,3 @@
- args:
sql: DROP TABLE "public"."allocations"
type: run_sql

View File

@@ -0,0 +1,22 @@
- args:
sql: CREATE EXTENSION IF NOT EXISTS pgcrypto;
type: run_sql
- args:
sql: "CREATE TABLE \"public\".\"allocations\"(\"id\" uuid NOT NULL DEFAULT gen_random_uuid(),
\"created_at\" timestamptz NOT NULL DEFAULT now(), \"updated_at\" timestamptz
NOT NULL DEFAULT now(), \"joblineid\" uuid NOT NULL, \"employeeid\" uuid NOT
NULL, \"hours\" numeric NOT NULL DEFAULT 0, PRIMARY KEY (\"id\") , FOREIGN KEY
(\"joblineid\") REFERENCES \"public\".\"joblines\"(\"id\") ON UPDATE cascade
ON DELETE cascade, FOREIGN KEY (\"employeeid\") REFERENCES \"public\".\"employees\"(\"id\")
ON UPDATE cascade ON DELETE cascade);\nCREATE OR REPLACE FUNCTION \"public\".\"set_current_timestamp_updated_at\"()\nRETURNS
TRIGGER AS $$\nDECLARE\n _new record;\nBEGIN\n _new := NEW;\n _new.\"updated_at\"
= NOW();\n RETURN _new;\nEND;\n$$ LANGUAGE plpgsql;\nCREATE TRIGGER \"set_public_allocations_updated_at\"\nBEFORE
UPDATE ON \"public\".\"allocations\"\nFOR EACH ROW\nEXECUTE PROCEDURE \"public\".\"set_current_timestamp_updated_at\"();\nCOMMENT
ON TRIGGER \"set_public_allocations_updated_at\" ON \"public\".\"allocations\"
\nIS 'trigger to set value of column \"updated_at\" to current timestamp on
row update';\n"
type: run_sql
- args:
name: allocations
schema: public
type: add_existing_table_or_view

View File

@@ -0,0 +1,24 @@
- args:
relationship: employee
table:
name: allocations
schema: public
type: drop_relationship
- args:
relationship: jobline
table:
name: allocations
schema: public
type: drop_relationship
- args:
relationship: allocations
table:
name: employees
schema: public
type: drop_relationship
- args:
relationship: allocations
table:
name: joblines
schema: public
type: drop_relationship

View File

@@ -0,0 +1,40 @@
- args:
name: employee
table:
name: allocations
schema: public
using:
foreign_key_constraint_on: employeeid
type: create_object_relationship
- args:
name: jobline
table:
name: allocations
schema: public
using:
foreign_key_constraint_on: joblineid
type: create_object_relationship
- args:
name: allocations
table:
name: employees
schema: public
using:
foreign_key_constraint_on:
column: employeeid
table:
name: allocations
schema: public
type: create_array_relationship
- args:
name: allocations
table:
name: joblines
schema: public
using:
foreign_key_constraint_on:
column: joblineid
table:
name: allocations
schema: public
type: create_array_relationship

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: allocations
schema: public
type: drop_insert_permission

View File

@@ -0,0 +1,30 @@
- args:
permission:
allow_upsert: true
check:
jobline:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- hours
- created_at
- updated_at
- employeeid
- id
- joblineid
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: allocations
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: allocations
schema: public
type: drop_select_permission

View File

@@ -0,0 +1,27 @@
- args:
permission:
allow_aggregations: false
columns:
- hours
- created_at
- updated_at
- employeeid
- id
- joblineid
filter:
jobline:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
limit: null
role: user
table:
name: allocations
schema: public
type: create_select_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: allocations
schema: public
type: drop_update_permission

View File

@@ -0,0 +1,29 @@
- args:
permission:
columns:
- hours
- created_at
- updated_at
- employeeid
- id
- joblineid
filter:
jobline:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: allocations
schema: public
type: create_update_permission

View File

@@ -0,0 +1,12 @@
- args:
role: user
table:
name: allocations
schema: public
type: drop_update_permission
- args:
role: user
table:
name: allocations
schema: public
type: create_update_permission

View File

@@ -0,0 +1,29 @@
- args:
role: user
table:
name: allocations
schema: public
type: drop_update_permission
- args:
permission:
columns: []
filter:
jobline:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
localPresets:
- key: ""
value: ""
set: {}
role: user
table:
name: allocations
schema: public
type: create_update_permission

View File

@@ -0,0 +1,6 @@
- args:
role: user
table:
name: allocations
schema: public
type: drop_delete_permission

View File

@@ -0,0 +1,18 @@
- args:
permission:
filter:
jobline:
job:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: allocations
schema: public
type: create_delete_permission

Some files were not shown because too many files have changed in this diff Show More