@@ -1,5 +1,35 @@
|
||||
**Required items**
|
||||
|
||||
|
||||
-Bodyshop Record
|
||||
-Counter Record - type: ronum
|
||||
..\*Include the statuses file in the format of:
|
||||
|
||||
```json
|
||||
"statuses": [
|
||||
"Open",
|
||||
"Scheduled",
|
||||
"Arrived",
|
||||
"Repair Plan",
|
||||
"Parts",
|
||||
"Body",
|
||||
"Prep",
|
||||
"Paint",
|
||||
"Reassembly",
|
||||
"Sublet",
|
||||
"Detail",
|
||||
"Completed",
|
||||
"Delivered",
|
||||
"Invoiced",
|
||||
"Exported"
|
||||
],
|
||||
"default_imported": "Open",
|
||||
"default_scheduled": "Scheduled",
|
||||
"default_arrived": "Arrived",
|
||||
"default_completed": "Completed",
|
||||
"default_delivered": "Delivered",
|
||||
"default_invoiced": "Invoiced",
|
||||
"default_exported": "Exported"
|
||||
}
|
||||
```
|
||||
|
||||
--\* Set the region for the shop.
|
||||
-Counter Record - type: ronum
|
||||
|
||||
@@ -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,439 @@
|
||||
<folder_node>
|
||||
<name>translation</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>appointments</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>actions</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>cancel</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>intake</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>
|
||||
<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>viewjob</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>canceling</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>saving</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>
|
||||
<concept_node>
|
||||
<name>arrivedon</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>cancelledappointment</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>nodateselected</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>priorappointments</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>scheduledfor</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>canceled</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>created</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>associations</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>actions</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>activate</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>shopname</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>
|
||||
<concept_node>
|
||||
<name>actions</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>bodyshop</name>
|
||||
<children>
|
||||
<folder_node>
|
||||
<name>errors</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>loading</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>documents</name>
|
||||
<children>
|
||||
@@ -667,6 +1100,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>changestatus</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>convert</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -730,6 +1184,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>schedule</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>
|
||||
@@ -1875,7 +2350,7 @@
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>pay_date</name>
|
||||
<name>ownr_ph1</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
@@ -1896,7 +2371,7 @@
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>phone1</name>
|
||||
<name>pay_date</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
<description></description>
|
||||
<comment></comment>
|
||||
@@ -2887,6 +3362,27 @@
|
||||
<folder_node>
|
||||
<name>labels</name>
|
||||
<children>
|
||||
<concept_node>
|
||||
<name>appointmentconfirmation</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>available_new_jobs</name>
|
||||
<definition_loaded>false</definition_loaded>
|
||||
@@ -3584,6 +4080,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>schedule</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>
|
||||
@@ -4407,6 +4924,27 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>schedule</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>
|
||||
@@ -4436,6 +4974,53 @@
|
||||
</translation>
|
||||
</translations>
|
||||
</concept_node>
|
||||
<concept_node>
|
||||
<name>updateprofile</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>displayname</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>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"node-sass": "^4.13.0",
|
||||
"react": "^16.12.0",
|
||||
"react-apollo": "^3.1.3",
|
||||
"react-big-calendar": "^0.23.0",
|
||||
"react-chartjs-2": "^2.8.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-i18next": "^11.2.7",
|
||||
|
||||
@@ -14,8 +14,6 @@ import SpinnerComponent from "../components/loading-spinner/loading-spinner.comp
|
||||
import errorLink from "../graphql/apollo-error-handling";
|
||||
import App from "./App";
|
||||
|
||||
|
||||
|
||||
class AppContainer extends Component {
|
||||
state = {
|
||||
client: null,
|
||||
|
||||
@@ -28,19 +28,19 @@ const mapDispatchToProps = dispatch => ({
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(({ checkUserSession, currentUser }) => {
|
||||
)(({ checkUserSession, currentUser, setBodyshop }) => {
|
||||
|
||||
useEffect(() => {
|
||||
checkUserSession();
|
||||
return () => {};
|
||||
}, [checkUserSession]);
|
||||
|
||||
if (false)
|
||||
i18next.changeLanguage("en_US", (err, t) => {
|
||||
if (currentUser && currentUser.language)
|
||||
i18next.changeLanguage(currentUser.language, (err, t) => {
|
||||
if (err)
|
||||
return console.log("Error encountered when changing languages.", err);
|
||||
});
|
||||
|
||||
console.log("currentUser", currentUser);
|
||||
if (currentUser.authorized === null) {
|
||||
//TODO: Translate this.
|
||||
return <LoadingSpinner message="Waiting for Current Auth to persist." />;
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
import React, { useState } from "react";
|
||||
import ChatWindowComponent from "./chat-window.component";
|
||||
import { Button } from "antd";
|
||||
import { Layout } from "antd";
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectCurrentUser } from "../../redux/user/user.selectors";
|
||||
import { toggleChatVisible } from "../../redux/messaging/messaging.actions";
|
||||
import { selectChatVisible } from "../../redux/messaging/messaging.selectors";
|
||||
import ChatWindowComponent from "./chat-window.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
chatVisible: selectChatVisible
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
// signOutStart: () => dispatch(signOutStart())
|
||||
toggleChatVisible: () => dispatch(toggleChatVisible())
|
||||
});
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(function ChatWindowContainer() {
|
||||
const [visible, setVisible] = useState(false);
|
||||
)(function ChatWindowContainer({ chatVisible, toggleChatVisible }) {
|
||||
return (
|
||||
<div>
|
||||
<Button onClick={() => setVisible(!visible)}>Drawer!</Button>
|
||||
<ChatWindowComponent
|
||||
mask={false}
|
||||
maskClosable={false}
|
||||
visible={visible}
|
||||
zIndex={0}
|
||||
/>
|
||||
</div>
|
||||
<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>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -29,6 +29,12 @@ export default ({ landingHeader, selectedNavItem }) => {
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
<Menu.SubMenu title={t("menus.header.jobs")}>
|
||||
<Menu.Item key="schedule">
|
||||
<Link to="/manage/schedule">
|
||||
<Icon type="calendar" />
|
||||
{t("menus.header.schedule")}
|
||||
</Link>
|
||||
</Menu.Item>
|
||||
<Menu.Item key="activejobs">
|
||||
<Link to="/manage/jobs">
|
||||
<Icon type="home" />
|
||||
|
||||
@@ -18,8 +18,6 @@ import JobDetailCardsPartsComponent from "./job-detail-cards.parts.component";
|
||||
import "./job-detail-cards.styles.scss";
|
||||
import JobDetailCardsTotalsComponent from "./job-detail-cards.totals.component";
|
||||
|
||||
|
||||
|
||||
export default function JobDetailCards({ selectedJob }) {
|
||||
const { loading, error, data, refetch } = useQuery(QUERY_JOB_CARD_DETAILS, {
|
||||
fetchPolicy: "network-only",
|
||||
@@ -33,10 +31,10 @@ export default function JobDetailCards({ selectedJob }) {
|
||||
return <div>{t("jobs.errors.nojobselected")}</div>;
|
||||
}
|
||||
if (loading) return <LoadingSpinner />;
|
||||
if (error) return <AlertComponent message={error.message} type='error' />;
|
||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||
|
||||
return (
|
||||
<div className='job-cards-container'>
|
||||
<div className="job-cards-container">
|
||||
<NoteUpsertModal
|
||||
jobId={data.jobs_by_pk.id}
|
||||
visible={noteModalVisible}
|
||||
@@ -47,9 +45,9 @@ export default function JobDetailCards({ selectedJob }) {
|
||||
ghost={false}
|
||||
onBack={() => window.history.back()}
|
||||
tags={
|
||||
<span key='job-status'>
|
||||
{data.jobs_by_pk.job_status ? (
|
||||
<Tag color='blue'>{data.jobs_by_pk.job_status.name}</Tag>
|
||||
<span key="job-status">
|
||||
{data.jobs_by_pk.status ? (
|
||||
<Tag color="blue">{data.jobs_by_pk.status}</Tag>
|
||||
) : null}
|
||||
</span>
|
||||
}
|
||||
@@ -68,31 +66,34 @@ export default function JobDetailCards({ selectedJob }) {
|
||||
}
|
||||
extra={[
|
||||
<Link
|
||||
key='documents'
|
||||
to={`/manage/jobs/${data.jobs_by_pk.id}#documents`}>
|
||||
key="documents"
|
||||
to={`/manage/jobs/${data.jobs_by_pk.id}#documents`}
|
||||
>
|
||||
<Button>
|
||||
<Icon type='file-image' />
|
||||
<Icon type="file-image" />
|
||||
{t("jobs.actions.addDocuments")}
|
||||
</Button>
|
||||
</Link>,
|
||||
<Button key='printing'>
|
||||
<Icon type='printer' />
|
||||
<Button key="printing">
|
||||
<Icon type="printer" />
|
||||
{t("jobs.actions.printCenter")}
|
||||
</Button>,
|
||||
<Button
|
||||
key='notes'
|
||||
actiontype='addNote'
|
||||
key="notes"
|
||||
actiontype="addNote"
|
||||
onClick={() => {
|
||||
setNoteModalVisible(!noteModalVisible);
|
||||
}}>
|
||||
<Icon type='edit' />
|
||||
}}
|
||||
>
|
||||
<Icon type="edit" />
|
||||
{t("jobs.actions.addNote")}
|
||||
</Button>,
|
||||
<Button key='postinvoices'>
|
||||
<Icon type='shopping-cart' />
|
||||
<Button key="postinvoices">
|
||||
<Icon type="shopping-cart" />
|
||||
{t("jobs.actions.postInvoices")}
|
||||
</Button>
|
||||
]}>
|
||||
]}
|
||||
>
|
||||
{
|
||||
// loading ? (
|
||||
// <LoadingSkeleton />
|
||||
@@ -113,7 +114,7 @@ export default function JobDetailCards({ selectedJob }) {
|
||||
// )
|
||||
}
|
||||
|
||||
<section className='job-cards'>
|
||||
<section className="job-cards">
|
||||
<JobDetailCardsCustomerComponent
|
||||
loading={loading}
|
||||
data={data ? data.jobs_by_pk : null}
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import {
|
||||
Avatar,
|
||||
Badge,
|
||||
Button,
|
||||
Checkbox,
|
||||
Descriptions,
|
||||
Dropdown,
|
||||
Icon,
|
||||
Menu,
|
||||
notification,
|
||||
PageHeader,
|
||||
Tag
|
||||
@@ -10,17 +14,31 @@ import {
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Moment from "react-moment";
|
||||
import { connect } from "react-redux";
|
||||
import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import CarImage from "../../assets/car.svg";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
|
||||
export default function JobsDetailHeader({
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop
|
||||
});
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
null
|
||||
)(function JobsDetailHeader({
|
||||
job,
|
||||
mutationConvertJob,
|
||||
refetch,
|
||||
handleSubmit
|
||||
handleSubmit,
|
||||
scheduleModalState,
|
||||
bodyshop,
|
||||
updateJobStatus
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const setscheduleModalVisible = scheduleModalState[1];
|
||||
|
||||
const tombstoneTitle = (
|
||||
<div>
|
||||
@@ -57,7 +75,34 @@ export default function JobsDetailHeader({
|
||||
</div>
|
||||
);
|
||||
|
||||
const statusmenu = (
|
||||
<Menu
|
||||
onClick={e => {
|
||||
updateJobStatus(e.key);
|
||||
}}
|
||||
>
|
||||
{bodyshop.md_ro_statuses.statuses.map(item => (
|
||||
<Menu.Item key={item}>{item}</Menu.Item>
|
||||
))}
|
||||
</Menu>
|
||||
);
|
||||
|
||||
const menuExtra = [
|
||||
<Dropdown overlay={statusmenu} key="changestatus">
|
||||
<Button>
|
||||
{t("jobs.actions.changestatus")} <Icon type="down" />
|
||||
</Button>
|
||||
</Dropdown>,
|
||||
<Badge key="schedule" count={job.appointments_aggregate.aggregate.count}>
|
||||
<Button
|
||||
//TODO: Enabled logic based on status.
|
||||
onClick={() => {
|
||||
setscheduleModalVisible(true);
|
||||
}}
|
||||
>
|
||||
{t("jobs.actions.schedule")}
|
||||
</Button>
|
||||
</Badge>,
|
||||
<Button
|
||||
key="convert"
|
||||
type="dashed"
|
||||
@@ -95,9 +140,7 @@ export default function JobsDetailHeader({
|
||||
subTitle={tombstoneSubtitle}
|
||||
tags={
|
||||
<span key="job-status">
|
||||
{job.job_status ? (
|
||||
<Tag color="blue">{job.job_status.name}</Tag>
|
||||
) : null}
|
||||
{job.status ? <Tag color="blue">{job.status}</Tag> : null}
|
||||
</span>
|
||||
}
|
||||
extra={menuExtra}
|
||||
@@ -127,4 +170,4 @@ export default function JobsDetailHeader({
|
||||
</Descriptions>
|
||||
</PageHeader>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Link } from "react-router-dom";
|
||||
import PhoneFormatter from "../../utils/PhoneFormatter";
|
||||
import { alphaSort } from "../../utils/sorters";
|
||||
import { withRouter } from "react-router-dom";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
|
||||
export default withRouter(function JobsList({
|
||||
loading,
|
||||
@@ -56,14 +57,12 @@ export default withRouter(function JobsList({
|
||||
</Link>
|
||||
) : (
|
||||
// t("jobs.errors.noowner")
|
||||
<span>
|
||||
{record.ownr_fn} {record.ownr_ln}
|
||||
</span>
|
||||
<span>{`${record.ownr_fn} ${record.ownr_ln}`}</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: t("jobs.fields.phone1"),
|
||||
title: t("jobs.fields.ownr_ph1"),
|
||||
dataIndex: "ownr_ph1",
|
||||
key: "ownr_ph1",
|
||||
width: "12%",
|
||||
@@ -95,7 +94,7 @@ export default withRouter(function JobsList({
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
|
||||
render: (text, record) => {
|
||||
return record.job_status?.name || t("general.labels.na");
|
||||
return record.status || t("general.labels.na");
|
||||
}
|
||||
},
|
||||
|
||||
@@ -154,13 +153,13 @@ export default withRouter(function JobsList({
|
||||
title: t("jobs.fields.clm_total"),
|
||||
dataIndex: "clm_total",
|
||||
key: "clm_total",
|
||||
width: "8%",
|
||||
width: "10%",
|
||||
sorter: (a, b) => a.clm_total - b.clm_total,
|
||||
sortOrder:
|
||||
state.sortedInfo.columnKey === "clm_total" && state.sortedInfo.order,
|
||||
render: (text, record) => {
|
||||
return record.clm_total ? (
|
||||
<span>{record.clm_total}</span>
|
||||
<CurrencyFormatter>{record.clm_total}</CurrencyFormatter>
|
||||
) : (
|
||||
t("general.labels.unknown")
|
||||
);
|
||||
|
||||
@@ -4,5 +4,5 @@ import "./loading-skeleton.styles.scss";
|
||||
import { Skeleton } from "antd";
|
||||
|
||||
export default function LoadingSkeleton(props) {
|
||||
return <Skeleton {...props} className='loading-skeleton' active />;
|
||||
return <Skeleton {...props} className="loading-skeleton" active />;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import ProfileMyComponent from "../profile-my/profile-my.component";
|
||||
import ProfileShopsContainer from "../profile-shops/profile-shops.container";
|
||||
|
||||
export default function ProfileContent({ sidebarSelection }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
switch (sidebarSelection.key) {
|
||||
case "profile":
|
||||
return <div>Profile stuff</div>;
|
||||
case "shop":
|
||||
return <div>Shop stuff</div>;
|
||||
return <ProfileMyComponent />;
|
||||
case "shops":
|
||||
return <ProfileShopsContainer />;
|
||||
default:
|
||||
return (
|
||||
<AlertComponent message={t("profile.errors.state")} type="error" />
|
||||
|
||||
74
client/src/components/profile-my/profile-my.component.jsx
Normal file
74
client/src/components/profile-my/profile-my.component.jsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectCurrentUser } from "../../redux/user/user.selectors";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import { Form, Input, notification, Button } from "antd";
|
||||
import { updateUserDetails } from "../../redux/user/user.actions";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
currentUser: selectCurrentUser
|
||||
});
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
updateUserDetails: userDetails => dispatch(updateUserDetails(userDetails))
|
||||
});
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(
|
||||
Form.create({ name: "ProfileMyComponentForm" })(function ProfileMyComponent({
|
||||
currentUser,
|
||||
form,
|
||||
updateUserDetails
|
||||
}) {
|
||||
const { isFieldsTouched, resetFields, getFieldDecorator } = form;
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
|
||||
form.validateFieldsAndScroll((err, values) => {
|
||||
if (err) {
|
||||
notification["error"]({
|
||||
message: t("jobs.errors.validationtitle"),
|
||||
description: t("jobs.errors.validation")
|
||||
});
|
||||
}
|
||||
if (!err) {
|
||||
console.log("values", values);
|
||||
updateUserDetails({ displayName: values.displayname });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
{isFieldsTouched() ? (
|
||||
//TODO: Appropriate Error
|
||||
<AlertComponent
|
||||
message={t("jobs.errors.validation")}
|
||||
onClick={() => resetFields()}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<Form onSubmit={handleSubmit} autoComplete={"no"}>
|
||||
<Form.Item label={t("user.fields.displayname")}>
|
||||
{getFieldDecorator("displayname", {
|
||||
initialValue: currentUser.displayName,
|
||||
rules: [{ required: true }]
|
||||
})(<Input name="displayname" />)}
|
||||
</Form.Item>
|
||||
<Button
|
||||
type="primary"
|
||||
key="submit"
|
||||
htmlType="submit"
|
||||
onClick={handleSubmit}
|
||||
>
|
||||
{t("user.actions.updateprofile")}
|
||||
</Button>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
);
|
||||
@@ -0,0 +1,52 @@
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Table, Button } from "antd";
|
||||
export default function ProfileShopsComponent({
|
||||
loading,
|
||||
data,
|
||||
updateActiveShop
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: t("associations.fields.shopname"),
|
||||
dataIndex: "shopname",
|
||||
key: "shopname",
|
||||
width: "25%",
|
||||
render: (text, record) => <span>{record.bodyshop.shopname}</span>
|
||||
},
|
||||
{
|
||||
title: t("associations.fields.active"),
|
||||
dataIndex: "active",
|
||||
key: "active",
|
||||
width: "25%",
|
||||
render: (text, record) => <span>{record.active ? "Yes" : "No"}</span>
|
||||
},
|
||||
{
|
||||
title: t("associations.labels.actions"),
|
||||
dataIndex: "actions",
|
||||
key: "actions",
|
||||
width: "25%",
|
||||
render: (text, record) => (
|
||||
<span>
|
||||
{record.active ? null : (
|
||||
<Button onClick={() => updateActiveShop(record.id)}>
|
||||
Activate
|
||||
</Button>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<Table
|
||||
loading={loading}
|
||||
size="small"
|
||||
columns={columns.map(item => ({ ...item }))}
|
||||
rowKey="id"
|
||||
dataSource={data}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from "react";
|
||||
import { useQuery, useMutation } from "react-apollo";
|
||||
import {
|
||||
QUERY_ALL_ASSOCIATIONS,
|
||||
UPDATE_ASSOCIATION
|
||||
} from "../../graphql/associations.queries";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import ProfileShopsComponent from "./profile-shops.component";
|
||||
|
||||
export default function ProfileShopsContainer() {
|
||||
const { loading, error, data, refetch } = useQuery(QUERY_ALL_ASSOCIATIONS);
|
||||
const [updateAssocation] = useMutation(UPDATE_ASSOCIATION);
|
||||
|
||||
const updateActiveShop = activeShopId => {
|
||||
data.associations.forEach(record => {
|
||||
updateAssocation({
|
||||
variables: {
|
||||
assocId: record.id,
|
||||
assocActive: record.id === activeShopId ? true : false
|
||||
}
|
||||
});
|
||||
});
|
||||
refetch();
|
||||
};
|
||||
|
||||
if (error) return <AlertComponent type="error" message={error.message} />;
|
||||
return (
|
||||
<ProfileShopsComponent
|
||||
loading={loading}
|
||||
data={data ? data.associations : null}
|
||||
updateActiveShop={updateActiveShop}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import moment from "moment";
|
||||
import React from "react";
|
||||
import { Calendar, momentLocalizer } from "react-big-calendar";
|
||||
import "react-big-calendar/lib/css/react-big-calendar.css";
|
||||
import DateCellWrapper from "../schedule-datecellwrapper/schedule-datecellwrapper.component";
|
||||
import Event from "../schedule-event/schedule-event.container";
|
||||
const localizer = momentLocalizer(moment);
|
||||
|
||||
export default function ScheduleCalendarWrapperComponent({
|
||||
data,
|
||||
refetch,
|
||||
defaultView,
|
||||
...otherProps
|
||||
}) {
|
||||
return (
|
||||
<Calendar
|
||||
events={data}
|
||||
defaultView={defaultView}
|
||||
step={30}
|
||||
showMultiDayTimes
|
||||
localizer={localizer}
|
||||
min={new Date("2020-01-01T06:00:00")} //TODO: Read from business settings.
|
||||
max={new Date("2020-01-01T20:00:00")}
|
||||
components={{
|
||||
event: e => {
|
||||
return Event({ event: e.event, refetch: refetch });
|
||||
},
|
||||
dateCellWrapper: DateCellWrapper
|
||||
}}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import React from "react";
|
||||
//import "react-big-calendar/lib/css/react-big-calendar.css";
|
||||
import ScheduleCalendarWrapperComponent from "../schedule-calendar-wrapper/scheduler-calendar-wrapper.component";
|
||||
|
||||
export default function ScheduleCalendarComponent({ data, refetch }) {
|
||||
return (
|
||||
<ScheduleCalendarWrapperComponent
|
||||
data={data}
|
||||
defaultView="week"
|
||||
refetch={refetch}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from "react";
|
||||
import { useQuery } from "react-apollo";
|
||||
import ScheduleCalendarComponent from "./schedule-calendar.component";
|
||||
import { QUERY_ALL_ACTIVE_APPOINTMENTS } from "../../graphql/appointments.queries";
|
||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
|
||||
export default function ScheduleCalendarContainer() {
|
||||
const { loading, error, data, refetch } = useQuery(
|
||||
QUERY_ALL_ACTIVE_APPOINTMENTS,
|
||||
{
|
||||
fetchPolicy: "network-only"
|
||||
}
|
||||
);
|
||||
|
||||
if (loading) return <LoadingSpinner />;
|
||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
||||
let normalizedData = data.appointments.map(e => {
|
||||
//Required becuase Hasura returns a string instead of a date object.
|
||||
return Object.assign(
|
||||
{},
|
||||
e,
|
||||
{ start: new Date(e.start) },
|
||||
{ end: new Date(e.end) }
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<ScheduleCalendarComponent
|
||||
refetch={refetch}
|
||||
data={data ? normalizedData : null}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import React from "react";
|
||||
|
||||
export default function ScheduleDateCellWrapper(dateCellWrapperProps) {
|
||||
// Show 'click me' text in arbitrary places by using the range prop
|
||||
|
||||
const style = {
|
||||
display: "flex",
|
||||
flex: 1,
|
||||
borderLeft: "1px solid #DDD",
|
||||
backgroundColor: "#fff"
|
||||
};
|
||||
return (
|
||||
<div style={style}>
|
||||
PLACEHOLDER:DATA
|
||||
{dateCellWrapperProps.children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from "react";
|
||||
import "react-big-calendar/lib/css/react-big-calendar.css";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ScheduleCalendarWrapperComponent from "../schedule-calendar-wrapper/scheduler-calendar-wrapper.component";
|
||||
|
||||
export default function ScheduleDayViewComponent({ data, day }) {
|
||||
const { t } = useTranslation();
|
||||
if (data)
|
||||
//TODO Remove addtional calendar elements from day view.
|
||||
return (
|
||||
<ScheduleCalendarWrapperComponent
|
||||
events={data}
|
||||
defaultView="day"
|
||||
style={{ height: "40vh" }}
|
||||
defaultDate={new Date(day)}
|
||||
//onNavigate={e => console.log("e", e)}
|
||||
/>
|
||||
);
|
||||
else return <div>{t("appointments.labels.nodateselected")}</div>;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import React from "react";
|
||||
import ScheduleDayViewComponent from "./schedule-day-view.component";
|
||||
import { useQuery } from "react-apollo";
|
||||
import { QUERY_APPOINTMENT_BY_DATE } from "../../graphql/appointments.queries";
|
||||
import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
|
||||
import moment from "moment";
|
||||
|
||||
export default function ScheduleDayViewContainer({ day }) {
|
||||
const { loading, error, data } = useQuery(QUERY_APPOINTMENT_BY_DATE, {
|
||||
variables: {
|
||||
start: moment(day).startOf("day"),
|
||||
end: moment(day).endOf("day")
|
||||
},
|
||||
skip: !day,
|
||||
fetchPolicy: "network-only"
|
||||
});
|
||||
|
||||
if (loading) return <LoadingSkeleton paragraph={{ rows: 4 }} />;
|
||||
if (error) return <div>{error.message}</div>;
|
||||
let normalizedData;
|
||||
if (data) {
|
||||
normalizedData = data.appointments.map(e => {
|
||||
//Required becuase Hasura returns a string instead of a date object.
|
||||
return Object.assign(
|
||||
{},
|
||||
e,
|
||||
{ start: new Date(e.start) },
|
||||
{ end: new Date(e.end) }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<ScheduleDayViewComponent data={data ? normalizedData : null} day={day} />
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import React from "react";
|
||||
import { Popover, Button } from "antd";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import PhoneFormatter from "../../utils/PhoneFormatter";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
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>
|
||||
<Button onClick={() => handleCancel(event.id)}>
|
||||
{t("appointments.actions.cancel")}
|
||||
</Button>
|
||||
<Button>
|
||||
{
|
||||
//TODO: Add reschedule Func.
|
||||
}
|
||||
{t("appointments.actions.reschedule")}
|
||||
</Button>
|
||||
<Button>
|
||||
{
|
||||
//TODO: Add intake func.
|
||||
}
|
||||
{t("appointments.actions.intake")}
|
||||
</Button>
|
||||
</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>
|
||||
</div>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from "react";
|
||||
import { useMutation } from "react-apollo";
|
||||
import { CANCEL_APPOINTMENT_BY_ID } from "../../graphql/appointments.queries";
|
||||
import ScheduleEventComponent from "./schedule-event.component";
|
||||
import { notification } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
export default function ScheduleEventContainer({ event, refetch }) {
|
||||
const { t } = useTranslation();
|
||||
const [cancelAppointment] = useMutation(CANCEL_APPOINTMENT_BY_ID);
|
||||
const handleCancel = id => {
|
||||
cancelAppointment({ variables: { appid: event.id } })
|
||||
.then(r => {
|
||||
notification["success"]({
|
||||
message: t("appointments.successes.canceled")
|
||||
});
|
||||
if (refetch) refetch();
|
||||
})
|
||||
.catch(error => {
|
||||
notification["error"]({ message: t("appointments.errors.canceling") });
|
||||
});
|
||||
};
|
||||
|
||||
return <ScheduleEventComponent event={event} handleCancel={handleCancel} />;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import React from "react";
|
||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import { Timeline } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
|
||||
export default function ScheduleExistingAppointmentsList({
|
||||
existingAppointments
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
if (existingAppointments.loading) return <LoadingSpinner />;
|
||||
if (existingAppointments.error)
|
||||
return (
|
||||
<AlertComponent
|
||||
message={existingAppointments.error.message}
|
||||
type="error"
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{t("appointments.labels.priorappointments")}
|
||||
<Timeline>
|
||||
{existingAppointments.data.appointments.map(item => {
|
||||
return (
|
||||
<Timeline.Item
|
||||
key={item.id}
|
||||
color={item.canceled ? "red" : item.arrived ? "green" : "blue"}
|
||||
>
|
||||
{item.canceled
|
||||
? t("appointments.labels.cancelledappointment")
|
||||
: item.arrived
|
||||
? t("appointments.labels.arrivedon")
|
||||
: t("appointments.labels.scheduledfor")}
|
||||
|
||||
<DateTimeFormatter>{item.start}</DateTimeFormatter>
|
||||
</Timeline.Item>
|
||||
);
|
||||
})}
|
||||
</Timeline>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import { Checkbox, Col, DatePicker, Modal, Row, Tabs, TimePicker } from "antd";
|
||||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import ScheduleDayViewContainer from "../schedule-day-view/schedule-day-view.container";
|
||||
import ScheduleExistingAppointmentsList from "../schedule-existing-appointments-list/schedule-existing-appointments-list.component";
|
||||
|
||||
export default function ScheduleJobModalComponent({
|
||||
existingAppointments,
|
||||
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}>
|
||||
<Tabs defaultActiveKey="1">
|
||||
<Tabs.TabPane tab="SMART Scheduling" key="auto">
|
||||
Automatic Job Selection.
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane tab="Manual Scheduling" key="manual">
|
||||
<Row>
|
||||
Manual Job Selection Scheduled Time
|
||||
<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>
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
<ScheduleExistingAppointmentsList
|
||||
existingAppointments={existingAppointments}
|
||||
/>
|
||||
{
|
||||
//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>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
import React, { useState } from "react";
|
||||
import ScheduleJobModalComponent from "./schedule-job-modal.component";
|
||||
import { useMutation, useQuery } from "react-apollo";
|
||||
import {
|
||||
INSERT_APPOINTMENT,
|
||||
QUERY_APPOINTMENTS_BY_JOBID
|
||||
} from "../../graphql/appointments.queries";
|
||||
import moment from "moment";
|
||||
import { notification } from "antd";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { UPDATE_JOB_STATUS } from "../../graphql/jobs.queries";
|
||||
|
||||
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 ScheduleJobModalContainer({
|
||||
scheduleModalState,
|
||||
jobId,
|
||||
bodyshop,
|
||||
refetch
|
||||
}) {
|
||||
const existingAppointments = useQuery(QUERY_APPOINTMENTS_BY_JOBID, {
|
||||
variables: { jobid: jobId },
|
||||
fetchPolicy: "network-only",
|
||||
skip: !jobId
|
||||
});
|
||||
const [scheduleModalVisible, setscheduleModalVisible] = scheduleModalState;
|
||||
const [appData, setAppData] = useState({ jobid: jobId, start: null });
|
||||
const [insertAppointment] = useMutation(INSERT_APPOINTMENT);
|
||||
const [updateJobStatus] = useMutation(UPDATE_JOB_STATUS, {
|
||||
variables: {
|
||||
jobId: jobId,
|
||||
status: bodyshop.md_ro_statuses.default_scheduled
|
||||
}
|
||||
});
|
||||
const [formData, setFormData] = useState({ notifyCustomer: false });
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<ScheduleJobModalComponent
|
||||
existingAppointments={existingAppointments}
|
||||
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 => {
|
||||
updateJobStatus().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
|
||||
})
|
||||
});
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@@ -34,6 +34,7 @@ export const createUserProfileDocument = async (userAuth, additionalData) => {
|
||||
};
|
||||
|
||||
export const auth = firebase.auth();
|
||||
|
||||
export const firestore = firebase.firestore();
|
||||
|
||||
const provider = new firebase.auth.GoogleAuthProvider();
|
||||
@@ -49,3 +50,15 @@ export const getCurrentUser = () => {
|
||||
}, reject);
|
||||
});
|
||||
};
|
||||
|
||||
export const updateCurrentUser = userDetails => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const unsubscribe = auth.onAuthStateChanged(userAuth => {
|
||||
console.log("userDetails", userDetails);
|
||||
userAuth.updateProfile(userDetails).then(r => {
|
||||
unsubscribe();
|
||||
resolve(userAuth);
|
||||
});
|
||||
}, reject);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -42,8 +42,9 @@ const errorLink = onError(
|
||||
authorization: token ? `Bearer ${token}` : ""
|
||||
}
|
||||
});
|
||||
|
||||
return forward(operation);
|
||||
console.log("forward", forward);
|
||||
console.log("operation", operation);
|
||||
return forward(operation).subscribe();
|
||||
|
||||
// return new Observable(observer => {
|
||||
// const subscriber = {
|
||||
|
||||
89
client/src/graphql/appointments.queries.js
Normal file
89
client/src/graphql/appointments.queries.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import { gql } from "apollo-boost";
|
||||
|
||||
export const QUERY_ALL_ACTIVE_APPOINTMENTS = gql`
|
||||
query QUERY_ALL_ACTIVE_APPOINTMENTS {
|
||||
appointments(where: { canceled: { _eq: false } }) {
|
||||
start
|
||||
id
|
||||
end
|
||||
job {
|
||||
ro_number
|
||||
ownr_ln
|
||||
ownr_fn
|
||||
ownr_ph1
|
||||
ownr_ea
|
||||
clm_total
|
||||
id
|
||||
clm_no
|
||||
vehicle {
|
||||
id
|
||||
v_model_yr
|
||||
v_make_desc
|
||||
v_model_desc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const INSERT_APPOINTMENT = gql`
|
||||
mutation INSERT_APPOINTMENT($app: [appointments_insert_input!]!) {
|
||||
insert_appointments(objects: $app) {
|
||||
returning {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const QUERY_APPOINTMENT_BY_DATE = gql`
|
||||
query QUERY_APPOINTMENT_BY_DATE($start: timestamptz, $end: timestamptz) {
|
||||
appointments(where: { start: { _lte: $end, _gte: $start } }) {
|
||||
start
|
||||
id
|
||||
end
|
||||
job {
|
||||
ro_number
|
||||
ownr_ln
|
||||
ownr_fn
|
||||
ownr_ph1
|
||||
ownr_ea
|
||||
clm_total
|
||||
id
|
||||
clm_no
|
||||
vehicle {
|
||||
id
|
||||
v_model_yr
|
||||
v_make_desc
|
||||
v_model_desc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const CANCEL_APPOINTMENT_BY_ID = gql`
|
||||
mutation CANCEL_APPOINTMENT_BY_ID($appid: uuid!) {
|
||||
update_appointments(
|
||||
where: { id: { _eq: $appid } }
|
||||
_set: { canceled: true }
|
||||
) {
|
||||
returning {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const QUERY_APPOINTMENTS_BY_JOBID = gql`
|
||||
query QUERY_APPOINTMENTS_BY_JOBID($jobid: uuid!) {
|
||||
appointments(where: { jobid: { _eq: $jobid } }) {
|
||||
start
|
||||
id
|
||||
end
|
||||
arrived
|
||||
canceled
|
||||
created_at
|
||||
}
|
||||
}
|
||||
`;
|
||||
27
client/src/graphql/associations.queries.js
Normal file
27
client/src/graphql/associations.queries.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import { gql } from "apollo-boost";
|
||||
|
||||
export const QUERY_ALL_ASSOCIATIONS = gql`
|
||||
query QUERY_ALL_ASSOCIATIONS {
|
||||
associations {
|
||||
id
|
||||
active
|
||||
bodyshop {
|
||||
shopname
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const UPDATE_ASSOCIATION = gql`
|
||||
mutation UPDATE_ASSOCIATION($assocId: uuid, $assocActive: Boolean) {
|
||||
update_associations(
|
||||
where: { id: { _eq: $assocId } }
|
||||
_set: { active: $assocActive }
|
||||
) {
|
||||
returning {
|
||||
id
|
||||
active
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -19,6 +19,7 @@ export const QUERY_BODYSHOP = gql`
|
||||
state_tax_id
|
||||
updated_at
|
||||
zip_post
|
||||
region_config
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -42,12 +42,9 @@ export const QUERY_ALL_OPEN_JOBS = gql`
|
||||
scheduled_completion
|
||||
scheduled_in
|
||||
scheduled_delivery
|
||||
job_status {
|
||||
id
|
||||
name
|
||||
}
|
||||
status
|
||||
updated_at
|
||||
claim_total
|
||||
clm_total
|
||||
ded_amt
|
||||
vehicle {
|
||||
id
|
||||
@@ -195,7 +192,7 @@ export const GET_JOB_BY_PK = gql`
|
||||
date_invoiced
|
||||
date_closed
|
||||
date_exported
|
||||
|
||||
status
|
||||
joblines {
|
||||
id
|
||||
unq_seq
|
||||
@@ -213,6 +210,11 @@ export const GET_JOB_BY_PK = gql`
|
||||
lbr_amt
|
||||
op_code_desc
|
||||
}
|
||||
appointments_aggregate {
|
||||
aggregate {
|
||||
count
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -253,6 +255,7 @@ export const QUERY_JOB_CARD_DETAILS = gql`
|
||||
est_ct_fn
|
||||
est_ct_ln
|
||||
clm_no
|
||||
status
|
||||
ro_number
|
||||
scheduled_completion
|
||||
scheduled_in
|
||||
@@ -264,12 +267,9 @@ export const QUERY_JOB_CARD_DETAILS = gql`
|
||||
private
|
||||
created_at
|
||||
}
|
||||
job_status {
|
||||
id
|
||||
name
|
||||
}
|
||||
|
||||
updated_at
|
||||
claim_total
|
||||
clm_total
|
||||
ded_amt
|
||||
documents(limit: 3, order_by: { created_at: desc }) {
|
||||
id
|
||||
@@ -321,3 +321,13 @@ export const INSERT_NEW_JOB = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const UPDATE_JOB_STATUS = gql`
|
||||
mutation UPDATE_JOB_STATUS($jobId: uuid!, $status: String!) {
|
||||
update_jobs(where: { id: { _eq: $jobId } }, _set: { status: $status }) {
|
||||
returning {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -16,13 +16,16 @@ import JobsDocumentsContainer from "../../components/jobs-documents/jobs-documen
|
||||
import JobNotesContainer from "../../components/jobs-notes/jobs-notes.container";
|
||||
import JobDetailFormContext from "./jobs-detail.page.context";
|
||||
import JobsDetailDatesComponent from "../../components/jobs-detail-dates/jobs-detail-dates.component";
|
||||
import ScheduleJobModalContainer from "../../components/schedule-job-modal/schedule-job-modal.container";
|
||||
|
||||
export default function JobsDetailPage({
|
||||
job,
|
||||
mutationUpdateJob,
|
||||
mutationConvertJob,
|
||||
handleSubmit,
|
||||
refetch
|
||||
refetch,
|
||||
scheduleModalState,
|
||||
updateJobStatus
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -41,12 +44,20 @@ export default function JobsDetailPage({
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ScheduleJobModalContainer
|
||||
scheduleModalState={scheduleModalState}
|
||||
jobId={job.id}
|
||||
refetch={refetch}
|
||||
/>
|
||||
|
||||
<Form onSubmit={handleSubmit} {...formItemLayout} autoComplete={"off"}>
|
||||
<JobsDetailHeader
|
||||
job={job}
|
||||
mutationConvertJob={mutationConvertJob}
|
||||
refetch={refetch}
|
||||
handleSubmit={handleSubmit}
|
||||
scheduleModalState={scheduleModalState}
|
||||
updateJobStatus={updateJobStatus}
|
||||
/>
|
||||
|
||||
{isFieldsTouched() ? (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Form, notification } from "antd";
|
||||
import React, { useEffect } from "react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useMutation, useQuery } from "react-apollo";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import AlertComponent from "../../components/alert/alert.component";
|
||||
@@ -7,7 +7,8 @@ import SpinComponent from "../../components/loading-spinner/loading-spinner.comp
|
||||
import {
|
||||
CONVERT_JOB_TO_RO,
|
||||
GET_JOB_BY_PK,
|
||||
UPDATE_JOB
|
||||
UPDATE_JOB,
|
||||
UPDATE_JOB_STATUS
|
||||
} from "../../graphql/jobs.queries";
|
||||
import JobsDetailPage from "./jobs-detail.page.component";
|
||||
import JobDetailFormContext from "./jobs-detail.page.context";
|
||||
@@ -16,12 +17,29 @@ function JobsDetailPageContainer({ match, form }) {
|
||||
const { jobId } = match.params;
|
||||
const { t } = useTranslation();
|
||||
|
||||
const scheduleModalState = useState(false);
|
||||
|
||||
const { loading, error, data, refetch } = useQuery(GET_JOB_BY_PK, {
|
||||
variables: { id: jobId },
|
||||
fetchPolicy: "network-only"
|
||||
});
|
||||
const [mutationUpdateJob] = useMutation(UPDATE_JOB);
|
||||
const [mutationConvertJob] = useMutation(CONVERT_JOB_TO_RO);
|
||||
const [mutationUpdateJobstatus] = useMutation(UPDATE_JOB_STATUS);
|
||||
|
||||
const updateJobStatus = status => {
|
||||
mutationUpdateJobstatus({
|
||||
variables: { jobId: jobId, status: status }
|
||||
})
|
||||
.then(r => {
|
||||
notification["success"]({ message: t("jobs.successes.save") });
|
||||
refetch();
|
||||
})
|
||||
.catch(error => {
|
||||
//TODO Error handling.
|
||||
console.log("error", error);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
document.title = loading
|
||||
@@ -71,6 +89,8 @@ function JobsDetailPageContainer({ match, form }) {
|
||||
handleSubmit={handleSubmit}
|
||||
getFieldDecorator={form.getFieldDecorator}
|
||||
refetch={refetch}
|
||||
scheduleModalState={scheduleModalState}
|
||||
updateJobStatus={updateJobStatus}
|
||||
/>
|
||||
</JobDetailFormContext.Provider>
|
||||
) : (
|
||||
|
||||
@@ -1,16 +1,21 @@
|
||||
import { BackTop, Layout } from "antd";
|
||||
import { BackTop, Layout, notification } from "antd";
|
||||
import React, { lazy, Suspense, useEffect } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
//This page will handle all routing for the entire application.
|
||||
import { connect } from "react-redux";
|
||||
import { Route } from "react-router";
|
||||
import ChatWindowContainer from "../../components/chat-window/chat-window.container";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { useQuery } from "react-apollo";
|
||||
import { QUERY_BODYSHOP } from "../../graphql/bodyshop.queries";
|
||||
import ErrorBoundary from "../../components/error-boundary/error-boundary.component";
|
||||
import FooterComponent from "../../components/footer/footer.component";
|
||||
//Component Imports
|
||||
import HeaderContainer from "../../components/header/header.container";
|
||||
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
|
||||
//const WhiteBoardPage = lazy(() => import("../white-board/white-board.page"));
|
||||
import { setBodyshop } from "../../redux/user/user.actions";
|
||||
import "./manage.page.styles.scss";
|
||||
|
||||
//const WhiteBoardPage = lazy(() => import("../white-board/white-board.page"));
|
||||
const ManageRootPage = lazy(() =>
|
||||
import("../manage-root/manage-root.page.container")
|
||||
);
|
||||
@@ -25,12 +30,35 @@ const JobsDocumentsPage = lazy(() =>
|
||||
const JobsAvailablePage = lazy(() =>
|
||||
import("../jobs-available/jobs-available.page.container")
|
||||
);
|
||||
const ChatWindowContainer = lazy(() =>
|
||||
import("../../components/chat-window/chat-window.container")
|
||||
);
|
||||
const ScheduleContainer = lazy(() =>
|
||||
import("../schedule/schedule.page.container")
|
||||
);
|
||||
|
||||
const { Header, Content, Footer, Sider } = Layout;
|
||||
//This page will handle all routing for the entire application.
|
||||
export default function Manage({ match }) {
|
||||
const { Header, Content, Footer } = Layout;
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
setBodyshop: bs => dispatch(setBodyshop(bs))
|
||||
});
|
||||
export default connect(
|
||||
null,
|
||||
mapDispatchToProps
|
||||
)(function Manage({ match, setBodyshop }) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { error, data } = useQuery(QUERY_BODYSHOP, {
|
||||
fetchPolicy: "network-only"
|
||||
});
|
||||
|
||||
if (error) {
|
||||
notification["error"]({ message: t("bodyshop.errors.loading") });
|
||||
}
|
||||
if (data) {
|
||||
setBodyshop(data.bodyshops[0]);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
document.title = t("titles.app");
|
||||
}, [t]);
|
||||
@@ -41,17 +69,9 @@ export default function Manage({ match }) {
|
||||
<HeaderContainer />
|
||||
</Header>
|
||||
<Layout>
|
||||
<Sider
|
||||
collapsible
|
||||
defaultCollapsed
|
||||
theme="light"
|
||||
collapsedWidth={0}
|
||||
width={300}
|
||||
>
|
||||
<chatWindowContainer />
|
||||
</Sider>
|
||||
<ChatWindowContainer />
|
||||
|
||||
<Content className="content-container" style={{ margin: "50px" }}>
|
||||
<Content className="content-container" style={{ margin: "0px" }}>
|
||||
<ErrorBoundary>
|
||||
<Suspense
|
||||
fallback={
|
||||
@@ -78,6 +98,12 @@ export default function Manage({ match }) {
|
||||
component={ProfilePage}
|
||||
/>
|
||||
|
||||
<Route
|
||||
exact
|
||||
path={`${match.path}/schedule`}
|
||||
component={ScheduleContainer}
|
||||
/>
|
||||
|
||||
<Route
|
||||
exact
|
||||
path={`${match.path}/available`}
|
||||
@@ -93,4 +119,4 @@ export default function Manage({ match }) {
|
||||
<BackTop />
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
6
client/src/pages/schedule/schedule.page.component.jsx
Normal file
6
client/src/pages/schedule/schedule.page.component.jsx
Normal file
@@ -0,0 +1,6 @@
|
||||
import React from "react";
|
||||
import ScheduleCalendarContainer from "../../components/schedule-calendar/schedule-calendar.container";
|
||||
|
||||
export default function SchedulePageComponent() {
|
||||
return <ScheduleCalendarContainer />;
|
||||
}
|
||||
12
client/src/pages/schedule/schedule.page.container.jsx
Normal file
12
client/src/pages/schedule/schedule.page.container.jsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React, { useEffect } from "react";
|
||||
import SchedulePageComponent from "./schedule.page.component";
|
||||
import { useTranslation } from "react-i18next";
|
||||
export default function SchedulePageContainer() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
document.title = t("titles.schedule");
|
||||
}, [t]);
|
||||
|
||||
return <SchedulePageComponent />;
|
||||
}
|
||||
7
client/src/redux/messaging/messaging.actions.js
Normal file
7
client/src/redux/messaging/messaging.actions.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import MessagingActionTypes from './messaging.types'
|
||||
|
||||
export const toggleChatVisible = () => ({
|
||||
type: MessagingActionTypes.TOGGLE_CHAT_VISIBLE,
|
||||
//payload: user
|
||||
});
|
||||
|
||||
24
client/src/redux/messaging/messaging.reducer.js
Normal file
24
client/src/redux/messaging/messaging.reducer.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import MessagingActionTypes from "./messaging.types";
|
||||
|
||||
const INITIAL_STATE = {
|
||||
visible: false
|
||||
};
|
||||
|
||||
const messagingReducer = (state = INITIAL_STATE, action) => {
|
||||
switch (action.type) {
|
||||
case MessagingActionTypes.TOGGLE_CHAT_VISIBLE:
|
||||
return {
|
||||
...state,
|
||||
visible: !state.visible
|
||||
};
|
||||
case MessagingActionTypes.SET_CHAT_VISIBLE:
|
||||
return {
|
||||
...state,
|
||||
visible: true
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default messagingReducer;
|
||||
90
client/src/redux/messaging/messaging.sagas.js
Normal file
90
client/src/redux/messaging/messaging.sagas.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import {
|
||||
all
|
||||
// call, put, takeLatest
|
||||
} from "redux-saga/effects";
|
||||
//import { auth, getCurrentUser } from "../../firebase/firebase.utils";
|
||||
|
||||
// import { toggleChatVisible } from "./messaging.actions";
|
||||
// import MessagingActionTypes from "./messaging.types";
|
||||
|
||||
// export function* getSnapshotFromUserAuth(userAuth) {
|
||||
// try {
|
||||
// const userRef = yield call(createUserProfileDocument, userAuth);
|
||||
// //const userSnapshot = yield userRef.get();
|
||||
// } catch (error) {
|
||||
// yield put(signInFailure(error));
|
||||
// }
|
||||
// }
|
||||
|
||||
// export function* signInWithEmail({ payload: { email, password } }) {
|
||||
// try {
|
||||
// const { user } = yield auth.signInWithEmailAndPassword(email, password);
|
||||
// yield put(
|
||||
// signInSuccess({
|
||||
// uid: user.uid,
|
||||
// email: user.email,
|
||||
// displayName: user.displayName,
|
||||
// authorized: true
|
||||
// })
|
||||
// );
|
||||
// } catch (error) {
|
||||
// yield put(signInFailure(error));
|
||||
// }
|
||||
// }
|
||||
// //This is the listener fo rthe call, and when it finds it, it triggers somethign else.
|
||||
// export function* onEmailSignInStart() {
|
||||
// yield takeLatest(UserActionTypes.EMAIL_SIGN_IN_START, signInWithEmail);
|
||||
// }
|
||||
|
||||
// export function* isUserAuthenticated() {
|
||||
// try {
|
||||
// const user = yield getCurrentUser();
|
||||
// if (!user) {
|
||||
// yield put(unauthorizedUser());
|
||||
// return;
|
||||
// }
|
||||
// let token = yield user.getIdToken();
|
||||
// localStorage.setItem("token", token);
|
||||
// window.sessionStorage.setItem(`lastTokenRefreshTime`, new Date());
|
||||
|
||||
// yield put(
|
||||
// signInSuccess({
|
||||
// uid: user.uid,
|
||||
// email: user.email,
|
||||
// displayName: user.displayName,
|
||||
// authorized: true
|
||||
// })
|
||||
// );
|
||||
// } catch (error) {
|
||||
// yield put(signInFailure(error));
|
||||
// }
|
||||
// }
|
||||
|
||||
// export function* onCheckUserSession() {
|
||||
// yield takeLatest(UserActionTypes.CHECK_USER_SESSION, isUserAuthenticated);
|
||||
// }
|
||||
|
||||
// export function* signOutStart() {
|
||||
// try {
|
||||
// yield auth.signOut();
|
||||
// yield put(signOutSuccess());
|
||||
// localStorage.removeItem("token");
|
||||
// } catch (error) {
|
||||
// yield put(signOutFailure(error.message));
|
||||
// }
|
||||
// }
|
||||
|
||||
// export function* onSignOutStart() {
|
||||
// yield takeLatest(UserActionTypes.SIGN_OUT_START, signOutStart);
|
||||
// }
|
||||
|
||||
export function* messagingSagas() {
|
||||
yield all([
|
||||
// call(onGoogleSignInStart),
|
||||
// call(onEmailSignInStart),
|
||||
// call(onCheckUserSession),
|
||||
// call(onSignOutStart)
|
||||
// call(onEmailSignUpStart),
|
||||
// call(onEmailSignUpSuccess)
|
||||
]);
|
||||
}
|
||||
8
client/src/redux/messaging/messaging.selectors.js
Normal file
8
client/src/redux/messaging/messaging.selectors.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import { createSelector } from "reselect";
|
||||
|
||||
const selectMessaging = state => state.messaging;
|
||||
|
||||
export const selectChatVisible = createSelector(
|
||||
[selectMessaging],
|
||||
messaging => messaging.visible
|
||||
);
|
||||
5
client/src/redux/messaging/messaging.types.js
Normal file
5
client/src/redux/messaging/messaging.types.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const MessagingActionTypes = {
|
||||
TOGGLE_CHAT_VISIBLE: "TOGGLE_CHAT_VISIBLE",
|
||||
SET_CHAT_VISIBLE: "SET_CHAT_VISIBLE"
|
||||
};
|
||||
export default MessagingActionTypes;
|
||||
@@ -3,6 +3,7 @@ import { persistReducer } from "redux-persist";
|
||||
import storage from "redux-persist/lib/storage";
|
||||
|
||||
import userReducer from "./user/user.reducer";
|
||||
import messagingReducer from "./messaging/messaging.reducer";
|
||||
// import cartReducer from './cart/cart.reducer';
|
||||
// import directoryReducer from './directory/directory.reducer';
|
||||
// import shopReducer from './shop/shop.reducer';
|
||||
@@ -15,7 +16,8 @@ const persistConfig = {
|
||||
};
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
user: userReducer
|
||||
user: userReducer,
|
||||
messaging: messagingReducer
|
||||
// cart: cartReducer,
|
||||
// directory: directoryReducer,
|
||||
// shop: shopReducer
|
||||
|
||||
@@ -3,9 +3,10 @@ import { all, call } from "redux-saga/effects";
|
||||
//List of all Sagas
|
||||
// import { shopSagas } from "./shop/shop.sagas";
|
||||
import { userSagas } from "./user/user.sagas";
|
||||
import { messagingSagas } from "./messaging/messaging.sagas";
|
||||
//import { cartSagas } from "./cart/cart.sagas";
|
||||
|
||||
export default function* rootSaga() {
|
||||
//All starts all the Sagas concurrently.
|
||||
yield all([call(userSagas)]);
|
||||
yield all([call(userSagas), call(messagingSagas)]);
|
||||
}
|
||||
|
||||
@@ -38,3 +38,18 @@ export const setUserLanguage = language => ({
|
||||
type: UserActionTypes.SET_USER_LANGUAGE,
|
||||
payload: language
|
||||
});
|
||||
|
||||
export const updateUserDetails = userDetails => ({
|
||||
type: UserActionTypes.UPDATE_USER_DETAILS,
|
||||
payload: userDetails
|
||||
});
|
||||
|
||||
export const updateUserDetailsSuccess = userDetails => ({
|
||||
type: UserActionTypes.UPDATE_USER_DETAILS_SUCCESS,
|
||||
payload: userDetails
|
||||
});
|
||||
|
||||
export const setBodyshop = bodyshop => ({
|
||||
type: UserActionTypes.SET_SHOP_DETAILS,
|
||||
payload: bodyshop
|
||||
});
|
||||
|
||||
@@ -3,8 +3,9 @@ import UserActionTypes from "./user.types";
|
||||
const INITIAL_STATE = {
|
||||
currentUser: {
|
||||
authorized: null,
|
||||
language: "en_US"
|
||||
language: "en_us"
|
||||
},
|
||||
bodyshop: null,
|
||||
error: null
|
||||
};
|
||||
|
||||
@@ -33,10 +34,20 @@ const userReducer = (state = INITIAL_STATE, action) => {
|
||||
...state,
|
||||
language: action.payload
|
||||
};
|
||||
case UserActionTypes.UPDATE_USER_DETAILS_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
currentUser: {
|
||||
...state.currentUser,
|
||||
...action.payload //Spread current user details in.
|
||||
}
|
||||
};
|
||||
|
||||
case UserActionTypes.SET_SHOP_DETAILS:
|
||||
return { ...state, bodyshop: action.payload };
|
||||
case UserActionTypes.SIGN_IN_FAILURE:
|
||||
case UserActionTypes.SIGN_OUT_FAILURE:
|
||||
case UserActionTypes.EMAIL_SIGN_UP_FAILURE:
|
||||
console.log("Reduced getting called.");
|
||||
return {
|
||||
...state,
|
||||
error: action.payload
|
||||
|
||||
@@ -1,6 +1,17 @@
|
||||
import { all, call, put, takeLatest } from "redux-saga/effects";
|
||||
import { auth, getCurrentUser } from "../../firebase/firebase.utils";
|
||||
import { signInFailure, signInSuccess, signOutFailure, signOutSuccess, unauthorizedUser } from "./user.actions";
|
||||
import {
|
||||
auth,
|
||||
getCurrentUser,
|
||||
updateCurrentUser
|
||||
} from "../../firebase/firebase.utils";
|
||||
import {
|
||||
signInFailure,
|
||||
signInSuccess,
|
||||
signOutFailure,
|
||||
signOutSuccess,
|
||||
unauthorizedUser,
|
||||
updateUserDetailsSuccess
|
||||
} from "./user.actions";
|
||||
import UserActionTypes from "./user.types";
|
||||
|
||||
// export function* getSnapshotFromUserAuth(userAuth) {
|
||||
@@ -15,6 +26,9 @@ import UserActionTypes from "./user.types";
|
||||
export function* signInWithEmail({ payload: { email, password } }) {
|
||||
try {
|
||||
const { user } = yield auth.signInWithEmailAndPassword(email, password);
|
||||
let token = yield user.getIdToken();
|
||||
localStorage.setItem("token", token);
|
||||
window.sessionStorage.setItem(`lastTokenRefreshTime`, new Date());
|
||||
yield put(
|
||||
signInSuccess({
|
||||
uid: user.uid,
|
||||
@@ -74,14 +88,24 @@ export function* onSignOutStart() {
|
||||
yield takeLatest(UserActionTypes.SIGN_OUT_START, signOutStart);
|
||||
}
|
||||
|
||||
export function* onUpdateUserDetails() {
|
||||
yield takeLatest(UserActionTypes.UPDATE_USER_DETAILS, updateUserDetails);
|
||||
}
|
||||
export function* updateUserDetails(userDetails) {
|
||||
try {
|
||||
yield updateCurrentUser(userDetails.payload);
|
||||
yield put(updateUserDetailsSuccess(userDetails.payload));
|
||||
} catch (error) {
|
||||
//yield put(signOutFailure(error.message));
|
||||
//TODO: error handling
|
||||
}
|
||||
}
|
||||
|
||||
export function* userSagas() {
|
||||
yield all([
|
||||
// call(onGoogleSignInStart),
|
||||
call(onEmailSignInStart),
|
||||
call(onCheckUserSession),
|
||||
call(onSignOutStart),
|
||||
// call(onEmailSignUpStart),
|
||||
// call(onEmailSignUpSuccess)
|
||||
call(onUpdateUserDetails)
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -11,3 +11,8 @@ export const selectSignInError = createSelector(
|
||||
[selectUser],
|
||||
user => user.error
|
||||
);
|
||||
|
||||
export const selectBodyshop = createSelector(
|
||||
[selectUser],
|
||||
user => user.bodyshop
|
||||
);
|
||||
|
||||
@@ -12,6 +12,9 @@ const UserActionTypes = {
|
||||
EMAIL_SIGN_UP_SUCCESS: "EMAIL_SIGN_UP_SUCCESS",
|
||||
EMAIL_SIGN_UP_FAILURE: "EMAIL_SIGN_UP_FAILURE",
|
||||
UNAUTHORIZED_USER: "UNAUTHORIZED_USER",
|
||||
SET_USER_LANGUAGE: "SET_USER_LANGUAGE"
|
||||
SET_USER_LANGUAGE: "SET_USER_LANGUAGE",
|
||||
UPDATE_USER_DETAILS: "UPDATE_USER_DETAILS",
|
||||
UPDATE_USER_DETAILS_SUCCESS: "UPDATE_USER_DETAILS_SUCCESS",
|
||||
SET_SHOP_DETAILS: "SET_SHOP_DETAILS"
|
||||
};
|
||||
export default UserActionTypes;
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
{
|
||||
"translation": {
|
||||
"appointments": {
|
||||
"actions": {
|
||||
"cancel": "Cancel",
|
||||
"intake": "Intake",
|
||||
"reschedule": "Reschedule",
|
||||
"viewjob": "View Job"
|
||||
},
|
||||
"errors": {
|
||||
"canceling": "Error canceling appointment.",
|
||||
"saving": "Error scheduling appointment. {{message}}"
|
||||
},
|
||||
"labels": {
|
||||
"arrivedon": "Arrived on: ",
|
||||
"cancelledappointment": "Canceled appointment for: ",
|
||||
"nodateselected": "No date has been selected.",
|
||||
"priorappointments": "Previous Appointments",
|
||||
"scheduledfor": "Scheduled appointment for: "
|
||||
},
|
||||
"successes": {
|
||||
"canceled": "Appointment canceled successfully.",
|
||||
"created": "Appointment scheduled successfully."
|
||||
}
|
||||
},
|
||||
"associations": {
|
||||
"actions": {
|
||||
"activate": "Activate"
|
||||
},
|
||||
"fields": {
|
||||
"active": "Active?",
|
||||
"shopname": "Shop Name"
|
||||
},
|
||||
"labels": {
|
||||
"actions": "Actions"
|
||||
}
|
||||
},
|
||||
"bodyshop": {
|
||||
"errors": {
|
||||
"loading": "Unable to load shop details. Please call technical support."
|
||||
}
|
||||
},
|
||||
"documents": {
|
||||
"errors": {
|
||||
"deletes3": "Error deleting document from storage. ",
|
||||
@@ -52,9 +92,11 @@
|
||||
"actions": {
|
||||
"addDocuments": "Add Job Documents",
|
||||
"addNote": "Add Note",
|
||||
"changestatus": "Change Status",
|
||||
"convert": "Convert",
|
||||
"postInvoices": "Post Invoices",
|
||||
"printCenter": "Print Center"
|
||||
"printCenter": "Print Center",
|
||||
"schedule": "Schedule"
|
||||
},
|
||||
"errors": {
|
||||
"creating": "Error encountered while creating job. {{error}}",
|
||||
@@ -113,8 +155,8 @@
|
||||
"owner": "Owner",
|
||||
"owner_owing": "Cust. Owes",
|
||||
"ownr_ea": "Email",
|
||||
"ownr_ph1": "Phone 1",
|
||||
"pay_date": "Inspection Date",
|
||||
"phone1": "Phone 1",
|
||||
"phoneshort": "PH",
|
||||
"policy_no": "Policy #",
|
||||
"ponumber": "PO Number",
|
||||
@@ -163,6 +205,7 @@
|
||||
"vehicle": "Vehicle"
|
||||
},
|
||||
"labels": {
|
||||
"appointmentconfirmation": "Send confirmation to customer?",
|
||||
"available_new_jobs": "",
|
||||
"cards": {
|
||||
"appraiser": "Appraiser",
|
||||
@@ -191,7 +234,7 @@
|
||||
"converted": "Job converted successfully.",
|
||||
"created": "Job created successfully. Click to view.",
|
||||
"deleted": "Job deleted successfully.",
|
||||
"save": "Record Saved",
|
||||
"save": "Job saved successfully.",
|
||||
"savetitle": "Record saved successfully."
|
||||
}
|
||||
},
|
||||
@@ -204,7 +247,8 @@
|
||||
"activejobs": "Active Jobs",
|
||||
"availablejobs": "Available Jobs",
|
||||
"home": "Home",
|
||||
"jobs": "Jobs"
|
||||
"jobs": "Jobs",
|
||||
"schedule": "Schedule"
|
||||
},
|
||||
"jobsdetail": {
|
||||
"claimdetail": "Claim Details",
|
||||
@@ -267,11 +311,16 @@
|
||||
"jobsavailable": "Available Jobs | $t(titles.app)",
|
||||
"jobsdetail": "Job {{ro_number}} | $t(titles.app)",
|
||||
"jobsdocuments": "Job Documents {{ro_number}} | $t(titles.app)",
|
||||
"profile": "My Profile | $t(titles.app)"
|
||||
"profile": "My Profile | $t(titles.app)",
|
||||
"schedule": "Schedule | $t(titles.app)"
|
||||
},
|
||||
"user": {
|
||||
"actions": {
|
||||
"signout": "Sign Out"
|
||||
"signout": "Sign Out",
|
||||
"updateprofile": "Update Profile"
|
||||
},
|
||||
"fields": {
|
||||
"displayname": "Display Name"
|
||||
}
|
||||
},
|
||||
"vehicles": {
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
{
|
||||
"translation": {
|
||||
"appointments": {
|
||||
"actions": {
|
||||
"cancel": "Cancelar",
|
||||
"intake": "Consumo",
|
||||
"reschedule": "Reprogramar",
|
||||
"viewjob": "Ver trabajo"
|
||||
},
|
||||
"errors": {
|
||||
"canceling": "Error al cancelar la cita.",
|
||||
"saving": "Error al programar la cita. {{message}}"
|
||||
},
|
||||
"labels": {
|
||||
"arrivedon": "Llegado el:",
|
||||
"cancelledappointment": "Cita cancelada para:",
|
||||
"nodateselected": "No se ha seleccionado ninguna fecha.",
|
||||
"priorappointments": "Nombramientos previos",
|
||||
"scheduledfor": "Cita programada para:"
|
||||
},
|
||||
"successes": {
|
||||
"canceled": "Cita cancelada con éxito.",
|
||||
"created": "Cita programada con éxito."
|
||||
}
|
||||
},
|
||||
"associations": {
|
||||
"actions": {
|
||||
"activate": "Activar"
|
||||
},
|
||||
"fields": {
|
||||
"active": "¿Activo?",
|
||||
"shopname": "Nombre de tienda"
|
||||
},
|
||||
"labels": {
|
||||
"actions": "Comportamiento"
|
||||
}
|
||||
},
|
||||
"bodyshop": {
|
||||
"errors": {
|
||||
"loading": "No se pueden cargar los detalles de la tienda. Por favor llame al soporte técnico."
|
||||
}
|
||||
},
|
||||
"documents": {
|
||||
"errors": {
|
||||
"deletes3": "Error al eliminar el documento del almacenamiento.",
|
||||
@@ -52,9 +92,11 @@
|
||||
"actions": {
|
||||
"addDocuments": "Agregar documentos de trabajo",
|
||||
"addNote": "Añadir la nota",
|
||||
"changestatus": "Cambiar Estado",
|
||||
"convert": "Convertir",
|
||||
"postInvoices": "Contabilizar facturas",
|
||||
"printCenter": "Centro de impresión"
|
||||
"printCenter": "Centro de impresión",
|
||||
"schedule": "Programar"
|
||||
},
|
||||
"errors": {
|
||||
"creating": "",
|
||||
@@ -113,8 +155,8 @@
|
||||
"owner": "Propietario",
|
||||
"owner_owing": "Cust. Debe",
|
||||
"ownr_ea": "Email",
|
||||
"ownr_ph1": "Teléfono 1",
|
||||
"pay_date": "Fecha de inspección",
|
||||
"phone1": "Teléfono 1",
|
||||
"phoneshort": "PH",
|
||||
"policy_no": "Política #",
|
||||
"ponumber": "numero postal",
|
||||
@@ -163,6 +205,7 @@
|
||||
"vehicle": "Vehículo"
|
||||
},
|
||||
"labels": {
|
||||
"appointmentconfirmation": "¿Enviar confirmación al cliente?",
|
||||
"available_new_jobs": "",
|
||||
"cards": {
|
||||
"appraiser": "Tasador",
|
||||
@@ -191,7 +234,7 @@
|
||||
"converted": "Trabajo convertido con éxito.",
|
||||
"created": "Trabajo creado con éxito. Click para ver.",
|
||||
"deleted": "Trabajo eliminado con éxito.",
|
||||
"save": "Registro guardado",
|
||||
"save": "Trabajo guardado con éxito.",
|
||||
"savetitle": "Registro guardado con éxito."
|
||||
}
|
||||
},
|
||||
@@ -204,7 +247,8 @@
|
||||
"activejobs": "Empleos activos",
|
||||
"availablejobs": "Trabajos disponibles",
|
||||
"home": "Casa",
|
||||
"jobs": "Trabajos"
|
||||
"jobs": "Trabajos",
|
||||
"schedule": "Programar"
|
||||
},
|
||||
"jobsdetail": {
|
||||
"claimdetail": "Detalles de la reclamación",
|
||||
@@ -267,11 +311,16 @@
|
||||
"jobsavailable": "Empleos disponibles | $t(titles.app)",
|
||||
"jobsdetail": "Trabajo {{ro_number}} | $t(titles.app)",
|
||||
"jobsdocuments": "Documentos de trabajo {{ro_number}} | $ t (títulos.app)",
|
||||
"profile": "Mi perfil | $t(titles.app)"
|
||||
"profile": "Mi perfil | $t(titles.app)",
|
||||
"schedule": "Horario | $t(titles.app)"
|
||||
},
|
||||
"user": {
|
||||
"actions": {
|
||||
"signout": "desconectar"
|
||||
"signout": "desconectar",
|
||||
"updateprofile": "Actualización del perfil"
|
||||
},
|
||||
"fields": {
|
||||
"displayname": "Nombre para mostrar"
|
||||
}
|
||||
},
|
||||
"vehicles": {
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
{
|
||||
"translation": {
|
||||
"appointments": {
|
||||
"actions": {
|
||||
"cancel": "annuler",
|
||||
"intake": "Admission",
|
||||
"reschedule": "Replanifier",
|
||||
"viewjob": "Voir le travail"
|
||||
},
|
||||
"errors": {
|
||||
"canceling": "Erreur lors de l'annulation du rendez-vous.",
|
||||
"saving": "Erreur lors de la planification du rendez-vous. {{message}}"
|
||||
},
|
||||
"labels": {
|
||||
"arrivedon": "Arrivé le:",
|
||||
"cancelledappointment": "Rendez-vous annulé pour:",
|
||||
"nodateselected": "Aucune date n'a été sélectionnée.",
|
||||
"priorappointments": "Rendez-vous précédents",
|
||||
"scheduledfor": "Rendez-vous prévu pour:"
|
||||
},
|
||||
"successes": {
|
||||
"canceled": "Rendez-vous annulé avec succès.",
|
||||
"created": "Rendez-vous planifié avec succès."
|
||||
}
|
||||
},
|
||||
"associations": {
|
||||
"actions": {
|
||||
"activate": "Activer"
|
||||
},
|
||||
"fields": {
|
||||
"active": "Actif?",
|
||||
"shopname": "nom de la boutique"
|
||||
},
|
||||
"labels": {
|
||||
"actions": "actes"
|
||||
}
|
||||
},
|
||||
"bodyshop": {
|
||||
"errors": {
|
||||
"loading": "Impossible de charger les détails de la boutique. Veuillez appeler le support technique."
|
||||
}
|
||||
},
|
||||
"documents": {
|
||||
"errors": {
|
||||
"deletes3": "Erreur lors de la suppression du document du stockage.",
|
||||
@@ -52,9 +92,11 @@
|
||||
"actions": {
|
||||
"addDocuments": "Ajouter des documents de travail",
|
||||
"addNote": "Ajouter une note",
|
||||
"changestatus": "Changer le statut",
|
||||
"convert": "Convertir",
|
||||
"postInvoices": "Poster des factures",
|
||||
"printCenter": "Centre d'impression"
|
||||
"printCenter": "Centre d'impression",
|
||||
"schedule": "Programme"
|
||||
},
|
||||
"errors": {
|
||||
"creating": "",
|
||||
@@ -113,8 +155,8 @@
|
||||
"owner": "Propriétaire",
|
||||
"owner_owing": "Cust. Owes",
|
||||
"ownr_ea": "Email",
|
||||
"ownr_ph1": "Téléphone 1",
|
||||
"pay_date": "Date d'inspection",
|
||||
"phone1": "Téléphone 1",
|
||||
"phoneshort": "PH",
|
||||
"policy_no": "Politique #",
|
||||
"ponumber": "Numéro de bon de commande",
|
||||
@@ -163,6 +205,7 @@
|
||||
"vehicle": "Véhicule"
|
||||
},
|
||||
"labels": {
|
||||
"appointmentconfirmation": "Envoyer une confirmation au client?",
|
||||
"available_new_jobs": "",
|
||||
"cards": {
|
||||
"appraiser": "Expert",
|
||||
@@ -191,7 +234,7 @@
|
||||
"converted": "Travail converti avec succès.",
|
||||
"created": "Le travail a été créé avec succès. Clique pour voir.",
|
||||
"deleted": "Le travail a bien été supprimé.",
|
||||
"save": "Enregistrement enregistré",
|
||||
"save": "Le travail a été enregistré avec succès.",
|
||||
"savetitle": "Enregistrement enregistré avec succès."
|
||||
}
|
||||
},
|
||||
@@ -204,7 +247,8 @@
|
||||
"activejobs": "Emplois actifs",
|
||||
"availablejobs": "Emplois disponibles",
|
||||
"home": "Accueil",
|
||||
"jobs": "Emplois"
|
||||
"jobs": "Emplois",
|
||||
"schedule": "Programme"
|
||||
},
|
||||
"jobsdetail": {
|
||||
"claimdetail": "Détails de la réclamation",
|
||||
@@ -267,11 +311,16 @@
|
||||
"jobsavailable": "Emplois disponibles | $t(titles.app)",
|
||||
"jobsdetail": "Travail {{ro_number}} | $t(titles.app)",
|
||||
"jobsdocuments": "Documents de travail {{ro_number}} | $ t (titres.app)",
|
||||
"profile": "Mon profil | $t(titles.app)"
|
||||
"profile": "Mon profil | $t(titles.app)",
|
||||
"schedule": "Horaire | $t(titles.app)"
|
||||
},
|
||||
"user": {
|
||||
"actions": {
|
||||
"signout": "Déconnexion"
|
||||
"signout": "Déconnexion",
|
||||
"updateprofile": "Mettre à jour le profil"
|
||||
},
|
||||
"fields": {
|
||||
"displayname": "Afficher un nom"
|
||||
}
|
||||
},
|
||||
"vehicles": {
|
||||
|
||||
170
client/src/utils/dates.js
Normal file
170
client/src/utils/dates.js
Normal file
@@ -0,0 +1,170 @@
|
||||
/* eslint no-fallthrough: off */
|
||||
import * as dates from "date-arithmetic";
|
||||
|
||||
export {
|
||||
milliseconds,
|
||||
seconds,
|
||||
minutes,
|
||||
hours,
|
||||
month,
|
||||
startOf,
|
||||
endOf,
|
||||
add,
|
||||
eq,
|
||||
gte,
|
||||
gt,
|
||||
lte,
|
||||
lt,
|
||||
inRange,
|
||||
min,
|
||||
max
|
||||
} from "date-arithmetic";
|
||||
|
||||
const MILLI = {
|
||||
seconds: 1000,
|
||||
minutes: 1000 * 60,
|
||||
hours: 1000 * 60 * 60,
|
||||
day: 1000 * 60 * 60 * 24
|
||||
};
|
||||
|
||||
const MONTHS = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
|
||||
|
||||
export function monthsInYear(year) {
|
||||
let date = new Date(year, 0, 1);
|
||||
|
||||
return MONTHS.map(i => dates.month(date, i));
|
||||
}
|
||||
|
||||
export function firstVisibleDay(date, localizer) {
|
||||
let firstOfMonth = dates.startOf(date, "month");
|
||||
|
||||
return dates.startOf(firstOfMonth, "week", localizer.startOfWeek());
|
||||
}
|
||||
|
||||
export function lastVisibleDay(date, localizer) {
|
||||
let endOfMonth = dates.endOf(date, "month");
|
||||
|
||||
return dates.endOf(endOfMonth, "week", localizer.startOfWeek());
|
||||
}
|
||||
|
||||
export function visibleDays(date, localizer) {
|
||||
let current = firstVisibleDay(date, localizer),
|
||||
last = lastVisibleDay(date, localizer),
|
||||
days = [];
|
||||
|
||||
while (dates.lte(current, last, "day")) {
|
||||
days.push(current);
|
||||
current = dates.add(current, 1, "day");
|
||||
}
|
||||
|
||||
return days;
|
||||
}
|
||||
|
||||
export function ceil(date, unit) {
|
||||
let floor = dates.startOf(date, unit);
|
||||
|
||||
return dates.eq(floor, date) ? floor : dates.add(floor, 1, unit);
|
||||
}
|
||||
|
||||
export function range(start, end, unit = "day") {
|
||||
let current = start,
|
||||
days = [];
|
||||
|
||||
while (dates.lte(current, end, unit)) {
|
||||
days.push(current);
|
||||
current = dates.add(current, 1, unit);
|
||||
}
|
||||
|
||||
return days;
|
||||
}
|
||||
|
||||
export function merge(date, time) {
|
||||
if (time == null && date == null) return null;
|
||||
|
||||
if (time == null) time = new Date();
|
||||
if (date == null) date = new Date();
|
||||
|
||||
date = dates.startOf(date, "day");
|
||||
date = dates.hours(date, dates.hours(time));
|
||||
date = dates.minutes(date, dates.minutes(time));
|
||||
date = dates.seconds(date, dates.seconds(time));
|
||||
return dates.milliseconds(date, dates.milliseconds(time));
|
||||
}
|
||||
|
||||
export function eqTime(dateA, dateB) {
|
||||
return (
|
||||
dates.hours(dateA) === dates.hours(dateB) &&
|
||||
dates.minutes(dateA) === dates.minutes(dateB) &&
|
||||
dates.seconds(dateA) === dates.seconds(dateB)
|
||||
);
|
||||
}
|
||||
|
||||
export function isJustDate(date) {
|
||||
return (
|
||||
dates.hours(date) === 0 &&
|
||||
dates.minutes(date) === 0 &&
|
||||
dates.seconds(date) === 0 &&
|
||||
dates.milliseconds(date) === 0
|
||||
);
|
||||
}
|
||||
|
||||
export function duration(start, end, unit, firstOfWeek) {
|
||||
if (unit === "day") unit = "date";
|
||||
return Math.abs(
|
||||
dates[unit](start, undefined, firstOfWeek) -
|
||||
dates[unit](end, undefined, firstOfWeek)
|
||||
);
|
||||
}
|
||||
|
||||
export function diff(dateA, dateB, unit) {
|
||||
if (!unit || unit === "milliseconds") return Math.abs(+dateA - +dateB);
|
||||
|
||||
// the .round() handles an edge case
|
||||
// with DST where the total won't be exact
|
||||
// since one day in the range may be shorter/longer by an hour
|
||||
return Math.round(
|
||||
Math.abs(
|
||||
+dates.startOf(dateA, unit) / MILLI[unit] -
|
||||
+dates.startOf(dateB, unit) / MILLI[unit]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function total(date, unit) {
|
||||
let ms = date.getTime(),
|
||||
div = 1;
|
||||
|
||||
switch (unit) {
|
||||
case "week":
|
||||
div *= 7;
|
||||
case "day":
|
||||
div *= 24;
|
||||
case "hours":
|
||||
div *= 60;
|
||||
case "minutes":
|
||||
div *= 60;
|
||||
case "seconds":
|
||||
div *= 1000;
|
||||
}
|
||||
|
||||
return ms / div;
|
||||
}
|
||||
|
||||
export function week(date) {
|
||||
var d = new Date(date);
|
||||
d.setHours(0, 0, 0);
|
||||
d.setDate(d.getDate() + 4 - (d.getDay() || 7));
|
||||
return Math.ceil(((d - new Date(d.getFullYear(), 0, 1)) / 8.64e7 + 1) / 7);
|
||||
}
|
||||
|
||||
export function today() {
|
||||
return dates.startOf(new Date(), "day");
|
||||
}
|
||||
|
||||
export function yesterday() {
|
||||
return dates.add(dates.startOf(new Date(), "day"), -1, "day");
|
||||
}
|
||||
|
||||
export function tomorrow() {
|
||||
return dates.add(dates.startOf(new Date(), "day"), 1, "day");
|
||||
}
|
||||
@@ -1026,7 +1026,7 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/runtime@^7.5.5":
|
||||
"@babel/runtime@^7.1.5", "@babel/runtime@^7.5.5":
|
||||
version "7.8.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.4.tgz#d79f5a2040f7caa24d53e563aad49cbc05581308"
|
||||
integrity sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ==
|
||||
@@ -1620,6 +1620,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@redux-saga/types/-/types-1.1.0.tgz#0e81ce56b4883b4b2a3001ebe1ab298b84237204"
|
||||
integrity sha512-afmTuJrylUU/0OtqzaRkbyYFFNgCF73Bvel/sw90pvGrWIZ+vyoIJqA6eMSoA6+nb443kTmulmBtC9NerXboNg==
|
||||
|
||||
"@restart/hooks@^0.3.12":
|
||||
version "0.3.20"
|
||||
resolved "https://registry.yarnpkg.com/@restart/hooks/-/hooks-0.3.20.tgz#e7179ab41e5f346b2feca091261fbdad77e8bc19"
|
||||
integrity sha512-Q1eeEqcxHQ4oqty7C5Me8/hzWwdCRR643nR/6EHxv8BVxLVYHe4IoWAHg8MIGkE4VtSm3/JnNhkoLJhCkLx5aw==
|
||||
|
||||
"@svgr/babel-plugin-add-jsx-attribute@^4.2.0":
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1"
|
||||
@@ -1839,6 +1844,14 @@
|
||||
"@types/prop-types" "*"
|
||||
csstype "^2.2.0"
|
||||
|
||||
"@types/react@^16.9.11":
|
||||
version "16.9.19"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.19.tgz#c842aa83ea490007d29938146ff2e4d9e4360c40"
|
||||
integrity sha512-LJV97//H+zqKWMms0kvxaKYJDG05U2TtQB3chRLF8MPNs+MQh/H1aGlyDUxjaHvu08EAGerdX2z4LTBc7ns77A==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
csstype "^2.2.0"
|
||||
|
||||
"@types/stack-utils@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
|
||||
@@ -3483,6 +3496,11 @@ clone-deep@^4.0.1:
|
||||
kind-of "^6.0.2"
|
||||
shallow-clone "^3.0.0"
|
||||
|
||||
clsx@^1.0.4:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702"
|
||||
integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA==
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
@@ -4103,7 +4121,7 @@ cssstyle@^1.0.0, cssstyle@^1.1.1:
|
||||
dependencies:
|
||||
cssom "0.3.x"
|
||||
|
||||
csstype@^2.2.0:
|
||||
csstype@^2.2.0, csstype@^2.6.7:
|
||||
version "2.6.8"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.8.tgz#0fb6fc2417ffd2816a418c9336da74d7f07db431"
|
||||
integrity sha512-msVS9qTuMT5zwAGCVm4mxfrZ18BNc6Csd0oJAtiFMZ1FAx1CCvy2+5MDmYoix63LM/6NDbNtodCiGYGmFgO0dA==
|
||||
@@ -4149,6 +4167,11 @@ data-urls@^1.0.0, data-urls@^1.1.0:
|
||||
whatwg-mimetype "^2.2.0"
|
||||
whatwg-url "^7.0.0"
|
||||
|
||||
date-arithmetic@^4.0.1:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/date-arithmetic/-/date-arithmetic-4.1.0.tgz#e5d6434e9deb71f79760a37b729e4a515e730ddf"
|
||||
integrity sha512-QWxYLR5P/6GStZcdem+V1xoto6DMadYWpMXU82ES3/RfR3Wdwr3D0+be7mgOJ+Ov0G9D5Dmb9T17sNLQYj9XOg==
|
||||
|
||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
@@ -4409,6 +4432,14 @@ dom-converter@^0.2:
|
||||
dependencies:
|
||||
utila "~0.4"
|
||||
|
||||
dom-helpers@^5.1.0:
|
||||
version "5.1.3"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.3.tgz#7233248eb3a2d1f74aafca31e52c5299cc8ce821"
|
||||
integrity sha512-nZD1OtwfWGRBWlpANxacBEZrEuLa16o1nh7YopFWeoF68Zt8GGEmzHu6Xv4F3XaFIC+YXtTLrzgqKxFgLEe4jw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
csstype "^2.6.7"
|
||||
|
||||
dom-matches@>=1.0.1:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-matches/-/dom-matches-2.0.0.tgz#d2728b416a87533980eb089b848d253cf23a758c"
|
||||
@@ -7487,6 +7518,11 @@ locate-path@^3.0.0:
|
||||
p-locate "^3.0.0"
|
||||
path-exists "^3.0.0"
|
||||
|
||||
lodash-es@^4.17.11:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.15.tgz#21bd96839354412f23d7a10340e5eac6ee455d78"
|
||||
integrity sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ==
|
||||
|
||||
lodash._reinterpolate@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
||||
@@ -7689,6 +7725,11 @@ mem@^4.0.0:
|
||||
mimic-fn "^2.0.0"
|
||||
p-is-promise "^2.0.0"
|
||||
|
||||
memoize-one@^4.0.3:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-4.1.0.tgz#a2387c58c03fff27ca390c31b764a79addf3f906"
|
||||
integrity sha512-2GApq0yI/b22J2j9rhbrAlsHb0Qcz+7yWxeLG8h+95sl1XPUgeLimQSOdur4Vw7cUhrBHwaUZxWFZueojqNRzA==
|
||||
|
||||
memoize-one@^5.0.0:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0"
|
||||
@@ -8908,6 +8949,11 @@ pnp-webpack-plugin@1.5.0:
|
||||
dependencies:
|
||||
ts-pnp "^1.1.2"
|
||||
|
||||
popper.js@^1.15.0:
|
||||
version "1.16.1"
|
||||
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b"
|
||||
integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==
|
||||
|
||||
portfinder@^1.0.9:
|
||||
version "1.0.25"
|
||||
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca"
|
||||
@@ -10342,6 +10388,24 @@ react-app-polyfill@^1.0.4:
|
||||
regenerator-runtime "^0.13.3"
|
||||
whatwg-fetch "^3.0.0"
|
||||
|
||||
react-big-calendar@^0.23.0:
|
||||
version "0.23.0"
|
||||
resolved "https://registry.yarnpkg.com/react-big-calendar/-/react-big-calendar-0.23.0.tgz#cc780481548fcefabb04cea05dd1a08456702a67"
|
||||
integrity sha512-f/v1J/oqvEJqXcT5clJ5wzFIWKRNUeMCvLLzH6PYszcR15mUgqQb31HH+2Ev+YZHVW3YSStcZn2HWEhmvFr9ew==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.5"
|
||||
clsx "^1.0.4"
|
||||
date-arithmetic "^4.0.1"
|
||||
dom-helpers "^5.1.0"
|
||||
invariant "^2.2.4"
|
||||
lodash "^4.17.11"
|
||||
lodash-es "^4.17.11"
|
||||
memoize-one "^4.0.3"
|
||||
prop-types "^15.6.2"
|
||||
react-overlays "^2.0.0-0"
|
||||
uncontrollable "^7.0.0"
|
||||
warning "^4.0.2"
|
||||
|
||||
react-chartjs-2@^2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/react-chartjs-2/-/react-chartjs-2-2.8.0.tgz#1c24de91fb3755f8c4302675de7d66fdda339759"
|
||||
@@ -10452,6 +10516,19 @@ react-number-format@^4.3.1:
|
||||
dependencies:
|
||||
prop-types "^15.7.2"
|
||||
|
||||
react-overlays@^2.0.0-0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/react-overlays/-/react-overlays-2.1.1.tgz#ffe2090c4a10da6b8947a1c7b1a67d0457648a0d"
|
||||
integrity sha512-gaQJwmb8Ij2IGVt4D1HmLtl4A0mDVYxlsv/8i0dHWK7Mw0kNat6ORelbbEWzaXTK1TqMeQtJw/jraL3WOADz3w==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.4.5"
|
||||
"@restart/hooks" "^0.3.12"
|
||||
dom-helpers "^5.1.0"
|
||||
popper.js "^1.15.0"
|
||||
prop-types "^15.7.2"
|
||||
uncontrollable "^7.0.0"
|
||||
warning "^4.0.3"
|
||||
|
||||
react-popopo@^2.1.9:
|
||||
version "2.1.9"
|
||||
resolved "https://registry.yarnpkg.com/react-popopo/-/react-popopo-2.1.9.tgz#d93f70a8fb68227907d00c0cea4d8f5d321053ea"
|
||||
@@ -12389,6 +12466,16 @@ uglify-js@^3.1.4:
|
||||
commander "~2.20.3"
|
||||
source-map "~0.6.1"
|
||||
|
||||
uncontrollable@^7.0.0:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-7.1.1.tgz#f67fed3ef93637126571809746323a9db815d556"
|
||||
integrity sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.3"
|
||||
"@types/react" "^16.9.11"
|
||||
invariant "^2.2.4"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
|
||||
unicode-canonical-property-names-ecmascript@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
- args:
|
||||
sql: DROP TABLE "public"."employees"
|
||||
type: run_sql
|
||||
@@ -0,0 +1,21 @@
|
||||
- args:
|
||||
sql: CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
type: run_sql
|
||||
- args:
|
||||
sql: "CREATE TABLE \"public\".\"employees\"(\"id\" uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
\"created_at\" timestamptz NOT NULL DEFAULT now(), \"updated_at\" timestamptz
|
||||
NOT NULL DEFAULT now(), \"first_name\" text NOT NULL, \"last_name\" text NOT
|
||||
NULL, \"employee_number\" text, \"shopid\" uuid NOT NULL, \"active\" boolean
|
||||
NOT NULL DEFAULT true, PRIMARY KEY (\"id\") , FOREIGN KEY (\"shopid\") REFERENCES
|
||||
\"public\".\"bodyshops\"(\"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_employees_updated_at\"\nBEFORE
|
||||
UPDATE ON \"public\".\"employees\"\nFOR EACH ROW\nEXECUTE PROCEDURE \"public\".\"set_current_timestamp_updated_at\"();\nCOMMENT
|
||||
ON TRIGGER \"set_public_employees_updated_at\" ON \"public\".\"employees\" \nIS
|
||||
'trigger to set value of column \"updated_at\" to current timestamp on row update';\n"
|
||||
type: run_sql
|
||||
- args:
|
||||
name: employees
|
||||
schema: public
|
||||
type: add_existing_table_or_view
|
||||
@@ -0,0 +1,12 @@
|
||||
- args:
|
||||
relationship: employees
|
||||
table:
|
||||
name: bodyshops
|
||||
schema: public
|
||||
type: drop_relationship
|
||||
- args:
|
||||
relationship: bodyshop
|
||||
table:
|
||||
name: employees
|
||||
schema: public
|
||||
type: drop_relationship
|
||||
@@ -0,0 +1,20 @@
|
||||
- args:
|
||||
name: employees
|
||||
table:
|
||||
name: bodyshops
|
||||
schema: public
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: shopid
|
||||
table:
|
||||
name: employees
|
||||
schema: public
|
||||
type: create_array_relationship
|
||||
- args:
|
||||
name: bodyshop
|
||||
table:
|
||||
name: employees
|
||||
schema: public
|
||||
using:
|
||||
foreign_key_constraint_on: shopid
|
||||
type: create_object_relationship
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: employees
|
||||
schema: public
|
||||
type: drop_insert_permission
|
||||
@@ -0,0 +1,30 @@
|
||||
- args:
|
||||
permission:
|
||||
allow_upsert: true
|
||||
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
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: employees
|
||||
schema: public
|
||||
type: drop_select_permission
|
||||
@@ -0,0 +1,27 @@
|
||||
- args:
|
||||
permission:
|
||||
allow_aggregations: false
|
||||
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
|
||||
limit: null
|
||||
role: user
|
||||
table:
|
||||
name: employees
|
||||
schema: public
|
||||
type: create_select_permission
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: employees
|
||||
schema: public
|
||||
type: drop_update_permission
|
||||
@@ -0,0 +1,29 @@
|
||||
- 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
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: employees
|
||||
schema: public
|
||||
type: drop_delete_permission
|
||||
@@ -0,0 +1,16 @@
|
||||
- args:
|
||||
permission:
|
||||
filter:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
role: user
|
||||
table:
|
||||
name: employees
|
||||
schema: public
|
||||
type: create_delete_permission
|
||||
@@ -0,0 +1,3 @@
|
||||
- args:
|
||||
sql: DROP TABLE "public"."appointments"
|
||||
type: run_sql
|
||||
@@ -0,0 +1,21 @@
|
||||
- args:
|
||||
sql: CREATE EXTENSION IF NOT EXISTS pgcrypto;
|
||||
type: run_sql
|
||||
- args:
|
||||
sql: "CREATE TABLE \"public\".\"appointments\"(\"id\" uuid NOT NULL DEFAULT gen_random_uuid(),
|
||||
\"created_at\" timestamptz NOT NULL DEFAULT now(), \"updated_at\" timestamptz
|
||||
NOT NULL DEFAULT now(), \"jobid\" uuid NOT NULL, \"start\" timestamptz NOT NULL,
|
||||
\"end\" timestamptz NOT NULL, PRIMARY KEY (\"id\") , FOREIGN KEY (\"jobid\")
|
||||
REFERENCES \"public\".\"jobs\"(\"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_appointments_updated_at\"\nBEFORE
|
||||
UPDATE ON \"public\".\"appointments\"\nFOR EACH ROW\nEXECUTE PROCEDURE \"public\".\"set_current_timestamp_updated_at\"();\nCOMMENT
|
||||
ON TRIGGER \"set_public_appointments_updated_at\" ON \"public\".\"appointments\"
|
||||
\nIS 'trigger to set value of column \"updated_at\" to current timestamp on
|
||||
row update';\n"
|
||||
type: run_sql
|
||||
- args:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: add_existing_table_or_view
|
||||
@@ -0,0 +1,12 @@
|
||||
- args:
|
||||
relationship: job
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: drop_relationship
|
||||
- args:
|
||||
relationship: appointments
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: drop_relationship
|
||||
@@ -0,0 +1,20 @@
|
||||
- args:
|
||||
name: job
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
using:
|
||||
foreign_key_constraint_on: jobid
|
||||
type: create_object_relationship
|
||||
- args:
|
||||
name: appointments
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: jobid
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: create_array_relationship
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: drop_insert_permission
|
||||
@@ -0,0 +1,29 @@
|
||||
- args:
|
||||
permission:
|
||||
allow_upsert: true
|
||||
check:
|
||||
job:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
columns:
|
||||
- created_at
|
||||
- end
|
||||
- start
|
||||
- updated_at
|
||||
- id
|
||||
- jobid
|
||||
localPresets:
|
||||
- key: ""
|
||||
value: ""
|
||||
set: {}
|
||||
role: user
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: create_insert_permission
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: drop_select_permission
|
||||
@@ -0,0 +1,26 @@
|
||||
- args:
|
||||
permission:
|
||||
allow_aggregations: false
|
||||
columns:
|
||||
- created_at
|
||||
- end
|
||||
- start
|
||||
- updated_at
|
||||
- id
|
||||
- jobid
|
||||
filter:
|
||||
job:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
limit: null
|
||||
role: user
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: create_select_permission
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: drop_update_permission
|
||||
@@ -0,0 +1,28 @@
|
||||
- args:
|
||||
permission:
|
||||
columns:
|
||||
- created_at
|
||||
- end
|
||||
- start
|
||||
- updated_at
|
||||
- id
|
||||
- jobid
|
||||
filter:
|
||||
job:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
localPresets:
|
||||
- key: ""
|
||||
value: ""
|
||||
set: {}
|
||||
role: user
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: create_update_permission
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: drop_delete_permission
|
||||
@@ -0,0 +1,17 @@
|
||||
- args:
|
||||
permission:
|
||||
filter:
|
||||
job:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
role: user
|
||||
table:
|
||||
name: appointments
|
||||
schema: public
|
||||
type: create_delete_permission
|
||||
@@ -0,0 +1,244 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
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
|
||||
- shopid
|
||||
- ro_number
|
||||
- ownerid
|
||||
- vehicleid
|
||||
- labor_rate_id
|
||||
- labor_rate_desc
|
||||
- rate_lab
|
||||
- rate_lad
|
||||
- rate_lae
|
||||
- rate_lar
|
||||
- rate_las
|
||||
- rate_laf
|
||||
- rate_lam
|
||||
- rate_lag
|
||||
- rate_atp
|
||||
- rate_lau
|
||||
- rate_la1
|
||||
- rate_la2
|
||||
- rate_la3
|
||||
- rate_la4
|
||||
- rate_mapa
|
||||
- rate_mash
|
||||
- rate_mahw
|
||||
- rate_ma2s
|
||||
- rate_ma3s
|
||||
- rate_ma2t
|
||||
- rate_mabl
|
||||
- rate_macs
|
||||
- rate_matd
|
||||
- federal_tax_rate
|
||||
- state_tax_rate
|
||||
- local_tax_rate
|
||||
- est_co_nm
|
||||
- est_addr1
|
||||
- est_addr2
|
||||
- est_city
|
||||
- est_st
|
||||
- est_zip
|
||||
- est_ctry
|
||||
- est_ph1
|
||||
- est_ea
|
||||
- est_ct_ln
|
||||
- est_ct_fn
|
||||
- scheduled_in
|
||||
- actual_in
|
||||
- scheduled_completion
|
||||
- actual_completion
|
||||
- scheduled_delivery
|
||||
- actual_delivery
|
||||
- regie_number
|
||||
- invoice_date
|
||||
- claim_total
|
||||
- deductible
|
||||
- inproduction
|
||||
- statusid
|
||||
- ins_co_id
|
||||
- ins_co_nm
|
||||
- ins_addr1
|
||||
- ins_addr2
|
||||
- ins_city
|
||||
- ins_st
|
||||
- ins_zip
|
||||
- ins_ctry
|
||||
- ins_ph1
|
||||
- ins_ph1x
|
||||
- ins_ph2
|
||||
- ins_ph2x
|
||||
- ins_fax
|
||||
- ins_faxx
|
||||
- ins_ct_ln
|
||||
- ins_ct_fn
|
||||
- ins_title
|
||||
- ins_ct_ph
|
||||
- ins_ct_phx
|
||||
- ins_ea
|
||||
- ins_memo
|
||||
- policy_no
|
||||
- ded_amt
|
||||
- ded_status
|
||||
- asgn_no
|
||||
- asgn_date
|
||||
- asgn_type
|
||||
- clm_no
|
||||
- clm_ofc_id
|
||||
- date_estimated
|
||||
- date_open
|
||||
- date_scheduled
|
||||
- date_invoiced
|
||||
- date_closed
|
||||
- date_exported
|
||||
- clm_total
|
||||
- owner_owing
|
||||
- converted
|
||||
- ciecaid
|
||||
- loss_date
|
||||
- clm_ofc_nm
|
||||
- clm_addr1
|
||||
- clm_addr2
|
||||
- clm_city
|
||||
- clm_st
|
||||
- clm_zip
|
||||
- clm_ctry
|
||||
- clm_ph1
|
||||
- clm_ph1x
|
||||
- clm_ph2
|
||||
- clm_ph2x
|
||||
- clm_fax
|
||||
- clm_faxx
|
||||
- clm_ct_ln
|
||||
- clm_ct_fn
|
||||
- clm_title
|
||||
- clm_ct_ph
|
||||
- clm_ct_phx
|
||||
- clm_ea
|
||||
- payee_nms
|
||||
- pay_type
|
||||
- pay_date
|
||||
- pay_chknm
|
||||
- pay_amt
|
||||
- agt_co_id
|
||||
- agt_co_nm
|
||||
- agt_addr1
|
||||
- agt_addr2
|
||||
- agt_city
|
||||
- agt_st
|
||||
- agt_zip
|
||||
- agt_ctry
|
||||
- agt_ph1
|
||||
- agt_ph1x
|
||||
- agt_ph2
|
||||
- agt_ph2x
|
||||
- agt_fax
|
||||
- agt_faxx
|
||||
- agt_ct_ln
|
||||
- agt_ct_fn
|
||||
- agt_ct_ph
|
||||
- agt_ct_phx
|
||||
- agt_ea
|
||||
- agt_lic_no
|
||||
- loss_type
|
||||
- loss_desc
|
||||
- theft_ind
|
||||
- cat_no
|
||||
- tlos_ind
|
||||
- cust_pr
|
||||
- insd_ln
|
||||
- insd_fn
|
||||
- insd_title
|
||||
- insd_co_nm
|
||||
- insd_addr1
|
||||
- insd_addr2
|
||||
- insd_city
|
||||
- insd_st
|
||||
- insd_zip
|
||||
- insd_ctry
|
||||
- insd_ph1
|
||||
- insd_ph1x
|
||||
- insd_ph2
|
||||
- insd_ph2x
|
||||
- insd_fax
|
||||
- insd_faxx
|
||||
- insd_ea
|
||||
- ownr_ln
|
||||
- ownr_fn
|
||||
- ownr_title
|
||||
- ownr_co_nm
|
||||
- ownr_addr1
|
||||
- ownr_addr2
|
||||
- ownr_city
|
||||
- ownr_st
|
||||
- ownr_zip
|
||||
- ownr_ctry
|
||||
- ownr_ph1
|
||||
- ownr_ph1x
|
||||
- ownr_ph2
|
||||
- ownr_ph2x
|
||||
- ownr_fax
|
||||
- ownr_faxx
|
||||
- ownr_ea
|
||||
- area_of_damage
|
||||
- loss_cat
|
||||
- est_number
|
||||
- service_car
|
||||
- special_coverage_policy
|
||||
- csr
|
||||
- po_number
|
||||
- unit_number
|
||||
- kmin
|
||||
- kmout
|
||||
- referral_source
|
||||
- selling_dealer
|
||||
- servicing_dealer
|
||||
- servicing_dealer_contact
|
||||
- selling_dealer_contact
|
||||
- depreciation_taxes
|
||||
- federal_tax_payable
|
||||
- other_amount_payable
|
||||
- towing_payable
|
||||
- storage_payable
|
||||
- adjustment_bottom_line
|
||||
- tax_pstthr
|
||||
- tax_tow_rt
|
||||
- tax_sub_rt
|
||||
- tax_paint_mat_rt
|
||||
- tax_levies_rt
|
||||
- tax_prethr
|
||||
- tax_thramt
|
||||
- tax_str_rt
|
||||
- tax_lbr_rt
|
||||
- adj_g_disc
|
||||
- adj_towdis
|
||||
- adj_strdis
|
||||
- tax_predis
|
||||
- rate_laa
|
||||
localPresets:
|
||||
- key: ""
|
||||
value: ""
|
||||
set: {}
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: create_insert_permission
|
||||
@@ -0,0 +1,243 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: drop_insert_permission
|
||||
- args:
|
||||
permission:
|
||||
check:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
columns:
|
||||
- actual_completion
|
||||
- actual_delivery
|
||||
- actual_in
|
||||
- adj_g_disc
|
||||
- adj_strdis
|
||||
- adj_towdis
|
||||
- adjustment_bottom_line
|
||||
- agt_addr1
|
||||
- agt_addr2
|
||||
- agt_city
|
||||
- agt_co_id
|
||||
- agt_co_nm
|
||||
- agt_ct_fn
|
||||
- agt_ct_ln
|
||||
- agt_ct_ph
|
||||
- agt_ct_phx
|
||||
- agt_ctry
|
||||
- agt_ea
|
||||
- agt_fax
|
||||
- agt_faxx
|
||||
- agt_lic_no
|
||||
- agt_ph1
|
||||
- agt_ph1x
|
||||
- agt_ph2
|
||||
- agt_ph2x
|
||||
- agt_st
|
||||
- agt_zip
|
||||
- area_of_damage
|
||||
- asgn_date
|
||||
- asgn_no
|
||||
- asgn_type
|
||||
- cat_no
|
||||
- ciecaid
|
||||
- clm_addr1
|
||||
- clm_addr2
|
||||
- clm_city
|
||||
- clm_ct_fn
|
||||
- clm_ct_ln
|
||||
- clm_ct_ph
|
||||
- clm_ct_phx
|
||||
- clm_ctry
|
||||
- clm_ea
|
||||
- clm_fax
|
||||
- clm_faxx
|
||||
- clm_no
|
||||
- clm_ofc_id
|
||||
- clm_ofc_nm
|
||||
- clm_ph1
|
||||
- clm_ph1x
|
||||
- clm_ph2
|
||||
- clm_ph2x
|
||||
- clm_st
|
||||
- clm_title
|
||||
- clm_total
|
||||
- clm_zip
|
||||
- converted
|
||||
- created_at
|
||||
- csr
|
||||
- cust_pr
|
||||
- date_closed
|
||||
- date_estimated
|
||||
- date_exported
|
||||
- date_invoiced
|
||||
- date_open
|
||||
- date_scheduled
|
||||
- ded_amt
|
||||
- ded_status
|
||||
- deductible
|
||||
- depreciation_taxes
|
||||
- est_addr1
|
||||
- est_addr2
|
||||
- est_city
|
||||
- est_co_nm
|
||||
- est_ct_fn
|
||||
- est_ct_ln
|
||||
- est_ctry
|
||||
- est_ea
|
||||
- est_number
|
||||
- est_ph1
|
||||
- est_st
|
||||
- est_zip
|
||||
- federal_tax_payable
|
||||
- federal_tax_rate
|
||||
- id
|
||||
- inproduction
|
||||
- ins_addr1
|
||||
- ins_addr2
|
||||
- ins_city
|
||||
- ins_co_id
|
||||
- ins_co_nm
|
||||
- ins_ct_fn
|
||||
- ins_ct_ln
|
||||
- ins_ct_ph
|
||||
- ins_ct_phx
|
||||
- ins_ctry
|
||||
- ins_ea
|
||||
- ins_fax
|
||||
- ins_faxx
|
||||
- ins_memo
|
||||
- ins_ph1
|
||||
- ins_ph1x
|
||||
- ins_ph2
|
||||
- ins_ph2x
|
||||
- ins_st
|
||||
- ins_title
|
||||
- ins_zip
|
||||
- insd_addr1
|
||||
- insd_addr2
|
||||
- insd_city
|
||||
- insd_co_nm
|
||||
- insd_ctry
|
||||
- insd_ea
|
||||
- insd_fax
|
||||
- insd_faxx
|
||||
- insd_fn
|
||||
- insd_ln
|
||||
- insd_ph1
|
||||
- insd_ph1x
|
||||
- insd_ph2
|
||||
- insd_ph2x
|
||||
- insd_st
|
||||
- insd_title
|
||||
- insd_zip
|
||||
- invoice_date
|
||||
- kmin
|
||||
- kmout
|
||||
- labor_rate_desc
|
||||
- labor_rate_id
|
||||
- local_tax_rate
|
||||
- loss_cat
|
||||
- loss_date
|
||||
- loss_desc
|
||||
- loss_type
|
||||
- other_amount_payable
|
||||
- owner_owing
|
||||
- ownerid
|
||||
- ownr_addr1
|
||||
- ownr_addr2
|
||||
- ownr_city
|
||||
- ownr_co_nm
|
||||
- ownr_ctry
|
||||
- ownr_ea
|
||||
- ownr_fax
|
||||
- ownr_faxx
|
||||
- ownr_fn
|
||||
- ownr_ln
|
||||
- ownr_ph1
|
||||
- ownr_ph1x
|
||||
- ownr_ph2
|
||||
- ownr_ph2x
|
||||
- ownr_st
|
||||
- ownr_title
|
||||
- ownr_zip
|
||||
- pay_amt
|
||||
- pay_chknm
|
||||
- pay_date
|
||||
- pay_type
|
||||
- payee_nms
|
||||
- po_number
|
||||
- policy_no
|
||||
- rate_atp
|
||||
- rate_la1
|
||||
- rate_la2
|
||||
- rate_la3
|
||||
- rate_la4
|
||||
- rate_laa
|
||||
- rate_lab
|
||||
- rate_lad
|
||||
- rate_lae
|
||||
- rate_laf
|
||||
- rate_lag
|
||||
- rate_lam
|
||||
- rate_lar
|
||||
- rate_las
|
||||
- rate_lau
|
||||
- rate_ma2s
|
||||
- rate_ma2t
|
||||
- rate_ma3s
|
||||
- rate_mabl
|
||||
- rate_macs
|
||||
- rate_mahw
|
||||
- rate_mapa
|
||||
- rate_mash
|
||||
- rate_matd
|
||||
- referral_source
|
||||
- regie_number
|
||||
- ro_number
|
||||
- scheduled_completion
|
||||
- scheduled_delivery
|
||||
- scheduled_in
|
||||
- selling_dealer
|
||||
- selling_dealer_contact
|
||||
- service_car
|
||||
- servicing_dealer
|
||||
- servicing_dealer_contact
|
||||
- shopid
|
||||
- special_coverage_policy
|
||||
- state_tax_rate
|
||||
- statusid
|
||||
- storage_payable
|
||||
- tax_lbr_rt
|
||||
- tax_levies_rt
|
||||
- tax_paint_mat_rt
|
||||
- tax_predis
|
||||
- tax_prethr
|
||||
- tax_pstthr
|
||||
- tax_str_rt
|
||||
- tax_sub_rt
|
||||
- tax_thramt
|
||||
- tax_tow_rt
|
||||
- theft_ind
|
||||
- tlos_ind
|
||||
- towing_payable
|
||||
- unit_number
|
||||
- updated_at
|
||||
- vehicleid
|
||||
localPresets:
|
||||
- key: ""
|
||||
value: ""
|
||||
set: {}
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: create_insert_permission
|
||||
@@ -0,0 +1,242 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: drop_select_permission
|
||||
- args:
|
||||
permission:
|
||||
allow_aggregations: false
|
||||
columns:
|
||||
- converted
|
||||
- inproduction
|
||||
- special_coverage_policy
|
||||
- theft_ind
|
||||
- tlos_ind
|
||||
- asgn_date
|
||||
- invoice_date
|
||||
- loss_date
|
||||
- pay_date
|
||||
- kmin
|
||||
- kmout
|
||||
- est_number
|
||||
- area_of_damage
|
||||
- adj_g_disc
|
||||
- adj_strdis
|
||||
- adj_towdis
|
||||
- adjustment_bottom_line
|
||||
- claim_total
|
||||
- clm_total
|
||||
- ded_amt
|
||||
- deductible
|
||||
- depreciation_taxes
|
||||
- federal_tax_payable
|
||||
- federal_tax_rate
|
||||
- local_tax_rate
|
||||
- other_amount_payable
|
||||
- owner_owing
|
||||
- pay_amt
|
||||
- rate_atp
|
||||
- rate_la1
|
||||
- rate_la2
|
||||
- rate_la3
|
||||
- rate_la4
|
||||
- rate_laa
|
||||
- rate_lab
|
||||
- rate_lad
|
||||
- rate_lae
|
||||
- rate_laf
|
||||
- rate_lag
|
||||
- rate_lam
|
||||
- rate_lar
|
||||
- rate_las
|
||||
- rate_lau
|
||||
- rate_ma2s
|
||||
- rate_ma2t
|
||||
- rate_ma3s
|
||||
- rate_mabl
|
||||
- rate_macs
|
||||
- rate_mahw
|
||||
- rate_mapa
|
||||
- rate_mash
|
||||
- rate_matd
|
||||
- state_tax_rate
|
||||
- storage_payable
|
||||
- tax_lbr_rt
|
||||
- tax_levies_rt
|
||||
- tax_paint_mat_rt
|
||||
- tax_predis
|
||||
- tax_prethr
|
||||
- tax_str_rt
|
||||
- tax_thramt
|
||||
- towing_payable
|
||||
- agt_addr1
|
||||
- agt_addr2
|
||||
- agt_city
|
||||
- agt_co_id
|
||||
- agt_co_nm
|
||||
- agt_ct_fn
|
||||
- agt_ct_ln
|
||||
- agt_ct_ph
|
||||
- agt_ct_phx
|
||||
- agt_ctry
|
||||
- agt_ea
|
||||
- agt_fax
|
||||
- agt_faxx
|
||||
- agt_lic_no
|
||||
- agt_ph1
|
||||
- agt_ph1x
|
||||
- agt_ph2
|
||||
- agt_ph2x
|
||||
- agt_st
|
||||
- agt_zip
|
||||
- asgn_no
|
||||
- asgn_type
|
||||
- cat_no
|
||||
- ciecaid
|
||||
- clm_addr1
|
||||
- clm_addr2
|
||||
- clm_city
|
||||
- clm_ct_fn
|
||||
- clm_ct_ln
|
||||
- clm_ct_ph
|
||||
- clm_ct_phx
|
||||
- clm_ctry
|
||||
- clm_ea
|
||||
- clm_fax
|
||||
- clm_faxx
|
||||
- clm_no
|
||||
- clm_ofc_id
|
||||
- clm_ofc_nm
|
||||
- clm_ph1
|
||||
- clm_ph1x
|
||||
- clm_ph2
|
||||
- clm_ph2x
|
||||
- clm_st
|
||||
- clm_title
|
||||
- clm_zip
|
||||
- csr
|
||||
- cust_pr
|
||||
- ded_status
|
||||
- est_addr1
|
||||
- est_addr2
|
||||
- est_city
|
||||
- est_co_nm
|
||||
- est_ct_fn
|
||||
- est_ct_ln
|
||||
- est_ctry
|
||||
- est_ea
|
||||
- est_ph1
|
||||
- est_st
|
||||
- est_zip
|
||||
- ins_addr1
|
||||
- ins_addr2
|
||||
- ins_city
|
||||
- ins_co_id
|
||||
- ins_co_nm
|
||||
- ins_ct_fn
|
||||
- ins_ct_ln
|
||||
- ins_ct_ph
|
||||
- ins_ct_phx
|
||||
- ins_ctry
|
||||
- insd_addr1
|
||||
- insd_addr2
|
||||
- insd_city
|
||||
- insd_co_nm
|
||||
- insd_ctry
|
||||
- insd_ea
|
||||
- insd_fax
|
||||
- insd_faxx
|
||||
- insd_fn
|
||||
- insd_ln
|
||||
- insd_ph1
|
||||
- insd_ph1x
|
||||
- insd_ph2
|
||||
- insd_ph2x
|
||||
- insd_st
|
||||
- insd_title
|
||||
- insd_zip
|
||||
- ins_ea
|
||||
- ins_fax
|
||||
- ins_faxx
|
||||
- ins_memo
|
||||
- ins_ph1
|
||||
- ins_ph1x
|
||||
- ins_ph2
|
||||
- ins_ph2x
|
||||
- ins_st
|
||||
- ins_title
|
||||
- ins_zip
|
||||
- labor_rate_desc
|
||||
- labor_rate_id
|
||||
- loss_cat
|
||||
- loss_desc
|
||||
- loss_type
|
||||
- ownr_addr1
|
||||
- ownr_addr2
|
||||
- ownr_city
|
||||
- ownr_co_nm
|
||||
- ownr_ctry
|
||||
- ownr_ea
|
||||
- ownr_fax
|
||||
- ownr_faxx
|
||||
- ownr_fn
|
||||
- ownr_ln
|
||||
- ownr_ph1
|
||||
- ownr_ph1x
|
||||
- ownr_ph2
|
||||
- ownr_ph2x
|
||||
- ownr_st
|
||||
- ownr_title
|
||||
- ownr_zip
|
||||
- pay_chknm
|
||||
- payee_nms
|
||||
- pay_type
|
||||
- policy_no
|
||||
- po_number
|
||||
- referral_source
|
||||
- regie_number
|
||||
- ro_number
|
||||
- selling_dealer
|
||||
- selling_dealer_contact
|
||||
- service_car
|
||||
- servicing_dealer
|
||||
- servicing_dealer_contact
|
||||
- unit_number
|
||||
- actual_completion
|
||||
- actual_delivery
|
||||
- actual_in
|
||||
- created_at
|
||||
- date_closed
|
||||
- date_estimated
|
||||
- date_exported
|
||||
- date_invoiced
|
||||
- date_open
|
||||
- date_scheduled
|
||||
- scheduled_completion
|
||||
- scheduled_delivery
|
||||
- scheduled_in
|
||||
- updated_at
|
||||
- id
|
||||
- ownerid
|
||||
- shopid
|
||||
- statusid
|
||||
- vehicleid
|
||||
- tax_pstthr
|
||||
- tax_sub_rt
|
||||
- tax_tow_rt
|
||||
computed_fields: []
|
||||
filter:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: create_select_permission
|
||||
@@ -0,0 +1,241 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: drop_select_permission
|
||||
- args:
|
||||
permission:
|
||||
allow_aggregations: false
|
||||
columns:
|
||||
- actual_completion
|
||||
- actual_delivery
|
||||
- actual_in
|
||||
- adj_g_disc
|
||||
- adj_strdis
|
||||
- adj_towdis
|
||||
- adjustment_bottom_line
|
||||
- agt_addr1
|
||||
- agt_addr2
|
||||
- agt_city
|
||||
- agt_co_id
|
||||
- agt_co_nm
|
||||
- agt_ct_fn
|
||||
- agt_ct_ln
|
||||
- agt_ct_ph
|
||||
- agt_ct_phx
|
||||
- agt_ctry
|
||||
- agt_ea
|
||||
- agt_fax
|
||||
- agt_faxx
|
||||
- agt_lic_no
|
||||
- agt_ph1
|
||||
- agt_ph1x
|
||||
- agt_ph2
|
||||
- agt_ph2x
|
||||
- agt_st
|
||||
- agt_zip
|
||||
- area_of_damage
|
||||
- asgn_date
|
||||
- asgn_no
|
||||
- asgn_type
|
||||
- cat_no
|
||||
- ciecaid
|
||||
- clm_addr1
|
||||
- clm_addr2
|
||||
- clm_city
|
||||
- clm_ct_fn
|
||||
- clm_ct_ln
|
||||
- clm_ct_ph
|
||||
- clm_ct_phx
|
||||
- clm_ctry
|
||||
- clm_ea
|
||||
- clm_fax
|
||||
- clm_faxx
|
||||
- clm_no
|
||||
- clm_ofc_id
|
||||
- clm_ofc_nm
|
||||
- clm_ph1
|
||||
- clm_ph1x
|
||||
- clm_ph2
|
||||
- clm_ph2x
|
||||
- clm_st
|
||||
- clm_title
|
||||
- clm_total
|
||||
- clm_zip
|
||||
- converted
|
||||
- created_at
|
||||
- csr
|
||||
- cust_pr
|
||||
- date_closed
|
||||
- date_estimated
|
||||
- date_exported
|
||||
- date_invoiced
|
||||
- date_open
|
||||
- date_scheduled
|
||||
- ded_amt
|
||||
- ded_status
|
||||
- deductible
|
||||
- depreciation_taxes
|
||||
- est_addr1
|
||||
- est_addr2
|
||||
- est_city
|
||||
- est_co_nm
|
||||
- est_ct_fn
|
||||
- est_ct_ln
|
||||
- est_ctry
|
||||
- est_ea
|
||||
- est_number
|
||||
- est_ph1
|
||||
- est_st
|
||||
- est_zip
|
||||
- federal_tax_payable
|
||||
- federal_tax_rate
|
||||
- id
|
||||
- inproduction
|
||||
- ins_addr1
|
||||
- ins_addr2
|
||||
- ins_city
|
||||
- ins_co_id
|
||||
- ins_co_nm
|
||||
- ins_ct_fn
|
||||
- ins_ct_ln
|
||||
- ins_ct_ph
|
||||
- ins_ct_phx
|
||||
- ins_ctry
|
||||
- ins_ea
|
||||
- ins_fax
|
||||
- ins_faxx
|
||||
- ins_memo
|
||||
- ins_ph1
|
||||
- ins_ph1x
|
||||
- ins_ph2
|
||||
- ins_ph2x
|
||||
- ins_st
|
||||
- ins_title
|
||||
- ins_zip
|
||||
- insd_addr1
|
||||
- insd_addr2
|
||||
- insd_city
|
||||
- insd_co_nm
|
||||
- insd_ctry
|
||||
- insd_ea
|
||||
- insd_fax
|
||||
- insd_faxx
|
||||
- insd_fn
|
||||
- insd_ln
|
||||
- insd_ph1
|
||||
- insd_ph1x
|
||||
- insd_ph2
|
||||
- insd_ph2x
|
||||
- insd_st
|
||||
- insd_title
|
||||
- insd_zip
|
||||
- invoice_date
|
||||
- kmin
|
||||
- kmout
|
||||
- labor_rate_desc
|
||||
- labor_rate_id
|
||||
- local_tax_rate
|
||||
- loss_cat
|
||||
- loss_date
|
||||
- loss_desc
|
||||
- loss_type
|
||||
- other_amount_payable
|
||||
- owner_owing
|
||||
- ownerid
|
||||
- ownr_addr1
|
||||
- ownr_addr2
|
||||
- ownr_city
|
||||
- ownr_co_nm
|
||||
- ownr_ctry
|
||||
- ownr_ea
|
||||
- ownr_fax
|
||||
- ownr_faxx
|
||||
- ownr_fn
|
||||
- ownr_ln
|
||||
- ownr_ph1
|
||||
- ownr_ph1x
|
||||
- ownr_ph2
|
||||
- ownr_ph2x
|
||||
- ownr_st
|
||||
- ownr_title
|
||||
- ownr_zip
|
||||
- pay_amt
|
||||
- pay_chknm
|
||||
- pay_date
|
||||
- pay_type
|
||||
- payee_nms
|
||||
- po_number
|
||||
- policy_no
|
||||
- rate_atp
|
||||
- rate_la1
|
||||
- rate_la2
|
||||
- rate_la3
|
||||
- rate_la4
|
||||
- rate_laa
|
||||
- rate_lab
|
||||
- rate_lad
|
||||
- rate_lae
|
||||
- rate_laf
|
||||
- rate_lag
|
||||
- rate_lam
|
||||
- rate_lar
|
||||
- rate_las
|
||||
- rate_lau
|
||||
- rate_ma2s
|
||||
- rate_ma2t
|
||||
- rate_ma3s
|
||||
- rate_mabl
|
||||
- rate_macs
|
||||
- rate_mahw
|
||||
- rate_mapa
|
||||
- rate_mash
|
||||
- rate_matd
|
||||
- referral_source
|
||||
- regie_number
|
||||
- ro_number
|
||||
- scheduled_completion
|
||||
- scheduled_delivery
|
||||
- scheduled_in
|
||||
- selling_dealer
|
||||
- selling_dealer_contact
|
||||
- service_car
|
||||
- servicing_dealer
|
||||
- servicing_dealer_contact
|
||||
- shopid
|
||||
- special_coverage_policy
|
||||
- state_tax_rate
|
||||
- statusid
|
||||
- storage_payable
|
||||
- tax_lbr_rt
|
||||
- tax_levies_rt
|
||||
- tax_paint_mat_rt
|
||||
- tax_predis
|
||||
- tax_prethr
|
||||
- tax_pstthr
|
||||
- tax_str_rt
|
||||
- tax_sub_rt
|
||||
- tax_thramt
|
||||
- tax_tow_rt
|
||||
- theft_ind
|
||||
- tlos_ind
|
||||
- towing_payable
|
||||
- unit_number
|
||||
- updated_at
|
||||
- vehicleid
|
||||
computed_fields: []
|
||||
filter:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: create_select_permission
|
||||
@@ -0,0 +1,244 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: drop_update_permission
|
||||
- args:
|
||||
permission:
|
||||
columns:
|
||||
- converted
|
||||
- inproduction
|
||||
- special_coverage_policy
|
||||
- theft_ind
|
||||
- tlos_ind
|
||||
- asgn_date
|
||||
- invoice_date
|
||||
- loss_date
|
||||
- pay_date
|
||||
- kmin
|
||||
- kmout
|
||||
- est_number
|
||||
- area_of_damage
|
||||
- adj_g_disc
|
||||
- adj_strdis
|
||||
- adj_towdis
|
||||
- adjustment_bottom_line
|
||||
- claim_total
|
||||
- clm_total
|
||||
- ded_amt
|
||||
- deductible
|
||||
- depreciation_taxes
|
||||
- federal_tax_payable
|
||||
- federal_tax_rate
|
||||
- local_tax_rate
|
||||
- other_amount_payable
|
||||
- owner_owing
|
||||
- pay_amt
|
||||
- rate_atp
|
||||
- rate_la1
|
||||
- rate_la2
|
||||
- rate_la3
|
||||
- rate_la4
|
||||
- rate_laa
|
||||
- rate_lab
|
||||
- rate_lad
|
||||
- rate_lae
|
||||
- rate_laf
|
||||
- rate_lag
|
||||
- rate_lam
|
||||
- rate_lar
|
||||
- rate_las
|
||||
- rate_lau
|
||||
- rate_ma2s
|
||||
- rate_ma2t
|
||||
- rate_ma3s
|
||||
- rate_mabl
|
||||
- rate_macs
|
||||
- rate_mahw
|
||||
- rate_mapa
|
||||
- rate_mash
|
||||
- rate_matd
|
||||
- state_tax_rate
|
||||
- storage_payable
|
||||
- tax_lbr_rt
|
||||
- tax_levies_rt
|
||||
- tax_paint_mat_rt
|
||||
- tax_predis
|
||||
- tax_prethr
|
||||
- tax_str_rt
|
||||
- tax_thramt
|
||||
- towing_payable
|
||||
- agt_addr1
|
||||
- agt_addr2
|
||||
- agt_city
|
||||
- agt_co_id
|
||||
- agt_co_nm
|
||||
- agt_ct_fn
|
||||
- agt_ct_ln
|
||||
- agt_ct_ph
|
||||
- agt_ct_phx
|
||||
- agt_ctry
|
||||
- agt_ea
|
||||
- agt_fax
|
||||
- agt_faxx
|
||||
- agt_lic_no
|
||||
- agt_ph1
|
||||
- agt_ph1x
|
||||
- agt_ph2
|
||||
- agt_ph2x
|
||||
- agt_st
|
||||
- agt_zip
|
||||
- asgn_no
|
||||
- asgn_type
|
||||
- cat_no
|
||||
- ciecaid
|
||||
- clm_addr1
|
||||
- clm_addr2
|
||||
- clm_city
|
||||
- clm_ct_fn
|
||||
- clm_ct_ln
|
||||
- clm_ct_ph
|
||||
- clm_ct_phx
|
||||
- clm_ctry
|
||||
- clm_ea
|
||||
- clm_fax
|
||||
- clm_faxx
|
||||
- clm_no
|
||||
- clm_ofc_id
|
||||
- clm_ofc_nm
|
||||
- clm_ph1
|
||||
- clm_ph1x
|
||||
- clm_ph2
|
||||
- clm_ph2x
|
||||
- clm_st
|
||||
- clm_title
|
||||
- clm_zip
|
||||
- csr
|
||||
- cust_pr
|
||||
- ded_status
|
||||
- est_addr1
|
||||
- est_addr2
|
||||
- est_city
|
||||
- est_co_nm
|
||||
- est_ct_fn
|
||||
- est_ct_ln
|
||||
- est_ctry
|
||||
- est_ea
|
||||
- est_ph1
|
||||
- est_st
|
||||
- est_zip
|
||||
- ins_addr1
|
||||
- ins_addr2
|
||||
- ins_city
|
||||
- ins_co_id
|
||||
- ins_co_nm
|
||||
- ins_ct_fn
|
||||
- ins_ct_ln
|
||||
- ins_ct_ph
|
||||
- ins_ct_phx
|
||||
- ins_ctry
|
||||
- insd_addr1
|
||||
- insd_addr2
|
||||
- insd_city
|
||||
- insd_co_nm
|
||||
- insd_ctry
|
||||
- insd_ea
|
||||
- insd_fax
|
||||
- insd_faxx
|
||||
- insd_fn
|
||||
- insd_ln
|
||||
- insd_ph1
|
||||
- insd_ph1x
|
||||
- insd_ph2
|
||||
- insd_ph2x
|
||||
- insd_st
|
||||
- insd_title
|
||||
- insd_zip
|
||||
- ins_ea
|
||||
- ins_fax
|
||||
- ins_faxx
|
||||
- ins_memo
|
||||
- ins_ph1
|
||||
- ins_ph1x
|
||||
- ins_ph2
|
||||
- ins_ph2x
|
||||
- ins_st
|
||||
- ins_title
|
||||
- ins_zip
|
||||
- labor_rate_desc
|
||||
- labor_rate_id
|
||||
- loss_cat
|
||||
- loss_desc
|
||||
- loss_type
|
||||
- ownr_addr1
|
||||
- ownr_addr2
|
||||
- ownr_city
|
||||
- ownr_co_nm
|
||||
- ownr_ctry
|
||||
- ownr_ea
|
||||
- ownr_fax
|
||||
- ownr_faxx
|
||||
- ownr_fn
|
||||
- ownr_ln
|
||||
- ownr_ph1
|
||||
- ownr_ph1x
|
||||
- ownr_ph2
|
||||
- ownr_ph2x
|
||||
- ownr_st
|
||||
- ownr_title
|
||||
- ownr_zip
|
||||
- pay_chknm
|
||||
- payee_nms
|
||||
- pay_type
|
||||
- policy_no
|
||||
- po_number
|
||||
- referral_source
|
||||
- regie_number
|
||||
- ro_number
|
||||
- selling_dealer
|
||||
- selling_dealer_contact
|
||||
- service_car
|
||||
- servicing_dealer
|
||||
- servicing_dealer_contact
|
||||
- unit_number
|
||||
- actual_completion
|
||||
- actual_delivery
|
||||
- actual_in
|
||||
- created_at
|
||||
- date_closed
|
||||
- date_estimated
|
||||
- date_exported
|
||||
- date_invoiced
|
||||
- date_open
|
||||
- date_scheduled
|
||||
- scheduled_completion
|
||||
- scheduled_delivery
|
||||
- scheduled_in
|
||||
- updated_at
|
||||
- id
|
||||
- ownerid
|
||||
- shopid
|
||||
- statusid
|
||||
- vehicleid
|
||||
- tax_pstthr
|
||||
- tax_sub_rt
|
||||
- tax_tow_rt
|
||||
filter:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
localPresets:
|
||||
- key: ""
|
||||
value: ""
|
||||
set: {}
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: create_update_permission
|
||||
@@ -0,0 +1,243 @@
|
||||
- args:
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: drop_update_permission
|
||||
- args:
|
||||
permission:
|
||||
columns:
|
||||
- actual_completion
|
||||
- actual_delivery
|
||||
- actual_in
|
||||
- adj_g_disc
|
||||
- adj_strdis
|
||||
- adj_towdis
|
||||
- adjustment_bottom_line
|
||||
- agt_addr1
|
||||
- agt_addr2
|
||||
- agt_city
|
||||
- agt_co_id
|
||||
- agt_co_nm
|
||||
- agt_ct_fn
|
||||
- agt_ct_ln
|
||||
- agt_ct_ph
|
||||
- agt_ct_phx
|
||||
- agt_ctry
|
||||
- agt_ea
|
||||
- agt_fax
|
||||
- agt_faxx
|
||||
- agt_lic_no
|
||||
- agt_ph1
|
||||
- agt_ph1x
|
||||
- agt_ph2
|
||||
- agt_ph2x
|
||||
- agt_st
|
||||
- agt_zip
|
||||
- area_of_damage
|
||||
- asgn_date
|
||||
- asgn_no
|
||||
- asgn_type
|
||||
- cat_no
|
||||
- ciecaid
|
||||
- clm_addr1
|
||||
- clm_addr2
|
||||
- clm_city
|
||||
- clm_ct_fn
|
||||
- clm_ct_ln
|
||||
- clm_ct_ph
|
||||
- clm_ct_phx
|
||||
- clm_ctry
|
||||
- clm_ea
|
||||
- clm_fax
|
||||
- clm_faxx
|
||||
- clm_no
|
||||
- clm_ofc_id
|
||||
- clm_ofc_nm
|
||||
- clm_ph1
|
||||
- clm_ph1x
|
||||
- clm_ph2
|
||||
- clm_ph2x
|
||||
- clm_st
|
||||
- clm_title
|
||||
- clm_total
|
||||
- clm_zip
|
||||
- converted
|
||||
- created_at
|
||||
- csr
|
||||
- cust_pr
|
||||
- date_closed
|
||||
- date_estimated
|
||||
- date_exported
|
||||
- date_invoiced
|
||||
- date_open
|
||||
- date_scheduled
|
||||
- ded_amt
|
||||
- ded_status
|
||||
- deductible
|
||||
- depreciation_taxes
|
||||
- est_addr1
|
||||
- est_addr2
|
||||
- est_city
|
||||
- est_co_nm
|
||||
- est_ct_fn
|
||||
- est_ct_ln
|
||||
- est_ctry
|
||||
- est_ea
|
||||
- est_number
|
||||
- est_ph1
|
||||
- est_st
|
||||
- est_zip
|
||||
- federal_tax_payable
|
||||
- federal_tax_rate
|
||||
- id
|
||||
- inproduction
|
||||
- ins_addr1
|
||||
- ins_addr2
|
||||
- ins_city
|
||||
- ins_co_id
|
||||
- ins_co_nm
|
||||
- ins_ct_fn
|
||||
- ins_ct_ln
|
||||
- ins_ct_ph
|
||||
- ins_ct_phx
|
||||
- ins_ctry
|
||||
- ins_ea
|
||||
- ins_fax
|
||||
- ins_faxx
|
||||
- ins_memo
|
||||
- ins_ph1
|
||||
- ins_ph1x
|
||||
- ins_ph2
|
||||
- ins_ph2x
|
||||
- ins_st
|
||||
- ins_title
|
||||
- ins_zip
|
||||
- insd_addr1
|
||||
- insd_addr2
|
||||
- insd_city
|
||||
- insd_co_nm
|
||||
- insd_ctry
|
||||
- insd_ea
|
||||
- insd_fax
|
||||
- insd_faxx
|
||||
- insd_fn
|
||||
- insd_ln
|
||||
- insd_ph1
|
||||
- insd_ph1x
|
||||
- insd_ph2
|
||||
- insd_ph2x
|
||||
- insd_st
|
||||
- insd_title
|
||||
- insd_zip
|
||||
- invoice_date
|
||||
- kmin
|
||||
- kmout
|
||||
- labor_rate_desc
|
||||
- labor_rate_id
|
||||
- local_tax_rate
|
||||
- loss_cat
|
||||
- loss_date
|
||||
- loss_desc
|
||||
- loss_type
|
||||
- other_amount_payable
|
||||
- owner_owing
|
||||
- ownerid
|
||||
- ownr_addr1
|
||||
- ownr_addr2
|
||||
- ownr_city
|
||||
- ownr_co_nm
|
||||
- ownr_ctry
|
||||
- ownr_ea
|
||||
- ownr_fax
|
||||
- ownr_faxx
|
||||
- ownr_fn
|
||||
- ownr_ln
|
||||
- ownr_ph1
|
||||
- ownr_ph1x
|
||||
- ownr_ph2
|
||||
- ownr_ph2x
|
||||
- ownr_st
|
||||
- ownr_title
|
||||
- ownr_zip
|
||||
- pay_amt
|
||||
- pay_chknm
|
||||
- pay_date
|
||||
- pay_type
|
||||
- payee_nms
|
||||
- po_number
|
||||
- policy_no
|
||||
- rate_atp
|
||||
- rate_la1
|
||||
- rate_la2
|
||||
- rate_la3
|
||||
- rate_la4
|
||||
- rate_laa
|
||||
- rate_lab
|
||||
- rate_lad
|
||||
- rate_lae
|
||||
- rate_laf
|
||||
- rate_lag
|
||||
- rate_lam
|
||||
- rate_lar
|
||||
- rate_las
|
||||
- rate_lau
|
||||
- rate_ma2s
|
||||
- rate_ma2t
|
||||
- rate_ma3s
|
||||
- rate_mabl
|
||||
- rate_macs
|
||||
- rate_mahw
|
||||
- rate_mapa
|
||||
- rate_mash
|
||||
- rate_matd
|
||||
- referral_source
|
||||
- regie_number
|
||||
- ro_number
|
||||
- scheduled_completion
|
||||
- scheduled_delivery
|
||||
- scheduled_in
|
||||
- selling_dealer
|
||||
- selling_dealer_contact
|
||||
- service_car
|
||||
- servicing_dealer
|
||||
- servicing_dealer_contact
|
||||
- shopid
|
||||
- special_coverage_policy
|
||||
- state_tax_rate
|
||||
- statusid
|
||||
- storage_payable
|
||||
- tax_lbr_rt
|
||||
- tax_levies_rt
|
||||
- tax_paint_mat_rt
|
||||
- tax_predis
|
||||
- tax_prethr
|
||||
- tax_pstthr
|
||||
- tax_str_rt
|
||||
- tax_sub_rt
|
||||
- tax_thramt
|
||||
- tax_tow_rt
|
||||
- theft_ind
|
||||
- tlos_ind
|
||||
- towing_payable
|
||||
- unit_number
|
||||
- updated_at
|
||||
- vehicleid
|
||||
filter:
|
||||
bodyshop:
|
||||
associations:
|
||||
_and:
|
||||
- user:
|
||||
authid:
|
||||
_eq: X-Hasura-User-Id
|
||||
- active:
|
||||
_eq: true
|
||||
localPresets:
|
||||
- key: ""
|
||||
value: ""
|
||||
set: {}
|
||||
role: user
|
||||
table:
|
||||
name: jobs
|
||||
schema: public
|
||||
type: create_update_permission
|
||||
@@ -0,0 +1,9 @@
|
||||
- args:
|
||||
sql: ALTER TABLE "public"."jobs" ADD COLUMN "claim_total" numeric
|
||||
type: run_sql
|
||||
- args:
|
||||
sql: ALTER TABLE "public"."jobs" ALTER COLUMN "claim_total" DROP NOT NULL
|
||||
type: run_sql
|
||||
- args:
|
||||
sql: ALTER TABLE "public"."jobs" ALTER COLUMN "claim_total" SET DEFAULT 0
|
||||
type: run_sql
|
||||
@@ -0,0 +1,3 @@
|
||||
- args:
|
||||
sql: ALTER TABLE "public"."jobs" DROP COLUMN "claim_total" CASCADE
|
||||
type: run_sql
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
sql: ALTER TABLE ONLY "public"."jobs" ALTER COLUMN "clm_total" SET DEFAULT 0;
|
||||
type: run_sql
|
||||
- args:
|
||||
sql: COMMENT ON COLUMN "public"."jobs"."clm_total" IS E'null'
|
||||
type: run_sql
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
sql: ALTER TABLE ONLY "public"."jobs" ALTER COLUMN "clm_total" SET DEFAULT 0;
|
||||
type: run_sql
|
||||
- args:
|
||||
sql: COMMENT ON COLUMN "public"."jobs"."clm_total" IS E''
|
||||
type: run_sql
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: anonymous
|
||||
table:
|
||||
name: users
|
||||
schema: public
|
||||
type: drop_select_permission
|
||||
@@ -0,0 +1,12 @@
|
||||
- args:
|
||||
permission:
|
||||
allow_aggregations: false
|
||||
columns:
|
||||
- authid
|
||||
filter: {}
|
||||
limit: null
|
||||
role: anonymous
|
||||
table:
|
||||
name: users
|
||||
schema: public
|
||||
type: create_select_permission
|
||||
@@ -0,0 +1,17 @@
|
||||
- args:
|
||||
permission:
|
||||
columns:
|
||||
- authid
|
||||
- email
|
||||
- created_at
|
||||
- updated_at
|
||||
filter: {}
|
||||
localPresets:
|
||||
- key: ""
|
||||
value: ""
|
||||
set: {}
|
||||
role: anonymous
|
||||
table:
|
||||
name: users
|
||||
schema: public
|
||||
type: create_update_permission
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: anonymous
|
||||
table:
|
||||
name: users
|
||||
schema: public
|
||||
type: drop_update_permission
|
||||
@@ -0,0 +1,17 @@
|
||||
- args:
|
||||
permission:
|
||||
check: {}
|
||||
columns:
|
||||
- authid
|
||||
- created_at
|
||||
- email
|
||||
- updated_at
|
||||
localPresets:
|
||||
- key: ""
|
||||
value: ""
|
||||
set: {}
|
||||
role: anonymous
|
||||
table:
|
||||
name: users
|
||||
schema: public
|
||||
type: create_insert_permission
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: anonymous
|
||||
table:
|
||||
name: users
|
||||
schema: public
|
||||
type: drop_insert_permission
|
||||
@@ -0,0 +1,12 @@
|
||||
- args:
|
||||
permission:
|
||||
allow_aggregations: false
|
||||
columns:
|
||||
- authid
|
||||
computed_fields: []
|
||||
filter: {}
|
||||
role: anonymous
|
||||
table:
|
||||
name: users
|
||||
schema: public
|
||||
type: create_select_permission
|
||||
@@ -0,0 +1,6 @@
|
||||
- args:
|
||||
role: anonymous
|
||||
table:
|
||||
name: users
|
||||
schema: public
|
||||
type: drop_select_permission
|
||||
@@ -0,0 +1,3 @@
|
||||
- args:
|
||||
sql: ALTER TABLE "public"."appointments" DROP COLUMN "canceled";
|
||||
type: run_sql
|
||||
@@ -0,0 +1,4 @@
|
||||
- args:
|
||||
sql: ALTER TABLE "public"."appointments" ADD COLUMN "canceled" boolean NOT NULL
|
||||
DEFAULT false;
|
||||
type: run_sql
|
||||
@@ -0,0 +1,3 @@
|
||||
- args:
|
||||
sql: ALTER TABLE "public"."appointments" DROP COLUMN "arrived";
|
||||
type: run_sql
|
||||
@@ -0,0 +1,4 @@
|
||||
- args:
|
||||
sql: ALTER TABLE "public"."appointments" ADD COLUMN "arrived" boolean NOT NULL
|
||||
DEFAULT false;
|
||||
type: run_sql
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user