From 16afc8004f0dee15247c5563224444378c005733 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 15:55:23 +0000 Subject: [PATCH 1/9] Initial plan From e2c504bd79b621093102d5910d1e709518ca9e04 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:12:50 +0000 Subject: [PATCH 2/9] fix: add lazy AG Charts module loading via dashEnableCharts Agent-Logs-Url: https://github.com/plotly/dash-ag-grid/sessions/52b7100d-a8cf-4090-a27d-31f1888b72dd Co-authored-by: BSd3v <82055130+BSd3v@users.noreply.github.com> --- dash_ag_grid/__init__.py | 12 ++++ src/lib/LazyLoader.js | 4 ++ src/lib/components/AgGrid.react.js | 58 ++++++++++++++-- src/lib/fragments/AgGridCharts.react.js | 30 ++++++++ src/lib/fragments/AgGridEnterprise.react.js | 11 ++- src/lib/utils/propCategories.js | 1 + tests/test_charts.py | 77 +++++++++++++++++++++ 7 files changed, 188 insertions(+), 5 deletions(-) create mode 100644 src/lib/fragments/AgGridCharts.react.js create mode 100644 tests/test_charts.py diff --git a/dash_ag_grid/__init__.py b/dash_ag_grid/__init__.py index d2eda1b6..0f546c5c 100644 --- a/dash_ag_grid/__init__.py +++ b/dash_ag_grid/__init__.py @@ -52,6 +52,18 @@ 'external_url': f'{_unpkg}async-community.js.map', 'dynamic': True }, + { + 'relative_package_path': 'async-community-charts.js', + 'namespace': package_name, + 'external_url': f'{_unpkg}async-community-charts.js', + 'async': True + }, + { + 'relative_package_path': 'async-community-charts.js.map', + 'namespace': package_name, + 'external_url': f'{_unpkg}async-community-charts.js.map', + 'dynamic': True + }, { 'relative_package_path': 'async-enterprise.js', 'namespace': package_name, diff --git a/src/lib/LazyLoader.js b/src/lib/LazyLoader.js index 31953bf2..50560b65 100644 --- a/src/lib/LazyLoader.js +++ b/src/lib/LazyLoader.js @@ -1,6 +1,10 @@ export default { agGrid: () => import(/* webpackChunkName: "community" */ './fragments/AgGrid.react'), + agGridCharts: () => + import( + /* webpackChunkName: "community-charts" */ './fragments/AgGridCharts.react' + ), agGridEnterprise: () => import( /* webpackChunkName: "enterprise" */ './fragments/AgGridEnterprise.react' diff --git a/src/lib/components/AgGrid.react.js b/src/lib/components/AgGrid.react.js index ce2e1c3a..4ebaff72 100644 --- a/src/lib/components/AgGrid.react.js +++ b/src/lib/components/AgGrid.react.js @@ -8,10 +8,20 @@ import {pick} from 'ramda'; ModuleRegistry.registerModules([AllCommunityModule]); const RealAgGrid = lazy(LazyLoader.agGrid); +const RealAgGridCharts = lazy(LazyLoader.agGridCharts); const RealAgGridEnterprise = lazy(LazyLoader.agGridEnterprise); -function getGrid(enable) { - return enable ? RealAgGridEnterprise : RealAgGrid; +function getGrid(enableEnterpriseModules, dashEnableCharts) { + const chartsEnabled = + dashEnableCharts === true || + dashEnableCharts === 'community' || + dashEnableCharts === 'enterprise'; + + if (enableEnterpriseModules) { + return RealAgGridEnterprise; + } + + return chartsEnabled ? RealAgGridCharts : RealAgGrid; } export const defaultProps = { @@ -21,6 +31,7 @@ export const defaultProps = { selectAll: false, deselectAll: false, enableEnterpriseModules: false, + dashEnableCharts: false, updateColumnState: false, persisted_props: ['selectedRows'], persistence_type: 'local', @@ -64,8 +75,38 @@ function DashAgGrid(props) { } }, [props.rowTransaction, state.mounted, buildArray]); - const {enableEnterpriseModules} = props; - const RealComponent = getGrid(enableEnterpriseModules); + const { + enableEnterpriseModules, + dashEnableCharts, + dashGridOptions = {}, + } = props; + const normalizedDashEnableCharts = + typeof dashEnableCharts === 'undefined' || dashEnableCharts === null + ? false + : dashEnableCharts; + const hasEnableCharts = props.enableCharts || dashGridOptions.enableCharts; + const validDashEnableCharts = + normalizedDashEnableCharts === false || + normalizedDashEnableCharts === true || + normalizedDashEnableCharts === 'community' || + normalizedDashEnableCharts === 'enterprise'; + + if (!validDashEnableCharts) { + throw new Error( + "dashEnableCharts must be one of: false, true, 'community', 'enterprise'." + ); + } + + if (hasEnableCharts && !normalizedDashEnableCharts) { + throw new Error( + "enableCharts is set, but chart modules are not loaded. Set dashEnableCharts to true, 'community', or 'enterprise'." + ); + } + + const RealComponent = getGrid( + enableEnterpriseModules, + normalizedDashEnableCharts + ); return ( @@ -499,6 +540,15 @@ DashAgGrid.propTypes = { */ enableEnterpriseModules: PropTypes.bool, + /** + * Load AG Charts modules for integrated charts when using `enableCharts`. + * Set to true (community charts), "community", or "enterprise". + */ + dashEnableCharts: PropTypes.oneOfType([ + PropTypes.bool, + PropTypes.oneOf(['community', 'enterprise']), + ]), + /** * The rowData in the grid after inline filters are applied. */ diff --git a/src/lib/fragments/AgGridCharts.react.js b/src/lib/fragments/AgGridCharts.react.js new file mode 100644 index 00000000..59561448 --- /dev/null +++ b/src/lib/fragments/AgGridCharts.react.js @@ -0,0 +1,30 @@ +import React from 'react'; +import {ModuleRegistry} from 'ag-grid-community'; +import {IntegratedChartsModule} from 'ag-grid-enterprise'; +import {AgChartsCommunityModule} from 'ag-charts-community'; +import {AgChartsEnterpriseModule} from 'ag-charts-enterprise'; +import MemoizedAgGrid, {propTypes} from './AgGrid.react'; + +const registeredChartModules = new Set(); +const chartsModules = { + community: AgChartsCommunityModule, + enterprise: AgChartsEnterpriseModule, +}; + +function registerChartsModule(mode) { + if (!registeredChartModules.has(mode)) { + ModuleRegistry.registerModules([ + IntegratedChartsModule.with(chartsModules[mode]), + ]); + registeredChartModules.add(mode); + } +} + +export default function DashAgGridCharts(props) { + const mode = + props.dashEnableCharts === 'enterprise' ? 'enterprise' : 'community'; + registerChartsModule(mode); + return ; +} + +DashAgGridCharts.propTypes = propTypes; diff --git a/src/lib/fragments/AgGridEnterprise.react.js b/src/lib/fragments/AgGridEnterprise.react.js index fa847e63..0e111fe5 100644 --- a/src/lib/fragments/AgGridEnterprise.react.js +++ b/src/lib/fragments/AgGridEnterprise.react.js @@ -2,6 +2,7 @@ import React from 'react'; import {ModuleRegistry} from 'ag-grid-community'; import { AllEnterpriseModule, + IntegratedChartsModule, LicenseManager, SparklinesModule, } from 'ag-grid-enterprise'; @@ -14,11 +15,19 @@ ModuleRegistry.registerModules([ SparklinesModule.with(AgChartsEnterpriseModule), ]); +let chartsModuleRegistered = false; + export default function DashAgGridEnterprise(props) { - const {licenseKey} = props; + const {licenseKey, dashEnableCharts} = props; if (licenseKey) { LicenseManager.setLicenseKey(licenseKey); } + if (dashEnableCharts && !chartsModuleRegistered) { + ModuleRegistry.registerModules([ + IntegratedChartsModule.with(AgChartsEnterpriseModule), + ]); + chartsModuleRegistered = true; + } return ; } diff --git a/src/lib/utils/propCategories.js b/src/lib/utils/propCategories.js index 74f0e781..4a7c9909 100644 --- a/src/lib/utils/propCategories.js +++ b/src/lib/utils/propCategories.js @@ -342,6 +342,7 @@ export const PROPS_NOT_FOR_AG_GRID = [ 'setProps', 'loading_state', 'enableEnterpriseModules', + 'dashEnableCharts', 'parentState', 'persistence', 'persisted_props', diff --git a/tests/test_charts.py b/tests/test_charts.py new file mode 100644 index 00000000..8402911b --- /dev/null +++ b/tests/test_charts.py @@ -0,0 +1,77 @@ +import dash_ag_grid as dag +from dash import Dash, html +from . import utils + + +def _make_chart_grid(**extra_props): + return dag.AgGrid( + id="grid", + columnDefs=[{"field": "make"}, {"field": "model"}, {"field": "price"}], + rowData=[ + {"make": "Toyota", "model": "Celica", "price": 35000}, + {"make": "Ford", "model": "Mondeo", "price": 32000}, + {"make": "Porsche", "model": "Boxster", "price": 72000}, + ], + dashGridOptions={"enableCharts": True}, + **extra_props, + ) + + +def _make_basic_grid(**extra_props): + return dag.AgGrid( + id="grid", + columnDefs=[{"field": "make"}, {"field": "model"}, {"field": "price"}], + rowData=[ + {"make": "Toyota", "model": "Celica", "price": 35000}, + {"make": "Ford", "model": "Mondeo", "price": 32000}, + {"make": "Porsche", "model": "Boxster", "price": 72000}, + ], + **extra_props, + ) + + +def test_charts001_enables_community_charts_modules(dash_duo): + app = Dash(__name__) + app.layout = html.Div([_make_chart_grid(dashEnableCharts=True)]) + + dash_duo.start_server(app) + + grid = utils.Grid(dash_duo, "grid") + grid.wait_for_cell_text(0, 0, "Toyota") + + assert not any( + "AG Grid: error #200" in entry.get("message", "") + for entry in dash_duo.get_logs() + ) + + +def test_charts002_enables_enterprise_charts_modules(dash_duo): + app = Dash(__name__) + app.layout = html.Div( + [ + _make_chart_grid( + enableEnterpriseModules=True, + dashEnableCharts="enterprise", + ) + ] + ) + + dash_duo.start_server(app) + + grid = utils.Grid(dash_duo, "grid") + grid.wait_for_cell_text(0, 0, "Toyota") + + assert not any( + "AG Grid: error #200" in entry.get("message", "") + for entry in dash_duo.get_logs() + ) + + +def test_charts003_keeps_enterprise_grid_without_charts(dash_duo): + app = Dash(__name__) + app.layout = html.Div([_make_basic_grid(enableEnterpriseModules=True)]) + + dash_duo.start_server(app) + + grid = utils.Grid(dash_duo, "grid") + grid.wait_for_cell_text(0, 0, "Toyota") From a1b9097f29ecb4ed886437ba24c373830e8c3ee5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:19:47 +0000 Subject: [PATCH 3/9] chore: address review feedback for chart module registration Agent-Logs-Url: https://github.com/plotly/dash-ag-grid/sessions/52b7100d-a8cf-4090-a27d-31f1888b72dd Co-authored-by: BSd3v <82055130+BSd3v@users.noreply.github.com> --- src/lib/components/AgGrid.react.js | 15 ++++++++------- src/lib/fragments/AgGridCharts.react.js | 12 +++++++++++- src/lib/fragments/AgGridEnterprise.react.js | 14 +++++++++++--- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/lib/components/AgGrid.react.js b/src/lib/components/AgGrid.react.js index 4ebaff72..c453eaff 100644 --- a/src/lib/components/AgGrid.react.js +++ b/src/lib/components/AgGrid.react.js @@ -84,12 +84,13 @@ function DashAgGrid(props) { typeof dashEnableCharts === 'undefined' || dashEnableCharts === null ? false : dashEnableCharts; - const hasEnableCharts = props.enableCharts || dashGridOptions.enableCharts; - const validDashEnableCharts = - normalizedDashEnableCharts === false || - normalizedDashEnableCharts === true || - normalizedDashEnableCharts === 'community' || - normalizedDashEnableCharts === 'enterprise'; + const hasEnableCharts = dashGridOptions.enableCharts; + const validDashEnableCharts = [ + false, + true, + 'community', + 'enterprise', + ].includes(normalizedDashEnableCharts); if (!validDashEnableCharts) { throw new Error( @@ -99,7 +100,7 @@ function DashAgGrid(props) { if (hasEnableCharts && !normalizedDashEnableCharts) { throw new Error( - "enableCharts is set, but chart modules are not loaded. Set dashEnableCharts to true, 'community', or 'enterprise'." + "enableCharts is set, but chart modules are not loaded. Set dashEnableCharts to true (same as 'community'), 'community', or 'enterprise'." ); } diff --git a/src/lib/fragments/AgGridCharts.react.js b/src/lib/fragments/AgGridCharts.react.js index 59561448..d129cc21 100644 --- a/src/lib/fragments/AgGridCharts.react.js +++ b/src/lib/fragments/AgGridCharts.react.js @@ -5,13 +5,23 @@ import {AgChartsCommunityModule} from 'ag-charts-community'; import {AgChartsEnterpriseModule} from 'ag-charts-enterprise'; import MemoizedAgGrid, {propTypes} from './AgGrid.react'; -const registeredChartModules = new Set(); const chartsModules = { community: AgChartsCommunityModule, enterprise: AgChartsEnterpriseModule, }; +function getRegisteredChartModules() { + if (typeof window === 'undefined') { + return new Set(); + } + if (!window.dashAgGridRegisteredChartModules) { + window.dashAgGridRegisteredChartModules = new Set(); + } + return window.dashAgGridRegisteredChartModules; +} + function registerChartsModule(mode) { + const registeredChartModules = getRegisteredChartModules(); if (!registeredChartModules.has(mode)) { ModuleRegistry.registerModules([ IntegratedChartsModule.with(chartsModules[mode]), diff --git a/src/lib/fragments/AgGridEnterprise.react.js b/src/lib/fragments/AgGridEnterprise.react.js index 0e111fe5..ebeac1fa 100644 --- a/src/lib/fragments/AgGridEnterprise.react.js +++ b/src/lib/fragments/AgGridEnterprise.react.js @@ -15,18 +15,26 @@ ModuleRegistry.registerModules([ SparklinesModule.with(AgChartsEnterpriseModule), ]); -let chartsModuleRegistered = false; +function shouldRegisterChartsModule() { + if (typeof window === 'undefined') { + return true; + } + if (window.dashAgGridEnterpriseChartsRegistered) { + return false; + } + window.dashAgGridEnterpriseChartsRegistered = true; + return true; +} export default function DashAgGridEnterprise(props) { const {licenseKey, dashEnableCharts} = props; if (licenseKey) { LicenseManager.setLicenseKey(licenseKey); } - if (dashEnableCharts && !chartsModuleRegistered) { + if (dashEnableCharts && shouldRegisterChartsModule()) { ModuleRegistry.registerModules([ IntegratedChartsModule.with(AgChartsEnterpriseModule), ]); - chartsModuleRegistered = true; } return ; } From 94d9b82d394ad2c943d7eb47cb6feefcec883084 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 16:56:00 +0000 Subject: [PATCH 4/9] fix: restrict dashEnableCharts loading to enterprise grids only Agent-Logs-Url: https://github.com/plotly/dash-ag-grid/sessions/b14d1d59-45d4-401b-a5e8-00e870e4eb19 Co-authored-by: BSd3v <82055130+BSd3v@users.noreply.github.com> --- dash_ag_grid/__init__.py | 12 -------- src/lib/LazyLoader.js | 4 --- src/lib/components/AgGrid.react.js | 27 +++++++---------- src/lib/fragments/AgGridCharts.react.js | 40 ------------------------- tests/test_charts.py | 19 ++++++++++-- 5 files changed, 27 insertions(+), 75 deletions(-) delete mode 100644 src/lib/fragments/AgGridCharts.react.js diff --git a/dash_ag_grid/__init__.py b/dash_ag_grid/__init__.py index 0f546c5c..d2eda1b6 100644 --- a/dash_ag_grid/__init__.py +++ b/dash_ag_grid/__init__.py @@ -52,18 +52,6 @@ 'external_url': f'{_unpkg}async-community.js.map', 'dynamic': True }, - { - 'relative_package_path': 'async-community-charts.js', - 'namespace': package_name, - 'external_url': f'{_unpkg}async-community-charts.js', - 'async': True - }, - { - 'relative_package_path': 'async-community-charts.js.map', - 'namespace': package_name, - 'external_url': f'{_unpkg}async-community-charts.js.map', - 'dynamic': True - }, { 'relative_package_path': 'async-enterprise.js', 'namespace': package_name, diff --git a/src/lib/LazyLoader.js b/src/lib/LazyLoader.js index 50560b65..31953bf2 100644 --- a/src/lib/LazyLoader.js +++ b/src/lib/LazyLoader.js @@ -1,10 +1,6 @@ export default { agGrid: () => import(/* webpackChunkName: "community" */ './fragments/AgGrid.react'), - agGridCharts: () => - import( - /* webpackChunkName: "community-charts" */ './fragments/AgGridCharts.react' - ), agGridEnterprise: () => import( /* webpackChunkName: "enterprise" */ './fragments/AgGridEnterprise.react' diff --git a/src/lib/components/AgGrid.react.js b/src/lib/components/AgGrid.react.js index c453eaff..426a7f77 100644 --- a/src/lib/components/AgGrid.react.js +++ b/src/lib/components/AgGrid.react.js @@ -8,20 +8,10 @@ import {pick} from 'ramda'; ModuleRegistry.registerModules([AllCommunityModule]); const RealAgGrid = lazy(LazyLoader.agGrid); -const RealAgGridCharts = lazy(LazyLoader.agGridCharts); const RealAgGridEnterprise = lazy(LazyLoader.agGridEnterprise); -function getGrid(enableEnterpriseModules, dashEnableCharts) { - const chartsEnabled = - dashEnableCharts === true || - dashEnableCharts === 'community' || - dashEnableCharts === 'enterprise'; - - if (enableEnterpriseModules) { - return RealAgGridEnterprise; - } - - return chartsEnabled ? RealAgGridCharts : RealAgGrid; +function getGrid(enableEnterpriseModules) { + return enableEnterpriseModules ? RealAgGridEnterprise : RealAgGrid; } export const defaultProps = { @@ -98,16 +88,19 @@ function DashAgGrid(props) { ); } + if (normalizedDashEnableCharts && !enableEnterpriseModules) { + throw new Error( + 'dashEnableCharts is only supported when enableEnterpriseModules is true.' + ); + } + if (hasEnableCharts && !normalizedDashEnableCharts) { throw new Error( - "enableCharts is set, but chart modules are not loaded. Set dashEnableCharts to true (same as 'community'), 'community', or 'enterprise'." + "enableCharts is set, but chart modules are not loaded. Set enableEnterpriseModules=true and dashEnableCharts=true or 'enterprise'." ); } - const RealComponent = getGrid( - enableEnterpriseModules, - normalizedDashEnableCharts - ); + const RealComponent = getGrid(enableEnterpriseModules); return ( diff --git a/src/lib/fragments/AgGridCharts.react.js b/src/lib/fragments/AgGridCharts.react.js deleted file mode 100644 index d129cc21..00000000 --- a/src/lib/fragments/AgGridCharts.react.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; -import {ModuleRegistry} from 'ag-grid-community'; -import {IntegratedChartsModule} from 'ag-grid-enterprise'; -import {AgChartsCommunityModule} from 'ag-charts-community'; -import {AgChartsEnterpriseModule} from 'ag-charts-enterprise'; -import MemoizedAgGrid, {propTypes} from './AgGrid.react'; - -const chartsModules = { - community: AgChartsCommunityModule, - enterprise: AgChartsEnterpriseModule, -}; - -function getRegisteredChartModules() { - if (typeof window === 'undefined') { - return new Set(); - } - if (!window.dashAgGridRegisteredChartModules) { - window.dashAgGridRegisteredChartModules = new Set(); - } - return window.dashAgGridRegisteredChartModules; -} - -function registerChartsModule(mode) { - const registeredChartModules = getRegisteredChartModules(); - if (!registeredChartModules.has(mode)) { - ModuleRegistry.registerModules([ - IntegratedChartsModule.with(chartsModules[mode]), - ]); - registeredChartModules.add(mode); - } -} - -export default function DashAgGridCharts(props) { - const mode = - props.dashEnableCharts === 'enterprise' ? 'enterprise' : 'community'; - registerChartsModule(mode); - return ; -} - -DashAgGridCharts.propTypes = propTypes; diff --git a/tests/test_charts.py b/tests/test_charts.py index 8402911b..a54edb52 100644 --- a/tests/test_charts.py +++ b/tests/test_charts.py @@ -30,9 +30,11 @@ def _make_basic_grid(**extra_props): ) -def test_charts001_enables_community_charts_modules(dash_duo): +def test_charts001_enables_enterprise_charts_modules_with_true(dash_duo): app = Dash(__name__) - app.layout = html.Div([_make_chart_grid(dashEnableCharts=True)]) + app.layout = html.Div( + [_make_chart_grid(enableEnterpriseModules=True, dashEnableCharts=True)] + ) dash_duo.start_server(app) @@ -75,3 +77,16 @@ def test_charts003_keeps_enterprise_grid_without_charts(dash_duo): grid = utils.Grid(dash_duo, "grid") grid.wait_for_cell_text(0, 0, "Toyota") + + +def test_charts004_rejects_charts_on_community_grid(dash_duo): + app = Dash(__name__) + app.layout = html.Div([_make_chart_grid(dashEnableCharts="community")]) + + dash_duo.start_server(app) + + assert any( + "dashEnableCharts is only supported when enableEnterpriseModules is true." + in entry.get("message", "") + for entry in dash_duo.get_logs() + ) From 59ee922a76720b996cddaa9e14b1337b03c2c55c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 17:04:24 +0000 Subject: [PATCH 5/9] fix: auto-enable enableCharts when dashEnableCharts is set Agent-Logs-Url: https://github.com/plotly/dash-ag-grid/sessions/9132d0c3-36f5-4796-9b93-ded3b9090eae Co-authored-by: BSd3v <82055130+BSd3v@users.noreply.github.com> --- src/lib/components/AgGrid.react.js | 29 +++++++++++++++++------------ tests/test_charts.py | 18 ++++++++++++++++-- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/lib/components/AgGrid.react.js b/src/lib/components/AgGrid.react.js index 426a7f77..dd76d5ee 100644 --- a/src/lib/components/AgGrid.react.js +++ b/src/lib/components/AgGrid.react.js @@ -74,17 +74,17 @@ function DashAgGrid(props) { typeof dashEnableCharts === 'undefined' || dashEnableCharts === null ? false : dashEnableCharts; - const hasEnableCharts = dashGridOptions.enableCharts; - const validDashEnableCharts = [ - false, - true, - 'community', - 'enterprise', - ].includes(normalizedDashEnableCharts); + const validDashEnableCharts = [false, true, 'enterprise'].includes( + normalizedDashEnableCharts + ); + const gridDashOptions = normalizedDashEnableCharts + ? {...dashGridOptions, enableCharts: true} + : dashGridOptions; + const hasEnableCharts = gridDashOptions.enableCharts; if (!validDashEnableCharts) { throw new Error( - "dashEnableCharts must be one of: false, true, 'community', 'enterprise'." + "dashEnableCharts must be one of: false, true, 'enterprise'." ); } @@ -104,7 +104,12 @@ function DashAgGrid(props) { return ( - + ); } @@ -535,12 +540,12 @@ DashAgGrid.propTypes = { enableEnterpriseModules: PropTypes.bool, /** - * Load AG Charts modules for integrated charts when using `enableCharts`. - * Set to true (community charts), "community", or "enterprise". + * Load enterprise AG Charts modules for integrated charts. + * Setting this to true or "enterprise" also sets dashGridOptions.enableCharts=true. */ dashEnableCharts: PropTypes.oneOfType([ PropTypes.bool, - PropTypes.oneOf(['community', 'enterprise']), + PropTypes.oneOf(['enterprise']), ]), /** diff --git a/tests/test_charts.py b/tests/test_charts.py index a54edb52..c4040f50 100644 --- a/tests/test_charts.py +++ b/tests/test_charts.py @@ -12,7 +12,6 @@ def _make_chart_grid(**extra_props): {"make": "Ford", "model": "Mondeo", "price": 32000}, {"make": "Porsche", "model": "Boxster", "price": 72000}, ], - dashGridOptions={"enableCharts": True}, **extra_props, ) @@ -81,7 +80,7 @@ def test_charts003_keeps_enterprise_grid_without_charts(dash_duo): def test_charts004_rejects_charts_on_community_grid(dash_duo): app = Dash(__name__) - app.layout = html.Div([_make_chart_grid(dashEnableCharts="community")]) + app.layout = html.Div([_make_chart_grid(dashEnableCharts=True)]) dash_duo.start_server(app) @@ -90,3 +89,18 @@ def test_charts004_rejects_charts_on_community_grid(dash_duo): in entry.get("message", "") for entry in dash_duo.get_logs() ) + + +def test_charts005_rejects_enablecharts_without_dashenablecharts(dash_duo): + app = Dash(__name__) + app.layout = html.Div( + [_make_chart_grid(dashGridOptions={"enableCharts": True})] + ) + + dash_duo.start_server(app) + + assert any( + "enableCharts is set, but chart modules are not loaded." + in entry.get("message", "") + for entry in dash_duo.get_logs() + ) From 2c072398ccb9135c2b61258acd87b56c42efe6b3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 7 Apr 2026 17:06:38 +0000 Subject: [PATCH 6/9] fix: auto-enable charts and guard conflicting enableCharts=false Agent-Logs-Url: https://github.com/plotly/dash-ag-grid/sessions/9132d0c3-36f5-4796-9b93-ded3b9090eae Co-authored-by: BSd3v <82055130+BSd3v@users.noreply.github.com> --- src/lib/components/AgGrid.react.js | 10 +++++++++- tests/test_charts.py | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/lib/components/AgGrid.react.js b/src/lib/components/AgGrid.react.js index dd76d5ee..e5dcd72c 100644 --- a/src/lib/components/AgGrid.react.js +++ b/src/lib/components/AgGrid.react.js @@ -77,6 +77,8 @@ function DashAgGrid(props) { const validDashEnableCharts = [false, true, 'enterprise'].includes( normalizedDashEnableCharts ); + const hasConflictingEnableChartsSetting = + normalizedDashEnableCharts && dashGridOptions.enableCharts === false; const gridDashOptions = normalizedDashEnableCharts ? {...dashGridOptions, enableCharts: true} : dashGridOptions; @@ -94,6 +96,12 @@ function DashAgGrid(props) { ); } + if (hasConflictingEnableChartsSetting) { + throw new Error( + 'dashEnableCharts cannot be combined with dashGridOptions.enableCharts=false.' + ); + } + if (hasEnableCharts && !normalizedDashEnableCharts) { throw new Error( "enableCharts is set, but chart modules are not loaded. Set enableEnterpriseModules=true and dashEnableCharts=true or 'enterprise'." @@ -541,7 +549,7 @@ DashAgGrid.propTypes = { /** * Load enterprise AG Charts modules for integrated charts. - * Setting this to true or "enterprise" also sets dashGridOptions.enableCharts=true. + * true and "enterprise" are equivalent and set dashGridOptions.enableCharts=true. */ dashEnableCharts: PropTypes.oneOfType([ PropTypes.bool, diff --git a/tests/test_charts.py b/tests/test_charts.py index c4040f50..2cf64516 100644 --- a/tests/test_charts.py +++ b/tests/test_charts.py @@ -104,3 +104,24 @@ def test_charts005_rejects_enablecharts_without_dashenablecharts(dash_duo): in entry.get("message", "") for entry in dash_duo.get_logs() ) + + +def test_charts006_rejects_conflicting_enablecharts_false(dash_duo): + app = Dash(__name__) + app.layout = html.Div( + [ + _make_chart_grid( + enableEnterpriseModules=True, + dashEnableCharts=True, + dashGridOptions={"enableCharts": False}, + ) + ] + ) + + dash_duo.start_server(app) + + assert any( + "dashEnableCharts cannot be combined with dashGridOptions.enableCharts=false." + in entry.get("message", "") + for entry in dash_duo.get_logs() + ) From 01d7df93fc631dc76276110ed7e9c4bc3ae03b97 Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Tue, 7 Apr 2026 13:22:55 -0400 Subject: [PATCH 7/9] adjustments for community default --- src/lib/components/AgGrid.react.js | 10 ++++---- src/lib/fragments/AgGridEnterprise.react.js | 26 +++++++++------------ 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/lib/components/AgGrid.react.js b/src/lib/components/AgGrid.react.js index e5dcd72c..a4b063d0 100644 --- a/src/lib/components/AgGrid.react.js +++ b/src/lib/components/AgGrid.react.js @@ -74,7 +74,7 @@ function DashAgGrid(props) { typeof dashEnableCharts === 'undefined' || dashEnableCharts === null ? false : dashEnableCharts; - const validDashEnableCharts = [false, true, 'enterprise'].includes( + const validDashEnableCharts = [false, true, 'enterprise', 'community'].includes( normalizedDashEnableCharts ); const hasConflictingEnableChartsSetting = @@ -86,7 +86,7 @@ function DashAgGrid(props) { if (!validDashEnableCharts) { throw new Error( - "dashEnableCharts must be one of: false, true, 'enterprise'." + "dashEnableCharts must be one of: false, true, 'enterprise', 'community'." ); } @@ -104,7 +104,7 @@ function DashAgGrid(props) { if (hasEnableCharts && !normalizedDashEnableCharts) { throw new Error( - "enableCharts is set, but chart modules are not loaded. Set enableEnterpriseModules=true and dashEnableCharts=true or 'enterprise'." + "enableCharts is set, but chart modules are not loaded. Set enableEnterpriseModules=true and dashEnableCharts=true, 'community', or 'enterprise'." ); } @@ -549,11 +549,11 @@ DashAgGrid.propTypes = { /** * Load enterprise AG Charts modules for integrated charts. - * true and "enterprise" are equivalent and set dashGridOptions.enableCharts=true. + * true and "community" are equivalent and set dashGridOptions.enableCharts=true. */ dashEnableCharts: PropTypes.oneOfType([ PropTypes.bool, - PropTypes.oneOf(['enterprise']), + PropTypes.oneOf(['community', 'enterprise']), ]), /** diff --git a/src/lib/fragments/AgGridEnterprise.react.js b/src/lib/fragments/AgGridEnterprise.react.js index ebeac1fa..512ac295 100644 --- a/src/lib/fragments/AgGridEnterprise.react.js +++ b/src/lib/fragments/AgGridEnterprise.react.js @@ -6,6 +6,7 @@ import { LicenseManager, SparklinesModule, } from 'ag-grid-enterprise'; +import {AgChartsCommunityModule} from 'ag-charts-community'; import {AgChartsEnterpriseModule} from 'ag-charts-enterprise'; import MemoizedAgGrid, {propTypes} from './AgGrid.react'; @@ -15,26 +16,21 @@ ModuleRegistry.registerModules([ SparklinesModule.with(AgChartsEnterpriseModule), ]); -function shouldRegisterChartsModule() { - if (typeof window === 'undefined') { - return true; - } - if (window.dashAgGridEnterpriseChartsRegistered) { - return false; - } - window.dashAgGridEnterpriseChartsRegistered = true; - return true; -} - export default function DashAgGridEnterprise(props) { const {licenseKey, dashEnableCharts} = props; if (licenseKey) { LicenseManager.setLicenseKey(licenseKey); } - if (dashEnableCharts && shouldRegisterChartsModule()) { - ModuleRegistry.registerModules([ - IntegratedChartsModule.with(AgChartsEnterpriseModule), - ]); + if (dashEnableCharts) { + if (dashEnableCharts === 'enterprise') { + ModuleRegistry.registerModules([ + IntegratedChartsModule.with(AgChartsEnterpriseModule), + ]); + } else { + ModuleRegistry.registerModules([ + IntegratedChartsModule.with(AgChartsCommunityModule), + ]); + } } return ; } From b361cef72a6229d950a238ee20679e3f16c1c89d Mon Sep 17 00:00:00 2001 From: BSd3v <82055130+BSd3v@users.noreply.github.com> Date: Tue, 7 Apr 2026 13:25:35 -0400 Subject: [PATCH 8/9] fix for lint --- src/lib/components/AgGrid.react.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib/components/AgGrid.react.js b/src/lib/components/AgGrid.react.js index a4b063d0..cc38b3a2 100644 --- a/src/lib/components/AgGrid.react.js +++ b/src/lib/components/AgGrid.react.js @@ -74,9 +74,12 @@ function DashAgGrid(props) { typeof dashEnableCharts === 'undefined' || dashEnableCharts === null ? false : dashEnableCharts; - const validDashEnableCharts = [false, true, 'enterprise', 'community'].includes( - normalizedDashEnableCharts - ); + const validDashEnableCharts = [ + false, + true, + 'enterprise', + 'community', + ].includes(normalizedDashEnableCharts); const hasConflictingEnableChartsSetting = normalizedDashEnableCharts && dashGridOptions.enableCharts === false; const gridDashOptions = normalizedDashEnableCharts From 2326ff5078047e39f4e3733f978b3b2bd820aed8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 8 Apr 2026 15:52:11 +0000 Subject: [PATCH 9/9] fix: add AG Charts enterprise license key support Agent-Logs-Url: https://github.com/plotly/dash-ag-grid/sessions/2184805b-e07e-4f34-be09-4ffde6381db6 Co-authored-by: BSd3v <82055130+BSd3v@users.noreply.github.com> --- src/lib/components/AgGrid.react.js | 6 ++++++ src/lib/fragments/AgGridEnterprise.react.js | 11 +++++++++-- tests/test_charts.py | 19 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/lib/components/AgGrid.react.js b/src/lib/components/AgGrid.react.js index cc38b3a2..3bec49b2 100644 --- a/src/lib/components/AgGrid.react.js +++ b/src/lib/components/AgGrid.react.js @@ -545,6 +545,12 @@ DashAgGrid.propTypes = { */ licenseKey: PropTypes.string, + /** + * License key for AG Charts Enterprise when dashEnableCharts is "enterprise". + * If not provided, licenseKey is used. + */ + chartsLicenseKey: PropTypes.string, + /** * If True, enable ag-grid Enterprise modules. Recommended to use with licenseKey. */ diff --git a/src/lib/fragments/AgGridEnterprise.react.js b/src/lib/fragments/AgGridEnterprise.react.js index 512ac295..a50c6368 100644 --- a/src/lib/fragments/AgGridEnterprise.react.js +++ b/src/lib/fragments/AgGridEnterprise.react.js @@ -7,7 +7,10 @@ import { SparklinesModule, } from 'ag-grid-enterprise'; import {AgChartsCommunityModule} from 'ag-charts-community'; -import {AgChartsEnterpriseModule} from 'ag-charts-enterprise'; +import { + AgChartsEnterpriseModule, + LicenseManager as AgChartsLicenseManager, +} from 'ag-charts-enterprise'; import MemoizedAgGrid, {propTypes} from './AgGrid.react'; // Register all enterprise features @@ -17,12 +20,16 @@ ModuleRegistry.registerModules([ ]); export default function DashAgGridEnterprise(props) { - const {licenseKey, dashEnableCharts} = props; + const {licenseKey, chartsLicenseKey, dashEnableCharts} = props; if (licenseKey) { LicenseManager.setLicenseKey(licenseKey); } if (dashEnableCharts) { if (dashEnableCharts === 'enterprise') { + const effectiveChartsLicenseKey = chartsLicenseKey || licenseKey; + if (effectiveChartsLicenseKey) { + AgChartsLicenseManager.setLicenseKey(effectiveChartsLicenseKey); + } ModuleRegistry.registerModules([ IntegratedChartsModule.with(AgChartsEnterpriseModule), ]); diff --git a/tests/test_charts.py b/tests/test_charts.py index 2cf64516..67b3d601 100644 --- a/tests/test_charts.py +++ b/tests/test_charts.py @@ -125,3 +125,22 @@ def test_charts006_rejects_conflicting_enablecharts_false(dash_duo): in entry.get("message", "") for entry in dash_duo.get_logs() ) + + +def test_charts007_accepts_charts_license_key_prop(dash_duo): + app = Dash(__name__) + app.layout = html.Div( + [ + _make_chart_grid( + enableEnterpriseModules=True, + dashEnableCharts="enterprise", + licenseKey="grid-key", + chartsLicenseKey="charts-key", + ) + ] + ) + + dash_duo.start_server(app) + + grid = utils.Grid(dash_duo, "grid") + grid.wait_for_cell_text(0, 0, "Toyota")