Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 7 additions & 21 deletions packages/core/components/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import './data-table.css'
import _ from 'lodash'
import { getDataSeriesColumns } from './helpers/getDataSeriesColumns'
import { getMapDataTableColumnKeys } from './helpers/getMapDataTableColumnKeys'
import { addOptionalFullGeoNameColumn } from './helpers/addOptionalFullGeoNameColumn'

export type DataTableProps = {
colorScale?: Function
Expand Down Expand Up @@ -327,27 +328,12 @@ const DataTable = (props: DataTableProps) => {
return newRow
})

// only use fullGeoName on County maps and no other
if (config.general?.geoType === 'us-county' || config.table.showFullGeoNameInCSV) {
// Add column for full Geo name along with State
return csvDataUpdated.map((row, index) => {
const originalRow = csvData[index]
if (!originalRow) {
console.warn('Data mismatch: originalRow missing.', {
index,
csvDataLength: csvData.length,
csvDataUpdatedLength: csvDataUpdated.length
})
return row
}
return {
FullGeoName: formatLegendLocation(originalRow[config.columns.geo.name]),
...row
}
})
} else {
return csvDataUpdated
}
return addOptionalFullGeoNameColumn({
config,
csvData,
csvDataUpdated,
formatLegendLocation
})
}

const getMediaControlsClasses = (belowTable, hasDownloadLink) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
type AddOptionalFullGeoNameColumnArgs = {
config: any
csvData: Record<string, any>[]
csvDataUpdated: Record<string, any>[]
formatLegendLocation?: (key: string) => string
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formatLegendLocation type here is (key: string) => string, but DataTableProps.formatLegendLocation is typed as (row: string, runtimeLookup: string) => string. To keep types consistent and avoid subtle TS assignability issues, consider reusing the prop type (e.g., DataTableProps['formatLegendLocation']) or updating this signature to accept the optional second parameter.

Suggested change
formatLegendLocation?: (key: string) => string
formatLegendLocation?: (key: string, runtimeLookup?: string) => string

Copilot uses AI. Check for mistakes.
}

export const addOptionalFullGeoNameColumn = ({
config,
csvData,
csvDataUpdated,
formatLegendLocation
}: AddOptionalFullGeoNameColumnArgs) => {
if (!config?.table?.showFullGeoNameInCSV || typeof formatLegendLocation !== 'function') {
return csvDataUpdated
}

return csvDataUpdated.map((row, index) => {
const originalRow = csvData[index]
if (!originalRow) {
console.warn('Data mismatch: originalRow missing.', {
index,
csvDataLength: csvData.length,
csvDataUpdatedLength: csvDataUpdated.length
})
return row
}

return {
FullGeoName: formatLegendLocation(originalRow[config.columns.geo.name]),
...row
Comment on lines +14 to +31
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addOptionalFullGeoNameColumn can throw if config.columns, config.columns.geo, or config.columns.geo.name is missing while table.showFullGeoNameInCSV is true (e.g., partially-migrated/hand-edited configs). Consider defensively checking for the geo column name (and the corresponding value on originalRow) and returning csvDataUpdated/row when unavailable to avoid runtime crashes during CSV export.

Copilot uses AI. Check for mistakes.
}
})
}

export default addOptionalFullGeoNameColumn
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { describe, expect, it, vi } from 'vitest'
import { addOptionalFullGeoNameColumn } from '../addOptionalFullGeoNameColumn'

