@adaptabletools/adaptable-cjs 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 +1 -2
- package/src/Api/GridApi.d.ts +18 -0
- package/src/Api/Implementation/GridApiImpl.d.ts +3 -0
- package/src/Api/Implementation/GridApiImpl.js +27 -0
- package/src/Api/Implementation/StyledColumnApiImpl.d.ts +2 -0
- package/src/Api/Implementation/StyledColumnApiImpl.js +3 -0
- package/src/Api/Internal/StyledColumnInternalApi.d.ts +10 -0
- package/src/Api/Internal/StyledColumnInternalApi.js +20 -0
- package/src/Api/StyledColumnApi.d.ts +14 -0
- package/src/Utilities/Helpers/Scheduling/CronExpression.d.ts +45 -0
- package/src/Utilities/Helpers/Scheduling/CronExpression.js +184 -0
- package/src/Utilities/Helpers/Scheduling/ScheduleHelper.js +7 -18
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/Components/StyledColumnSparklinePreview.js +1 -19
- package/src/agGrid/AgGridAdapter.d.ts +2 -0
- package/src/agGrid/AgGridAdapter.js +10 -0
- package/src/env.js +2 -2
- package/tsconfig.cjs.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaptabletools/adaptable-cjs",
|
|
3
|
-
"version": "23.0.
|
|
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",
|
|
@@ -49,7 +49,6 @@
|
|
|
49
49
|
"@tanstack/react-virtual": "^3.13.22",
|
|
50
50
|
"class-variance-authority": "^0.7.1",
|
|
51
51
|
"clsx": "^2.1.1",
|
|
52
|
-
"cron-parser": "^4.9.0",
|
|
53
52
|
"date-fns": "^4.1.0",
|
|
54
53
|
"lucide-react": "^0.563.0",
|
|
55
54
|
"normalize.css": "^8.0.1",
|
package/src/Api/GridApi.d.ts
CHANGED
|
@@ -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[];
|
|
@@ -51,6 +51,33 @@ class GridApiImpl extends ApiBase_1.ApiBase {
|
|
|
51
51
|
});
|
|
52
52
|
return data;
|
|
53
53
|
}
|
|
54
|
+
getColumnData(columnId) {
|
|
55
|
+
const data = [];
|
|
56
|
+
this._adaptable.forAllRowNodesDo((rowNode) => {
|
|
57
|
+
if (!this.isGroupRowNode(rowNode)) {
|
|
58
|
+
data.push(this.getRawValueFromRowNode(rowNode, columnId));
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return data;
|
|
62
|
+
}
|
|
63
|
+
getFilteredColumnData(columnId) {
|
|
64
|
+
const data = [];
|
|
65
|
+
this.getAgGridApi().forEachNodeAfterFilter((rowNode) => {
|
|
66
|
+
if (!this.isGroupRowNode(rowNode)) {
|
|
67
|
+
data.push(this.getRawValueFromRowNode(rowNode, columnId));
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
return data;
|
|
71
|
+
}
|
|
72
|
+
getVisibleColumnData(columnId) {
|
|
73
|
+
const data = [];
|
|
74
|
+
this.getAdaptableInternalApi().forAllVisibleRowNodesDo((rowNode) => {
|
|
75
|
+
if (!this.isGroupRowNode(rowNode)) {
|
|
76
|
+
data.push(this.getRawValueFromRowNode(rowNode, columnId));
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return data;
|
|
80
|
+
}
|
|
54
81
|
async updateGridData(dataRows, dataUpdateConfig) {
|
|
55
82
|
const rowNodes = await this._adaptable.updateRows(dataRows, dataUpdateConfig);
|
|
56
83
|
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;
|
|
@@ -83,6 +83,9 @@ class StyledColumnApiImpl extends ApiBase_1.ApiBase {
|
|
|
83
83
|
canDisplaySparklines() {
|
|
84
84
|
return this._adaptable.canDisplaySparklines();
|
|
85
85
|
}
|
|
86
|
+
renderSparkline(options) {
|
|
87
|
+
return this.internalApi.createSparkline(options);
|
|
88
|
+
}
|
|
86
89
|
suspendStyledColumn(styledColumn) {
|
|
87
90
|
this.dispatchAction(StyledColumnRedux.StyledColumnSuspend(styledColumn));
|
|
88
91
|
}
|
|
@@ -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;
|
|
@@ -14,6 +14,26 @@ const DYNAMIC_RANGE_ENDPOINTS = [
|
|
|
14
14
|
const isDynamicRangeEndpoint = (value) => typeof value === 'string' &&
|
|
15
15
|
DYNAMIC_RANGE_ENDPOINTS.includes(value);
|
|
16
16
|
class StyledColumnInternalApi extends ApiBase_1.ApiBase {
|
|
17
|
+
/**
|
|
18
|
+
* Creates a sparkline described by `options` in its target container and
|
|
19
|
+
* returns the chart instance (used to update / destroy it).
|
|
20
|
+
*
|
|
21
|
+
* Centralises sparkline creation so view components don't import
|
|
22
|
+
* `ag-charts-enterprise` directly: the `createSparkline` factory is sourced
|
|
23
|
+
* from the AG Grid Sparklines module via the grid's registry bean.
|
|
24
|
+
*/
|
|
25
|
+
createSparkline(options) {
|
|
26
|
+
if (!this.getStyledColumnApi().canDisplaySparklines()) {
|
|
27
|
+
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.');
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const createSparklineFactory = this._adaptable.agGridAdapter.DANGER_getCreateSparkline();
|
|
31
|
+
if (!createSparklineFactory) {
|
|
32
|
+
this.logWarn('Cannot render Sparkline: unable to obtain the AG Grid Sparkline rendering factory.');
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return createSparklineFactory(options);
|
|
36
|
+
}
|
|
17
37
|
getMinValueForNumericColumn(column) {
|
|
18
38
|
if (!column || column.dataType !== 'number') {
|
|
19
39
|
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,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Lightweight, dependency-free parser for standard 5-field cron expressions:
|
|
4
|
+
*
|
|
5
|
+
* minute hour day-of-month month day-of-week
|
|
6
|
+
*
|
|
7
|
+
* Each field supports:
|
|
8
|
+
* - `*` — every value in the field range
|
|
9
|
+
* - A single integer (e.g. `9`)
|
|
10
|
+
* - A comma-separated list (e.g. `1,3,5`)
|
|
11
|
+
* - A range (e.g. `1-5`)
|
|
12
|
+
* - A step (e.g. `* /15`, `0-30/5`)
|
|
13
|
+
*
|
|
14
|
+
* For day-of-week, both `0` and `7` represent Sunday.
|
|
15
|
+
*
|
|
16
|
+
* This module exists to keep AdapTable free of the `cron-parser` package (which
|
|
17
|
+
* transitively pulls in `luxon`). AdapTable only uses cron expressions in the
|
|
18
|
+
* Scheduling system, and only ever needs to:
|
|
19
|
+
* 1. validate a user-entered cron string, and
|
|
20
|
+
* 2. compute the next fire time from "now".
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.parseCronExpression = parseCronExpression;
|
|
24
|
+
exports.isCronExpressionValid = isCronExpressionValid;
|
|
25
|
+
exports.getNextCronOccurrence = getNextCronOccurrence;
|
|
26
|
+
const MINUTE_RANGE = [0, 59];
|
|
27
|
+
const HOUR_RANGE = [0, 23];
|
|
28
|
+
const DAY_OF_MONTH_RANGE = [1, 31];
|
|
29
|
+
const MONTH_RANGE = [1, 12];
|
|
30
|
+
const FIELD_LABELS = ['minute', 'hour', 'day-of-month', 'month', 'day-of-week'];
|
|
31
|
+
/**
|
|
32
|
+
* Parses a 5-field cron expression. Throws when the expression is invalid.
|
|
33
|
+
*/
|
|
34
|
+
function parseCronExpression(expression) {
|
|
35
|
+
if (!expression || typeof expression !== 'string') {
|
|
36
|
+
throw new Error('Cron expression is empty');
|
|
37
|
+
}
|
|
38
|
+
const parts = expression.trim().split(/\s+/);
|
|
39
|
+
if (parts.length !== 5) {
|
|
40
|
+
throw new Error(`Expected 5 cron fields (minute hour day-of-month month day-of-week) but got ${parts.length}`);
|
|
41
|
+
}
|
|
42
|
+
const minute = parseField(parts[0], MINUTE_RANGE, FIELD_LABELS[0]);
|
|
43
|
+
const hour = parseField(parts[1], HOUR_RANGE, FIELD_LABELS[1]);
|
|
44
|
+
const dayOfMonth = parseField(parts[2], DAY_OF_MONTH_RANGE, FIELD_LABELS[2]);
|
|
45
|
+
const month = parseField(parts[3], MONTH_RANGE, FIELD_LABELS[3]);
|
|
46
|
+
const dayOfWeek = parseDayOfWeekField(parts[4]);
|
|
47
|
+
return {
|
|
48
|
+
minute,
|
|
49
|
+
hour,
|
|
50
|
+
dayOfMonth,
|
|
51
|
+
month,
|
|
52
|
+
dayOfWeek,
|
|
53
|
+
dayOfMonthIsStar: parts[2] === '*',
|
|
54
|
+
dayOfWeekIsStar: parts[4] === '*',
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns true if the given expression is a valid 5-field cron expression.
|
|
59
|
+
*/
|
|
60
|
+
function isCronExpressionValid(expression) {
|
|
61
|
+
try {
|
|
62
|
+
parseCronExpression(expression);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Returns the next time the cron expression fires after `fromDate` (exclusive).
|
|
71
|
+
* Returns null if no match is found within a 4-year horizon.
|
|
72
|
+
*/
|
|
73
|
+
function getNextCronOccurrence(expression, fromDate = new Date()) {
|
|
74
|
+
const cron = parseCronExpression(expression);
|
|
75
|
+
// Bump to the start of the next minute - cron has minute granularity and
|
|
76
|
+
// we never want to return `fromDate` itself.
|
|
77
|
+
const next = new Date(fromDate.getTime());
|
|
78
|
+
next.setSeconds(0, 0);
|
|
79
|
+
next.setMinutes(next.getMinutes() + 1);
|
|
80
|
+
// Safety horizon — patterns like "0 0 31 2 *" (31 Feb) can never match.
|
|
81
|
+
const horizon = new Date(next.getTime());
|
|
82
|
+
horizon.setFullYear(horizon.getFullYear() + 4);
|
|
83
|
+
while (next < horizon) {
|
|
84
|
+
if (!cron.month.has(next.getMonth() + 1)) {
|
|
85
|
+
// Jump to the 1st of the next month.
|
|
86
|
+
next.setDate(1);
|
|
87
|
+
next.setHours(0, 0, 0, 0);
|
|
88
|
+
next.setMonth(next.getMonth() + 1);
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (!matchesDay(cron, next)) {
|
|
92
|
+
next.setHours(0, 0, 0, 0);
|
|
93
|
+
next.setDate(next.getDate() + 1);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (!cron.hour.has(next.getHours())) {
|
|
97
|
+
next.setMinutes(0, 0, 0);
|
|
98
|
+
next.setHours(next.getHours() + 1);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
if (!cron.minute.has(next.getMinutes())) {
|
|
102
|
+
next.setSeconds(0, 0);
|
|
103
|
+
next.setMinutes(next.getMinutes() + 1);
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
return next;
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Standard cron day matching:
|
|
112
|
+
* - if both day-of-month and day-of-week are `*`, the day always matches
|
|
113
|
+
* - if only one is `*`, only the other is applied
|
|
114
|
+
* - if neither is `*`, the day matches when **either** matches (OR semantics)
|
|
115
|
+
*/
|
|
116
|
+
function matchesDay(cron, date) {
|
|
117
|
+
const domMatches = cron.dayOfMonth.has(date.getDate());
|
|
118
|
+
const dowMatches = cron.dayOfWeek.has(date.getDay());
|
|
119
|
+
if (cron.dayOfMonthIsStar && cron.dayOfWeekIsStar) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
if (cron.dayOfMonthIsStar) {
|
|
123
|
+
return dowMatches;
|
|
124
|
+
}
|
|
125
|
+
if (cron.dayOfWeekIsStar) {
|
|
126
|
+
return domMatches;
|
|
127
|
+
}
|
|
128
|
+
return domMatches || dowMatches;
|
|
129
|
+
}
|
|
130
|
+
function parseField(field, range, label) {
|
|
131
|
+
const [min, max] = range;
|
|
132
|
+
const values = new Set();
|
|
133
|
+
const segments = field.split(',');
|
|
134
|
+
for (const raw of segments) {
|
|
135
|
+
const segment = raw.trim();
|
|
136
|
+
if (segment === '') {
|
|
137
|
+
throw new Error(`Invalid ${label} field "${field}"`);
|
|
138
|
+
}
|
|
139
|
+
const [rangePart, stepPart] = segment.split('/');
|
|
140
|
+
const step = stepPart === undefined ? 1 : Number(stepPart);
|
|
141
|
+
if (!Number.isInteger(step) || step <= 0) {
|
|
142
|
+
throw new Error(`Invalid step value in ${label} field "${segment}"`);
|
|
143
|
+
}
|
|
144
|
+
let from;
|
|
145
|
+
let to;
|
|
146
|
+
if (rangePart === '*') {
|
|
147
|
+
from = min;
|
|
148
|
+
to = max;
|
|
149
|
+
}
|
|
150
|
+
else if (rangePart.includes('-')) {
|
|
151
|
+
const [fromStr, toStr] = rangePart.split('-');
|
|
152
|
+
from = Number(fromStr);
|
|
153
|
+
to = Number(toStr);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
from = Number(rangePart);
|
|
157
|
+
to = from;
|
|
158
|
+
}
|
|
159
|
+
if (!Number.isInteger(from) || !Number.isInteger(to)) {
|
|
160
|
+
throw new Error(`Invalid ${label} field "${segment}"`);
|
|
161
|
+
}
|
|
162
|
+
if (from < min || to > max || from > to) {
|
|
163
|
+
throw new Error(`Out-of-range ${label} field "${segment}" (expected ${min}-${max})`);
|
|
164
|
+
}
|
|
165
|
+
for (let v = from; v <= to; v += step) {
|
|
166
|
+
values.add(v);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (values.size === 0) {
|
|
170
|
+
throw new Error(`Empty ${label} field`);
|
|
171
|
+
}
|
|
172
|
+
return values;
|
|
173
|
+
}
|
|
174
|
+
function parseDayOfWeekField(field) {
|
|
175
|
+
// Cron allows 0 or 7 to represent Sunday — parse with an extended range
|
|
176
|
+
// [0,7] and then collapse 7 → 0 so callers can compare against
|
|
177
|
+
// `Date.getDay()` which returns 0-6.
|
|
178
|
+
const extended = parseField(field, [0, 7], 'day-of-week');
|
|
179
|
+
const normalised = new Set();
|
|
180
|
+
for (const value of extended) {
|
|
181
|
+
normalised.add(value === 7 ? 0 : value);
|
|
182
|
+
}
|
|
183
|
+
return normalised;
|
|
184
|
+
}
|
|
@@ -10,8 +10,8 @@ exports.isScheduleValid = isScheduleValid;
|
|
|
10
10
|
exports.getScheduleDescription = getScheduleDescription;
|
|
11
11
|
exports.isValidCronExpression = isValidCronExpression;
|
|
12
12
|
const tslib_1 = require("tslib");
|
|
13
|
-
const cron_parser_1 = require("cron-parser");
|
|
14
13
|
const StringExtensions_1 = tslib_1.__importDefault(require("../../Extensions/StringExtensions"));
|
|
14
|
+
const CronExpression_1 = require("./CronExpression");
|
|
15
15
|
const WEEKDAY_TO_CRON = {
|
|
16
16
|
Sunday: 0,
|
|
17
17
|
Monday: 1,
|
|
@@ -135,11 +135,9 @@ function getNextRunDateFromSchedule(schedule) {
|
|
|
135
135
|
if (!schedule.CronExpression?.trim()) {
|
|
136
136
|
return null;
|
|
137
137
|
}
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
const next = interval.next().toDate();
|
|
142
|
-
return next > new Date() ? next : null;
|
|
138
|
+
const now = new Date();
|
|
139
|
+
const next = (0, CronExpression_1.getNextCronOccurrence)(schedule.CronExpression.trim(), now);
|
|
140
|
+
return next && next > now ? next : null;
|
|
143
141
|
}
|
|
144
142
|
catch {
|
|
145
143
|
return null;
|
|
@@ -166,13 +164,10 @@ function isScheduleValid(schedule) {
|
|
|
166
164
|
if (preset === 'selectedDays' && days.length === 0) {
|
|
167
165
|
return 'Select at least one day';
|
|
168
166
|
}
|
|
169
|
-
|
|
170
|
-
(0, cron_parser_1.parseExpression)(schedule.CronExpression.trim());
|
|
171
|
-
return true;
|
|
172
|
-
}
|
|
173
|
-
catch {
|
|
167
|
+
if (!(0, CronExpression_1.isCronExpressionValid)(schedule.CronExpression.trim())) {
|
|
174
168
|
return 'Cron expression is not valid';
|
|
175
169
|
}
|
|
170
|
+
return true;
|
|
176
171
|
}
|
|
177
172
|
function getScheduleDescription(schedule) {
|
|
178
173
|
if (!schedule) {
|
|
@@ -238,11 +233,5 @@ function isValidCronExpression(expression) {
|
|
|
238
233
|
if (StringExtensions_1.default.IsNullOrEmpty(expression)) {
|
|
239
234
|
return false;
|
|
240
235
|
}
|
|
241
|
-
|
|
242
|
-
(0, cron_parser_1.parseExpression)(expression.trim());
|
|
243
|
-
return true;
|
|
244
|
-
}
|
|
245
|
-
catch {
|
|
246
|
-
return false;
|
|
247
|
-
}
|
|
236
|
+
return (0, CronExpression_1.isCronExpressionValid)(expression.trim());
|
|
248
237
|
}
|
|
@@ -5,7 +5,6 @@ exports.getSparklineCellChromeCss = getSparklineCellChromeCss;
|
|
|
5
5
|
const tslib_1 = require("tslib");
|
|
6
6
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
7
7
|
const React = tslib_1.__importStar(require("react"));
|
|
8
|
-
const ag_charts_enterprise_1 = require("ag-charts-enterprise");
|
|
9
8
|
const AdaptableHelper_1 = require("../../../../../Utilities/Helpers/AdaptableHelper");
|
|
10
9
|
const SparklineStyleHelper_1 = require("../../../../../Utilities/Helpers/StyledColumns/SparklineStyleHelper");
|
|
11
10
|
const StyleHelper_1 = require("../../../../../Utilities/Helpers/StyleHelper");
|
|
@@ -58,23 +57,6 @@ const buildSparklinePreviewOptions = (sparklineStyle, container, data, width, he
|
|
|
58
57
|
}
|
|
59
58
|
return options;
|
|
60
59
|
};
|
|
61
|
-
/**
|
|
62
|
-
* AG Grid registers chart modules via `AgChartsEnterpriseModule.setup()` when
|
|
63
|
-
* sparklines are enabled. Standalone `AgCharts.createSparkline` needs the same
|
|
64
|
-
* setup — otherwise the settings-panel preview throws "No modules registered".
|
|
65
|
-
*/
|
|
66
|
-
let agChartsPreviewModulesReady = false;
|
|
67
|
-
const ensureAgChartsEnterpriseModules = () => {
|
|
68
|
-
if (agChartsPreviewModulesReady) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
ag_charts_enterprise_1.AgChartsEnterpriseModule.setup();
|
|
72
|
-
agChartsPreviewModulesReady = true;
|
|
73
|
-
};
|
|
74
|
-
const createSparkline = (options) => {
|
|
75
|
-
ensureAgChartsEnterpriseModules();
|
|
76
|
-
return ag_charts_enterprise_1.AgChartsEnterpriseModule.createSparkline(options);
|
|
77
|
-
};
|
|
78
60
|
const SparklinePreviewCanvas = ({ sparklineStyle, columnId }) => {
|
|
79
61
|
const adaptable = (0, AdaptableContext_1.useAdaptable)();
|
|
80
62
|
const containerRef = React.useRef(null);
|
|
@@ -98,7 +80,7 @@ const SparklinePreviewCanvas = ({ sparklineStyle, columnId }) => {
|
|
|
98
80
|
const options = buildSparklinePreviewOptions(sparklineStyle, container, data, width, PREVIEW_HEIGHT);
|
|
99
81
|
try {
|
|
100
82
|
if (!instanceRef.current) {
|
|
101
|
-
instanceRef.current = createSparkline(options);
|
|
83
|
+
instanceRef.current = adaptable.api.styledColumnApi.internalApi.createSparkline(options);
|
|
102
84
|
}
|
|
103
85
|
else {
|
|
104
86
|
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
|
/**
|
|
@@ -243,6 +243,16 @@ class AgGridAdapter {
|
|
|
243
243
|
}
|
|
244
244
|
return beans;
|
|
245
245
|
}
|
|
246
|
+
// #sparkline_factory
|
|
247
|
+
// The AG Grid Sparklines module stores the `createSparkline` factory (sourced from
|
|
248
|
+
// `AgChartsEnterpriseModule`) in the registered `agSparklineCellRenderer` default params.
|
|
249
|
+
// We read it straight from the registry bean so Adaptable can render standalone sparkline
|
|
250
|
+
// previews without taking a direct dependency on `ag-charts-enterprise`.
|
|
251
|
+
DANGER_getCreateSparkline() {
|
|
252
|
+
const registry = this.DANGER_getPrivateAgGridBeans()?.registry;
|
|
253
|
+
const sparklineComponent = registry?.getUserComponent('agSparklineCellRenderer', 'agSparklineCellRenderer');
|
|
254
|
+
return sparklineComponent?.params?.createSparkline;
|
|
255
|
+
}
|
|
246
256
|
DANGER_getLiveGridOptions() {
|
|
247
257
|
return this.DANGER_getPrivateAgGridBeans()?.gridOptions;
|
|
248
258
|
}
|
package/src/env.js
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = {
|
|
4
4
|
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" || '',
|
|
5
|
-
PUBLISH_TIMESTAMP:
|
|
6
|
-
VERSION: "23.0.
|
|
5
|
+
PUBLISH_TIMESTAMP: 1782415257078 || Date.now(),
|
|
6
|
+
VERSION: "23.0.4" || '--current-version--',
|
|
7
7
|
};
|