@gooddata/sdk-ui-pivot 11.50.0-alpha.2 → 11.50.0-alpha.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.
Files changed (25) hide show
  1. package/esm/index.d.ts +1 -1
  2. package/esm/index.d.ts.map +1 -1
  3. package/esm/next/features/columns/applyAllFeaturesToColDef.d.ts +3 -2
  4. package/esm/next/features/columns/applyAllFeaturesToColDef.d.ts.map +1 -1
  5. package/esm/next/features/columns/applyAllFeaturesToColDef.js +2 -2
  6. package/esm/next/features/columns/applyConditionalFormattingToColDef.d.ts +2 -2
  7. package/esm/next/features/columns/applyConditionalFormattingToColDef.d.ts.map +1 -1
  8. package/esm/next/features/columns/applyConditionalFormattingToColDef.js +2 -2
  9. package/esm/next/features/data/createServerSideDataSource.d.ts.map +1 -1
  10. package/esm/next/features/data/createServerSideDataSource.js +2 -1
  11. package/esm/next/features/data/dataViewToColDefs.d.ts.map +1 -1
  12. package/esm/next/features/data/dataViewToColDefs.js +6 -1
  13. package/esm/next/features/styling/conditionalFormatting.d.ts +12 -2
  14. package/esm/next/features/styling/conditionalFormatting.d.ts.map +1 -1
  15. package/esm/next/features/styling/conditionalFormatting.js +82 -6
  16. package/esm/next/features/styling/dateConditionResolution.d.ts +89 -0
  17. package/esm/next/features/styling/dateConditionResolution.d.ts.map +1 -0
  18. package/esm/next/features/styling/dateConditionResolution.js +346 -0
  19. package/esm/next/index.d.ts +2 -1
  20. package/esm/next/index.d.ts.map +1 -1
  21. package/esm/next/index.js +2 -0
  22. package/esm/next/types/conditionalFormatting.d.ts +70 -9
  23. package/esm/next/types/conditionalFormatting.d.ts.map +1 -1
  24. package/esm/sdk-ui-pivot.d.ts +51 -8
  25. package/package.json +13 -13
package/esm/index.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  */
9
9
  export { PivotTable, pivotTableMenuForCapabilities, getPivotTableDimensions } from "./PivotTable.js";
10
10
  export { CorePivotTable } from "./CorePivotTable.js";
11
- export { PivotTableNext, type IPivotTableNextProps, type PivotTableNextConfig, type PivotTableNextAccessibilityConfig, type PivotTableNextTranspositionConfig, type PivotTableNextTextWrappingConfig, type PivotTableNextColumnsSizingConfig, type PivotTableNextMenuConfig, type PivotTableNextFormattingConfig, type PivotTableNextExecutionCancellingConfig, type PivotTableNextLayoutConfig, type PivotTableNextGrandTotalsPositionConfig, type PivotTableNextCellSelectionConfig, type PivotTableNextAgGridLicenseConfig, type PivotTableNextPaginationConfig, type PivotTableNextExperimentalConfig, type PivotTableNextConditionalFormattingConfig, type IConditionalFormatting, type IConditionalFormattingRule, type IConditionalFormattingCondition, type IConditionalFormattingFormat, type ConditionalFormattingTarget, type ConditionalFormattingOperator, type ConditionalFormattingTextOperator, type ConditionalFormattingValue, type ColumnResizedCallback as ColumnResizedCallbackNext, type IColumnSizing as IColumnSizingNext, type IMenu as IMenuNext, type IPagination, type ITextWrapping, type IColumnTextWrappingItem, type MeasureGroupDimension as MeasureGroupDimensionNext, type ColumnHeadersPosition as ColumnHeadersPositionNext, type GrandTotalsPosition as GrandTotalsPositionNext, type ColumnWidthItem as ColumnWidthItemNext, type DefaultColumnWidth as DefaultColumnWidthNext, type IAttributeColumnWidthItem as IAttributeColumnWidthItemNext, type IMeasureColumnWidthItem as IMeasureColumnWidthItemNext, type ISliceMeasureColumnWidthItem as ISliceMeasureColumnWidthItemNext, type IMixedValuesColumnWidthItem as IMixedValuesColumnWidthItemNext, type IAllMeasureColumnWidthItem as IAllMeasureColumnWidthItemNext, type IWeakMeasureColumnWidthItem as IWeakMeasureColumnWidthItemNext, type ColumnLocator as ColumnLocatorNext, type IAttributeColumnLocator as IAttributeColumnLocatorNext, type IMeasureColumnLocator as IMeasureColumnLocatorNext, type ITotalColumnLocator as ITotalColumnLocatorNext, type IAttributeColumnLocatorBody as IAttributeColumnLocatorBodyNext, type IMeasureColumnLocatorBody as IMeasureColumnLocatorBodyNext, type ITotalColumnLocatorBody as ITotalColumnLocatorBodyNext, type IAttributeColumnWidthItemBody as IAttributeColumnWidthItemBodyNext, type IMeasureColumnWidthItemBody as IMeasureColumnWidthItemBodyNext, type ISliceMeasureColumnWidthItemBody as ISliceMeasureColumnWidthItemBodyNext, type IMixedValuesColumnWidthItemBody as IMixedValuesColumnWidthItemBodyNext, type IAllMeasureColumnWidthItemBody as IAllMeasureColumnWidthItemBodyNext, type IWeakMeasureColumnWidthItemBody as IWeakMeasureColumnWidthItemBodyNext, type ColumnWidth as ColumnWidthNext, type IAbsoluteColumnWidth as IAbsoluteColumnWidthNext, type IAutoColumnWidth as IAutoColumnWidthNext, } from "./next/index.js";
11
+ export { PivotTableNext, type IPivotTableNextProps, type PivotTableNextConfig, type PivotTableNextAccessibilityConfig, type PivotTableNextTranspositionConfig, type PivotTableNextTextWrappingConfig, type PivotTableNextColumnsSizingConfig, type PivotTableNextMenuConfig, type PivotTableNextFormattingConfig, type PivotTableNextExecutionCancellingConfig, type PivotTableNextLayoutConfig, type PivotTableNextGrandTotalsPositionConfig, type PivotTableNextCellSelectionConfig, type PivotTableNextAgGridLicenseConfig, type PivotTableNextPaginationConfig, type PivotTableNextExperimentalConfig, type PivotTableNextConditionalFormattingConfig, type IConditionalFormatting, type IConditionalFormattingRule, type IConditionalFormattingCondition, type IConditionalFormattingFormat, type ConditionalFormattingTarget, type ConditionalFormattingOperator, type ConditionalFormattingTextOperator, type ConditionalFormattingEmptinessOperator, type ConditionalFormattingValue, type ColumnResizedCallback as ColumnResizedCallbackNext, type IColumnSizing as IColumnSizingNext, type IMenu as IMenuNext, type IPagination, type ITextWrapping, type IColumnTextWrappingItem, type MeasureGroupDimension as MeasureGroupDimensionNext, type ColumnHeadersPosition as ColumnHeadersPositionNext, type GrandTotalsPosition as GrandTotalsPositionNext, type ColumnWidthItem as ColumnWidthItemNext, type DefaultColumnWidth as DefaultColumnWidthNext, type IAttributeColumnWidthItem as IAttributeColumnWidthItemNext, type IMeasureColumnWidthItem as IMeasureColumnWidthItemNext, type ISliceMeasureColumnWidthItem as ISliceMeasureColumnWidthItemNext, type IMixedValuesColumnWidthItem as IMixedValuesColumnWidthItemNext, type IAllMeasureColumnWidthItem as IAllMeasureColumnWidthItemNext, type IWeakMeasureColumnWidthItem as IWeakMeasureColumnWidthItemNext, type ColumnLocator as ColumnLocatorNext, type IAttributeColumnLocator as IAttributeColumnLocatorNext, type IMeasureColumnLocator as IMeasureColumnLocatorNext, type ITotalColumnLocator as ITotalColumnLocatorNext, type IAttributeColumnLocatorBody as IAttributeColumnLocatorBodyNext, type IMeasureColumnLocatorBody as IMeasureColumnLocatorBodyNext, type ITotalColumnLocatorBody as ITotalColumnLocatorBodyNext, type IAttributeColumnWidthItemBody as IAttributeColumnWidthItemBodyNext, type IMeasureColumnWidthItemBody as IMeasureColumnWidthItemBodyNext, type ISliceMeasureColumnWidthItemBody as ISliceMeasureColumnWidthItemBodyNext, type IMixedValuesColumnWidthItemBody as IMixedValuesColumnWidthItemBodyNext, type IAllMeasureColumnWidthItemBody as IAllMeasureColumnWidthItemBodyNext, type IWeakMeasureColumnWidthItemBody as IWeakMeasureColumnWidthItemBodyNext, type ColumnWidth as ColumnWidthNext, type IAbsoluteColumnWidth as IAbsoluteColumnWidthNext, type IAutoColumnWidth as IAutoColumnWidthNext, } from "./next/index.js";
12
12
  export type { IPivotTableBucketProps, IPivotTableBaseProps, IPivotTableProps, IPivotTableConfig, IColumnSizing, DefaultColumnWidth, ICorePivotTableProps, ColumnResizedCallback, IMenu, MeasureGroupDimension, ColumnHeadersPosition, GrandTotalsPosition, } from "./publicTypes.js";
13
13
  export { type IWeakMeasureColumnWidthItem, type IWeakMeasureColumnWidthItemBody, type ColumnWidthItem, type ColumnWidth, type IAttributeColumnWidthItem, type IAttributeColumnWidthItemBody, type IMeasureColumnWidthItem, type IMeasureColumnWidthItemBody, type ISliceMeasureColumnWidthItem, type ISliceMeasureColumnWidthItemBody, type IMixedValuesColumnWidthItem, type IMixedValuesColumnWidthItemBody, type IAbsoluteColumnWidth, type IAllMeasureColumnWidthItem, type IAllMeasureColumnWidthItemBody, type IAutoColumnWidth, type ColumnLocator, type IAttributeColumnLocator, type IAttributeColumnLocatorBody, type ITotalColumnLocator, type ITotalColumnLocatorBody, type IMeasureColumnLocator, type IMeasureColumnLocatorBody, isWeakMeasureColumnWidthItem, isAttributeColumnWidthItem, isMeasureColumnWidthItem, isSliceMeasureColumnWidthItem, isMixedValuesColumnWidthItem, isAbsoluteColumnWidth, isAllMeasureColumnWidthItem, isMeasureColumnLocator, isAttributeColumnLocator, isTotalColumnLocator, newAttributeColumnLocator, newWidthForAllColumnsForMeasure, newWidthForAllMeasureColumns, newWidthForAttributeColumn, newWidthForSelectedColumns, setNewWidthForSelectedColumns, newTotalColumnLocator, } from "./columnWidths.js";
