IO-3624 Polish employee and team config layouts
This commit is contained in:
@@ -8,7 +8,7 @@ import { INSERT_VACATION } from "../../graphql/employees.queries";
|
|||||||
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx";
|
import DateTimePicker from "../form-date-time-picker/form-date-time-picker.component.jsx";
|
||||||
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
import { useNotification } from "../../contexts/Notifications/notificationContext.jsx";
|
||||||
|
|
||||||
export default function ShopEmployeeAddVacation({ employee }) {
|
export default function ShopEmployeeAddVacation({ employee, buttonProps }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [insertVacation] = useMutation(INSERT_VACATION);
|
const [insertVacation] = useMutation(INSERT_VACATION);
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ export default function ShopEmployeeAddVacation({ employee }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Popover content={overlay} open={visibility}>
|
<Popover content={overlay} open={visibility}>
|
||||||
<Button loading={loading} disabled={!employee?.active} onClick={handleClick}>
|
<Button loading={loading} disabled={!employee?.active} onClick={handleClick} {...buttonProps}>
|
||||||
{t("employees.actions.addvacation")}
|
{t("employees.actions.addvacation")}
|
||||||
</Button>
|
</Button>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { DeleteFilled } from "@ant-design/icons";
|
import { DeleteFilled } from "@ant-design/icons";
|
||||||
import { useApolloClient, useMutation, useQuery } from "@apollo/client/react";
|
import { useApolloClient, useMutation, useQuery } from "@apollo/client/react";
|
||||||
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
|
import { useTreatmentsWithConfig } from "@splitsoftware/splitio-react";
|
||||||
import { Button, Card, Form, Input, InputNumber, Select, Space, Switch } from "antd";
|
import { Button, Card, Col, Form, Input, InputNumber, Row, Select, Space, Switch } from "antd";
|
||||||
import ResponsiveTable from "../responsive-table/responsive-table.component";
|
import ResponsiveTable from "../responsive-table/responsive-table.component";
|
||||||
import { useForm } from "antd/es/form/Form";
|
import { useForm } from "antd/es/form/Form";
|
||||||
import queryString from "query-string";
|
import queryString from "query-string";
|
||||||
@@ -30,6 +30,7 @@ import FormListMoveArrows from "../form-list-move-arrows/form-list-move-arrows.c
|
|||||||
import { getFormListItemTitle } from "../form-list-move-arrows/form-list-item-title.utils";
|
import { getFormListItemTitle } from "../form-list-move-arrows/form-list-item-title.utils";
|
||||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||||
import ShopEmployeeAddVacation from "./shop-employees-add-vacation.component";
|
import ShopEmployeeAddVacation from "./shop-employees-add-vacation.component";
|
||||||
|
import FormItemEmail from "../form-items-formatted/email-form-item.component.jsx";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
bodyshop: selectBodyshop
|
bodyshop: selectBodyshop
|
||||||
@@ -42,6 +43,14 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [form] = useForm();
|
const [form] = useForm();
|
||||||
const employeeRates = Form.useWatch(["rates"], form) || [];
|
const employeeRates = Form.useWatch(["rates"], form) || [];
|
||||||
|
const employeeOptionsColProps = {
|
||||||
|
xs: 24,
|
||||||
|
sm: 12,
|
||||||
|
md: 8,
|
||||||
|
lg: { flex: "0 0 320px" },
|
||||||
|
xl: { flex: "0 0 280px" },
|
||||||
|
xxl: { flex: "0 0 380px" }
|
||||||
|
};
|
||||||
const history = useNavigate();
|
const history = useNavigate();
|
||||||
const search = queryString.parse(useLocation().search);
|
const search = queryString.parse(useLocation().search);
|
||||||
const [deleteVacation] = useMutation(DELETE_VACATION);
|
const [deleteVacation] = useMutation(DELETE_VACATION);
|
||||||
@@ -177,7 +186,10 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Form onFinish={handleFinish} autoComplete={"off"} layout="vertical" form={form}>
|
<Form onFinish={handleFinish} autoComplete={"off"} layout="vertical" form={form}>
|
||||||
<LayoutFormRow>
|
<LayoutFormRow title={t("bodyshop.labels.employee_options")}>
|
||||||
|
<div style={{ display: "grid", rowGap: 16 }}>
|
||||||
|
<Row gutter={[16, 16]} wrap>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="first_name"
|
name="first_name"
|
||||||
label={t("employees.fields.first_name")}
|
label={t("employees.fields.first_name")}
|
||||||
@@ -190,6 +202,8 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("employees.fields.last_name")}
|
label={t("employees.fields.last_name")}
|
||||||
name="last_name"
|
name="last_name"
|
||||||
@@ -202,6 +216,8 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="employee_number"
|
name="employee_number"
|
||||||
label={t("employees.fields.employee_number")}
|
label={t("employees.fields.employee_number")}
|
||||||
@@ -240,6 +256,8 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("employees.fields.pin")}
|
label={t("employees.fields.pin")}
|
||||||
name="pin"
|
name="pin"
|
||||||
@@ -252,14 +270,20 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
>
|
>
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</Col>
|
||||||
<LayoutFormRow>
|
</Row>
|
||||||
|
<Row gutter={[16, 16]} wrap>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item label={t("employees.fields.active")} valuePropName="checked" name="active">
|
<Form.Item label={t("employees.fields.active")} valuePropName="checked" name="active">
|
||||||
<Switch />
|
<Switch />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item label={t("employees.fields.flat_rate")} name="flat_rate" valuePropName="checked">
|
<Form.Item label={t("employees.fields.flat_rate")} name="flat_rate" valuePropName="checked">
|
||||||
<Switch />
|
<Switch />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="hire_date"
|
name="hire_date"
|
||||||
label={t("employees.fields.hire_date")}
|
label={t("employees.fields.hire_date")}
|
||||||
@@ -272,9 +296,13 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
>
|
>
|
||||||
<DateTimePicker isDateOnly />
|
<DateTimePicker isDateOnly />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item label={t("employees.fields.termination_date")} name="termination_date">
|
<Form.Item label={t("employees.fields.termination_date")} name="termination_date">
|
||||||
<DateTimePicker isDateOnly />
|
<DateTimePicker isDateOnly />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={t("employees.fields.user_email")}
|
label={t("employees.fields.user_email")}
|
||||||
name="user_email"
|
name="user_email"
|
||||||
@@ -303,12 +331,18 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
})
|
})
|
||||||
]}
|
]}
|
||||||
>
|
>
|
||||||
<Input />
|
<FormItemEmail />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
<Col {...employeeOptionsColProps}>
|
||||||
<Form.Item label={t("employees.fields.external_id")} name="external_id">
|
<Form.Item label={t("employees.fields.external_id")} name="external_id">
|
||||||
<Input />
|
<Input />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow title={t("bodyshop.labels.employee_rates")}>
|
||||||
<Form.List name={["rates"]}>
|
<Form.List name={["rates"]}>
|
||||||
{(fields, { add, remove, move }) => {
|
{(fields, { add, remove, move }) => {
|
||||||
return (
|
return (
|
||||||
@@ -320,7 +354,11 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
<Form.Item key={field.key} style={{ padding: 0, margin: 2 }}>
|
<Form.Item key={field.key} style={{ padding: 0, margin: 2 }}>
|
||||||
<LayoutFormRow
|
<LayoutFormRow
|
||||||
grow
|
grow
|
||||||
title={getFormListItemTitle(t("employees.fields.cost_center"), index, employeeRate.cost_center)}
|
title={getFormListItemTitle(
|
||||||
|
t("employees.fields.cost_center"),
|
||||||
|
index,
|
||||||
|
employeeRate.cost_center
|
||||||
|
)}
|
||||||
extra={
|
extra={
|
||||||
<Space align="center" size="small">
|
<Space align="center" size="small">
|
||||||
<Button
|
<Button
|
||||||
@@ -399,15 +437,29 @@ export function ShopEmployeesFormComponent({ bodyshop }) {
|
|||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.List>
|
</Form.List>
|
||||||
|
</LayoutFormRow>
|
||||||
</Form>
|
</Form>
|
||||||
|
|
||||||
|
<LayoutFormRow title={t("bodyshop.labels.employee_vacation")}>
|
||||||
|
<div>
|
||||||
<ResponsiveTable
|
<ResponsiveTable
|
||||||
title={() => <ShopEmployeeAddVacation employee={data && data.employees_by_pk} />}
|
|
||||||
columns={columns}
|
columns={columns}
|
||||||
mobileColumnKeys={["start", "length", "actions"]}
|
mobileColumnKeys={["start", "length", "actions"]}
|
||||||
rowKey={"id"}
|
rowKey={"id"}
|
||||||
dataSource={data?.employees_by_pk?.employee_vacations ?? []}
|
dataSource={data?.employees_by_pk?.employee_vacations ?? []}
|
||||||
|
pagination={false}
|
||||||
/>
|
/>
|
||||||
|
<div style={{ marginTop: 12 }}>
|
||||||
|
<ShopEmployeeAddVacation
|
||||||
|
employee={data && data.employees_by_pk}
|
||||||
|
buttonProps={{
|
||||||
|
type: "dashed",
|
||||||
|
block: true
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</LayoutFormRow>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export default function ShopEmployeesListComponent({ loading, employees }) {
|
|||||||
};
|
};
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: t("employees.fields.employee_number"),
|
title: t("employees.labels.employee_number_short"),
|
||||||
dataIndex: "employee_number",
|
dataIndex: "employee_number",
|
||||||
key: "employee_number",
|
key: "employee_number",
|
||||||
sorter: (a, b) => alphaSort(a.employee_number, b.employee_number),
|
sorter: (a, b) => alphaSort(a.employee_number, b.employee_number),
|
||||||
|
|||||||
@@ -1,29 +1,47 @@
|
|||||||
import { useQuery } from "@apollo/client/react";
|
import { useQuery } from "@apollo/client/react";
|
||||||
|
import queryString from "query-string";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { QUERY_EMPLOYEES } from "../../graphql/employees.queries";
|
import { QUERY_EMPLOYEES } from "../../graphql/employees.queries";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import ShopEmployeesFormComponent from "./shop-employees-form.component";
|
import ShopEmployeesFormComponent from "./shop-employees-form.component";
|
||||||
import ShopEmployeesListComponent from "./shop-employees-list.component";
|
import ShopEmployeesListComponent from "./shop-employees-list.component";
|
||||||
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||||
|
import "./shop-employees.styles.scss";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({});
|
const mapStateToProps = createStructuredSelector({});
|
||||||
|
|
||||||
function ShopEmployeesContainer() {
|
function ShopEmployeesContainer() {
|
||||||
|
const search = queryString.parse(useLocation().search);
|
||||||
const { loading, error, data } = useQuery(QUERY_EMPLOYEES, {
|
const { loading, error, data } = useQuery(QUERY_EMPLOYEES, {
|
||||||
fetchPolicy: "network-only",
|
fetchPolicy: "network-only",
|
||||||
nextFetchPolicy: "network-only"
|
nextFetchPolicy: "network-only"
|
||||||
});
|
});
|
||||||
|
const hasSelectedEmployee = Boolean(search.employeeId);
|
||||||
|
|
||||||
if (error) return <AlertComponent title={error.message} type="error" />;
|
if (error) return <AlertComponent title={error.message} type="error" />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
|
||||||
<RbacWrapper action="employees:page">
|
<RbacWrapper action="employees:page">
|
||||||
|
<div
|
||||||
|
className={[
|
||||||
|
"shop-employees-layout",
|
||||||
|
hasSelectedEmployee ? "shop-employees-layout--with-detail" : null
|
||||||
|
]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(" ")}
|
||||||
|
>
|
||||||
|
<div className="shop-employees-layout__list">
|
||||||
<ShopEmployeesListComponent employees={data ? data.employees : []} loading={loading} />
|
<ShopEmployeesListComponent employees={data ? data.employees : []} loading={loading} />
|
||||||
<ShopEmployeesFormComponent />
|
|
||||||
</RbacWrapper>
|
|
||||||
</div>
|
</div>
|
||||||
|
{hasSelectedEmployee ? (
|
||||||
|
<div className="shop-employees-layout__details">
|
||||||
|
<ShopEmployeesFormComponent />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</RbacWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
.shop-employees-layout {
|
||||||
|
display: grid;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-employees-layout__list,
|
||||||
|
.shop-employees-layout__details {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1700px) {
|
||||||
|
.shop-employees-layout--with-detail {
|
||||||
|
grid-template-columns: minmax(420px, 500px) minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Card, Typography } from "antd";
|
import { Card } from "antd";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
@@ -15,9 +15,8 @@ function ShopInfoConsentComponent({ bodyshop }) {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card title={t("settings.title")}>
|
||||||
<Typography.Title level={4}>{t("settings.title")}</Typography.Title>
|
<PhoneNumberConsentList bodyshop={bodyshop} />
|
||||||
{<PhoneNumberConsentList bodyshop={bodyshop} />}
|
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,9 +132,22 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
|
|||||||
const teamName = Form.useWatch("name", form);
|
const teamName = Form.useWatch("name", form);
|
||||||
const teamMembers = Form.useWatch(["employee_team_members"], form) || [];
|
const teamMembers = Form.useWatch(["employee_team_members"], form) || [];
|
||||||
const isTeamHydrating = !isNewTeam && Boolean(search.employeeTeamId) && hydratedTeamId !== search.employeeTeamId;
|
const isTeamHydrating = !isNewTeam && Boolean(search.employeeTeamId) && hydratedTeamId !== search.employeeTeamId;
|
||||||
|
const isAllocationTotalExact = hasExactSplitTotal(teamMembers);
|
||||||
|
const allocationTotalValue = formatAllocationPercentage(getSplitTotal(teamMembers))?.replace("%", "") || "0";
|
||||||
|
const teamNameDisplay = teamName?.trim() || t("employee_teams.fields.name");
|
||||||
const teamCardTitle = isTeamHydrating
|
const teamCardTitle = isTeamHydrating
|
||||||
? t("employee_teams.fields.name")
|
? t("employee_teams.fields.name")
|
||||||
: teamName?.trim() || t("employee_teams.fields.name");
|
: (
|
||||||
|
<span>
|
||||||
|
<span>{teamNameDisplay}</span>
|
||||||
|
<span> - </span>
|
||||||
|
<Typography.Text type={isAllocationTotalExact ? undefined : "danger"}>
|
||||||
|
{t("employee_teams.labels.allocation_total", {
|
||||||
|
total: allocationTotalValue
|
||||||
|
})}
|
||||||
|
</Typography.Text>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
|
||||||
const getTeamMemberTitle = (teamMember = {}) => {
|
const getTeamMemberTitle = (teamMember = {}) => {
|
||||||
const employeeName =
|
const employeeName =
|
||||||
@@ -241,7 +254,7 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
|
|||||||
<Skeleton active title={false} paragraph={{ rows: 12 }} />
|
<Skeleton active title={false} paragraph={{ rows: 12 }} />
|
||||||
) : (
|
) : (
|
||||||
<Form onFinish={handleFinish} autoComplete={"off"} layout="vertical" form={form}>
|
<Form onFinish={handleFinish} autoComplete={"off"} layout="vertical" form={form}>
|
||||||
<LayoutFormRow>
|
<LayoutFormRow title={t("employee_teams.labels.team_options")}>
|
||||||
<Form.Item
|
<Form.Item
|
||||||
name="name"
|
name="name"
|
||||||
label={t("employee_teams.fields.name")}
|
label={t("employee_teams.fields.name")}
|
||||||
@@ -268,6 +281,7 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
|
|||||||
<InputNumber min={0} precision={1} />
|
<InputNumber min={0} precision={1} />
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
</LayoutFormRow>
|
</LayoutFormRow>
|
||||||
|
<LayoutFormRow title={t("employee_teams.labels.members")}>
|
||||||
<Form.List name={["employee_team_members"]}>
|
<Form.List name={["employee_team_members"]}>
|
||||||
{(fields, { add, remove, move }) => {
|
{(fields, { add, remove, move }) => {
|
||||||
return (
|
return (
|
||||||
@@ -400,24 +414,11 @@ export function ShopEmployeeTeamsFormComponent({ bodyshop }) {
|
|||||||
{t("employee_teams.actions.newmember")}
|
{t("employee_teams.actions.newmember")}
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item noStyle shouldUpdate>
|
|
||||||
{() => {
|
|
||||||
const teamMembers = form.getFieldValue(["employee_team_members"]) || [];
|
|
||||||
const splitTotal = getSplitTotal(teamMembers);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Typography.Text type={hasExactSplitTotal(teamMembers) ? undefined : "danger"}>
|
|
||||||
{t("employee_teams.labels.allocation_total", {
|
|
||||||
total: splitTotal.toFixed(2)
|
|
||||||
})}
|
|
||||||
</Typography.Text>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Form.Item>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
</Form.List>
|
</Form.List>
|
||||||
|
</LayoutFormRow>
|
||||||
</Form>
|
</Form>
|
||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -1,36 +1,44 @@
|
|||||||
import { useQuery } from "@apollo/client/react";
|
import { useQuery } from "@apollo/client/react";
|
||||||
|
import queryString from "query-string";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
import { useLocation } from "react-router-dom";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import { QUERY_TEAMS } from "../../graphql/employee_teams.queries";
|
import { QUERY_TEAMS } from "../../graphql/employee_teams.queries";
|
||||||
import AlertComponent from "../alert/alert.component";
|
import AlertComponent from "../alert/alert.component";
|
||||||
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
import RbacWrapper from "../rbac-wrapper/rbac-wrapper.component";
|
||||||
import ShopEmployeeTeamsListComponent from "./shop-employee-teams.list";
|
import ShopEmployeeTeamsListComponent from "./shop-employee-teams.list";
|
||||||
import ShopEmployeeTeamsFormComponent from "./shop-employee-teams.form.component";
|
import ShopEmployeeTeamsFormComponent from "./shop-employee-teams.form.component";
|
||||||
import { Col, Row } from "antd";
|
import "./shop-teams.styles.scss";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({});
|
const mapStateToProps = createStructuredSelector({});
|
||||||
|
|
||||||
function ShopTeamsContainer() {
|
function ShopTeamsContainer() {
|
||||||
|
const search = queryString.parse(useLocation().search);
|
||||||
const { loading, error, data } = useQuery(QUERY_TEAMS, {
|
const { loading, error, data } = useQuery(QUERY_TEAMS, {
|
||||||
fetchPolicy: "network-only",
|
fetchPolicy: "network-only",
|
||||||
nextFetchPolicy: "network-only"
|
nextFetchPolicy: "network-only"
|
||||||
});
|
});
|
||||||
|
const hasSelectedTeam = Boolean(search.employeeTeamId);
|
||||||
|
|
||||||
if (error) return <AlertComponent title={error.message} type="error" />;
|
if (error) return <AlertComponent title={error.message} type="error" />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
|
||||||
<RbacWrapper action="employee_teams:page">
|
<RbacWrapper action="employee_teams:page">
|
||||||
<Row gutter={[16, 16]}>
|
<div
|
||||||
<Col span={6}>
|
className={["shop-teams-layout", hasSelectedTeam ? "shop-teams-layout--with-detail" : null]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(" ")}
|
||||||
|
>
|
||||||
|
<div className="shop-teams-layout__list">
|
||||||
<ShopEmployeeTeamsListComponent employee_teams={data ? data.employee_teams : []} loading={loading} />
|
<ShopEmployeeTeamsListComponent employee_teams={data ? data.employee_teams : []} loading={loading} />
|
||||||
</Col>
|
|
||||||
<Col span={18}>
|
|
||||||
<ShopEmployeeTeamsFormComponent />
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</RbacWrapper>
|
|
||||||
</div>
|
</div>
|
||||||
|
{hasSelectedTeam ? (
|
||||||
|
<div className="shop-teams-layout__details">
|
||||||
|
<ShopEmployeeTeamsFormComponent />
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
</RbacWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
client/src/components/shop-teams/shop-teams.styles.scss
Normal file
16
client/src/components/shop-teams/shop-teams.styles.scss
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
.shop-teams-layout {
|
||||||
|
display: grid;
|
||||||
|
gap: 16px;
|
||||||
|
align-items: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shop-teams-layout__list,
|
||||||
|
.shop-teams-layout__details {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 1700px) {
|
||||||
|
.shop-teams-layout--with-detail {
|
||||||
|
grid-template-columns: minmax(420px, 500px) minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -736,6 +736,9 @@
|
|||||||
},
|
},
|
||||||
"emaillater": "Email Later",
|
"emaillater": "Email Later",
|
||||||
"employee_teams": "Employee Teams",
|
"employee_teams": "Employee Teams",
|
||||||
|
"employee_options": "Employee Options",
|
||||||
|
"employee_rates": "Employee Rates",
|
||||||
|
"employee_vacation": "Employee Vacation",
|
||||||
"employees": "Employees",
|
"employees": "Employees",
|
||||||
"estimators": "Estimators",
|
"estimators": "Estimators",
|
||||||
"filehandlers": "Adjusters",
|
"filehandlers": "Adjusters",
|
||||||
@@ -1202,7 +1205,9 @@
|
|||||||
"percentage": "Percent"
|
"percentage": "Percent"
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"allocation_total": "Allocation Total: {{total}}%"
|
"allocation_total": "Allocation Total: {{total}}%",
|
||||||
|
"members": "Members",
|
||||||
|
"team_options": "Team Options"
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"commission": "Commission",
|
"commission": "Commission",
|
||||||
@@ -1246,6 +1251,7 @@
|
|||||||
"labels": {
|
"labels": {
|
||||||
"actions": "Actions",
|
"actions": "Actions",
|
||||||
"active": "Active",
|
"active": "Active",
|
||||||
|
"employee_number_short": "Employee #",
|
||||||
"endmustbeafterstart": "End date must be after start date.",
|
"endmustbeafterstart": "End date must be after start date.",
|
||||||
"flat_rate": "Flat Rate",
|
"flat_rate": "Flat Rate",
|
||||||
"inactive": "Inactive",
|
"inactive": "Inactive",
|
||||||
|
|||||||
@@ -736,6 +736,9 @@
|
|||||||
},
|
},
|
||||||
"emaillater": "",
|
"emaillater": "",
|
||||||
"employee_teams": "",
|
"employee_teams": "",
|
||||||
|
"employee_options": "",
|
||||||
|
"employee_rates": "",
|
||||||
|
"employee_vacation": "",
|
||||||
"employees": "",
|
"employees": "",
|
||||||
"estimators": "",
|
"estimators": "",
|
||||||
"filehandlers": "",
|
"filehandlers": "",
|
||||||
@@ -1202,7 +1205,9 @@
|
|||||||
"percentage": ""
|
"percentage": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"allocation_total": ""
|
"allocation_total": "",
|
||||||
|
"members": "",
|
||||||
|
"team_options": ""
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"commission": "",
|
"commission": "",
|
||||||
@@ -1246,6 +1251,7 @@
|
|||||||
"labels": {
|
"labels": {
|
||||||
"actions": "",
|
"actions": "",
|
||||||
"active": "",
|
"active": "",
|
||||||
|
"employee_number_short": "",
|
||||||
"endmustbeafterstart": "",
|
"endmustbeafterstart": "",
|
||||||
"flat_rate": "",
|
"flat_rate": "",
|
||||||
"inactive": "",
|
"inactive": "",
|
||||||
|
|||||||
@@ -736,6 +736,9 @@
|
|||||||
},
|
},
|
||||||
"emaillater": "",
|
"emaillater": "",
|
||||||
"employee_teams": "",
|
"employee_teams": "",
|
||||||
|
"employee_options": "",
|
||||||
|
"employee_rates": "",
|
||||||
|
"employee_vacation": "",
|
||||||
"employees": "",
|
"employees": "",
|
||||||
"estimators": "",
|
"estimators": "",
|
||||||
"filehandlers": "",
|
"filehandlers": "",
|
||||||
@@ -1202,7 +1205,9 @@
|
|||||||
"percentage": ""
|
"percentage": ""
|
||||||
},
|
},
|
||||||
"labels": {
|
"labels": {
|
||||||
"allocation_total": ""
|
"allocation_total": "",
|
||||||
|
"members": "",
|
||||||
|
"team_options": ""
|
||||||
},
|
},
|
||||||
"options": {
|
"options": {
|
||||||
"commission": "",
|
"commission": "",
|
||||||
@@ -1246,6 +1251,7 @@
|
|||||||
"labels": {
|
"labels": {
|
||||||
"actions": "",
|
"actions": "",
|
||||||
"active": "",
|
"active": "",
|
||||||
|
"employee_number_short": "",
|
||||||
"endmustbeafterstart": "",
|
"endmustbeafterstart": "",
|
||||||
"flat_rate": "",
|
"flat_rate": "",
|
||||||
"inactive": "",
|
"inactive": "",
|
||||||
|
|||||||
Reference in New Issue
Block a user