Added block calendar day for BOD-94

This commit is contained in:
Patrick Fic
2020-06-25 13:36:11 -07:00
parent 2e30a9078e
commit 7305994a05
20 changed files with 392 additions and 65 deletions

View File

@@ -196,6 +196,27 @@
<folder_node>
<name>actions</name>
<children>
<concept_node>
<name>block</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>cancel</name>
<definition_loaded>false</definition_loaded>
@@ -442,6 +463,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>blocked</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>cancelledappointment</name>
<definition_loaded>false</definition_loaded>

View File

@@ -1,36 +0,0 @@
import React, { useState } from "react";
import { Button, Popover, Input, InputNumber, Form } from "antd";
import { SelectOutlined } from "@ant-design/icons";
import { useTranslation } from "react-i18next";
export default function InvoiceAddLineButton({ jobLine, discount, disabled }) {
const [visibility, setVisibility] = useState(false);
const { t } = useTranslation();
const popContent = (
<div style={{ display: "flex" }}>
<Form.Item name="line_desc" label={t("joblines.fields.line_desc")}>
<Input />
</Form.Item>
<Form.Item name="oem_partno" label={t("joblines.fields.oem_partno")}>
<Input />
</Form.Item>
<Form.Item name="retail" label={t("invoicelines.fields.retail")}>
<InputNumber precision={2} />
</Form.Item>
<Form.Item name="actual" label={t("invoicelines.fields.actual")}>
<InputNumber precision={2} />
</Form.Item>
DISC: {discount}
<Button onClick={() => setVisibility(false)}>X</Button>
</div>
);
return (
<Popover content={popContent} visible={visibility}>
<Button onClick={() => setVisibility(true)} disabled={!disabled}>
<SelectOutlined />
</Button>
</Popover>
);
}

View File

@@ -0,0 +1,61 @@
import React from "react";
import { MinusCircleTwoTone } from "@ant-design/icons";
import { Dropdown, Menu } from "antd";
import { useTranslation } from "react-i18next";
import { useMutation } from "@apollo/react-hooks";
import { INSERT_APPOINTMENT } from "../../graphql/appointments.queries";
import moment from "moment";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(mapStateToProps, mapDispatchToProps)(ScheduleBlockDay);
export function ScheduleBlockDay({ date, children, refetch, bodyshop }) {
const { t } = useTranslation();
const [insertBlock] = useMutation(INSERT_APPOINTMENT);
const handleMenu = async (e) => {
e.domEvent.stopPropagation();
console.log("date", date);
if (e.key === "block") {
console.log("Block.");
const blockAppt = {
title: t("appointments.labels.blocked"),
block: true,
isintake: false,
bodyshopid: bodyshop.id,
start: moment(date).startOf("day"),
end: moment(date).endOf("day"),
};
console.log("handleMenu -> blockAppt", blockAppt);
const result = await insertBlock({
variables: { app: [blockAppt] },
});
if (!!refetch) refetch();
}
};
const menu = (
<Menu onClick={handleMenu}>
<Menu.Item key="block">{t("appointments.actions.block")}</Menu.Item>
<Menu.Item key="2">2nd menu item</Menu.Item>
<Menu.Item key="3">3rd menu item</Menu.Item>
</Menu>
);
return (
<Dropdown overlay={menu} trigger={["contextMenu"]}>
{children}
</Dropdown>
);
}

View File

