Fixed vendor issues + new logos

This commit is contained in:
Patrick Fic
2020-10-05 17:13:04 -07:00
parent f188e9512b
commit 27c1dc2c47
18 changed files with 166 additions and 84 deletions

View File

@@ -24450,6 +24450,27 @@
</translation> </translation>
</translations> </translations>
</concept_node> </concept_node>
<concept_node>
<name>shop-vendors</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> <concept_node>
<name>timetickets</name> <name>timetickets</name>
<definition_loaded>false</definition_loaded> <definition_loaded>false</definition_loaded>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

BIN
client/public/vorfahrt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -69,6 +69,7 @@ function Header({
<Menu <Menu
mode="horizontal" mode="horizontal"
theme="light" theme="light"
style={{ backgroundColor: "#eee" }}
className="header-main-menu" className="header-main-menu"
selectedKeys={[selectedHeader]} selectedKeys={[selectedHeader]}
onClick={handleMenuClick} onClick={handleMenuClick}

View File

@@ -1,12 +1,14 @@
import { DeleteFilled } from "@ant-design/icons"; import { DeleteFilled } from "@ant-design/icons";
import { Button, Form, Input, InputNumber, Select } from "antd"; import { Button, Form, Input, InputNumber, Select, Space } from "antd";
import React from "react"; import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import InputNumberCalculator from "../form-input-number-calculator/form-input-number-calculator.component"; import InputNumberCalculator from "../form-input-number-calculator/form-input-number-calculator.component";
import FormItemEmail from "../form-items-formatted/email-form-item.component"; import FormItemEmail from "../form-items-formatted/email-form-item.component";
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
export default function VendorsFormComponent({ export default function VendorsFormComponent({
form, form,
formLoading,
handleDelete, handleDelete,
responsibilityCenters, responsibilityCenters,
}) { }) {
@@ -14,12 +16,91 @@ export default function VendorsFormComponent({
const { getFieldValue } = form; const { getFieldValue } = form;
return ( return (
<div> <div>
<Button htmlType="submit" type="primary"> <Space>
{t("general.actions.save")} <Button
</Button> onClick={() => form.submit()}
<Button type="danger" onClick={handleDelete}> type="primary"
{t("general.actions.delete")} loading={formLoading}
</Button> >
{t("general.actions.save")}
</Button>
<Button type="danger" onClick={handleDelete} loading={formLoading}>
{t("general.actions.delete")}
</Button>
</Space>
<LayoutFormRow grow>
<Form.Item label={t("vendors.fields.name")} name="name">
<Input />
</Form.Item>
<Form.Item
label={t("vendors.fields.email")}
rules={[
{
type: "email",
message: t("general.validation.invalidemail"),
},
]}
name="email"
>
<FormItemEmail email={getFieldValue("email")} />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow grow>
<Form.Item label={t("vendors.fields.street1")} name="street1">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.street2")} name="street2">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.city")} name="city">
<Input />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow grow>
{" "}
<Form.Item label={t("vendors.fields.state")} name="state">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.zip")} name="zip">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.country")} name="country">
<Input />
</Form.Item>
</LayoutFormRow>
<LayoutFormRow>
<Form.Item label={t("vendors.fields.discount")} name="discount">
<InputNumberCalculator />
</Form.Item>
<Form.Item label={t("vendors.fields.terms")} name="terms">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.due_date")} name="due_date">
<InputNumber />
</Form.Item>
<Form.Item label={t("vendors.fields.taxid")} name="taxid">
<Input />
</Form.Item>
<Form.Item
label={t("vendors.fields.prompt_discount")}
name="prompt_discount"
>
<InputNumberCalculator />
</Form.Item>
<Form.Item
label={t("vendors.fields.cost_center")}
rules={[
{ required: true, message: t("general.validation.required") },
]}
name="cost_center"
>
<Select style={{ width: "150px" }}>
{responsibilityCenters.costs.map((item) => (
<Select.Option key={item.name}>{item.name}</Select.Option>
))}
</Select>
</Form.Item>
</LayoutFormRow>
<Form.List name="favorite"> <Form.List name="favorite">
{(fields, { add, remove }) => { {(fields, { add, remove }) => {
@@ -65,72 +146,6 @@ export default function VendorsFormComponent({
); );
}} }}
</Form.List> </Form.List>
<Form.Item label={t("vendors.fields.zip")} name="zip">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.terms")} name="terms">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.taxid")} name="taxid">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.street1")} name="street1">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.street2")} name="street2">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.state")} name="state">
<Input />
</Form.Item>
<Form.Item
label={t("vendors.fields.prompt_discount")}
name="prompt_discount"
>
<InputNumberCalculator />
</Form.Item>
<Form.Item label={t("vendors.fields.name")} name="name">
<Input />
</Form.Item>
<Form.Item
label={t("vendors.fields.email")}
rules={[
{
type: "email",
message: t("general.validation.invalidemail"),
},
]}
name="email"
>
<FormItemEmail email={getFieldValue("email")} />
</Form.Item>
<Form.Item label={t("vendors.fields.due_date")} name="due_date">
<InputNumber />
</Form.Item>
<Form.Item label={t("vendors.fields.display_name")} name="display_name">
<Input />
</Form.Item>
<Form.Item label={t("vendors.fields.discount")} name="discount">
<InputNumberCalculator />
</Form.Item>
<Form.Item label={t("vendors.fields.country")} name="country">
<Input />
</Form.Item>
<Form.Item
label={t("vendors.fields.cost_center")}
rules={[{ required: true, message: t("general.validation.required") }]}
name="cost_center"
>
<Select style={{ width: "150px" }}>
{responsibilityCenters.costs.map((item) => (
<Select.Option key={item.name}>{item.name}</Select.Option>
))}
</Select>
</Form.Item>
<Form.Item label={t("vendors.fields.city")} name="city">
<Input />
</Form.Item>
</div> </div>
); );
} }

