IO-347 Manual appointments.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<babeledit_project version="1.2" be_version="2.7.1">
|
<babeledit_project be_version="2.7.1" version="1.2">
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
BabelEdit project file
|
BabelEdit project file
|
||||||
@@ -500,6 +500,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>end</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>note</name>
|
<name>note</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -521,6 +542,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>start</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>time</name>
|
<name>time</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -673,6 +715,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>dataconsistency</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>history</name>
|
<name>history</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -715,6 +778,27 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>manualevent</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>noarrivingjobs</name>
|
<name>noarrivingjobs</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import { GenerateDocument } from "../../utils/RenderTemplate";
|
|||||||
import { TemplateList } from "../../utils/TemplateConstants";
|
import { TemplateList } from "../../utils/TemplateConstants";
|
||||||
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
|
import ChatOpenButton from "../chat-open-button/chat-open-button.component";
|
||||||
import DataLabel from "../data-label/data-label.component";
|
import DataLabel from "../data-label/data-label.component";
|
||||||
|
import ScheduleManualEvent from "../schedule-manual-event/schedule-manual-event.component";
|
||||||
import ScheduleAtChange from "./job-at-change.component";
|
import ScheduleAtChange from "./job-at-change.component";
|
||||||
import ScheduleEventColor from "./schedule-event.color.component";
|
import ScheduleEventColor from "./schedule-event.color.component";
|
||||||
import ScheduleEventNote from "./schedule-event.note.component";
|
import ScheduleEventNote from "./schedule-event.note.component";
|
||||||
@@ -66,7 +67,10 @@ export function ScheduleEventComponent({
|
|||||||
const popoverContent = (
|
const popoverContent = (
|
||||||
<div style={{ maxWidth: "40vw" }}>
|
<div style={{ maxWidth: "40vw" }}>
|
||||||
{!event.isintake ? (
|
{!event.isintake ? (
|
||||||
<strong>{event.title}</strong>
|
<Space>
|
||||||
|
<strong>{event.title}</strong>
|
||||||
|
<ScheduleEventColor event={event} />
|
||||||
|
</Space>
|
||||||
) : (
|
) : (
|
||||||
<Space>
|
<Space>
|
||||||
<strong>{`${(event.job && event.job.ownr_fn) || ""} ${
|
<strong>{`${(event.job && event.job.ownr_fn) || ""} ${
|
||||||
@@ -118,7 +122,9 @@ export function ScheduleEventComponent({
|
|||||||
</DataLabel>
|
</DataLabel>
|
||||||
<ScheduleEventNote event={event} />
|
<ScheduleEventNote event={event} />
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : (
|
||||||
|
<div>{event.note || ""}</div>
|
||||||
|
)}
|
||||||
<Divider />
|
<Divider />
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
{event.job ? (
|
{event.job ? (
|
||||||
@@ -140,84 +146,89 @@ export function ScheduleEventComponent({
|
|||||||
{t("appointments.actions.preview")}
|
{t("appointments.actions.preview")}
|
||||||
</Button>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
|
{event.job ? (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
overlay={
|
overlay={
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const Template = TemplateList("job").appointment_reminder;
|
const Template = TemplateList("job").appointment_reminder;
|
||||||
GenerateDocument(
|
GenerateDocument(
|
||||||
{
|
{
|
||||||
name: Template.key,
|
name: Template.key,
|
||||||
variables: { id: event.job.id },
|
variables: { id: event.job.id },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: event.job && event.job.ownr_ea,
|
to: event.job && event.job.ownr_ea,
|
||||||
subject: Template.subject,
|
subject: Template.subject,
|
||||||
},
|
},
|
||||||
"e",
|
"e",
|
||||||
event.job && event.job.id
|
event.job && event.job.id
|
||||||
);
|
|
||||||
}}
|
|
||||||
disabled={event.arrived}
|
|
||||||
>
|
|
||||||
{t("general.labels.email")}
|
|
||||||
</Menu.Item>
|
|
||||||
<Menu.Item
|
|
||||||
onClick={() => {
|
|
||||||
const p = parsePhoneNumber(event.job.ownr_ph1, "CA");
|
|
||||||
if (p && p.isValid()) {
|
|
||||||
openChatByPhone({
|
|
||||||
phone_num: p.formatInternational(),
|
|
||||||
jobid: event.job.id,
|
|
||||||
});
|
|
||||||
setMessage(
|
|
||||||
t("appointments.labels.reminder", {
|
|
||||||
shopname: bodyshop.shopname,
|
|
||||||
date: moment(event.start).format("MM/DD/YYYY"),
|
|
||||||
time: moment(event.start).format("HH:mm a"),
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
setVisible(false);
|
}}
|
||||||
} else {
|
disabled={event.arrived}
|
||||||
notification["error"]({
|
>
|
||||||
message: t("messaging.error.invalidphone"),
|
{t("general.labels.email")}
|
||||||
});
|
</Menu.Item>
|
||||||
}
|
<Menu.Item
|
||||||
}}
|
onClick={() => {
|
||||||
disabled={event.arrived || !bodyshop.messagingservicesid}
|
const p = parsePhoneNumber(event.job.ownr_ph1, "CA");
|
||||||
>
|
if (p && p.isValid()) {
|
||||||
{t("general.labels.sms")}
|
openChatByPhone({
|
||||||
</Menu.Item>
|
phone_num: p.formatInternational(),
|
||||||
</Menu>
|
jobid: event.job.id,
|
||||||
}
|
});
|
||||||
>
|
setMessage(
|
||||||
<Button>{t("appointments.actions.sendreminder")}</Button>
|
t("appointments.labels.reminder", {
|
||||||
</Dropdown>
|
shopname: bodyshop.shopname,
|
||||||
|
date: moment(event.start).format("MM/DD/YYYY"),
|
||||||
|
time: moment(event.start).format("HH:mm a"),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
setVisible(false);
|
||||||
|
} else {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("messaging.error.invalidphone"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
disabled={event.arrived || !bodyshop.messagingservicesid}
|
||||||
|
>
|
||||||
|
{t("general.labels.sms")}
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Button>{t("appointments.actions.sendreminder")}</Button>
|
||||||
|
</Dropdown>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<Button onClick={() => handleCancel(event.id)} disabled={event.arrived}>
|
<Button onClick={() => handleCancel(event.id)} disabled={event.arrived}>
|
||||||
{t("appointments.actions.cancel")}
|
{t("appointments.actions.cancel")}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
{event.isintake ? (
|
||||||
disabled={event.arrived}
|
<Button
|
||||||
onClick={() => {
|
disabled={event.arrived}
|
||||||
setVisible(false);
|
onClick={() => {
|
||||||
setScheduleContext({
|
setVisible(false);
|
||||||
actions: { refetch: refetch },
|
setScheduleContext({
|
||||||
context: {
|
actions: { refetch: refetch },
|
||||||
jobId: event.job.id,
|
context: {
|
||||||
job: event.job,
|
jobId: event.job.id,
|
||||||
previousEvent: event.id,
|
job: event.job,
|
||||||
color: event.color,
|
previousEvent: event.id,
|
||||||
alt_transport: event.job && event.job.alt_transport,
|
color: event.color,
|
||||||
note: event.note,
|
alt_transport: event.job && event.job.alt_transport,
|
||||||
},
|
note: event.note,
|
||||||
});
|
},
|
||||||
}}
|
});
|
||||||
>
|
}}
|
||||||
{t("appointments.actions.reschedule")}
|
>
|
||||||
</Button>
|
{t("appointments.actions.reschedule")}
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<ScheduleManualEvent event={event} />
|
||||||
|
)}
|
||||||
{event.isintake ? (
|
{event.isintake ? (
|
||||||
<Link
|
<Link
|
||||||
to={{
|
to={{
|
||||||
@@ -235,7 +246,13 @@ export function ScheduleEventComponent({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const RegularEvent = event.isintake ? (
|
const RegularEvent = event.isintake ? (
|
||||||
<div style={{ display: "flex", flexWrap: "wrap" }}>
|
<div
|
||||||
|
style={{
|
||||||
|
display: "flex",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
height: "100%",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Space>
|
<Space>
|
||||||
{event.note && <AlertFilled className="production-alert" />}
|
{event.note && <AlertFilled className="production-alert" />}
|
||||||
<strong>{`${event.job.ro_number || t("general.labels.na")}`}</strong>
|
<strong>{`${event.job.ro_number || t("general.labels.na")}`}</strong>
|
||||||
@@ -262,7 +279,7 @@ export function ScheduleEventComponent({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div>
|
<div style={{ height: "100%", width: "100%" }}>
|
||||||
<strong>{`${event.title || ""}`}</strong>
|
<strong>{`${event.title || ""}`}</strong>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import "./schedule-calendar.styles.scss";
|
|||||||
import JobDetailCards from "../job-detail-cards/job-detail-cards.component";
|
import JobDetailCards from "../job-detail-cards/job-detail-cards.component";
|
||||||
import { selectProblemJobs } from "../../redux/application/application.selectors";
|
import { selectProblemJobs } from "../../redux/application/application.selectors";
|
||||||
import { Alert } from "antd";
|
import { Alert } from "antd";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop,
|
bodyshop: selectBodyshop,
|
||||||
@@ -30,7 +31,7 @@ export function ScheduleCalendarWrapperComponent({
|
|||||||
}) {
|
}) {
|
||||||
const search = queryString.parse(useLocation().search);
|
const search = queryString.parse(useLocation().search);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const { t } = useTranslation();
|
||||||
const handleEventPropStyles = (event, start, end, isSelected) => {
|
const handleEventPropStyles = (event, start, end, isSelected) => {
|
||||||
return {
|
return {
|
||||||
...(event.color
|
...(event.color
|
||||||
@@ -57,7 +58,10 @@ export function ScheduleCalendarWrapperComponent({
|
|||||||
<Alert
|
<Alert
|
||||||
key={problem.id}
|
key={problem.id}
|
||||||
type="error"
|
type="error"
|
||||||
message={`${problem.ro_number} has a data consistency issue. It has been exlcuded for scheduling purposes. CODE: ${problem.code}`}
|
message={t("appointments.labels.dataconsistency", {
|
||||||
|
ro_number: problem.ro_number,
|
||||||
|
code: problem.code,
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Button, Card, Col, PageHeader, Row, Space } from "antd";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import ScheduleCalendarWrapperComponent from "../schedule-calendar-wrapper/scheduler-calendar-wrapper.component";
|
import ScheduleCalendarWrapperComponent from "../schedule-calendar-wrapper/scheduler-calendar-wrapper.component";
|
||||||
import ScheduleModal from "../schedule-job-modal/schedule-job-modal.container";
|
import ScheduleModal from "../schedule-job-modal/schedule-job-modal.container";
|
||||||
//import ScheduleManualEvent from "../schedule-manual-event/schedule-manual-event.component";
|
import ScheduleManualEvent from "../schedule-manual-event/schedule-manual-event.component";
|
||||||
import ScheduleProductionList from "../schedule-production-list/schedule-production-list.component";
|
import ScheduleProductionList from "../schedule-production-list/schedule-production-list.component";
|
||||||
import ScheduleVerifyIntegrity from "../schedule-verify-integrity/schedule-verify-integrity.component";
|
import ScheduleVerifyIntegrity from "../schedule-verify-integrity/schedule-verify-integrity.component";
|
||||||
|
|
||||||
@@ -25,9 +25,8 @@ export default function ScheduleCalendarComponent({ data, refetch }) {
|
|||||||
<SyncOutlined />
|
<SyncOutlined />
|
||||||
</Button>
|
</Button>
|
||||||
<ScheduleProductionList />
|
<ScheduleProductionList />
|
||||||
{
|
|
||||||
// <ScheduleManualEvent />
|
<ScheduleManualEvent />
|
||||||
}
|
|
||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1,17 +1,32 @@
|
|||||||
import { useMutation } from "@apollo/client";
|
import { useMutation } from "@apollo/client";
|
||||||
import { Button, Card, Form, Input, Popover, Space } from "antd";
|
import { Button, Card, Form, Input, Popover, Select, Space } from "antd";
|
||||||
|
import moment from "moment";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
import { logImEXEvent } from "../../firebase/firebase.utils";
|
import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||||
import {
|
import {
|
||||||
INSERT_APPOINTMENT,
|
INSERT_MANUAL_APPT,
|
||||||
UPDATE_APPOINTMENT,
|
UPDATE_APPOINTMENT,
|
||||||
} from "../../graphql/appointments.queries";
|
} from "../../graphql/appointments.queries";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time-picker.component";
|
import FormDateTimePickerComponent from "../form-date-time-picker/form-date-time-picker.component";
|
||||||
|
|
||||||
export default function ScheduleManualEvent({ event }) {
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(ScheduleManualEvent);
|
||||||
|
|
||||||
|
export function ScheduleManualEvent({ bodyshop, event }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [insertAppointment] = useMutation(INSERT_APPOINTMENT);
|
const [insertAppointment] = useMutation(INSERT_MANUAL_APPT);
|
||||||
const [updateAppointment] = useMutation(UPDATE_APPOINTMENT);
|
const [updateAppointment] = useMutation(UPDATE_APPOINTMENT);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
@@ -22,26 +37,27 @@ export default function ScheduleManualEvent({ event }) {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (visibility && event) {
|
if (visibility && event) {
|
||||||
form.setFieldsValue({ event });
|
form.setFieldsValue(event);
|
||||||
}
|
}
|
||||||
}, [visibility, form, event]);
|
}, [visibility, form, event]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// if (entryData && entryData.scoreboard && entryData.scoreboard[0]) {
|
|
||||||
// console.log("Setting FOrm");
|
|
||||||
// // form.setFieldsValue(entryData.scoreboard[0]);
|
|
||||||
// }
|
|
||||||
}, [form]);
|
|
||||||
|
|
||||||
const handleFinish = async (values) => {
|
const handleFinish = async (values) => {
|
||||||
logImEXEvent("job_close_add_to_scoreboard");
|
logImEXEvent("schedule_manual_event");
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
if (event && event.id) {
|
if (event && event.id) {
|
||||||
updateAppointment();
|
updateAppointment({
|
||||||
|
variables: { appid: event.id, app: values },
|
||||||
|
refetchQueries: ["QUERY_ALL_ACTIVE_APPOINTMENTS"],
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
insertAppointment();
|
insertAppointment({
|
||||||
|
variables: {
|
||||||
|
apt: { ...values, isintake: false, bodyshopid: bodyshop.id },
|
||||||
|
},
|
||||||
|
refetchQueries: ["QUERY_ALL_ACTIVE_APPOINTMENTS"],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
@@ -56,8 +72,8 @@ export default function ScheduleManualEvent({ event }) {
|
|||||||
<div>
|
<div>
|
||||||
<Form form={form} layout="vertical" onFinish={handleFinish}>
|
<Form form={form} layout="vertical" onFinish={handleFinish}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("schedule.fields.note")}
|
label={t("appointments.fields.title")}
|
||||||
name="note"
|
name="title"
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
@@ -67,8 +83,11 @@ export default function ScheduleManualEvent({ event }) {
|
|||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item label={t("appointments.fields.note")} name="note">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("schedule.fields.start")}
|
label={t("appointments.fields.start")}
|
||||||
name="start"
|
name="start"
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
@@ -80,17 +99,42 @@ export default function ScheduleManualEvent({ event }) {
|
|||||||
<FormDateTimePickerComponent />
|
<FormDateTimePickerComponent />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("schedule.fields.end")}
|
label={t("appointments.fields.end")}
|
||||||
name="end"
|
name="end"
|
||||||
rules={[
|
rules={[
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
//message: t("general.validation.required"),
|
//message: t("general.validation.required"),
|
||||||
},
|
},
|
||||||
|
({ getFieldValue }) => ({
|
||||||
|
async validator(rule, value) {
|
||||||
|
if (value) {
|
||||||
|
const { start } = form.getFieldsValue();
|
||||||
|
if (moment(start).isAfter(moment(value))) {
|
||||||
|
return Promise.reject(
|
||||||
|
t("employees.labels.endmustbeafterstart")
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}),
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<FormDateTimePickerComponent />
|
<FormDateTimePickerComponent />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item label={t("appointments.fields.color")} name="color">
|
||||||
|
<Select>
|
||||||
|
{bodyshop.appt_colors.map((col, idx) => (
|
||||||
|
<Select.Option key={idx} value={col.color.hex}>
|
||||||
|
{col.label}
|
||||||
|
</Select.Option>
|
||||||
|
))}
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<Button type="primary" htmlType="submit">
|
<Button type="primary" htmlType="submit">
|
||||||
@@ -112,7 +156,9 @@ export default function ScheduleManualEvent({ event }) {
|
|||||||
return (
|
return (
|
||||||
<Popover content={overlay} visible={visibility}>
|
<Popover content={overlay} visible={visibility}>
|
||||||
<Button loading={loading} onClick={handleClick}>
|
<Button loading={loading} onClick={handleClick}>
|
||||||
{t("schedule.labels.manualevent")}
|
{event
|
||||||
|
? t("appointments.actions.reschedule")
|
||||||
|
: t("appointments.labels.manualevent")}
|
||||||
</Button>
|
</Button>
|
||||||
</Popover>
|
</Popover>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -91,6 +91,26 @@ export const INSERT_APPOINTMENT_BLOCK = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const INSERT_MANUAL_APPT = gql`
|
||||||
|
mutation INSERT_MANUAL_APPT($apt: appointments_insert_input!) {
|
||||||
|
insert_appointments_one(object: $apt) {
|
||||||
|
start
|
||||||
|
id
|
||||||
|
end
|
||||||
|
arrived
|
||||||
|
title
|
||||||
|
isintake
|
||||||
|
block
|
||||||
|
color
|
||||||
|
note
|
||||||
|
canceled
|
||||||
|
job {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const INSERT_APPOINTMENT = gql`
|
export const INSERT_APPOINTMENT = gql`
|
||||||
mutation INSERT_APPOINTMENT(
|
mutation INSERT_APPOINTMENT(
|
||||||
$app: [appointments_insert_input!]!
|
$app: [appointments_insert_input!]!
|
||||||
|
|||||||
@@ -37,7 +37,9 @@
|
|||||||
"fields": {
|
"fields": {
|
||||||
"alt_transport": "Alt. Trans.",
|
"alt_transport": "Alt. Trans.",
|
||||||
"color": "Appointment Color",
|
"color": "Appointment Color",
|
||||||
"note": "Appt. Note",
|
"end": "End",
|
||||||
|
"note": "Note",
|
||||||
|
"start": "Start",
|
||||||
"time": "Appointment Time",
|
"time": "Appointment Time",
|
||||||
"title": "Title"
|
"title": "Title"
|
||||||
},
|
},
|
||||||
@@ -47,8 +49,10 @@
|
|||||||
"blocked": "Blocked",
|
"blocked": "Blocked",
|
||||||
"cancelledappointment": "Canceled appointment for: ",
|
"cancelledappointment": "Canceled appointment for: ",
|
||||||
"completingjobs": "Completing Jobs",
|
"completingjobs": "Completing Jobs",
|
||||||
|
"dataconsistency": "{{ro_number}} has a data consistency issue. It has been excluded for scheduling purposes. CODE: {{code}}.",
|
||||||
"history": "History",
|
"history": "History",
|
||||||
"inproduction": "Jobs In Production",
|
"inproduction": "Jobs In Production",
|
||||||
|
"manualevent": "Add Manual Appointment",
|
||||||
"noarrivingjobs": "No jobs are arriving.",
|
"noarrivingjobs": "No jobs are arriving.",
|
||||||
"nocompletingjobs": "No jobs scheduled for completion.",
|
"nocompletingjobs": "No jobs scheduled for completion.",
|
||||||
"nodateselected": "No date has been selected.",
|
"nodateselected": "No date has been selected.",
|
||||||
@@ -864,7 +868,7 @@
|
|||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"endmustbeafterstart": "End date must be after start date.Ï",
|
"endmustbeafterstart": "End date must be after start date.",
|
||||||
"flat_rate": "Flat Rate",
|
"flat_rate": "Flat Rate",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"rate_type": "Rate Type",
|
"rate_type": "Rate Type",
|
||||||
|
|||||||
@@ -37,7 +37,9 @@
|
|||||||
"fields": {
|
"fields": {
|
||||||
"alt_transport": "",
|
"alt_transport": "",
|
||||||
"color": "",
|
"color": "",
|
||||||
|
"end": "",
|
||||||
"note": "",
|
"note": "",
|
||||||
|
"start": "",
|
||||||
"time": "",
|
"time": "",
|
||||||
"title": "Título"
|
"title": "Título"
|
||||||
},
|
},
|
||||||
@@ -47,8 +49,10 @@
|
|||||||
"blocked": "",
|
"blocked": "",
|
||||||
"cancelledappointment": "Cita cancelada para:",
|
"cancelledappointment": "Cita cancelada para:",
|
||||||
"completingjobs": "",
|
"completingjobs": "",
|
||||||
|
"dataconsistency": "",
|
||||||
"history": "",
|
"history": "",
|
||||||
"inproduction": "",
|
"inproduction": "",
|
||||||
|
"manualevent": "",
|
||||||
"noarrivingjobs": "",
|
"noarrivingjobs": "",
|
||||||
"nocompletingjobs": "",
|
"nocompletingjobs": "",
|
||||||
"nodateselected": "No se ha seleccionado ninguna fecha.",
|
"nodateselected": "No se ha seleccionado ninguna fecha.",
|
||||||
|
|||||||
@@ -37,7 +37,9 @@
|
|||||||
"fields": {
|
"fields": {
|
||||||
"alt_transport": "",
|
"alt_transport": "",
|
||||||
"color": "",
|
"color": "",
|
||||||
|
"end": "",
|
||||||
"note": "",
|
"note": "",
|
||||||
|
"start": "",
|
||||||
"time": "",
|
"time": "",
|
||||||
"title": "Titre"
|
"title": "Titre"
|
||||||
},
|
},
|
||||||
@@ -47,8 +49,10 @@
|
|||||||
"blocked": "",
|
"blocked": "",
|
||||||
"cancelledappointment": "Rendez-vous annulé pour:",
|
"cancelledappointment": "Rendez-vous annulé pour:",
|
||||||
"completingjobs": "",
|
"completingjobs": "",
|
||||||
|
"dataconsistency": "",
|
||||||
"history": "",
|
"history": "",
|
||||||
"inproduction": "",
|
"inproduction": "",
|
||||||
|
"manualevent": "",
|
||||||
"noarrivingjobs": "",
|
"noarrivingjobs": "",
|
||||||
"nocompletingjobs": "",
|
"nocompletingjobs": "",
|
||||||
"nodateselected": "Aucune date n'a été sélectionnée.",
|
"nodateselected": "Aucune date n'a été sélectionnée.",
|
||||||
|
|||||||
Reference in New Issue
Block a user