From 04ef1dd3a482cc4caef948fd510c57d3045d3731 Mon Sep 17 00:00:00 2001 From: Jim O'Donnell Date: Fri, 24 May 2024 13:45:08 +0100 Subject: [PATCH] chore(frontend): clean up lint errors and imports - Clean up lodash imports for better tree-shaking. - Clean up misc. linter errors. --- frontend/src/asset-list/use-sorted-features.ts | 4 ++-- frontend/src/config/assets/data-formats.ts | 4 ++-- .../details/features/damages/DamagesSection.tsx | 6 +++--- .../details/solutions/SolutionsSidebarContent.tsx | 4 ++-- .../lib/controls/checkbox-tree/CheckboxTree.tsx | 2 +- .../controls/checkbox-tree/CheckboxTreeItem.tsx | 2 +- .../src/lib/controls/checkbox-tree/tree-node.ts | 4 ++-- frontend/src/lib/controls/data-params.ts | 10 ++++++---- frontend/src/lib/controls/params/value-label.ts | 2 +- frontend/src/lib/data-map/DataMap.tsx | 6 +++--- .../lib/data-map/MapContextProviderWithLimits.tsx | 6 +++--- .../data-map/interactions/interaction-state.ts | 4 ++-- .../lib/data-map/interactions/use-interactions.ts | 15 +++++++++------ frontend/src/lib/data-map/view-layers.ts | 10 +++++----- frontend/src/lib/deck/props/color-map.ts | 4 ++-- frontend/src/lib/deck/props/data-source.ts | 4 ++-- frontend/src/lib/helpers.ts | 7 ++++--- frontend/src/lib/react/with-props.tsx | 4 ++-- frontend/src/lib/recoil/grouped-family.ts | 4 ++-- .../tooltip/content/SolutionHoverDescription.tsx | 4 ++-- frontend/src/map/use-background-config.ts | 7 ++++--- .../src/sidebar/networks/AdaptationControl.tsx | 5 +++-- frontend/src/state/damage-mapping/damage-map.ts | 4 ++-- frontend/src/state/data-params.ts | 12 +++++++----- frontend/src/state/hazards/hazard-selection.ts | 4 ++-- frontend/src/state/layers/networks.ts | 10 ++++++---- frontend/src/state/networks/network-selection.ts | 6 +++--- frontend/src/state/solutions/landuse-tree.ts | 9 +++++---- frontend/src/state/view.ts | 12 +++++++----- 29 files changed, 95 insertions(+), 80 deletions(-) diff --git a/frontend/src/asset-list/use-sorted-features.ts b/frontend/src/asset-list/use-sorted-features.ts index 5a116795..15de2e0a 100644 --- a/frontend/src/asset-list/use-sorted-features.ts +++ b/frontend/src/asset-list/use-sorted-features.ts @@ -4,7 +4,7 @@ import bbox from '@turf/bbox'; import { ApiClient, FeatureListItemOut_float_ } from 'lib/api-client'; import { BoundingBox } from 'lib/bounding-box'; import { FieldSpec } from 'lib/data-map/view-layers'; -import _ from 'lodash'; +import pick from 'lodash/pick'; import { useCallback, useEffect, useState } from 'react'; const apiClient = new ApiClient({ @@ -69,7 +69,7 @@ export const useSortedFeatures = ( const features = (response.items as FeatureListItemOut_float_[]).map(processFeature); setFeatures(features); - setPageInfo(_.pick(response, ['page', 'size', 'total'])); + setPageInfo(pick(response, ['page', 'size', 'total'])); } catch (error) { setError(error); } diff --git a/frontend/src/config/assets/data-formats.ts b/frontend/src/config/assets/data-formats.ts index 8b8938b8..460f8ef8 100644 --- a/frontend/src/config/assets/data-formats.ts +++ b/frontend/src/config/assets/data-formats.ts @@ -1,7 +1,7 @@ import { HAZARDS_METADATA } from 'config/hazards/metadata'; import { FieldSpec, FormatConfig } from 'lib/data-map/view-layers'; import { isNullish, numFormat, numFormatMoney, paren } from 'lib/helpers'; -import _ from 'lodash'; +import startCase from 'lodash/startCase'; function getSourceLabel(eadSource: string) { if (eadSource === 'all') return 'All Hazards'; @@ -43,7 +43,7 @@ const adaptationFieldLabels = { }; function getAdaptationFieldLabel(field: string) { - return adaptationFieldLabels[field] || _.startCase(field); + return adaptationFieldLabels[field] || startCase(field); } function formatAdaptationValue(value: number, { field }: FieldSpec) { diff --git a/frontend/src/details/features/damages/DamagesSection.tsx b/frontend/src/details/features/damages/DamagesSection.tsx index c07c171e..74692ae0 100644 --- a/frontend/src/details/features/damages/DamagesSection.tsx +++ b/frontend/src/details/features/damages/DamagesSection.tsx @@ -5,7 +5,7 @@ import { HAZARD_DOMAINS } from 'config/hazards/domains'; import { ExpectedDamage, ReturnPeriodDamage } from 'lib/api-client'; import { downloadFile, titleCase, unique } from 'lib/helpers'; import { useSelect } from 'lib/hooks/use-select'; -import _ from 'lodash'; +import fromPairs from 'lodash/fromPairs'; import { useMemo } from 'react'; import { DamageTable } from './DamageTable'; import { RPDamageTable } from './RPDamageTable'; @@ -122,7 +122,7 @@ function prepareRPDamages(rpDamages: ReturnPeriodDamage[]) { } function orderDamages(damages: ExpectedDamageCell[]) { - const lookup = _.fromPairs(damages.map((d) => [d.key, d])); + const lookup = fromPairs(damages.map((d) => [d.key, d])); return DAMAGES_ORDERING.map(getDamageKey) .map((key) => lookup[key]) @@ -130,7 +130,7 @@ function orderDamages(damages: ExpectedDamageCell[]) { } function orderRPDamages(damages: RPDamageCell[]) { - const lookup = _.fromPairs(damages.map((d) => [d.key, d])); + const lookup = fromPairs(damages.map((d) => [d.key, d])); return RP_ORDERING.map(getRPDamageKey) .map((key) => lookup[key]) diff --git a/frontend/src/details/solutions/SolutionsSidebarContent.tsx b/frontend/src/details/solutions/SolutionsSidebarContent.tsx index 51ade76d..168324c1 100644 --- a/frontend/src/details/solutions/SolutionsSidebarContent.tsx +++ b/frontend/src/details/solutions/SolutionsSidebarContent.tsx @@ -3,7 +3,7 @@ import { VECTOR_COLOR_MAPS } from 'config/color-maps'; import { MARINE_HABITATS_LOOKUP } from 'config/solutions/domains'; import { DataItem } from 'details/features/detail-components'; import { colorMap } from 'lib/color-map'; -import _ from 'lodash'; +import startCase from 'lodash/startCase'; import { ColorBox } from 'map/tooltip/content/ColorBox'; import { FC } from 'react'; import { habitatColorMap } from 'state/layers/marine'; @@ -24,7 +24,7 @@ export const SolutionsSidebarContent: FC = ({ }) => { return ( <> - {_.startCase(solutionType)} + {startCase(solutionType)} {solutionType === 'terrestrial' && ( <> diff --git a/frontend/src/lib/controls/checkbox-tree/CheckboxTree.tsx b/frontend/src/lib/controls/checkbox-tree/CheckboxTree.tsx index eaf11307..53567488 100644 --- a/frontend/src/lib/controls/checkbox-tree/CheckboxTree.tsx +++ b/frontend/src/lib/controls/checkbox-tree/CheckboxTree.tsx @@ -75,7 +75,7 @@ export function CheckboxTree({ }: { config: CheckboxTreeConfig; nodes: TreeNode[]; - getLabel: (node: TreeNode, checked: boolean) => any; + getLabel: (node: TreeNode, checked: boolean) => string | JSX.Element; checkboxState: CheckboxTreeState; onCheckboxState: (state: CheckboxTreeState) => void; expanded: string[]; diff --git a/frontend/src/lib/controls/checkbox-tree/CheckboxTreeItem.tsx b/frontend/src/lib/controls/checkbox-tree/CheckboxTreeItem.tsx index 30e0eef8..3b5cd62b 100644 --- a/frontend/src/lib/controls/checkbox-tree/CheckboxTreeItem.tsx +++ b/frontend/src/lib/controls/checkbox-tree/CheckboxTreeItem.tsx @@ -19,7 +19,7 @@ export function CheckboxTreeItem({ root: TreeNode; handleChange: (checked: boolean, node: TreeNode) => void; checkboxState: CheckboxTreeState; - getLabel: (node: TreeNode, checked: boolean) => any; + getLabel: (node: TreeNode, checked: boolean) => string | JSX.Element; disableCheck?: boolean; }) { const indeterminate = checkboxState.indeterminate[root.id]; diff --git a/frontend/src/lib/controls/checkbox-tree/tree-node.ts b/frontend/src/lib/controls/checkbox-tree/tree-node.ts index 85d7dd36..a28b19e5 100644 --- a/frontend/src/lib/controls/checkbox-tree/tree-node.ts +++ b/frontend/src/lib/controls/checkbox-tree/tree-node.ts @@ -13,10 +13,10 @@ export type TreeNode = { */ export function dfs( node: TreeNode, - action: (node: TreeNode) => any, + action: (node: TreeNode) => number | void | false, skipRoot = false, order: 'pre' | 'post' = 'pre', -): any { +) { if (order === 'pre' && !skipRoot) { const continueTraversal = action(node); diff --git a/frontend/src/lib/controls/data-params.ts b/frontend/src/lib/controls/data-params.ts index cced92c8..5d3b1d0f 100644 --- a/frontend/src/lib/controls/data-params.ts +++ b/frontend/src/lib/controls/data-params.ts @@ -1,4 +1,6 @@ -import _ from 'lodash'; +import groupBy from 'lodash/groupBy'; +import mapValues from 'lodash/mapValues'; +import uniq from 'lodash/uniq'; export type Param = any; export type ParamDomain = PT[]; @@ -65,12 +67,12 @@ function getGroupKey(keys: (keyof T)[]) { } function groupByMulti(data: T[], properties: (keyof T)[]) { - return _.groupBy(data, getGroupKey(properties)); + return groupBy(data, getGroupKey(properties)); } function makeDependencyFunction(data: T[], param: keyof T, inputs: (keyof T)[]) { const grouped = groupByMulti(data, inputs); - const groupedDomains = _.mapValues(grouped, (g) => _.uniq(g.map((d) => d[param]))); + const groupedDomains = mapValues(grouped, (g) => uniq(g.map((d) => d[param]))); return (params: T) => groupedDomains[getGroupKey(inputs)(params)]; } @@ -93,7 +95,7 @@ export function inferDomainsFromData(data: T[]): ParamGroupDom const keys = Object.keys(data[0]); for (const key of keys) { const values = data.map((d) => d[key]); - domains[key] = _.uniq(values); + domains[key] = uniq(values); } return domains; } diff --git a/frontend/src/lib/controls/params/value-label.ts b/frontend/src/lib/controls/params/value-label.ts index e7884594..b836e2e5 100644 --- a/frontend/src/lib/controls/params/value-label.ts +++ b/frontend/src/lib/controls/params/value-label.ts @@ -7,7 +7,7 @@ export function isValueLabel(value): value is ValueLabel { return typeof value === 'object' && 'value' in value && 'label' in value; } -export function getValueLabel(value: any): ValueLabel { +export function getValueLabel(value: ValueLabel | string): ValueLabel { if (isValueLabel(value)) { return value; } diff --git a/frontend/src/lib/data-map/DataMap.tsx b/frontend/src/lib/data-map/DataMap.tsx index 954e1357..61ec4269 100644 --- a/frontend/src/lib/data-map/DataMap.tsx +++ b/frontend/src/lib/data-map/DataMap.tsx @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import difference from 'lodash/difference'; import { FC, ReactNode, useCallback, useEffect, useMemo } from 'react'; import { usePrevious } from '../hooks/use-previous'; @@ -53,11 +53,11 @@ export const DataMap: FC = ({ useEffect(() => { // destroy removed data loaders to free up memory - const removedLoaders = _.difference(previousLoaders ?? [], dataLoaders); + const removedLoaders = difference(previousLoaders ?? [], dataLoaders); removedLoaders.forEach((dl) => dl.destroy()); // subscribe to new data loaders to get notified when data is loaded - const addedLoaders = _.difference(dataLoaders, previousLoaders ?? []); + const addedLoaders = difference(dataLoaders, previousLoaders ?? []); addedLoaders.forEach((dl) => dl.subscribe(doTrigger)); // if there was a change in data loaders, trigger an update to the data map diff --git a/frontend/src/lib/data-map/MapContextProviderWithLimits.tsx b/frontend/src/lib/data-map/MapContextProviderWithLimits.tsx index d4f7b7e9..8b440c10 100644 --- a/frontend/src/lib/data-map/MapContextProviderWithLimits.tsx +++ b/frontend/src/lib/data-map/MapContextProviderWithLimits.tsx @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import omit from 'lodash/omit'; import { FC, ReactNode, useContext, useMemo } from 'react'; import { MapContext, MapContextProps } from 'react-map-gl'; @@ -27,10 +27,10 @@ export const MapContextProviderWithLimits: FC<{ // need to make a plain object out of viewport, and then assign the missing fields const plainViewport = Object.fromEntries(Object.entries(baseContext.viewport ?? {})); - const viewport: any = Object.assign(plainViewport, viewLimits); + const viewport: any = { ...plainViewport, ...viewLimits }; const extendedContext = useMemo( - () => ({ ..._.omit(baseContext, 'viewport'), viewport }), + () => ({ ...omit(baseContext, 'viewport'), viewport }), [baseContext, viewport], ); return {children}; diff --git a/frontend/src/lib/data-map/interactions/interaction-state.ts b/frontend/src/lib/data-map/interactions/interaction-state.ts index 713d8f23..f1d4cb4a 100644 --- a/frontend/src/lib/data-map/interactions/interaction-state.ts +++ b/frontend/src/lib/data-map/interactions/interaction-state.ts @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import forEach from 'lodash/forEach'; import { atom, atomFamily, selector } from 'recoil'; import { isReset } from 'lib/recoil/is-reset'; @@ -55,7 +55,7 @@ export const allowedGroupLayersState = selector({ set: ({ get, set, reset }, newAllowedGroups) => { const oldAllowedGroupLayers = get(allowedGroupLayersImpl); if (isReset(newAllowedGroups)) { - _.forEach(oldAllowedGroupLayers, (layers, group) => { + forEach(oldAllowedGroupLayers, (layers, group) => { reset(hoverState(group)); reset(selectionState(group)); }); diff --git a/frontend/src/lib/data-map/interactions/use-interactions.ts b/frontend/src/lib/data-map/interactions/use-interactions.ts index cfdb3b6a..88a6f99a 100644 --- a/frontend/src/lib/data-map/interactions/use-interactions.ts +++ b/frontend/src/lib/data-map/interactions/use-interactions.ts @@ -1,6 +1,9 @@ import DeckGL, { Deck, PickInfo } from 'deck.gl'; import { readPixelsToArray } from '@luma.gl/core'; -import _ from 'lodash'; +import keyBy from 'lodash/keyBy'; +import filter from 'lodash/filter'; +import groupBy from 'lodash/groupBy'; +import mapValues from 'lodash/mapValues'; import { useCallback, useEffect, useMemo } from 'react'; import { useRecoilCallback, useSetRecoilState } from 'recoil'; @@ -115,7 +118,7 @@ export function useInteractions( const setInteractionGroupSelection = useSetInteractionGroupState(selectionState); const interactionGroupLookup = useMemo( - () => _.keyBy(interactionGroups, 'id'), + () => keyBy(interactionGroups, 'id'), [interactionGroups], ); @@ -127,11 +130,11 @@ export function useInteractions( [viewLayers], ); const viewLayerLookup = useMemo( - () => _.keyBy(interactiveLayers, (layer) => layer.id), + () => keyBy(interactiveLayers, (layer) => layer.id), [interactiveLayers], ); const activeGroups = useMemo( - () => _.groupBy(interactiveLayers, (viewLayer) => viewLayer.interactionGroup), + () => groupBy(interactiveLayers, (viewLayer) => viewLayer.interactionGroup), [interactiveLayers], ); @@ -139,7 +142,7 @@ export function useInteractions( useEffect(() => { setAllowedGroupLayers( - _.mapValues(activeGroups, (viewLayers) => viewLayers.map((viewLayer) => viewLayer.id)), + mapValues(activeGroups, (viewLayers) => viewLayers.map((viewLayer) => viewLayer.id)), ); }, [activeGroups, setAllowedGroupLayers]); @@ -218,7 +221,7 @@ export function useInteractions( const hoverPassGroups = useMemo( () => new Set( - _.filter( + filter( interactionGroups, (group) => group.id === primaryGroup || group.usesAutoHighlight, ).map((group) => group.id), diff --git a/frontend/src/lib/data-map/view-layers.ts b/frontend/src/lib/data-map/view-layers.ts index 73f51da2..0aa98308 100644 --- a/frontend/src/lib/data-map/view-layers.ts +++ b/frontend/src/lib/data-map/view-layers.ts @@ -34,23 +34,23 @@ export interface ViewLayerFunctionOptions { } export interface DataManager { - getDataAccessor: (layer: string, fieldSpec: any) => (d: any) => any; - getDataLoader: (layer: string, fieldSpec: any) => DataLoader; + getDataAccessor: (layer: string, fieldSpec: FieldSpec) => Accessor; + getDataLoader: (layer: string, fieldSpec: FieldSpec) => DataLoader; } -export interface FormatConfig { +export interface FormatConfig { getDataLabel: (fieldSpec: FieldSpec) => string; getValueFormatted: (value: D, fieldSpec: FieldSpec) => string; } -export type ViewLayerDataAccessFunction = (fieldSpec: FieldSpec) => Accessor; +export type ViewLayerDataAccessFunction = (fieldSpec: FieldSpec) => Accessor; export type ViewLayerDataFormatFunction = (fieldSpec: FieldSpec) => FormatConfig; export interface ViewLayer { id: string; params?: any; styleParams?: StyleParams; group: string; - fn: (options: ViewLayerFunctionOptions) => any; + fn: (options: ViewLayerFunctionOptions) => unknown; dataAccessFn?: ViewLayerDataAccessFunction; dataFormatsFn?: ViewLayerDataFormatFunction; legendDataFormatsFn?: ViewLayerDataFormatFunction; diff --git a/frontend/src/lib/deck/props/color-map.ts b/frontend/src/lib/deck/props/color-map.ts index d8440f48..a2ce4057 100644 --- a/frontend/src/lib/deck/props/color-map.ts +++ b/frontend/src/lib/deck/props/color-map.ts @@ -1,8 +1,8 @@ import { colorCssToRgb } from 'lib/helpers'; -import _ from 'lodash'; +import memoize from 'lodash/memoize'; import { Accessor, mergeTriggers, withTriggers } from './getters'; -const memoizedColorCssToRgb = _.memoize(colorCssToRgb); +const memoizedColorCssToRgb = memoize(colorCssToRgb); export function dataColorMap(dataSource: Accessor, colorSource: Accessor) { return withTriggers( diff --git a/frontend/src/lib/deck/props/data-source.ts b/frontend/src/lib/deck/props/data-source.ts index 5fbf0143..a77e7363 100644 --- a/frontend/src/lib/deck/props/data-source.ts +++ b/frontend/src/lib/deck/props/data-source.ts @@ -1,11 +1,11 @@ -import _ from 'lodash'; +import memoize from 'lodash/memoize'; import { MapboxGeoJSONFeature } from 'mapbox-gl'; import { DataLoader } from 'lib/data-loader/data-loader'; import { Accessor, withLoaderTriggers, withTriggers } from './getters'; -export const featureProperty = _.memoize( +export const featureProperty = memoize( (field: string | Accessor): Accessor => { return typeof field === 'string' ? withTriggers((f) => f.properties[field], [field]) : field; }, diff --git a/frontend/src/lib/helpers.ts b/frontend/src/lib/helpers.ts index dd1e618e..c55c63f2 100644 --- a/frontend/src/lib/helpers.ts +++ b/frontend/src/lib/helpers.ts @@ -1,5 +1,6 @@ import * as d3 from 'd3-color'; -import _ from 'lodash'; +import mapValues from 'lodash/mapValues'; +import fromPairs from 'lodash/fromPairs'; /** * Common helper functions @@ -73,7 +74,7 @@ export function makeConfig(cfg: (C & { id: K })[]) { } export function makeColorConfig(cfg: Record) { - return _.mapValues(cfg, (c) => ({ css: c, deck: colorCssToRgb(c) })); + return mapValues(cfg, (c) => ({ css: c, deck: colorCssToRgb(c) })); } // see discussion at https://stackoverflow.com/questions/23437476/in-typescript-how-to-check-if-a-string-is-numeric @@ -86,7 +87,7 @@ export function truthyKeys(obj: Record) { } export function fromKeys(keys: K[], values: T): Record { - return _.fromPairs(keys.map((key) => [key, values])) as Record; + return fromPairs(keys.map((key) => [key, values])) as Record; } /** diff --git a/frontend/src/lib/react/with-props.tsx b/frontend/src/lib/react/with-props.tsx index b685b9b0..62811b29 100644 --- a/frontend/src/lib/react/with-props.tsx +++ b/frontend/src/lib/react/with-props.tsx @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import merge from 'lodash/merge'; import { ComponentType, FC, memo } from 'react'; /** @@ -16,7 +16,7 @@ export function withProps>( displayName: string = 'WithProps', ): FC & Partial> { const WithProps: FC & Partial> = memo((props) => { - const mergedProps = _.merge({}, applyProps, props); + const mergedProps = merge({}, applyProps, props); return ; }); diff --git a/frontend/src/lib/recoil/grouped-family.ts b/frontend/src/lib/recoil/grouped-family.ts index e7eed143..01b3b627 100644 --- a/frontend/src/lib/recoil/grouped-family.ts +++ b/frontend/src/lib/recoil/grouped-family.ts @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import fromPairs from 'lodash/fromPairs'; import { selectorFamily, waitForAll } from 'recoil'; import { RecoilReadableStateFamily } from './types'; @@ -14,7 +14,7 @@ export function groupedFamily( (group) => ({ get }) => { const groupParams = get(paramsFamily(group)); - const deps = _.fromPairs( + const deps = fromPairs( groupParams.map((param) => [param, family(paramFn(group, param))]), ); return get(waitForAll(deps)); diff --git a/frontend/src/map/tooltip/content/SolutionHoverDescription.tsx b/frontend/src/map/tooltip/content/SolutionHoverDescription.tsx index af5728ec..d1bc6db5 100644 --- a/frontend/src/map/tooltip/content/SolutionHoverDescription.tsx +++ b/frontend/src/map/tooltip/content/SolutionHoverDescription.tsx @@ -3,7 +3,7 @@ import { VECTOR_COLOR_MAPS } from 'config/color-maps'; import { MARINE_HABITATS_LOOKUP } from 'config/solutions/domains'; import { DataItem } from 'details/features/detail-components'; import { InteractionTarget, VectorTarget } from 'lib/data-map/interactions/use-interactions'; -import _ from 'lodash'; +import startCase from 'lodash/startCase'; import { FC } from 'react'; import { habitatColorMap } from 'state/layers/marine'; import { landuseColorMap } from 'state/layers/terrestrial'; @@ -30,7 +30,7 @@ export const SolutionHoverDescription: FC<{ return ( <> - {_.startCase(viewLayer.id)} + {startCase(viewLayer.id)} {viewLayer.id === 'terrestrial' && ( <> diff --git a/frontend/src/map/use-background-config.ts b/frontend/src/map/use-background-config.ts index 04129b38..2b2e19f0 100644 --- a/frontend/src/map/use-background-config.ts +++ b/frontend/src/map/use-background-config.ts @@ -1,4 +1,5 @@ -import _ from 'lodash'; +import mapValues from 'lodash/mapValues'; +import merge from 'lodash/merge'; import { useMemo } from 'react'; import { BACKGROUNDS, BackgroundName } from 'config/backgrounds'; @@ -10,9 +11,9 @@ function visible(isVisible: boolean): 'visible' | 'none' { function makeBackgroundConfig(background: BackgroundName) { return { version: 8, - sources: _.mapValues(BACKGROUNDS, (b) => b.source), + sources: mapValues(BACKGROUNDS, (b) => b.source), layers: Object.values(BACKGROUNDS).map((b) => - _.merge(b.layer, { layout: { visibility: visible(background === b.id) } }), + merge(b.layer, { layout: { visibility: visible(background === b.id) } }), ), }; } diff --git a/frontend/src/sidebar/networks/AdaptationControl.tsx b/frontend/src/sidebar/networks/AdaptationControl.tsx index 23451dd7..be160469 100644 --- a/frontend/src/sidebar/networks/AdaptationControl.tsx +++ b/frontend/src/sidebar/networks/AdaptationControl.tsx @@ -1,4 +1,5 @@ -import _ from 'lodash'; +import startCase from 'lodash/startCase'; +import lowerCase from 'lodash/lowerCase'; import { FormLabel, Slider, Typography } from '@mui/material'; import { CustomNumberSlider } from 'lib/controls/CustomSlider'; import { ParamDropdown } from 'lib/controls/ParamDropdown'; @@ -29,7 +30,7 @@ function hazardLabel(val) { } function autoLabel(x) { - return _.startCase(_.lowerCase(x)); + return startCase(lowerCase(x)); } function makeOptions(values, labelFn = (x) => x) { diff --git a/frontend/src/state/damage-mapping/damage-map.ts b/frontend/src/state/damage-mapping/damage-map.ts index 67c0ec0d..3786543d 100644 --- a/frontend/src/state/damage-mapping/damage-map.ts +++ b/frontend/src/state/damage-mapping/damage-map.ts @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import forEach from 'lodash/forEach'; import { atom, selector } from 'recoil'; import { HAZARD_DOMAINS } from 'config/hazards/domains'; @@ -37,7 +37,7 @@ export const damageSourceStateEffect = ({ get, set }, damageSource) => { }; function syncHazardsWithDamageSourceStateEffect({ set }, damageSource) { - _.forEach(HAZARD_DOMAINS, (groupConfig, group) => { + forEach(HAZARD_DOMAINS, (groupConfig, group) => { set(hazardSelectionState(group), group === damageSource); }); } diff --git a/frontend/src/state/data-params.ts b/frontend/src/state/data-params.ts index 1821731d..a7fafc4c 100644 --- a/frontend/src/state/data-params.ts +++ b/frontend/src/state/data-params.ts @@ -8,7 +8,9 @@ import { } from 'lib/controls/data-params'; import { toDictionary } from 'lib/helpers'; import { groupedFamily } from 'lib/recoil/grouped-family'; -import _ from 'lodash'; +import forEach from 'lodash/forEach'; +import mapValues from 'lodash/mapValues'; +import keys from 'lodash/keys'; import { atomFamily, useRecoilTransaction_UNSTABLE } from 'recoil'; import { adaptationDomainsConfig } from 'config/domains/adaptation'; @@ -23,11 +25,11 @@ export const dataParamConfig: Record = { adaptation: adaptationDomainsConfig, }; -export const dataParamNamesByGroup = _.mapValues(dataParamConfig, (groupConfig) => - _.keys(groupConfig.paramDefaults), +export const dataParamNamesByGroup = mapValues(dataParamConfig, (groupConfig) => + keys(groupConfig.paramDefaults), ); -const dataParamDefaultsByGroup = _.mapValues(dataParamConfig, (groupConfig) => +const dataParamDefaultsByGroup = mapValues(dataParamConfig, (groupConfig) => resolveParamDependencies(groupConfig.paramDefaults, groupConfig), ); @@ -77,7 +79,7 @@ export function useUpdateDataParam(group: string, paramId: string) { groupConfig, ); - _.forEach(resolvedParams, (resolvedParamValue, paramId) => { + forEach(resolvedParams, (resolvedParamValue, paramId) => { const recoilParam = { group, param: paramId }; set(dataParamState(recoilParam), resolvedParamValue); set(dataParamOptionsState(recoilParam), resolvedOptions[paramId]); diff --git a/frontend/src/state/hazards/hazard-selection.ts b/frontend/src/state/hazards/hazard-selection.ts index ede3cb91..eeb2b45e 100644 --- a/frontend/src/state/hazards/hazard-selection.ts +++ b/frontend/src/state/hazards/hazard-selection.ts @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import fromPairs from 'lodash/fromPairs'; import { atomFamily, RecoilValue } from 'recoil'; export const hazardSelectionState = atomFamily({ @@ -14,5 +14,5 @@ export function getHazardSelectionAggregate( { get }: TransactionGetterInterface, hazards: string[], ) { - return _.fromPairs(hazards.map((group) => [group, get(hazardSelectionState(group))])); + return fromPairs(hazards.map((group) => [group, get(hazardSelectionState(group))])); } diff --git a/frontend/src/state/layers/networks.ts b/frontend/src/state/layers/networks.ts index 88a29e81..b1f31396 100644 --- a/frontend/src/state/layers/networks.ts +++ b/frontend/src/state/layers/networks.ts @@ -15,7 +15,9 @@ import { networksStyleState } from 'state/networks/networks-style'; import { sectionVisibilityState } from 'state/sections'; import adaptationSectorLayers from 'config/domains/adaptation-sector-layers.json'; -import _ from 'lodash'; +import uniq from 'lodash/uniq'; +import fromPairs from 'lodash/fromPairs'; +import mapValues from 'lodash/mapValues'; import { recalculateCheckboxStates } from 'lib/controls/checkbox-tree/CheckboxTree'; import { LayerSpec } from 'asset-list/use-sorted-features'; @@ -50,7 +52,7 @@ export const adaptationDataParamsStateEffect: StateEffect { const { sector, subsector, asset_type } = adaptationParams; - const layers = _.uniq( + const layers = uniq( adaptationSectorLayers .filter( (x) => x.sector === sector && x.subsector === subsector && x.asset_type === asset_type, @@ -61,8 +63,8 @@ export const adaptationDataParamsStateEffect: StateEffect false), - ..._.fromPairs(layers.map((layer) => [layer, true])), + ...mapValues(currentSelection.checked, () => false), + ...fromPairs(layers.map((layer) => [layer, true])), }, indeterminate: {}, }; diff --git a/frontend/src/state/networks/network-selection.ts b/frontend/src/state/networks/network-selection.ts index 802d52c7..0d275742 100644 --- a/frontend/src/state/networks/network-selection.ts +++ b/frontend/src/state/networks/network-selection.ts @@ -1,6 +1,6 @@ import { NETWORK_LAYERS_HIERARCHY } from 'config/networks/hierarchy'; import { buildTreeConfig, CheckboxTreeState } from 'lib/controls/checkbox-tree/CheckboxTree'; -import _ from 'lodash'; +import mapValues from 'lodash/mapValues'; import { atom, selector } from 'recoil'; export const networkTreeExpandedState = atom({ @@ -13,8 +13,8 @@ export const networkTreeConfig = buildTreeConfig(NETWORK_LAYERS_HIERARCHY); export const networkTreeCheckboxState = atom({ key: 'networkTreeSelectionState', default: { - checked: _.mapValues(networkTreeConfig.nodes, () => false), - indeterminate: _.mapValues(networkTreeConfig.nodes, () => false), + checked: mapValues(networkTreeConfig.nodes, () => false), + indeterminate: mapValues(networkTreeConfig.nodes, () => false), }, }); diff --git a/frontend/src/state/solutions/landuse-tree.ts b/frontend/src/state/solutions/landuse-tree.ts index 301d8860..a282ba8c 100644 --- a/frontend/src/state/solutions/landuse-tree.ts +++ b/frontend/src/state/solutions/landuse-tree.ts @@ -1,7 +1,8 @@ import { LANDUSE_HIERARCHY } from 'config/solutions/landuse-hierarchy'; import { LandUseOption } from 'config/solutions/domains'; import { buildTreeConfig, CheckboxTreeState } from 'lib/controls/checkbox-tree/CheckboxTree'; -import _ from 'lodash'; +import mapValues from 'lodash/mapValues'; +import pickBy from 'lodash/pickBy'; import { atom, selector } from 'recoil'; export const landuseTreeExpandedState = atom({ @@ -14,8 +15,8 @@ export const landuseTreeConfig = buildTreeConfig(LANDUSE_HIERARCHY); export const landuseTreeCheckboxState = atom({ key: 'landuseTreeCheckboxState', default: { - checked: _.mapValues(landuseTreeConfig.nodes, () => true), - indeterminate: _.mapValues(landuseTreeConfig.nodes, () => false), + checked: mapValues(landuseTreeConfig.nodes, () => true), + indeterminate: mapValues(landuseTreeConfig.nodes, () => false), }, }); @@ -24,7 +25,7 @@ export const landuseFilterState = selector>({ get: ({ get }) => { const checkboxState = get(landuseTreeCheckboxState).checked; - return _.pickBy(checkboxState, (value, id) => !landuseTreeConfig.nodes[id].children) as Record< + return pickBy(checkboxState, (value, id) => !landuseTreeConfig.nodes[id].children) as Record< LandUseOption, boolean >; diff --git a/frontend/src/state/view.ts b/frontend/src/state/view.ts index 66f5838f..521a24f5 100644 --- a/frontend/src/state/view.ts +++ b/frontend/src/state/view.ts @@ -1,4 +1,6 @@ -import _ from 'lodash'; +import difference from 'lodash/difference'; +import forEach from 'lodash/forEach'; +import keys from 'lodash/keys'; import { atom } from 'recoil'; import { StateEffect } from 'lib/recoil/state-effects/types'; @@ -21,16 +23,16 @@ export const viewStateEffect: StateEffect = ({ set }, view, previousView const viewSectionsConfig = VIEW_SECTIONS[view]; const previousViewSectionsConfig = VIEW_SECTIONS[previousView]; - const removedSections = _.difference( - _.keys(previousViewSectionsConfig), - _.keys(viewSectionsConfig), + const removedSections = difference( + keys(previousViewSectionsConfig), + keys(viewSectionsConfig), ); removedSections.forEach((section) => { set(sectionVisibilityState(section), false); }); - _.forEach(viewSectionsConfig, (sectionConfig, section) => { + forEach(viewSectionsConfig, (sectionConfig, section) => { set(sectionVisibilityState(section), sectionConfig.visible); set(sidebarSectionExpandedState(section), sectionConfig.expanded); const styleOptions = sectionConfig.styles?.map(