Skip to content
74 changes: 70 additions & 4 deletions src/lib/components/AgGrid.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ ModuleRegistry.registerModules([AllCommunityModule]);
const RealAgGrid = lazy(LazyLoader.agGrid);
const RealAgGridEnterprise = lazy(LazyLoader.agGridEnterprise);

function getGrid(enable) {
return enable ? RealAgGridEnterprise : RealAgGrid;
function getGrid(enableEnterpriseModules) {
return enableEnterpriseModules ? RealAgGridEnterprise : RealAgGrid;
}

export const defaultProps = {
Expand All @@ -21,6 +21,7 @@ export const defaultProps = {
selectAll: false,
deselectAll: false,
enableEnterpriseModules: false,
dashEnableCharts: false,
updateColumnState: false,
persisted_props: ['selectedRows'],
persistence_type: 'local',
Expand Down Expand Up @@ -64,12 +65,62 @@ function DashAgGrid(props) {
}
}, [props.rowTransaction, state.mounted, buildArray]);

const {enableEnterpriseModules} = props;
const {
enableEnterpriseModules,
dashEnableCharts,
dashGridOptions = {},
} = props;
const normalizedDashEnableCharts =
typeof dashEnableCharts === 'undefined' || dashEnableCharts === null
? false
: dashEnableCharts;
const validDashEnableCharts = [
false,
true,
'enterprise',
'community',
].includes(normalizedDashEnableCharts);
const hasConflictingEnableChartsSetting =
normalizedDashEnableCharts && dashGridOptions.enableCharts === false;
const gridDashOptions = normalizedDashEnableCharts
? {...dashGridOptions, enableCharts: true}
: dashGridOptions;
const hasEnableCharts = gridDashOptions.enableCharts;

if (!validDashEnableCharts) {
throw new Error(
"dashEnableCharts must be one of: false, true, 'enterprise', 'community'."
);
}

if (normalizedDashEnableCharts && !enableEnterpriseModules) {
throw new Error(
'dashEnableCharts is only supported when enableEnterpriseModules is true.'
);
}

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, 'community', or 'enterprise'."
);
}

const RealComponent = getGrid(enableEnterpriseModules);

return (
<Suspense fallback={null}>
<RealComponent parentState={state} {...defaultProps} {...props} />
<RealComponent
parentState={state}
{...defaultProps}
{...props}
dashGridOptions={gridDashOptions}
/>
</Suspense>
);
}
Expand Down Expand Up @@ -494,11 +545,26 @@ 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.
*/
enableEnterpriseModules: PropTypes.bool,

/**
* Load enterprise AG Charts modules for integrated charts.
* true and "community" are equivalent and set dashGridOptions.enableCharts=true.
*/
dashEnableCharts: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.oneOf(['community', 'enterprise']),
]),

/**
* The rowData in the grid after inline filters are applied.
*/
Expand Down
24 changes: 22 additions & 2 deletions src/lib/fragments/AgGridEnterprise.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ import React from 'react';
import {ModuleRegistry} from 'ag-grid-community';
import {
AllEnterpriseModule,
IntegratedChartsModule,
LicenseManager,
SparklinesModule,
} from 'ag-grid-enterprise';
import {AgChartsEnterpriseModule} from 'ag-charts-enterprise';
import {AgChartsCommunityModule} from 'ag-charts-community';
import {
AgChartsEnterpriseModule,
LicenseManager as AgChartsLicenseManager,
} from 'ag-charts-enterprise';
import MemoizedAgGrid, {propTypes} from './AgGrid.react';

// Register all enterprise features
Expand All @@ -15,10 +20,25 @@ ModuleRegistry.registerModules([
]);

export default function DashAgGridEnterprise(props) {
const {licenseKey} = 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),
]);
} else {
ModuleRegistry.registerModules([
IntegratedChartsModule.with(AgChartsCommunityModule),
]);
}
}
return <MemoizedAgGrid {...props} />;
}

Expand Down
1 change: 1 addition & 0 deletions src/lib/utils/propCategories.js
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ export const PROPS_NOT_FOR_AG_GRID = [
'setProps',
'loading_state',
'enableEnterpriseModules',
'dashEnableCharts',
'parentState',
'persistence',
'persisted_props',
Expand Down
146 changes: 146 additions & 0 deletions tests/test_charts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
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},
],
**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_enterprise_charts_modules_with_true(dash_duo):
app = Dash(__name__)
app.layout = html.Div(
[_make_chart_grid(enableEnterpriseModules=True, 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")


def test_charts004_rejects_charts_on_community_grid(dash_duo):
app = Dash(__name__)
app.layout = html.Div([_make_chart_grid(dashEnableCharts=True)])

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()
)


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()
)


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()
)


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")