@cdmx/wappler_ag_grid 2.1.4 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdmx/wappler_ag_grid",
3
- "version": "2.1.4",
3
+ "version": "2.1.5",
4
4
  "type": "module",
5
5
  "description": "App Connect module for AG Grid v35 - Advanced data grid with enhanced editing, filtering, and tree data capabilities.",
6
6
  "license": "MIT",
@@ -16,11 +16,13 @@
16
16
  "dependencies": {
17
17
  "@ag-grid-community/locale": "~35.1.0",
18
18
  "ag-grid-community": "~35.1.0",
19
- "exceljs": "^4.4.0",
20
19
  "papaparse": "~5.5.2",
21
20
  "pdfmake": "~0.2.18",
22
21
  "read-excel-file": "~5.8.7"
23
22
  },
23
+ "devDependencies": {
24
+ "exceljs": "github:cdmx-in/exceljs#v4.4.0-uuid11.1.1-r2"
25
+ },
24
26
  "scripts": {
25
27
  "build": "rollup --config",
26
28
  "publish-dry-run": "npm publish ./dist --access public --dry-run"
@@ -0,0 +1,106 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>01 · Basic Render · AG Grid Test Suite</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+
8
+ <link rel="stylesheet" href="./lib/test-suite.css">
9
+ <link rel="stylesheet" href="../node_modules/ag-grid-community/styles/ag-theme-alpine.css">
10
+ <link rel="stylesheet" href="../ag-theme-custom.css">
11
+ <link rel="stylesheet" href="../switch-toggle-slider.css">
12
+
13
+ <script src="./dmxAppConnect/dmxAppConnect.js" defer></script>
14
+ <script src="./lib/version-banner.js" defer></script>
15
+ <script src="./lib/test-helpers.js" defer></script>
16
+ <script src="./lib/page-template.js" defer></script>
17
+ <script src="../node_modules/ag-grid-community/dist/ag-grid-community.min.js" defer></script>
18
+ <script src="../dmx-ag-grid.js" defer></script>
19
+ <script src="./data/sample-data.js" defer></script>
20
+ </head>
21
+ <body is="dmx-app" id="page01">
22
+
23
+ <script>
24
+ window.addEventListener('DOMContentLoaded', () => {
25
+ TestPage.header({
26
+ title: '01 · Basic Render',
27
+ summary: 'Auto-inferred columns, default sort + text/number filters, floating filter row, pagination.'
28
+ });
29
+ });
30
+ </script>
31
+
32
+ <main class="test-main">
33
+
34
+ <section class="feature">
35
+ <h2>Default grid — inferred columns</h2>
36
+ <p class="desc">
37
+ Source: <code>window.SampleData.employees</code> (25 rows). The grid infers column types from
38
+ data, renders Alpine theme, pagination size 10, sortable + filterable + floating filter row.
39
+ </p>
40
+ <dmx-test-data id="employees" source="employees"></dmx-test-data>
41
+
42
+ <div class="grid-wrap">
43
+ <dmx-ag-grid
44
+ id="basicGrid"
45
+ dmx-bind:data="employees.value"
46
+ grid_theme="ag-theme-alpine"
47
+ pagination="true"
48
+ dmx-bind:pagination_page_size="10"
49
+ sortable="true"
50
+ filter="true"
51
+ floating_filter="true"
52
+ resizable="true"
53
+ animate_rows="true">
54
+ </dmx-ag-grid>
55
+ </div>
56
+
57
+ <div class="kv">
58
+ <div class="k">Row count (binding)</div>
59
+ <div class="v" id="row-count" dmx-text="basicGrid.count">…</div>
60
+ <div class="k">gridReady</div>
61
+ <div class="v" dmx-text="basicGrid.state.gridReady">…</div>
62
+ <div class="k">firstDataRendered</div>
63
+ <div class="v" dmx-text="basicGrid.state.firstDataRendered">…</div>
64
+ <div class="k">rowDataUpdated</div>
65
+ <div class="v" dmx-text="basicGrid.state.rowDataUpdated">…</div>
66
+ </div>
67
+
68
+ <div class="controls" style="margin-top: 12px;">
69
+ <button class="primary" onclick="TestKit.callMethod('basicGrid', 'reloadGrid', true)">reloadGrid()</button>
70
+ <button onclick="TestKit.callMethod('basicGrid', 'loadGrid')">loadGrid()</button>
71
+ <button onclick="logSnapshot('basicGrid')">log snapshot</button>
72
+ <input type="search" id="qf" placeholder="Quick filter…" oninput="quickFilter(this.value)">
73
+ </div>
74
+ </section>
75
+
76
+ <section class="feature">
77
+ <h2>Console log</h2>
78
+ <div class="log" id="cli-log"></div>
79
+ </section>
80
+
81
+ </main>
82
+
83
+ <script>
84
+ function log(line) {
85
+ const box = document.getElementById('cli-log');
86
+ if (!box) return;
87
+ const el = document.createElement('div');
88
+ el.className = 'log-entry';
89
+ el.textContent = '[' + new Date().toISOString().slice(11,19) + '] ' + line;
90
+ box.insertBefore(el, box.firstChild);
91
+ }
92
+ function logSnapshot(id) {
93
+ log(id + ': ' + JSON.stringify(TestKit.snapshot(id)));
94
+ }
95
+ function quickFilter(value) {
96
+ const g = TestKit.grid('basicGrid');
97
+ if (!g) return;
98
+ const inst = g.get('gridInstance');
99
+ if (inst && inst.setGridOption) {
100
+ inst.setGridOption('quickFilterText', value);
101
+ }
102
+ }
103
+ window.addEventListener('error', (e) => log('error: ' + e.message));
104
+ </script>
105
+ </body>
106
+ </html>
@@ -0,0 +1,98 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>02 · Themes &amp; Locale · AG Grid Test Suite</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+
8
+ <link rel="stylesheet" href="./lib/test-suite.css">
9
+ <link rel="stylesheet" href="../node_modules/ag-grid-community/styles/ag-theme-alpine.css">
10
+ <link rel="stylesheet" href="../node_modules/ag-grid-community/styles/ag-theme-balham.css">
11
+ <link rel="stylesheet" href="../node_modules/ag-grid-community/styles/ag-theme-material.css">
12
+ <link rel="stylesheet" href="../node_modules/ag-grid-community/styles/ag-theme-quartz.css">
13
+ <link rel="stylesheet" href="../ag-theme-custom.css">
14
+ <link rel="stylesheet" href="../switch-toggle-slider.css">
15
+
16
+ <script src="./dmxAppConnect/dmxAppConnect.js" defer></script>
17
+ <script src="./lib/version-banner.js" defer></script>
18
+ <script src="./lib/test-helpers.js" defer></script>
19
+ <script src="./lib/page-template.js" defer></script>
20
+ <script src="../node_modules/ag-grid-community/dist/ag-grid-community.min.js" defer></script>
21
+ <script src="../node_modules/@ag-grid-community/locale/dist/umd/@ag-grid-community/locale.min.js" defer></script>
22
+ <script src="../ru.js" defer></script>
23
+ <script src="../dmx-ag-grid.js" defer></script>
24
+ <script src="./data/sample-data.js" defer></script>
25
+ </head>
26
+ <body is="dmx-app" id="page02">
27
+
28
+ <script>
29
+ window.addEventListener('DOMContentLoaded', () => {
30
+ TestPage.header({
31
+ title: '02 · Themes & Locale',
32
+ summary: 'Toggle theme, dark mode, RTL, locale. The grid re-renders when dark_mode flips.'
33
+ });
34
+ });
35
+ </script>
36
+
37
+ <main class="test-main">
38
+ <dmx-test-data id="rows" source="employees"></dmx-test-data>
39
+
40
+ <section class="feature">
41
+ <h2>Theme matrix</h2>
42
+ <p class="desc">Each grid is a separate instance, demonstrating that the <code>grid_theme</code> attribute swaps the CSS class.</p>
43
+
44
+ <h3 style="margin-top:14px;">Alpine</h3>
45
+ <div class="grid-wrap"><dmx-ag-grid id="g_alpine" dmx-bind:data="rows.value" grid_theme="ag-theme-alpine" dmx-bind:pagination="false" dmx-bind:row_height="28"></dmx-ag-grid></div>
46
+
47
+ <h3 style="margin-top:14px;">Balham</h3>
48
+ <div class="grid-wrap"><dmx-ag-grid id="g_balham" dmx-bind:data="rows.value" grid_theme="ag-theme-balham" dmx-bind:pagination="false" dmx-bind:row_height="26"></dmx-ag-grid></div>
49
+
50
+ <h3 style="margin-top:14px;">Material</h3>
51
+ <div class="grid-wrap"><dmx-ag-grid id="g_material" dmx-bind:data="rows.value" grid_theme="ag-theme-material" dmx-bind:pagination="false"></dmx-ag-grid></div>
52
+
53
+ <h3 style="margin-top:14px;">Quartz</h3>
54
+ <div class="grid-wrap"><dmx-ag-grid id="g_quartz" dmx-bind:data="rows.value" grid_theme="ag-theme-quartz" dmx-bind:pagination="false"></dmx-ag-grid></div>
55
+
56
+ <h3 style="margin-top:14px;">Custom (alpine + ag-theme-custom)</h3>
57
+ <div class="grid-wrap"><dmx-ag-grid id="g_custom" dmx-bind:data="rows.value" grid_theme="ag-theme-alpine ag-theme-custom" dmx-bind:pagination="false"></dmx-ag-grid></div>
58
+ </section>
59
+
60
+ <section class="feature">
61
+ <h2>Dark mode toggle</h2>
62
+ <p class="desc">Flipping <code>dark_mode</code> triggers the grid's <code>requestUpdate</code> branch and rebuilds the instance with a <code>-dark</code> theme suffix.</p>
63
+ <div class="controls">
64
+ <button class="primary" onclick="toggleDark()">Toggle dark mode</button>
65
+ <span class="kv" style="display:inline-grid; grid-template-columns: auto auto; gap: 4px 8px;">
66
+ <span class="k">dark_mode</span><span class="v" id="dark-val">false</span>
67
+ </span>
68
+ </div>
69
+ <div class="grid-wrap">
70
+ <dmx-ag-grid id="g_dark" dmx-bind:data="rows.value" grid_theme="ag-theme-alpine" dmx-bind:dark_mode="false" dmx-bind:pagination="false"></dmx-ag-grid>
71
+ </div>
72
+ </section>
73
+
74
+ <section class="feature">
75
+ <h2>RTL + locale</h2>
76
+ <p class="desc">Hebrew locale forces RTL; Russian uses the shipped <code>ru.js</code>; Spanish/Portuguese come from <code>@ag-grid-community/locale</code>.</p>
77
+ <h3>Hebrew (RTL)</h3>
78
+ <div class="grid-wrap"><dmx-ag-grid id="g_he" dmx-bind:data="rows.value" grid_theme="ag-theme-alpine" locale_text="HE" dmx-bind:enable_rtl="true" dmx-bind:pagination="false"></dmx-ag-grid></div>
79
+
80
+ <h3 style="margin-top:14px;">Russian</h3>
81
+ <div class="grid-wrap"><dmx-ag-grid id="g_ru" dmx-bind:data="rows.value" grid_theme="ag-theme-alpine" locale_text="RU" dmx-bind:pagination="false"></dmx-ag-grid></div>
82
+
83
+ <h3 style="margin-top:14px;">Spanish</h3>
84
+ <div class="grid-wrap"><dmx-ag-grid id="g_es" dmx-bind:data="rows.value" grid_theme="ag-theme-alpine" locale_text="ES" dmx-bind:pagination="false"></dmx-ag-grid></div>
85
+ </section>
86
+ </main>
87
+
88
+ <script>
89
+ let dark = false;
90
+ function toggleDark() {
91
+ dark = !dark;
92
+ document.getElementById('dark-val').textContent = String(dark);
93
+ const c = TestKit.grid('g_dark');
94
+ if (c) c.set('dark_mode', dark);
95
+ }
96
+ </script>
97
+ </body>
98
+ </html>
@@ -0,0 +1,119 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>03 · Editing · AG Grid Test Suite</title>
6
+ <link rel="stylesheet" href="./lib/test-suite.css">
7
+ <link rel="stylesheet" href="../node_modules/ag-grid-community/styles/ag-theme-alpine.css">
8
+ <link rel="stylesheet" href="../ag-theme-custom.css">
9
+ <link rel="stylesheet" href="../switch-toggle-slider.css">
10
+
11
+ <script src="./dmxAppConnect/dmxAppConnect.js" defer></script>
12
+ <script src="./lib/version-banner.js" defer></script>
13
+ <script src="./lib/test-helpers.js" defer></script>
14
+ <script src="./lib/page-template.js" defer></script>
15
+ <script src="../node_modules/ag-grid-community/dist/ag-grid-community.min.js" defer></script>
16
+ <script src="../dmx-ag-grid.js" defer></script>
17
+ <script src="./data/sample-data.js" defer></script>
18
+ </head>
19
+ <body is="dmx-app" id="page03">
20
+
21
+ <script>
22
+ window.addEventListener('DOMContentLoaded', () => {
23
+ TestPage.header({
24
+ title: '03 · Editing',
25
+ summary: 'Cell vs row editing, restricted editable_fields, static + dynamic select editors.'
26
+ });
27
+ });
28
+ </script>
29
+
30
+ <main class="test-main">
31
+
32
+ <dmx-test-data id="rows" source="employees"></dmx-test-data>
33
+ <dmx-event-log id="editLog"></dmx-event-log>
34
+
35
+ <section class="feature">
36
+ <h2>Cell editable — all fields</h2>
37
+ <p class="desc">
38
+ Double-click any cell to edit. <code>cell_data_edited</code> fires for each change with
39
+ <code>{ field, oldValue, newValue, rowId }</code>. Logged below.
40
+ </p>
41
+ <div class="grid-wrap">
42
+ <dmx-ag-grid
43
+ id="cellEdit"
44
+ dmx-bind:data="rows.value"
45
+ grid_theme="ag-theme-alpine"
46
+ dmx-bind:cell_editable="true"
47
+ dmx-bind:pagination="false"
48
+ dmx-bind:floating_filter="false"
49
+ dmx-on:cell_data_edited="editLog.add('cell_data_edited')">
50
+ </dmx-ag-grid>
51
+ </div>
52
+ </section>
53
+
54
+ <section class="feature">
55
+ <h2>Row editable — restricted fields</h2>
56
+ <p class="desc">
57
+ <code>row_editable=true</code> with <code>editable_fields="salary,rating,active"</code> — only those columns
58
+ are editable. <code>row_data_edited</code> fires once per row commit.
59
+ </p>
60
+ <div class="grid-wrap">
61
+ <dmx-ag-grid
62
+ id="rowEdit"
63
+ dmx-bind:data="rows.value"
64
+ grid_theme="ag-theme-alpine"
65
+ dmx-bind:row_editable="true"
66
+ editable_fields="salary,rating,active"
67
+ dmx-bind:pagination="false"
68
+ dmx-on:row_data_edited="editLog.add('row_data_edited')">
69
+ </dmx-ag-grid>
70
+ </div>
71
+ </section>
72
+
73
+ <section class="feature">
74
+ <h2>Select editors</h2>
75
+ <p class="desc">
76
+ <code>cstatic_select_editors</code> for <code>department</code>, <code>cdynamic_select_editors</code> for <code>active</code>.
77
+ Both render a dropdown editor when the cell is edited.
78
+ </p>
79
+ <div class="grid-wrap">
80
+ <!-- cstatic_select_editors expects { fieldName: { options: '<JSON string>' } } where
81
+ the JSON parses to an object whose keys become the displayed values. -->
82
+ <dmx-ag-grid
83
+ id="selectEdit"
84
+ dmx-bind:data="rows.value"
85
+ grid_theme="ag-theme-alpine"
86
+ dmx-bind:cell_editable="true"
87
+ dmx-bind:cstatic_select_editors='{"department": {"options": "{\"Engineering\":\"Engineering\",\"Sales\":\"Sales\",\"Marketing\":\"Marketing\",\"HR\":\"HR\",\"Finance\":\"Finance\"}"}}'
88
+ cselect_placeholder="—"
89
+ dmx-bind:pagination="false"
90
+ dmx-on:cell_data_edited="editLog.add('select_cell_edited')">
91
+ </dmx-ag-grid>
92
+ </div>
93
+ </section>
94
+
95
+ <section class="feature">
96
+ <h2>Edit log</h2>
97
+ <div class="kv">
98
+ <div class="k">events captured</div><div class="v" dmx-text="editLog.count">0</div>
99
+ <div class="k">last event</div><div class="v" dmx-text="editLog.last.name">—</div>
100
+ </div>
101
+ <div class="log" id="log-out"></div>
102
+ </section>
103
+ </main>
104
+
105
+ <script>
106
+ function renderLog() {
107
+ if (!window.dmx || !dmx.app) return setTimeout(renderLog, 100);
108
+ const log = dmx.app.get('editLog');
109
+ if (!log) return setTimeout(renderLog, 100);
110
+ const box = document.getElementById('log-out');
111
+ setInterval(() => {
112
+ const evs = log.events || [];
113
+ box.innerHTML = evs.map(e => '<div class="log-entry">' + e.at + ' — ' + e.name + '</div>').join('');
114
+ }, 500);
115
+ }
116
+ renderLog();
117
+ </script>
118
+ </body>
119
+ </html>
@@ -0,0 +1,103 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>04 · Selection &amp; Row Events</title>
6
+ <link rel="stylesheet" href="./lib/test-suite.css">
7
+ <link rel="stylesheet" href="../node_modules/ag-grid-community/styles/ag-theme-alpine.css">
8
+ <link rel="stylesheet" href="../ag-theme-custom.css">
9
+ <link rel="stylesheet" href="../switch-toggle-slider.css">
10
+ <script src="./dmxAppConnect/dmxAppConnect.js" defer></script>
11
+ <script src="./lib/version-banner.js" defer></script>
12
+ <script src="./lib/test-helpers.js" defer></script>
13
+ <script src="./lib/page-template.js" defer></script>
14
+ <script src="../node_modules/ag-grid-community/dist/ag-grid-community.min.js" defer></script>
15
+ <script src="../dmx-ag-grid.js" defer></script>
16
+ <script src="./data/sample-data.js" defer></script>
17
+ </head>
18
+ <body is="dmx-app" id="page04">
19
+
20
+ <script>
21
+ window.addEventListener('DOMContentLoaded', () => {
22
+ TestPage.header({
23
+ title: '04 · Selection & Row Events',
24
+ summary: 'Single vs multi-row selection, row checkbox events, status toggle, click + double-click hooks.'
25
+ });
26
+ });
27
+ </script>
28
+
29
+ <main class="test-main">
30
+ <dmx-test-data id="rows" source="employees"></dmx-test-data>
31
+ <dmx-event-log id="evLog"></dmx-event-log>
32
+
33
+ <section class="feature">
34
+ <h2>Multi-row selection with checkbox events</h2>
35
+ <p class="desc">
36
+ <code>row_selection="multiRow"</code>, <code>row_checkbox_event=true</code>, <code>row_status_event=true</code>.
37
+ Selected rows are exposed via <code>selectedRows</code>.
38
+ </p>
39
+ <div class="grid-wrap">
40
+ <dmx-ag-grid
41
+ id="selGrid"
42
+ dmx-bind:data="rows.value"
43
+ grid_theme="ag-theme-alpine"
44
+ row_selection="multiRow"
45
+ dmx-bind:row_checkbox_event="true"
46
+ dmx-bind:row_status_event="true"
47
+ dmx-bind:row_click_event="true"
48
+ dmx-bind:row_double_click_event="true"
49
+ dmx-bind:pagination="false"
50
+ dmx-on:row_clicked="evLog.add('row_clicked')"
51
+ dmx-on:row_double_clicked="evLog.add('row_double_clicked')"
52
+ dmx-on:row_checkbox_checked="evLog.add('row_checkbox_checked')"
53
+ dmx-on:row_checkbox_unchecked="evLog.add('row_checkbox_unchecked')"
54
+ dmx-on:row_status_enabled="evLog.add('row_status_enabled')"
55
+ dmx-on:row_status_disabled="evLog.add('row_status_disabled')">
56
+ </dmx-ag-grid>
57
+ </div>
58
+
59
+ <div class="controls">
60
+ <button class="primary" onclick="TestKit.callMethod('selGrid','getSelectedRows')">getSelectedRows()</button>
61
+ <button onclick="dumpSelected()">log selectedRows binding</button>
62
+ </div>
63
+
64
+ <div class="kv">
65
+ <div class="k">selectedRows.length</div>
66
+ <div class="v" dmx-text="selGrid.selectedRows.length">0</div>
67
+ <div class="k">last event</div>
68
+ <div class="v" dmx-text="evLog.last.name">—</div>
69
+ </div>
70
+ </section>
71
+
72
+ <section class="feature">
73
+ <h2>Single-row selection</h2>
74
+ <p class="desc"><code>row_selection="singleRow"</code> — clicking a row replaces selection.</p>
75
+ <div class="grid-wrap">
76
+ <dmx-ag-grid id="singleSel" dmx-bind:data="rows.value" grid_theme="ag-theme-alpine" row_selection="singleRow" dmx-bind:pagination="false"></dmx-ag-grid>
77
+ </div>
78
+ </section>
79
+
80
+ <section class="feature">
81
+ <h2>Event log</h2>
82
+ <div class="log" id="log-out"></div>
83
+ </section>
84
+ </main>
85
+
86
+ <script>
87
+ function dumpSelected() {
88
+ const c = TestKit.grid('selGrid');
89
+ console.log('selectedRows', c && c.get('selectedRows'));
90
+ }
91
+ (function pollLog() {
92
+ if (!window.dmx || !dmx.app) return setTimeout(pollLog, 100);
93
+ const log = dmx.app.get('evLog');
94
+ if (!log) return setTimeout(pollLog, 100);
95
+ setInterval(() => {
96
+ const evs = log.events || [];
97
+ document.getElementById('log-out').innerHTML =
98
+ evs.slice(0, 30).map(e => '<div class="log-entry">' + e.at + ' — ' + e.name + '</div>').join('');
99
+ }, 400);
100
+ })();
101
+ </script>
102
+ </body>
103
+ </html>
@@ -0,0 +1,97 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>05 · Action Buttons</title>
6
+ <link rel="stylesheet" href="./lib/test-suite.css">
7
+ <link rel="stylesheet" href="../node_modules/ag-grid-community/styles/ag-theme-alpine.css">
8
+ <link rel="stylesheet" href="../ag-theme-custom.css">
9
+ <link rel="stylesheet" href="../switch-toggle-slider.css">
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
11
+ <script src="./dmxAppConnect/dmxAppConnect.js" defer></script>
12
+ <script src="./lib/version-banner.js" defer></script>
13
+ <script src="./lib/test-helpers.js" defer></script>
14
+ <script src="./lib/page-template.js" defer></script>
15
+ <script src="../node_modules/ag-grid-community/dist/ag-grid-community.min.js" defer></script>
16
+ <script src="../dmx-ag-grid.js" defer></script>
17
+ <script src="./data/sample-data.js" defer></script>
18
+ </head>
19
+ <body is="dmx-app" id="page05">
20
+
21
+ <script>
22
+ window.addEventListener('DOMContentLoaded', () => {
23
+ TestPage.header({
24
+ title: '05 · Action Buttons',
25
+ summary: 'Built-in edit/view/delete actions plus 5 custom buttons with conditions.'
26
+ });
27
+ });
28
+ </script>
29
+
30
+ <main class="test-main">
31
+ <dmx-test-data id="rows" source="employees"></dmx-test-data>
32
+ <dmx-event-log id="actLog"></dmx-event-log>
33
+
34
+ <section class="feature">
35
+ <h2>Standard actions + 5 custom buttons</h2>
36
+ <p class="desc">
37
+ Pinned right. Built-in edit/view/delete + custom button1..button5. <code>button2_action_btn_condition</code>
38
+ restricts button 2 to active employees only.
39
+ </p>
40
+
41
+ <div class="grid-wrap">
42
+ <dmx-ag-grid
43
+ id="actGrid"
44
+ dmx-bind:data="rows.value"
45
+ grid_theme="ag-theme-alpine"
46
+ dmx-bind:enable_actions="true"
47
+ actions_column_position="right"
48
+ dmx-bind:pin_actions="true"
49
+ dmx-bind:edit_action_btn="true" edit_action_tooltip="Edit row"
50
+ dmx-bind:view_action_btn="true" view_action_tooltip="View row"
51
+ dmx-bind:delete_action_btn="true" delete_action_tooltip="Delete row"
52
+
53
+ dmx-bind:enable_custom_action_btns="true"
54
+ dmx-bind:button1_action_btn="true" button1_action_tooltip="Promote" button1_action_icon_class="fas fa-star"
55
+ dmx-bind:button2_action_btn="true" button2_action_tooltip="Email" button2_action_icon_class="fas fa-envelope" button2_action_btn_condition="active"
56
+ dmx-bind:button3_action_btn="true" button3_action_tooltip="Archive" button3_action_icon_class="fas fa-box-archive"
57
+ dmx-bind:button4_action_btn="true" button4_action_tooltip="Flag" button4_action_icon_class="fas fa-flag"
58
+ dmx-bind:button5_action_btn="true" button5_action_tooltip="Print" button5_action_icon_class="fas fa-print"
59
+
60
+ dmx-bind:pagination="false"
61
+
62
+ dmx-on:row_action_edit="actLog.add('row_action_edit')"
63
+ dmx-on:row_action_view="actLog.add('row_action_view')"
64
+ dmx-on:row_action_delete="actLog.add('row_action_delete')"
65
+ dmx-on:row_action_button1="actLog.add('row_action_button1')"
66
+ dmx-on:row_action_button2="actLog.add('row_action_button2')"
67
+ dmx-on:row_action_button3="actLog.add('row_action_button3')"
68
+ dmx-on:row_action_button4="actLog.add('row_action_button4')"
69
+ dmx-on:row_action_button5="actLog.add('row_action_button5')">
70
+ </dmx-ag-grid>
71
+ </div>
72
+
73
+ <div class="kv">
74
+ <div class="k">last action</div><div class="v" dmx-text="actLog.last.name">—</div>
75
+ <div class="k">action count</div><div class="v" dmx-text="actLog.count">0</div>
76
+ <div class="k">field captured</div><div class="v" dmx-text="actGrid.fields">{}</div>
77
+ <div class="k">id captured</div><div class="v" dmx-text="actGrid.id">—</div>
78
+ </div>
79
+
80
+ <div class="log" id="log-out"></div>
81
+ </section>
82
+ </main>
83
+
84
+ <script>
85
+ (function pollLog() {
86
+ if (!window.dmx || !dmx.app) return setTimeout(pollLog, 100);
87
+ const log = dmx.app.get('actLog');
88
+ if (!log) return setTimeout(pollLog, 100);
89
+ setInterval(() => {
90
+ const evs = log.events || [];
91
+ document.getElementById('log-out').innerHTML =
92
+ evs.slice(0, 30).map(e => '<div class="log-entry">' + e.at + ' — ' + e.name + '</div>').join('');
93
+ }, 400);
94
+ })();
95
+ </script>
96
+ </body>
97
+ </html>
@@ -0,0 +1,80 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>06 · Export · AG Grid Test Suite</title>
6
+ <link rel="stylesheet" href="./lib/test-suite.css">
7
+ <link rel="stylesheet" href="../node_modules/ag-grid-community/styles/ag-theme-alpine.css">
8
+ <link rel="stylesheet" href="../ag-theme-custom.css">
9
+ <link rel="stylesheet" href="../switch-toggle-slider.css">
10
+ <script src="./dmxAppConnect/dmxAppConnect.js" defer></script>
11
+ <script src="./lib/version-banner.js" defer></script>
12
+ <script src="./lib/test-helpers.js" defer></script>
13
+ <script src="./lib/page-template.js" defer></script>
14
+ <script src="../node_modules/ag-grid-community/dist/ag-grid-community.min.js" defer></script>
15
+ <script src="../node_modules/pdfmake/build/pdfmake.min.js" defer></script>
16
+ <script src="../node_modules/pdfmake/build/vfs_fonts.js" defer></script>
17
+ <script src="../node_modules/exceljs/dist/exceljs.min.js" defer></script>
18
+ <script src="../dmx-ag-grid.js" defer></script>
19
+ <script src="./data/sample-data.js" defer></script>
20
+ </head>
21
+ <body is="dmx-app" id="page06">
22
+
23
+ <script>
24
+ window.addEventListener('DOMContentLoaded', () => {
25
+ TestPage.header({
26
+ title: '06 · Export',
27
+ summary: 'CSV / XLSX / PDF export with trim, hidden-field handling, HTML stripping, custom filename.'
28
+ });
29
+ });
30
+ </script>
31
+
32
+ <main class="test-main">
33
+ <dmx-test-data id="rows" source="employees"></dmx-test-data>
34
+
35
+ <section class="feature">
36
+ <h2>Multi-format export</h2>
37
+ <p class="desc">
38
+ All three exporters enabled. Buttons call <code>exportGrid('csv'|'xls'|'pdf')</code>.
39
+ Use the file save dialog to confirm filenames.
40
+ </p>
41
+
42
+ <div class="grid-wrap">
43
+ <dmx-ag-grid
44
+ id="expGrid"
45
+ dmx-bind:data="rows.value"
46
+ grid_theme="ag-theme-alpine"
47
+ dmx-bind:export_to_csv="true" export_csv_filename="employees-export.csv"
48
+ dmx-bind:export_to_xls="true" export_xls_filename="employees-export.xlsx"
49
+ dmx-bind:export_to_pdf="true" export_pdf_filename="employees-export.pdf"
50
+ dmx-bind:export_trim_data="true"
51
+ dmx-bind:export_remove_html="true"
52
+ dmx-bind:export_exclude_hidden_fields="true"
53
+ export_exclude_fields="email"
54
+ dmx-bind:hide_fields="rating"
55
+ dmx-bind:pagination="false">
56
+ </dmx-ag-grid>
57
+ </div>
58
+
59
+ <div class="controls" style="margin-top: 12px;">
60
+ <button class="primary" onclick="TestKit.callMethod('expGrid','exportGrid','csv')">Export CSV</button>
61
+ <button onclick="TestKit.callMethod('expGrid','exportGrid','xls')">Export XLSX</button>
62
+ <button onclick="TestKit.callMethod('expGrid','exportGrid','pdf')">Export PDF</button>
63
+ </div>
64
+ </section>
65
+
66
+ <section class="feature">
67
+ <h2>Export with no options</h2>
68
+ <p class="desc">Disable all exporters. Calling <code>exportGrid()</code> should log an error (still callable but harmless).</p>
69
+ <div class="grid-wrap">
70
+ <dmx-ag-grid id="noExp" dmx-bind:data="rows.value" grid_theme="ag-theme-alpine"
71
+ dmx-bind:export_to_csv="false" dmx-bind:export_to_xls="false" dmx-bind:export_to_pdf="false"
72
+ dmx-bind:pagination="false"></dmx-ag-grid>
73
+ </div>
74
+ <div class="controls">
75
+ <button onclick="TestKit.callMethod('noExp','exportGrid','csv')">exportGrid('csv') — should warn</button>
76
+ </div>
77
+ </section>
78
+ </main>
79
+ </body>
80
+ </html>