Added QB like calculator field for numbers that can be used. Resolved issue for unsaved changes indicator BOD-245 BOD-220
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
PaymentRequestButtonElement,
|
||||
useStripe
|
||||
useStripe,
|
||||
} from "@stripe/react-stripe-js";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { connect } from "react-redux";
|
||||
@@ -9,6 +9,8 @@ import { logImEXEvent } from "../../firebase/firebase.utils";
|
||||
import { setEmailOptions } from "../../redux/email/email.actions";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import { TemplateList } from "../../utils/TemplateConstants";
|
||||
import { Input, InputNumber, Popover } from "antd";
|
||||
import { isInteger } from "lodash";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -18,13 +20,14 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
setEmailOptions: (e) => dispatch(setEmailOptions(e)),
|
||||
});
|
||||
|
||||
|
||||
|
||||
function Test({ bodyshop, setEmailOptions }) {
|
||||
const stripe = useStripe();
|
||||
|
||||
const [paymentRequest, setPaymentRequest] = useState(null);
|
||||
useEffect(() => {
|
||||
if (stripe) {
|
||||
console.log("in useeff");
|
||||
const pr = stripe.paymentRequest({
|
||||
country: "CA",
|
||||
displayItems: [{ label: "Deductible", amount: 1099 }],
|
||||
@@ -37,10 +40,8 @@ function Test({ bodyshop, setEmailOptions }) {
|
||||
requestPayerEmail: true,
|
||||
});
|
||||
|
||||
console.log("pr", pr);
|
||||
// Check the availability of the Payment Request API.
|
||||
pr.canMakePayment().then((result) => {
|
||||
console.log("result", result);
|
||||
if (result) {
|
||||
setPaymentRequest(pr);
|
||||
} else {
|
||||
|
||||
@@ -11,7 +11,7 @@ const ContractStatusComponent = (
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (onChange) {
|
||||
if (value !== option && onChange) {
|
||||
onChange(option);
|
||||
}
|
||||
}, [option, onChange]);
|
||||
|
||||
@@ -7,7 +7,7 @@ const CourtesyCarFuelComponent = ({ value = 100, onChange }, ref) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (onChange) {
|
||||
if (value !== option && onChange) {
|
||||
onChange(option);
|
||||
}
|
||||
}, [option, onChange]);
|
||||
|
||||
@@ -11,7 +11,7 @@ const CourtesyCarStatusComponent = (
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (onChange) {
|
||||
if (value !== option && onChange) {
|
||||
onChange(option);
|
||||
}
|
||||
}, [option, onChange]);
|
||||
|
||||
@@ -12,7 +12,7 @@ const EmployeeSearchSelect = (
|
||||
const [option, setOption] = useState(value);
|
||||
const { t } = useTranslation();
|
||||
useEffect(() => {
|
||||
if (onChange) {
|
||||
if (value !== option && onChange) {
|
||||
onChange(option);
|
||||
}
|
||||
}, [option, onChange]);
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
import { Input, Popover } from "antd";
|
||||
import React, { useEffect, useState, forwardRef } from "react";
|
||||
|
||||
const FieldInputNUmberCalculator = (
|
||||
{ value: formValue, onChange: formOnChange },
|
||||
ref
|
||||
) => {
|
||||
const [value, setValue] = useState(formValue);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [history, setHistory] = useState([]);
|
||||
|
||||
const handleChange = (e) => {
|
||||
const key = e.target.value;
|
||||
switch (key) {
|
||||
case "/":
|
||||
case "*":
|
||||
case "+":
|
||||
case "-":
|
||||
return;
|
||||
default:
|
||||
setValue(key);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyDown = (e) => {
|
||||
const { key } = e;
|
||||
|
||||
let action;
|
||||
switch (key) {
|
||||
case "/":
|
||||
case "*":
|
||||
case "+":
|
||||
case "-":
|
||||
action = key;
|
||||
break;
|
||||
case "Enter":
|
||||
action = "=";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
const val = parseFloat(value);
|
||||
setValue(null);
|
||||
if (!isNaN(val)) {
|
||||
setHistory([...history, val, action]);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (value !== formValue && formOnChange) formOnChange(value);
|
||||
}, [formOnChange, value]);
|
||||
|
||||
useEffect(() => {
|
||||
if (history.length > 2) {
|
||||
const subTotal = history.reduce((acc, val, idx) => {
|
||||
if (idx === 0) {
|
||||
return val;
|
||||
}
|
||||
switch (val) {
|
||||
case "/":
|
||||
case "*":
|
||||
case "+":
|
||||
case "-":
|
||||
return acc;
|
||||
|
||||
default:
|
||||
//Weve got math on our hands. Find the last operator, and apply it accordingly.
|
||||
switch (history[idx - 1]) {
|
||||
case "/":
|
||||
return acc / val;
|
||||
case "*":
|
||||
return acc * val;
|
||||
case "+":
|
||||
return acc + val;
|
||||
case "-":
|
||||
return acc - val;
|
||||
default:
|
||||
return acc;
|
||||
}
|
||||
}
|
||||
}, 0);
|
||||
setTotal(subTotal);
|
||||
if (history[history.length - 1] === "=") setValue(subTotal);
|
||||
}
|
||||
}, [history]);
|
||||
|
||||
const popContent = (
|
||||
<div style={{ display: "flex", flexDirection: "column" }}>
|
||||
History
|
||||
{history.map((h, idx) => (
|
||||
<div style={{ marginLeft: "auto" }} key={idx}>
|
||||
{h}
|
||||
</div>
|
||||
))}
|
||||
<div>{total}</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Popover content={popContent} visible={history.length > 0}>
|
||||
<Input
|
||||
ref={ref}
|
||||
value={value}
|
||||
defaultValue={value}
|
||||
onChange={handleChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
onBlur={(e) => setHistory([])}
|
||||
/>
|
||||
</Popover>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default forwardRef(FieldInputNUmberCalculator);
|
||||
@@ -8,16 +8,16 @@ import { useTranslation } from "react-i18next";
|
||||
const DateTimePicker = ({ value, onChange, onBlur }, ref) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const handleChange = (value) => {
|
||||
if (onChange) {
|
||||
onChange(value);
|
||||
const handleChange = (newDate) => {
|
||||
if (value !== newDate && onChange) {
|
||||
onChange(newDate);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<DatePicker
|
||||
className='ant-picker ant-picker-input'
|
||||
data-lpignore='true'
|
||||
className="ant-picker ant-picker-input"
|
||||
data-lpignore="true"
|
||||
selected={value ? new Date(value) : null}
|
||||
onChange={handleChange}
|
||||
showTimeSelect
|
||||
@@ -25,7 +25,7 @@ const DateTimePicker = ({ value, onChange, onBlur }, ref) => {
|
||||
onBlur={onBlur}
|
||||
isClearable
|
||||
placeholderText={t("general.labels.selectdate")}
|
||||
dateFormat='MMMM d, yyyy h:mm aa'
|
||||
dateFormat="MMMM d, yyyy h:mm aa"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ const InvoiceLineSearchSelect = (
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (onChange) {
|
||||
if (value !== option && onChange) {
|
||||
onChange(option);
|
||||
}
|
||||
}, [option, onChange]);
|
||||
|
||||
@@ -11,7 +11,7 @@ const JobSearchSelect = (
|
||||
const [option, setOption] = useState(value);
|
||||
|
||||
useEffect(() => {
|
||||
if (onChange) {
|
||||
if (value !== option && onChange) {
|
||||
onChange(option);
|
||||
}
|
||||
}, [option, onChange]);
|
||||
|
||||
@@ -6,10 +6,10 @@ import JobTotalsTable from "../job-totals-table/job-totals-table.component";
|
||||
import FormRow from "../layout-form-row/layout-form-row.component";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import { DateTimeFormatter } from "../../utils/DateFormatter";
|
||||
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import FieldInputNumberCalculator from "../field-input-number-calculator/field-input-number-calculator.component";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
|
||||
@@ -11,7 +11,7 @@ const VendorSearchSelect = (
|
||||
const [option, setOption] = useState(value);
|
||||
|
||||
useEffect(() => {
|
||||
if (onChange) {
|
||||
if (value !== option && onChange) {
|
||||
onChange(option);
|
||||
}
|
||||
}, [option, onChange]);
|
||||
|
||||
@@ -180,11 +180,7 @@ export function Manage({ match, conflict }) {
|
||||
component={TestComponent}
|
||||
/>
|
||||
<Route exact path={`${match.path}`} component={ManageRootPage} />
|
||||
<Route
|
||||
exact
|
||||
path={`${match.path}/_test`}
|
||||
component={TestComponent}
|
||||
/>
|
||||
|
||||
<Route exact path={`${match.path}/jobs`} component={JobsPage} />
|
||||
<Switch>
|
||||
<Route
|
||||
|
||||
Reference in New Issue
Block a user