14
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,OAAO,EAAE,UAAU,EAAE,6BAA6B,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACrG,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,EACH,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,iCAAiC,EACtC,KAAK,iCAAiC,EACtC,KAAK,gCAAgC,EACrC,KAAK,iCAAiC,EACtC,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACnC,KAAK,uCAAuC,EAC5C,KAAK,0BAA0B,EAC/B,KAAK,uCAAuC,EAC5C,KAAK,iCAAiC,EACtC,KAAK,iCAAiC,EACtC,KAAK,8BAA8B,EACnC,KAAK,gCAAgC,EACrC,KAAK,yCAAyC,EAC9C,KAAK,sBAAsB,EAC3B,KAAK,0BAA0B,EAC/B,KAAK,+BAA+B,EACpC,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EAChC,KAAK,6BAA6B,EAClC,KAAK,iCAAiC,EACtC,KAAK,0BAA0B,EAC/B,KAAK,qBAAqB,IAAI,yBAAyB,EACvD,KAAK,aAAa,IAAI,iBAAiB,EACvC,KAAK,KAAK,IAAI,SAAS,EACvB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,IAAI,yBAAyB,EACvD,KAAK,qBAAqB,IAAI,yBAAyB,EACvD,KAAK,mBAAmB,IAAI,uBAAuB,EACnD,KAAK,eAAe,IAAI,mBAAmB,EAC3C,KAAK,kBAAkB,IAAI,sBAAsB,EACjD,KAAK,yBAAyB,IAAI,6BAA6B,EAC/D,KAAK,uBAAuB,IAAI,2BAA2B,EAC3D,KAAK,4BAA4B,IAAI,gCAAgC,EACrE,KAAK,2BAA2B,IAAI,+BAA+B,EACnE,KAAK,0BAA0B,IAAI,8BAA8B,EACjE,KAAK,2BAA2B,IAAI,+BAA+B,EACnE,KAAK,aAAa,IAAI,iBAAiB,EACvC,KAAK,uBAAuB,IAAI,2BAA2B,EAC3D,KAAK,qBAAqB,IAAI,yBAAyB,EACvD,KAAK,mBAAmB,IAAI,uBAAuB,EACnD,KAAK,2BAA2B,IAAI,+BAA+B,EACnE,KAAK,yBAAyB,IAAI,6BAA6B,EAC/D,KAAK,uBAAuB,IAAI,2BAA2B,EAC3D,KAAK,6BAA6B,IAAI,iCAAiC,EACvE,KAAK,2BAA2B,IAAI,+BAA+B,EACnE,KAAK,gCAAgC,IAAI,oCAAoC,EAC7E,KAAK,+BAA+B,IAAI,mCAAmC,EAC3E,KAAK,8BAA8B,IAAI,kCAAkC,EACzE,KAAK,+BAA+B,IAAI,mCAAmC,EAC3E,KAAK,WAAW,IAAI,eAAe,EACnC,KAAK,oBAAoB,IAAI,wBAAwB,EACrD,KAAK,gBAAgB,IAAI,oBAAoB,GAChD,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EACR,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,EACL,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,GACtB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACH,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACpC,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,EAClC,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,gCAAgC,EACrC,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACpC,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,4BAA4B,EAC5B,0BAA0B,EAC1B,wBAAwB,EACxB,6BAA6B,EAC7B,4BAA4B,EAC5B,qBAAqB,EACrB,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,oBAAoB,EACpB,yBAAyB,EACzB,+BAA+B,EAC/B,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,6BAA6B,EAC7B,qBAAqB,GACxB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { type RefObject } from "react";
2
2
  import { type ISortItem } from "@gooddata/sdk-model";
3
3
  import { type DataViewFacade, type ExplicitDrill } from "@gooddata/sdk-ui";
4
4
  import { type AgGridColumnDef } from "../../types/agGrid.js";
5
- import { type ConditionalFormattingTriggerColIds, type IConditionalFormatting } from "../../types/conditionalFormatting.js";
5
+ import { type ConditionalFormattingDateBounds, type ConditionalFormattingTriggerColIds, type IConditionalFormatting } from "../../types/conditionalFormatting.js";
6
6
  import { type ColumnWidthItem } from "../../types/resizing.js";
7
7
  import { type ITextWrapping } from "../../types/textWrapping.js";
8
8
  /**
@@ -10,7 +10,7 @@ import { type ITextWrapping } from "../../types/textWrapping.js";
10
10
  *
11
11
  * @internal
12
12
  */
