From 076b028556bd528e0c1d71c315d4dee5c03832d4 Mon Sep 17 00:00:00 2001 From: Pratiksha Janbandhu Date: Fri, 27 Mar 2026 11:44:48 +0530 Subject: [PATCH 1/2] Fix redundant updates in MappingHome by restricting componentDidUpdate triggers --- src/components/mappings/MappingHome.jsx | 281 ++++++++++++++++-------- 1 file changed, 190 insertions(+), 91 deletions(-) diff --git a/src/components/mappings/MappingHome.jsx b/src/components/mappings/MappingHome.jsx index d95c6d2a..2b867b8c 100644 --- a/src/components/mappings/MappingHome.jsx +++ b/src/components/mappings/MappingHome.jsx @@ -1,13 +1,13 @@ -import React from 'react'; -import { CircularProgress } from '@mui/material'; -import { get, isObject, has } from 'lodash'; -import APIService from '../../services/APIService'; -import { recordGAAction, highlightTexts } from '../../common/utils' -import ScopeHeader from './ScopeHeader' -import MappingHomeDetails from './MappingHomeDetails'; -import NotFound from '../common/NotFound'; -import AccessDenied from '../common/AccessDenied'; -import PermissionDenied from '../common/PermissionDenied'; +import React from "react"; +import { CircularProgress } from "@mui/material"; +import { get, isObject, has } from "lodash"; +import APIService from "../../services/APIService"; +import { recordGAAction, highlightTexts } from "../../common/utils"; +import ScopeHeader from "./ScopeHeader"; +import MappingHomeDetails from "./MappingHomeDetails"; +import NotFound from "../common/NotFound"; +import AccessDenied from "../common/AccessDenied"; +import PermissionDenied from "../common/PermissionDenied"; class MappingHome extends React.Component { constructor(props) { @@ -21,141 +21,240 @@ class MappingHome extends React.Component { mapping: {}, versions: [], collections: [], - } + }; } componentDidMount() { - this.refreshDataByURL() + this.refreshDataByURL(); } + // componentDidUpdate(prevProps) { + // if(prevProps.location.pathname !== this.props.location.pathname) { + // this.refreshDataByURL() + // } + + // this.highlightFromSearch() + // } + componentDidUpdate(prevProps) { - if(prevProps.location.pathname !== this.props.location.pathname) { - this.refreshDataByURL() + const currentPath = this.props.location.pathname; + const prevPath = prevProps.location.pathname; + // Only refetch data when URL changes + if (prevPath !== currentPath) { + this.refreshDataByURL(); + } + // Only highlight when search metadata changes + if (prevProps.searchMeta !== this.props.searchMeta) { + this.highlightFromSearch(); } - - this.highlightFromSearch() } getMappingURLFromPath() { const { location, match, scoped, parentURL, mapping } = this.props; - if(scoped === 'collection') - return `${parentURL}mappings/${mapping.id}/${mapping.version}/` - if(scoped) - return location.pathname - if(location.pathname.indexOf('/details') > -1) - return location.pathname.split('/details')[0] + '/' - if(location.pathname.indexOf('/history') > -1) - return location.pathname.split('/history')[0] + '/' - if(match.params.mappingVersion) - return location.pathname.split('/').slice(0, 8).join('/') + '/'; + if (scoped === "collection") + return `${parentURL}mappings/${mapping.id}/${mapping.version}/`; + if (scoped) return location.pathname; + if (location.pathname.indexOf("/details") > -1) + return location.pathname.split("/details")[0] + "/"; + if (location.pathname.indexOf("/history") > -1) + return location.pathname.split("/history")[0] + "/"; + if (match.params.mappingVersion) + return ( + location.pathname + .split("/") + .slice(0, 8) + .join("/") + "/" + ); return this.getVersionedObjectURLFromPath(); } getVersionedObjectURLFromPath() { const { location } = this.props; - return location.pathname.split('/').slice(0, 7).join('/') + '/'; + return ( + location.pathname + .split("/") + .slice(0, 7) + .join("/") + "/" + ); } refreshDataByURL() { - this.setState({isLoading: true, notFound: false, accessDenied: false, permissionDenied: false}, () => { - const URL = this.getMappingURLFromPath() - APIService.new() - .overrideURL(URL) - .get(null, null, {includeReferences: this.props.scoped === 'collection'}) - .then(response => { - recordGAAction('Mapping', 'split_view', `Mapping - ${URL}`) - if(get(response, 'detail') === "Not found.") - this.setState({isLoading: false, mapping: {}, notFound: true, accessDenied: false, permissionDenied: false}) - else if(get(response, 'detail') === "Authentication credentials were not provided.") - this.setState({isLoading: false, notFound: false, mapping: {}, accessDenied: true, permissionDenied: false}) - else if(get(response, 'detail') === "You do not have permission to perform this action.") - this.setState({isLoading: false, notFound: false, mapping: {}, accessDenied: false, permissionDenied: true}) - else if(!isObject(response)) - this.setState({isLoading: false}, () => {throw response}) - else - this.setState({isLoading: false, mapping: response.data}, () => { - if(this.props.scoped !== 'collection') { - this.getVersions() - this.getCollectionVersions() - } - }) - }) - - }) + this.setState( + { + isLoading: true, + notFound: false, + accessDenied: false, + permissionDenied: false, + }, + () => { + const URL = this.getMappingURLFromPath(); + APIService.new() + .overrideURL(URL) + .get(null, null, { + includeReferences: this.props.scoped === "collection", + }) + .then((response) => { + recordGAAction("Mapping", "split_view", `Mapping - ${URL}`); + if (get(response, "detail") === "Not found.") + this.setState({ + isLoading: false, + mapping: {}, + notFound: true, + accessDenied: false, + permissionDenied: false, + }); + else if ( + get(response, "detail") === + "Authentication credentials were not provided." + ) + this.setState({ + isLoading: false, + notFound: false, + mapping: {}, + accessDenied: true, + permissionDenied: false, + }); + else if ( + get(response, "detail") === + "You do not have permission to perform this action." + ) + this.setState({ + isLoading: false, + notFound: false, + mapping: {}, + accessDenied: false, + permissionDenied: true, + }); + else if (!isObject(response)) + this.setState({ isLoading: false }, () => { + throw response; + }); + else + this.setState( + { isLoading: false, mapping: response.data }, + () => { + if (this.props.scoped !== "collection") { + this.getVersions(); + this.getCollectionVersions(); + } + }, + ); + }); + }, + ); } - highlightFromSearch = () => this.props.searchMeta && setTimeout(() => highlightTexts([{...this.state.mapping, search_meta: this.props.searchMeta}]), 100) + highlightFromSearch = () => + this.props.searchMeta && + setTimeout( + () => + highlightTexts([ + { ...this.state.mapping, search_meta: this.props.searchMeta }, + ]), + 100, + ); getVersions() { APIService.new() - .overrideURL(this.getVersionedObjectURLFromPath() + 'versions/') - .get(null, null, {includeCollectionVersions: true, includeSourceVersions: true}) - .then(response => { - this.setState({versions: response.data}) - }) + .overrideURL(this.getVersionedObjectURLFromPath() + "versions/") + .get(null, null, { + includeCollectionVersions: true, + includeSourceVersions: true, + }) + .then((response) => { + this.setState({ versions: response.data }); + }); } getCollectionVersions() { - this.setState({isLoadingCollections: true}, () => { + this.setState({ isLoadingCollections: true }, () => { APIService.new() - .overrideURL(this.getMappingURLFromPath() + 'collection-versions/?limit=100') - .get() - .then(response => { - this.setState({collections: response.data, isLoadingCollections: false}) - }) - }) + .overrideURL( + this.getMappingURLFromPath() + "collection-versions/?limit=100", + ) + .get() + .then((response) => { + this.setState({ + collections: response.data, + isLoadingCollections: false, + }); + }); + }); } isVersionedObject() { - return this.props.global || !this.props.match.params.mappingVersion || this.state.mapping?.type === 'Mapping'; + return ( + this.props.global || + !this.props.match.params.mappingVersion || + this.state.mapping?.type === "Mapping" + ); } - getContentMarginTop = () => `${get(document.querySelector('header.resource-header.home-header'), 'offsetHeight') || 95}px`; + getContentMarginTop = () => + `${get( + document.querySelector("header.resource-header.home-header"), + "offsetHeight", + ) || 95}px`; render() { const { - mapping, versions, isLoading, notFound, accessDenied, permissionDenied, collections, isLoadingCollections + mapping, + versions, + isLoading, + notFound, + accessDenied, + permissionDenied, + collections, + isLoadingCollections, } = this.state; - const currentURL = this.getMappingURLFromPath() - const isVersionedObject = this.isVersionedObject() + const currentURL = this.getMappingURLFromPath(); + const isVersionedObject = this.isVersionedObject(); const hasError = notFound || accessDenied || permissionDenied; const headerParams = { mapping: mapping, isVersionedObject: isVersionedObject, versionedObjectURL: this.getVersionedObjectURLFromPath(), currentURL: currentURL, - header: has(this.props, 'header') ? this.props.header : true - } + header: has(this.props, "header") ? this.props.header : true, + }; return ( -
- { isLoading && } - { notFound && } - { accessDenied && } - { permissionDenied && } - { - !isLoading && !hasError && -
- -
+
+ {isLoading && } + {notFound && } + {accessDenied && } + {permissionDenied && } + {!isLoading && !hasError && ( +
+ +
- } + )}
- ) + ); } } From 39f32971970e2f4c8b298adc031b1ec340a9fd95 Mon Sep 17 00:00:00 2001 From: Pratiksha Janbandhu Date: Fri, 27 Mar 2026 15:05:20 +0530 Subject: [PATCH 2/2] Fix redundant updates in MappingHome by restricting componentDidUpdate --- src/components/mappings/MappingHome.jsx | 288 ++++++++---------------- 1 file changed, 97 insertions(+), 191 deletions(-) diff --git a/src/components/mappings/MappingHome.jsx b/src/components/mappings/MappingHome.jsx index 2b867b8c..6f326521 100644 --- a/src/components/mappings/MappingHome.jsx +++ b/src/components/mappings/MappingHome.jsx @@ -1,13 +1,13 @@ -import React from "react"; -import { CircularProgress } from "@mui/material"; -import { get, isObject, has } from "lodash"; -import APIService from "../../services/APIService"; -import { recordGAAction, highlightTexts } from "../../common/utils"; -import ScopeHeader from "./ScopeHeader"; -import MappingHomeDetails from "./MappingHomeDetails"; -import NotFound from "../common/NotFound"; -import AccessDenied from "../common/AccessDenied"; -import PermissionDenied from "../common/PermissionDenied"; +import React from 'react'; +import { CircularProgress } from '@mui/material'; +import { get, isObject, has } from 'lodash'; +import APIService from '../../services/APIService'; +import { recordGAAction, highlightTexts } from '../../common/utils' +import ScopeHeader from './ScopeHeader' +import MappingHomeDetails from './MappingHomeDetails'; +import NotFound from '../common/NotFound'; +import AccessDenied from '../common/AccessDenied'; +import PermissionDenied from '../common/PermissionDenied'; class MappingHome extends React.Component { constructor(props) { @@ -21,240 +21,146 @@ class MappingHome extends React.Component { mapping: {}, versions: [], collections: [], - }; + } } componentDidMount() { - this.refreshDataByURL(); + this.refreshDataByURL() } - // componentDidUpdate(prevProps) { - // if(prevProps.location.pathname !== this.props.location.pathname) { - // this.refreshDataByURL() - // } - - // this.highlightFromSearch() - // } - componentDidUpdate(prevProps) { - const currentPath = this.props.location.pathname; - const prevPath = prevProps.location.pathname; - // Only refetch data when URL changes - if (prevPath !== currentPath) { - this.refreshDataByURL(); - } - // Only highlight when search metadata changes - if (prevProps.searchMeta !== this.props.searchMeta) { - this.highlightFromSearch(); - } + const currentPath = this.props.location.pathname + const prevPath = prevProps.location.pathname + + if (prevPath !== currentPath) { + this.refreshDataByURL() + } + + if (prevProps.searchMeta !== this.props.searchMeta) { + this.highlightFromSearch() } +} getMappingURLFromPath() { const { location, match, scoped, parentURL, mapping } = this.props; - if (scoped === "collection") - return `${parentURL}mappings/${mapping.id}/${mapping.version}/`; - if (scoped) return location.pathname; - if (location.pathname.indexOf("/details") > -1) - return location.pathname.split("/details")[0] + "/"; - if (location.pathname.indexOf("/history") > -1) - return location.pathname.split("/history")[0] + "/"; - if (match.params.mappingVersion) - return ( - location.pathname - .split("/") - .slice(0, 8) - .join("/") + "/" - ); + if(scoped === 'collection') + return `${parentURL}mappings/${mapping.id}/${mapping.version}/` + if(scoped) + return location.pathname + if(location.pathname.indexOf('/details') > -1) + return location.pathname.split('/details')[0] + '/' + if(location.pathname.indexOf('/history') > -1) + return location.pathname.split('/history')[0] + '/' + if(match.params.mappingVersion) + return location.pathname.split('/').slice(0, 8).join('/') + '/'; return this.getVersionedObjectURLFromPath(); } getVersionedObjectURLFromPath() { const { location } = this.props; - return ( - location.pathname - .split("/") - .slice(0, 7) - .join("/") + "/" - ); + return location.pathname.split('/').slice(0, 7).join('/') + '/'; } refreshDataByURL() { - this.setState( - { - isLoading: true, - notFound: false, - accessDenied: false, - permissionDenied: false, - }, - () => { - const URL = this.getMappingURLFromPath(); - APIService.new() - .overrideURL(URL) - .get(null, null, { - includeReferences: this.props.scoped === "collection", - }) - .then((response) => { - recordGAAction("Mapping", "split_view", `Mapping - ${URL}`); - if (get(response, "detail") === "Not found.") - this.setState({ - isLoading: false, - mapping: {}, - notFound: true, - accessDenied: false, - permissionDenied: false, - }); - else if ( - get(response, "detail") === - "Authentication credentials were not provided." - ) - this.setState({ - isLoading: false, - notFound: false, - mapping: {}, - accessDenied: true, - permissionDenied: false, - }); - else if ( - get(response, "detail") === - "You do not have permission to perform this action." - ) - this.setState({ - isLoading: false, - notFound: false, - mapping: {}, - accessDenied: false, - permissionDenied: true, - }); - else if (!isObject(response)) - this.setState({ isLoading: false }, () => { - throw response; - }); - else - this.setState( - { isLoading: false, mapping: response.data }, - () => { - if (this.props.scoped !== "collection") { - this.getVersions(); - this.getCollectionVersions(); - } - }, - ); - }); - }, - ); + this.setState({isLoading: true, notFound: false, accessDenied: false, permissionDenied: false}, () => { + const URL = this.getMappingURLFromPath() + APIService.new() + .overrideURL(URL) + .get(null, null, {includeReferences: this.props.scoped === 'collection'}) + .then(response => { + recordGAAction('Mapping', 'split_view', `Mapping - ${URL}`) + if(get(response, 'detail') === "Not found.") + this.setState({isLoading: false, mapping: {}, notFound: true, accessDenied: false, permissionDenied: false}) + else if(get(response, 'detail') === "Authentication credentials were not provided.") + this.setState({isLoading: false, notFound: false, mapping: {}, accessDenied: true, permissionDenied: false}) + else if(get(response, 'detail') === "You do not have permission to perform this action.") + this.setState({isLoading: false, notFound: false, mapping: {}, accessDenied: false, permissionDenied: true}) + else if(!isObject(response)) + this.setState({isLoading: false}, () => {throw response}) + else + this.setState({isLoading: false, mapping: response.data}, () => { + if(this.props.scoped !== 'collection') { + this.getVersions() + this.getCollectionVersions() + } + }) + }) + + }) } - highlightFromSearch = () => - this.props.searchMeta && - setTimeout( - () => - highlightTexts([ - { ...this.state.mapping, search_meta: this.props.searchMeta }, - ]), - 100, - ); + highlightFromSearch = () => this.props.searchMeta && setTimeout(() => highlightTexts([{...this.state.mapping, search_meta: this.props.searchMeta}]), 100) getVersions() { APIService.new() - .overrideURL(this.getVersionedObjectURLFromPath() + "versions/") - .get(null, null, { - includeCollectionVersions: true, - includeSourceVersions: true, - }) - .then((response) => { - this.setState({ versions: response.data }); - }); + .overrideURL(this.getVersionedObjectURLFromPath() + 'versions/') + .get(null, null, {includeCollectionVersions: true, includeSourceVersions: true}) + .then(response => { + this.setState({versions: response.data}) + }) } getCollectionVersions() { - this.setState({ isLoadingCollections: true }, () => { + this.setState({isLoadingCollections: true}, () => { APIService.new() - .overrideURL( - this.getMappingURLFromPath() + "collection-versions/?limit=100", - ) - .get() - .then((response) => { - this.setState({ - collections: response.data, - isLoadingCollections: false, - }); - }); - }); + .overrideURL(this.getMappingURLFromPath() + 'collection-versions/?limit=100') + .get() + .then(response => { + this.setState({collections: response.data, isLoadingCollections: false}) + }) + }) } isVersionedObject() { - return ( - this.props.global || - !this.props.match.params.mappingVersion || - this.state.mapping?.type === "Mapping" - ); + return this.props.global || !this.props.match.params.mappingVersion || this.state.mapping?.type === 'Mapping'; } - getContentMarginTop = () => - `${get( - document.querySelector("header.resource-header.home-header"), - "offsetHeight", - ) || 95}px`; + getContentMarginTop = () => `${get(document.querySelector('header.resource-header.home-header'), 'offsetHeight') || 95}px`; render() { const { - mapping, - versions, - isLoading, - notFound, - accessDenied, - permissionDenied, - collections, - isLoadingCollections, + mapping, versions, isLoading, notFound, accessDenied, permissionDenied, collections, isLoadingCollections } = this.state; - const currentURL = this.getMappingURLFromPath(); - const isVersionedObject = this.isVersionedObject(); + const currentURL = this.getMappingURLFromPath() + const isVersionedObject = this.isVersionedObject() const hasError = notFound || accessDenied || permissionDenied; const headerParams = { mapping: mapping, isVersionedObject: isVersionedObject, versionedObjectURL: this.getVersionedObjectURLFromPath(), currentURL: currentURL, - header: has(this.props, "header") ? this.props.header : true, - }; + header: has(this.props, 'header') ? this.props.header : true + } return ( -
- {isLoading && } - {notFound && } - {accessDenied && } - {permissionDenied && } - {!isLoading && !hasError && ( -
- -
+
+ { isLoading && } + { notFound && } + { accessDenied && } + { permissionDenied && } + { + !isLoading && !hasError && +
+ +
- )} + }
- ); + ) } }