IO-1275 Finish appointment notes.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Button, Popover, Space } from "antd";
|
import { Button, Divider, Popover, Space } from "antd";
|
||||||
import { AlertFilled } from "@ant-design/icons";
|
import { AlertFilled } from "@ant-design/icons";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -13,6 +13,7 @@ import DataLabel from "../data-label/data-label.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 queryString from "query-string";
|
import queryString from "query-string";
|
||||||
|
import ScheduleEventNote from "./schedule-event.note.component";
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => ({
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
setScheduleContext: (context) =>
|
setScheduleContext: (context) =>
|
||||||
@@ -39,7 +40,7 @@ export function ScheduleEventComponent({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const popoverContent = (
|
const popoverContent = (
|
||||||
<div>
|
<div style={{ maxWidth: "40vw" }}>
|
||||||
{!event.isintake ? (
|
{!event.isintake ? (
|
||||||
<strong>{event.title}</strong>
|
<strong>{event.title}</strong>
|
||||||
) : (
|
) : (
|
||||||
@@ -84,12 +85,10 @@ export function ScheduleEventComponent({
|
|||||||
{(event.job && event.job.alt_transport) || ""}
|
{(event.job && event.job.alt_transport) || ""}
|
||||||
<ScheduleAtChange job={event && event.job} />
|
<ScheduleAtChange job={event && event.job} />
|
||||||
</DataLabel>
|
</DataLabel>
|
||||||
<DataLabel label={t("appointments.fields.note")}>
|
<ScheduleEventNote event={event} />
|
||||||
{event.note || ""}
|
|
||||||
</DataLabel>
|
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
|
<Divider />
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
{event.job ? (
|
{event.job ? (
|
||||||
<Link to={`/manage/jobs/${event.job && event.job.id}`}>
|
<Link to={`/manage/jobs/${event.job && event.job.id}`}>
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import { EditFilled, SaveFilled } from "@ant-design/icons";
|
||||||
|
import { useMutation } from "@apollo/client";
|
||||||
|
import { Button, Input, notification, Space } from "antd";
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { UPDATE_APPOINTMENT } from "../../graphql/appointments.queries";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
import DataLabel from "../data-label/data-label.component";
|
||||||
|
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
bodyshop: selectBodyshop,
|
||||||
|
});
|
||||||
|
const mapDispatchToProps = (dispatch) => ({
|
||||||
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
||||||
|
});
|
||||||
|
|
||||||
|
export function ScheduleEventNote({ event }) {
|
||||||
|
const [editing, setEditing] = useState(false);
|
||||||
|
const [note, setNote] = useState(event.note || "");
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [updateAppointment] = useMutation(UPDATE_APPOINTMENT);
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const toggleEdit = async () => {
|
||||||
|
if (editing) {
|
||||||
|
//Await the update
|
||||||
|
setLoading(true);
|
||||||
|
const result = await updateAppointment({
|
||||||
|
variables: {
|
||||||
|
appid: event.id,
|
||||||
|
app: { note },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!!!result.errors) {
|
||||||
|
// notification["success"]({ message: t("appointments.successes.saved") });
|
||||||
|
} else {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("jobs.errors.saving", {
|
||||||
|
error: JSON.stringify(result.errors),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setEditing(false);
|
||||||
|
} else {
|
||||||
|
setEditing(true);
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DataLabel label={t("appointments.fields.note")}>
|
||||||
|
<Space flex>
|
||||||
|
{!editing ? (
|
||||||
|
event.note || ""
|
||||||
|
) : (
|
||||||
|
<Input.TextArea
|
||||||
|
rows={3}
|
||||||
|
value={note}
|
||||||
|
onChange={(e) => setNote(e.target.value)}
|
||||||
|
style={{ maxWidth: "8vw" }}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Button onClick={toggleEdit} loading={loading}>
|
||||||
|
{editing ? <SaveFilled /> : <EditFilled />}
|
||||||
|
</Button>
|
||||||
|
</Space>
|
||||||
|
</DataLabel>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(ScheduleEventNote);
|
||||||
@@ -1,4 +1,14 @@
|
|||||||
import { Button, Col, Form, Input, Row, Select, Switch } from "antd";
|
import {
|
||||||
|
Button,
|
||||||
|
Col,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
Row,
|
||||||
|
Select,
|
||||||
|
Space,
|
||||||
|
Switch,
|
||||||
|
Typography,
|
||||||
|
} from "antd";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
@@ -91,31 +101,34 @@ export function ScheduleJobModalComponent({
|
|||||||
<DateTimePicker onlyFuture />
|
<DateTimePicker onlyFuture />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
<LayoutFormRow header={t("appointments.labels.smartscheduling")}>
|
|
||||||
|
<Typography.Title level={4}>
|
||||||
|
{t("appointments.labels.smartscheduling")}
|
||||||
|
</Typography.Title>
|
||||||
|
|
||||||
|
{
|
||||||
|
// smartOptions.length > 0 && (
|
||||||
|
// <div>{t("appointments.labels.suggesteddates")}</div>
|
||||||
|
// )
|
||||||
|
}
|
||||||
|
<Space wrap>
|
||||||
<Button onClick={handleSmartScheduling} loading={loading}>
|
<Button onClick={handleSmartScheduling} loading={loading}>
|
||||||
{t("appointments.actions.calculate")}
|
{t("appointments.actions.calculate")}
|
||||||
</Button>
|
</Button>
|
||||||
{smartOptions.length > 0 && (
|
{smartOptions.map((d, idx) => (
|
||||||
<div>{t("appointments.labels.suggesteddates")}</div>
|
<Button
|
||||||
)}
|
className="imex-flex-row__margin"
|
||||||
<div
|
key={idx}
|
||||||
className="imex-flex-row imex-flex-row__flex-space-around"
|
onClick={() => {
|
||||||
style={{ flexWrap: "wrap" }}
|
form.setFieldsValue({ start: new moment(d).add(8, "hours") });
|
||||||
>
|
handleDateBlur();
|
||||||
{smartOptions.map((d, idx) => (
|
}}
|
||||||
<Button
|
>
|
||||||
className="imex-flex-row__margin"
|
<DateFormatter>{d}</DateFormatter>
|
||||||
key={idx}
|
</Button>
|
||||||
onClick={() => {
|
))}
|
||||||
form.setFieldsValue({ start: new moment(d).add(8, "hours") });
|
</Space>
|
||||||
handleDateBlur();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<DateFormatter>{d}</DateFormatter>
|
|
||||||
</Button>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</LayoutFormRow>
|
|
||||||
<LayoutFormRow grow>
|
<LayoutFormRow grow>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="notifyCustomer"
|
name="notifyCustomer"
|
||||||
|
|||||||
Reference in New Issue
Block a user