@@ -9,6 +9,8 @@ import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component";
import { Progress } from "antd";
import { MdCallReceived, MdCallMissedOutgoing } from "react-icons/md";
import Icon from "@ant-design/icons";
import ScheduleBlockDay from "../schedule-block-day/schedule-block-day.component";
const ShopTargetHrs = 100;
const mapStateToProps = createStructuredSelector({
@@ -23,6 +25,7 @@ const mapDispatchToProps = (dispatch) => ({
export function ScheduleCalendarHeaderComponent({
label,
refetch,
date,
load,
calculating,
@@ -37,7 +40,7 @@ export function ScheduleCalendarHeaderComponent({
percent={((loadData.expectedLoad || 0) / ShopTargetHrs) * 100}
/>
<div>
<div className="imex-flex-row imex-flex-row__flex-space-around">
<Icon component={MdCallReceived} />
{(loadData.hoursIn || 0) && loadData.hoursIn.toFixed(2)}
<Icon component={MdCallMissedOutgoing} />
@@ -47,14 +50,16 @@ export function ScheduleCalendarHeaderComponent({
) : null;
return (
<div>
{label}
{calculating || JSON.stringify(load) === "{}" ? (
<LoadingSkeleton />
) : (
LoadComponent
)}
</div>
<ScheduleBlockDay date={date} refetch={refetch}>
<div>
{label}
{calculating || JSON.stringify(load) === "{}" ? (
<LoadingSkeleton />
) : (
LoadComponent
)}
</div>
</ScheduleBlockDay>
);
}
export default connect(

View File

@@ -6,5 +6,9 @@
}
.imex-event-arrived {
background-color: green;
background-color: rgba(4, 141, 4, 0.4);
}
.imex-event-block {
background-color: rgba(212, 2, 2, 0.6);
}

View File

@@ -37,14 +37,20 @@ export function ScheduleCalendarWrapperComponent({
// bucket.gte <= jobHrs && (!!bucket.lt ? bucket.lt > jobHrs : true)
// )[0];
return { className: event.arrived ? "imex-event-arrived" : "" };
return {
className: `${event.arrived ? "imex-event-arrived" : ""} ${
event.block ? "imex-event-block" : ""
}`,
};
};
const selectedDate = new Date(date || moment(search.date) || Date.now());
return (
<Calendar
events={data}
defaultView={search.view || defaultView || "week"}
date={new Date(date || search.date || Date.now())}
date={selectedDate}
onNavigate={(date, view, action) => {
search.date = date.toISOString().substr(0, 10);
history.push({ search: queryString.stringify(search) });

View File

@@ -5,6 +5,8 @@ import { UPDATE_JOB } from "../../graphql/jobs.queries";
import ScheduleEventComponent from "./schedule-event.component";
import { notification } from "antd";
import { useTranslation } from "react-i18next";
export default function ScheduleEventContainer({ event, refetch }) {
const { t } = useTranslation();
const [cancelAppointment] = useMutation(CANCEL_APPOINTMENT_BY_ID);

View File

@@ -18,6 +18,7 @@ export const QUERY_ALL_ACTIVE_APPOINTMENTS = gql`
arrived
title
isintake
block
job {
ro_number
ownr_ln
@@ -42,6 +43,12 @@ export const INSERT_APPOINTMENT = gql`
insert_appointments(objects: $app) {
returning {
id
start
end
arrived
title
isintake
block
}
}
}
@@ -85,6 +92,7 @@ export const CANCEL_APPOINTMENT_BY_ID = gql`
) {
returning {
id
canceled
}
}
}

View File

@@ -19,6 +19,7 @@
},
"appointments": {
"actions": {
"block": "Block Day",
"cancel": "Cancel",
"intake": "Intake",
"new": "New Appointment",
@@ -36,6 +37,7 @@
},
"labels": {
"arrivedon": "Arrived on: ",
"blocked": "Blocked",
"cancelledappointment": "Canceled appointment for: ",
"history": "History",
"nodateselected": "No date has been selected.",

View File

@@ -19,6 +19,7 @@
},
"appointments": {
"actions": {
"block": "",
"cancel": "Cancelar",
"intake": "Consumo",
"new": "Nueva cita",
@@ -36,6 +37,7 @@
},
"labels": {
"arrivedon": "Llegado el:",
"blocked": "",
"cancelledappointment": "Cita cancelada para:",
"history": "",
"nodateselected": "No se ha seleccionado ninguna fecha.",

View File

@@ -19,6 +19,7 @@
},
"appointments": {
"actions": {
"block": "",
"cancel": "annuler",
"intake": "Admission",
"new": "Nouveau rendez-vous",
@@ -36,6 +37,7 @@
},
"labels": {
"arrivedon": "Arrivé le:",
"blocked": "",
"cancelledappointment": "Rendez-vous annulé pour:",
"history": "",
"nodateselected": "Aucune date n'a été sélectionnée.",

View File

@@ -0,0 +1,5 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."appointments" DROP COLUMN "block";
type: run_sql

View File

@@ -0,0 +1,6 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."appointments" ADD COLUMN "block" boolean NOT NULL DEFAULT
false;
type: run_sql

View File

@@ -0,0 +1,35 @@
- args:
role: user
table:
name: appointments
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
- jobid
- start
- end
- canceled
- arrived
- isintake
- bodyshopid
- title
set: {}
role: user
table:
name: appointments
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,36 @@
- args:
role: user
table:
name: appointments
schema: public
type: drop_insert_permission
- args:
permission:
check:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
columns:
- arrived
- block
- bodyshopid
- canceled
- created_at
- end
- id
- isintake
- jobid
- start
- title
- updated_at
set: {}
role: user
table:
name: appointments
schema: public
type: create_insert_permission

View File

@@ -0,0 +1,36 @@
- args:
role: user
table:
name: appointments
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: true
columns:
- arrived
- canceled
- isintake
- title
- created_at
- end
- start
- updated_at
- bodyshopid
- id
- jobid
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: appointments
schema: public
type: create_select_permission

View File

@@ -0,0 +1,37 @@
- args:
role: user
table:
name: appointments
schema: public
type: drop_select_permission
- args:
permission:
allow_aggregations: true
columns:
- arrived
- block
- bodyshopid
- canceled
- created_at
- end
- id
- isintake
- jobid
- start
- title
- updated_at
computed_fields: []
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
role: user
table:
name: appointments
schema: public
type: create_select_permission

View File

@@ -0,0 +1,35 @@
- args:
role: user
table:
name: appointments
schema: public
type: drop_update_permission
- args:
permission:
columns:
- arrived
- canceled
- isintake
- title
- created_at
- end
- start
- updated_at
- bodyshopid
- id
- jobid
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: appointments
schema: public
type: create_update_permission

View File

@@ -0,0 +1,36 @@
- args:
role: user
table:
name: appointments
schema: public
type: drop_update_permission
- args:
permission:
columns:
- arrived
- block
- bodyshopid
- canceled
- created_at
- end
- id
- isintake
- jobid
- start
- title
- updated_at
filter:
bodyshop:
associations:
_and:
- user:
authid:
_eq: X-Hasura-User-Id
- active:
_eq: true
set: {}
role: user
table:
name: appointments
schema: public
type: create_update_permission

View File

@@ -105,32 +105,34 @@ tables:
- active:
_eq: true
columns:
- id
- arrived
- block
- bodyshopid
- canceled
- created_at
- updated_at
- end
- id
- isintake
- jobid
- start
- end
- canceled
- arrived
- isintake
- bodyshopid
- title
- updated_at
select_permissions:
- role: user
permission:
columns:
- arrived
- block
- bodyshopid
- canceled
- isintake
- title
- created_at
- end
- start
- updated_at
- bodyshopid
- id
- isintake
- jobid
- start
- title
- updated_at
filter:
bodyshop:
associations:
@@ -146,16 +148,17 @@ tables:
permission:
columns:
- arrived
- block
- bodyshopid
- canceled
- isintake
- title
- created_at
- end
- start
- updated_at
- bodyshopid
- id
- isintake
- jobid
- start
- title
- updated_at
filter:
bodyshop:
associations: