From 9a40fa6c7384c234a3ba69f9b329a2d85ff3846e Mon Sep 17 00:00:00 2001 From: Juan Mrad Date: Thu, 19 Mar 2026 20:42:31 -0500 Subject: [PATCH] [Code Simplification] Remove use of `react-google-charts` and ui fixes (#131) * [Code Simplification] Remove use of and ui fixes * fix betterer issue * fix pre-existing bug --- .betterer.results | 50 +++++----- client/package-lock.json | 10 -- client/package.json | 1 - .../visualization/RulesDashboardInsights.tsx | 92 +++++++++++++++---- .../ReportingRuleInsightsSamplesTable.tsx | 5 +- .../insights/RuleInsightsActionsChart.tsx | 20 ++-- .../insights/RuleInsightsSamplesTable.tsx | 5 +- 7 files changed, 110 insertions(+), 73 deletions(-) diff --git a/.betterer.results b/.betterer.results index d5b6c9a..e267d67 100644 --- a/.betterer.results +++ b/.betterer.results @@ -118,14 +118,14 @@ exports[`No explicit any in client`] = { "client/src/webpages/dashboard/rules/dashboard/RulesDashboard.tsx:3586802679": [ [192, 30, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx:2418477128": [ - [309, 21, 3, "Unexpected any. Specify a different type.", "193409811"], - [338, 19, 3, "Unexpected any. Specify a different type.", "193409811"], - [397, 52, 3, "Unexpected any. Specify a different type.", "193409811"], - [410, 52, 3, "Unexpected any. Specify a different type.", "193409811"], - [422, 28, 3, "Unexpected any. Specify a different type.", "193409811"], - [439, 30, 3, "Unexpected any. Specify a different type.", "193409811"], - [661, 20, 3, "Unexpected any. Specify a different type.", "193409811"] + "client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx:3222042515": [ + [311, 21, 3, "Unexpected any. Specify a different type.", "193409811"], + [340, 19, 3, "Unexpected any. Specify a different type.", "193409811"], + [399, 52, 3, "Unexpected any. Specify a different type.", "193409811"], + [412, 52, 3, "Unexpected any. Specify a different type.", "193409811"], + [424, 28, 3, "Unexpected any. Specify a different type.", "193409811"], + [441, 30, 3, "Unexpected any. Specify a different type.", "193409811"], + [663, 20, 3, "Unexpected any. Specify a different type.", "193409811"] ], "client/src/webpages/dashboard/rules/dashboard/visualization/rulesDashboardInsightsChart.tsx:3641428222": [ [198, 32, 3, "Unexpected any. Specify a different type.", "193409811"], @@ -136,23 +136,23 @@ exports[`No explicit any in client`] = { [135, 52, 3, "Unexpected any. Specify a different type.", "193409811"], [147, 28, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx:2418655797": [ + "client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx:1919031301": [ [442, 42, 3, "Unexpected any. Specify a different type.", "193409811"], [454, 32, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx:1526952710": [ + "client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx:179927555": [ [74, 20, 3, "Unexpected any. Specify a different type.", "193409811"], [75, 40, 3, "Unexpected any. Specify a different type.", "193409811"], [122, 12, 3, "Unexpected any. Specify a different type.", "193409811"], [122, 20, 3, "Unexpected any. Specify a different type.", "193409811"], [125, 24, 3, "Unexpected any. Specify a different type.", "193409811"], - [138, 52, 3, "Unexpected any. Specify a different type.", "193409811"], - [151, 52, 3, "Unexpected any. Specify a different type.", "193409811"] + [132, 52, 3, "Unexpected any. Specify a different type.", "193409811"], + [145, 52, 3, "Unexpected any. Specify a different type.", "193409811"] ], - "client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx:1132615281": [ + "client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx:3800335297": [ [611, 25, 3, "Unexpected any. Specify a different type.", "193409811"], [623, 32, 3, "Unexpected any. Specify a different type.", "193409811"], - [747, 11, 3, "Unexpected any. Specify a different type.", "193409811"] + [748, 11, 3, "Unexpected any. Specify a different type.", "193409811"] ], "client/src/webpages/dashboard/rules/rule_form/ReportingRuleForm.tsx:3391496803": [ [424, 38, 3, "Unexpected any. Specify a different type.", "193409811"], @@ -482,19 +482,19 @@ exports[`No counterproductive type annotations`] = { "client/src/webpages/dashboard/mrt/manual_review_job/v2/ManualReviewJobFieldsComponent.tsx:3836324260": [ [204, 33, 16, "When a function \`x\` is written inline and passed as an argument, it\'s usually better not to write explicit type annotations on \`x\`\'s arguments because the argument types should be able to be inferred, and the inferred type will usually be more accurate than what you\'d write manually. Plus, the inferred type will automatically update.\\n\\nIf the type for x\'s arguments is not being correctly inferred, that suggests an issue with the type definition of the function that \`x\` is being passed to.", "2813373547"] ], - "client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx:2418477128": [ - [661, 16, 7, "When a function \`x\` is written inline and passed as an argument, it\'s usually better not to write explicit type annotations on \`x\`\'s arguments because the argument types should be able to be inferred, and the inferred type will usually be more accurate than what you\'d write manually. Plus, the inferred type will automatically update.\\n\\nIf the type for x\'s arguments is not being correctly inferred, that suggests an issue with the type definition of the function that \`x\` is being passed to.", "2339939476"] + "client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx:3222042515": [ + [663, 16, 7, "When a function \`x\` is written inline and passed as an argument, it\'s usually better not to write explicit type annotations on \`x\`\'s arguments because the argument types should be able to be inferred, and the inferred type will usually be more accurate than what you\'d write manually. Plus, the inferred type will automatically update.\\n\\nIf the type for x\'s arguments is not being correctly inferred, that suggests an issue with the type definition of the function that \`x\` is being passed to.", "2339939476"] ], - "client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx:2418655797": [ + "client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx:1919031301": [ [239, 15, 18, "When a function \`x\` is written inline and passed as an argument, it\'s usually better not to write explicit type annotations on \`x\`\'s arguments because the argument types should be able to be inferred, and the inferred type will usually be more accurate than what you\'d write manually. Plus, the inferred type will automatically update.\\n\\nIf the type for x\'s arguments is not being correctly inferred, that suggests an issue with the type definition of the function that \`x\` is being passed to.", "4144316489"] ], - "client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx:1526952710": [ + "client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx:179927555": [ [75, 26, 17, "When a function \`x\` is written inline and passed as an argument, it\'s usually better not to write explicit type annotations on \`x\`\'s arguments because the argument types should be able to be inferred, and the inferred type will usually be more accurate than what you\'d write manually. Plus, the inferred type will automatically update.\\n\\nIf the type for x\'s arguments is not being correctly inferred, that suggests an issue with the type definition of the function that \`x\` is being passed to.", "1029763998"], [122, 9, 6, "When a function \`x\` is written inline and passed as an argument, it\'s usually better not to write explicit type annotations on \`x\`\'s arguments because the argument types should be able to be inferred, and the inferred type will usually be more accurate than what you\'d write manually. Plus, the inferred type will automatically update.\\n\\nIf the type for x\'s arguments is not being correctly inferred, that suggests an issue with the type definition of the function that \`x\` is being passed to.", "1412855912"], [122, 17, 6, "When a function \`x\` is written inline and passed as an argument, it\'s usually better not to write explicit type annotations on \`x\`\'s arguments because the argument types should be able to be inferred, and the inferred type will usually be more accurate than what you\'d write manually. Plus, the inferred type will automatically update.\\n\\nIf the type for x\'s arguments is not being correctly inferred, that suggests an issue with the type definition of the function that \`x\` is being passed to.", "1449682699"], [125, 12, 15, "When a function \`x\` is written inline and passed as an argument, it\'s usually better not to write explicit type annotations on \`x\`\'s arguments because the argument types should be able to be inferred, and the inferred type will usually be more accurate than what you\'d write manually. Plus, the inferred type will automatically update.\\n\\nIf the type for x\'s arguments is not being correctly inferred, that suggests an issue with the type definition of the function that \`x\` is being passed to.", "2927082151"] ], - "client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx:1132615281": [ + "client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx:3800335297": [ [404, 15, 18, "When a function \`x\` is written inline and passed as an argument, it\'s usually better not to write explicit type annotations on \`x\`\'s arguments because the argument types should be able to be inferred, and the inferred type will usually be more accurate than what you\'d write manually. Plus, the inferred type will automatically update.\\n\\nIf the type for x\'s arguments is not being correctly inferred, that suggests an issue with the type definition of the function that \`x\` is being passed to.", "4144316489"] ], "client/src/webpages/dashboard/rules/rule_form/RuleForm.tsx:1069542000": [ @@ -651,22 +651,22 @@ exports[`No new ant-design icon imports`] = { "client/src/webpages/dashboard/rules/dashboard/RulesDashboard.tsx:3586802679": [ [8, 0, 76, "\'@ant-design/icons\' import is restricted from being used. AntDesign icons are now deprecated in our codebase. Please use line icons instead.", "4151994019"] ], - "client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx:2418477128": [ + "client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx:3222042515": [ [5, 0, 113, "\'@ant-design/icons\' import is restricted from being used. AntDesign icons are now deprecated in our codebase. Please use line icons instead.", "3403673047"] ], "client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsActionsChart.tsx:1076126041": [ [2, 0, 72, "\'@ant-design/icons\' import is restricted from being used. AntDesign icons are now deprecated in our codebase. Please use line icons instead.", "87078707"] ], - "client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx:2418655797": [ + "client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx:1919031301": [ [0, 0, 92, "\'@ant-design/icons\' import is restricted from being used. AntDesign icons are now deprecated in our codebase. Please use line icons instead.", "3155850297"] ], - "client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx:1526952710": [ + "client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx:179927555": [ [3, 0, 72, "\'@ant-design/icons\' import is restricted from being used. AntDesign icons are now deprecated in our codebase. Please use line icons instead.", "87078707"] ], "client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesPlayVideoButton.tsx:3799970987": [ [0, 0, 53, "\'@ant-design/icons\' import is restricted from being used. AntDesign icons are now deprecated in our codebase. Please use line icons instead.", "1828321615"] ], - "client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx:1132615281": [ + "client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx:3800335297": [ [0, 0, 92, "\'@ant-design/icons\' import is restricted from being used. AntDesign icons are now deprecated in our codebase. Please use line icons instead.", "3155850297"] ], "client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesVideoModal.tsx:2468150091": [ @@ -826,7 +826,7 @@ exports[`No new line-icon imports`] = { [0, 0, 87, "\'@/icons/lni/Direction/chevron-down.svg\' import is restricted from being used by a pattern.", "3761457464"], [1, 0, 83, "\'@/icons/lni/Direction/chevron-up.svg\' import is restricted from being used by a pattern.", "1296196504"] ], - "client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx:2418477128": [ + "client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx:3222042515": [ [3, 0, 62, "\'@/icons\' import is restricted from being used.", "469112768"] ], "client/src/webpages/dashboard/rules/dashboard/visualization/rulesDashboardInsightsChart.tsx:3641428222": [ @@ -836,7 +836,7 @@ exports[`No new line-icon imports`] = { "client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsActionsChart.tsx:1076126041": [ [1, 0, 43, "\'@/icons\' import is restricted from being used.", "3049589739"] ], - "client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx:1526952710": [ + "client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx:179927555": [ [1, 0, 62, "\'@/icons\' import is restricted from being used.", "469112768"] ], "client/src/webpages/dashboard/rules/rule_form/ReportingRuleForm.tsx:3391496803": [ diff --git a/client/package-lock.json b/client/package-lock.json index de58c19..101120a 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -64,7 +64,6 @@ "react-csv": "^2.2.2", "react-day-picker": "^8.9.1", "react-dom": "^18.2.0", - "react-google-charts": "^4.0.0", "react-helmet-async": "^2.0.3", "react-markdown": "^9.0.1", "react-player": "^2.10.1", @@ -24622,15 +24621,6 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" }, - "node_modules/react-google-charts": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/react-google-charts/-/react-google-charts-4.0.0.tgz", - "integrity": "sha512-9OG0EkBb9JerKEPQYdhmAXnhGLzOdOHOPS9j7l+P1a3z1kcmq9mGDa7PUoX/VQUY4IjZl2/81nsO4o+1cuYsuw==", - "peerDependencies": { - "react": ">=16.3.0", - "react-dom": ">=16.3.0" - } - }, "node_modules/react-helmet-async": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.3.tgz", diff --git a/client/package.json b/client/package.json index 2fc6f9a..edd7f81 100644 --- a/client/package.json +++ b/client/package.json @@ -72,7 +72,6 @@ "react-csv": "^2.2.2", "react-day-picker": "^8.9.1", "react-dom": "^18.2.0", - "react-google-charts": "^4.0.0", "react-helmet-async": "^2.0.3", "react-markdown": "^9.0.1", "react-player": "^2.10.1", diff --git a/client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx b/client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx index b8d0b50..b010fce 100644 --- a/client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx +++ b/client/src/webpages/dashboard/rules/dashboard/visualization/RulesDashboardInsights.tsx @@ -25,17 +25,19 @@ import sum from 'lodash/sum'; import sumBy from 'lodash/sumBy'; import union from 'lodash/union'; import without from 'lodash/without'; -import moment from 'moment'; +import { format, parseISO } from 'date-fns'; import React, { ReactNode, useCallback, useMemo, useState } from 'react'; -import { Chart } from 'react-google-charts'; import { Area, Bar, BarChart, CartesianGrid, + Cell, ComposedChart, Legend, Line, + Pie, + PieChart, ReferenceLine, ResponsiveContainer, Tooltip, @@ -403,7 +405,7 @@ export default function RulesDashboardInsights() { fill="#71717a" className="pt-3 text-slate-500" > - {moment(payload.value).format('MM/DD/YY')} + {format(parseISO(payload.value), 'MM/dd/yy')} ); }; @@ -472,7 +474,7 @@ export default function RulesDashboardInsights() { return (
- {moment(label).format('MM/DD/YY')} + {format(parseISO(label), 'MM/dd/yy')}
{data.length > 1 && (
@@ -667,25 +669,75 @@ export default function RulesDashboardInsights() { }); return curr; }, - {} as { [k: string]: string }, + {} as { [k: string]: number }, ); - const pieChartData = Object.keys(combinedChartData).map((category) => [ - category, - combinedChartData[category], - ]); + const pieChartData = Object.keys(combinedChartData).map((category) => ({ + name: category, + value: combinedChartData[category], + })); + + const RADIAN = Math.PI / 180; + const renderLabel = ({ + cx, + cy, + midAngle, + innerRadius, + outerRadius, + percent, + }: { + cx: number; + cy: number; + midAngle: number; + innerRadius: number; + outerRadius: number; + percent: number; + }) => { + const radius = innerRadius + (outerRadius - innerRadius) * 0.5; + const x = cx + radius * Math.cos(-midAngle * RADIAN); + const y = cy + radius * Math.sin(-midAngle * RADIAN); + return ( + + {`${(percent * 100).toFixed(0)}%`} + + ); + }; return ( - + + + + {pieChartData.map((_, index) => ( + + ))} + + + + + ); }, [sortedChartData]); diff --git a/client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx b/client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx index 0f524e4..0707ace 100644 --- a/client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx +++ b/client/src/webpages/dashboard/rules/info/insights/ReportingRuleInsightsSamplesTable.tsx @@ -532,13 +532,14 @@ export default function ReportingRuleInsightsSamplesTable(props: { ) : tableData?.length === 0 ? ( noSamples ) : ( -
-
+
+
{detailViewData.visible && detailViewData.item && ( diff --git a/client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx b/client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx index 7a66fe6..e8d5e5f 100644 --- a/client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx +++ b/client/src/webpages/dashboard/rules/info/insights/RuleInsightsActionsChart.tsx @@ -7,7 +7,7 @@ import last from 'lodash/last'; import orderBy from 'lodash/orderBy'; import sortBy from 'lodash/sortBy'; import sumBy from 'lodash/sumBy'; -import moment from 'moment'; +import { format, parseISO } from 'date-fns'; import { ReactNode, useCallback, useMemo, useState } from 'react'; import { Bar, @@ -123,17 +123,11 @@ export default function RuleInsightsActionsChart(props: { ruleId: string }) { (a: any, b: any) => new Date(a.date).getTime() - new Date(b.date).getTime(), ) - .map((actionData: any) => { - // change actionData.date format from YYYY-MM-DD to MM/DD - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [year, month, date] = actionData.date.split('-'); - - return { - date: `${month}/${date}/${year.slice(-2)}`, - totalMatches: actionData.totalMatches, - totalRequests: actionData.totalRequests, - }; - }); + .map((actionData: any) => ({ + date: format(parseISO(actionData.date), 'MM/dd/yy'), + totalMatches: actionData.totalMatches, + totalRequests: actionData.totalRequests, + })); }, [filteredPassRateData]); const renderCustomXAxisTick = ({ x, y, payload }: any) => { @@ -177,7 +171,7 @@ export default function RuleInsightsActionsChart(props: { ruleId: string }) { return (
- {moment(label).format('MM/DD/YY')} + {label}
{data.length > 1 && (
diff --git a/client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx b/client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx index ddfbf4e..559a68c 100644 --- a/client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx +++ b/client/src/webpages/dashboard/rules/info/insights/RuleInsightsSamplesTable.tsx @@ -700,13 +700,14 @@ export default function RuleInsightsSamplesTable(props: { ruleId: string }) { ) : tableData?.length === 0 ? ( noSamples ) : ( -
-
+
+
{detailViewData.visible && detailViewData.item && ( -- 2.51.2