From 6bfd20cc0e4fa156e044f803be89ce4147300a34 Mon Sep 17 00:00:00 2001 From: Nathan Drezner Date: Fri, 3 Apr 2026 09:52:36 -0400 Subject: [PATCH 1/3] Split publish workflow into separate PyPI and npm workflows Replaces the single publish.yml with: - pypi-publish.yml: publishes to PyPI on release - npm-publish.yml: publishes to npm on release + supports manual trigger via workflow_dispatch Co-Authored-By: Claude Opus 4.6 --- .github/workflows/npm-publish.yml | 42 +++++++++++++++++++ .../{publish.yml => pypi-publish.yml} | 21 +--------- 2 files changed, 43 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/npm-publish.yml rename .github/workflows/{publish.yml => pypi-publish.yml} (59%) diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml new file mode 100644 index 00000000..89ef561a --- /dev/null +++ b/.github/workflows/npm-publish.yml @@ -0,0 +1,42 @@ +name: Publish to NPM + +on: + release: + types: [published] + workflow_dispatch: + +jobs: + build: + uses: ./.github/workflows/build.yml + with: + python-version: '3.10' + node-version: 'v18.16.0' + + npm-publish: + name: Upload release to NPM + runs-on: ubuntu-latest + environment: + name: npm + permissions: + id-token: write + contents: read + needs: build + steps: + - uses: actions/setup-node@v4 + with: + node-version: '20.x' + registry-url: 'https://registry.npmjs.org' + - name: Download npm package + uses: actions/download-artifact@v4 + with: + name: npm-package + path: npm-dist/ + - name: Publish to npm + run: | + pushd npm-dist + FILE=$(echo *.tgz) + npm publish "$FILE" --provenance --access public + popd + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + shell: bash diff --git a/.github/workflows/publish.yml b/.github/workflows/pypi-publish.yml similarity index 59% rename from .github/workflows/publish.yml rename to .github/workflows/pypi-publish.yml index ae3d8ba1..55987dc8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -1,4 +1,4 @@ -name: Publish to PyPI & NPM +name: Publish to PyPI on: release: @@ -30,22 +30,3 @@ jobs: path: dist/ - name: Publish package distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1 - - - name: Download npm package - uses: actions/download-artifact@v4 - with: - name: npm-package - path: npm-dist/ - - uses: actions/setup-node@v4 - with: - node-version: '20.x' - registry-url: 'https://registry.npmjs.org' - - name: Publish to npm - run: | - pushd npm-dist - FILE=$(echo *.tgz) - npm publish "$FILE" --provenance --access public - popd - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - shell: bash From 77e4c13c1ea17599cf307996f1488f9b89081f02 Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Sat, 11 Apr 2026 13:15:25 -0700 Subject: [PATCH 2/3] add totalValueGetter to propCategories --- src/lib/utils/propCategories.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/utils/propCategories.js b/src/lib/utils/propCategories.js index 60f819ac..bd535281 100644 --- a/src/lib/utils/propCategories.js +++ b/src/lib/utils/propCategories.js @@ -255,6 +255,7 @@ export const COLUMN_MAYBE_FUNCTIONS = { // Groups toolPanelClass: 1, + totalValueGetter: 1, // Groups: Header headerClass: 1, From 2ae461306b3c307f74ca840803bbfde5bd85a41e Mon Sep 17 00:00:00 2001 From: AnnMarueW Date: Sat, 11 Apr 2026 16:54:42 -0700 Subject: [PATCH 3/3] add test --- tests/assets/dashAgGridFunctions.js | 13 +++++- tests/test_row_groupings.py | 65 ++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/tests/assets/dashAgGridFunctions.js b/tests/assets/dashAgGridFunctions.js index a5bbcc36..d5ba9f96 100644 --- a/tests/assets/dashAgGridFunctions.js +++ b/tests/assets/dashAgGridFunctions.js @@ -541,4 +541,15 @@ dagfuncs.testToyota = (params) => { dagfuncs.customTheme = (theme, agGrid) => { return theme.withPart(agGrid.createPart(agGrid.colorSchemeDark)).withPart(agGrid.createPart(agGrid.iconSetAlpine)); -} \ No newline at end of file +} + + +dagfuncs.myTotalValueGetter = function (params) { + const isRootLevel = params.node.level === -1; + + if (isRootLevel) { + return 'Grand Total'; + } + + return `Sub Total (${params.value})`; + } diff --git a/tests/test_row_groupings.py b/tests/test_row_groupings.py index 4381d10a..15d1345d 100644 --- a/tests/test_row_groupings.py +++ b/tests/test_row_groupings.py @@ -181,4 +181,67 @@ def update(cell_changed, row_data, virtual_row_data): until(lambda: dash_duo.find_element('#grid-virtualRowData-info').text == "{'country': 'Ireland', 'type': 'Non Fiction', 'city': 'texas'}", - timeout=3) \ No newline at end of file + timeout=3) + + +def test_rg003_total_value_getter(dash_duo): + import dash + from dash import html + import dash_ag_grid as dag + + from dash.testing.wait import until + from . import utils + + app = dash.Dash(__name__) + + row_data = [ + {"country": "USA", "year": 2020, "gold": 1, "silver": 0, "bronze": 1}, + {"country": "USA", "year": 2020, "gold": 2, "silver": 1, "bronze": 0}, + {"country": "USA", "year": 2024, "gold": 1, "silver": 1, "bronze": 1}, + {"country": "Canada", "year": 2020, "gold": 0, "silver": 1, "bronze": 1}, + {"country": "Canada", "year": 2024, "gold": 2, "silver": 0, "bronze": 0}, + ] + + column_defs = [ + {"field": "country", "rowGroup": True, "hide": True}, + {"field": "year", "rowGroup": True, "hide": True}, + {"field": "gold", "aggFunc": "sum"}, + {"field": "silver", "aggFunc": "sum"}, + {"field": "bronze", "aggFunc": "sum"}, + ] + + auto_group_column_def = { + "minWidth": 300, + "cellRendererParams": { + "totalValueGetter": {"function": "myTotalValueGetter(params)"}, + }, + } + + app.layout = html.Div( + [ + dag.AgGrid( + id="grid", + rowData=row_data, + columnDefs=column_defs, + defaultColDef={"flex": 1, "minWidth": 150}, + enableEnterpriseModules=True, + dashGridOptions={ + "autoGroupColumnDef": auto_group_column_def, + "groupTotalRow": "bottom", + "grandTotalRow": "bottom", + "groupDefaultExpanded": 1, + }, + + ) + ] + ) + + dash_duo.start_server(app) + + grid = utils.Grid(dash_duo, "grid") + + until(lambda: "USA" in grid.get_cell(0, 0).text, timeout=3) + all_text = [el.text for el in dash_duo.find_elements(".ag-cell")] + + assert any("Sub Total (" in t for t in all_text) + assert "Grand Total" in all_text \ No newline at end of file