13
- export declare const applyAllFeaturesToColDef: ({ columnWidths, sortBy, textWrapping, drillableItemsRef, dataViewFacade, conditionalFormatting, conditionalFormattingTriggers, }: {
13
+ export declare const applyAllFeaturesToColDef: ({ columnWidths, sortBy, textWrapping, drillableItemsRef, dataViewFacade, conditionalFormatting, conditionalFormattingTriggers, conditionalFormattingDateBounds, }: {
14
14
  columnWidths: ColumnWidthItem[];
15
15
  sortBy: ISortItem[];
16
16
  textWrapping: ITextWrapping;
@@ -18,5 +18,6 @@ export declare const applyAllFeaturesToColDef: ({ columnWidths, sortBy, textWrap
18
18
  dataViewFacade?: DataViewFacade | undefined;
19
19
  conditionalFormatting?: IConditionalFormatting | undefined;
20
20
  conditionalFormattingTriggers: ConditionalFormattingTriggerColIds;
21
+ conditionalFormattingDateBounds: ConditionalFormattingDateBounds;
21
22
  }) => (colDef: AgGridColumnDef) => AgGridColumnDef;
22
23
  //# sourceMappingURL=applyAllFeaturesToColDef.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"applyAllFeaturesToColDef.d.ts","sourceRoot":"","sources":["../../../../src/next/features/columns/applyAllFeaturesToColDef.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EACH,KAAK,kCAAkC,EACvC,KAAK,sBAAsB,EAC9B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAQjE;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;kDA2BhC,CAAC"}
1
+ {"version":3,"file":"applyAllFeaturesToColDef.d.ts","sourceRoot":"","sources":["../../../../src/next/features/columns/applyAllFeaturesToColDef.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EACH,KAAK,+BAA+B,EACpC,KAAK,kCAAkC,EACvC,KAAK,sBAAsB,EAC9B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAQjE;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;kDAiChC,CAAC"}
@@ -9,13 +9,13 @@ import { applyConditionalFormattingToColDef } from "./applyConditionalFormatting
9
9
  *
10
10
  * @internal
11
11
  */
12
- export const applyAllFeaturesToColDef = ({ columnWidths, sortBy, textWrapping, drillableItemsRef, dataViewFacade, conditionalFormatting, conditionalFormattingTriggers, }) => (colDef) => {
12
+ export const applyAllFeaturesToColDef = ({ columnWidths, sortBy, textWrapping, drillableItemsRef, dataViewFacade, conditionalFormatting, conditionalFormattingTriggers, conditionalFormattingDateBounds, }) => (colDef) => {
13
13
  return [
14
14
  applyColumnWidthsToColDef(columnWidths),
15
15
  applySortByToColDef(sortBy),
16
16
  applyCellRenderingToColDef(drillableItemsRef, dataViewFacade),
17
17
  applyTextWrappingToColDef(textWrapping),
18
18
  // Conditional formatting is applied last so its colors win over format-string colors.
19
- applyConditionalFormattingToColDef(conditionalFormatting, conditionalFormattingTriggers),
19
+ applyConditionalFormattingToColDef(conditionalFormatting, conditionalFormattingTriggers, conditionalFormattingDateBounds),
20
20
  ].reduce((acc, fn) => fn(acc), colDef);
21
21
  };
@@ -1,5 +1,5 @@
1
1
  import { type AgGridColumnDef } from "../../types/agGrid.js";
2
- import { type ConditionalFormattingTriggerColIds, type IConditionalFormatting } from "../../types/conditionalFormatting.js";
2
+ import { type ConditionalFormattingDateBounds, type ConditionalFormattingTriggerColIds, type IConditionalFormatting } from "../../types/conditionalFormatting.js";
3
3
  /**
4
4
  * Decorates a col def's `cellStyle` so conditional-formatting colors are merged on top of any
5
5
  * existing (format-string-derived) styling — i.e. conditional formatting wins on conflict.
@@ -10,5 +10,5 @@ import { type ConditionalFormattingTriggerColIds, type IConditionalFormatting }
10
10
  *
11
11
  * @internal
12
12
  */
13
- export declare const applyConditionalFormattingToColDef: (config: IConditionalFormatting | undefined, triggers: ConditionalFormattingTriggerColIds) => (colDef: AgGridColumnDef) => AgGridColumnDef;
13
+ export declare const applyConditionalFormattingToColDef: (config: IConditionalFormatting | undefined, triggers: ConditionalFormattingTriggerColIds, dateBounds: ConditionalFormattingDateBounds) => (colDef: AgGridColumnDef) => AgGridColumnDef;
14
14
  //# sourceMappingURL=applyConditionalFormattingToColDef.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"applyConditionalFormattingToColDef.d.ts","sourceRoot":"","sources":["../../../../src/next/features/columns/applyConditionalFormattingToColDef.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EACH,KAAK,kCAAkC,EACvC,KAAK,sBAAsB,EAC9B,MAAM,sCAAsC,CAAC;AAI9C;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,4IA6B1C,CAAC"}
1
+ {"version":3,"file":"applyConditionalFormattingToColDef.d.ts","sourceRoot":"","sources":["../../../../src/next/features/columns/applyConditionalFormattingToColDef.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EACH,KAAK,+BAA+B,EACpC,KAAK,kCAAkC,EACvC,KAAK,sBAAsB,EAC9B,MAAM,sCAAsC,CAAC;AAI9C;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,yLAuC1C,CAAC"}
@@ -10,7 +10,7 @@ import { evaluateConditionalFormatting } from "../styling/conditionalFormatting.
10
10
  *
11
11
  * @internal
12
12
  */
13
- export const applyConditionalFormattingToColDef = (config, triggers) => (colDef) => {
13
+ export const applyConditionalFormattingToColDef = (config, triggers, dateBounds) => (colDef) => {
14
14
  if (!config || !config.enabled || config.rules.length === 0) {
15
15
  return colDef;
16
16
  }
@@ -23,7 +23,7 @@ export const applyConditionalFormattingToColDef = (config, triggers) => (colDef)
23
23
  if (!params.data || !colId) {
24
24
  return base;
25
25
  }
26
- const fragment = evaluateConditionalFormatting(config, triggers, params.data, colId);
26
+ const fragment = evaluateConditionalFormatting(config, triggers, params.data, colId, dateBounds);
27
27
  if (!fragment) {
28
28
  return base;
29
29
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createServerSideDataSource.d.ts","sourceRoot":"","sources":["../../../../src/next/features/data/createServerSideDataSource.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,qBAAqB,EAG7B,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACvG,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,aAAa,EAErB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,EACrC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAS1E;;GAEG;AACH,UAAU,iCAAkC,SAAQ,qBAAqB;IACrE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,uBAAuB,EAAE,6BAA6B,CAAC;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,KAAK,IAAI,CAAC;IACnE,eAAe,EAAE,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/D,qBAAqB,EAAE,CAAC,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC;IACpD,iBAAiB,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IACpF,sBAAsB,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IAC/E,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AA4DD;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,sYA2MtC,CAAC"}
1
+ {"version":3,"file":"createServerSideDataSource.d.ts","sourceRoot":"","sources":["../../../../src/next/features/data/createServerSideDataSource.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,qBAAqB,EAG7B,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACvG,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,aAAa,EAErB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,6BAA6B,EACrC,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAS1E;;GAEG;AACH,UAAU,iCAAkC,SAAQ,qBAAqB;IACrE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACrB,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,uBAAuB,EAAE,6BAA6B,CAAC;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,KAAK,IAAI,CAAC;IACnE,eAAe,EAAE,CAAC,KAAK,EAAE,gBAAgB,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/D,qBAAqB,EAAE,CAAC,OAAO,EAAE,SAAS,KAAK,IAAI,CAAC;IACpD,iBAAiB,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IACpF,sBAAsB,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IAC/E,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AA4DD;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,sYA6MtC,CAAC"}
@@ -133,7 +133,8 @@ export const createServerSideDataSource = ({ measures, rows, sortBy, initialExec
133
133
  const startRow = params.request.startRow ?? 0;
134
134
  const endRow = params.request.endRow ?? pageSize;
135
135
  const { backendStartRow, backendEndRow } = getBackendRowOffset(startRow, endRow, grandTotalsPosition, cachedGrandTotalCount);
136
- const nextDataView = isFirstRequest
136
+ // The pre-loaded first page is only valid while the execution it was loaded from is still current.
137
+ const nextDataView = isFirstRequest && executionResult === initialExecutionResult
137
138
  ? initialDataView
138
139
  : await loadDataView({
139
140
  executionResult,
@@ -1 +1 @@
1
- {"version":3,"file":"dataViewToColDefs.d.ts","sourceRoot":"","sources":["../../../../src/next/features/data/dataViewToColDefs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAU1E;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAC9B,QAAQ,EACR,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,IAAI,EACJ,UAAU,EACV,qBAAqB,EACxB,EAAE;IACC,QAAQ,EAAE,cAAc,CAAC;IACzB,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,iBAAiB,EAAE,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC;IAC9C,YAAY,EAAE,aAAa,CAAC;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,qBAAqB,CAAC,EAAE,sBAAsB,CAAC;CAClD,GAAG;IACA,uBAAuB,EAAE,6BAA6B,CAAC;IACvD,UAAU,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,CAAC;IACvD,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;CACtB,CA8DA"}
1
+ {"version":3,"file":"dataViewToColDefs.d.ts","sourceRoot":"","sources":["../../../../src/next/features/data/dataViewToColDefs.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAa1E;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAC9B,QAAQ,EACR,qBAAqB,EACrB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,IAAI,EACJ,UAAU,EACV,qBAAqB,EACxB,EAAE;IACC,QAAQ,EAAE,cAAc,CAAC;IACzB,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,iBAAiB,EAAE,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC;IAC9C,YAAY,EAAE,aAAa,CAAC;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB,qBAAqB,CAAC,EAAE,sBAAsB,CAAC;CAClD,GAAG;IACA,uBAAuB,EAAE,6BAA6B,CAAC;IACvD,UAAU,EAAE,CAAC,eAAe,GAAG,oBAAoB,CAAC,EAAE,CAAC;IACvD,cAAc,EAAE,eAAe,EAAE,CAAC;IAClC,SAAS,EAAE,OAAO,CAAC;CACtB,CAmEA"}
@@ -3,7 +3,7 @@ import { applyAllFeaturesToColDef } from "../columns/applyAllFeaturesToColDef.js
3
3
  import { columnDefinitionToColId } from "../columns/colId.js";
4
4
  import { createColDef } from "../columns/createColDef.js";
5
5
  import { columnDefsToPivotGroups } from "../pivoting/columnDefsToPivotGroups.js";
6
- import { resolveConditionalFormattingTriggers } from "../styling/conditionalFormatting.js";
6
+ import { resolveConditionalFormattingDateBounds, resolveConditionalFormattingTriggers, } from "../styling/conditionalFormatting.js";
7
7
  import { applyTextWrappingToGroupDef } from "../textWrapping/applyTextWrappingToGroupDef.js";
8
8
  import { getTableData } from "./valueFormatter.js";
9
9
  /**
@@ -24,6 +24,10 @@ export function dataViewToColDefs({ dataView, columnHeadersPosition, columnWidth
24
24
  const conditionalFormattingTriggers = conditionalFormatting?.enabled
25
25
  ? resolveConditionalFormattingTriggers(conditionalFormatting, tableData.columnDefinitions, columnHeadersPosition)
26
26
  : [];
27
+ // Resolved once per render like the triggers; relative periods anchor to render time.
28
+ const conditionalFormattingDateBounds = conditionalFormatting?.enabled
29
+ ? resolveConditionalFormattingDateBounds(conditionalFormatting, tableData.columnDefinitions)
30
+ : {};
27
31
  const colDefs = tableData.columnDefinitions.map((columnDefinition) => {
28
32
  const colDef = createColDef(columnDefinition, columnHeadersPosition, intl, dataView);
29
33
  return applyAllFeaturesToColDef({
@@ -34,6 +38,7 @@ export function dataViewToColDefs({ dataView, columnHeadersPosition, columnWidth
34
38
  dataViewFacade: dataView,
35
39
  conditionalFormatting,
36
40
  conditionalFormattingTriggers,
41
+ conditionalFormattingDateBounds,
37
42
  })(colDef);
38
43
  });
39
44
  const columnDefsWithPivotGroups = columnDefsToPivotGroups(colDefs, columnHeadersPosition, intl);
@@ -1,7 +1,8 @@
1
1
  import { type ITableColumnDefinition } from "@gooddata/sdk-ui";
2
- import { type ConditionalFormattingTriggerColIds, type IConditionalFormatting } from "../../types/conditionalFormatting.js";
2
+ import { type ConditionalFormattingDateBounds, type ConditionalFormattingTriggerColIds, type IConditionalFormatting } from "../../types/conditionalFormatting.js";
3
3
  import { type AgGridRowData } from "../../types/internal.js";
4
4
  import { type ColumnHeadersPosition } from "../../types/transposition.js";
5
+ import { type IDateResolutionContext } from "./dateConditionResolution.js";
5
6
  /**
6
7
  * The colors a matched cell/row receives — a subset of ag-grid CellStyle, merged on top of the
7
8
  * format-string-derived styling by the caller.
@@ -20,6 +21,15 @@ interface IConditionalFormattingStyle {
20
21
  * @internal
21
22
  */
22
23
  export declare function resolveConditionalFormattingTriggers(config: IConditionalFormatting, columnDefinitions: readonly ITableColumnDefinition[], columnHeadersPosition: ColumnHeadersPosition): ConditionalFormattingTriggerColIds;
24
+ /**
25
+ * Resolves every date-valued condition to label-space bounds at its target column's granularity,
26
+ * once per render (bounds depend only on the config, the column descriptors, and the anchor).
27
+ * Keyed by `<ruleIndex>:<conditionId>`; `null` = unresolvable (never matches). Non-date conditions
28
+ * are absent.
29
+ *
30
+ * @internal
31
+ */
32
+ export declare function resolveConditionalFormattingDateBounds(config: IConditionalFormatting, columnDefinitions: readonly ITableColumnDefinition[], context?: IDateResolutionContext): ConditionalFormattingDateBounds;
23
33
  /**
24
34
  * Evaluates the conditional-formatting config for one rendered cell; returns the style fragment to
25
35
  * apply, or undefined if no rule matches.
@@ -30,6 +40,6 @@ export declare function resolveConditionalFormattingTriggers(config: IConditiona
30
40
  *
31
41
  * @internal
32
42
  */
33
- export declare function evaluateConditionalFormatting(config: IConditionalFormatting, triggerColIdsByRule: ConditionalFormattingTriggerColIds, rowData: AgGridRowData, currentColId: string): IConditionalFormattingStyle | undefined;
43
+ export declare function evaluateConditionalFormatting(config: IConditionalFormatting, triggerColIdsByRule: ConditionalFormattingTriggerColIds, rowData: AgGridRowData, currentColId: string, dateBoundsByCondition?: ConditionalFormattingDateBounds): IConditionalFormattingStyle | undefined;
34
44
  export {};
35
45
  //# sourceMappingURL=conditionalFormatting.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conditionalFormatting.d.ts","sourceRoot":"","sources":["../../../../src/next/features/styling/conditionalFormatting.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,sBAAsB,EAO9B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAGH,KAAK,kCAAkC,EAEvC,KAAK,sBAAsB,EAG9B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAK1E;;;;;GAKG;AACH,UAAU,2BAA2B;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AA+CD;;;;;;GAMG;AACH,wBAAgB,oCAAoC,CAChD,MAAM,EAAE,sBAAsB,EAC9B,iBAAiB,EAAE,SAAS,sBAAsB,EAAE,EACpD,qBAAqB,EAAE,qBAAqB,GAC7C,kCAAkC,CAMpC;AA+ID;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CACzC,MAAM,EAAE,sBAAsB,EAC9B,mBAAmB,EAAE,kCAAkC,EACvD,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,MAAM,GACrB,2BAA2B,GAAG,SAAS,CAyCzC"}
1
+ {"version":3,"file":"conditionalFormatting.d.ts","sourceRoot":"","sources":["../../../../src/next/features/styling/conditionalFormatting.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,KAAK,sBAAsB,EAO9B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACH,KAAK,+BAA+B,EAGpC,KAAK,kCAAkC,EAEvC,KAAK,sBAAsB,EAI9B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAI1E,OAAO,EACH,KAAK,sBAAsB,EAG9B,MAAM,8BAA8B,CAAC;AAEtC;;;;;GAKG;AACH,UAAU,2BAA2B;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AA+CD;;;;;;GAMG;AACH,wBAAgB,oCAAoC,CAChD,MAAM,EAAE,sBAAsB,EAC9B,iBAAiB,EAAE,SAAS,sBAAsB,EAAE,EACpD,qBAAqB,EAAE,qBAAqB,GAC7C,kCAAkC,CAMpC;AAID;;;;;;;GAOG;AACH,wBAAgB,sCAAsC,CAClD,MAAM,EAAE,sBAAsB,EAC9B,iBAAiB,EAAE,SAAS,sBAAsB,EAAE,EACpD,OAAO,CAAC,EAAE,sBAAsB,GACjC,+BAA+B,CA+BjC;AA+LD;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CACzC,MAAM,EAAE,sBAAsB,EAC9B,mBAAmB,EAAE,kCAAkC,EACvD,OAAO,EAAE,aAAa,EACtB,YAAY,EAAE,MAAM,EACpB,qBAAqB,CAAC,EAAE,+BAA+B,GACxD,2BAA2B,GAAG,SAAS,CA4CzC"}
@@ -1,7 +1,9 @@
1
1
  // (C) 2026 GoodData Corporation
2
+ import { isResultAttributeHeader } from "@gooddata/sdk-model";
2
3
  import { isAttributeColumnDefinition, isMeasureGroupValueColumnDefinition, isMeasureScope, isValueColumnDefinition, } from "@gooddata/sdk-ui";
3
4
  import { columnDefinitionToColId } from "../columns/colId.js";
4
5
  import { isTotalCell } from "./cellClassification.js";
6
+ import { isDateConditionValue, resolveDateConditionBounds, } from "./dateConditionResolution.js";
5
7
  // Reads BOTH column and row scope so the measure is found wherever transposition places it (mirrors
6
8
  // `valueRow/value.ts`). This is what gates the shared transposed value column to its own measure's rows.
7
9
  const cellHoldsMeasure = (cell, measureLocalId) => {
@@ -46,6 +48,38 @@ export function resolveConditionalFormattingTriggers(config, columnDefinitions,
46
48
  .filter((columnDefinition) => columnHoldsTarget(columnDefinition, rule.target))
47
49
  .map((columnDefinition) => columnDefinitionToColId(columnDefinition, columnHeadersPosition)));
48
50
  }
51
+ const dateBoundsKey = (ruleIndex, conditionId) => `${ruleIndex}:${conditionId}`;
52
+ /**
53
+ * Resolves every date-valued condition to label-space bounds at its target column's granularity,
54
+ * once per render (bounds depend only on the config, the column descriptors, and the anchor).
55
+ * Keyed by `<ruleIndex>:<conditionId>`; `null` = unresolvable (never matches). Non-date conditions
56
+ * are absent.
57
+ *
58
+ * @internal
59
+ */
60
+ export function resolveConditionalFormattingDateBounds(config, columnDefinitions, context) {
61
+ // Single anchor so every relative condition sees the same current period.
62
+ const resolutionContext = { anchor: context?.anchor ?? new Date() };
63
+ const bounds = {};
64
+ config.rules.forEach((rule, ruleIndex) => {
65
+ if (!rule.conditions.some((condition) => isDateConditionValue(condition.value))) {
66
+ return;
67
+ }
68
+ // Date conditions target attributes; the target's column carries granularity + timezone.
69
+ const attributeIdentifier = rule.target.kind === "attribute" ? rule.target.attributeIdentifier : undefined;
70
+ const targetColumn = columnDefinitions.find((columnDefinition) => isAttributeColumnDefinition(columnDefinition) &&
71
+ columnDefinition.attributeDescriptor.attributeHeader.localIdentifier === attributeIdentifier);
72
+ const attributeHeader = isAttributeColumnDefinition(targetColumn)
73
+ ? targetColumn.attributeDescriptor.attributeHeader
74
+ : undefined;
75
+ for (const condition of rule.conditions) {
76
+ if (isDateConditionValue(condition.value)) {
77
+ bounds[dateBoundsKey(ruleIndex, condition.id)] = resolveDateConditionBounds(condition.value, attributeHeader?.granularity, attributeHeader?.format?.timezone, resolutionContext);
78
+ }
79
+ }
80
+ });
81
+ return bounds;
82
+ }
49
83
  const TEXT_OPERATORS = new Set([
50
84
  "CONTAINS",
51
85
  "NOT_CONTAINS",
@@ -131,7 +165,38 @@ const isEmptyTriggerCell = (cell, targetKind) => {
131
165
  }
132
166
  return cell.value === null || cell.value === undefined;
133
167
  };
134
- const conditionMatches = (condition, triggerCell, targetKind) => {
168
+ // Raw wire label ("2023-12"), never the localized formattedValue ("Dec 2023"): comparison must
169
+ // stay portable to a server evaluator. Null when the cell carries no attribute header.
170
+ const attributeWireLabel = (cell) => {
171
+ if (!("value" in cell) || !isResultAttributeHeader(cell.value)) {
172
+ return null;
173
+ }
174
+ const name = cell.value.attributeHeaderItem.name;
175
+ return typeof name === "string" ? name : null;
176
+ };
177
+ // Labels are fixed-width and zero-padded, so period containment/ordering are plain string compares.
178
+ const matchesDateLabel = (operator, label, bounds) => {
179
+ switch (operator) {
180
+ case "EQUAL_TO":
181
+ return label >= bounds.fromLabel && label <= bounds.toLabel;
182
+ case "NOT_EQUAL_TO":
183
+ return label < bounds.fromLabel || label > bounds.toLabel;
184
+ case "GREATER_THAN":
185
+ return label > bounds.toLabel;
186
+ case "GREATER_THAN_OR_EQUAL_TO":
187
+ return label >= bounds.fromLabel;
188
+ case "LESS_THAN":
189
+ return label < bounds.fromLabel;
190
+ case "LESS_THAN_OR_EQUAL_TO":
191
+ return label <= bounds.toLabel;
192
+ default:
193
+ return false;
194
+ }
195
+ };
196
+ const conditionMatches = (condition, triggerCell, targetKind, dateBounds) => {
197
+ if (isDateConditionValue(condition.value) && !dateBounds) {
198
+ return false;
199
+ }
135
200
  const empty = isEmptyTriggerCell(triggerCell, targetKind);
136
201
  if (condition.operator === "IS_EMPTY") {
137
202
  return empty;
@@ -146,9 +211,17 @@ const conditionMatches = (condition, triggerCell, targetKind) => {
146
211
  if (condition.operator === "ALL") {
147
212
  return true;
148
213
  }
149
- const useText = targetKind === "attribute" || TEXT_OPERATORS.has(condition.operator);
150
- if (useText) {
151
- return matchesText(condition.operator, condition.value, triggerCell.formattedValue ?? "");
214
+ if (isDateConditionValue(condition.value) && dateBounds) {
215
+ const label = attributeWireLabel(triggerCell);
216
+ return label === null ? false : matchesDateLabel(condition.operator, label, dateBounds);
217
+ }
218
+ // Text operators are attribute-only — on a measure they'd match the locale-dependent formatted
219
+ // string, unportable to a server evaluator.
220
+ if (TEXT_OPERATORS.has(condition.operator) && targetKind !== "attribute") {
221
+ return false;
222
+ }
223
+ if (targetKind === "attribute") {
224
+ return matchesText(condition.operator, condition.value, attributeWireLabel(triggerCell) ?? "");
152
225
  }
153
226
  if (!("value" in triggerCell)) {
154
227
  return false;
@@ -173,7 +246,7 @@ const toFragment = (format) => ({
173
246
  *
174
247
  * @internal
175
248
  */
176
- export function evaluateConditionalFormatting(config, triggerColIdsByRule, rowData, currentColId) {
249
+ export function evaluateConditionalFormatting(config, triggerColIdsByRule, rowData, currentColId, dateBoundsByCondition) {
177
250
  if (!config.enabled) {
178
251
  return undefined;
179
252
  }
@@ -194,7 +267,10 @@ export function evaluateConditionalFormatting(config, triggerColIdsByRule, rowDa
194
267
  continue;
195
268
  }
196
269
  for (const condition of rule.conditions) {
197
- if (!conditionMatches(condition, triggerCell, rule.target.kind)) {
270
+ const dateBounds = isDateConditionValue(condition.value)
271
+ ? dateBoundsByCondition?.[dateBoundsKey(i, condition.id)]
272
+ : undefined;
273
+ if (!conditionMatches(condition, triggerCell, rule.target.kind, dateBounds)) {
198
274
  continue;
199
275
  }
200
276
  // First match wins the rule: row-scope paints any cell, cell-scope only the trigger cell.
@@ -0,0 +1,89 @@
1
+ import { type DateFilterGranularity } from "@gooddata/sdk-model";
2
+ import { type ConditionalFormattingValue, type IDateConditionBounds } from "../../types/conditionalFormatting.js";
3
+ /**
4
+ * Context for resolving relative date conditions. The anchor is the instant "now" is measured from —
5
+ * render time by default; exports pass their own so re-resolution is deterministic.
6
+ *
7
+ * @internal
8
+ */
9
+ export interface IDateResolutionContext {
10
+ anchor?: Date;
11
+ }
12
+ /**
13
+ * Date-condition value kinds (absolute period / relative period).
14
+ *
15
+ * @internal
16
+ */
17
+ export type ConditionalFormattingDateValue = Extract<ConditionalFormattingValue, {
18
+ kind: "absoluteDate";
19
+ } | {
20
+ kind: "relativeDate";
21
+ }>;
22
+ /**
23
+ * Type-guard for date-valued condition operands.
24
+ *
25
+ * @internal
26
+ */
27
+ export declare const isDateConditionValue: (value: ConditionalFormattingValue) => value is ConditionalFormattingDateValue;
28
+ /**
29
+ * Normalizes a date attribute's granularity — as found on an execution descriptor (raw wire enum)
30
+ * or in persisted config (GDC constant) — to the granularity the date-condition machinery speaks.
31
+ * Null = the attribute cannot carry date conditions (cyclic, fiscal, unknown, absent).
32
+ *
33
+ * @internal
34
+ */
35
+ export declare function normalizeDateConditionGranularity(granularity: string | undefined): DateFilterGranularity | null;
36
+ /**
37
+ * Value granularities combinable with a column of the given granularity. Under overlap semantics
38
+ * every supported linear granularity combines with every date column (a cell matches when its
39
+ * period touches the value's window), so this is the full supported set — empty only when the
40
+ * column itself cannot carry date conditions. Accepts both descriptor wire enums and GDC constants.
41
+ *
42
+ * @internal
43
+ */
44
+ export declare const allowedValueGranularities: (columnGranularity: string | undefined) => readonly DateFilterGranularity[];
45
+ /**
46
+ * True when the granularity's platform strings and wire labels carry a time component ("… HH[:mm]")
47
+ * — hour and minute. Accepts both descriptor wire enums and GDC constants; false for anything the
48
+ * date-condition machinery does not support.
49
+ *
50
+ * @internal
51
+ */
52
+ export declare const usesTimeResolution: (granularity: string | undefined) => boolean;
53
+ /**
54
+ * Resolves a date condition value into label-space bounds at the column's granularity — the pair of
55
+ * column periods containing the value's edges, so the engine's label comparisons implement overlap
56
+ * semantics (a cell matches "is on" when its period touches the value; negations and strict
57
+ * orderings are exact complements). Null only when the value cannot resolve at all
58
+ * (fiscal/unknown granularity, malformed input); such a condition never matches and the authoring
59
+ * UI flags it invalid.
60
+ *
61
+ * This is the normative resolution contract — server-side evaluators must mirror it exactly.
62
+ *
63
+ * @internal
64
+ */
65
+ export declare function resolveDateConditionBounds(value: ConditionalFormattingValue, columnGranularity: string | undefined, columnTimezone: string | undefined, context?: IDateResolutionContext): IDateConditionBounds | null;
66
+ /**
67
+ * Snaps a picker-produced wall-clock range to period bounds at the given granularity and serializes
68
+ * it into the platform strings an `absoluteDate` value persists (authoring-side).
69
+ * Input Dates are read in their LOCAL fields (that is what DateRangePicker produces). Null for
70
+ * granularities the resolver does not support (fiscal).
71
+ *
72
+ * @internal
73
+ */
74
+ export declare function snapToPeriodBounds(from: Date, to: Date, granularity: string): {
75
+ from: string;
76
+ to: string;
77
+ } | null;
78
+ /**
79
+ * {@link snapToPeriodBounds} for platform date strings ("YYYY-MM-DD"[ HH:mm]) — the shape the date
80
+ * filter's absolute form delivers on apply. Null when either string is malformed, the range is
81
+ * inverted, or the granularity is unsupported.
82
+ *
83
+ * @internal
84
+ */
85
+ export declare function snapPlatformRangeToPeriodBounds(from: string, to: string, granularity: string): {
86
+ from: string;
87
+ to: string;
88
+ } | null;
89
+ //# sourceMappingURL=dateConditionResolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dateConditionResolution.d.ts","sourceRoot":"","sources":["../../../../src/next/features/styling/dateConditionResolution.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EACH,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,EAC5B,MAAM,sCAAsC,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACnC,MAAM,CAAC,EAAE,IAAI,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,MAAM,8BAA8B,GAAG,OAAO,CAChD,0BAA0B,EAC1B;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CACtD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,gFAE2E,CAAC;AAsC7G;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAC7C,WAAW,EAAE,MAAM,GAAG,SAAS,GAChC,qBAAqB,GAAG,IAAI,CAE9B;AAaD;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,6EAIrC,CAAC;AAuLF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,8CAG9B,CAAC;AAiEF;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CACtC,KAAK,EAAE,0BAA0B,EACjC,iBAAiB,EAAE,MAAM,GAAG,SAAS,EACrC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,OAAO,CAAC,EAAE,sBAAsB,GACjC,oBAAoB,GAAG,IAAI,CAQ7B;AAiBD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAC9B,IAAI,EAAE,IAAI,EACV,EAAE,EAAE,IAAI,EACR,WAAW,EAAE,MAAM,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMrC;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC3C,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAiBrC"}
@@ -0,0 +1,346 @@
1
+ // (C) 2026 GoodData Corporation
2
+ /**
3
+ * Type-guard for date-valued condition operands.
4
+ *
5
+ * @internal
6
+ */
7
+ export const isDateConditionValue = (value) => value.kind === "absoluteDate" || value.kind === "relativeDate";
8
+ // Granularities the resolver handles. Fiscal granularities are deliberately absent: their wire
9
+ // labeling convention is unverified against a live workspace, so fiscal columns resolve to null.
10
+ const SUPPORTED_GRANULARITIES = [
11
+ "GDC.time.year",
12
+ "GDC.time.quarter",
13
+ "GDC.time.month",
14
+ "GDC.time.week_us",
15
+ "GDC.time.date",
16
+ "GDC.time.hour",
17
+ "GDC.time.minute",
18
+ ];
19
+ const isSupportedGranularity = (granularity) => SUPPORTED_GRANULARITIES.some((supported) => supported === granularity);
20
+ // Execution ATTRIBUTE DESCRIPTORS on Tiger carry the raw wire enum ("MONTH"), not the SDK
21
+ // "GDC.time.month" (toSdkGranularity runs for headers, not dimension descriptors).
22
+ const WIRE_GRANULARITIES = {
23
+ MINUTE: "GDC.time.minute",
24
+ HOUR: "GDC.time.hour",
25
+ DAY: "GDC.time.date",
26
+ WEEK: "GDC.time.week_us",
27
+ MONTH: "GDC.time.month",
28
+ QUARTER: "GDC.time.quarter",
29
+ YEAR: "GDC.time.year",
30
+ };
31
+ const normalizeSupported = (granularity) => {
32
+ if (isSupportedGranularity(granularity)) {
33
+ return granularity;
34
+ }
35
+ return (granularity === undefined ? undefined : WIRE_GRANULARITIES[granularity]) ?? null;
36
+ };
37
+ /**
38
+ * Normalizes a date attribute's granularity — as found on an execution descriptor (raw wire enum)
39
+ * or in persisted config (GDC constant) — to the granularity the date-condition machinery speaks.
40
+ * Null = the attribute cannot carry date conditions (cyclic, fiscal, unknown, absent).
41
+ *
42
+ * @internal
43
+ */
44
+ export function normalizeDateConditionGranularity(granularity) {
45
+ return normalizeSupported(granularity);
46
+ }
47
+ // Fine-to-coarse authoring order for granularity tabs and preset groups.
48
+ const VALUE_GRANULARITIES = [
49
+ "GDC.time.minute",
50
+ "GDC.time.hour",
51
+ "GDC.time.date",
52
+ "GDC.time.week_us",
53
+ "GDC.time.month",
54
+ "GDC.time.quarter",
55
+ "GDC.time.year",
56
+ ];
57
+ /**
58
+ * Value granularities combinable with a column of the given granularity. Under overlap semantics
59
+ * every supported linear granularity combines with every date column (a cell matches when its
60
+ * period touches the value's window), so this is the full supported set — empty only when the
61
+ * column itself cannot carry date conditions. Accepts both descriptor wire enums and GDC constants.
62
+ *
63
+ * @internal
64
+ */
65
+ export const allowedValueGranularities = (columnGranularity) => {
66
+ return normalizeSupported(columnGranularity) ? VALUE_GRANULARITIES : [];
67
+ };
68
+ const MINUTE_MS = 60_000;
69
+ const DAY_MS = 24 * 60 * MINUTE_MS;
70
+ const WEEK_MS = 7 * DAY_MS;
71
+ const pad = (value, length) => String(value).padStart(length, "0");
72
+ // A wall time built from a Date's LOCAL fields (the host-timezone reading of the instant).
73
+ const localWallTime = (local) => new Date(Date.UTC(local.getFullYear(), local.getMonth(), local.getDate(), local.getHours(), local.getMinutes()));
74
+ // Intl.DateTimeFormat construction is expensive and stateless — cache per timezone.
75
+ const wallTimeFormatters = new Map();
76
+ const wallTimeFormatter = (timezone) => {
77
+ const cached = wallTimeFormatters.get(timezone);
78
+ if (cached) {
79
+ return cached;
80
+ }
81
+ const formatter = new Intl.DateTimeFormat("en-US", {
82
+ timeZone: timezone,
83
+ year: "numeric",
84
+ month: "2-digit",
85
+ day: "2-digit",
86
+ hour: "2-digit",
87
+ minute: "2-digit",
88
+ hourCycle: "h23",
89
+ });
90
+ wallTimeFormatters.set(timezone, formatter);
91
+ return formatter;
92
+ };
93
+ // Period math runs on "wall times": Dates whose UTC fields hold the wall-clock components of the
94
+ // column's timezone — no DST discontinuities, no host timezone, matching the backend's wire labels.
95
+ const wallTimeFromInstant = (instant, timezone) => {
96
+ if (timezone) {
97
+ try {
98
+ const parts = wallTimeFormatter(timezone).formatToParts(instant);
99
+ const component = (type) => {
100
+ const part = parts.find((candidate) => candidate.type === type);
101
+ return part === undefined ? Number.NaN : Number(part.value);
102
+ };
103
+ const year = component("year");
104
+ const month = component("month");
105
+ const day = component("day");
106
+ // Some ICU versions render midnight as "24" even with h23.
107
+ const hour = component("hour") % 24;
108
+ const minute = component("minute");
109
+ if (![year, month, day, hour, minute].some(Number.isNaN)) {
110
+ return new Date(Date.UTC(year, month - 1, day, hour, minute));
111
+ }
112
+ }
113
+ catch {
114
+ // Unknown/invalid timezone id — fall through to the host's local wall time.
115
+ }
116
+ }
117
+ return localWallTime(instant);
118
+ };
119
+ const PLATFORM_DATE_REGEX = /^(\d{4})-(\d{2})-(\d{2})(?: (\d{2}):(\d{2}))?$/;
120
+ // Parses a platform date string ("YYYY-MM-DD" or "YYYY-MM-DD HH:mm") into a wall time; null on a
121
+ // malformed shape or an impossible date (e.g. 2026-02-31, which Date.UTC would silently roll over).
122
+ const parsePlatformDateString = (value) => {
123
+ const match = PLATFORM_DATE_REGEX.exec(value);
124
+ if (!match) {
125
+ return null;
126
+ }
127
+ const [, year, month, day, hour, minute] = match;
128
+ const hasTime = hour !== undefined;
129
+ const numbers = {
130
+ year: Number(year),
131
+ month: Number(month),
132
+ day: Number(day),
133
+ hour: hasTime ? Number(hour) : 0,
134
+ minute: hasTime ? Number(minute) : 0,
135
+ };
136
+ const wall = new Date(Date.UTC(numbers.year, numbers.month - 1, numbers.day, numbers.hour, numbers.minute));
137
+ const roundTrips = wall.getUTCFullYear() === numbers.year &&
138
+ wall.getUTCMonth() === numbers.month - 1 &&
139
+ wall.getUTCDate() === numbers.day &&
140
+ wall.getUTCHours() === numbers.hour &&
141
+ wall.getUTCMinutes() === numbers.minute;
142
+ return roundTrips ? { wall, hasTime } : null;
143
+ };
144
+ // ISO week math (Monday start, week 1 contains Jan 4) — must mirror the backend's "RRRR-II" grammar.
145
+ const startOfIsoWeek = (wall) => {
146
+ const daysFromMonday = (wall.getUTCDay() + 6) % 7;
147
+ return new Date(Date.UTC(wall.getUTCFullYear(), wall.getUTCMonth(), wall.getUTCDate() - daysFromMonday));
148
+ };
149
+ const isoWeekLabel = (weekStart) => {
150
+ const thursday = new Date(weekStart.getTime() + 3 * DAY_MS);
151
+ const isoYear = thursday.getUTCFullYear();
152
+ const week1Start = startOfIsoWeek(new Date(Date.UTC(isoYear, 0, 4)));
153
+ const week = 1 + Math.round((weekStart.getTime() - week1Start.getTime()) / WEEK_MS);
154
+ return `${pad(isoYear, 4)}-${pad(week, 2)}`;
155
+ };
156
+ const startOfPeriod = (wall, granularity) => {
157
+ const year = wall.getUTCFullYear();
158
+ const month = wall.getUTCMonth();
159
+ const day = wall.getUTCDate();
160
+ switch (granularity) {
161
+ case "GDC.time.year":
162
+ return new Date(Date.UTC(year, 0, 1));
163
+ case "GDC.time.quarter":
164
+ return new Date(Date.UTC(year, Math.floor(month / 3) * 3, 1));
165
+ case "GDC.time.month":
166
+ return new Date(Date.UTC(year, month, 1));
167
+ case "GDC.time.week_us":
168
+ return startOfIsoWeek(new Date(Date.UTC(year, month, day)));
169
+ case "GDC.time.date":
170
+ return new Date(Date.UTC(year, month, day));
171
+ case "GDC.time.hour":
172
+ return new Date(Date.UTC(year, month, day, wall.getUTCHours()));
173
+ case "GDC.time.minute":
174
+ return new Date(Date.UTC(year, month, day, wall.getUTCHours(), wall.getUTCMinutes()));
175
+ }
176
+ };
177
+ // `periodStart` must be a period start; Date.UTC normalizes component overflow (month 13 → next year).
178
+ const addPeriods = (periodStart, granularity, count) => {
179
+ const year = periodStart.getUTCFullYear();
180
+ const month = periodStart.getUTCMonth();
181
+ switch (granularity) {
182
+ case "GDC.time.year":
183
+ return new Date(Date.UTC(year + count, 0, 1));
184
+ case "GDC.time.quarter":
185
+ return new Date(Date.UTC(year, month + count * 3, 1));
186
+ case "GDC.time.month":
187
+ return new Date(Date.UTC(year, month + count, 1));
188
+ case "GDC.time.week_us":
189
+ return new Date(periodStart.getTime() + count * WEEK_MS);
190
+ case "GDC.time.date":
191
+ return new Date(Date.UTC(year, month, periodStart.getUTCDate() + count));
192
+ case "GDC.time.hour":
193
+ return new Date(Date.UTC(year, month, periodStart.getUTCDate(), periodStart.getUTCHours() + count));
194
+ case "GDC.time.minute":
195
+ return new Date(periodStart.getTime() + count * MINUTE_MS);
196
+ }
197
+ };
198
+ // Serializes a period start into the backend's wire-label format (pinned by a contract test).
199
+ const serializePeriodLabel = (periodStart, granularity) => {
200
+ const year = pad(periodStart.getUTCFullYear(), 4);
201
+ const month = pad(periodStart.getUTCMonth() + 1, 2);
202
+ const day = pad(periodStart.getUTCDate(), 2);
203
+ switch (granularity) {
204
+ case "GDC.time.year":
205
+ return year;
206
+ case "GDC.time.quarter":
207
+ return `${year}-${Math.floor(periodStart.getUTCMonth() / 3) + 1}`;
208
+ case "GDC.time.month":
209
+ return `${year}-${month}`;
210
+ case "GDC.time.week_us":
211
+ return isoWeekLabel(periodStart);
212
+ case "GDC.time.date":
213
+ return `${year}-${month}-${day}`;
214
+ case "GDC.time.hour":
215
+ return `${year}-${month}-${day} ${pad(periodStart.getUTCHours(), 2)}`;
216
+ case "GDC.time.minute":
217
+ return `${year}-${month}-${day} ${pad(periodStart.getUTCHours(), 2)}:${pad(periodStart.getUTCMinutes(), 2)}`;
218
+ }
219
+ };
220
+ /**
221
+ * True when the granularity's platform strings and wire labels carry a time component ("… HH[:mm]")
222
+ * — hour and minute. Accepts both descriptor wire enums and GDC constants; false for anything the
223
+ * date-condition machinery does not support.
224
+ *
225
+ * @internal
226
+ */
227
+ export const usesTimeResolution = (granularity) => {
228
+ const normalized = normalizeSupported(granularity);
229
+ return normalized === "GDC.time.hour" || normalized === "GDC.time.minute";
230
+ };
231
+ const toPlatformString = (wall, withTime) => {
232
+ const date = `${pad(wall.getUTCFullYear(), 4)}-${pad(wall.getUTCMonth() + 1, 2)}-${pad(wall.getUTCDate(), 2)}`;
233
+ return withTime ? `${date} ${pad(wall.getUTCHours(), 2)}:${pad(wall.getUTCMinutes(), 2)}` : date;
234
+ };
235
+ // Inclusive period end: last day for day-and-coarser columns, last minute for hour/minute.
236
+ const inclusivePeriodEnd = (periodStart, granularity) => {
237
+ const nextStart = addPeriods(periodStart, granularity, 1);
238
+ return new Date(nextStart.getTime() - (usesTimeResolution(granularity) ? MINUTE_MS : DAY_MS));
239
+ };
240
+ const resolveAbsolute = (value, columnGranularity) => {
241
+ const from = parsePlatformDateString(value.from);
242
+ const to = parsePlatformDateString(value.to);
243
+ if (!from || !to) {
244
+ return null;
245
+ }
246
+ // A date-only `to` means the whole day, so its inclusive end is the day's last minute.
247
+ const toWallInclusive = to.hasTime ? to.wall : new Date(to.wall.getTime() + DAY_MS - MINUTE_MS);
248
+ if (from.wall.getTime() > toWallInclusive.getTime()) {
249
+ return null;
250
+ }
251
+ // Overlap semantics: bounds snap OUTWARD to the column periods containing the value's edges —
252
+ // a cell matches when its period touches the value ("sub-match is a match", per filters).
253
+ return {
254
+ fromLabel: serializePeriodLabel(startOfPeriod(from.wall, columnGranularity), columnGranularity),
255
+ toLabel: serializePeriodLabel(startOfPeriod(toWallInclusive, columnGranularity), columnGranularity),
256
+ };
257
+ };
258
+ const resolveRelative = (value, columnGranularity, columnTimezone, context) => {
259
+ const valueGranularity = value.granularity;
260
+ if (!isSupportedGranularity(valueGranularity)) {
261
+ return null;
262
+ }
263
+ if (!Number.isInteger(value.from) || !Number.isInteger(value.to) || value.from > value.to) {
264
+ return null;
265
+ }
266
+ const anchorWall = wallTimeFromInstant(context?.anchor ?? new Date(), columnTimezone);
267
+ const currentStart = startOfPeriod(anchorWall, valueGranularity);
268
+ const rangeStart = addPeriods(currentStart, valueGranularity, value.from);
269
+ const rangeEndInclusive = new Date(addPeriods(currentStart, valueGranularity, value.to + 1).getTime() - MINUTE_MS);
270
+ // Overlap semantics: the label pair covers every column period the window touches, whether the
271
+ // value granularity is coarser or finer than the column's.
272
+ return {
273
+ fromLabel: serializePeriodLabel(startOfPeriod(rangeStart, columnGranularity), columnGranularity),
274
+ toLabel: serializePeriodLabel(startOfPeriod(rangeEndInclusive, columnGranularity), columnGranularity),
275
+ };
276
+ };
277
+ /**
278
+ * Resolves a date condition value into label-space bounds at the column's granularity — the pair of
279
+ * column periods containing the value's edges, so the engine's label comparisons implement overlap
280
+ * semantics (a cell matches "is on" when its period touches the value; negations and strict
281
+ * orderings are exact complements). Null only when the value cannot resolve at all
282
+ * (fiscal/unknown granularity, malformed input); such a condition never matches and the authoring
283
+ * UI flags it invalid.
284
+ *
285
+ * This is the normative resolution contract — server-side evaluators must mirror it exactly.
286
+ *
287
+ * @internal
288
+ */
289
+ export function resolveDateConditionBounds(value, columnGranularity, columnTimezone, context) {
290
+ const normalized = normalizeSupported(columnGranularity);
291
+ if (!isDateConditionValue(value) || !normalized) {
292
+ return null;
293
+ }
294
+ return value.kind === "absoluteDate"
295
+ ? resolveAbsolute(value, normalized)
296
+ : resolveRelative(value, normalized, columnTimezone, context);
297
+ }
298
+ const snapWallRange = (wallFrom, wallTo, granularity) => {
299
+ if (wallFrom.getTime() > wallTo.getTime()) {
300
+ return null;
301
+ }
302
+ const withTime = usesTimeResolution(granularity);
303
+ return {
304
+ from: toPlatformString(startOfPeriod(wallFrom, granularity), withTime),
305
+ to: toPlatformString(inclusivePeriodEnd(startOfPeriod(wallTo, granularity), granularity), withTime),
306
+ };
307
+ };
308
+ /**
309
+ * Snaps a picker-produced wall-clock range to period bounds at the given granularity and serializes
310
+ * it into the platform strings an `absoluteDate` value persists (authoring-side).
311
+ * Input Dates are read in their LOCAL fields (that is what DateRangePicker produces). Null for
312
+ * granularities the resolver does not support (fiscal).
313
+ *
314
+ * @internal
315
+ */
316
+ export function snapToPeriodBounds(from, to, granularity) {
317
+ const normalized = normalizeSupported(granularity);
318
+ if (!normalized) {
319
+ return null;
320
+ }
321
+ return snapWallRange(localWallTime(from), localWallTime(to), normalized);
322
+ }
323
+ /**
324
+ * {@link snapToPeriodBounds} for platform date strings ("YYYY-MM-DD"[ HH:mm]) — the shape the date
325
+ * filter's absolute form delivers on apply. Null when either string is malformed, the range is
326
+ * inverted, or the granularity is unsupported.
327
+ *
328
+ * @internal
329
+ */
330
+ export function snapPlatformRangeToPeriodBounds(from, to, granularity) {
331
+ const normalized = normalizeSupported(granularity);
332
+ if (!normalized) {
333
+ return null;
334
+ }
335
+ const parsedFrom = parsePlatformDateString(from);
336
+ const parsedTo = parsePlatformDateString(to);
337
+ if (!parsedFrom || !parsedTo) {
338
+ return null;
339
+ }
340
+ // A date-only `to` means the WHOLE day (absolute presets carry day-level bounds). On hour/minute
341
+ // granularities that must snap to the day's last period, not the midnight its parse lands on.
342
+ const toWall = !parsedTo.hasTime && usesTimeResolution(normalized)
343
+ ? new Date(parsedTo.wall.getTime() + DAY_MS - MINUTE_MS)
344
+ : parsedTo.wall;
345
+ return snapWallRange(parsedFrom.wall, toWall, normalized);
346
+ }
@@ -11,7 +11,8 @@ export type { PivotTableNextAgGridLicenseConfig } from "./types/license.js";
11
11
  export type { PivotTableNextPaginationConfig, IPagination } from "./types/pagination.js";
12
12
  export type { PivotTableNextTranspositionConfig, MeasureGroupDimension, ColumnHeadersPosition, } from "./types/transposition.js";
13
13
  export type { PivotTableNextExperimentalConfig } from "./types/experimental.js";
14
- export type { PivotTableNextConditionalFormattingConfig, IConditionalFormatting, IConditionalFormattingRule, IConditionalFormattingCondition, IConditionalFormattingFormat, ConditionalFormattingTarget, ConditionalFormattingOperator, ConditionalFormattingTextOperator, ConditionalFormattingValue, } from "./types/conditionalFormatting.js";
14
+ export type { PivotTableNextConditionalFormattingConfig, IConditionalFormatting, IConditionalFormattingRule, IConditionalFormattingCondition, IConditionalFormattingFormat, ConditionalFormattingTarget, ConditionalFormattingOperator, ConditionalFormattingTextOperator, ConditionalFormattingEmptinessOperator, ConditionalFormattingValue, } from "./types/conditionalFormatting.js";
15
+ export { type ConditionalFormattingDateValue, allowedValueGranularities, isDateConditionValue, normalizeDateConditionGranularity, resolveDateConditionBounds, snapPlatformRangeToPeriodBounds, snapToPeriodBounds, usesTimeResolution, } from "./features/styling/dateConditionResolution.js";
15
16
  export { CorePivotTableNext } from "./PivotTableNextPluggable.js";
16
17
  export type { ICorePivotTableNextProps } from "./types/internal.js";
17
18
  export { type ColumnLocator, type IAttributeColumnLocator, type IAttributeColumnLocatorBody, type IMeasureColumnLocator, type IMeasureColumnLocatorBody, type ITotalColumnLocator, type ITotalColumnLocatorBody, isAttributeColumnLocator, isMeasureColumnLocator, isTotalColumnLocator, newAttributeColumnLocator, newMeasureColumnLocator, newTotalColumnLocator, } from "./types/locators.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACH,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,eAAe,GAClB,MAAM,iCAAiC,CAAC;AAEzC,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACpF,YAAY,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAClF,YAAY,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAClF,YAAY,EAAE,uCAAuC,EAAE,MAAM,gCAAgC,CAAC;AAC9F,YAAY,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAC5E,YAAY,EACR,uCAAuC,EACvC,mBAAmB,GACtB,MAAM,gCAAgC,CAAC;AACxC,YAAY,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AACpE,YAAY,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EAAE,8BAA8B,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzF,YAAY,EACR,iCAAiC,EACjC,qBAAqB,EACrB,qBAAqB,GACxB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAGhF,YAAY,EACR,yCAAyC,EACzC,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,EAC/B,4BAA4B,EAC5B,2BAA2B,EAC3B,6BAA6B,EAC7B,iCAAiC,EACjC,0BAA0B,GAC7B,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,YAAY,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,KAAK,iCAAiC,EACtC,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,EAClC,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACpC,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,gCAAgC,EACrC,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACpC,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC1B,wBAAwB,EACxB,4BAA4B,EAC5B,4BAA4B,EAC5B,6BAA6B,EAC7B,+BAA+B,EAC/B,4BAA4B,EAC5B,0BAA0B,EAC1B,6BAA6B,GAChC,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACR,gCAAgC,EAChC,aAAa,EACb,uBAAuB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,wBAAwB,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/next/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACH,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACd,eAAe,GAClB,MAAM,iCAAiC,CAAC;AAEzC,YAAY,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACpF,YAAY,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAClF,YAAY,EAAE,iCAAiC,EAAE,MAAM,0BAA0B,CAAC;AAClF,YAAY,EAAE,uCAAuC,EAAE,MAAM,gCAAgC,CAAC;AAC9F,YAAY,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;AAC5E,YAAY,EACR,uCAAuC,EACvC,mBAAmB,GACtB,MAAM,gCAAgC,CAAC;AACxC,YAAY,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AACpE,YAAY,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAC;AAC5E,YAAY,EAAE,8BAA8B,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzF,YAAY,EACR,iCAAiC,EACjC,qBAAqB,EACrB,qBAAqB,GACxB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EAAE,gCAAgC,EAAE,MAAM,yBAAyB,CAAC;AAGhF,YAAY,EACR,yCAAyC,EACzC,sBAAsB,EACtB,0BAA0B,EAC1B,+BAA+B,EAC/B,4BAA4B,EAC5B,2BAA2B,EAC3B,6BAA6B,EAC7B,iCAAiC,EACjC,sCAAsC,EACtC,0BAA0B,GAC7B,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EACH,KAAK,8BAA8B,EACnC,yBAAyB,EACzB,oBAAoB,EACpB,iCAAiC,EACjC,0BAA0B,EAC1B,+BAA+B,EAC/B,kBAAkB,EAClB,kBAAkB,GACrB,MAAM,+CAA+C,CAAC;AAGvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,YAAY,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,wBAAwB,EACxB,sBAAsB,EACtB,oBAAoB,EACpB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,GACxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,KAAK,iCAAiC,EACtC,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,EAClC,KAAK,gBAAgB,EACrB,KAAK,2BAA2B,EAChC,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACpC,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,gCAAgC,EACrC,KAAK,2BAA2B,EAChC,KAAK,+BAA+B,EACpC,qBAAqB,EACrB,2BAA2B,EAC3B,0BAA0B,EAC1B,wBAAwB,EACxB,4BAA4B,EAC5B,4BAA4B,EAC5B,6BAA6B,EAC7B,+BAA+B,EAC/B,4BAA4B,EAC5B,0BAA0B,EAC1B,6BAA6B,GAChC,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EACR,gCAAgC,EAChC,aAAa,EACb,uBAAuB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,wBAAwB,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC"}
package/esm/next/index.js CHANGED
@@ -2,6 +2,8 @@
2
2
  /* oxlint-disable no-barrel-files/no-barrel-files */
3
3
  export { PivotTableNext } from "./PivotTableNext.js";
4
4
  export { AgGridTokenProvider, enrichAgGridToken, useAgGridToken, withAgGridToken, } from "./context/AgGridTokenContext.js";
5
+ // Date-condition helpers shared with the authoring UI (sdk-ui-ext).
6
+ export { allowedValueGranularities, isDateConditionValue, normalizeDateConditionGranularity, resolveDateConditionBounds, snapPlatformRangeToPeriodBounds, snapToPeriodBounds, usesTimeResolution, } from "./features/styling/dateConditionResolution.js";
5
7
  // Pluggable Visualization
6
8
  export { CorePivotTableNext } from "./PivotTableNextPluggable.js";
7
9
  export { isAttributeColumnLocator, isMeasureColumnLocator, isTotalColumnLocator, newAttributeColumnLocator, newMeasureColumnLocator, newTotalColumnLocator, } from "./types/locators.js";
@@ -1,4 +1,4 @@
1
- import { type ComparisonConditionOperator, type RangeConditionOperator } from "@gooddata/sdk-model";
1
+ import { type ComparisonConditionOperator, type DateFilterGranularity, type RangeConditionOperator } from "@gooddata/sdk-model";
2
2
  /**
3
3
  * Identifies the measure or attribute a conditional-formatting rule targets. Layout-neutral on
4
4
  * purpose: the same target applies whether the item renders as a column or — when transposed — as a
@@ -14,25 +14,39 @@ export type ConditionalFormattingTarget = {
14
14
  measureIdentifier: string;
15
15
  };
16
16
  /**
17
- * Text and empty operators specific to conditional formatting. No existing SDK enum covers text
17
+ * Substring operators specific to conditional formatting. No existing SDK enum covers text
18
18
  * matching (attribute filters are element-based IN/NOT_IN), so these are CF-specific.
19
19
  *
20
20
  * @alpha
21
21
  */
22
- export type ConditionalFormattingTextOperator = "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH" | "IS_EMPTY" | "IS_NOT_EMPTY";
22
+ export type ConditionalFormattingTextOperator = "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH";
23
23
  /**
24
- * Every operator a condition may use. Numeric and range operators reuse the SDK
25
- * measure-value-filter vocabulary (`ComparisonConditionOperator`, `RangeConditionOperator` from
26
- * `@gooddata/sdk-model`); `"ALL"` always matches; text/empty operators are
27
- * {@link ConditionalFormattingTextOperator}.
24
+ * Emptiness operators — target-agnostic: an empty cell (null measure value, valueless attribute
25
+ * element) is matched only by these, on any target kind.
28
26
  *
29
27
  * @alpha
30
28
  */
31
- export type ConditionalFormattingOperator = "ALL" | ComparisonConditionOperator | RangeConditionOperator | ConditionalFormattingTextOperator;
29
+ export type ConditionalFormattingEmptinessOperator = "IS_EMPTY" | "IS_NOT_EMPTY";
32
30
  /**
33
- * The operand a condition compares against. Discriminated so range / no-operand / (future
31
+ * Every operator a stored condition may carry. One shared, shape-grouped vocabulary: numeric and
32
+ * range operators reuse the SDK measure-value-filter enums (`ComparisonConditionOperator`,
33
+ * `RangeConditionOperator` from `@gooddata/sdk-model`); `"ALL"` always matches non-empty cells;
34
+ * substring operators are {@link ConditionalFormattingTextOperator}; emptiness operators are
35
+ * {@link ConditionalFormattingEmptinessOperator}. Which subset a target kind AUTHORS is editor
36
+ * policy (see `operatorsForTarget` in sdk-ui-ext); the evaluation engine accepts any combination
37
+ * and treats inapplicable ones as never matching.
38
+ *
39
+ * @alpha
40
+ */
41
+ export type ConditionalFormattingOperator = "ALL" | ComparisonConditionOperator | RangeConditionOperator | ConditionalFormattingTextOperator | ConditionalFormattingEmptinessOperator;
42
+ /**
43
+ * The operand a condition compares against. Discriminated so range / no-operand / date / (future
34
44
  * column-reference) shapes stay valid by construction.
35
45
  *
46
+ * Date values target date attributes and express a period; a single date is a period whose bounds
47
+ * coincide. "Is on" (EQUAL_TO) means the cell's period lies within the value period; "Is after"
48
+ * (GREATER_THAN) means after the period ends; "Is before" (LESS_THAN) before it starts.
49
+ *
36
50
  * @alpha
37
51
  */
38
52
  export type ConditionalFormattingValue = {
@@ -44,6 +58,33 @@ export type ConditionalFormattingValue = {
44
58
  kind: "literalRange";
45
59
  from: number;
46
60
  to: number;
61
+ } | {
62
+ kind: "absoluteDate";
63
+ /**
64
+ * Period start as a platform date string: "YYYY-MM-DD", or "YYYY-MM-DD HH:mm" for
65
+ * hour/minute-granularity targets. Snapped to the period start at save time.
66
+ */
67
+ from: string;
68
+ /**
69
+ * Inclusive period end — the last day (or minute) of the period, mirroring how absolute
70
+ * date filters store their `to` bound.
71
+ */
72
+ to: string;
73
+ } | {
74
+ kind: "relativeDate";
75
+ /**
76
+ * Granularity the offsets count in (linear granularities only).
77
+ */
78
+ granularity: DateFilterGranularity;
79
+ /**
80
+ * Integer period offset of the range start; 0 = the period containing the anchor,
81
+ * negative = past, positive = future.
82
+ */
83
+ from: number;
84
+ /**
85
+ * Integer period offset of the range end (inclusive), \>= `from`.
86
+ */
87
+ to: number;
47
88
  };
48
89
  /**
49
90
  * The visual format applied to a matched cell or row.
@@ -111,6 +152,26 @@ export interface IConditionalFormatting {
111
152
  * @internal
112
153
  */
113
154
  export type ConditionalFormattingTriggerColIds = readonly (readonly string[])[];
155
+ /**
156
+ * Label-space bounds of one resolved date condition: the first and last wire label (at the target
157
+ * column's granularity) of the value period. Labels are fixed-width and zero-padded, so containment
158
+ * and ordering reduce to plain string comparison.
159
+ *
160
+ * @internal
161
+ */
162
+ export interface IDateConditionBounds {
163
+ fromLabel: string;
164
+ toLabel: string;
165
+ }
166
+ /**
167
+ * Resolved date bounds keyed by `<ruleIndex>:<conditionId>` (ids in hand-authored config are only
168
+ * trustworthy within a rule; position is collision-proof) — computed once per render alongside
169
+ * trigger resolution. `null` marks an unresolvable condition (malformed value, fiscal or unknown
170
+ * granularity, non-date target): it never matches. Conditions without a date value are absent.
171
+ *
172
+ * @internal
173
+ */
174
+ export type ConditionalFormattingDateBounds = Record<string, IDateConditionBounds | null>;
114
175
  /**
115
176
  * Config slot intersected into {@link PivotTableNextConfig} so conditional formatting can be passed
116
177
  * through the `config` prop (and read back from insight properties).
@@ -1 +1 @@
1
- {"version":3,"file":"conditionalFormatting.d.ts","sourceRoot":"","sources":["../../../src/next/types/conditionalFormatting.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,2BAA2B,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAEpG;;;;;;GAMG;AACH,MAAM,MAAM,2BAA2B,GACjC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD;;;;;GAKG;AACH,MAAM,MAAM,iCAAiC,GACvC,UAAU,GACV,cAAc,GACd,aAAa,GACb,iBAAiB,GACjB,WAAW,GACX,eAAe,GACf,UAAU,GACV,cAAc,CAAC;AAErB;;;;;;;GAOG;AACH,MAAM,MAAM,6BAA6B,GACnC,KAAK,GACL,2BAA2B,GAC3B,sBAAsB,GACtB,iCAAiC,CAAC;AAExC;;;;;GAKG;AACH,MAAM,MAAM,0BAA0B,GAChC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IACzC;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,+BAA+B;IAC5C,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,6BAA6B,CAAC;IACxC,KAAK,EAAE,0BAA0B,CAAC;IAClC,MAAM,EAAE,4BAA4B,CAAC;CACxC;AAED;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,2BAA2B,CAAC;IACpC,UAAU,EAAE,SAAS,+BAA+B,EAAE,CAAC;CAC1D;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,SAAS,0BAA0B,EAAE,CAAC;CAChD;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,kCAAkC,GAAG,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC;AAEhF;;;;;GAKG;AACH,MAAM,MAAM,yCAAyC,GAAG;IACpD;;OAEG;IACH,qBAAqB,CAAC,EAAE,sBAAsB,CAAC;CAClD,CAAC"}
1
+ {"version":3,"file":"conditionalFormatting.d.ts","sourceRoot":"","sources":["../../../src/next/types/conditionalFormatting.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@
10
10
  import { AttributesMeasuresOrPlaceholders } from '@gooddata/sdk-ui';
11
11
  import { AttributesOrPlaceholders } from '@gooddata/sdk-ui';
12
12
  import { ComparisonConditionOperator } from '@gooddata/sdk-model';
13
+ import { DateFilterGranularity } from '@gooddata/sdk-model';
13
14
  import { ExplicitDrill } from '@gooddata/sdk-ui';
14
15
  import { IAnalyticalBackend } from '@gooddata/sdk-backend-spi';
15
16
  import { IAttribute } from '@gooddata/sdk-model';
@@ -83,14 +84,25 @@ export declare type ColumnWidthItemNext = IAttributeColumnWidthItemNext | IMeasu
83
84
  export declare type ColumnWidthNext = IAbsoluteColumnWidthNext | IAutoColumnWidthNext;
84
85
 
85
86
  /**
86
- * Every operator a condition may use. Numeric and range operators reuse the SDK
87
- * measure-value-filter vocabulary (`ComparisonConditionOperator`, `RangeConditionOperator` from
88
- * `@gooddata/sdk-model`); `"ALL"` always matches; text/empty operators are
89
- * {@link ConditionalFormattingTextOperator}.
87
+ * Emptiness operators — target-agnostic: an empty cell (null measure value, valueless attribute
88
+ * element) is matched only by these, on any target kind.
90
89
  *
91
90
  * @alpha
92
91
  */
93
- export declare type ConditionalFormattingOperator = "ALL" | ComparisonConditionOperator | RangeConditionOperator | ConditionalFormattingTextOperator;
92
+ export declare type ConditionalFormattingEmptinessOperator = "IS_EMPTY" | "IS_NOT_EMPTY";
93
+
94
+ /**
95
+ * Every operator a stored condition may carry. One shared, shape-grouped vocabulary: numeric and
96
+ * range operators reuse the SDK measure-value-filter enums (`ComparisonConditionOperator`,
97
+ * `RangeConditionOperator` from `@gooddata/sdk-model`); `"ALL"` always matches non-empty cells;
98
+ * substring operators are {@link ConditionalFormattingTextOperator}; emptiness operators are
99
+ * {@link ConditionalFormattingEmptinessOperator}. Which subset a target kind AUTHORS is editor
100
+ * policy (see `operatorsForTarget` in sdk-ui-ext); the evaluation engine accepts any combination
101
+ * and treats inapplicable ones as never matching.
102
+ *
103
+ * @alpha
104
+ */
105
+ export declare type ConditionalFormattingOperator = "ALL" | ComparisonConditionOperator | RangeConditionOperator | ConditionalFormattingTextOperator | ConditionalFormattingEmptinessOperator;
94
106
 
95
107
  /**
96
108
  * Identifies the measure or attribute a conditional-formatting rule targets. Layout-neutral on
@@ -108,17 +120,21 @@ export declare type ConditionalFormattingTarget = {
108
120
  };
109
121
 
110
122
  /**
111
- * Text and empty operators specific to conditional formatting. No existing SDK enum covers text
123
+ * Substring operators specific to conditional formatting. No existing SDK enum covers text
112
124
  * matching (attribute filters are element-based IN/NOT_IN), so these are CF-specific.
113
125
  *
114
126
  * @alpha
115
127
  */
116
- export declare type ConditionalFormattingTextOperator = "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH" | "IS_EMPTY" | "IS_NOT_EMPTY";
128
+ export declare type ConditionalFormattingTextOperator = "CONTAINS" | "NOT_CONTAINS" | "STARTS_WITH" | "NOT_STARTS_WITH" | "ENDS_WITH" | "NOT_ENDS_WITH";
117
129
 
118
130
  /**
119
- * The operand a condition compares against. Discriminated so range / no-operand / (future
131
+ * The operand a condition compares against. Discriminated so range / no-operand / date / (future
120
132
  * column-reference) shapes stay valid by construction.
121
133
  *
134
+ * Date values target date attributes and express a period; a single date is a period whose bounds
135
+ * coincide. "Is on" (EQUAL_TO) means the cell's period lies within the value period; "Is after"
136
+ * (GREATER_THAN) means after the period ends; "Is before" (LESS_THAN) before it starts.
137
+ *
122
138
  * @alpha
123
139
  */
124
140
  export declare type ConditionalFormattingValue = {
@@ -130,6 +146,33 @@ export declare type ConditionalFormattingValue = {
130
146
  kind: "literalRange";
131
147
  from: number;
132
148
  to: number;
149
+ } | {
150
+ kind: "absoluteDate";
151
+ /**
152
+ * Period start as a platform date string: "YYYY-MM-DD", or "YYYY-MM-DD HH:mm" for
153
+ * hour/minute-granularity targets. Snapped to the period start at save time.
154
+ */
155
+ from: string;
156
+ /**
157
+ * Inclusive period end — the last day (or minute) of the period, mirroring how absolute
158
+ * date filters store their `to` bound.
159
+ */
160
+ to: string;
161
+ } | {
162
+ kind: "relativeDate";
163
+ /**
164
+ * Granularity the offsets count in (linear granularities only).
165
+ */
166
+ granularity: DateFilterGranularity;
167
+ /**
168
+ * Integer period offset of the range start; 0 = the period containing the anchor,
169
+ * negative = past, positive = future.
170
+ */
171
+ from: number;
172
+ /**
173
+ * Integer period offset of the range end (inclusive), \>= `from`.
174
+ */
175
+ to: number;
133
176
  };
134
177
 
135
178
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-ui-pivot",
3
- "version": "11.50.0-alpha.2",
3
+ "version": "11.50.0-alpha.4",
4
4
  "description": "GoodData.UI SDK - Pivot Table",
5
5
  "license": "MIT",
6
6
  "author": "GoodData Corporation",
@@ -42,12 +42,12 @@
42
42
  "ts-invariant": "0.10.3",
43
43
  "tslib": "2.8.1",
44
44
  "uuid": "11.1.1",
45
- "@gooddata/sdk-backend-spi": "11.50.0-alpha.2",
46
- "@gooddata/sdk-model": "11.50.0-alpha.2",
47
- "@gooddata/sdk-ui": "11.50.0-alpha.2",
48
- "@gooddata/sdk-ui-theme-provider": "11.50.0-alpha.2",
49
- "@gooddata/sdk-ui-kit": "11.50.0-alpha.2",
50
- "@gooddata/sdk-ui-vis-commons": "11.50.0-alpha.2"
45
+ "@gooddata/sdk-backend-spi": "11.50.0-alpha.4",
46
+ "@gooddata/sdk-model": "11.50.0-alpha.4",
47
+ "@gooddata/sdk-ui": "11.50.0-alpha.4",
48
+ "@gooddata/sdk-ui-theme-provider": "11.50.0-alpha.4",
49
+ "@gooddata/sdk-ui-kit": "11.50.0-alpha.4",
50
+ "@gooddata/sdk-ui-vis-commons": "11.50.0-alpha.4"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@microsoft/api-documenter": "^7.17.0",
@@ -89,12 +89,12 @@
89
89
  "typescript": "5.9.3",
90
90
  "vitest": "4.1.8",
91
91
  "vitest-dom": "0.1.1",
92
- "@gooddata/eslint-config": "11.50.0-alpha.2",
93
- "@gooddata/oxlint-config": "11.50.0-alpha.2",
94
- "@gooddata/sdk-backend-base": "11.50.0-alpha.2",
95
- "@gooddata/sdk-backend-mockingbird": "11.50.0-alpha.2",
96
- "@gooddata/stylelint-config": "11.50.0-alpha.2",
97
- "@gooddata/reference-workspace": "11.50.0-alpha.2"
92
+ "@gooddata/oxlint-config": "11.50.0-alpha.4",
93
+ "@gooddata/eslint-config": "11.50.0-alpha.4",
94
+ "@gooddata/reference-workspace": "11.50.0-alpha.4",
95
+ "@gooddata/sdk-backend-mockingbird": "11.50.0-alpha.4",
96
+ "@gooddata/stylelint-config": "11.50.0-alpha.4",
97
+ "@gooddata/sdk-backend-base": "11.50.0-alpha.4"
98
98
  },
99
99
  "peerDependencies": {
100
100
  "react": "^18.0.0 || ^19.0.0",