diff --git a/client/src/components/shop-employees/shop-employees-add-vacation.component.jsx b/client/src/components/shop-employees/shop-employees-add-vacation.component.jsx
new file mode 100644
index 000000000..d12bfcc03
--- /dev/null
+++ b/client/src/components/shop-employees/shop-employees-add-vacation.component.jsx
@@ -0,0 +1,124 @@
+import { useMutation } from "@apollo/client";
+import { Button, Card, Form, notification, Popover, Space } from "antd";
+import moment from "moment";
+import React, { useState } from "react";
+import { useTranslation } from "react-i18next";
+import { logImEXEvent } from "../../firebase/firebase.utils";
+import { INSERT_VACATION } from "../../graphql/employees.queries";
+import FormDatePicker from "../form-date-picker/form-date-picker.component";
+
+export default function ShopEmployeeAddVacation({ employee }) {
+ const { t } = useTranslation();
+ const [insertVacation] = useMutation(INSERT_VACATION);
+
+ const [loading, setLoading] = useState(false);
+ const [form] = Form.useForm();
+ const [visibility, setVisibility] = useState(false);
+
+ const handleFinish = async (values) => {
+ logImEXEvent("employee_add_vacation");
+
+ setLoading(true);
+ let result;
+
+ result = await insertVacation({
+ variables: { vacation: { ...values, employeeid: employee.id } },
+ update(cache, { data }) {
+ cache.modify({
+ id: cache.identify({ id: employee.id, __typename: "employees" }),
+ fields: {
+ employee_vacations(ex) {
+ return [data.insert_employee_vacation_one, ...ex];
+ },
+ },
+ });
+ },
+ });
+
+ if (!!result.errors) {
+ notification["error"]({
+ message: t("employees.errors.adding", {
+ message: JSON.stringify(result.errors),
+ }),
+ });
+ } else {
+ notification["success"]({
+ message: t("employees.successes.added"),
+ });
+ }
+ setLoading(false);
+ setVisibility(false);
+ };
+
+ const overlay = (
+
+
+
+
+ ({
+ 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();
+ }
+ },
+ }),
+ ]}
+ >
+
+
+
+
+
+
+
+
+
+ );
+
+ const handleClick = (e) => {
+ setVisibility(true);
+ };
+
+ return (
+
+
+
+ );
+}
diff --git a/client/src/components/shop-employees/shop-employees-form.component.jsx b/client/src/components/shop-employees/shop-employees-form.component.jsx
index acfadbcde..2282d62ef 100644
--- a/client/src/components/shop-employees/shop-employees-form.component.jsx
+++ b/client/src/components/shop-employees/shop-employees-form.component.jsx
@@ -1,20 +1,41 @@
import { DeleteFilled } from "@ant-design/icons";
-import { Button, Card, Form, Input, InputNumber, Select, Switch } from "antd";
+import { useApolloClient, useMutation, useQuery } from "@apollo/client";
+import {
+ Button,
+ Card,
+ Form,
+ Input,
+ InputNumber,
+ notification,
+ Select,
+ Switch,
+ Table,
+} from "antd";
+import { useForm } from "antd/es/form/Form";
import moment from "moment";
+import querystring from "query-string";
import React, { useEffect } from "react";
-import { useApolloClient } from "@apollo/client";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
+import { useHistory, useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect";
+import { logImEXEvent } from "../../firebase/firebase.utils";
import {
CHECK_EMPLOYEE_NUMBER,
+ DELETE_VACATION,
+ INSERT_EMPLOYEES,
+ QUERY_EMPLOYEE_BY_ID,
QUERY_USERS_BY_EMAIL,
+ UPDATE_EMPLOYEE,
} from "../../graphql/employees.queries";
import { selectBodyshop } from "../../redux/user/user.selectors";
+import CiecaSelect from "../../utils/Ciecaselect";
+import { DateFormatter } from "../../utils/DateFormatter";
+import AlertComponent from "../alert/alert.component";
import FormDatePicker from "../form-date-picker/form-date-picker.component";
import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
-import CiecaSelect from "../../utils/Ciecaselect";
+import ShopEmployeeAddVacation from "./shop-employees-add-vacation.component";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -23,20 +44,129 @@ const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
-export function ShopEmployeesFormComponent({
- bodyshop,
- form,
- selectedEmployee,
- handleFinish,
-}) {
+export function ShopEmployeesFormComponent({ bodyshop }) {
const { t } = useTranslation();
+ const [form] = useForm();
+ const history = useHistory();
+ const search = querystring.parse(useLocation().search);
+ const [deleteVacation] = useMutation(DELETE_VACATION);
+ const { error, data } = useQuery(QUERY_EMPLOYEE_BY_ID, {
+ variables: { id: search.employeeId },
+ skip: !search.employeeId || search.employeeId === "new",
+ fetchPolicy: "network-only",
+ nextFetchPolicy: "network-only",
+ });
const client = useApolloClient();
useEffect(() => {
- if (selectedEmployee) form.resetFields();
- }, [selectedEmployee, form]);
+ if (data && data.employees_by_pk) form.setFieldsValue(data.employees_by_pk);
+ else {
+ form.resetFields();
+ }
+ }, [form, data, search.employeeId]);
- if (!selectedEmployee) return null;
+ const [updateEmployee] = useMutation(UPDATE_EMPLOYEE);
+ const [insertEmployees] = useMutation(INSERT_EMPLOYEES);
+
+ const handleFinish = (values) => {
+ if (search.employeeId && search.employeeId !== "new") {
+ //Update a record.
+ logImEXEvent("shop_employee_update");
+
+ updateEmployee({
+ variables: {
+ id: search.employeeId,
+ employee: {
+ ...values,
+ user_email: values.user_email === "" ? null : values.user_email,
+ },
+ },
+ })
+ .then((r) => {
+ notification["success"]({
+ message: t("employees.successes.save"),
+ });
+ })
+ .catch((error) => {
+ notification["error"]({
+ message: t("employees.errors.save", {
+ message: JSON.stringify(error),
+ }),
+ });
+ });
+ } else {
+ //New record, insert it.
+ logImEXEvent("shop_employee_insert");
+
+ insertEmployees({
+ variables: { employees: [{ ...values, shopid: bodyshop.id }] },
+ refetchQueries: ["QUERY_EMPLOYEES"],
+ }).then((r) => {
+ search.employeeId = r.data.insert_employees.returning[0].id;
+ history.push({ search: querystring.stringify(search) });
+ notification["success"]({
+ message: t("employees.successes.save"),
+ });
+ });
+ }
+ };
+
+ if (!search.employeeId) return null;
+ if (error) return
;
+
+ const columns = [
+ {
+ title: t("employees.fields.vacation.start"),
+ dataIndex: "start",
+ key: "start",
+ render: (text, record) =>
{text},
+ },
+ {
+ title: t("employees.fields.vacation.end"),
+ dataIndex: "end",
+ key: "end",
+ render: (text, record) =>
{text},
+ },
+ {
+ title: t("employees.fields.vacation.length"),
+ dataIndex: "length",
+ key: "length",
+ render: (text, record) =>
+ moment(record.end).diff(moment(record.start), "days", true).toFixed(1),
+ },
+ {
+ title: t("general.labels.actions"),
+ dataIndex: "actions",
+ key: "actions",
+ render: (text, record) => (
+
+ ),
+ },
+ ];
return (
+
+ (
+
+ )}
+ columns={columns}
+ rowKey={"id"}
+ dataSource={data ? data.employees_by_pk.employee_vacations : []}
+ />
);
}
diff --git a/client/src/components/shop-employees/shop-employees-list.component.jsx b/client/src/components/shop-employees/shop-employees-list.component.jsx
index e6e3374d7..416e875f9 100644
--- a/client/src/components/shop-employees/shop-employees-list.component.jsx
+++ b/client/src/components/shop-employees/shop-employees-list.component.jsx
@@ -1,19 +1,22 @@
import { Button, Table } from "antd";
+import queryString from "query-string";
import React from "react";
import { useTranslation } from "react-i18next";
-export default function ShopEmployeesListComponent({
- loading,
- employees,
- selectedEmployee,
- setSelectedEmployee,
- handleDelete,
-}) {
+import { useHistory, useLocation } from "react-router-dom";
+
+export default function ShopEmployeesListComponent({ loading, employees }) {
const { t } = useTranslation();
+ const history = useHistory();
+ const search = queryString.parse(useLocation().search);
const handleOnRowClick = (record) => {
if (record) {
- setSelectedEmployee(record);
- } else setSelectedEmployee({});
+ search.employeeId = record.id;
+ history.push({ search: queryString.stringify(search) });
+ } else {
+ delete search.employeeId;
+ history.push({ search: queryString.stringify(search) });
+ }
};
const columns = [
{
@@ -41,18 +44,6 @@ export default function ShopEmployeesListComponent({
? t("employees.labels.flat_rate")
: t("employees.labels.straight_time"),
},
- // {
- // title: t("employees.labels.actions"),
- // dataIndex: "actions",
- // key: "actions",
- // render: (text, record) => (
- //
- //
- //
- // )
- // }
];
return (
@@ -62,7 +53,8 @@ export default function ShopEmployeesListComponent({