Skip to content

Commit

Permalink
Upgrade recharts to modern version.
Browse files Browse the repository at this point in the history
  • Loading branch information
tdilauro committed Aug 22, 2024
1 parent f54d231 commit 47d8419
Show file tree
Hide file tree
Showing 9 changed files with 636 additions and 393 deletions.
361 changes: 237 additions & 124 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"react-dom": "^16.8.6",
"react-redux": "^7.2.9",
"react-router": "^3.2.0",
"recharts": "^1.8.6",
"recharts": "^2.12.7",
"redux": "^4.2.1",
"redux-thunk": "^2.4.2",
"request": "^2.85.0",
Expand Down Expand Up @@ -119,6 +119,7 @@
"react-axe": "^3.3.0",
"react-test-renderer": "^16.14.0",
"redux-mock-store": "^1.5.4",
"resize-observer-polyfill": "^1.5.1",
"sass": "^1.64.2",
"sass-lint": "^1.13.1",
"sass-loader": "^13.2.0",
Expand Down
4 changes: 3 additions & 1 deletion src/components/ContextProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from "react";
import { Store } from "@reduxjs/toolkit";
import * as PropTypes from "prop-types";
import buildStore, { RootState } from "../store";
import { FeatureFlags, PathFor } from "../interfaces";
import { FeatureFlags, PathFor, TestingFlags } from "../interfaces";
import Admin from "../models/Admin";
import PathForProvider from "@thepalaceproject/web-opds-client/lib/components/context/PathForContext";
import ActionCreator from "../actions";
Expand All @@ -25,6 +25,7 @@ export interface ContextProviderProps extends React.Props<ContextProvider> {
}[];
featureFlags: FeatureFlags;
quicksightPagePath?: string;
testingFlags?: TestingFlags;
}

/** Provides a redux store, configuration options, and a function to create URLs
Expand Down Expand Up @@ -109,6 +110,7 @@ export default class ContextProvider extends React.Component<
admin: this.admin,
featureFlags: this.props.featureFlags,
quicksightPagePath: this.props.quicksightPagePath,
testingFlags: this.props.testingFlags,
};
return (
<PathForProvider pathFor={this.pathFor}>
Expand Down
33 changes: 25 additions & 8 deletions src/components/StatsCollectionsBarChart.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import * as React from "react";
import { useTestingFlagEnabled } from "../context/appContext";
import { CollectionInventory } from "../interfaces";
import { ValueType } from "recharts/types/component/DefaultTooltipContent";
import {
Bar,
BarChart,
ResponsiveContainer,
ResponsiveContainer as RechartsResponsiveContainer,
Tooltip,
TooltipProps,
XAxis,
Expand All @@ -12,6 +14,20 @@ import {
import { inventoryKeyToLabelMap } from "./LibraryStats";
import { formatNumber } from "../utils/sharedFunctions";

// These values are needed for testing, in some cases.
export const COLLECTION_BAR_CHART_TEST_FLAG_KEY =
"COLLECTION_BAR_CHART_TEST_FLAG_KEY";
const TestResponsiveContainer = ({ children }) => (
<RechartsResponsiveContainer width={800} height={800}>
{children}
</RechartsResponsiveContainer>
);

type Props = {
collections: CollectionInventory[];
ResponsiveContainer?: any;
};

const StatsCollectionsBarChart = ({ collections }: Props) => {
const chartItems = collections
?.map(({ name, inventory, inventoryByMedium }) => ({
Expand All @@ -21,19 +37,23 @@ const StatsCollectionsBarChart = ({ collections }: Props) => {
}))
.sort((a, b) => (a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1));

const ResponsiveContainer = useTestingFlagEnabled(
COLLECTION_BAR_CHART_TEST_FLAG_KEY
)
? TestResponsiveContainer
: RechartsResponsiveContainer;
return (
<ResponsiveContainer height={chartItems.length * 100 + 75} width="100%">
<BarChart
data={chartItems}
layout="vertical"
margin={{ top: 5, right: 30, left: 0, bottom: 50 }}
margin={{ top: 5, right: 30, left: 10, bottom: 50 }}
>
<YAxis
type="category"
dataKey="name"
interval={0}
angle={-45}
tick={{ dx: -20 }}
tick={{ dx: -5 }}
padding={{ top: 0, bottom: 0 }}
height={175}
width={125}
Expand Down Expand Up @@ -76,15 +96,12 @@ type chartTooltipData = {
perMedium?: OneLevelStatistics;
};

type Props = {
collections: CollectionInventory[];
};
/* Customize the Rechart tooltip to provide additional information */
export const CustomTooltip = ({
active,
payload,
label: collectionName,
}: TooltipProps) => {
}: TooltipProps<ValueType, string>) => {
if (!active) {
return null;
}
Expand Down
2 changes: 2 additions & 0 deletions src/components/__tests__/LibraryStats-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const getAllProviders = ({ isSysAdmin = false } = {}) => {
return componentWithProviders({ contextProviderProps });
};

global.ResizeObserver = require("resize-observer-polyfill");

describe("LibraryStats", () => {
// Convert from the API format to our in-app format.
const statisticsData = normalizeStatistics(statisticsApiResponseData);
Expand Down
13 changes: 12 additions & 1 deletion src/context/appContext.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createContext, useContext } from "react";
import { FeatureFlags } from "../interfaces";
import { FeatureFlags, TestingFlags } from "../interfaces";
import Admin from "../models/Admin";

export type AppContextType = {
Expand All @@ -8,6 +8,8 @@ export type AppContextType = {
admin: Admin;
featureFlags: FeatureFlags;
quicksightPagePath: string;
// These flags are used only during testing and are discouraged wherever possible.
testingFlags?: { [key: string]: boolean };
};

// Don't export this, since we always want the error handling behavior of our hook.
Expand All @@ -21,6 +23,15 @@ export const useAppContext = (): AppContextType => {
return context;
};

const flagEnabled = (flags: TestingFlags, flagName: string) => {
// A flag must be affirmatively set and `true` to be considered "enabled".
return !!flags?.[flagName];
};
export const useTestingFlagEnabled = (flagName: string) => {
const testingFlags = useAppContext().testingFlags;
return flagEnabled(testingFlags, flagName);
};

export const useCsrfToken = () => useAppContext().csrfToken;
export const useAppAdmin = () => useAppContext().admin;
export const useAppEmail = () => useAppAdmin().email;
Expand Down
8 changes: 8 additions & 0 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ export interface ConfigurationSettings {
/** `quickSightPagePath` contains the URL to the QuickSight dashboard page.
Currently, this value does not change, so we can share it via fixed config. */
quicksightPagePath: string;

/** These flags are used only during testing and are discouraged wherever
possible. */
testingFlags?: TestingFlags;
}

export interface TestingFlags {
[key: string]: boolean;
}

export interface FeatureFlags {
Expand Down
2 changes: 2 additions & 0 deletions src/stylesheets/stats.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
text-align: left;
font-style: italic;
font-size: small;
text-wrap: balance;
}

.stat-usage-reports {
Expand All @@ -102,6 +103,7 @@
h3 {
font-weight: bolder;
text-transform: uppercase;
text-wrap: balance;
margin: 10px;
margin-bottom: 2px;
}
Expand Down
Loading

0 comments on commit 47d8419

Please sign in to comment.