IO-827 Update employee config screen.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<babeledit_project be_version="2.7.1" version="1.2">
|
<babeledit_project version="1.2" be_version="2.7.1">
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
BabelEdit project file
|
BabelEdit project file
|
||||||
@@ -10975,6 +10975,69 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>flat_rate</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>rate_type</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>straight_time</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>
|
||||||
</children>
|
</children>
|
||||||
</folder_node>
|
</folder_node>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
|
|||||||
25120
client/package-lock.json
generated
25120
client/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
import { DeleteFilled } from "@ant-design/icons";
|
import { DeleteFilled } from "@ant-design/icons";
|
||||||
import { Button, Form, Input, InputNumber, Select, Switch } from "antd";
|
import { Button, Card, Form, Input, InputNumber, Select, Switch } from "antd";
|
||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import React, { useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { useApolloClient } from "@apollo/client";
|
import { useApolloClient } from "@apollo/client";
|
||||||
@@ -26,6 +26,7 @@ export function ShopEmployeesFormComponent({
|
|||||||
handleFinish,
|
handleFinish,
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedEmployee) form.resetFields();
|
if (selectedEmployee) form.resetFields();
|
||||||
@@ -34,206 +35,213 @@ export function ShopEmployeesFormComponent({
|
|||||||
if (!selectedEmployee) return null;
|
if (!selectedEmployee) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form
|
<Card
|
||||||
onFinish={handleFinish}
|
extra={
|
||||||
autoComplete={"off"}
|
<Button type="primary" onClick={() => form.submit()}>
|
||||||
form={form}
|
{t("general.actions.save")}
|
||||||
initialValues={{
|
</Button>
|
||||||
...selectedEmployee,
|
}
|
||||||
hire_date: selectedEmployee.hire_date
|
|
||||||
? moment(selectedEmployee.hire_date)
|
|
||||||
: null,
|
|
||||||
termination_date: selectedEmployee.termination_date
|
|
||||||
? moment(selectedEmployee.termination_date)
|
|
||||||
: null,
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Button type="primary" htmlType="submit">
|
<Form
|
||||||
{t("general.actions.save")}
|
onFinish={handleFinish}
|
||||||
</Button>
|
autoComplete={"off"}
|
||||||
|
layout="vertical"
|
||||||
<Form.Item
|
form={form}
|
||||||
name="first_name"
|
initialValues={{
|
||||||
label={t("employees.fields.first_name")}
|
...selectedEmployee,
|
||||||
rules={[
|
hire_date: selectedEmployee.hire_date
|
||||||
{
|
? moment(selectedEmployee.hire_date)
|
||||||
required: true,
|
: null,
|
||||||
message: t("general.validation.required"),
|
termination_date: selectedEmployee.termination_date
|
||||||
},
|
? moment(selectedEmployee.termination_date)
|
||||||
]}
|
: null,
|
||||||
>
|
|
||||||
<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")}
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Input />
|
|
||||||
</Form.Item>
|
|
||||||
<Form.Item
|
|
||||||
label={t("employees.fields.pin")}
|
|
||||||
name="pin"
|
|
||||||
rules={[
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: t("general.validation.required"),
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
>
|
|
||||||
<Input />
|
|
||||||
</Form.Item>
|
|
||||||
<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.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>
|
|
||||||
{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.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 />
|
<LayoutFormRow>
|
||||||
</Form.Item>
|
<Form.Item
|
||||||
</Form>
|
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")}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: t("general.validation.required"),
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<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>
|
||||||
|
{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(
|
export default connect(
|
||||||
|
|||||||
@@ -34,12 +34,13 @@ export default function ShopEmployeesListComponent({
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: t("employees.fields.base_rate"),
|
title: t("employees.labels.rate_type"),
|
||||||
dataIndex: "base_rate",
|
dataIndex: "rate_type",
|
||||||
key: "base_rate",
|
key: "rate_type",
|
||||||
render: (text, record) => (
|
render: (text, record) =>
|
||||||
<CurrencyFormatter>{record.base_rate}</CurrencyFormatter>
|
record.flat_rate
|
||||||
),
|
? t("employees.labels.flat_rate")
|
||||||
|
: t("employees.labels.straight_time"),
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// title: t("employees.labels.actions"),
|
// title: t("employees.labels.actions"),
|
||||||
|
|||||||
@@ -711,7 +711,10 @@
|
|||||||
"user_email": "User Email"
|
"user_email": "User Email"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"actions": "Actions"
|
"actions": "Actions",
|
||||||
|
"flat_rate": "Flat Rate",
|
||||||
|
"rate_type": "Rate Type",
|
||||||
|
"straight_time": "Straight Time"
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
"delete": "Employee deleted successfully.",
|
"delete": "Employee deleted successfully.",
|
||||||
|
|||||||
@@ -711,7 +711,10 @@
|
|||||||
"user_email": ""
|
"user_email": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"actions": ""
|
"actions": "",
|
||||||
|
"flat_rate": "",
|
||||||
|
"rate_type": "",
|
||||||
|
"straight_time": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
"delete": "Empleado eliminado con éxito.",
|
"delete": "Empleado eliminado con éxito.",
|
||||||
|
|||||||
@@ -711,7 +711,10 @@
|
|||||||
"user_email": ""
|
"user_email": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"actions": ""
|
"actions": "",
|
||||||
|
"flat_rate": "",
|
||||||
|
"rate_type": "",
|
||||||
|
"straight_time": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
"delete": "L'employé a bien été supprimé.",
|
"delete": "L'employé a bien été supprimé.",
|
||||||
|
|||||||
6051
package-lock.json
generated
6051
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user