Finish the majority of work on vendors page to add/delete/edit.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<babeledit_project version="1.2" be_version="2.6.1">
|
<babeledit_project be_version="2.6.1" version="1.2">
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
BabelEdit project file
|
BabelEdit project file
|
||||||
@@ -1487,6 +1487,27 @@
|
|||||||
<folder_node>
|
<folder_node>
|
||||||
<name>validation</name>
|
<name>validation</name>
|
||||||
<children>
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>invalidemail</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>required</name>
|
<name>required</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -6819,6 +6840,58 @@
|
|||||||
<folder_node>
|
<folder_node>
|
||||||
<name>vendors</name>
|
<name>vendors</name>
|
||||||
<children>
|
<children>
|
||||||
|
<folder_node>
|
||||||
|
<name>actions</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>new</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>
|
||||||
|
</folder_node>
|
||||||
|
<folder_node>
|
||||||
|
<name>errors</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>saving</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>
|
||||||
|
</folder_node>
|
||||||
<folder_node>
|
<folder_node>
|
||||||
<name>fields</name>
|
<name>fields</name>
|
||||||
<children>
|
<children>
|
||||||
@@ -6864,6 +6937,111 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>country</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>discount</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>display_name</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>due_date</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>email</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>favorite</name>
|
<name>favorite</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -6906,6 +7084,48 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>prompt_discount</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>state</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>street1</name>
|
<name>street1</name>
|
||||||
<definition_loaded>false</definition_loaded>
|
<definition_loaded>false</definition_loaded>
|
||||||
@@ -6927,6 +7147,163 @@
|
|||||||
</translation>
|
</translation>
|
||||||
</translations>
|
</translations>
|
||||||
</concept_node>
|
</concept_node>
|
||||||
|
<concept_node>
|
||||||
|
<name>street2</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>taxid</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>terms</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>zip</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>
|
||||||
|
</folder_node>
|
||||||
|
<folder_node>
|
||||||
|
<name>labels</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>noneselected</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>
|
||||||
|
</folder_node>
|
||||||
|
<folder_node>
|
||||||
|
<name>successes</name>
|
||||||
|
<children>
|
||||||
|
<concept_node>
|
||||||
|
<name>deleted</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>saved</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>
|
||||||
</children>
|
</children>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
import { Button, Form, Input, notification } from "antd";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
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";
|
||||||
import { selectCurrentUser } from "../../redux/user/user.selectors";
|
|
||||||
import AlertComponent from "../alert/alert.component";
|
|
||||||
import { Form, Input, notification, Button } from "antd";
|
|
||||||
import { updateUserDetails } from "../../redux/user/user.actions";
|
import { updateUserDetails } from "../../redux/user/user.actions";
|
||||||
|
import { selectCurrentUser } from "../../redux/user/user.selectors";
|
||||||
|
import ResetForm from "../form-items-formatted/reset-form-item.component";
|
||||||
|
|
||||||
const mapStateToProps = createStructuredSelector({
|
const mapStateToProps = createStructuredSelector({
|
||||||
currentUser: selectCurrentUser
|
currentUser: selectCurrentUser
|
||||||
@@ -47,33 +47,26 @@ export default connect(
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{isFieldsTouched() ? (
|
{isFieldsTouched() ? <ResetForm resetFields={resetFields} /> : null}
|
||||||
//TODO: Appropriate Error
|
|
||||||
<AlertComponent
|
|
||||||
message={t("jobs.errors.validation")}
|
|
||||||
onClick={() => resetFields()}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<Form onSubmit={handleSubmit} autoComplete={"no"}>
|
<Form onSubmit={handleSubmit} autoComplete={"no"}>
|
||||||
<Form.Item label={t("user.fields.displayname")}>
|
<Form.Item label={t("user.fields.displayname")}>
|
||||||
{getFieldDecorator("displayname", {
|
{getFieldDecorator("displayname", {
|
||||||
initialValue: currentUser.displayName,
|
initialValue: currentUser.displayName,
|
||||||
rules: [{ required: true }]
|
rules: [{ required: true }]
|
||||||
})(<Input name="displayname" />)}
|
})(<Input name='displayname' />)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
<Form.Item label={t("user.fields.photourl")}>
|
<Form.Item label={t("user.fields.photourl")}>
|
||||||
{getFieldDecorator("photoURL", {
|
{getFieldDecorator("photoURL", {
|
||||||
initialValue: currentUser.photoURL
|
initialValue: currentUser.photoURL
|
||||||
})(<Input name="photoURL" />)}
|
})(<Input name='photoURL' />)}
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type='primary'
|
||||||
key="submit"
|
key='submit'
|
||||||
htmlType="submit"
|
htmlType='submit'
|
||||||
onClick={handleSubmit}
|
onClick={handleSubmit}>
|
||||||
>
|
|
||||||
{t("user.actions.updateprofile")}
|
{t("user.actions.updateprofile")}
|
||||||
</Button>
|
</Button>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
114
client/src/components/vendors-form/vendors-form.component.jsx
Normal file
114
client/src/components/vendors-form/vendors-form.component.jsx
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
import { Button, Form, Input, InputNumber, Switch } from "antd";
|
||||||
|
import React from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import FormItemEmail from "../form-items-formatted/email-form-item.component";
|
||||||
|
import ResetForm from "../form-items-formatted/reset-form-item.component";
|
||||||
|
export default function VendorsFormComponent({ form, vendor, handleDelete }) {
|
||||||
|
const {
|
||||||
|
getFieldDecorator,
|
||||||
|
isFieldsTouched,
|
||||||
|
getFieldValue,
|
||||||
|
resetFields
|
||||||
|
} = form;
|
||||||
|
|
||||||
|
const { t } = useTranslation();
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
{isFieldsTouched() ? <ResetForm resetFields={resetFields} /> : null}
|
||||||
|
<Button htmlType='submit' type='primary'>
|
||||||
|
{t("general.actions.save")}
|
||||||
|
</Button>
|
||||||
|
<Button type='danger' onClick={handleDelete}>
|
||||||
|
{t("general.actions.delete")}
|
||||||
|
</Button>
|
||||||
|
<Form.Item label={t("vendors.fields.zip")}>
|
||||||
|
{getFieldDecorator("zip", {
|
||||||
|
initialValue: vendor.zip
|
||||||
|
})(<Input name='zip' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.terms")}>
|
||||||
|
{getFieldDecorator("terms", {
|
||||||
|
initialValue: vendor.terms
|
||||||
|
})(<Input name='terms' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.taxid")}>
|
||||||
|
{getFieldDecorator("taxid", {
|
||||||
|
initialValue: vendor.taxid
|
||||||
|
})(<Input name='taxid' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.street1")}>
|
||||||
|
{getFieldDecorator("street1", {
|
||||||
|
initialValue: vendor.street1
|
||||||
|
})(<Input name='street1' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.street2")}>
|
||||||
|
{getFieldDecorator("street2", {
|
||||||
|
initialValue: vendor.street2
|
||||||
|
})(<Input name='street2' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.state")}>
|
||||||
|
{getFieldDecorator("state", {
|
||||||
|
initialValue: vendor.state
|
||||||
|
})(<Input name='state' />)}
|
||||||
|
</Form.Item>{" "}
|
||||||
|
<Form.Item label={t("vendors.fields.prompt_discount")}>
|
||||||
|
{getFieldDecorator("prompt_discount", {
|
||||||
|
initialValue: vendor.prompt_discount
|
||||||
|
})(<InputNumber name='prompt_discount' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.name")}>
|
||||||
|
{getFieldDecorator("name", {
|
||||||
|
initialValue: vendor.name
|
||||||
|
})(<Input name='name' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.favorite")}>
|
||||||
|
{getFieldDecorator("favorite", {
|
||||||
|
initialValue: vendor.favorite,
|
||||||
|
valuePropName: "checked"
|
||||||
|
})(<Switch name='favorite' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.email")}>
|
||||||
|
{getFieldDecorator("email", {
|
||||||
|
initialValue: vendor.email,
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
type: "email",
|
||||||
|
message: t("general.validation.invalidemail")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})(<FormItemEmail name='email' email={getFieldValue("email")} />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.due_date")}>
|
||||||
|
{getFieldDecorator("due_date", {
|
||||||
|
initialValue: vendor.due_date
|
||||||
|
})(<InputNumber name='due_date' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.display_name")}>
|
||||||
|
{getFieldDecorator("display_name", {
|
||||||
|
initialValue: vendor.display_name
|
||||||
|
})(<Input name='display_name' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.discount")}>
|
||||||
|
{getFieldDecorator("discount", {
|
||||||
|
initialValue: vendor.discount
|
||||||
|
})(<InputNumber name='discount' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.country")}>
|
||||||
|
{getFieldDecorator("country", {
|
||||||
|
initialValue: vendor.country
|
||||||
|
})(<Input name='country' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.cost_center")}>
|
||||||
|
{getFieldDecorator("cost_center", {
|
||||||
|
initialValue: vendor.cost_center,
|
||||||
|
rules: [{ required: true, message: t("general.validation.required") }]
|
||||||
|
})(<Input name='cost_center' />)}
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label={t("vendors.fields.city")}>
|
||||||
|
{getFieldDecorator("city", {
|
||||||
|
initialValue: vendor.city
|
||||||
|
})(<Input name='city' />)}
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
109
client/src/components/vendors-form/vendors-form.container.jsx
Normal file
109
client/src/components/vendors-form/vendors-form.container.jsx
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { Form } from "antd";
|
||||||
|
import VendorsFormComponent from "./vendors-form.component";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { notification } from "antd";
|
||||||
|
import {
|
||||||
|
UPDATE_VENDOR,
|
||||||
|
INSERT_NEW_VENDOR,
|
||||||
|
DELETE_VENDOR
|
||||||
|
} from "../../graphql/vendors.queries";
|
||||||
|
import { useMutation } from "react-apollo";
|
||||||
|
|
||||||
|
import { connect } from "react-redux";
|
||||||
|
import { createStructuredSelector } from "reselect";
|
||||||
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||||
|
const mapStateToProps = createStructuredSelector({
|
||||||
|
bodyshop: selectBodyshop
|
||||||
|
});
|
||||||
|
|
||||||
|
function VendorsFormContainer({ form, vendor, refetch, bodyshop }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const [updateVendor] = useMutation(UPDATE_VENDOR);
|
||||||
|
const [insertvendor] = useMutation(INSERT_NEW_VENDOR);
|
||||||
|
const [deleteVendor] = useMutation(DELETE_VENDOR);
|
||||||
|
const handleDelete = () => {
|
||||||
|
deleteVendor({ variables: { id: vendor.id } })
|
||||||
|
.then(r => {
|
||||||
|
notification["success"]({
|
||||||
|
message: t("vendors.successes.deleted")
|
||||||
|
});
|
||||||
|
//TODO: Better way to reset the field decorators?
|
||||||
|
if (refetch) refetch().then(r => form.resetFields());
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("vendors.errors.deleting")
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = e => {
|
||||||
|
e.preventDefault();
|
||||||
|
form.validateFieldsAndScroll((err, values) => {
|
||||||
|
if (err) {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("jobs.errors.validationtitle"),
|
||||||
|
description: t("jobs.errors.validation")
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!err) {
|
||||||
|
if (vendor.id) {
|
||||||
|
//It's a vendor to update.
|
||||||
|
updateVendor({
|
||||||
|
variables: { id: vendor.id, vendor: values }
|
||||||
|
})
|
||||||
|
.then(r => {
|
||||||
|
notification["success"]({
|
||||||
|
message: t("vendors.successes.saved")
|
||||||
|
});
|
||||||
|
//TODO: Better way to reset the field decorators?
|
||||||
|
if (refetch) refetch().then(r => form.resetFields());
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("vendors.errors.saving")
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
//It's a new vendor to insert.
|
||||||
|
insertvendor({
|
||||||
|
variables: { vendorInput: [{ ...values, bodyshopid: bodyshop.id }] }
|
||||||
|
})
|
||||||
|
.then(r => {
|
||||||
|
notification["success"]({
|
||||||
|
message: t("vendors.successes.saved")
|
||||||
|
});
|
||||||
|
//TODO: Better way to reset the field decorators?
|
||||||
|
if (refetch) refetch().then(r => form.resetFields());
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
notification["error"]({
|
||||||
|
message: t("vendors.errors.saving")
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Form onSubmit={handleSubmit} autoComplete='new-password'>
|
||||||
|
{vendor ? (
|
||||||
|
<VendorsFormComponent
|
||||||
|
form={form}
|
||||||
|
vendor={vendor}
|
||||||
|
handleDelete={handleDelete}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
t("vendors.labels.noneselected")
|
||||||
|
)}
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default connect(
|
||||||
|
mapStateToProps,
|
||||||
|
null
|
||||||
|
)(Form.create({ name: "VendorsFormContainer" })(VendorsFormContainer));
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
import { Input, Table } from "antd";
|
import { Input, Table, Button } from "antd";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { alphaSort } from "../../utils/sorters";
|
import { alphaSort } from "../../utils/sorters";
|
||||||
export default function VendorsListComponent({
|
export default function VendorsListComponent({
|
||||||
selectedVendor,
|
selectedVendor,
|
||||||
setSelectedVendor,
|
setSelectedVendor,
|
||||||
|
handleNewVendor,
|
||||||
loading,
|
loading,
|
||||||
refetch,
|
refetch,
|
||||||
|
handleOnRowClick,
|
||||||
vendors
|
vendors
|
||||||
}) {
|
}) {
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
@@ -57,14 +59,6 @@ export default function VendorsListComponent({
|
|||||||
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
|
setState({ ...state, filteredInfo: filters, sortedInfo: sorter });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnRowClick = record => {
|
|
||||||
if (record) {
|
|
||||||
setSelectedVendor(record);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSelectedVendor(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
//TODO Implement search
|
//TODO Implement search
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -72,19 +66,25 @@ export default function VendorsListComponent({
|
|||||||
loading={loading}
|
loading={loading}
|
||||||
title={() => {
|
title={() => {
|
||||||
return (
|
return (
|
||||||
<Input.Search
|
<div>
|
||||||
placeholder={t("general.labels.search")}
|
{" "}
|
||||||
onSearch={value => {
|
<Input.Search
|
||||||
console.log(value);
|
placeholder={t("general.labels.search")}
|
||||||
}}
|
onSearch={value => {
|
||||||
enterButton
|
console.log(value);
|
||||||
/>
|
}}
|
||||||
|
enterButton
|
||||||
|
/>
|
||||||
|
<Button onClick={handleNewVendor}>
|
||||||
|
{t("vendors.actions.new")}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
size="small"
|
size='small'
|
||||||
pagination={{ position: "top" }}
|
pagination={{ position: "top" }}
|
||||||
columns={columns.map(item => ({ ...item }))}
|
columns={columns.map(item => ({ ...item }))}
|
||||||
rowKey="id"
|
rowKey='id'
|
||||||
onChange={handleTableChange}
|
onChange={handleTableChange}
|
||||||
dataSource={vendors}
|
dataSource={vendors}
|
||||||
rowSelection={{
|
rowSelection={{
|
||||||
@@ -92,7 +92,7 @@ export default function VendorsListComponent({
|
|||||||
setSelectedVendor(record);
|
setSelectedVendor(record);
|
||||||
},
|
},
|
||||||
type: "radio",
|
type: "radio",
|
||||||
selectedRowKeys: selectedVendor.id || null
|
selectedRowKeys: selectedVendor ? selectedVendor.id : null
|
||||||
}}
|
}}
|
||||||
onRow={(record, rowIndex) => {
|
onRow={(record, rowIndex) => {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { useQuery } from "react-apollo";
|
import { useQuery } from "react-apollo";
|
||||||
import AlertComponent from "../../components/alert/alert.component";
|
import AlertComponent from "../../components/alert/alert.component";
|
||||||
import { QUERY_ALL_VENDORS, QUERY_VENDOR_BY_ID } from "../../graphql/vendors.queries";
|
import { QUERY_ALL_VENDORS } from "../../graphql/vendors.queries";
|
||||||
import VendorsListComponent from "./vendors-list.component";
|
import VendorsListComponent from "./vendors-list.component";
|
||||||
|
|
||||||
export default function VendorsListContainer({ selectedVendorState }) {
|
export default function VendorsListContainer({ selectedVendorState }) {
|
||||||
@@ -10,23 +10,28 @@ export default function VendorsListContainer({ selectedVendorState }) {
|
|||||||
fetchPolicy: "network-only"
|
fetchPolicy: "network-only"
|
||||||
});
|
});
|
||||||
|
|
||||||
const vendorDetail = useQuery(QUERY_VENDOR_BY_ID, {
|
const handleNewVendor = () => {
|
||||||
fetchPolicy: "network-only",
|
setSelectedVendor({});
|
||||||
variables: { id: selectedVendor.id },
|
};
|
||||||
skip: !selectedVendor.id
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error) return <AlertComponent message={error.message} type="error" />;
|
const handleOnRowClick = record => {
|
||||||
|
if (record) {
|
||||||
|
setSelectedVendor(record);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSelectedVendor(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (error) return <AlertComponent message={error.message} type='error' />;
|
||||||
return (
|
return (
|
||||||
<div>
|
<VendorsListComponent
|
||||||
<VendorsListComponent
|
selectedVendor={selectedVendor}
|
||||||
selectedVendor={selectedVendor}
|
setSelectedVendor={setSelectedVendor}
|
||||||
setSelectedVendor={setSelectedVendor}
|
handleNewVendor={handleNewVendor}
|
||||||
loading={loading}
|
handleOnRowClick={handleOnRowClick}
|
||||||
refetch={refetch}
|
loading={loading}
|
||||||
vendors={data ? data.vendors : null}
|
refetch={refetch}
|
||||||
/>
|
vendors={data ? data.vendors : null}
|
||||||
{JSON.stringify(vendorDetail && vendorDetail.data)}
|
/>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ export const QUERY_VENDOR_BY_ID = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const UPDATE_VEHICLE = gql`
|
export const UPDATE_VENDOR = gql`
|
||||||
mutation UPDATE_VEHICLE($vehId: uuid!, $vehicle: vehicles_set_input!) {
|
mutation UPDATE_VENDOR($id: uuid!, $vendor: vendors_set_input!) {
|
||||||
update_vehicles(where: { id: { _eq: $vehId } }, _set: $vehicle) {
|
update_vendors(where: { id: { _eq: $id } }, _set: $vendor) {
|
||||||
returning {
|
returning {
|
||||||
id
|
id
|
||||||
}
|
}
|
||||||
@@ -46,3 +46,23 @@ export const QUERY_ALL_VENDORS = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const INSERT_NEW_VENDOR = gql`
|
||||||
|
mutation INSERT_NEW_VENDOR($vendorInput: [vendors_insert_input!]!) {
|
||||||
|
insert_vendors(objects: $vendorInput) {
|
||||||
|
returning {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const DELETE_VENDOR = gql`
|
||||||
|
mutation DELETE_VENDOR($id: uuid!) {
|
||||||
|
delete_vendors(where: { id: { _eq: $id } }) {
|
||||||
|
returning {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import VendorsListContainer from "../../components/vendors-list/vendors-list.container";
|
import VendorsListContainer from "../../components/vendors-list/vendors-list.container";
|
||||||
|
import VendorsFormContainer from "../../components/vendors-form/vendors-form.container";
|
||||||
|
|
||||||
export default function ShopVendorPageComponent({ selectedVendorState }) {
|
export default function ShopVendorPageComponent({ selectedVendorState }) {
|
||||||
|
//TODO Figure out how to handle the refresh list when saving form
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<VendorsListContainer selectedVendorState={selectedVendorState} />
|
<VendorsListContainer selectedVendorState={selectedVendorState} />
|
||||||
|
<VendorsFormContainer vendor={selectedVendorState[0]} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default function ShopVendorPageContainer() {
|
|||||||
document.title = t("titles.shop_vendors");
|
document.title = t("titles.shop_vendors");
|
||||||
}, [t]);
|
}, [t]);
|
||||||
|
|
||||||
const selectedVendorState = useState({});
|
const selectedVendorState = useState();
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ShopVendorPageComponent selectedVendorState={selectedVendorState} />
|
<ShopVendorPageComponent selectedVendorState={selectedVendorState} />
|
||||||
|
|||||||
@@ -121,6 +121,7 @@
|
|||||||
"unsavedchanges": "You have unsaved changes."
|
"unsavedchanges": "You have unsaved changes."
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
|
"invalidemail": "Please enter a valid email.",
|
||||||
"required": "This field is required. "
|
"required": "This field is required. "
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -441,12 +442,36 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vendors": {
|
"vendors": {
|
||||||
|
"actions": {
|
||||||
|
"new": "New Vendor"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"saving": "Error encountered while saving vendor. "
|
||||||
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"city": "City",
|
"city": "City",
|
||||||
"cost_center": "Cost Center",
|
"cost_center": "Cost Center",
|
||||||
|
"country": "Country",
|
||||||
|
"discount": "Discount %",
|
||||||
|
"display_name": "Display Name",
|
||||||
|
"due_date": "Payment Due Date",
|
||||||
|
"email": "Contact Email",
|
||||||
"favorite": "Favorite?",
|
"favorite": "Favorite?",
|
||||||
"name": "Vendor Name",
|
"name": "Vendor Name",
|
||||||
"street1": "Street"
|
"prompt_discount": "Prompt Discount %",
|
||||||
|
"state": "State/Province",
|
||||||
|
"street1": "Street",
|
||||||
|
"street2": "Address 2",
|
||||||
|
"taxid": "Tax ID",
|
||||||
|
"terms": "Payment Terms",
|
||||||
|
"zip": "Zip/Postal Code"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"noneselected": "No vendor is selected."
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"deleted": "Vendor deleted successfully. ",
|
||||||
|
"saved": "Vendor saved successfully."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,7 @@
|
|||||||
"unsavedchanges": "Usted tiene cambios no guardados."
|
"unsavedchanges": "Usted tiene cambios no guardados."
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
|
"invalidemail": "Por favor introduzca una dirección de correo electrónico válida.",
|
||||||
"required": "Este campo es requerido."
|
"required": "Este campo es requerido."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -441,12 +442,36 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vendors": {
|
"vendors": {
|
||||||
|
"actions": {
|
||||||
|
"new": "Nuevo vendedor"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"saving": "Se encontró un error al guardar el proveedor."
|
||||||
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"city": "ciudad",
|
"city": "ciudad",
|
||||||
"cost_center": "Centro de costos",
|
"cost_center": "Centro de costos",
|
||||||
|
"country": "País",
|
||||||
|
"discount": "% De descuento",
|
||||||
|
"display_name": "Nombre para mostrar",
|
||||||
|
"due_date": "Fecha de vencimiento del pago",
|
||||||
|
"email": "Email de contacto",
|
||||||
"favorite": "¿Favorito?",
|
"favorite": "¿Favorito?",
|
||||||
"name": "Nombre del vendedor",
|
"name": "Nombre del vendedor",
|
||||||
"street1": "calle"
|
"prompt_discount": "Descuento pronto",
|
||||||
|
"state": "Provincia del estado",
|
||||||
|
"street1": "calle",
|
||||||
|
"street2": "Dirección 2",
|
||||||
|
"taxid": "Identificación del impuesto",
|
||||||
|
"terms": "Términos de pago",
|
||||||
|
"zip": "código postal"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"noneselected": "Ningún vendedor está seleccionado."
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"deleted": "Proveedor eliminado correctamente.",
|
||||||
|
"saved": "Proveedor guardado con éxito."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,6 +121,7 @@
|
|||||||
"unsavedchanges": "Vous avez des changements non enregistrés."
|
"unsavedchanges": "Vous avez des changements non enregistrés."
|
||||||
},
|
},
|
||||||
"validation": {
|
"validation": {
|
||||||
|
"invalidemail": "S'il vous plaît entrer un email valide.",
|
||||||
"required": "Ce champ est requis."
|
"required": "Ce champ est requis."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -441,12 +442,36 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vendors": {
|
"vendors": {
|
||||||
|
"actions": {
|
||||||
|
"new": "Nouveau vendeur"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"saving": "Erreur rencontrée lors de l'enregistrement du fournisseur."
|
||||||
|
},
|
||||||
"fields": {
|
"fields": {
|
||||||
"city": "Ville",
|
"city": "Ville",
|
||||||
"cost_center": "Centre de coûts",
|
"cost_center": "Centre de coûts",
|
||||||
|
"country": "Pays",
|
||||||
|
"discount": "Remise %",
|
||||||
|
"display_name": "Afficher un nom",
|
||||||
|
"due_date": "Date limite de paiement",
|
||||||
|
"email": "Email du contact",
|
||||||
"favorite": "Préféré?",
|
"favorite": "Préféré?",
|
||||||
"name": "Nom du vendeur",
|
"name": "Nom du vendeur",
|
||||||
"street1": "rue"
|
"prompt_discount": "Remise rapide%",
|
||||||
|
"state": "Etat / Province",
|
||||||
|
"street1": "rue",
|
||||||
|
"street2": "Adresse 2 ",
|
||||||
|
"taxid": "Identifiant de taxe",
|
||||||
|
"terms": "Modalités de paiement",
|
||||||
|
"zip": "Zip / code postal"
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
|
"noneselected": "Aucun fournisseur n'est sélectionné."
|
||||||
|
},
|
||||||
|
"successes": {
|
||||||
|
"deleted": "Le fournisseur a bien été supprimé.",
|
||||||
|
"saved": "Le fournisseur a bien enregistré."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user