From 659ffb43183fed5eba7d15ed18d5b9792992facb Mon Sep 17 00:00:00 2001 From: Eliot Eikenberry Date: Fri, 20 Sep 2024 15:16:38 -0400 Subject: [PATCH] fix: address infinite rerender bug (#27) * fix: address infinite rerender bug * chore: remove unused import --- package.json | 8 +- src/components/AtAGlance.tsx | 5 +- src/components/Charts.tsx | 177 ++++++++++++++++------------------- yarn.lock | 8 +- 4 files changed, 93 insertions(+), 105 deletions(-) diff --git a/package.json b/package.json index 6e76a8d..b1dbc91 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "@liatrio/backstage-dora-plugin", - "version": "0.0.0", - "main": "dist/index.esm.js", - "types": "dist/index.d.ts", + "version": "0.0.37", + "main": "./dist/index.esm.js", + "types": "./dist/index.d.ts", "license": "Apache-2.0", "description": "A Backstage plugin for DORA metrics", "keywords": [ @@ -46,7 +46,7 @@ "@backstage/core-plugin-api": "^1.9.1", "@backstage/plugin-catalog-react": "^1.12.3", "@backstage/theme": "^0.5.2", - "@liatrio/react-dora-charts": "^1.1.4", + "@liatrio/react-dora-charts": "^1.1.8", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.61", diff --git a/src/components/AtAGlance.tsx b/src/components/AtAGlance.tsx index 527350c..f64b015 100644 --- a/src/components/AtAGlance.tsx +++ b/src/components/AtAGlance.tsx @@ -80,7 +80,8 @@ export const AtAGlance = () => { }; fetch(); - }, [apiUrl, daysToFetch, getAuthHeaderValue, repositoryName]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const tTitle = ( { DORA Metrics are not available for Non-GitHub repos currently ) : ( -
+
{showTrendGraph ? ( { - const entity = useEntity(); + // eslint-disable-next-line react-hooks/rules-of-hooks + const entity = props.showTeamSelection ? null : useEntity(); const configApi = useApi(configApiRef); const backendUrl = configApi.getString('backend.baseUrl'); const dataEndpoint = configApi.getString('dora.dataEndpoint'); @@ -177,98 +178,91 @@ export const Charts = (props: ChartProps) => { const theme = backstageTheme.palette.mode === 'dark' ? Theme.Dark : Theme.Light; - const getMetrics = useCallback( - (respData: any) => { - if (!respData || respData.length === 0) { - setMetrics({ ...defaultMetrics }); - return; - } + const getMetrics = (respData: any) => { + if (!respData || respData.length === 0) { + setMetrics({ ...defaultMetrics }); + return; + } - const metricsData = buildDoraStateForPeriod( - { - data: [], - metricThresholdSet: rankThresholds, - holidays: [], - includeWeekendsInCalculations: includeWeekends, - graphEnd: endDate, - graphStart: startDate, - }, - respData, - startDate, - endDate, - ); - - setMetrics(metricsData); - }, - [endDate, includeWeekends, rankThresholds, startDate], - ); + const metricsData = buildDoraStateForPeriod( + { + data: [], + metricThresholdSet: rankThresholds, + holidays: [], + includeWeekendsInCalculations: includeWeekends, + graphEnd: endDate, + graphStart: startDate, + }, + respData, + startDate, + endDate, + ); - const updateData = useCallback( - (respData: any, start?: Date, end?: Date, msg?: string) => { - if (!respData || respData.length < 1) { - setData([]); - setMetrics({ ...defaultMetrics }); - setMessage(''); - } else { - setData(respData); - } + setMetrics(metricsData); + }; - getMetrics(respData); + const updateData = ( + respData: any, + start?: Date, + end?: Date, + msg?: string, + ) => { + if (!respData || respData.length < 1) { + setData([]); + setMetrics({ ...defaultMetrics }); + setMessage(''); + } else { + setData(respData); + } - if (msg !== undefined) { - setMessage(msg); - } + getMetrics(respData); - if (start) { - setStartDate(start); - } + if (msg !== undefined) { + setMessage(msg); + } - if (end) { - setEndDate(end); - } - }, - [getMetrics], - ); + if (start) { + setStartDate(start); + } - const makeFetchOptions = useCallback( - (team?: string, repositories?: string[]) => { - const fetchOptions: any = { - api: apiUrl, - getAuthHeaderValue: getAuthHeaderValue, - start: getDateDaysInPast(daysToFetch), - end: getDateDaysInPastUtc(0), - }; - - if (!props.showTeamSelection) { - fetchOptions.repositories = repositories!; - } else { - fetchOptions.team = team; - } + if (end) { + setEndDate(end); + } + }; - return fetchOptions; - }, - [apiUrl, daysToFetch, getAuthHeaderValue, props.showTeamSelection], - ); + const makeFetchOptions = (team?: string, repositories?: string[]) => { + const fetchOptions: any = { + api: apiUrl, + getAuthHeaderValue: getAuthHeaderValue, + start: getDateDaysInPast(daysToFetch), + end: getDateDaysInPastUtc(0), + }; - const callFetchData = useCallback( - async (idx: number, repo: string) => { - const fetchOptions = makeFetchOptions(teams[idx]?.value, [repo]); - - setLoading(true); - - await fetchData( - fetchOptions, - (respData: any) => { - updateData(respData, undefined, undefined, ''); - setLoading(false); - }, - _ => { - setLoading(false); - }, - ); - }, - [makeFetchOptions, teams, updateData], - ); + if (!props.showTeamSelection) { + fetchOptions.repositories = repositories!; + } else { + fetchOptions.team = team; + } + + return fetchOptions; + }; + + const callFetchData = async (idx: number, repo: string) => { + const fetchOptions = makeFetchOptions(teams[idx]?.value, [repo]); + + setLoading(true); + + await fetchData( + fetchOptions, + (respData: any) => { + updateData(respData, undefined, undefined, ''); + setLoading(false); + }, + _ => { + setLoading(false); + }, + ); + }; const updateTeam = async (value: any) => { const newIndex = teams.findIndex( @@ -374,15 +368,8 @@ export const Charts = (props: ChartProps) => { }; fetch(); - }, [ - callFetchData, - entity, - getAuthHeaderValue, - props.showTeamSelection, - teamIndex, - teamListUrl, - teamsList, - ]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); if (repository === '' && !props.showTeamSelection) { return ( @@ -528,7 +515,7 @@ export const Charts = (props: ChartProps) => {
diff --git a/yarn.lock b/yarn.lock index e5f8d0c..80374f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2299,10 +2299,10 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== -"@liatrio/react-dora-charts@^1.1.4": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@liatrio/react-dora-charts/-/react-dora-charts-1.1.4.tgz#c80acf857f450b685939c985250e480bb04d5eea" - integrity sha512-ztz3/ItjgtEUXW1K9YBYT4fm8sbiYlE0rELF3Xk0qeOvzUhzv3c5Gen9TQDqfwbCrr77KupKVUtkyduveMgQTg== +"@liatrio/react-dora-charts@^1.1.8": + version "1.1.8" + resolved "https://registry.yarnpkg.com/@liatrio/react-dora-charts/-/react-dora-charts-1.1.8.tgz#dc211ad7dcf309f86433b72a62c4632326b01ea6" + integrity sha512-1nHCTmMg3S1WPwNhEJ9RF3rg3Gt1Es4QeD1VdloDwMwwbILwO02ORjVruNAC2Cb4LWOxUHD+FqMTcTadjKIfDg== dependencies: js-yaml "^4.1.0" react-tooltip "^5.28.0"