@adaptabletools/adaptable 23.0.3 → 23.0.4

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": "@adaptabletools/adaptable",
3
- "version": "23.0.3",
3
+ "version": "23.0.4",
4
4
  "description": "Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements",
5
5
  "keywords": [
6
6
  "web-components",
@@ -48,7 +48,6 @@
48
48
  "@tanstack/react-virtual": "^3.13.22",
49
49
  "class-variance-authority": "^0.7.1",
50
50
  "clsx": "^2.1.1",
51
- "cron-parser": "^4.9.0",
52
51
  "date-fns": "^4.1.0",
53
52
  "lucide-react": "^0.563.0",
54
53
  "normalize.css": "^8.0.1",
@@ -38,6 +38,24 @@ export interface GridApi {
38
38
  * Retrieves visible data from the grid (filtered and sorted)
39
39
  */
40
40
  getVisibleData(): any[];
41
+ /**
42
+ * Retrieves all the values for a single Column.
43
+ *
44
+ * @param columnId the Column to read the values from
45
+ */
46
+ getColumnData(columnId: string): any[];
47
+ /**
48
+ * Retrieves the filtered values for a single Column.
49
+ *
50
+ * @param columnId the Column to read the values from
51
+ */
52
+ getFilteredColumnData(columnId: string): any[];
53
+ /**
54
+ * Retrieves the visible (filtered and sorted) values for a single Column.
55
+ *
56
+ * @param columnId the Column to read the values from
57
+ */
58
+ getVisibleColumnData(columnId: string): any[];
41
59
  /**
42
60
  * Loads data into grid and fire a `RowChanged.trigger='Load'` event
43
61
  * @param data data to load
@@ -27,6 +27,9 @@ export declare class GridApiImpl extends ApiBase implements GridApi {
27
27
  getGridData(): any[];
28
28
  getFilteredData(): any[];
29
29
  getVisibleData(): any[];
30
+ getColumnData(columnId: string): any[];
31
+ getFilteredColumnData(columnId: string): any[];
32
+ getVisibleColumnData(columnId: string): any[];
30
33
  updateGridData(dataRows: any[], dataUpdateConfig?: DataUpdateConfig): Promise<IRowNode[]>;
31
34
  addOrUpdateGridData(dataRows: any[], dataUpdateConfig?: DataUpdateConfig): Promise<{
32
35
  addedRows: IRowNode[];
@@ -47,6 +47,33 @@ export class GridApiImpl extends ApiBase {
47
47
  });
48
48
  return data;
49
49
  }
50
+ getColumnData(columnId) {
51
+ const data = [];
52
+ this._adaptable.forAllRowNodesDo((rowNode) => {
53
+ if (!this.isGroupRowNode(rowNode)) {
54
+ data.push(this.getRawValueFromRowNode(rowNode, columnId));
55
+ }
56
+ });
57
+ return data;
58
+ }
59
+ getFilteredColumnData(columnId) {
60
+ const data = [];
61
+ this.getAgGridApi().forEachNodeAfterFilter((rowNode) => {
62
+ if (!this.isGroupRowNode(rowNode)) {
63
+ data.push(this.getRawValueFromRowNode(rowNode, columnId));
64
+ }
65
+ });
66
+ return data;
67
+ }
68
+ getVisibleColumnData(columnId) {
69
+ const data = [];
70
+ this.getAdaptableInternalApi().forAllVisibleRowNodesDo((rowNode) => {
71
+ if (!this.isGroupRowNode(rowNode)) {
72
+ data.push(this.getRawValueFromRowNode(rowNode, columnId));
73
+ }
74
+ });
75
+ return data;
76
+ }
50
77
  async updateGridData(dataRows, dataUpdateConfig) {
51
78
  const rowNodes = await this._adaptable.updateRows(dataRows, dataUpdateConfig);
52
79
  const rowDataChangedInfo = this.getAdaptableInternalApi().buildRowDataChangedInfo(dataRows, rowNodes, 'Update');
@@ -1,3 +1,4 @@
1
+ import type { AgChartInstance, AgSparklineOptions } from 'ag-charts-types';
1
2
  import { ApiBase } from './ApiBase';
2
3
  import { StyledColumnApi } from '../StyledColumnApi';
3
4
  import { StyledColumn, StyledColumnState } from '../../AdaptableState/StyledColumnState';
@@ -25,6 +26,7 @@ export declare class StyledColumnApiImpl extends ApiBase implements StyledColumn
25
26
  hasBulletChartStyle(columnId: string): boolean;
26
27
  hasRatingStyle(columnId: string): boolean;
27
28
  canDisplaySparklines(): boolean;
29
+ renderSparkline(options: AgSparklineOptions): AgChartInstance<AgSparklineOptions> | null;
28
30
  suspendStyledColumn(styledColumn: StyledColumn): void;
29
31
  unSuspendStyledColumn(styledColumn: StyledColumn): void;
30
32
  suspendAllStyledColumn(): void;
@@ -79,6 +79,9 @@ export class StyledColumnApiImpl extends ApiBase {
79
79
  canDisplaySparklines() {
80
80
  return this._adaptable.canDisplaySparklines();
81
81
  }
82
+ renderSparkline(options) {
83
+ return this.internalApi.createSparkline(options);
84
+ }
82
85
  suspendStyledColumn(styledColumn) {
83
86
  this.dispatchAction(StyledColumnRedux.StyledColumnSuspend(styledColumn));
84
87
  }
@@ -4,8 +4,18 @@ import { StyledColumn } from '../../AdaptableState/StyledColumnState';
4
4
  import { CellColorRange, ColumnComparison, NumericStyledColumn } from '../../AdaptableState/StyledColumns/Common/NumericStyledColumn';
5
5
  import { BadgeStyle, BadgeStyleDefinition } from '../../AdaptableState/StyledColumns/BadgeStyle';
6
6
  import { IRowNode } from 'ag-grid-enterprise';
7
+ import type { AgChartInstance, AgSparklineOptions } from 'ag-charts-types';
7
8
  import { PredicateDefHandlerContext } from '../../types';
8
9
  export declare class StyledColumnInternalApi extends ApiBase {
10
+ /**
11
+ * Creates a sparkline described by `options` in its target container and
12
+ * returns the chart instance (used to update / destroy it).
13
+ *
14
+ * Centralises sparkline creation so view components don't import
15
+ * `ag-charts-enterprise` directly: the `createSparkline` factory is sourced
16
+ * from the AG Grid Sparklines module via the grid's registry bean.
17
+ */
18
+ createSparkline(options: AgSparklineOptions): AgChartInstance<AgSparklineOptions> | null;
9
19
  getMinValueForNumericColumn(column: AdaptableColumn | undefined): number | undefined;
10
20
  getMaxValueForNumericColumn(column: AdaptableColumn | undefined): number | undefined;
11
21
  getAvgValueForNumericColumn(column: AdaptableColumn | undefined): number | undefined;
@@ -10,6 +10,26 @@ const DYNAMIC_RANGE_ENDPOINTS = [
10
10
  const isDynamicRangeEndpoint = (value) => typeof value === 'string' &&
11
11
  DYNAMIC_RANGE_ENDPOINTS.includes(value);
12
12
  export class StyledColumnInternalApi extends ApiBase {
13
+ /**
14
+ * Creates a sparkline described by `options` in its target container and
15
+ * returns the chart instance (used to update / destroy it).
16
+ *
17
+ * Centralises sparkline creation so view components don't import
18
+ * `ag-charts-enterprise` directly: the `createSparkline` factory is sourced
19
+ * from the AG Grid Sparklines module via the grid's registry bean.
20
+ */
21
+ createSparkline(options) {
22
+ if (!this.getStyledColumnApi().canDisplaySparklines()) {
23
+ this.logWarn('Cannot render Sparkline: AG Grid Sparklines are not enabled. Register the AG Grid Sparklines module (e.g. `AllEnterpriseModule.with(AgChartsEnterpriseModule)`) to use Sparklines.');
24
+ return null;
25
+ }
26
+ const createSparklineFactory = this._adaptable.agGridAdapter.DANGER_getCreateSparkline();
27
+ if (!createSparklineFactory) {
28
+ this.logWarn('Cannot render Sparkline: unable to obtain the AG Grid Sparkline rendering factory.');
29
+ return null;
30
+ }
31
+ return createSparklineFactory(options);
32
+ }
13
33
  getMinValueForNumericColumn(column) {
14
34
  if (!column || column.dataType !== 'number') {
15
35
  return undefined;
@@ -1,3 +1,4 @@
1
+ import type { AgChartInstance, AgSparklineOptions } from 'ag-charts-types';
1
2
  import { AdaptableColumn } from '../AdaptableState/Common/AdaptableColumn';
2
3
  import { StyledColumn, StyledColumnState } from '../AdaptableState/StyledColumnState';
3
4
  import { LayoutExtendedConfig } from '../types';
@@ -117,4 +118,17 @@ export interface StyledColumnApi {
117
118
  * Can this AdapTable instance display Sparklines (e.g. is AG Grid SparklinesModule installed)
118
119
  */
119
120
  canDisplaySparklines(): boolean;
121
+ /**
122
+ * Renders a standalone [Sparkline](https://www.ag-grid.com/javascript-data-grid/sparklines-overview/)
123
+ * into a DOM element you provide, using the same AG Charts engine as Sparkline Styled Columns.
124
+ *
125
+ * Provide at least `container` (where to render) and `data` (what to plot) on `options`; see
126
+ * [AgSparklineOptions](https://www.ag-grid.com/javascript-data-grid/sparklines-overview/) for the
127
+ * full set (`type`, `width`/`height`, `min`/`max`, etc.).
128
+ *
129
+ * The caller owns the returned instance and is responsible for its lifecycle: call `update()` to
130
+ * re-render it when the data or options change, and `destroy()` to dispose of it (e.g. when the
131
+ * `container` is removed) to avoid memory leaks. AdapTable does not track or clean it up for you.
132
+ */
133
+ renderSparkline(options: AgSparklineOptions): AgChartInstance<AgSparklineOptions> | null;
120
134
  }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Lightweight, dependency-free parser for standard 5-field cron expressions:
3
+ *
4
+ * minute hour day-of-month month day-of-week
5
+ *
6
+ * Each field supports:
7
+ * - `*` — every value in the field range
8
+ * - A single integer (e.g. `9`)
9
+ * - A comma-separated list (e.g. `1,3,5`)
10
+ * - A range (e.g. `1-5`)
11
+ * - A step (e.g. `* /15`, `0-30/5`)
12
+ *
13
+ * For day-of-week, both `0` and `7` represent Sunday.
14
+ *
15
+ * This module exists to keep AdapTable free of the `cron-parser` package (which
16
+ * transitively pulls in `luxon`). AdapTable only uses cron expressions in the
17
+ * Scheduling system, and only ever needs to:
18
+ * 1. validate a user-entered cron string, and
19
+ * 2. compute the next fire time from "now".
20
+ */
21
+ interface ParsedCron {
22
+ minute: Set<number>;
23
+ hour: Set<number>;
24
+ dayOfMonth: Set<number>;
25
+ month: Set<number>;
26
+ dayOfWeek: Set<number>;
27
+ /** True when the day-of-month field is `*` (i.e. unrestricted). */
28
+ dayOfMonthIsStar: boolean;
29
+ /** True when the day-of-week field is `*` (i.e. unrestricted). */
30
+ dayOfWeekIsStar: boolean;
31
+ }
32
+ /**
33
+ * Parses a 5-field cron expression. Throws when the expression is invalid.
34
+ */
35
+ export declare function parseCronExpression(expression: string): ParsedCron;
36
+ /**
37
+ * Returns true if the given expression is a valid 5-field cron expression.
38
+ */
39
+ export declare function isCronExpressionValid(expression: string): boolean;
40
+ /**
41
+ * Returns the next time the cron expression fires after `fromDate` (exclusive).
42
+ * Returns null if no match is found within a 4-year horizon.
43
+ */
44
+ export declare function getNextCronOccurrence(expression: string, fromDate?: Date): Date | null;
45
+ export {};
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Lightweight, dependency-free parser for standard 5-field cron expressions:
3
+ *
4
+ * minute hour day-of-month month day-of-week
5
+ *
6
+ * Each field supports:
7
+ * - `*` — every value in the field range
8
+ * - A single integer (e.g. `9`)
9
+ * - A comma-separated list (e.g. `1,3,5`)
10
+ * - A range (e.g. `1-5`)
11
+ * - A step (e.g. `* /15`, `0-30/5`)
12
+ *
13
+ * For day-of-week, both `0` and `7` represent Sunday.
14
+ *
15
+ * This module exists to keep AdapTable free of the `cron-parser` package (which
16
+ * transitively pulls in `luxon`). AdapTable only uses cron expressions in the
17
+ * Scheduling system, and only ever needs to:
18
+ * 1. validate a user-entered cron string, and
19
+ * 2. compute the next fire time from "now".
20
+ */
21
+ const MINUTE_RANGE = [0, 59];
22
+ const HOUR_RANGE = [0, 23];
23
+ const DAY_OF_MONTH_RANGE = [1, 31];
24
+ const MONTH_RANGE = [1, 12];
25
+ const FIELD_LABELS = ['minute', 'hour', 'day-of-month', 'month', 'day-of-week'];
26
+ /**
27
+ * Parses a 5-field cron expression. Throws when the expression is invalid.
28
+ */
29
+ export function parseCronExpression(expression) {
30
+ if (!expression || typeof expression !== 'string') {
31
+ throw new Error('Cron expression is empty');
32
+ }
33
+ const parts = expression.trim().split(/\s+/);
34
+ if (parts.length !== 5) {
35
+ throw new Error(`Expected 5 cron fields (minute hour day-of-month month day-of-week) but got ${parts.length}`);
36
+ }
37
+ const minute = parseField(parts[0], MINUTE_RANGE, FIELD_LABELS[0]);
38
+ const hour = parseField(parts[1], HOUR_RANGE, FIELD_LABELS[1]);
39
+ const dayOfMonth = parseField(parts[2], DAY_OF_MONTH_RANGE, FIELD_LABELS[2]);
40
+ const month = parseField(parts[3], MONTH_RANGE, FIELD_LABELS[3]);
41
+ const dayOfWeek = parseDayOfWeekField(parts[4]);
42
+ return {
43
+ minute,
44
+ hour,
45
+ dayOfMonth,
46
+ month,
47
+ dayOfWeek,
48
+ dayOfMonthIsStar: parts[2] === '*',
49
+ dayOfWeekIsStar: parts[4] === '*',
50
+ };
51
+ }
52
+ /**
53
+ * Returns true if the given expression is a valid 5-field cron expression.
54
+ */
55
+ export function isCronExpressionValid(expression) {
56
+ try {
57
+ parseCronExpression(expression);
58
+ return true;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ }
64
+ /**
65
+ * Returns the next time the cron expression fires after `fromDate` (exclusive).
66
+ * Returns null if no match is found within a 4-year horizon.
67
+ */
68
+ export function getNextCronOccurrence(expression, fromDate = new Date()) {
69
+ const cron = parseCronExpression(expression);
70
+ // Bump to the start of the next minute - cron has minute granularity and
71
+ // we never want to return `fromDate` itself.
72
+ const next = new Date(fromDate.getTime());
73
+ next.setSeconds(0, 0);
74
+ next.setMinutes(next.getMinutes() + 1);
75
+ // Safety horizon — patterns like "0 0 31 2 *" (31 Feb) can never match.
76
+ const horizon = new Date(next.getTime());
77
+ horizon.setFullYear(horizon.getFullYear() + 4);
78
+ while (next < horizon) {
79
+ if (!cron.month.has(next.getMonth() + 1)) {
80
+ // Jump to the 1st of the next month.
81
+ next.setDate(1);
82
+ next.setHours(0, 0, 0, 0);
83
+ next.setMonth(next.getMonth() + 1);
84
+ continue;
85
+ }
86
+ if (!matchesDay(cron, next)) {
87
+ next.setHours(0, 0, 0, 0);
88
+ next.setDate(next.getDate() + 1);
89
+ continue;
90
+ }
91
+ if (!cron.hour.has(next.getHours())) {
92
+ next.setMinutes(0, 0, 0);
93
+ next.setHours(next.getHours() + 1);
94
+ continue;
95
+ }
96
+ if (!cron.minute.has(next.getMinutes())) {
97
+ next.setSeconds(0, 0);
98
+ next.setMinutes(next.getMinutes() + 1);
99
+ continue;
100
+ }
101
+ return next;
102
+ }
103
+ return null;
104
+ }
105
+ /**
106
+ * Standard cron day matching:
107
+ * - if both day-of-month and day-of-week are `*`, the day always matches
108
+ * - if only one is `*`, only the other is applied
109
+ * - if neither is `*`, the day matches when **either** matches (OR semantics)
110
+ */
111
+ function matchesDay(cron, date) {
112
+ const domMatches = cron.dayOfMonth.has(date.getDate());
113
+ const dowMatches = cron.dayOfWeek.has(date.getDay());
114
+ if (cron.dayOfMonthIsStar && cron.dayOfWeekIsStar) {
115
+ return true;
116
+ }
117
+ if (cron.dayOfMonthIsStar) {
118
+ return dowMatches;
119
+ }
120
+ if (cron.dayOfWeekIsStar) {
121
+ return domMatches;
122
+ }
123
+ return domMatches || dowMatches;
124
+ }
125
+ function parseField(field, range, label) {
126
+ const [min, max] = range;
127
+ const values = new Set();
128
+ const segments = field.split(',');
129
+ for (const raw of segments) {
130
+ const segment = raw.trim();
131
+ if (segment === '') {
132
+ throw new Error(`Invalid ${label} field "${field}"`);
133
+ }
134
+ const [rangePart, stepPart] = segment.split('/');
135
+ const step = stepPart === undefined ? 1 : Number(stepPart);
136
+ if (!Number.isInteger(step) || step <= 0) {
137
+ throw new Error(`Invalid step value in ${label} field "${segment}"`);
138
+ }
139
+ let from;
140
+ let to;
141
+ if (rangePart === '*') {
142
+ from = min;
143
+ to = max;
144
+ }
145
+ else if (rangePart.includes('-')) {
146
+ const [fromStr, toStr] = rangePart.split('-');
147
+ from = Number(fromStr);
148
+ to = Number(toStr);
149
+ }
150
+ else {
151
+ from = Number(rangePart);
152
+ to = from;
153
+ }
154
+ if (!Number.isInteger(from) || !Number.isInteger(to)) {
155
+ throw new Error(`Invalid ${label} field "${segment}"`);
156
+ }
157
+ if (from < min || to > max || from > to) {
158
+ throw new Error(`Out-of-range ${label} field "${segment}" (expected ${min}-${max})`);
159
+ }
160
+ for (let v = from; v <= to; v += step) {
161
+ values.add(v);
162
+ }
163
+ }
164
+ if (values.size === 0) {
165
+ throw new Error(`Empty ${label} field`);
166
+ }
167
+ return values;
168
+ }
169
+ function parseDayOfWeekField(field) {
170
+ // Cron allows 0 or 7 to represent Sunday — parse with an extended range
171
+ // [0,7] and then collapse 7 → 0 so callers can compare against
172
+ // `Date.getDay()` which returns 0-6.
173
+ const extended = parseField(field, [0, 7], 'day-of-week');
174
+ const normalised = new Set();
175
+ for (const value of extended) {
176
+ normalised.add(value === 7 ? 0 : value);
177
+ }
178
+ return normalised;
179
+ }
@@ -1,5 +1,5 @@
1
- import { parseExpression } from 'cron-parser';
2
1
  import StringExtensions from '../../Extensions/StringExtensions';
2
+ import { getNextCronOccurrence, isCronExpressionValid as isCronExpressionValidInternal, } from './CronExpression';
3
3
  const WEEKDAY_TO_CRON = {
4
4
  Sunday: 0,
5
5
  Monday: 1,
@@ -123,11 +123,9 @@ export function getNextRunDateFromSchedule(schedule) {
123
123
  if (!schedule.CronExpression?.trim()) {
124
124
  return null;
125
125
  }
126
- const interval = parseExpression(schedule.CronExpression.trim(), {
127
- currentDate: new Date(),
128
- });
129
- const next = interval.next().toDate();
130
- return next > new Date() ? next : null;
126
+ const now = new Date();
127
+ const next = getNextCronOccurrence(schedule.CronExpression.trim(), now);
128
+ return next && next > now ? next : null;
131
129
  }
132
130
  catch {
133
131
  return null;
@@ -154,13 +152,10 @@ export function isScheduleValid(schedule) {
154
152
  if (preset === 'selectedDays' && days.length === 0) {
155
153
  return 'Select at least one day';
156
154
  }
157
- try {
158
- parseExpression(schedule.CronExpression.trim());
159
- return true;
160
- }
161
- catch {
155
+ if (!isCronExpressionValidInternal(schedule.CronExpression.trim())) {
162
156
  return 'Cron expression is not valid';
163
157
  }
158
+ return true;
164
159
  }
165
160
  export function getScheduleDescription(schedule) {
166
161
  if (!schedule) {
@@ -226,11 +221,5 @@ export function isValidCronExpression(expression) {
226
221
  if (StringExtensions.IsNullOrEmpty(expression)) {
227
222
  return false;
228
223
  }
229
- try {
230
- parseExpression(expression.trim());
231
- return true;
232
- }
233
- catch {
234
- return false;
235
- }
224
+ return isCronExpressionValidInternal(expression.trim());
236
225
  }
@@ -1,6 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
- import { AgChartsEnterpriseModule } from 'ag-charts-enterprise';
4
3
  import { AdaptableHelper } from '../../../../../Utilities/Helpers/AdaptableHelper';
5
4
  import { resolveSparklineOptionsForRender } from '../../../../../Utilities/Helpers/StyledColumns/SparklineStyleHelper';
6
5
  import { convertAdaptableStyleToCSS, hasCellBoxStyle, } from '../../../../../Utilities/Helpers/StyleHelper';
@@ -53,23 +52,6 @@ const buildSparklinePreviewOptions = (sparklineStyle, container, data, width, he
53
52
  }
54
53
  return options;
55
54
  };
56
- /**
57
- * AG Grid registers chart modules via `AgChartsEnterpriseModule.setup()` when
58
- * sparklines are enabled. Standalone `AgCharts.createSparkline` needs the same
59
- * setup — otherwise the settings-panel preview throws "No modules registered".
60
- */
61
- let agChartsPreviewModulesReady = false;
62
- const ensureAgChartsEnterpriseModules = () => {
63
- if (agChartsPreviewModulesReady) {
64
- return;
65
- }
66
- AgChartsEnterpriseModule.setup();
67
- agChartsPreviewModulesReady = true;
68
- };
69
- const createSparkline = (options) => {
70
- ensureAgChartsEnterpriseModules();
71
- return AgChartsEnterpriseModule.createSparkline(options);
72
- };
73
55
  const SparklinePreviewCanvas = ({ sparklineStyle, columnId }) => {
74
56
  const adaptable = useAdaptable();
75
57
  const containerRef = React.useRef(null);
@@ -93,7 +75,7 @@ const SparklinePreviewCanvas = ({ sparklineStyle, columnId }) => {
93
75
  const options = buildSparklinePreviewOptions(sparklineStyle, container, data, width, PREVIEW_HEIGHT);
94
76
  try {
95
77
  if (!instanceRef.current) {
96
- instanceRef.current = createSparkline(options);
78
+ instanceRef.current = adaptable.api.styledColumnApi.internalApi.createSparkline(options);
97
79
  }
98
80
  else {
99
81
  instanceRef.current.update(options);
@@ -1,4 +1,5 @@
1
1
  import { ColDef, ColGroupDef, Column, GridApi, GridOptions, IRowNode, ManagedGridOptionKey, ManagedGridOptions, Module } from 'ag-grid-enterprise';
2
+ import type { AgChartInstance, AgSparklineOptions } from 'ag-charts-types';
2
3
  import { AdaptableAgGrid } from './AdaptableAgGrid';
3
4
  import { AdaptableColumn, AdaptableColumnGroup } from '../AdaptableState/Common/AdaptableColumn';
4
5
  import { SelectedCellInfo } from '../AdaptableState/Selection/SelectedCellInfo';
@@ -31,6 +32,7 @@ export declare class AgGridAdapter {
31
32
  monkeyPatchingAggColumnFilters(): void;
32
33
  monkeyPatchingAggFuncLabels(): void;
33
34
  private DANGER_getPrivateAgGridBeans;
35
+ DANGER_getCreateSparkline(): ((options: AgSparklineOptions) => AgChartInstance<AgSparklineOptions>) | undefined;
34
36
  DANGER_getLiveGridOptions(): GridOptions<any>;
35
37
  getAgGridRootElement(): HTMLElement;
36
38
  /**
@@ -239,6 +239,16 @@ export class AgGridAdapter {
239
239
  }
240
240
  return beans;
241
241
  }
242
+ // #sparkline_factory
243
+ // The AG Grid Sparklines module stores the `createSparkline` factory (sourced from
244
+ // `AgChartsEnterpriseModule`) in the registered `agSparklineCellRenderer` default params.
245
+ // We read it straight from the registry bean so Adaptable can render standalone sparkline
246
+ // previews without taking a direct dependency on `ag-charts-enterprise`.
247
+ DANGER_getCreateSparkline() {
248
+ const registry = this.DANGER_getPrivateAgGridBeans()?.registry;
249
+ const sparklineComponent = registry?.getUserComponent('agSparklineCellRenderer', 'agSparklineCellRenderer');
250
+ return sparklineComponent?.params?.createSparkline;
251
+ }
242
252
  DANGER_getLiveGridOptions() {
243
253
  return this.DANGER_getPrivateAgGridBeans()?.gridOptions;
244
254
  }
package/src/env.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export default {
2
2
  NEXT_PUBLIC_INFINITE_TABLE_LICENSE_KEY: "StartDate=2021-06-29|EndDate=2030-01-01|Owner=Adaptable|Type=distribution|TS=1624971462479|C=137829811,1004007071,2756196225,1839832928,3994409405,636616862" || '',
3
- PUBLISH_TIMESTAMP: 1782392443346 || Date.now(),
4
- VERSION: "23.0.3" || '--current-version--',
3
+ PUBLISH_TIMESTAMP: 1782415229232 || Date.now(),
4
+ VERSION: "23.0.4" || '--current-version--',
5
5
  };