View File

@@ -1,12 +1,17 @@
import { useMutation, useQuery } from "@apollo/react-hooks"; import { useMutation, useQuery } from "@apollo/react-hooks";
import { Form, notification } from "antd"; import { Form, notification } from "antd";
import queryString from "query-string"; import queryString from "query-string";
import React, { useEffect } from "react"; import React, { useEffect, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { createStructuredSelector } from "reselect"; import { createStructuredSelector } from "reselect";
import { DELETE_VENDOR, INSERT_NEW_VENDOR, QUERY_VENDOR_BY_ID, UPDATE_VENDOR } from "../../graphql/vendors.queries"; import {
DELETE_VENDOR,
INSERT_NEW_VENDOR,
QUERY_VENDOR_BY_ID,
UPDATE_VENDOR,
} from "../../graphql/vendors.queries";
import { selectBodyshop } from "../../redux/user/user.selectors"; import { selectBodyshop } from "../../redux/user/user.selectors";
import AlertComponent from "../alert/alert.component"; import AlertComponent from "../alert/alert.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component"; import LoadingSpinner from "../loading-spinner/loading-spinner.component";
@@ -19,7 +24,7 @@ const mapStateToProps = createStructuredSelector({
function VendorsFormContainer({ refetch, bodyshop }) { function VendorsFormContainer({ refetch, bodyshop }) {
const search = queryString.parse(useLocation().search); const search = queryString.parse(useLocation().search);
const { selectedvendor } = search; const { selectedvendor } = search;
const [formLoading, setFormLoading] = useState(false);
const [form] = Form.useForm(); const [form] = Form.useForm();
const { t } = useTranslation(); const { t } = useTranslation();
const { loading, error, data } = useQuery(QUERY_VENDOR_BY_ID, { const { loading, error, data } = useQuery(QUERY_VENDOR_BY_ID, {
@@ -32,6 +37,7 @@ function VendorsFormContainer({ refetch, bodyshop }) {
const [insertvendor] = useMutation(INSERT_NEW_VENDOR); const [insertvendor] = useMutation(INSERT_NEW_VENDOR);
const [deleteVendor] = useMutation(DELETE_VENDOR); const [deleteVendor] = useMutation(DELETE_VENDOR);
const handleDelete = () => { const handleDelete = () => {
setFormLoading(true);
deleteVendor({ variables: { id: selectedvendor } }) deleteVendor({ variables: { id: selectedvendor } })
.then((r) => { .then((r) => {
notification["success"]({ notification["success"]({
@@ -45,9 +51,11 @@ function VendorsFormContainer({ refetch, bodyshop }) {
message: t("vendors.errors.deleting"), message: t("vendors.errors.deleting"),
}); });
}); });
setFormLoading(false);
}; };
const handleFinish = (values) => { const handleFinish = (values) => {
setFormLoading(true);
if (selectedvendor && selectedvendor !== "new") { if (selectedvendor && selectedvendor !== "new") {
//It's a vendor to update. //It's a vendor to update.
updateVendor({ updateVendor({
@@ -85,6 +93,7 @@ function VendorsFormContainer({ refetch, bodyshop }) {
}); });
}); });
} }
setFormLoading(false);
}; };
useEffect(() => { useEffect(() => {
@@ -92,16 +101,19 @@ function VendorsFormContainer({ refetch, bodyshop }) {
}, [data, form, selectedvendor]); }, [data, form, selectedvendor]);
if (loading) return <LoadingSpinner />; if (loading) return <LoadingSpinner />;
if (error) return <AlertComponent message={error.message} type='error' />; if (error) return <AlertComponent message={error.message} type="error" />;
return ( return (
<Form <Form
onFinish={handleFinish} onFinish={handleFinish}
form={form} form={form}
autoComplete='new-password' layout="vertical"
initialValues={data ? data.vendors_by_pk : null}> autoComplete="new-password"
initialValues={data ? data.vendors_by_pk : null}
>
{selectedvendor ? ( {selectedvendor ? (
<VendorsFormComponent <VendorsFormComponent
form={form} form={form}
formLoading={formLoading}
handleDelete={handleDelete} handleDelete={handleDelete}
responsibilityCenters={bodyshop.md_responsibility_centers || null} responsibilityCenters={bodyshop.md_responsibility_centers || null}
/> />

View File

@@ -14,7 +14,6 @@ export const QUERY_VENDOR_BY_ID = gql`
favorite favorite
email email
due_date due_date
display_name
discount discount
country country
cost_center cost_center

View File

@@ -158,7 +158,7 @@ export function Manage({ match, conflict }) {
return ( return (
<Layout className="layout-container"> <Layout className="layout-container">
<Header style={{ background: "#fff" }}> <Header style={{ background: "azure" }}>
<HeaderContainer /> <HeaderContainer />
</Header> </Header>
<Content className="content-container"> <Content className="content-container">

View File

@@ -1,12 +1,28 @@
import { Col, Row } from "antd";
import React from "react"; import React from "react";
import VendorsListContainer from "../../components/vendors-list/vendors-list.container";
import VendorsFormContainer from "../../components/vendors-form/vendors-form.container"; import VendorsFormContainer from "../../components/vendors-form/vendors-form.container";
import VendorsListContainer from "../../components/vendors-list/vendors-list.container";
const listSpan = {
md: { span: 24 },
lg: { span: 8 },
};
const formSapn = {
md: { span: 24 },
lg: { span: 16 },
};
export default function ShopVendorPageComponent() { export default function ShopVendorPageComponent() {
return ( return (
<div> <div>
<VendorsListContainer /> <Row gutter={[16, 16]}>
<VendorsFormContainer /> <Col {...listSpan}>
<VendorsListContainer />
</Col>
<Col {...formSapn}>
<VendorsFormContainer />
</Col>
</Row>
</div> </div>
); );
} }

View File

@@ -1514,6 +1514,7 @@
"shop": "Manage my Shop ({{shopname}})", "shop": "Manage my Shop ({{shopname}})",
"shop-csi": "CSI Responses", "shop-csi": "CSI Responses",
"shop-templates": "Shop Templates", "shop-templates": "Shop Templates",
"shop-vendors": "Vendors",
"timetickets": "Time Tickets", "timetickets": "Time Tickets",
"vehicle-details": "Vehicle: {{vehicle}}", "vehicle-details": "Vehicle: {{vehicle}}",
"vehicles": "Vehicles" "vehicles": "Vehicles"

View File

@@ -1514,6 +1514,7 @@
"shop": "", "shop": "",
"shop-csi": "", "shop-csi": "",
"shop-templates": "", "shop-templates": "",
"shop-vendors": "",
"timetickets": "", "timetickets": "",
"vehicle-details": "", "vehicle-details": "",
"vehicles": "" "vehicles": ""

View File

@@ -1514,6 +1514,7 @@
"shop": "", "shop": "",
"shop-csi": "", "shop-csi": "",
"shop-templates": "", "shop-templates": "",
"shop-vendors": "",
"timetickets": "", "timetickets": "",
"vehicle-details": "", "vehicle-details": "",
"vehicles": "" "vehicles": ""

View File

@@ -0,0 +1,10 @@
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."vendors" ADD COLUMN "display_name" text;
type: run_sql
- args:
cascade: false
read_only: false
sql: ALTER TABLE "public"."vendors" ALTER COLUMN "display_name" DROP NOT NULL;
type: run_sql

View File

@@ -0,0 +1,5 @@
- args:
cascade: true
read_only: false
sql: ALTER TABLE "public"."vendors" DROP COLUMN "display_name" CASCADE;
type: run_sql