291 lines
9.2 KiB
JavaScript
291 lines
9.2 KiB
JavaScript
import { DeleteFilled } from "@ant-design/icons";
|
|
import { Button, Card, Form, Input, InputNumber, Select, Switch } from "antd";
|
|
import moment from "moment";
|
|
import React, { useEffect } from "react";
|
|
import { useApolloClient } from "@apollo/client";
|
|
import { useTranslation } from "react-i18next";
|
|
import { connect } from "react-redux";
|
|
import { createStructuredSelector } from "reselect";
|
|
import {
|
|
CHECK_EMPLOYEE_NUMBER,
|
|
QUERY_USERS_BY_EMAIL,
|
|
} from "../../graphql/employees.queries";
|
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
|
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";
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
bodyshop: selectBodyshop,
|
|
});
|
|
const mapDispatchToProps = (dispatch) => ({
|
|
//setUserLanguage: language => dispatch(setUserLanguage(language))
|
|
});
|
|
|
|
export function ShopEmployeesFormComponent({
|
|
bodyshop,
|
|
form,
|
|
selectedEmployee,
|
|
handleFinish,
|
|
}) {
|
|
const { t } = useTranslation();
|
|
|
|
const client = useApolloClient();
|
|
useEffect(() => {
|
|
if (selectedEmployee) form.resetFields();
|
|
}, [selectedEmployee, form]);
|
|
|
|
if (!selectedEmployee) return null;
|
|
|
|
return (
|
|
<Card
|
|
extra={
|
|
<Button type="primary" onClick={() => form.submit()}>
|
|
{t("general.actions.save")}
|
|
</Button>
|
|
}
|
|
>
|
|
<Form
|
|
onFinish={handleFinish}
|
|
autoComplete={"off"}
|
|
layout="vertical"
|
|
form={form}
|
|
initialValues={{
|
|
...selectedEmployee,
|
|
hire_date: selectedEmployee.hire_date
|
|
? moment(selectedEmployee.hire_date)
|
|
: null,
|
|
termination_date: selectedEmployee.termination_date
|
|
? moment(selectedEmployee.termination_date)
|
|
: null,
|
|
}}
|
|
>
|
|
<LayoutFormRow>
|
|
<Form.Item
|
|
name="first_name"
|
|
label={t("employees.fields.first_name")}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<Input />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("employees.fields.last_name")}
|
|
name="last_name"
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<Input />
|
|
</Form.Item>
|
|
<Form.Item
|
|
name="employee_number"
|
|
label={t("employees.fields.employee_number")}
|
|
validateTrigger="onBlur"
|
|
hasFeedback
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
({ getFieldValue }) => ({
|
|
async validator(rule, value) {
|
|
if (value) {
|
|
const response = await client.query({
|
|
query: CHECK_EMPLOYEE_NUMBER,
|
|
variables: {
|
|
employeenumber: value,
|
|
},
|
|
});
|
|
|
|
if (
|
|
response.data.employees_aggregate.aggregate.count === 0
|
|
) {
|
|
return Promise.resolve();
|
|
} else if (
|
|
response.data.employees_aggregate.nodes.length === 1 &&
|
|
response.data.employees_aggregate.nodes[0].id ===
|
|
form.getFieldValue("id")
|
|
) {
|
|
return Promise.resolve();
|
|
}
|
|
return Promise.reject(
|
|
t("employees.validation.unique_employee_number")
|
|
);
|
|
} else {
|
|
return Promise.resolve();
|
|
}
|
|
},
|
|
}),
|
|
]}
|
|
>
|
|
<Input />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("employees.fields.pin")}
|
|
name="pin"
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<Input />
|
|
</Form.Item>
|
|
</LayoutFormRow>
|
|
<LayoutFormRow>
|
|
<Form.Item
|
|
label={t("employees.fields.active")}
|
|
valuePropName="checked"
|
|
name="active"
|
|
>
|
|
<Switch />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("employees.fields.flat_rate")}
|
|
name="flat_rate"
|
|
valuePropName="checked"
|
|
>
|
|
<Switch />
|
|
</Form.Item>
|
|
<Form.Item
|
|
name="hire_date"
|
|
label={t("employees.fields.hire_date")}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<FormDatePicker />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("employees.fields.termination_date")}
|
|
name="termination_date"
|
|
>
|
|
<FormDatePicker />
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("employees.fields.user_email")}
|
|
name="user_email"
|
|
validateTrigger="onBlur"
|
|
rules={[
|
|
({ getFieldValue }) => ({
|
|
async validator(rule, value) {
|
|
const user_email = getFieldValue("user_email");
|
|
|
|
if (user_email && value) {
|
|
const response = await client.query({
|
|
query: QUERY_USERS_BY_EMAIL,
|
|
variables: {
|
|
email: user_email,
|
|
},
|
|
});
|
|
|
|
if (response.data.users.length === 1) {
|
|
return Promise.resolve();
|
|
}
|
|
return Promise.reject(
|
|
t("bodyshop.validation.useremailmustexist")
|
|
);
|
|
} else {
|
|
return Promise.resolve();
|
|
}
|
|
},
|
|
}),
|
|
]}
|
|
>
|
|
<Input />
|
|
</Form.Item>
|
|
</LayoutFormRow>
|
|
<Form.List name={["rates"]}>
|
|
{(fields, { add, remove, move }) => {
|
|
return (
|
|
<div>
|
|
{fields.map((field, index) => (
|
|
<Form.Item key={field.key} style={{ padding: 0, margin: 2 }}>
|
|
<LayoutFormRow grow>
|
|
<Form.Item
|
|
label={t("employees.fields.cost_center")}
|
|
key={`${index}`}
|
|
name={[field.name, "cost_center"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<Select>
|
|
<Select.Option
|
|
key={"shift"}
|
|
value="timetickets.labels.shift"
|
|
>
|
|
{t("timetickets.labels.shift")}
|
|
</Select.Option>
|
|
{bodyshop.md_responsibility_centers.costs.map((c) => (
|
|
<Select.Option key={c.name} value={c.name}>
|
|
{c.name}
|
|
</Select.Option>
|
|
))}
|
|
</Select>
|
|
</Form.Item>
|
|
<Form.Item
|
|
label={t("employees.fields.rate")}
|
|
key={`${index}`}
|
|
name={[field.name, "rate"]}
|
|
rules={[
|
|
{
|
|
required: true,
|
|
//message: t("general.validation.required"),
|
|
},
|
|
]}
|
|
>
|
|
<InputNumber min={0} precision={2} />
|
|
</Form.Item>
|
|
<DeleteFilled
|
|
onClick={() => {
|
|
remove(field.name);
|
|
}}
|
|
/>
|
|
<FormListMoveArrows
|
|
move={move}
|
|
index={index}
|
|
total={fields.length}
|
|
/>
|
|
</LayoutFormRow>
|
|
</Form.Item>
|
|
))}
|
|
<Form.Item>
|
|
<Button
|
|
type="dashed"
|
|
onClick={() => {
|
|
add();
|
|
}}
|
|
style={{ width: "100%" }}
|
|
>
|
|
{t("employees.actions.newrate")}
|
|
</Button>
|
|
</Form.Item>
|
|
</div>
|
|
);
|
|
}}
|
|
</Form.List>
|
|
</Form>
|
|
</Card>
|
|
);
|
|
}
|
|
export default connect(
|
|
mapStateToProps,
|
|
mapDispatchToProps
|
|
)(ShopEmployeesFormComponent);
|