describe('addOptionalFullGeoNameColumn', () => {
const csvData = [{ geo: '01001', value: 1 }]
const csvDataUpdated = [{ Geo: '01001', Value: 1 }]
const formatLegendLocation = vi.fn((key: string) => `AL, ${key}`)

it('does not add FullGeoName for county maps when the toggle is off', () => {
const result = addOptionalFullGeoNameColumn({
config: {
general: { geoType: 'us-county' },
table: { showFullGeoNameInCSV: false },
columns: { geo: { name: 'geo' } }
},
csvData,
csvDataUpdated,
formatLegendLocation
})

expect(result).toEqual(csvDataUpdated)
expect(result[0]).not.toHaveProperty('FullGeoName')
})

it('adds FullGeoName for county maps when the toggle is on', () => {
const result = addOptionalFullGeoNameColumn({
config: {
general: { geoType: 'us-county' },
table: { showFullGeoNameInCSV: true },
columns: { geo: { name: 'geo' } }
},
csvData,
csvDataUpdated,
formatLegendLocation
})

expect(result).toEqual([{ FullGeoName: 'AL, 01001', Geo: '01001', Value: 1 }])
})

it('does not add FullGeoName for non-county maps when the toggle is off', () => {
const result = addOptionalFullGeoNameColumn({
config: {
general: { geoType: 'us' },
table: { showFullGeoNameInCSV: false },
columns: { geo: { name: 'geo' } }
},
csvData,
csvDataUpdated,
formatLegendLocation
})

expect(result).toEqual(csvDataUpdated)
})

it('adds FullGeoName for non-county maps when the toggle is on', () => {
const result = addOptionalFullGeoNameColumn({
config: {
general: { geoType: 'us' },
table: { showFullGeoNameInCSV: true },
columns: { geo: { name: 'geo' } }
},
csvData,
csvDataUpdated,
formatLegendLocation
})

expect(result).toEqual([{ FullGeoName: 'AL, 01001', Geo: '01001', Value: 1 }])
})
})
8 changes: 8 additions & 0 deletions packages/core/helpers/ver/4.26.4.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,19 @@ const applyMarkupVariableSourceTypes = config => {
})
}

const enableFullGeoNameCsvOnLegacyCountyMaps = config => {
if (config.type === 'map' && config.general?.geoType === 'us-county') {
config.table = config.table || {}
config.table.showFullGeoNameInCSV = true
}
}

const run_4_26_4_migrations = config => {
disableExtraChartVisualSettings(config)
addMarkupIncludeStyle(config)
applyWaffleValueDescriptorDefaults(config)
applyMarkupVariableSourceTypes(config)
enableFullGeoNameCsvOnLegacyCountyMaps(config)

if (config.type === 'dashboard' && config.visualizations) {
Object.values((config as DashboardConfig).visualizations).forEach(visualization => {
Expand Down
52 changes: 52 additions & 0 deletions packages/core/helpers/ver/tests/4.26.4.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,4 +377,56 @@ describe('update_4_26_4', () => {
expect(result.visualizations.nestedChart.markupVariables[0].sourceType).toBe('column')
expect(result.visualizations.nestedChart.markupVariables[1].sourceType).toBe('metadata')
})

it('enables full geo name CSV export for legacy county maps', () => {
const config: any = {
type: 'map',
version: '4.26.3',
general: { geoType: 'us-county' },
table: { showFullGeoNameInCSV: false }
}

const result = update_4_26_4(config)

expect(result.table.showFullGeoNameInCSV).toBe(true)
expect(result.version).toBe('4.26.4')
expect(config.table.showFullGeoNameInCSV).toBe(false)
})

it('does not change non-county map CSV full geo name settings', () => {
const config: any = {
type: 'map',
version: '4.26.3',
general: { geoType: 'us' },
table: { showFullGeoNameInCSV: false }
}

const result = update_4_26_4(config)

expect(result.table.showFullGeoNameInCSV).toBe(false)
})

it('enables full geo name CSV export for county maps inside dashboards', () => {
const config: any = {
type: 'dashboard',
version: '4.26.3',
visualizations: {
countyMap: {
type: 'map',
general: { geoType: 'us-county' },
table: { showFullGeoNameInCSV: false }
},
usMap: {
type: 'map',
general: { geoType: 'us' },
table: { showFullGeoNameInCSV: false }
}
}
}

const result = update_4_26_4(config)

expect(result.visualizations.countyMap.table.showFullGeoNameInCSV).toBe(true)
expect(result.visualizations.usMap.table.showFullGeoNameInCSV).toBe(false)
})
})
Loading