ImEX and App Improvements.
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
import Icon, {UploadOutlined} from "@ant-design/icons";
|
||||
import {useApolloClient} from "@apollo/client";
|
||||
import {useSplitTreatments} from "@splitsoftware/splitio-react";
|
||||
import {Alert, Divider, Form, Input, Select, Space, Statistic, Switch, Upload,} from "antd";
|
||||
import Icon, { UploadOutlined } from "@ant-design/icons";
|
||||
import { useApolloClient } from "@apollo/client";
|
||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||
import { Alert, Divider, Form, Input, Select, Space, Statistic, Switch, Upload, } from "antd";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { MdOpenInNew } from "react-icons/md";
|
||||
import { connect } from "react-redux";
|
||||
import { Link } from "react-router-dom";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import { CHECK_BILL_INVOICE_NUMBER } from "../../graphql/bills.queries";
|
||||
import { selectBodyshop } from "../../redux/user/user.selectors";
|
||||
import dayjs from "../../utils/day";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {MdOpenInNew} from "react-icons/md";
|
||||
import {connect} from "react-redux";
|
||||
import {Link} from "react-router-dom";
|
||||
import {createStructuredSelector} from "reselect";
|
||||
import {CHECK_BILL_INVOICE_NUMBER} from "../../graphql/bills.queries";
|
||||
import {selectBodyshop} from "../../redux/user/user.selectors";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import BillFormLinesExtended from "../bill-form-lines-extended/bill-form-lines-extended.component";
|
||||
import FormDatePicker from "../form-date-picker/form-date-picker.component";
|
||||
@@ -20,8 +21,7 @@ import JobSearchSelect from "../job-search-select/job-search-select.component";
|
||||
import LayoutFormRow from "../layout-form-row/layout-form-row.component";
|
||||
import VendorSearchSelect from "../vendor-search-select/vendor-search-select.component";
|
||||
import BillFormLines from "./bill-form.lines.component";
|
||||
import {CalculateBillTotal} from "./bill-form.totals.utility";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import { CalculateBillTotal } from "./bill-form.totals.utility";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -149,9 +149,9 @@ export function BillFormComponent({
|
||||
convertedOnly
|
||||
notExported={false}
|
||||
onBlur={() => {
|
||||
if (form.getFieldValue("jobid") !== null) {
|
||||
if (form.getFieldValue("jobid") !== null && form.getFieldValue("jobid") !== undefined) {
|
||||
loadLines({variables: {id: form.getFieldValue("jobid")}});
|
||||
if (form.getFieldValue("vendorid") !== null) {
|
||||
if (form.getFieldValue("vendorid") !== null && form.getFieldValue("vendorid") !== undefined) {
|
||||
loadOutstandingReturns({
|
||||
variables: {
|
||||
jobId: form.getFieldValue("jobid"),
|
||||
|
||||
@@ -62,7 +62,7 @@ export function ChatAffixContainer({bodyshop, chatVisible}) {
|
||||
|
||||
SubscribeToTopic();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [bodyshop]);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
function handleMessage(payload) {
|
||||
|
||||
@@ -19,7 +19,6 @@ export default function FormsFieldChanged({form, skipPrompt}) {
|
||||
style={{margin: 0, padding: 0, minHeight: "unset"}}
|
||||
>
|
||||
{() => {
|
||||
console.log("should update",form.isFieldsTouched())
|
||||
const errors = form.getFieldsError().filter((e) => e.errors.length > 0);
|
||||
if (form.isFieldsTouched())
|
||||
return (
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import {useMutation} from "@apollo/client";
|
||||
import {Button, Form, notification, Popover, Tooltip} from "antd";
|
||||
import {t} from "i18next";
|
||||
import React, {useState} from "react";
|
||||
import {UPDATE_LINE_PPC} from "../../graphql/jobs-lines.queries";
|
||||
import { useMutation } from "@apollo/client";
|
||||
import { Button, Form, notification, Popover, Tooltip } from "antd";
|
||||
import axios from "axios";
|
||||
import { t } from "i18next";
|
||||
import React, { useState } from "react";
|
||||
import { UPDATE_LINE_PPC } from "../../graphql/jobs-lines.queries";
|
||||
import CurrencyFormatter from "../../utils/CurrencyFormatter";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
import CurrencyFormItemComponent from "../form-items-formatted/currency-form-item.component";
|
||||
import JobLineConvertToLabor from "../job-line-convert-to-labor/job-line-convert-to-labor.component";
|
||||
import axios from "axios";
|
||||
import InstanceRenderManager from "../../utils/instanceRenderMgr";
|
||||
|
||||
export default function JobLinesPartPriceChange({job, line, refetch}) {
|
||||
const [loading, setLoading] = useState(false);
|
||||
@@ -54,7 +54,9 @@ export default function JobLinesPartPriceChange({job, line, refetch}) {
|
||||
}
|
||||
};
|
||||
|
||||
const popcontent = (
|
||||
const popcontent = InstanceRenderManager({
|
||||
imex: null,
|
||||
rome: (
|
||||
<Form layout="vertical" onFinish={handleFinish} initialValues={{act_price: line.act_price}}>
|
||||
<Form.Item
|
||||
name="act_price"
|
||||
@@ -63,15 +65,18 @@ export default function JobLinesPartPriceChange({job, line, refetch}) {
|
||||
>
|
||||
<CurrencyFormItemComponent/>
|
||||
</Form.Item>
|
||||
<Button loading={loading} htmlType="primary">
|
||||
<Button disabled={InstanceRenderManager({imex:true, rome: false, promanager: true})} loading={loading} htmlType="primary">
|
||||
{t("general.actions.save")}
|
||||
</Button>
|
||||
</Form>
|
||||
);
|
||||
),
|
||||
promanager: null
|
||||
}) ;
|
||||
|
||||
return (
|
||||
<JobLineConvertToLabor jobline={line} job={job}>
|
||||
<Popover trigger="click" disabled={line.manual_line || InstanceRenderManager({imex:false, rome:true})} content={popcontent}>
|
||||
<Popover trigger="click"
|
||||
disabled={true || line.manual_line} content={popcontent}>
|
||||
<CurrencyFormatter>
|
||||
{line.db_ref === "900510" || line.db_ref === "900511"
|
||||
? line.prt_dsmk_m
|
||||
|
||||
@@ -8,9 +8,9 @@ import {
|
||||
SyncOutlined,
|
||||
WarningFilled,
|
||||
} from '@ant-design/icons';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { Button, Checkbox, Dropdown, Input, Space, Table, Tag } from 'antd';
|
||||
import { PageHeader } from '@ant-design/pro-layout';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { Button, Dropdown, Input, Space, Table, Tag } from 'antd';
|
||||
import axios from 'axios';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -29,19 +29,19 @@ import JobLinesBillRefernece from '../job-lines-bill-reference/job-lines-bill-re
|
||||
// import AllocationsAssignmentContainer from "../allocations-assignment/allocations-assignment.container";
|
||||
// import AllocationsBulkAssignmentContainer from "../allocations-bulk-assignment/allocations-bulk-assignment.container";
|
||||
// import AllocationsEmployeeLabelContainer from "../allocations-employee-label/allocations-employee-label.container";
|
||||
import { useSplitTreatments } from '@splitsoftware/splitio-react';
|
||||
import _ from 'lodash';
|
||||
import { selectBodyshop } from '../../redux/user/user.selectors';
|
||||
import dayjs from '../../utils/day';
|
||||
import { HasFeatureAccess } from '../feature-wrapper/feature-wrapper.component';
|
||||
import JobCreateIOU from '../job-create-iou/job-create-iou.component';
|
||||
import JobLineBulkAssignComponent from '../job-line-bulk-assign/job-line-bulk-assign.component';
|
||||
import JobLineDispatchButton from '../job-line-dispatch-button/job-line-dispatch-button.component';
|
||||
import JoblineTeamAssignment from '../job-line-team-assignment/job-line-team-assignmnent.component';
|
||||
import JobSendPartPriceChangeComponent from '../job-send-parts-price-change/job-send-parts-price-change.component';
|
||||
import PartsOrderModalContainer from '../parts-order-modal/parts-order-modal.container';
|
||||
import JobLinesExpander from './job-lines-expander.component';
|
||||
import { selectBodyshop } from '../../redux/user/user.selectors';
|
||||
import dayjs from '../../utils/day';
|
||||
import JobLinesPartPriceChange from './job-lines-part-price-change.component';
|
||||
import JoblineTeamAssignment from '../job-line-team-assignment/job-line-team-assignmnent.component';
|
||||
import JobLineDispatchButton from '../job-line-dispatch-button/job-line-dispatch-button.component';
|
||||
import JobLineBulkAssignComponent from '../job-line-bulk-assign/job-line-bulk-assign.component';
|
||||
import { useSplitTreatments } from '@splitsoftware/splitio-react';
|
||||
import { HasFeatureAccess } from '../feature-wrapper/feature-wrapper.component';
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
bodyshop: selectBodyshop,
|
||||
@@ -219,12 +219,12 @@ export function JobLinesComponent({
|
||||
key: 'part_qty',
|
||||
},
|
||||
|
||||
{
|
||||
title: t('joblines.fields.tax_part'),
|
||||
dataIndex: 'tax_part',
|
||||
key: 'tax_part',
|
||||
render: (text, record) => <Checkbox checked={record.tax_part} />,
|
||||
},
|
||||
// {
|
||||
// title: t('joblines.fields.tax_part'),
|
||||
// dataIndex: 'tax_part',
|
||||
// key: 'tax_part',
|
||||
// render: (text, record) => <Checkbox checked={record.tax_part} />,
|
||||
// },
|
||||
// {
|
||||
// title: t("joblines.fields.total"),
|
||||
// dataIndex: "total",
|
||||
|
||||
@@ -57,7 +57,7 @@ export function JobLineDispatchButton({
|
||||
parts_dispatch_lines: {
|
||||
data: selectedLines.map((l) => ({
|
||||
joblineid: l.id,
|
||||
quantity: l.part_qty,
|
||||
quantity: l.part_qty,
|
||||
})),
|
||||
},
|
||||
},
|
||||
@@ -65,6 +65,7 @@ export function JobLineDispatchButton({
|
||||
},
|
||||
});
|
||||
if (result.errors) {
|
||||
console.log("🚀 ~ handleConvert ~ result.errors:", result.errors)
|
||||
notification.open({
|
||||
type: "error",
|
||||
message: t("parts_dispatch.errors.creating", {
|
||||
@@ -86,6 +87,7 @@ export function JobLineDispatchButton({
|
||||
}
|
||||
setVisible(false);
|
||||
} catch (error) {
|
||||
console.log("🚀 ~ handleConvert ~ error:", error)
|
||||
notification.open({
|
||||
type: "error",
|
||||
message: t("parts_dispatch.errors.creating", {
|
||||
@@ -136,7 +138,7 @@ export function JobLineDispatchButton({
|
||||
|
||||
<Space wrap>
|
||||
<Button
|
||||
type="danger"
|
||||
danger
|
||||
onClick={() => form.submit()}
|
||||
loading={loading}
|
||||
disabled={selectedLines.length === 0}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import {useLazyQuery} from "@apollo/client";
|
||||
import {Select, Space, Tag} from "antd";
|
||||
import {Select, Space, Spin, Tag} from "antd";
|
||||
import _ from "lodash";
|
||||
import React, {forwardRef, useEffect, useState} from "react";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {SEARCH_JOBS_BY_ID_FOR_AUTOCOMPLETE, SEARCH_JOBS_FOR_AUTOCOMPLETE,} from "../../graphql/jobs.queries";
|
||||
import AlertComponent from "../alert/alert.component";
|
||||
import {OwnerNameDisplayFunction} from "../owner-name-display/owner-name-display.component";
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { LoadingOutlined } from '@ant-design/icons';
|
||||
|
||||
const {Option} = Select;
|
||||
|
||||
@@ -31,7 +33,6 @@ const JobSearchSelect = (
|
||||
useLazyQuery(SEARCH_JOBS_BY_ID_FOR_AUTOCOMPLETE);
|
||||
|
||||
const executeSearch = (v) => {
|
||||
console.log(v);
|
||||
if (v && v.variables?.search !== "" && v.variables.search.length >= 2)
|
||||
callSearch(v);
|
||||
};
|
||||
@@ -77,14 +78,15 @@ const JobSearchSelect = (
|
||||
disabled={disabled}
|
||||
showSearch
|
||||
autoFocus
|
||||
allowClear
|
||||
allowClear={!loading}
|
||||
style={{
|
||||
width: "100%",
|
||||
}}
|
||||
filterOption={false}
|
||||
onSearch={handleSearch}
|
||||
loading={loading || idLoading}
|
||||
//notFoundContent={loading ? <LoadingOutlined /> : <Empty />}
|
||||
//loading={loading || idLoading}
|
||||
suffixIcon={loading &&<Spin/>}
|
||||
notFoundContent={loading ? <LoadingOutlined /> : null}
|
||||
{...restProps}
|
||||
>
|
||||
{theOptions
|
||||
@@ -106,6 +108,7 @@ const JobSearchSelect = (
|
||||
))
|
||||
: null}
|
||||
</Select>
|
||||
|
||||
{error ? <AlertComponent message={error.message} type="error"/> : null}
|
||||
{idError ? (
|
||||
<AlertComponent message={idError.message} type="error"/>
|
||||
|
||||
@@ -117,7 +117,6 @@ export function JobsAvailableContainer({bodyshop, currentUser, insertAuditTrail,
|
||||
//IO-539 Check for Parts Rate on PAL for SGI use case.
|
||||
//TODO:AIO Check that the async function is actually waiting before moving on.
|
||||
await InstanceRenderManager({executeFunction: true,
|
||||
debug:true,
|
||||
imex: CheckTaxRates, rome: CheckTaxRatesUSA, promanager: CheckTaxRatesUSA, args: [estData.est_data, bodyshop]})
|
||||
|
||||
// }
|
||||
|
||||
@@ -153,7 +153,7 @@ function PaymentModalContainer({
|
||||
}}
|
||||
afterClose={() => form.resetFields()}
|
||||
footer={
|
||||
<span>
|
||||
<Space>
|
||||
<Button onClick={handleCancel}>{t("general.actions.cancel")}</Button>
|
||||
<Button loading={loading} onClick={() => form.submit()}>
|
||||
{t("general.actions.save")}
|
||||
@@ -169,7 +169,7 @@ function PaymentModalContainer({
|
||||
{t("general.actions.saveandnew")}
|
||||
</Button>
|
||||
)}
|
||||
</span>
|
||||
</Space>
|
||||
}
|
||||
>
|
||||
{!context || (context && !context.id) ? null : (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Icon from "@ant-design/icons";
|
||||
import {Popover} from "antd";
|
||||
import {Popover, Space} from "antd";
|
||||
import _ from "lodash";
|
||||
import dayjs from "../../utils/day";
|
||||
|
||||
@@ -135,7 +135,7 @@ export function ScheduleCalendarHeaderComponent({
|
||||
|
||||
const LoadComponent = loadData ? (
|
||||
<div>
|
||||
<div className="imex-flex-row imex-flex-row__flex-space-around">
|
||||
<Space align='center'>
|
||||
<Popover
|
||||
placement={"bottom"}
|
||||
content={jobsInPopup}
|
||||
@@ -155,7 +155,7 @@ export function ScheduleCalendarHeaderComponent({
|
||||
{(loadData.allHoursOut || 0) && loadData.allHoursOut.toFixed(2)}
|
||||
</Popover>
|
||||
<ScheduleCalendarHeaderGraph loadData={loadData}/>
|
||||
</div>
|
||||
</Space>
|
||||
<div>
|
||||
<ul style={{listStyleType: "none", columns: "2 auto", padding: 0}}>
|
||||
{Object.keys(ATSToday).map((key, idx) => (
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
import { AlertOutlined } from '@ant-design/icons';
|
||||
import { Alert, Button, Col, Row, Space } from 'antd';
|
||||
import i18n from 'i18next';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { connect } from 'react-redux';
|
||||
import { createStructuredSelector } from 'reselect';
|
||||
import { selectUpdateAvailable } from '../../redux/application/application.selectors';
|
||||
import { AlertOutlined } from '@ant-design/icons';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { setUpdateAvailable } from '../../redux/application/application.actions';
|
||||
import { store } from '../../redux/store';
|
||||
//import * as serviceWorkerRegistration from '../../serviceWorkerRegistration';
|
||||
import InstanceRenderManager from '../../utils/instanceRenderMgr';
|
||||
import { useRegisterSW } from 'virtual:pwa-register/react';
|
||||
|
||||
let globalRegistration;
|
||||
import InstanceRenderManager from '../../utils/instanceRenderMgr';
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
updateAvailable: selectUpdateAvailable,
|
||||
@@ -46,7 +41,9 @@ export function UpdateAlert({ updateAvailable }) {
|
||||
console.log('SW registration error', error);
|
||||
},
|
||||
});
|
||||
console.log(`SW Status => Refresh? ${needRefresh} - offlineReady? ${offlineReady}`);
|
||||
|
||||
if (import.meta.env.DEV)
|
||||
console.log(`SW Status => Refresh? ${needRefresh} - offlineReady? ${offlineReady}`);
|
||||
|
||||
if (!needRefresh) return null;
|
||||
return (
|
||||
|
||||
@@ -13,6 +13,7 @@ import {GET_UNACCEPTED_PARTS_DISPATCH} from "../../graphql/parts-dispatch.querie
|
||||
import {selectTechnician} from "../../redux/tech/tech.selectors";
|
||||
import {selectBodyshop} from "../../redux/user/user.selectors";
|
||||
import {alphaSort} from "../../utils/sorters";
|
||||
import { useSplitTreatments } from "@splitsoftware/splitio-react";
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
//currentUser: selectCurrentUser
|
||||
@@ -25,6 +26,12 @@ export function TechDispatchedParts({technician, bodyshop}) {
|
||||
const searchParams = queryString.parse(useLocation().search);
|
||||
const {page} = searchParams;
|
||||
|
||||
const {treatments: {Enhanced_Payroll}} = useSplitTreatments({
|
||||
attributes: {},
|
||||
names: ["Enhanced_Payroll"],
|
||||
splitKey: bodyshop.imexshopid,
|
||||
});
|
||||
|
||||
const {loading, error, data, refetch} = useQuery(
|
||||
GET_UNACCEPTED_PARTS_DISPATCH,
|
||||
{
|
||||
@@ -73,7 +80,7 @@ export function TechDispatchedParts({technician, bodyshop}) {
|
||||
} ${record.job.v_model_desc || ""}`}</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
...Enhanced_Payroll.treatment=== 'on' ? [ {
|
||||
title: t("general.labels.actions"),
|
||||
dataIndex: "actions",
|
||||
key: "actions",
|
||||
@@ -83,7 +90,9 @@ export function TechDispatchedParts({technician, bodyshop}) {
|
||||
{t("timetickets.actions.claimtasks")}
|
||||
</Button>
|
||||
),
|
||||
},
|
||||
},] : []
|
||||
|
||||
|
||||
];
|
||||
const handleTableChange = (pagination, filters, sorter) => {
|
||||
searchParams.page = pagination.current;
|
||||
|
||||
@@ -220,24 +220,26 @@ export function* signInSuccessSaga({payload}) {
|
||||
LogRocket.identify(payload.email);
|
||||
|
||||
try {
|
||||
InstanceRenderManager({
|
||||
executeFunction: true,
|
||||
imex: () => {
|
||||
window.$crisp.push([
|
||||
"set",
|
||||
"user:nickname",
|
||||
[payload.displayName || payload.email],
|
||||
]);
|
||||
|
||||
window.$crisp.push(["set", "session:segments", [["user"]]]);
|
||||
} })
|
||||
|
||||
Sentry.setUser({
|
||||
email: payload.email,
|
||||
username: payload.displayName || payload.email,
|
||||
});
|
||||
InstanceRenderManager({
|
||||
executeFunction: true,
|
||||
args:[],
|
||||
imex: () => {
|
||||
window.$crisp.push(['set', 'user:nickname', [payload.displayName || payload.email]]);
|
||||
window.$crisp.push(['set', 'session:segments', [['user']]]);
|
||||
},
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
console.log("Error updating Crisp settings.", error);
|
||||
console.log('Error updating Crisp settings.', error);
|
||||
}
|
||||
|
||||
try {
|
||||
Sentry.setUser({
|
||||
email: payload.email,
|
||||
username: payload.displayName || payload.email,
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('Error setting Sentry user.', error);
|
||||
}
|
||||
|
||||
setUserId(analytics, payload.email);
|
||||
|
||||
@@ -2342,7 +2342,7 @@
|
||||
"associatedbills": "This parts order cannot",
|
||||
"backordering": "Error backordering part {{message}}.",
|
||||
"creating": "Error encountered when creating parts order. ",
|
||||
"oec": "Error creating EMS files for OEC. {{error}}",
|
||||
"oec": "Error creating EMS files for parts order. {{error}}",
|
||||
"saving": "Error saving parts order. {{error}}.",
|
||||
"updating": "Error updating parts order/parts order line. {{error}}."
|
||||
},
|
||||
@@ -2379,7 +2379,7 @@
|
||||
"mark_as_received": "Mark as Received?",
|
||||
"newpartsorder": "New Parts Order",
|
||||
"notyetordered": "This part has not yet been ordered.",
|
||||
"oec": "Order via OEC",
|
||||
"oec": "Order via EMS",
|
||||
"order_type": "Order Type",
|
||||
"orderhistory": "Order History",
|
||||
"parts_order": "Parts Order",
|
||||
|
||||
@@ -20,7 +20,7 @@ i18n
|
||||
//lng: "en",
|
||||
detection: {},
|
||||
fallbackLng: 'en-US',
|
||||
debug: import.meta.env.PROD ? false : true,
|
||||
debug: import.meta.env.DEV,
|
||||
//keySeparator: false, // we do not use keys in form messages.welcome
|
||||
interpolation: {
|
||||
escapeValue: false, // react already safes from xss
|
||||
|
||||
37
client/src/utils/useEffectDebugger.js
Normal file
37
client/src/utils/useEffectDebugger.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
const usePrevious = (value, initialValue) => {
|
||||
const ref = useRef(initialValue);
|
||||
useEffect(() => {
|
||||
ref.current = value;
|
||||
});
|
||||
return ref.current;
|
||||
};
|
||||
|
||||
const useEffectDebugger = (effectHook, dependencies, dependencyNames = []) => {
|
||||
const previousDeps = usePrevious(dependencies, []);
|
||||
|
||||
const changedDeps = dependencies.reduce((accum, dependency, index) => {
|
||||
if (dependency !== previousDeps[index]) {
|
||||
const keyName = dependencyNames[index] || index;
|
||||
return {
|
||||
...accum,
|
||||
[keyName]: {
|
||||
before: previousDeps[index],
|
||||
after: dependency,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return accum;
|
||||
}, {});
|
||||
|
||||
if (Object.keys(changedDeps).length) {
|
||||
console.log('[use-effect-debugger] ', changedDeps);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
useEffect(effectHook, dependencies);
|
||||
};
|
||||
|
||||
export default useEffectDebugger;
|
||||
Reference in New Issue
Block a user