Added shift clock framework + login on tech console BOD-97 BOD-188
This commit is contained in:
@@ -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
|
BabelEdit project file
|
||||||
@@ -17556,6 +17556,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>memo</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>
|
<concept_node>
|
||||||
<name>productivehrs</name>
|
<name>productivehrs</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -17624,6 +17645,48 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>ambreak</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>amshift</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>
|
<concept_node>
|
||||||
<name>clockintojob</name>
|
<name>clockintojob</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -17708,6 +17771,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>lunch</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>
|
<concept_node>
|
||||||
<name>new</name>
|
<name>new</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -17729,6 +17813,90 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>pmbreak</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>pmshift</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>shift</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>shiftalreadyclockedon</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>
|
<concept_node>
|
||||||
<name>straight_time</name>
|
<name>straight_time</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -55,7 +55,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: .25rem;
|
width: 0.25rem;
|
||||||
|
max-height: 0.25rem;
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -155,6 +155,9 @@ export function ShopEmployeesFormComponent({
|
|||||||
]}>
|
]}>
|
||||||
<InputNumber />
|
<InputNumber />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item label={t("employees.fields.user_email")} name='user_email'>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
</Form>
|
</Form>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import {
|
|||||||
DELETE_EMPLOYEE,
|
DELETE_EMPLOYEE,
|
||||||
INSERT_EMPLOYEES,
|
INSERT_EMPLOYEES,
|
||||||
QUERY_EMPLOYEES,
|
QUERY_EMPLOYEES,
|
||||||
UPDATE_EMPLOYEE
|
UPDATE_EMPLOYEE,
|
||||||
} from "../../graphql/employees.queries";
|
} from "../../graphql/employees.queries";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import ShopEmployeeComponent from "./shop-employees.component";
|
import ShopEmployeeComponent from "./shop-employees.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop,
|
||||||
});
|
});
|
||||||
|
|
||||||
function ShopEmployeesContainer({ bodyshop }) {
|
function ShopEmployeesContainer({ bodyshop }) {
|
||||||
@@ -23,69 +23,75 @@ function ShopEmployeesContainer({ bodyshop }) {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const employeeState = useState(null);
|
const employeeState = useState(null);
|
||||||
const { loading, error, data, refetch } = useQuery(QUERY_EMPLOYEES, {
|
const { loading, error, data, refetch } = useQuery(QUERY_EMPLOYEES, {
|
||||||
fetchPolicy: "network-only"
|
fetchPolicy: "network-only",
|
||||||
});
|
});
|
||||||
|
|
||||||
const [updateEmployee] = useMutation(UPDATE_EMPLOYEE);
|
const [updateEmployee] = useMutation(UPDATE_EMPLOYEE);
|
||||||
const [insertEmployees] = useMutation(INSERT_EMPLOYEES);
|
const [insertEmployees] = useMutation(INSERT_EMPLOYEES);
|
||||||
const [deleteEmployee] = useMutation(DELETE_EMPLOYEE);
|
const [deleteEmployee] = useMutation(DELETE_EMPLOYEE);
|
||||||
const handleDelete = id => {
|
const handleDelete = (id) => {
|
||||||
deleteEmployee({ variables: { id: id } })
|
deleteEmployee({ variables: { id: id } })
|
||||||
.then(r => {
|
.then((r) => {
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("employees.successes.delete")
|
message: t("employees.successes.delete"),
|
||||||
});
|
});
|
||||||
//TODO Better way to reset the field decorators?
|
//TODO Better way to reset the field decorators?
|
||||||
employeeState[1](null);
|
employeeState[1](null);
|
||||||
refetch().then(r => form.resetFields());
|
refetch().then((r) => form.resetFields());
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("employees.errors.delete")
|
message: t("employees.errors.delete", {
|
||||||
|
message: JSON.stringify(error),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFinish = values => {
|
const handleFinish = (values) => {
|
||||||
console.log("values", values);
|
console.log("values", values);
|
||||||
if (employeeState[0].id) {
|
if (employeeState[0].id) {
|
||||||
//Update a record.
|
//Update a record.
|
||||||
updateEmployee({
|
updateEmployee({
|
||||||
variables: { id: employeeState[0].id, employee: values }
|
variables: { id: employeeState[0].id, employee: values },
|
||||||
})
|
})
|
||||||
.then(r => {
|
.then((r) => {
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("employees.successes.save")
|
message: t("employees.successes.save"),
|
||||||
});
|
});
|
||||||
//TODO Better way to reset the field decorators?
|
//TODO Better way to reset the field decorators?
|
||||||
employeeState[1](null);
|
employeeState[1](null);
|
||||||
refetch().then(r => form.resetFields());
|
refetch().then((r) => form.resetFields());
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch((error) => {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("employees.errors.save")
|
message: t("employees.errors.save", {
|
||||||
|
message: JSON.stringify(error),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
//New record, insert it.
|
//New record, insert it.
|
||||||
insertEmployees({
|
insertEmployees({
|
||||||
variables: { employees: [{ ...values, shopid: bodyshop.id }] }
|
variables: { employees: [{ ...values, shopid: bodyshop.id }] },
|
||||||
}).then(r => {
|
}).then((r) => {
|
||||||
notification["success"]({
|
notification["success"]({
|
||||||
message: t("employees.successes.save")
|
message: t("employees.successes.save"),
|
||||||
});
|
});
|
||||||
//TODO Better way to reset the field decorators?
|
//TODO Better way to reset the field decorators?
|
||||||
employeeState[1](null);
|
employeeState[1](null);
|
||||||
refetch().catch(error => {
|
refetch().catch((error) => {
|
||||||
notification["error"]({
|
notification["error"]({
|
||||||
message: t("employees.errors.save")
|
message: t("employees.errors.save", {
|
||||||
|
message: JSON.stringify(error),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
if (error) return <AlertComponent message={error.message} type='error' />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ShopEmployeeComponent
|
<ShopEmployeeComponent
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Button, Form, notification, Card } from "antd";
|
import { Button, Card, Form, notification } from "antd";
|
||||||
import React from "react";
|
import axios from "axios";
|
||||||
|
import React, { useState } from "react";
|
||||||
import { useMutation } from "react-apollo";
|
import { useMutation } from "react-apollo";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -16,29 +17,35 @@ const mapStateToProps = createStructuredSelector({
|
|||||||
|
|
||||||
export function TechClockInContainer({ technician, bodyshop }) {
|
export function TechClockInContainer({ technician, bodyshop }) {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
const [insertTimeTicket] = useMutation(INSERT_NEW_TIME_TICKET, {
|
const [insertTimeTicket] = useMutation(INSERT_NEW_TIME_TICKET, {
|
||||||
refetchQueries: ["QUERY_ACTIVE_TIME_TICKETS"],
|
refetchQueries: ["QUERY_ACTIVE_TIME_TICKETS"],
|
||||||
});
|
});
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
|
setLoading(true);
|
||||||
|
const theTime = (await axios.post("/utils/time")).data;
|
||||||
const result = await insertTimeTicket({
|
const result = await insertTimeTicket({
|
||||||
variables: {
|
variables: {
|
||||||
timeTicketInput: {
|
timeTicketInput: [
|
||||||
employeeid: technician.id,
|
{
|
||||||
date: new Date(),
|
bodyshopid: bodyshop.id,
|
||||||
clockon: new Date(),
|
employeeid: technician.id,
|
||||||
jobid: values.jobid,
|
date: theTime,
|
||||||
cost_center: technician.cost_center,
|
clockon: theTime,
|
||||||
ciecacode: Object.keys(
|
jobid: values.jobid,
|
||||||
bodyshop.md_responsibility_centers.defaults.costs
|
cost_center: technician.cost_center,
|
||||||
).find((key) => {
|
ciecacode: Object.keys(
|
||||||
return (
|
bodyshop.md_responsibility_centers.defaults.costs
|
||||||
bodyshop.md_responsibility_centers.defaults.costs[key] ===
|
).find((key) => {
|
||||||
values.cost_center
|
return (
|
||||||
);
|
bodyshop.md_responsibility_centers.defaults.costs[key] ===
|
||||||
}),
|
values.cost_center
|
||||||
},
|
);
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -53,13 +60,14 @@ export function TechClockInContainer({ technician, bodyshop }) {
|
|||||||
message: t("timetickets.successes.clockedin"),
|
message: t("timetickets.successes.clockedin"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
setLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Card title={t("timetickets.labels.clockintojob")}>
|
<Card title={t("timetickets.labels.clockintojob")}>
|
||||||
<Form form={form} layout="vertical" onFinish={handleFinish}>
|
<Form form={form} layout='vertical' onFinish={handleFinish}>
|
||||||
<Button type="primary" htmlType="submit">
|
<Button type='primary' htmlType='submit' loading={loading}>
|
||||||
{t("timetickets.actions.clockin")}
|
{t("timetickets.actions.clockin")}
|
||||||
</Button>
|
</Button>
|
||||||
<TechClockInComponent form={form} />
|
<TechClockInComponent form={form} />
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { UPDATE_TIME_TICKET } from "../../graphql/timetickets.queries";
|
import { UPDATE_TIME_TICKET } from "../../graphql/timetickets.queries";
|
||||||
|
import axios from "axios";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
@@ -27,6 +27,7 @@ export function TechClockOffButton({
|
|||||||
technician,
|
technician,
|
||||||
timeTicketId,
|
timeTicketId,
|
||||||
completedCallback,
|
completedCallback,
|
||||||
|
isShiftTicket,
|
||||||
otherBtnProps,
|
otherBtnProps,
|
||||||
}) {
|
}) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
@@ -40,7 +41,10 @@ export function TechClockOffButton({
|
|||||||
const result = await updateTimeticket({
|
const result = await updateTimeticket({
|
||||||
variables: {
|
variables: {
|
||||||
timeticketId: timeTicketId,
|
timeticketId: timeTicketId,
|
||||||
timeticket: { clockoff: new Date(), ...values },
|
timeticket: {
|
||||||
|
clockoff: (await axios.post("/utils/time")).data,
|
||||||
|
...values,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -64,65 +68,76 @@ export function TechClockOffButton({
|
|||||||
<div>
|
<div>
|
||||||
<Form
|
<Form
|
||||||
form={form}
|
form={form}
|
||||||
layout="vertical"
|
layout='vertical'
|
||||||
onFinish={handleFinish}
|
onFinish={handleFinish}
|
||||||
initialValues={{
|
initialValues={{
|
||||||
cost_center: technician ? technician.cost_center : null,
|
cost_center: isShiftTicket
|
||||||
}}
|
? "timetickets.labels.shift"
|
||||||
>
|
: technician
|
||||||
|
? technician.cost_center
|
||||||
|
: null,
|
||||||
|
}}>
|
||||||
|
{!isShiftTicket ? (
|
||||||
|
<div>
|
||||||
|
<Form.Item
|
||||||
|
label={t("timetickets.fields.actualhrs")}
|
||||||
|
name='actualhrs'
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<InputNumber precision={1} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label={t("timetickets.fields.productivehrs")}
|
||||||
|
name='productivehrs'
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<InputNumber precision={1} />
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("timetickets.fields.actualhrs")}
|
name='cost_center'
|
||||||
name="actualhrs"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<InputNumber precision={1} />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label={t("timetickets.fields.productivehrs")}
|
|
||||||
name="productivehrs"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<InputNumber precision={1} />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
name="cost_center"
|
|
||||||
label={t("timetickets.fields.cost_center")}
|
label={t("timetickets.fields.cost_center")}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: t("general.validation.required"),
|
message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
]}
|
]}>
|
||||||
>
|
<Select disabled={isShiftTicket}>
|
||||||
<Select>
|
{isShiftTicket ? (
|
||||||
{bodyshop.md_responsibility_centers.costs.map((i, idx) => (
|
<Select.Option value='timetickets.labels.shift'>
|
||||||
<Select.Option key={idx} value={i.name}>
|
{t("timetickets.labels.shift")}
|
||||||
{i.name}
|
|
||||||
</Select.Option>
|
</Select.Option>
|
||||||
))}
|
) : (
|
||||||
|
bodyshop.md_responsibility_centers.costs.map((i, idx) => (
|
||||||
|
<Select.Option key={idx} value={i.name}>
|
||||||
|
{i.name}
|
||||||
|
</Select.Option>
|
||||||
|
))
|
||||||
|
)}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Button type="primary" htmlType="submit">
|
<Button type='primary' htmlType='submit' loading={loading}>
|
||||||
{t("general.actions.save")}
|
{t("general.actions.save")}
|
||||||
</Button>
|
</Button>
|
||||||
<TechJobClockoutDelete timeTicketId={timeTicketId} />
|
<TechJobClockoutDelete completedCallback={completedCallback} timeTicketId={timeTicketId} />
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover content={overlay} trigger="click">
|
<Popover content={overlay} trigger='click'>
|
||||||
<Button loading={loading} {...otherBtnProps}>
|
<Button loading={loading} {...otherBtnProps}>
|
||||||
{t("timetickets.actions.clockout")}
|
{t("timetickets.actions.clockout")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import { DELETE_TIME_TICKET } from "../../graphql/timetickets.queries";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { useMutation } from "@apollo/react-hooks";
|
import { useMutation } from "@apollo/react-hooks";
|
||||||
|
|
||||||
export default function TechJobClockoutDelete({ timeTicketId }) {
|
export default function TechJobClockoutDelete({
|
||||||
|
timeTicketId,
|
||||||
|
completedCallback,
|
||||||
|
}) {
|
||||||
const [deleteTimeTicket] = useMutation(DELETE_TIME_TICKET);
|
const [deleteTimeTicket] = useMutation(DELETE_TIME_TICKET);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const handleDelete = async () => {
|
const handleDelete = async () => {
|
||||||
@@ -25,6 +28,7 @@ export default function TechJobClockoutDelete({ timeTicketId }) {
|
|||||||
message: t("timetickets.successes.deleted"),
|
message: t("timetickets.successes.deleted"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (completedCallback) completedCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -32,8 +36,7 @@ export default function TechJobClockoutDelete({ timeTicketId }) {
|
|||||||
title={t("timetickets.labels.deleteconfirm")}
|
title={t("timetickets.labels.deleteconfirm")}
|
||||||
okButtonProps={{ type: "danger" }}
|
okButtonProps={{ type: "danger" }}
|
||||||
okText={t("general.actions.delete")}
|
okText={t("general.actions.delete")}
|
||||||
onConfirm={handleDelete}
|
onConfirm={handleDelete}>
|
||||||
>
|
|
||||||
<DeleteFilled style={{ margin: "1rem", color: "red" }} />
|
<DeleteFilled style={{ margin: "1rem", color: "red" }} />
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,17 +2,17 @@ import { Card, List, Typography } from "antd";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useQuery } from "react-apollo";
|
import { useQuery } from "react-apollo";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
import { QUERY_ACTIVE_TIME_TICKETS } from "../../graphql/timetickets.queries";
|
import { QUERY_ACTIVE_TIME_TICKETS } from "../../graphql/timetickets.queries";
|
||||||
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import DataLabel from "../data-label/data-label.component";
|
import DataLabel from "../data-label/data-label.component";
|
||||||
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||||
import TechClockOffButton from "../tech-job-clock-out-button/tech-job-clock-out-button.component";
|
import TechClockOffButton from "../tech-job-clock-out-button/tech-job-clock-out-button.component";
|
||||||
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
|
||||||
|
|
||||||
import { connect } from "react-redux";
|
|
||||||
import { createStructuredSelector } from "reselect";
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
technician: selectTechnician,
|
technician: selectTechnician,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import Icon, { SearchOutlined } from "@ant-design/icons";
|
|||||||
import { Layout, Menu } from "antd";
|
import { Layout, Menu } from "antd";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { FaBusinessTime } from "react-icons/fa";
|
||||||
import { FiLogIn, FiLogOut } from "react-icons/fi";
|
import { FiLogIn, FiLogOut } from "react-icons/fi";
|
||||||
import { MdTimer } from "react-icons/md";
|
import { MdTimer } from "react-icons/md";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
@@ -9,6 +10,7 @@ import { Link } from "react-router-dom";
|
|||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { techLogout } from "../../redux/tech/tech.actions";
|
import { techLogout } from "../../redux/tech/tech.actions";
|
||||||
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
|
|
||||||
const { Sider } = Layout;
|
const { Sider } = Layout;
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
@@ -27,36 +29,39 @@ export function TechSider({ technician, techLogout }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Sider collapsible collapsed={collapsed} onCollapse={onCollapse}>
|
<Sider collapsible collapsed={collapsed} onCollapse={onCollapse}>
|
||||||
<Menu theme="dark" defaultSelectedKeys={["1"]} mode="inline">
|
<Menu theme='dark' defaultSelectedKeys={["1"]} mode='inline'>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key="1"
|
key='1'
|
||||||
disabled={!!technician}
|
disabled={!!technician}
|
||||||
icon={<Icon component={FiLogIn} />}
|
icon={<Icon component={FiLogIn} />}>
|
||||||
>
|
|
||||||
<Link to={`/tech/login`}>{t("menus.tech.login")}</Link>
|
<Link to={`/tech/login`}>{t("menus.tech.login")}</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="2" disabled={!!!technician} icon={<SearchOutlined />}>
|
<Menu.Item key='2' disabled={!!!technician} icon={<SearchOutlined />}>
|
||||||
<Link to={`/tech/joblookup`}>{t("menus.tech.joblookup")}</Link>
|
<Link to={`/tech/joblookup`}>{t("menus.tech.joblookup")}</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key="3"
|
key='3'
|
||||||
disabled={!!!technician}
|
disabled={!!!technician}
|
||||||
icon={<Icon component={MdTimer} />}
|
icon={<Icon component={FaBusinessTime} />}>
|
||||||
>
|
<Link to={`/tech/jobclock`}>{t("menus.tech.jobclockin")}</Link>
|
||||||
<Link to={`/tech/jobclockin`}>{t("menus.tech.jobclockin")}</Link>
|
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="5" disabled={!!!technician} icon={<SearchOutlined />}>
|
<Menu.Item
|
||||||
|
key='4'
|
||||||
|
disabled={!!!technician}
|
||||||
|
icon={<Icon component={MdTimer} />}>
|
||||||
|
<Link to={`/tech/shiftclock`}>{t("menus.tech.shiftclockin")}</Link>
|
||||||
|
</Menu.Item>
|
||||||
|
<Menu.Item key='5' disabled={!!!technician} icon={<SearchOutlined />}>
|
||||||
<Link to={`/tech/list`}>{t("menus.tech.productionlist")}</Link>
|
<Link to={`/tech/list`}>{t("menus.tech.productionlist")}</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item key="6" disabled={!!!technician} icon={<SearchOutlined />}>
|
<Menu.Item key='6' disabled={!!!technician} icon={<SearchOutlined />}>
|
||||||
<Link to={`/tech/board`}> {t("menus.tech.productionboard")}</Link>
|
<Link to={`/tech/board`}> {t("menus.tech.productionboard")}</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
key="7"
|
key='7'
|
||||||
disabled={!!!technician}
|
disabled={!!!technician}
|
||||||
onClick={() => techLogout()}
|
onClick={() => techLogout()}
|
||||||
icon={<Icon component={FiLogOut} />}
|
icon={<Icon component={FiLogOut} />}>
|
||||||
>
|
|
||||||
{t("menus.tech.logout")}
|
{t("menus.tech.logout")}
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
</Menu>
|
</Menu>
|
||||||
|
|||||||
@@ -19,15 +19,14 @@ export default function TimeTicketModalComponent({
|
|||||||
<div>
|
<div>
|
||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex" }}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="jobid"
|
name='jobid'
|
||||||
label={t("timetickets.fields.ro_number")}
|
label={t("timetickets.fields.ro_number")}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: t("general.validation.required"),
|
message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
]}
|
]}>
|
||||||
>
|
|
||||||
<JobSearchSelect
|
<JobSearchSelect
|
||||||
options={roAutoCompleteOptions}
|
options={roAutoCompleteOptions}
|
||||||
onBlur={() => {
|
onBlur={() => {
|
||||||
@@ -40,15 +39,14 @@ export default function TimeTicketModalComponent({
|
|||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="employeeid"
|
name='employeeid'
|
||||||
label={t("timetickets.fields.employee")}
|
label={t("timetickets.fields.employee")}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: t("general.validation.required"),
|
message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
]}
|
]}>
|
||||||
>
|
|
||||||
<EmployeeSearchSelect options={employeeAutoCompleteOptions} />
|
<EmployeeSearchSelect options={employeeAutoCompleteOptions} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
@@ -56,71 +54,65 @@ export default function TimeTicketModalComponent({
|
|||||||
<div style={{ display: "flex" }}>
|
<div style={{ display: "flex" }}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("timetickets.fields.date")}
|
label={t("timetickets.fields.date")}
|
||||||
name="date"
|
name='date'
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: t("general.validation.required"),
|
message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
]}
|
]}>
|
||||||
>
|
|
||||||
<DatePicker />
|
<DatePicker />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("timetickets.fields.productivehrs")}
|
label={t("timetickets.fields.productivehrs")}
|
||||||
name="productivehrs"
|
name='productivehrs'
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: t("general.validation.required"),
|
message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
]}
|
]}>
|
||||||
>
|
<InputNumber min={0} precision={1} />
|
||||||
<InputNumber />
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("timetickets.fields.actualhrs")}
|
label={t("timetickets.fields.actualhrs")}
|
||||||
name="actualhrs"
|
name='actualhrs'
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: t("general.validation.required"),
|
message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
]}
|
]}>
|
||||||
>
|
<InputNumber min={0} precision={1} />
|
||||||
<InputNumber />
|
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="cost_center"
|
name='cost_center'
|
||||||
label={t("timetickets.fields.cost_center")}
|
label={t("timetickets.fields.cost_center")}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: t("general.validation.required"),
|
message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
]}
|
]}>
|
||||||
>
|
|
||||||
<Select
|
<Select
|
||||||
style={{ width: "150px" }}
|
style={{ width: "150px" }}
|
||||||
onChange={() => {
|
onChange={() => {
|
||||||
console.log("Changed.");
|
console.log("Changed.");
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
{responsibilityCenters.costs.map((item) => (
|
{responsibilityCenters.costs.map((item) => (
|
||||||
<Select.Option key={item.name}>{item.name}</Select.Option>
|
<Select.Option key={item.name}>{item.name}</Select.Option>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="ciecacode"
|
name='ciecacode'
|
||||||
label={t("timetickets.fields.ciecacode")}
|
label={t("timetickets.fields.ciecacode")}
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: t("general.validation.required"),
|
message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
]}
|
]}>
|
||||||
>
|
|
||||||
<Input disabled />
|
<Input disabled />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export function TimeTicketModalContainer({
|
|||||||
} else {
|
} else {
|
||||||
insertTicket({
|
insertTicket({
|
||||||
variables: {
|
variables: {
|
||||||
timeTicketInput: [values],
|
timeTicketInput: [{ ...values, bodyshop: bodyshop.id }],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(handleMutationSuccess)
|
.then(handleMutationSuccess)
|
||||||
@@ -108,22 +108,21 @@ export function TimeTicketModalContainer({
|
|||||||
);
|
);
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
cost_center: emps.length > 0 ? emps[0].cost_center : "",
|
cost_center: emps.length > 0 ? emps[0].cost_center : "",
|
||||||
ciecacode: Object.keys(
|
ciecacode:
|
||||||
bodyshop.md_responsibility_centers.defaults
|
Object.keys(bodyshop.md_responsibility_centers.defaults.costs).find(
|
||||||
).find(
|
(key) =>
|
||||||
(key) =>
|
bodyshop.md_responsibility_centers.defaults.costs[key] ===
|
||||||
bodyshop.md_responsibility_centers.defaults[key] ===
|
emps[0].cost_center
|
||||||
emps[0].cost_center
|
) || "LAB",
|
||||||
),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (!!changedFields.cost_center && !!EmployeeAutoCompleteData) {
|
if (!!changedFields.cost_center && !!EmployeeAutoCompleteData) {
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
ciecacode: Object.keys(
|
ciecacode: Object.keys(
|
||||||
bodyshop.md_responsibility_centers.defaults
|
bodyshop.md_responsibility_centers.defaults.costs
|
||||||
).find(
|
).find(
|
||||||
(key) =>
|
(key) =>
|
||||||
bodyshop.md_responsibility_centers.defaults[key] ===
|
bodyshop.md_responsibility_centers.defaults.costs[key] ===
|
||||||
changedFields.cost_center
|
changedFields.cost_center
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
@@ -152,18 +151,16 @@ export function TimeTicketModalContainer({
|
|||||||
</Button>
|
</Button>
|
||||||
{timeTicketModal.context && timeTicketModal.context.id ? null : (
|
{timeTicketModal.context && timeTicketModal.context.id ? null : (
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type='primary'
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEnterAgain(true);
|
setEnterAgain(true);
|
||||||
}}
|
}}>
|
||||||
>
|
|
||||||
{t("general.actions.saveandnew")}
|
{t("general.actions.saveandnew")}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
destroyOnClose
|
destroyOnClose>
|
||||||
>
|
|
||||||
<Form
|
<Form
|
||||||
onFinish={handleFinish}
|
onFinish={handleFinish}
|
||||||
autoComplete={"off"}
|
autoComplete={"off"}
|
||||||
@@ -178,8 +175,7 @@ export function TimeTicketModalContainer({
|
|||||||
}
|
}
|
||||||
: { jobid: timeTicketModal.context.jobId || null }
|
: { jobid: timeTicketModal.context.jobId || null }
|
||||||
}
|
}
|
||||||
onValuesChange={handleFieldsChange}
|
onValuesChange={handleFieldsChange}>
|
||||||
>
|
|
||||||
<TimeTicketModalComponent
|
<TimeTicketModalComponent
|
||||||
form={form}
|
form={form}
|
||||||
roAutoCompleteOptions={RoAutoCompleteData && RoAutoCompleteData.jobs}
|
roAutoCompleteOptions={RoAutoCompleteData && RoAutoCompleteData.jobs}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
import { Card, List, Typography } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||||
|
import DataLabel from "../data-label/data-label.component";
|
||||||
|
import TechClockOffButton from "../tech-job-clock-out-button/tech-job-clock-out-button.component";
|
||||||
|
|
||||||
|
export default function TimeTicketShiftActive({ timetickets, refetch }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{timetickets.length > 0 ? (
|
||||||
|
<div>
|
||||||
|
<Typography.Title level={2}>
|
||||||
|
{t("timetickets.labels.shiftalreadyclockedon")}
|
||||||
|
</Typography.Title>
|
||||||
|
<List
|
||||||
|
grid={{
|
||||||
|
gutter: 32,
|
||||||
|
xs: 1,
|
||||||
|
sm: 2,
|
||||||
|
md: 3,
|
||||||
|
lg: 4,
|
||||||
|
xl: 5,
|
||||||
|
xxl: 6,
|
||||||
|
}}
|
||||||
|
dataSource={timetickets || []}
|
||||||
|
renderItem={(ticket) => (
|
||||||
|
<List.Item>
|
||||||
|
<Card
|
||||||
|
title={t(ticket.memo)}
|
||||||
|
actions={[
|
||||||
|
<TechClockOffButton
|
||||||
|
timeTicketId={ticket.id}
|
||||||
|
completedCallback={refetch}
|
||||||
|
isShiftTicket
|
||||||
|
/>,
|
||||||
|
]}>
|
||||||
|
<DataLabel label={t("timetickets.fields.clockon")}>
|
||||||
|
<DateTimeFormatter>{ticket.clockon}</DateTimeFormatter>
|
||||||
|
</DataLabel>
|
||||||
|
</Card>
|
||||||
|
</List.Item>
|
||||||
|
)}></List>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import { Form, InputNumber, Select } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
//currentUser: selectCurrentUser
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
|
||||||
|
export function TimeTicketShiftFormComponent({ bodyshop, form }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form.Item
|
||||||
|
name='memo'
|
||||||
|
label={t("timetickets.fields.memo")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<Select>
|
||||||
|
<Select.Option value='timetickets.labels.amshift'>
|
||||||
|
{t("timetickets.labels.amshift")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value='timetickets.labels.ambreak'>
|
||||||
|
{t("timetickets.labels.ambreak")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value='timetickets.labels.lunch'>
|
||||||
|
{t("timetickets.labels.lunch")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value='timetickets.labels.pmshift'>
|
||||||
|
{t("timetickets.labels.pmshift")}
|
||||||
|
</Select.Option>
|
||||||
|
<Select.Option value='timetickets.labels.pmbreak'>
|
||||||
|
{t("timetickets.labels.pmbreak")}
|
||||||
|
</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(TimeTicketShiftFormComponent);
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import { useMutation } from "@apollo/react-hooks";
|
||||||
|
import { Button, Form, notification } from "antd";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { INSERT_NEW_TIME_TICKET } from "../../graphql/timetickets.queries";
|
||||||
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
import TimeTicektShiftComponent from "./time-ticket-shift-form.component";
|
||||||
|
import axios from "axios";
|
||||||
|
import moment from "moment";
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
//currentUser: selectCurrentUser
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
technician: selectTechnician,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
|
||||||
|
export function TimeTicektShiftContainer({
|
||||||
|
bodyshop,
|
||||||
|
technician,
|
||||||
|
isTechConsole,
|
||||||
|
}) {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [insertTimeTicket] = useMutation(INSERT_NEW_TIME_TICKET);
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
const handleFinish = async (values) => {
|
||||||
|
setLoading(true);
|
||||||
|
console.log(values);
|
||||||
|
const theTime = moment((await axios.post("/utils/time")).data);
|
||||||
|
|
||||||
|
const result = await insertTimeTicket({
|
||||||
|
variables: {
|
||||||
|
timeTicketInput: [
|
||||||
|
{
|
||||||
|
bodyshopid: bodyshop.id,
|
||||||
|
employeeid: isTechConsole
|
||||||
|
? technician.id
|
||||||
|
: bodyshop.associations[0].user.employee.id,
|
||||||
|
cost_center: "timetickets.labels.shift",
|
||||||
|
clockon: theTime,
|
||||||
|
date: theTime,
|
||||||
|
memo: values.memo,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
awaitRefetchQueries: true,
|
||||||
|
refetchQueries: ["QUERY_ACTIVE_SHIFT_TIME_TICKETS"],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!!result.errors) {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("timetickets.errors.clockingin", {
|
||||||
|
message: JSON.stringify(result.errors),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
notification["success"]({
|
||||||
|
message: t("timetickets.successes.clockedin"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
The form TimeTicektShiftContainer
|
||||||
|
<Form
|
||||||
|
form={form}
|
||||||
|
layout='vertical'
|
||||||
|
autoComplete='no'
|
||||||
|
onFinish={handleFinish}
|
||||||
|
initialValues={{ cost_center: t("timetickets.labels.shift") }}>
|
||||||
|
<TimeTicektShiftComponent form={form} />
|
||||||
|
<Button htmlType='submit' loading={loading}>
|
||||||
|
{t("timetickets.actions.clockin")}
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(TimeTicektShiftContainer);
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { useQuery } from "react-apollo";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { QUERY_ACTIVE_SHIFT_TIME_TICKETS } from "../../graphql/timetickets.queries";
|
||||||
|
import { selectTechnician } from "../../redux/tech/tech.selectors";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
import AlertComponent from "../alert/alert.component";
|
||||||
|
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
|
||||||
|
import TimeTicketShiftActive from "../time-ticket-shift-active/time-ticket-shift-active.component";
|
||||||
|
import TimeTicketShiftFormContainer from "../time-ticket-shift-form/time-ticket-shift-form.container";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
technician: selectTechnician,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
|
||||||
|
export function TimeTicketShiftContainer({
|
||||||
|
bodyshop,
|
||||||
|
technician,
|
||||||
|
isTechConsole,
|
||||||
|
}) {
|
||||||
|
const { loading, error, data, refetch } = useQuery(
|
||||||
|
QUERY_ACTIVE_SHIFT_TIME_TICKETS,
|
||||||
|
{
|
||||||
|
variables: {
|
||||||
|
employeeId: isTechConsole
|
||||||
|
? technician.id
|
||||||
|
: bodyshop.associations[0].user.employee.id,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (loading) return <LoadingSpinner />;
|
||||||
|
if (error) return <AlertComponent message={error.message} type='error' />;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{data.timetickets.length > 0 ? (
|
||||||
|
<TimeTicketShiftActive
|
||||||
|
timetickets={data ? data.timetickets : []}
|
||||||
|
refetch={refetch}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<TimeTicketShiftFormContainer isTechConsole={isTechConsole} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(TimeTicketShiftContainer);
|
||||||
@@ -8,6 +8,9 @@ export const QUERY_BODYSHOP = gql`
|
|||||||
authid
|
authid
|
||||||
email
|
email
|
||||||
dashboardlayout
|
dashboardlayout
|
||||||
|
employee {
|
||||||
|
id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
address1
|
address1
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export const QUERY_EMPLOYEES = gql`
|
|||||||
cost_center
|
cost_center
|
||||||
base_rate
|
base_rate
|
||||||
pin
|
pin
|
||||||
|
user_email
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
@@ -43,6 +44,7 @@ export const UPDATE_EMPLOYEE = gql`
|
|||||||
cost_center
|
cost_center
|
||||||
base_rate
|
base_rate
|
||||||
pin
|
pin
|
||||||
|
user_email
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,11 +72,13 @@ export const QUERY_ACTIVE_TIME_TICKETS = gql`
|
|||||||
clockoff: { _is_null: true }
|
clockoff: { _is_null: true }
|
||||||
employeeid: { _eq: $employeeId }
|
employeeid: { _eq: $employeeId }
|
||||||
clockon: { _is_null: false }
|
clockon: { _is_null: false }
|
||||||
|
jobid: {_is_null: false}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
id
|
id
|
||||||
clockon
|
clockon
|
||||||
|
memo
|
||||||
job {
|
job {
|
||||||
id
|
id
|
||||||
est_number
|
est_number
|
||||||
@@ -91,6 +93,37 @@ export const QUERY_ACTIVE_TIME_TICKETS = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const QUERY_ACTIVE_SHIFT_TIME_TICKETS = gql`
|
||||||
|
query QUERY_ACTIVE_SHIFT_TIME_TICKETS($employeeId: uuid) {
|
||||||
|
timetickets(
|
||||||
|
where: {
|
||||||
|
_and: {
|
||||||
|
clockoff: { _is_null: true }
|
||||||
|
employeeid: { _eq: $employeeId }
|
||||||
|
clockon: { _is_null: false }
|
||||||
|
jobid: {_is_null: true}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
clockon
|
||||||
|
memo
|
||||||
|
job {
|
||||||
|
id
|
||||||
|
est_number
|
||||||
|
ownr_fn
|
||||||
|
ownr_ln
|
||||||
|
ownr_co_nm
|
||||||
|
v_model_desc
|
||||||
|
v_make_desc
|
||||||
|
v_model_yr
|
||||||
|
ro_number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const DELETE_TIME_TICKET = gql`
|
export const DELETE_TIME_TICKET = gql`
|
||||||
mutation DELETE_TIME_TICKET($id: uuid!) {
|
mutation DELETE_TIME_TICKET($id: uuid!) {
|
||||||
delete_timetickets_by_pk(id: $id) {
|
delete_timetickets_by_pk(id: $id) {
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import React from "react";
|
||||||
|
import TimeTicketShift from "../../components/time-ticket-shift/time-ticket-shift.container";
|
||||||
|
|
||||||
|
export default function TechShiftClock() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TimeTicketShift isTechConsole />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -27,9 +27,12 @@ const ProductionListPage = lazy(() =>
|
|||||||
const ProductionBoardPage = lazy(() =>
|
const ProductionBoardPage = lazy(() =>
|
||||||
import("../production-board/production-board.container")
|
import("../production-board/production-board.container")
|
||||||
);
|
);
|
||||||
const TechJobClockIn = lazy(() =>
|
const TechJobClock = lazy(() =>
|
||||||
import("../tech-job-clock/tech-job-clock.component")
|
import("../tech-job-clock/tech-job-clock.component")
|
||||||
);
|
);
|
||||||
|
const TechShiftClock = lazy(() =>
|
||||||
|
import("../tech-shift-clock/tech-shift-clock.component")
|
||||||
|
);
|
||||||
|
|
||||||
const { Content } = Layout;
|
const { Content } = Layout;
|
||||||
|
|
||||||
@@ -48,19 +51,18 @@ export function TechPage({ technician, match }) {
|
|||||||
}, [t]);
|
}, [t]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout className="tech-layout-container">
|
<Layout className='tech-layout-container'>
|
||||||
<TechSider />
|
<TechSider />
|
||||||
<Layout>
|
<Layout>
|
||||||
{technician ? null : <Redirect to={`${match.path}/login`} />}
|
{technician ? null : <Redirect to={`${match.path}/login`} />}
|
||||||
<TechHeader />
|
<TechHeader />
|
||||||
<Content className="tech-content-container">
|
<Content className='tech-content-container'>
|
||||||
<FcmNotification />
|
<FcmNotification />
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<Suspense
|
<Suspense
|
||||||
fallback={
|
fallback={
|
||||||
<LoadingSpinner message={t("general.labels.loadingapp")} />
|
<LoadingSpinner message={t("general.labels.loadingapp")} />
|
||||||
}
|
}>
|
||||||
>
|
|
||||||
<TimeTicketModalContainer />
|
<TimeTicketModalContainer />
|
||||||
<PrintCenterModalContainer />
|
<PrintCenterModalContainer />
|
||||||
<Switch>
|
<Switch>
|
||||||
@@ -78,11 +80,16 @@ export function TechPage({ technician, match }) {
|
|||||||
exact
|
exact
|
||||||
path={`${match.path}/list`}
|
path={`${match.path}/list`}
|
||||||
component={ProductionListPage}
|
component={ProductionListPage}
|
||||||
/>{" "}
|
/>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path={`${match.path}/jobclockin`}
|
path={`${match.path}/jobclock`}
|
||||||
component={TechJobClockIn}
|
component={TechJobClock}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
exact
|
||||||
|
path={`${match.path}/shiftclock`}
|
||||||
|
component={TechShiftClock}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ const applicationReducer = (state = INITIAL_STATE, action) => {
|
|||||||
...state,
|
...state,
|
||||||
technician: action.payload,
|
technician: action.payload,
|
||||||
loginLoading: false,
|
loginLoading: false,
|
||||||
|
loginError: false,
|
||||||
};
|
};
|
||||||
case TechActionTypes.TECH_LOGIN_FAILURE:
|
case TechActionTypes.TECH_LOGIN_FAILURE:
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -351,8 +351,8 @@
|
|||||||
"new": "New Employee"
|
"new": "New Employee"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"delete": "Error encountered while deleting employee.",
|
"delete": "Error encountered while deleting employee. {{message}}",
|
||||||
"save": "Error encountered saving employee.",
|
"save": "Error encountered saving employee. {{message}}",
|
||||||
"validation": "Please check all fields.",
|
"validation": "Please check all fields.",
|
||||||
"validationtitle": "Unable to save employee."
|
"validationtitle": "Unable to save employee."
|
||||||
},
|
},
|
||||||
@@ -1117,16 +1117,24 @@
|
|||||||
"cost_center": "Cost Center",
|
"cost_center": "Cost Center",
|
||||||
"date": "Ticket Date",
|
"date": "Ticket Date",
|
||||||
"employee": "Employee",
|
"employee": "Employee",
|
||||||
|
"memo": "Memo",
|
||||||
"productivehrs": "Productive Hours",
|
"productivehrs": "Productive Hours",
|
||||||
"ro_number": "Job to Post Against"
|
"ro_number": "Job to Post Against"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"alreadyclockedon": "You are already clocked in to the following job(s):",
|
"alreadyclockedon": "You are already clocked in to the following job(s):",
|
||||||
|
"ambreak": "AM Break",
|
||||||
|
"amshift": "AM Shift",
|
||||||
"clockintojob": "Clock In to Job",
|
"clockintojob": "Clock In to Job",
|
||||||
"deleteconfirm": "Are you sure you want to delete this time ticket? This cannot be undone.",
|
"deleteconfirm": "Are you sure you want to delete this time ticket? This cannot be undone.",
|
||||||
"edit": "Edit Time Ticket",
|
"edit": "Edit Time Ticket",
|
||||||
"flat_rate": "Flat Rate",
|
"flat_rate": "Flat Rate",
|
||||||
|
"lunch": "Lunch",
|
||||||
"new": "New Time Ticket",
|
"new": "New Time Ticket",
|
||||||
|
"pmbreak": "PM Break",
|
||||||
|
"pmshift": "PM Shift",
|
||||||
|
"shift": "Shift",
|
||||||
|
"shiftalreadyclockedon": "Active Shift Time Tickets",
|
||||||
"straight_time": "Straight Time"
|
"straight_time": "Straight Time"
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
|
|||||||
@@ -351,8 +351,8 @@
|
|||||||
"new": "Nuevo empleado"
|
"new": "Nuevo empleado"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"delete": "Se encontró un error al eliminar al empleado.",
|
"delete": "Se encontró un error al eliminar al empleado. {{message}}",
|
||||||
"save": "Se encontró un error al salvar al empleado.",
|
"save": "Se encontró un error al salvar al empleado. {{message}}",
|
||||||
"validation": "Por favor verifique todos los campos.",
|
"validation": "Por favor verifique todos los campos.",
|
||||||
"validationtitle": "No se puede salvar al empleado."
|
"validationtitle": "No se puede salvar al empleado."
|
||||||
},
|
},
|
||||||
@@ -1117,16 +1117,24 @@
|
|||||||
"cost_center": "",
|
"cost_center": "",
|
||||||
"date": "",
|
"date": "",
|
||||||
"employee": "",
|
"employee": "",
|
||||||
|
"memo": "",
|
||||||
"productivehrs": "",
|
"productivehrs": "",
|
||||||
"ro_number": ""
|
"ro_number": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"alreadyclockedon": "",
|
"alreadyclockedon": "",
|
||||||
|
"ambreak": "",
|
||||||
|
"amshift": "",
|
||||||
"clockintojob": "",
|
"clockintojob": "",
|
||||||
"deleteconfirm": "",
|
"deleteconfirm": "",
|
||||||
"edit": "",
|
"edit": "",
|
||||||
"flat_rate": "",
|
"flat_rate": "",
|
||||||
|
"lunch": "",
|
||||||
"new": "",
|
"new": "",
|
||||||
|
"pmbreak": "",
|
||||||
|
"pmshift": "",
|
||||||
|
"shift": "",
|
||||||
|
"shiftalreadyclockedon": "",
|
||||||
"straight_time": ""
|
"straight_time": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
|
|||||||
@@ -351,8 +351,8 @@
|
|||||||
"new": "Nouvel employé"
|
"new": "Nouvel employé"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"delete": "Erreur rencontrée lors de la suppression de l'employé.",
|
"delete": "Erreur rencontrée lors de la suppression de l'employé. {{message}}",
|
||||||
"save": "Une erreur s'est produite lors de l'enregistrement de l'employé.",
|
"save": "Une erreur s'est produite lors de l'enregistrement de l'employé. {{message}}",
|
||||||
"validation": "Veuillez cocher tous les champs.",
|
"validation": "Veuillez cocher tous les champs.",
|
||||||
"validationtitle": "Impossible d'enregistrer l'employé."
|
"validationtitle": "Impossible d'enregistrer l'employé."
|
||||||
},
|
},
|
||||||
@@ -1117,16 +1117,24 @@
|
|||||||
"cost_center": "",
|
"cost_center": "",
|
||||||
"date": "",
|
"date": "",
|
||||||
"employee": "",
|
"employee": "",
|
||||||
|
"memo": "",
|
||||||
"productivehrs": "",
|
"productivehrs": "",
|
||||||
"ro_number": ""
|
"ro_number": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"alreadyclockedon": "",
|
"alreadyclockedon": "",
|
||||||
|
"ambreak": "",
|
||||||
|
"amshift": "",
|
||||||
"clockintojob": "",
|
"clockintojob": "",
|
||||||
"deleteconfirm": "",
|
"deleteconfirm": "",
|
||||||
"edit": "",
|
"edit": "",
|
||||||
"flat_rate": "",
|
"flat_rate": "",
|
||||||
|
"lunch": "",
|
||||||
"new": "",
|
"new": "",
|
||||||
|
"pmbreak": "",
|
||||||
|
"pmshift": "",
|
||||||
|
"shift": "",
|
||||||
|
"shiftalreadyclockedon": "",
|
||||||
"straight_time": ""
|
"straight_time": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: ALTER TABLE "public"."employees" DROP COLUMN "user_email";
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: ALTER TABLE "public"."employees" ADD COLUMN "user_email" text NULL UNIQUE;
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: alter table "public"."employees" drop constraint "employees_user_email_fkey";
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: |-
|
||||||
|
alter table "public"."employees"
|
||||||
|
add constraint "employees_user_email_fkey"
|
||||||
|
foreign key ("user_email")
|
||||||
|
references "public"."users"
|
||||||
|
("email") on update restrict on delete restrict;
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: |-
|
||||||
|
alter table "public"."employees" drop constraint "employees_user_email_fkey",
|
||||||
|
add constraint "employees_user_email_fkey"
|
||||||
|
foreign key ("shopid")
|
||||||
|
references "public"."bodyshops"
|
||||||
|
("id")
|
||||||
|
on update cascade
|
||||||
|
on delete cascade;
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: |-
|
||||||
|
alter table "public"."employees" drop constraint "employees_user_email_fkey",
|
||||||
|
add constraint "employees_user_email_fkey"
|
||||||
|
foreign key ("user_email")
|
||||||
|
references "public"."users"
|
||||||
|
("email") on update set null on delete set null;
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- args:
|
||||||
|
relationship: employee
|
||||||
|
table:
|
||||||
|
name: users
|
||||||
|
schema: public
|
||||||
|
type: drop_relationship
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
- args:
|
||||||
|
name: employee
|
||||||
|
table:
|
||||||
|
name: users
|
||||||
|
schema: public
|
||||||
|
using:
|
||||||
|
manual_configuration:
|
||||||
|
column_mapping:
|
||||||
|
email: user_email
|
||||||
|
remote_table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: create_object_relationship
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
- args:
|
||||||
|
relationship: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: drop_relationship
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
- args:
|
||||||
|
name: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: user_email
|
||||||
|
type: create_object_relationship
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
columns:
|
||||||
|
- active
|
||||||
|
- base_rate
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- employee_number
|
||||||
|
- first_name
|
||||||
|
- flat_rate
|
||||||
|
- hire_date
|
||||||
|
- id
|
||||||
|
- last_name
|
||||||
|
- pin
|
||||||
|
- shopid
|
||||||
|
- termination_date
|
||||||
|
- updated_at
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
columns:
|
||||||
|
- active
|
||||||
|
- base_rate
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- employee_number
|
||||||
|
- first_name
|
||||||
|
- flat_rate
|
||||||
|
- hire_date
|
||||||
|
- id
|
||||||
|
- last_name
|
||||||
|
- pin
|
||||||
|
- shopid
|
||||||
|
- termination_date
|
||||||
|
- updated_at
|
||||||
|
- user_email
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: drop_select_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
allow_aggregations: false
|
||||||
|
columns:
|
||||||
|
- active
|
||||||
|
- base_rate
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- employee_number
|
||||||
|
- first_name
|
||||||
|
- flat_rate
|
||||||
|
- hire_date
|
||||||
|
- id
|
||||||
|
- last_name
|
||||||
|
- pin
|
||||||
|
- shopid
|
||||||
|
- termination_date
|
||||||
|
- updated_at
|
||||||
|
computed_fields: []
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: create_select_permission
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: drop_select_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
allow_aggregations: false
|
||||||
|
columns:
|
||||||
|
- active
|
||||||
|
- base_rate
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- employee_number
|
||||||
|
- first_name
|
||||||
|
- flat_rate
|
||||||
|
- hire_date
|
||||||
|
- id
|
||||||
|
- last_name
|
||||||
|
- pin
|
||||||
|
- shopid
|
||||||
|
- termination_date
|
||||||
|
- updated_at
|
||||||
|
- user_email
|
||||||
|
computed_fields: []
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: create_select_permission
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: drop_update_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- active
|
||||||
|
- base_rate
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- employee_number
|
||||||
|
- first_name
|
||||||
|
- flat_rate
|
||||||
|
- hire_date
|
||||||
|
- id
|
||||||
|
- last_name
|
||||||
|
- pin
|
||||||
|
- shopid
|
||||||
|
- termination_date
|
||||||
|
- updated_at
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: create_update_permission
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: drop_update_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- active
|
||||||
|
- base_rate
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- employee_number
|
||||||
|
- first_name
|
||||||
|
- flat_rate
|
||||||
|
- hire_date
|
||||||
|
- id
|
||||||
|
- last_name
|
||||||
|
- pin
|
||||||
|
- shopid
|
||||||
|
- termination_date
|
||||||
|
- updated_at
|
||||||
|
- user_email
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: employees
|
||||||
|
schema: public
|
||||||
|
type: create_update_permission
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check:
|
||||||
|
job:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
columns:
|
||||||
|
- id
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- date
|
||||||
|
- cost_center
|
||||||
|
- employeeid
|
||||||
|
- jobid
|
||||||
|
- rate
|
||||||
|
- productivehrs
|
||||||
|
- actualhrs
|
||||||
|
- clockon
|
||||||
|
- clockoff
|
||||||
|
- ciecacode
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check: {}
|
||||||
|
columns:
|
||||||
|
- id
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- date
|
||||||
|
- cost_center
|
||||||
|
- employeeid
|
||||||
|
- jobid
|
||||||
|
- rate
|
||||||
|
- productivehrs
|
||||||
|
- actualhrs
|
||||||
|
- clockon
|
||||||
|
- clockoff
|
||||||
|
- ciecacode
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: ALTER TABLE "public"."timetickets" DROP COLUMN "bodyshopid";
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: ALTER TABLE "public"."timetickets" ADD COLUMN "bodyshopid" uuid NOT NULL;
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: alter table "public"."timetickets" drop constraint "timetickets_bodyshopid_fkey";
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: |-
|
||||||
|
alter table "public"."timetickets"
|
||||||
|
add constraint "timetickets_bodyshopid_fkey"
|
||||||
|
foreign key ("bodyshopid")
|
||||||
|
references "public"."bodyshops"
|
||||||
|
("id") on update restrict on delete restrict;
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
- args:
|
||||||
|
relationship: timetickets
|
||||||
|
table:
|
||||||
|
name: bodyshops
|
||||||
|
schema: public
|
||||||
|
type: drop_relationship
|
||||||
|
- args:
|
||||||
|
relationship: bodyshop
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_relationship
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
- args:
|
||||||
|
name: timetickets
|
||||||
|
table:
|
||||||
|
name: bodyshops
|
||||||
|
schema: public
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: bodyshopid
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_array_relationship
|
||||||
|
- args:
|
||||||
|
name: bodyshop
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: bodyshopid
|
||||||
|
type: create_object_relationship
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check: {}
|
||||||
|
columns:
|
||||||
|
- id
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- date
|
||||||
|
- cost_center
|
||||||
|
- employeeid
|
||||||
|
- jobid
|
||||||
|
- rate
|
||||||
|
- productivehrs
|
||||||
|
- actualhrs
|
||||||
|
- clockon
|
||||||
|
- clockoff
|
||||||
|
- ciecacode
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
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
|
||||||
|
- date
|
||||||
|
- cost_center
|
||||||
|
- employeeid
|
||||||
|
- jobid
|
||||||
|
- rate
|
||||||
|
- productivehrs
|
||||||
|
- actualhrs
|
||||||
|
- clockon
|
||||||
|
- clockoff
|
||||||
|
- ciecacode
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_select_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
allow_aggregations: false
|
||||||
|
columns:
|
||||||
|
- date
|
||||||
|
- actualhrs
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- ciecacode
|
||||||
|
- cost_center
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
computed_fields: []
|
||||||
|
filter:
|
||||||
|
job:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_select_permission
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_select_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
allow_aggregations: false
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
computed_fields: []
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_select_permission
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
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
|
||||||
|
- date
|
||||||
|
- cost_center
|
||||||
|
- employeeid
|
||||||
|
- jobid
|
||||||
|
- rate
|
||||||
|
- productivehrs
|
||||||
|
- actualhrs
|
||||||
|
- clockon
|
||||||
|
- clockoff
|
||||||
|
- ciecacode
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_update_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- date
|
||||||
|
- actualhrs
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- ciecacode
|
||||||
|
- cost_center
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- created_at
|
||||||
|
- updated_at
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
filter:
|
||||||
|
job:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_update_permission
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_update_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_update_permission
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_delete_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
filter:
|
||||||
|
job:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_delete_permission
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_delete_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_delete_permission
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: ALTER TABLE "public"."timetickets" DROP COLUMN "memo";
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- args:
|
||||||
|
cascade: false
|
||||||
|
read_only: false
|
||||||
|
sql: ALTER TABLE "public"."timetickets" ADD COLUMN "memo" text NULL;
|
||||||
|
type: run_sql
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_insert_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
check:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- memo
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_insert_permission
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_select_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
allow_aggregations: false
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
computed_fields: []
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_select_permission
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_select_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
allow_aggregations: false
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- memo
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
computed_fields: []
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_select_permission
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_update_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_update_permission
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
- args:
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: drop_update_permission
|
||||||
|
- args:
|
||||||
|
permission:
|
||||||
|
columns:
|
||||||
|
- actualhrs
|
||||||
|
- bodyshopid
|
||||||
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- memo
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
|
filter:
|
||||||
|
bodyshop:
|
||||||
|
associations:
|
||||||
|
_and:
|
||||||
|
- user:
|
||||||
|
authid:
|
||||||
|
_eq: X-Hasura-User-Id
|
||||||
|
- active:
|
||||||
|
_eq: true
|
||||||
|
set: {}
|
||||||
|
role: user
|
||||||
|
table:
|
||||||
|
name: timetickets
|
||||||
|
schema: public
|
||||||
|
type: create_update_permission
|
||||||
@@ -433,6 +433,13 @@ tables:
|
|||||||
table:
|
table:
|
||||||
schema: public
|
schema: public
|
||||||
name: templates
|
name: templates
|
||||||
|
- name: timetickets
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on:
|
||||||
|
column: bodyshopid
|
||||||
|
table:
|
||||||
|
schema: public
|
||||||
|
name: timetickets
|
||||||
- name: vehicles
|
- name: vehicles
|
||||||
using:
|
using:
|
||||||
foreign_key_constraint_on:
|
foreign_key_constraint_on:
|
||||||
@@ -1175,6 +1182,9 @@ tables:
|
|||||||
- name: bodyshop
|
- name: bodyshop
|
||||||
using:
|
using:
|
||||||
foreign_key_constraint_on: shopid
|
foreign_key_constraint_on: shopid
|
||||||
|
- name: user
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: user_email
|
||||||
array_relationships:
|
array_relationships:
|
||||||
- name: allocations
|
- name: allocations
|
||||||
using:
|
using:
|
||||||
@@ -1217,6 +1227,7 @@ tables:
|
|||||||
- shopid
|
- shopid
|
||||||
- termination_date
|
- termination_date
|
||||||
- updated_at
|
- updated_at
|
||||||
|
- user_email
|
||||||
select_permissions:
|
select_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
@@ -1235,6 +1246,7 @@ tables:
|
|||||||
- shopid
|
- shopid
|
||||||
- termination_date
|
- termination_date
|
||||||
- updated_at
|
- updated_at
|
||||||
|
- user_email
|
||||||
filter:
|
filter:
|
||||||
bodyshop:
|
bodyshop:
|
||||||
associations:
|
associations:
|
||||||
@@ -1262,6 +1274,7 @@ tables:
|
|||||||
- shopid
|
- shopid
|
||||||
- termination_date
|
- termination_date
|
||||||
- updated_at
|
- updated_at
|
||||||
|
- user_email
|
||||||
filter:
|
filter:
|
||||||
bodyshop:
|
bodyshop:
|
||||||
associations:
|
associations:
|
||||||
@@ -3538,6 +3551,9 @@ tables:
|
|||||||
schema: public
|
schema: public
|
||||||
name: timetickets
|
name: timetickets
|
||||||
object_relationships:
|
object_relationships:
|
||||||
|
- name: bodyshop
|
||||||
|
using:
|
||||||
|
foreign_key_constraint_on: bodyshopid
|
||||||
- name: employee
|
- name: employee
|
||||||
using:
|
using:
|
||||||
foreign_key_constraint_on: employeeid
|
foreign_key_constraint_on: employeeid
|
||||||
@@ -3548,100 +3564,111 @@ tables:
|
|||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
check:
|
check:
|
||||||
job:
|
bodyshop:
|
||||||
bodyshop:
|
associations:
|
||||||
associations:
|
_and:
|
||||||
_and:
|
- user:
|
||||||
- user:
|
authid:
|
||||||
authid:
|
_eq: X-Hasura-User-Id
|
||||||
_eq: X-Hasura-User-Id
|
- active:
|
||||||
- active:
|
_eq: true
|
||||||
_eq: true
|
|
||||||
columns:
|
columns:
|
||||||
- id
|
|
||||||
- created_at
|
|
||||||
- updated_at
|
|
||||||
- date
|
|
||||||
- cost_center
|
|
||||||
- employeeid
|
|
||||||
- jobid
|
|
||||||
- rate
|
|
||||||
- productivehrs
|
|
||||||
- actualhrs
|
- actualhrs
|
||||||
- clockon
|
- bodyshopid
|
||||||
- clockoff
|
|
||||||
- ciecacode
|
- ciecacode
|
||||||
|
- clockoff
|
||||||
|
- clockon
|
||||||
|
- cost_center
|
||||||
|
- created_at
|
||||||
|
- date
|
||||||
|
- employeeid
|
||||||
|
- id
|
||||||
|
- jobid
|
||||||
|
- memo
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
select_permissions:
|
select_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
columns:
|
columns:
|
||||||
- date
|
|
||||||
- actualhrs
|
- actualhrs
|
||||||
- productivehrs
|
- bodyshopid
|
||||||
- rate
|
|
||||||
- ciecacode
|
- ciecacode
|
||||||
- cost_center
|
|
||||||
- clockoff
|
- clockoff
|
||||||
- clockon
|
- clockon
|
||||||
|
- cost_center
|
||||||
- created_at
|
- created_at
|
||||||
- updated_at
|
- date
|
||||||
- employeeid
|
- employeeid
|
||||||
- id
|
- id
|
||||||
- jobid
|
- jobid
|
||||||
|
- memo
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
filter:
|
filter:
|
||||||
job:
|
bodyshop:
|
||||||
bodyshop:
|
associations:
|
||||||
associations:
|
_and:
|
||||||
_and:
|
- user:
|
||||||
- user:
|
authid:
|
||||||
authid:
|
_eq: X-Hasura-User-Id
|
||||||
_eq: X-Hasura-User-Id
|
- active:
|
||||||
- active:
|
_eq: true
|
||||||
_eq: true
|
|
||||||
update_permissions:
|
update_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
columns:
|
columns:
|
||||||
- date
|
|
||||||
- actualhrs
|
- actualhrs
|
||||||
- productivehrs
|
- bodyshopid
|
||||||
- rate
|
|
||||||
- ciecacode
|
- ciecacode
|
||||||
- cost_center
|
|
||||||
- clockoff
|
- clockoff
|
||||||
- clockon
|
- clockon
|
||||||
|
- cost_center
|
||||||
- created_at
|
- created_at
|
||||||
- updated_at
|
- date
|
||||||
- employeeid
|
- employeeid
|
||||||
- id
|
- id
|
||||||
- jobid
|
- jobid
|
||||||
|
- memo
|
||||||
|
- productivehrs
|
||||||
|
- rate
|
||||||
|
- updated_at
|
||||||
filter:
|
filter:
|
||||||
job:
|
bodyshop:
|
||||||
bodyshop:
|
associations:
|
||||||
associations:
|
_and:
|
||||||
_and:
|
- user:
|
||||||
- user:
|
authid:
|
||||||
authid:
|
_eq: X-Hasura-User-Id
|
||||||
_eq: X-Hasura-User-Id
|
- active:
|
||||||
- active:
|
_eq: true
|
||||||
_eq: true
|
|
||||||
check: null
|
check: null
|
||||||
delete_permissions:
|
delete_permissions:
|
||||||
- role: user
|
- role: user
|
||||||
permission:
|
permission:
|
||||||
filter:
|
filter:
|
||||||
job:
|
bodyshop:
|
||||||
bodyshop:
|
associations:
|
||||||
associations:
|
_and:
|
||||||
_and:
|
- user:
|
||||||
- user:
|
authid:
|
||||||
authid:
|
_eq: X-Hasura-User-Id
|
||||||
_eq: X-Hasura-User-Id
|
- active:
|
||||||
- active:
|
_eq: true
|
||||||
_eq: true
|
|
||||||
- table:
|
- table:
|
||||||
schema: public
|
schema: public
|
||||||
name: users
|
name: users
|
||||||
|
object_relationships:
|
||||||
|
- name: employee
|
||||||
|
using:
|
||||||
|
manual_configuration:
|
||||||
|
remote_table:
|
||||||
|
schema: public
|
||||||
|
name: employees
|
||||||
|
column_mapping:
|
||||||
|
email: user_email
|
||||||
array_relationships:
|
array_relationships:
|
||||||
- name: associations
|
- name: associations
|
||||||
using:
|
using:
|
||||||
|
|||||||
Reference in New Issue
Block a user