diff --git a/.prettierignore b/.prettierignore index 8afa953c..8b03f2d0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,6 +5,7 @@ node_modules/ # Ignore artifacts: dist/ +**/dist/ coverage/ # Ignore auto-generated files: diff --git a/CHANGELOG.md b/CHANGELOG.md index fb5ab704..bfa9a45d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,39 @@ # Changelog +## [1.18.0] - 2024-09-03 + +### Added + +- Add auto zoom feature to `DashboardWidget` +- Support forecast and trend in Fusion widgets + +### Changed + +- Improve `SisenseContextProvider`: support of Fusion authentication +- Extend `measureFactory.customFormula` to support filters +- Improve `PivotTable`: proper handling of web socket readiness +- Fix `DashboardWidget` with filter relations and highlights +- Improve tooltips for forecast and trend +- Improve charts: palette colors of `BoxplotChart`, refactoring `ThemeSettings.chart.panelBackgroundColor`, making `color` column optional in `AreamapChart`, support of thousands separator from old `numberFormat` config, axis labels for stacked percent charts +- Improve infrastructure: visual tests of dashboard assets of diffent widget types, replacement of CommonJS dependencies (e.g., lodash) + +## [1.17.1] - 2024-08-22 + +### Changed +- Improve error handling of WAT authentication +- Fix an issue in `Table` so user-provided data are sorted in their entirety, instead of per page +- Apply widget description as `accessibility.description` for `ChartWidget` + ## [1.17.0] - 2024-08-20 ### Added - Move components `DashboardById` and `Dashboard` to internal alpha for React, Angular, and Vue -- Support external usage tracking in `AppConfig.trackingConfig.onTrackingEvent` +- Support external usage tracking callback configured through `trackingConfig.onTrackingEvent` of the `AppConfig` - Refactor `ChartWidget` to reuse `DrilldownWidget` internally - Support drill down for scatter chart widgets ### Changed -- Mark internal property `enableTracking?` as `@deprecated` in `SisenseContextProviderProps` – use `AppConfig.trackingConfig.enabled` instead +- Deprecate internal `enableTracking` property in `SisenseContextProviderProps` – use `trackingConfig.enabled` of the `AppConfig` instead - Extend `ThemeSettings` to support animation-related config - Improve dashboard rendering: locked filters in cross filtering, resetting levels of `CascadingFilterTile`, highlight of all categories in cartesian charts, dashboard theme setting, matching theme for widget header info panel - Refactor component `Table` to reduce computations and re-renders diff --git a/ci/lint_commits.sh b/ci/lint_commits.sh index 0ef7da07..f599e8a4 100755 --- a/ci/lint_commits.sh +++ b/ci/lint_commits.sh @@ -3,10 +3,10 @@ set -o xtrace # It looks like the external URL is not set up correctly for GitLab -# It is probably set to http://gitlab.sisense.com/ instead of https://gitlab.sisense.com/ (HTTP instead of HTTPS) +# It is probably set to http://gitlab.rnd.sisense.com/ instead of https://gitlab.rnd.sisense.com/ (HTTP instead of HTTPS) # Reference: https://docs.gitlab.com/omnibus/settings/configuration.html#configure-the-external-url-for-gitlab # As a temporary workaround, we are setting the remote URL manually -git remote set-url origin https://gitlab-ci-token:"$GITLAB_TOKEN"@gitlab.sisense.com/SisenseTeam/compose-sdk-monorepo.git +git remote set-url origin https://gitlab-ci-token:"$GITLAB_TOKEN"@gitlab.rnd.sisense.com/SisenseTeam/compose-sdk-monorepo.git if [[ "$CI_COMMIT_REF_NAME" == "" ]]; then echo '$CI_COMMIT_REF_NAME missing' diff --git a/docs-md/sdk/CHANGELOG.md b/docs-md/sdk/CHANGELOG.md index fb5ab704..bfa9a45d 100644 --- a/docs-md/sdk/CHANGELOG.md +++ b/docs-md/sdk/CHANGELOG.md @@ -1,15 +1,39 @@ # Changelog +## [1.18.0] - 2024-09-03 + +### Added + +- Add auto zoom feature to `DashboardWidget` +- Support forecast and trend in Fusion widgets + +### Changed + +- Improve `SisenseContextProvider`: support of Fusion authentication +- Extend `measureFactory.customFormula` to support filters +- Improve `PivotTable`: proper handling of web socket readiness +- Fix `DashboardWidget` with filter relations and highlights +- Improve tooltips for forecast and trend +- Improve charts: palette colors of `BoxplotChart`, refactoring `ThemeSettings.chart.panelBackgroundColor`, making `color` column optional in `AreamapChart`, support of thousands separator from old `numberFormat` config, axis labels for stacked percent charts +- Improve infrastructure: visual tests of dashboard assets of diffent widget types, replacement of CommonJS dependencies (e.g., lodash) + +## [1.17.1] - 2024-08-22 + +### Changed +- Improve error handling of WAT authentication +- Fix an issue in `Table` so user-provided data are sorted in their entirety, instead of per page +- Apply widget description as `accessibility.description` for `ChartWidget` + ## [1.17.0] - 2024-08-20 ### Added - Move components `DashboardById` and `Dashboard` to internal alpha for React, Angular, and Vue -- Support external usage tracking in `AppConfig.trackingConfig.onTrackingEvent` +- Support external usage tracking callback configured through `trackingConfig.onTrackingEvent` of the `AppConfig` - Refactor `ChartWidget` to reuse `DrilldownWidget` internally - Support drill down for scatter chart widgets ### Changed -- Mark internal property `enableTracking?` as `@deprecated` in `SisenseContextProviderProps` – use `AppConfig.trackingConfig.enabled` instead +- Deprecate internal `enableTracking` property in `SisenseContextProviderProps` – use `trackingConfig.enabled` of the `AppConfig` instead - Extend `ThemeSettings` to support animation-related config - Improve dashboard rendering: locked filters in cross filtering, resetting levels of `CascadingFilterTile`, highlight of all categories in cartesian charts, dashboard theme setting, matching theme for widget header info panel - Refactor component `Table` to reduce computations and re-renders diff --git a/docs-md/sdk/modules/sdk-data/factories/namespace.measureFactory/functions/function.customFormula.md b/docs-md/sdk/modules/sdk-data/factories/namespace.measureFactory/functions/function.customFormula.md index 757d0122..bc8bf78e 100644 --- a/docs-md/sdk/modules/sdk-data/factories/namespace.measureFactory/functions/function.customFormula.md +++ b/docs-md/sdk/modules/sdk-data/factories/namespace.measureFactory/functions/function.customFormula.md @@ -7,17 +7,17 @@ title: customFormula > **customFormula**( `title`, `formula`, - `context`): [`Attribute`](../../../interfaces/interface.Attribute.md) \| [`Measure`](../../../interfaces/interface.Measure.md) + `context`): [`CalculatedMeasure`](../../../interfaces/interface.CalculatedMeasure.md) Creates a calculated measure for a valid custom formula built from [base functions](/guides/sdk/reference/functions.html#measured-value-functions). -Use square brackets (`[]`) within the `formula` property to include dimensions or measures. -Each unique dimension or measure included in the `formula` must be defined using a property:value pair in the `context` parameter. +Use square brackets (`[]`) within the `formula` property to include dimensions, measures, or filters. +Each unique dimension, measure, or filter included in the `formula` must be defined using a property:value pair in the `context` parameter. You can nest custom formulas by placing one inside the `formula` parameter of another. Note: To use [shared formulas](https://docs.sisense.com/main/SisenseLinux/shared-formulas.htm) -from a Fusion Embed instance, you must fetch them first using [useGetSharedFormula](../../../../sdk-ui/fusion-embed/function.useGetSharedFormula.md). +from a Fusion instance, you must fetch them first using [useGetSharedFormula](../../../../sdk-ui/fusion-embed/function.useGetSharedFormula.md). ## Parameters @@ -25,11 +25,11 @@ from a Fusion Embed instance, you must fetch them first using [useGetSharedFormu | :------ | :------ | :------ | | `title` | `string` | Title of the measure to be displayed in legend | | `formula` | `string` | Formula to be used for the measure | -| `context` | [`CustomFormulaContext`](../../../interfaces/interface.CustomFormulaContext.md) | Formula context as a map of strings to measures or attributes | +| `context` | [`CustomFormulaContext`](../../../interfaces/interface.CustomFormulaContext.md) | Formula context as a map of strings to attributes, measures, or filters | ## Returns -[`Attribute`](../../../interfaces/interface.Attribute.md) \| [`Measure`](../../../interfaces/interface.Measure.md) +[`CalculatedMeasure`](../../../interfaces/interface.CalculatedMeasure.md) A calculated measure instance @@ -57,3 +57,15 @@ const profitabilityRatioRank = measureFactory.customFormula( }, ); ``` + +Another example of constructing a custom formula using measures and filters +```ts +const totalCostWithFilter = measureFactory.customFormula( + 'Total Cost with Filter', + '(SUM([cost]), [categoryFilter])', + { + cost: DM.Commerce.Cost, + categoryFilter: filterFactory.members(DM.Category.Category, ['Apple Mac Desktops']), + }, +); +``` diff --git a/docs-md/sdk/modules/sdk-data/interfaces/interface.CustomFormulaContext.md b/docs-md/sdk/modules/sdk-data/interfaces/interface.CustomFormulaContext.md index 6084ae8a..e79bc8f8 100644 --- a/docs-md/sdk/modules/sdk-data/interfaces/interface.CustomFormulaContext.md +++ b/docs-md/sdk/modules/sdk-data/interfaces/interface.CustomFormulaContext.md @@ -4,6 +4,8 @@ title: CustomFormulaContext # Interface CustomFormulaContext +Context for a custom formula, as defined by `measureFactory.customFormula()` + ## Indexable - \[`key`: `string`\]: [`Attribute`](interface.Attribute.md) \| [`Measure`](interface.Measure.md) + \[`key`: `string`\]: [`Attribute`](interface.Attribute.md) \| [`Measure`](interface.Measure.md) \| [`Filter`](interface.Filter.md) diff --git a/docs-md/sdk/modules/sdk-ui-angular/charts/class.AreamapChartComponent.md b/docs-md/sdk/modules/sdk-ui-angular/charts/class.AreamapChartComponent.md index 3863668a..e9979aea 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/charts/class.AreamapChartComponent.md +++ b/docs-md/sdk/modules/sdk-ui-angular/charts/class.AreamapChartComponent.md @@ -14,7 +14,9 @@ An Angular component that allows to visualize geographical data as polygons on a [dataOptions]="areamapChart.dataOptions" [styleOptions]="areamapChart.styleOptions" (dataPointClick)="logArguments($event)" - /> * ``` + /> +``` + ```ts import { Component } from '@angular/core'; import { measureFactory } from '@sisense/sdk-data'; diff --git a/docs-md/sdk/modules/sdk-ui-angular/charts/class.BarChartComponent.md b/docs-md/sdk/modules/sdk-ui-angular/charts/class.BarChartComponent.md index 4f874d0b..f055d403 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/charts/class.BarChartComponent.md +++ b/docs-md/sdk/modules/sdk-ui-angular/charts/class.BarChartComponent.md @@ -18,7 +18,9 @@ whose lengths are proportional to the values that they represent. (dataPointClick)="logArguments($event)" (dataPointContextMenu)="logArguments($event)" (dataPointsSelect)="logArguments($event)" - /> * ``` + /> +``` + ```ts import { Component } from '@angular/core'; import { measureFactory, filterFactory } from '@sisense/sdk-data'; diff --git a/docs-md/sdk/modules/sdk-ui-angular/charts/class.BoxplotChartComponent.md b/docs-md/sdk/modules/sdk-ui-angular/charts/class.BoxplotChartComponent.md index 2ff813ee..4e1e4bcb 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/charts/class.BoxplotChartComponent.md +++ b/docs-md/sdk/modules/sdk-ui-angular/charts/class.BoxplotChartComponent.md @@ -18,7 +18,9 @@ variability, and center of a data set along an axis. (dataPointClick)="logArguments($event)" (dataPointContextMenu)="logArguments($event)" (dataPointsSelect)="logArguments($event)" - /> * ``` + /> +``` + ```ts import { Component } from '@angular/core'; import { filterFactory } from '@sisense/sdk-data'; diff --git a/docs-md/sdk/modules/sdk-ui-angular/charts/class.ChartComponent.md b/docs-md/sdk/modules/sdk-ui-angular/charts/class.ChartComponent.md index 6becca4f..aec75329 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/charts/class.ChartComponent.md +++ b/docs-md/sdk/modules/sdk-ui-angular/charts/class.ChartComponent.md @@ -10,6 +10,18 @@ An Angular component used for easily switching chart types or rendering multiple An example of using the `Chart` component to plot a column chart of the Sample Healthcare data source hosted in a Sisense instance: + +```html + + +``` + ```ts // Component behavior in .component.ts chart = { @@ -39,16 +51,6 @@ chart = { }, }; ``` -```html - - -``` diff --git a/docs-md/sdk/modules/sdk-ui-angular/filter-tiles/class.DateRangeFilterTileComponent.md b/docs-md/sdk/modules/sdk-ui-angular/filter-tiles/class.DateRangeFilterTileComponent.md index 49de4877..140bd9a0 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/filter-tiles/class.DateRangeFilterTileComponent.md +++ b/docs-md/sdk/modules/sdk-ui-angular/filter-tiles/class.DateRangeFilterTileComponent.md @@ -43,7 +43,7 @@ export class FiltersComponent { }; } ``` - + ## Implements diff --git a/docs-md/sdk/modules/sdk-ui-angular/filter-tiles/class.MemberFilterTileComponent.md b/docs-md/sdk/modules/sdk-ui-angular/filter-tiles/class.MemberFilterTileComponent.md index 9a6b3e48..673b0afa 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/filter-tiles/class.MemberFilterTileComponent.md +++ b/docs-md/sdk/modules/sdk-ui-angular/filter-tiles/class.MemberFilterTileComponent.md @@ -39,7 +39,7 @@ export class FiltersComponent { }; } ``` - + ## Implements diff --git a/docs-md/sdk/modules/sdk-ui-angular/fusion-embed/class.DashboardWidgetComponent.md b/docs-md/sdk/modules/sdk-ui-angular/fusion-embed/class.DashboardWidgetComponent.md index c42c698e..1210fdad 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/fusion-embed/class.DashboardWidgetComponent.md +++ b/docs-md/sdk/modules/sdk-ui-angular/fusion-embed/class.DashboardWidgetComponent.md @@ -27,12 +27,13 @@ import * as DM from '../../assets/sample-healthcare-model'; @Component({ selector: 'app-widgets', -templateUrl: './widgets.component.html', -styleUrls: ['./widgets.component.scss'], + templateUrl: './widgets.component.html', + styleUrls: ['./widgets.component.scss'], }) export class WidgetsComponent { widgetOid: string = '60f3e3e3e4b0e3e3e4b0e3e3'; dashboardOid: string = '60f3e3e3e4b0e3e3e4b0e3e3'; +} ``` ## Implements diff --git a/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.AreamapChartDataOptions.md b/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.AreamapChartDataOptions.md index d2ff9da0..5f6f4142 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.AreamapChartDataOptions.md +++ b/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.AreamapChartDataOptions.md @@ -11,7 +11,7 @@ to geographic features of an Areamap chart. ### color -> **color**: [[`MeasureColumn`](../../sdk-data/interfaces/interface.MeasureColumn.md) \| [`CalculatedMeasureColumn`](../../sdk-data/interfaces/interface.CalculatedMeasureColumn.md) \| [`StyledMeasureColumn`](interface.StyledMeasureColumn.md)] +> **color**?: [[`MeasureColumn`](../../sdk-data/interfaces/interface.MeasureColumn.md) \| [`CalculatedMeasureColumn`](../../sdk-data/interfaces/interface.CalculatedMeasureColumn.md) \| [`StyledMeasureColumn`](interface.StyledMeasureColumn.md)] Measure column (or measure) encoded by the color of the countries (or states) on the map. diff --git a/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.SisenseContextConfig.md b/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.SisenseContextConfig.md index 1914a0b1..39e1f0ad 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.SisenseContextConfig.md +++ b/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.SisenseContextConfig.md @@ -60,6 +60,16 @@ To signify that the token is pending (e.g., being generated), set the value to ` *** +#### useFusionAuth + +> **useFusionAuth**?: `boolean` + +Flag to delegate authentication to Fusion. + +Defaults to `false`. + +*** + #### wat > **wat**?: `null` \| `string` diff --git a/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.ThemeSettings.md b/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.ThemeSettings.md index ebdc07ba..5cbd46c1 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.ThemeSettings.md +++ b/docs-md/sdk/modules/sdk-ui-angular/interfaces/interface.ThemeSettings.md @@ -24,6 +24,14 @@ Chart theme settings *** +### filter + +> **filter**?: [`FilterThemeSettings`](../../sdk-ui/type-aliases/type-alias.FilterThemeSettings.md) + +Filter theme settings + +*** + ### general > **general**?: [`GeneralThemeSettings`](../../sdk-ui/interfaces/interface.GeneralThemeSettings.md) diff --git a/docs-md/sdk/modules/sdk-ui-angular/type-aliases/type-alias.Navigator.md b/docs-md/sdk/modules/sdk-ui-angular/type-aliases/type-alias.Navigator.md index 804508c7..5429fb69 100644 --- a/docs-md/sdk/modules/sdk-ui-angular/type-aliases/type-alias.Navigator.md +++ b/docs-md/sdk/modules/sdk-ui-angular/type-aliases/type-alias.Navigator.md @@ -15,3 +15,9 @@ Options that define navigator - zoom/pan tool for large datasets in a chart. **enabled**: `boolean` Boolean flag that defines if navigator should be shown on the chart + +*** + +### `scrollerLocation` + +**scrollerLocation**?: [`AutoZoomNavigatorScrollerLocation`](../../sdk-ui/type-aliases/type-alias.AutoZoomNavigatorScrollerLocation.md) diff --git a/docs-md/sdk/modules/sdk-ui-vue/chart-utilities/class.ChartWidget.md b/docs-md/sdk/modules/sdk-ui-vue/chart-utilities/class.ChartWidget.md index e19f8d45..37b56c80 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/chart-utilities/class.ChartWidget.md +++ b/docs-md/sdk/modules/sdk-ui-vue/chart-utilities/class.ChartWidget.md @@ -47,7 +47,7 @@ Here's how you can use the ChartWidget component in a Vue application: import { ref } from 'vue'; import { measureFactory, filterFactory } from '@sisense/sdk-data'; import * as DM from '../assets/sample-retail-model'; -import {ChartWidget} from '@sisense/sdk-ui-vue'; +import { ChartWidget } from '@sisense/sdk-ui-vue'; const dimProductName = DM.DimProducts.ProductName; const measureTotalRevenue = measureFactory.sum(DM.Fact_Sale_orders.OrderRevenue, 'Total Revenue'); diff --git a/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreaChart.md b/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreaChart.md index 04e155b1..826e1c42 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreaChart.md +++ b/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreaChart.md @@ -23,7 +23,7 @@ Here's how you can use the AreaChart component in a Vue application: import { ref } from 'vue'; import { measureFactory, filterFactory } from '@sisense/sdk-data'; import * as DM from '../assets/sample-retail-model'; -import {AreaChart, type AreaChartProps} from '@sisense/sdk-ui-vue'; +import { AreaChart, type AreaChartProps } from '@sisense/sdk-ui-vue'; const dimProductName = DM.DimProducts.ProductName; const measureTotalRevenue = measureFactory.sum(DM.Fact_Sale_orders.OrderRevenue, 'Total Revenue'); diff --git a/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreaRangeChart.md b/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreaRangeChart.md index 9a5c1185..76a0a25d 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreaRangeChart.md +++ b/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreaRangeChart.md @@ -24,7 +24,7 @@ Here's how you can use the AreaRangeChart component in a Vue application: import { ref } from 'vue'; import { measureFactory } from '@sisense/sdk-data'; import * as DM from '../assets/sample-retail-model'; -import {AreaRangeChart, type AreaRangeChartProps} from '@sisense/sdk-ui-vue'; +import { AreaRangeChart, type AreaRangeChartProps } from '@sisense/sdk-ui-vue'; const dimProductName = DM.DimProducts.ProductName; const areaRangeChartProps = ref({ diff --git a/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreamapChart.md b/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreamapChart.md index 0e4d3b24..9b0fd296 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreamapChart.md +++ b/docs-md/sdk/modules/sdk-ui-vue/charts/class.AreamapChart.md @@ -22,7 +22,7 @@ Here's how you can use the AreamapChart component in a Vue application: import { ref } from 'vue'; import { measureFactory, filterFactory } from '@sisense/sdk-data'; import * as DM from '../assets/sample-retail-model'; -import {AreamapChart, type AreamapChartProps} from '@sisense/sdk-ui-vue'; +import { AreamapChart, type AreamapChartProps } from '@sisense/sdk-ui-vue'; const dimProductName = DM.DimProducts.ProductName; const measureTotalRevenue = measureFactory.sum(DM.Fact_Sale_orders.OrderRevenue, 'Total Revenue'); diff --git a/docs-md/sdk/modules/sdk-ui-vue/charts/class.BarChart.md b/docs-md/sdk/modules/sdk-ui-vue/charts/class.BarChart.md index 3f3d1244..ef9c2da4 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/charts/class.BarChart.md +++ b/docs-md/sdk/modules/sdk-ui-vue/charts/class.BarChart.md @@ -23,7 +23,7 @@ Here's how you can use the BarChart component in a Vue application: import { ref } from 'vue'; import { measureFactory, filterFactory } from '@sisense/sdk-data'; import * as DM from '../assets/sample-retail-model'; -import {BarChart,type BarChartProps} from '@sisense/sdk-ui-vue'; +import { BarChart,type BarChartProps } from '@sisense/sdk-ui-vue'; const dimProductName = DM.DimProducts.ProductName; const measureTotalRevenue = measureFactory.sum(DM.Fact_Sale_orders.OrderRevenue, 'Total Revenue'); diff --git a/docs-md/sdk/modules/sdk-ui-vue/charts/class.BoxplotChart.md b/docs-md/sdk/modules/sdk-ui-vue/charts/class.BoxplotChart.md index 5008a750..85fd69aa 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/charts/class.BoxplotChart.md +++ b/docs-md/sdk/modules/sdk-ui-vue/charts/class.BoxplotChart.md @@ -23,7 +23,7 @@ Here's how you can use the BoxplotChart component in a Vue application: import { ref } from 'vue'; import { measureFactory, filterFactory } from '@sisense/sdk-data'; import * as DM from '../assets/sample-retail-model'; -import {BoxplotChart, type BoxplotChartProps} from '@sisense/sdk-ui-vue'; +import { BoxplotChart, type BoxplotChartProps } from '@sisense/sdk-ui-vue'; const dimProductName = DM.DimProducts.ProductName; const measureTotalRevenue = measureFactory.sum(DM.Fact_Sale_orders.OrderRevenue, 'Total Revenue'); diff --git a/docs-md/sdk/modules/sdk-ui-vue/charts/class.ColumnChart.md b/docs-md/sdk/modules/sdk-ui-vue/charts/class.ColumnChart.md index 988272be..cda051f1 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/charts/class.ColumnChart.md +++ b/docs-md/sdk/modules/sdk-ui-vue/charts/class.ColumnChart.md @@ -23,7 +23,7 @@ Here's how you can use the ColumnChart component in a Vue application: import { ref } from 'vue'; import { measureFactory, filterFactory } from '@sisense/sdk-data'; import * as DM from '../assets/sample-retail-model'; -import {ColumnChart, type ColumnChartProps} from '@sisense/sdk-ui-vue'; +import { ColumnChart, type ColumnChartProps } from '@sisense/sdk-ui-vue'; const dimProductName = DM.DimProducts.ProductName; const measureTotalRevenue = measureFactory.sum(DM.Fact_Sale_orders.OrderRevenue, 'Total Revenue'); diff --git a/docs-md/sdk/modules/sdk-ui-vue/charts/class.FunnelChart.md b/docs-md/sdk/modules/sdk-ui-vue/charts/class.FunnelChart.md index 979d5d29..096ca1fa 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/charts/class.FunnelChart.md +++ b/docs-md/sdk/modules/sdk-ui-vue/charts/class.FunnelChart.md @@ -21,7 +21,7 @@ Here's how you can use the FunnelChart component in a Vue application: ``` - + ## Param diff --git a/docs-md/sdk/modules/sdk-ui-vue/filter-tiles/class.DateRangeFilterTile.md b/docs-md/sdk/modules/sdk-ui-vue/filter-tiles/class.DateRangeFilterTile.md index 61aadeb1..af3565e0 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/filter-tiles/class.DateRangeFilterTile.md +++ b/docs-md/sdk/modules/sdk-ui-vue/filter-tiles/class.DateRangeFilterTile.md @@ -22,7 +22,7 @@ Vue example of configuring the date min max values and handling onChange event. ``` - + ## Param diff --git a/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/class.DashboardWidget.md b/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/class.DashboardWidget.md index 2c3bddbe..db7885de 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/class.DashboardWidget.md +++ b/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/class.DashboardWidget.md @@ -22,7 +22,7 @@ Here's how you can use the DashboardWidget component in a Vue application: ``` diff --git a/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/function.useExecuteQueryByWidgetId.md b/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/function.useExecuteQueryByWidgetId.md index 185f183c..94a4b107 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/function.useExecuteQueryByWidgetId.md +++ b/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/function.useExecuteQueryByWidgetId.md @@ -29,7 +29,7 @@ Here's how to use `useExecuteQueryByWidgetId` within a Vue component: ```vue ``` diff --git a/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/function.useGetDashboardModels.md b/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/function.useGetDashboardModels.md index 607a16a4..2f0fb1bf 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/function.useGetDashboardModels.md +++ b/docs-md/sdk/modules/sdk-ui-vue/fusion-embed/function.useGetDashboardModels.md @@ -29,7 +29,7 @@ How to use `useGetDashboardModels` within a Vue component to fetch and list Sise ```vue + ``` The composable returns an object with reactive properties that represent the state of the widget model fetch operation: diff --git a/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.AreamapChartDataOptions.md b/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.AreamapChartDataOptions.md index d2ff9da0..5f6f4142 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.AreamapChartDataOptions.md +++ b/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.AreamapChartDataOptions.md @@ -11,7 +11,7 @@ to geographic features of an Areamap chart. ### color -> **color**: [[`MeasureColumn`](../../sdk-data/interfaces/interface.MeasureColumn.md) \| [`CalculatedMeasureColumn`](../../sdk-data/interfaces/interface.CalculatedMeasureColumn.md) \| [`StyledMeasureColumn`](interface.StyledMeasureColumn.md)] +> **color**?: [[`MeasureColumn`](../../sdk-data/interfaces/interface.MeasureColumn.md) \| [`CalculatedMeasureColumn`](../../sdk-data/interfaces/interface.CalculatedMeasureColumn.md) \| [`StyledMeasureColumn`](interface.StyledMeasureColumn.md)] Measure column (or measure) encoded by the color of the countries (or states) on the map. diff --git a/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.SisenseContextProviderProps.md b/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.SisenseContextProviderProps.md index fe5f55e8..cf988c32 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.SisenseContextProviderProps.md +++ b/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.SisenseContextProviderProps.md @@ -60,6 +60,16 @@ To signify that the token is pending (e.g., being generated), set the value to ` *** +#### useFusionAuth + +> **useFusionAuth**?: `boolean` + +Flag to delegate authentication to Fusion. + +Defaults to `false`. + +*** + #### wat > **wat**?: `null` \| `string` diff --git a/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.ThemeSettings.md b/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.ThemeSettings.md index ebdc07ba..5cbd46c1 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.ThemeSettings.md +++ b/docs-md/sdk/modules/sdk-ui-vue/interfaces/interface.ThemeSettings.md @@ -24,6 +24,14 @@ Chart theme settings *** +### filter + +> **filter**?: [`FilterThemeSettings`](../../sdk-ui/type-aliases/type-alias.FilterThemeSettings.md) + +Filter theme settings + +*** + ### general > **general**?: [`GeneralThemeSettings`](../../sdk-ui/interfaces/interface.GeneralThemeSettings.md) diff --git a/docs-md/sdk/modules/sdk-ui-vue/queries/function.useExecuteQuery.md b/docs-md/sdk/modules/sdk-ui-vue/queries/function.useExecuteQuery.md index 9a37a795..b7886dac 100644 --- a/docs-md/sdk/modules/sdk-ui-vue/queries/function.useExecuteQuery.md +++ b/docs-md/sdk/modules/sdk-ui-vue/queries/function.useExecuteQuery.md @@ -27,7 +27,7 @@ How to use `useExecuteQuery` within a Vue component: ```vue * ``` - * + * * @param props - Criteria filter tile props * @returns Criteria filter tile component * @group Filter Tiles diff --git a/packages/sdk-ui-vue/src/components/filters/date-range-filter-tile.ts b/packages/sdk-ui-vue/src/components/filters/date-range-filter-tile.ts index 256fcacc..6b935f83 100644 --- a/packages/sdk-ui-vue/src/components/filters/date-range-filter-tile.ts +++ b/packages/sdk-ui-vue/src/components/filters/date-range-filter-tile.ts @@ -22,7 +22,7 @@ import { setupHelper } from '../../setup-helper'; * * * ``` - * + * * @param props - MemberFilterTile props * @returns MemberFilterTile component * @group Filter Tiles diff --git a/packages/sdk-ui-vue/src/components/widgets/chart-widget.ts b/packages/sdk-ui-vue/src/components/widgets/chart-widget.ts index 392db5e8..b233343e 100644 --- a/packages/sdk-ui-vue/src/components/widgets/chart-widget.ts +++ b/packages/sdk-ui-vue/src/components/widgets/chart-widget.ts @@ -48,7 +48,7 @@ import type DrilldownWidget from '../drilldown-widget.vue'; * import { ref } from 'vue'; * import { measureFactory, filterFactory } from '@sisense/sdk-data'; * import * as DM from '../assets/sample-retail-model'; - * import {ChartWidget} from '@sisense/sdk-ui-vue'; + * import { ChartWidget } from '@sisense/sdk-ui-vue'; * const dimProductName = DM.DimProducts.ProductName; * const measureTotalRevenue = measureFactory.sum(DM.Fact_Sale_orders.OrderRevenue, 'Total Revenue'); diff --git a/packages/sdk-ui-vue/src/components/widgets/dashboard-widget.ts b/packages/sdk-ui-vue/src/components/widgets/dashboard-widget.ts index 81cdd19f..84354a7f 100644 --- a/packages/sdk-ui-vue/src/components/widgets/dashboard-widget.ts +++ b/packages/sdk-ui-vue/src/components/widgets/dashboard-widget.ts @@ -23,7 +23,7 @@ import type { ChartWidget } from './chart-widget'; * * * ``` diff --git a/packages/sdk-ui-vue/src/composables/use-execute-query-by-widget-id.ts b/packages/sdk-ui-vue/src/composables/use-execute-query-by-widget-id.ts index 1c4f5a28..3a473c15 100644 --- a/packages/sdk-ui-vue/src/composables/use-execute-query-by-widget-id.ts +++ b/packages/sdk-ui-vue/src/composables/use-execute-query-by-widget-id.ts @@ -28,7 +28,7 @@ import type { MaybeRefOrWithRefs } from '../types'; * ```vue * * ``` diff --git a/packages/sdk-ui-vue/src/composables/use-get-dashboard-models.ts b/packages/sdk-ui-vue/src/composables/use-get-dashboard-models.ts index a3765d1c..6f9be4f1 100644 --- a/packages/sdk-ui-vue/src/composables/use-get-dashboard-models.ts +++ b/packages/sdk-ui-vue/src/composables/use-get-dashboard-models.ts @@ -33,7 +33,7 @@ import type { MaybeRefOrWithRefs } from '../types'; * ```vue * + * * ``` * * The composable returns an object with reactive properties that represent the state of the widget model fetch operation: diff --git a/packages/sdk-ui-vue/src/composables/use-tracking.ts b/packages/sdk-ui-vue/src/composables/use-tracking.ts index 36d4b704..0aa2d731 100644 --- a/packages/sdk-ui-vue/src/composables/use-tracking.ts +++ b/packages/sdk-ui-vue/src/composables/use-tracking.ts @@ -3,7 +3,6 @@ import { getSisenseContext } from '../providers/sisense-context-provider.js'; import { ref, watchEffect } from 'vue'; /** - * @internal * A Vue composable function `useTracking` designed to track the usage of hooks within Vue applications * using the Sisense SDK. It sends tracking information to the server whenever a specified hook is used, * helping in the analysis and optimization of application performance and usage patterns. This composable @@ -15,7 +14,7 @@ import { ref, watchEffect } from 'vue'; * @example * How to use `useTracking` to track the usage of a custom hook: * ```javascript - * import { useTracking } from './composables/useTracking'; + * import { useTracking } from '@sisense/sdk-ui-vue'; * * // Example hook that utilizes useTracking for monitoring its usage * export const useCustomHook = () => { @@ -37,6 +36,8 @@ import { ref, watchEffect } from 'vue'; * This internal utility composable is essential for maintaining insights into the usage of custom hooks * within applications leveraging the Sisense SDK, enabling developers and analysts to understand and optimize * hook interactions and performance. + * + * @internal */ export const useTracking = (hookName: string) => { const hasTrackedRef = ref(false); diff --git a/packages/sdk-ui-vue/src/providers/theme-provider.ts b/packages/sdk-ui-vue/src/providers/theme-provider.ts index 05b0a9ad..69ceec14 100644 --- a/packages/sdk-ui-vue/src/providers/theme-provider.ts +++ b/packages/sdk-ui-vue/src/providers/theme-provider.ts @@ -88,12 +88,14 @@ export const createThemeContextConnector = ( * ``` * * Indicator chart with custom theme settings: + * * * * * For comparison, indicator chart with default theme settings: * * + * * @see {@link ThemeSettings} and {@link IndicatorChart} * @param props - Theme provider props * @returns A Theme Provider component * @prop {Object | String} theme - Theme settings object for custom themes or a string identifier to fetch theme settings. When provided as an object, it merges with the default theme settings. When provided as a string, it attempts to fetch theme settings using the provided ID. diff --git a/packages/sdk-ui-vue/src/utils.ts b/packages/sdk-ui-vue/src/utils.ts index 618e628c..6d5edb1a 100644 --- a/packages/sdk-ui-vue/src/utils.ts +++ b/packages/sdk-ui-vue/src/utils.ts @@ -1,5 +1,5 @@ import { isRef, toRaw, toValue, type Ref } from 'vue'; -import values from 'lodash/values'; +import values from 'lodash-es/values'; import type { MaybeRef, MaybeRefOrWithRefs, MaybeWithRefs } from './types'; export function isObject(value: unknown): boolean { diff --git a/packages/sdk-ui/package.json b/packages/sdk-ui/package.json index 303cd21b..7d9bbd4f 100644 --- a/packages/sdk-ui/package.json +++ b/packages/sdk-ui/package.json @@ -11,7 +11,7 @@ "Sisense", "Compose SDK" ], - "version": "1.17.1", + "version": "1.18.0", "type": "module", "exports": { ".": { @@ -53,12 +53,12 @@ "@emotion/styled": "^11.10.5", "@mui/material": "^5.15.16", "@mui/system": "^5.15.15", - "@sisense/sdk-common": "^1.17.1", - "@sisense/sdk-data": "^1.17.1", - "@sisense/sdk-pivot-client": "^1.17.1", - "@sisense/sdk-query-client": "^1.17.1", - "@sisense/sdk-rest-client": "^1.17.1", - "@sisense/sdk-tracking": "^1.17.1", + "@sisense/sdk-common": "^1.18.0", + "@sisense/sdk-data": "^1.18.0", + "@sisense/sdk-pivot-client": "^1.18.0", + "@sisense/sdk-query-client": "^1.18.0", + "@sisense/sdk-rest-client": "^1.18.0", + "@sisense/sdk-tracking": "^1.18.0", "@sisense/sisense-charts": "5.1.1", "@tanstack/react-query": "4.36.1", "classnames": "^2.3.2", @@ -72,7 +72,7 @@ "highcharts-react-official": "^3.2.1", "immer": "^10.0.2", "leaflet": "^1.9.4", - "lodash": "^4.17.21", + "lodash-es": "^4.17.21", "merge-deep": "^3.0.3", "proj4leaflet": "^1.0.2", "react-datepicker": "^7.3.0", diff --git a/packages/sdk-ui/src/__snapshots__/boxplot-chart.test.tsx.snap b/packages/sdk-ui/src/__snapshots__/boxplot-chart.test.tsx.snap index 5d4c82ce..7f317448 100644 --- a/packages/sdk-ui/src/__snapshots__/boxplot-chart.test.tsx.snap +++ b/packages/sdk-ui/src/__snapshots__/boxplot-chart.test.tsx.snap @@ -15,6 +15,7 @@ exports[`Boxplot Chart > render boxplot with custom data options that allow to p }, "backgroundColor": "#FFFFFF", "events": { + "load": [Function], "selection": [Function], }, "polar": false, @@ -68,9 +69,6 @@ exports[`Boxplot Chart > render boxplot with custom data options that allow to p "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "boxplot": { "dataLabels": { @@ -361,6 +359,7 @@ exports[`Boxplot Chart > render boxplot with single value in data options 1`] = }, "backgroundColor": "#FFFFFF", "events": { + "load": [Function], "selection": [Function], }, "polar": false, @@ -414,9 +413,6 @@ exports[`Boxplot Chart > render boxplot with single value in data options 1`] = "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "boxplot": { "dataLabels": { diff --git a/packages/sdk-ui/src/__test-helpers__/index.tsx b/packages/sdk-ui/src/__test-helpers__/index.tsx index 9d738379..4050c4d5 100644 --- a/packages/sdk-ui/src/__test-helpers__/index.tsx +++ b/packages/sdk-ui/src/__test-helpers__/index.tsx @@ -4,7 +4,7 @@ import { PropsWithChildren, ReactElement } from 'react'; import { render, RenderResult } from '@testing-library/react'; import type { Cell, Data } from '@sisense/sdk-data'; -import isObject from 'lodash/isObject'; +import isObject from 'lodash-es/isObject'; import userEvent from '@testing-library/user-event'; import { SisenseContext, SisenseContextPayload } from '../sisense-context/sisense-context'; import { Authenticator, HttpClient } from '@sisense/sdk-rest-client'; diff --git a/packages/sdk-ui/src/ai/messages/feedback-wrapper.tsx b/packages/sdk-ui/src/ai/messages/feedback-wrapper.tsx index 385dac49..586fe894 100644 --- a/packages/sdk-ui/src/ai/messages/feedback-wrapper.tsx +++ b/packages/sdk-ui/src/ai/messages/feedback-wrapper.tsx @@ -1,4 +1,4 @@ -import debounce from 'lodash/debounce'; +import debounce from 'lodash-es/debounce'; import { ReactNode, useCallback, useMemo, useState } from 'react'; import { useChatApi } from '@/ai/api/chat-api-provider'; diff --git a/packages/sdk-ui/src/analytics-composer/translators/model-translator.ts b/packages/sdk-ui/src/analytics-composer/translators/model-translator.ts index 8bd88dda..271a5528 100644 --- a/packages/sdk-ui/src/analytics-composer/translators/model-translator.ts +++ b/packages/sdk-ui/src/analytics-composer/translators/model-translator.ts @@ -14,7 +14,7 @@ import { generateCode } from './generate-code'; import { stringifyProps } from './translate-props-to-code'; import { stringifyFilterList } from './translate-filters-to-code'; // .js is required for lodash import -import cloneDeep from 'lodash/cloneDeep.js'; +import cloneDeep from 'lodash-es/cloneDeep.js'; type Stringify = { [K in keyof T as `${K & string}String`]: string; diff --git a/packages/sdk-ui/src/analytics-composer/translators/query-translator.ts b/packages/sdk-ui/src/analytics-composer/translators/query-translator.ts index 669b807f..3b3bae5d 100644 --- a/packages/sdk-ui/src/analytics-composer/translators/query-translator.ts +++ b/packages/sdk-ui/src/analytics-composer/translators/query-translator.ts @@ -10,7 +10,7 @@ import { ChartRecommendations, deriveChartFamily } from '../../ai'; import { AggregationTypes, DimensionalBaseMeasure } from '@sisense/sdk-data'; import { capitalizeFirstLetter, sanitizeDimensionId, validateQueryModel } from './utils'; // .js is required for lodash import -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { QUERY_TEMPLATE } from './query-templates'; import { populatePlaceholders } from './generate-code'; diff --git a/packages/sdk-ui/src/api/types/dashboard-dto.ts b/packages/sdk-ui/src/api/types/dashboard-dto.ts index e1b4784d..6dacdd10 100644 --- a/packages/sdk-ui/src/api/types/dashboard-dto.ts +++ b/packages/sdk-ui/src/api/types/dashboard-dto.ts @@ -48,6 +48,9 @@ export const isCascadingFilterDto = ( return 'levels' in filter && filter.isCascading === true; }; +/** + * @internal + */ export type DashboardDto = { oid: string; title: string; diff --git a/packages/sdk-ui/src/app/client-application.ts b/packages/sdk-ui/src/app/client-application.ts index 82e62b33..c74cd2b4 100644 --- a/packages/sdk-ui/src/app/client-application.ts +++ b/packages/sdk-ui/src/app/client-application.ts @@ -193,7 +193,14 @@ export class ClientApplication { type ClientApplicationParams = Pick< SisenseContextProviderProps, - 'appConfig' | 'defaultDataSource' | 'url' | 'token' | 'wat' | 'ssoEnabled' | 'enableSilentPreAuth' + | 'appConfig' + | 'defaultDataSource' + | 'url' + | 'token' + | 'wat' + | 'ssoEnabled' + | 'enableSilentPreAuth' + | 'useFusionAuth' >; /** @internal */ @@ -205,6 +212,7 @@ export const createClientApplication = async ({ ssoEnabled, appConfig, enableSilentPreAuth, + useFusionAuth, }: ClientApplicationParams): Promise => { if (url !== undefined) { const auth = getAuthenticator({ @@ -213,6 +221,7 @@ export const createClientApplication = async ({ wat, ssoEnabled, enableSilentPreAuth, + useFusionAuth, }); if (auth) { diff --git a/packages/sdk-ui/src/boxplot-utils.test.ts b/packages/sdk-ui/src/boxplot-utils.test.ts index c480861c..9b02f350 100644 --- a/packages/sdk-ui/src/boxplot-utils.test.ts +++ b/packages/sdk-ui/src/boxplot-utils.test.ts @@ -1,6 +1,6 @@ import { createAttribute, Measure, type Data, type QueryResultData } from '@sisense/sdk-data'; import { boxWhiskerProcessResult, executeBoxplotQuery } from './boxplot-utils.js'; -import isObject from 'lodash/isObject'; +import isObject from 'lodash-es/isObject'; import { executePivotQueryMock } from './query/__mocks__/execute-query'; import { Value, type ClientApplication } from './index.js'; diff --git a/packages/sdk-ui/src/boxplot-utils.ts b/packages/sdk-ui/src/boxplot-utils.ts index 75f783e4..b55e93a7 100644 --- a/packages/sdk-ui/src/boxplot-utils.ts +++ b/packages/sdk-ui/src/boxplot-utils.ts @@ -1,5 +1,5 @@ import { Attribute, Measure, Filter, QueryResultData, DataSource } from '@sisense/sdk-data'; -import isNull from 'lodash/isNull'; +import isNull from 'lodash-es/isNull'; import { ClientApplication } from './app/client-application.js'; import { executeQuery as executeQueryFunction } from './query/execute-query.js'; import { diff --git a/packages/sdk-ui/src/chart-data-options/translate-data-options.ts b/packages/sdk-ui/src/chart-data-options/translate-data-options.ts index bd8ab2de..a9b6e91f 100644 --- a/packages/sdk-ui/src/chart-data-options/translate-data-options.ts +++ b/packages/sdk-ui/src/chart-data-options/translate-data-options.ts @@ -202,7 +202,8 @@ export function getMeasures( }, ); } else if (isAreamap(chartType)) { - values = [(dataOptions as AreamapChartDataOptionsInternal).color]; + const color = (dataOptions as AreamapChartDataOptionsInternal).color; + values = color ? [color] : []; } else if (isScattermap(chartType)) { values = ['size', 'colorBy', 'details'].flatMap((key) => { return dataOptions[key] && isValue(dataOptions[key]) ? [dataOptions[key]] : []; diff --git a/packages/sdk-ui/src/chart-data-options/types.ts b/packages/sdk-ui/src/chart-data-options/types.ts index b5c9bbc9..cf8b789f 100644 --- a/packages/sdk-ui/src/chart-data-options/types.ts +++ b/packages/sdk-ui/src/chart-data-options/types.ts @@ -400,7 +400,7 @@ export interface AreamapChartDataOptions { /** Column or attribute representing the countries (or states) on the map. */ geo: [Column | StyledColumn]; /** Measure column (or measure) encoded by the color of the countries (or states) on the map. */ - color: [MeasureColumn | CalculatedMeasureColumn | StyledMeasureColumn]; + color?: [MeasureColumn | CalculatedMeasureColumn | StyledMeasureColumn]; } /** @@ -772,5 +772,5 @@ export interface BoxplotChartDataOptionsInternal { /** @internal */ export type AreamapChartDataOptionsInternal = { geo: Category; - color: Value; + color?: Value; }; diff --git a/packages/sdk-ui/src/chart-data-options/utils.ts b/packages/sdk-ui/src/chart-data-options/utils.ts index c993d654..3e2a5ac3 100644 --- a/packages/sdk-ui/src/chart-data-options/utils.ts +++ b/packages/sdk-ui/src/chart-data-options/utils.ts @@ -7,7 +7,7 @@ import { MeasureColumn, isDatetime, } from '@sisense/sdk-data'; -import isEmpty from 'lodash/isEmpty'; +import isEmpty from 'lodash-es/isEmpty'; import { Category, Value, diff --git a/packages/sdk-ui/src/chart-data-processor/data-table-date-period.ts b/packages/sdk-ui/src/chart-data-processor/data-table-date-period.ts index 70842eff..f50beb45 100644 --- a/packages/sdk-ui/src/chart-data-processor/data-table-date-period.ts +++ b/packages/sdk-ui/src/chart-data-processor/data-table-date-period.ts @@ -27,7 +27,7 @@ import subWeeks from 'date-fns/subWeeks'; import subYears from 'date-fns/subYears'; import { enUS, de, fr, es, it, ja, ko, nl, pt, ru, tr, zhCN } from 'date-fns/locale'; -import range from 'lodash/range'; +import range from 'lodash-es/range'; export type SystemSettings = { language: string }; diff --git a/packages/sdk-ui/src/chart-data-processor/row-comparator.ts b/packages/sdk-ui/src/chart-data-processor/row-comparator.ts index a744ce25..cccb8032 100644 --- a/packages/sdk-ui/src/chart-data-processor/row-comparator.ts +++ b/packages/sdk-ui/src/chart-data-processor/row-comparator.ts @@ -2,7 +2,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { isNumber, isDatetime } from '@sisense/sdk-data'; import parseISO from 'date-fns/parseISO'; -import isObject from 'lodash/isObject'; +import isObject from 'lodash-es/isObject'; import { Row, Column, Value, ComparableData, CompareValue } from './table-processor'; export const createCompareValue = ( diff --git a/packages/sdk-ui/src/chart-data-processor/table-processor.test.ts b/packages/sdk-ui/src/chart-data-processor/table-processor.test.ts index 419c18ba..ee28c272 100644 --- a/packages/sdk-ui/src/chart-data-processor/table-processor.test.ts +++ b/packages/sdk-ui/src/chart-data-processor/table-processor.test.ts @@ -20,7 +20,7 @@ import { } from './table-processor'; import { createSortableTable, TableData } from './table-creators'; import parseISO from 'date-fns/parseISO'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; const tableData: TableData = { columns: [ diff --git a/packages/sdk-ui/src/chart-data/areamap-data.ts b/packages/sdk-ui/src/chart-data/areamap-data.ts index 2b313fc1..a2525ba1 100644 --- a/packages/sdk-ui/src/chart-data/areamap-data.ts +++ b/packages/sdk-ui/src/chart-data/areamap-data.ts @@ -19,14 +19,17 @@ export const getAreamapData = ( dataTable: DataTable, ): AreamapData => { const geoColumn = getColumnByName(dataTable, chartDataOptions.geo.name); - const colorColumn = getColumnByName(dataTable, chartDataOptions.color.name); + const colorColumn = getColumnByName( + dataTable, + chartDataOptions.color?.name ?? chartDataOptions.geo.name, + ); if (!geoColumn || !colorColumn) { throw new Error('Missing required column'); } const rawGeoData: RawGeoDataElement[] = dataTable.rows.map((row) => { const originalValue = getValue(row, colorColumn) as number; const numberFormatConfig = getCompleteNumberFormatConfig( - chartDataOptions.color.numberFormatConfig, + chartDataOptions.color?.numberFormatConfig, ); const formattedOriginalValue = applyFormatPlainText(numberFormatConfig, originalValue); return { @@ -36,13 +39,16 @@ export const getAreamapData = ( }; }); - const coloredGeoData = geoDataColoringFunction( - rawGeoData, - chartDataOptions.color.color || defaultAreamapColorOptions, - ); + let coloredGeoData; + if (chartDataOptions.color) { + coloredGeoData = geoDataColoringFunction( + rawGeoData, + chartDataOptions.color?.color || defaultAreamapColorOptions, + ); + } return { type: 'areamap', - geoData: coloredGeoData, + geoData: coloredGeoData || rawGeoData, }; }; diff --git a/packages/sdk-ui/src/chart-data/filter-and-aggregate-chart-data.ts b/packages/sdk-ui/src/chart-data/filter-and-aggregate-chart-data.ts index 85702bab..7091f2ba 100644 --- a/packages/sdk-ui/src/chart-data/filter-and-aggregate-chart-data.ts +++ b/packages/sdk-ui/src/chart-data/filter-and-aggregate-chart-data.ts @@ -1,5 +1,5 @@ /* eslint-disable max-params */ -import union from 'lodash/union'; +import union from 'lodash-es/union'; import { Category, Value } from '../chart-data-options/types'; import { DataColumnNamesMapping } from '../chart-data-options/validate-data-options'; import { rownumColumnName } from '../chart-data-processor/table-creators'; diff --git a/packages/sdk-ui/src/chart-options-processor/__snapshots__/chart-options-service.test.ts.snap b/packages/sdk-ui/src/chart-options-processor/__snapshots__/chart-options-service.test.ts.snap index 988d0582..bd810de9 100644 --- a/packages/sdk-ui/src/chart-options-processor/__snapshots__/chart-options-service.test.ts.snap +++ b/packages/sdk-ui/src/chart-options-processor/__snapshots__/chart-options-service.test.ts.snap @@ -10,6 +10,9 @@ exports[`cartesianData > timeseries treat null as zero 1`] = ` }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -44,9 +47,6 @@ exports[`cartesianData > timeseries treat null as zero 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -700,6 +700,9 @@ exports[`cartesianData > timeseries treat null as zero 2`] = ` }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -734,9 +737,6 @@ exports[`cartesianData > timeseries treat null as zero 2`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -1395,6 +1395,9 @@ exports[`cartesianData > timeseries treat null as zero when negative values 1`] }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -1429,9 +1432,6 @@ exports[`cartesianData > timeseries treat null as zero when negative values 1`] "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -2085,6 +2085,9 @@ exports[`cartesianData > timeseries treat null as zero when negative values 2`] }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -2119,9 +2122,6 @@ exports[`cartesianData > timeseries treat null as zero when negative values 2`] "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -2780,6 +2780,9 @@ exports[`cartesianData > timeseries with one data point 1`] = ` }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -2814,9 +2817,6 @@ exports[`cartesianData > timeseries with one data point 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -3103,6 +3103,9 @@ exports[`renders a categorical line chart 1`] = ` }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -3137,9 +3140,6 @@ exports[`renders a categorical line chart 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -3491,6 +3491,9 @@ exports[`renders a categorical line chart with two x axes 1`] = ` }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -3525,9 +3528,6 @@ exports[`renders a categorical line chart with two x axes 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -4100,6 +4100,9 @@ exports[`renders a time series chart with break by 1`] = ` }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -4134,9 +4137,6 @@ exports[`renders a time series chart with break by 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -4746,6 +4746,9 @@ exports[`renders a time series chart with break by with connectNulls true 1`] = }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -4780,9 +4783,6 @@ exports[`renders a time series chart with break by with connectNulls true 1`] = "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -5392,6 +5392,9 @@ exports[`renders a time series with connectNulls true on one measure 1`] = ` }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -5426,9 +5429,6 @@ exports[`renders a time series with connectNulls true on one measure 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -6008,6 +6008,9 @@ exports[`renders a time series with granularity Month 1`] = ` }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -6042,9 +6045,6 @@ exports[`renders a time series with granularity Month 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -6624,6 +6624,9 @@ exports[`renders a time series with multiple measures and no break by 1`] = ` }, "chart": { "alignTicks": false, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -6658,9 +6661,6 @@ exports[`renders a time series with multiple measures and no break by 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", diff --git a/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/forecast-tooltip.stories.tsx b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/forecast-tooltip.stories.tsx new file mode 100644 index 00000000..9a145a26 --- /dev/null +++ b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/forecast-tooltip.stories.tsx @@ -0,0 +1,19 @@ +import { templateForComponent } from '@/__stories__/template'; +import { default as ForecastToolipComponent } from './forecast-tooltip.js'; + +const template = templateForComponent(ForecastToolipComponent); + +export default { + title: 'Charts/Tooltips/Forecast Tooltip', + component: ForecastToolipComponent, + argTypes: {}, +}; + +export const ForecastToolip = template({ + confidenceValue: '80%', + lowerValue: '1.01M', + forecastValue: '2.01M', + upperValue: '3.01M', + title: 'Total Cost', + x1Value: '2.01k', +}); diff --git a/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/forecast-tooltip.tsx b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/forecast-tooltip.tsx new file mode 100644 index 00000000..9710be5e --- /dev/null +++ b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/forecast-tooltip.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import ReactDOMServer from 'react-dom/server'; +import { useTranslation } from 'react-i18next'; +import { TFunction } from '@sisense/sdk-common'; +import AdvancedAnalyticsTooltipTitle from './tooltip-title.js'; +import AdvancedAnalyticsTooltipRow from './tooltip-row.js'; +import AdvancedAnalyticsTooltipFooter from './tooltip-footer.js'; + +type ForecastToolipProps = { + x1Value?: string; + x2Value?: string; + title: string; + forecastValue: string; + upperValue: string; + lowerValue: string; + confidenceValue: string; + translate?: TFunction; +}; + +export default function ForecastToolipComponent(props: ForecastToolipProps) { + const { t } = useTranslation(); + const translate = props.translate || t; + const { confidenceValue, lowerValue, forecastValue, upperValue, title, x1Value, x2Value } = props; + + return ( +
+ +
+ + + + +
+ + +
+ ); +} + +export const renderForecastTooltipString = (props: ForecastToolipProps) => + ReactDOMServer.renderToString(); diff --git a/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/tooltip-footer.tsx b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/tooltip-footer.tsx new file mode 100644 index 00000000..b0166b46 --- /dev/null +++ b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/tooltip-footer.tsx @@ -0,0 +1,41 @@ +import React from 'react'; + +type AdvancedAnalyticsTooltipFooterProps = { + x1Value?: string; + x2Value?: string; +}; +export default function AdvancedAnalyticsTooltipFooter(props: AdvancedAnalyticsTooltipFooterProps) { + const { x1Value, x2Value } = props; + return ( + <> +
+ {x2Value || x1Value ?
: ''} +
+ {x2Value ? x2Value : ''} + {x2Value && x1Value ? ( + + + + ) : ( + '' + )} + {x1Value ? x1Value : ''} + + ); +} diff --git a/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/tooltip-row.tsx b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/tooltip-row.tsx new file mode 100644 index 00000000..9415ded8 --- /dev/null +++ b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/tooltip-row.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +type AdvancedAnalyticsTooltipRowProps = { + name: string; + value: string[]; +}; + +export default function AdvancedAnalyticsTooltipRow(props: AdvancedAnalyticsTooltipRowProps) { + const { name, value } = props; + return ( +
+
+
+ {name} +
+
+ {value.map((v, i) => ( +
{v}
+ ))} +
+
+
+ ); +} diff --git a/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/tooltip-title.tsx b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/tooltip-title.tsx new file mode 100644 index 00000000..8c4d8ccf --- /dev/null +++ b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/tooltip-title.tsx @@ -0,0 +1,37 @@ +import React from 'react'; +type AdvancedAnalyticsTooltipTitleProps = { + prefix: string; + title: string; +}; +export default function AdvancedAnalyticsTooltipTitle(props: AdvancedAnalyticsTooltipTitleProps) { + const { prefix, title } = props; + return ( +
+
+ {prefix} +
+
+ {title} +
+
+ ); +} diff --git a/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/trend-tooltip.stories.tsx b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/trend-tooltip.stories.tsx new file mode 100644 index 00000000..c1237e92 --- /dev/null +++ b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/trend-tooltip.stories.tsx @@ -0,0 +1,25 @@ +import { templateForComponent } from '@/__stories__/template'; +import { default as TrendToolipComponent } from './trend-tooltip'; + +const template = templateForComponent(TrendToolipComponent); + +export default { + title: 'Charts/Tooltips/Trend Tooltip', + component: TrendToolipComponent, + argTypes: {}, +}; + +export const TrendToolip = template({ + x1Value: '2.01k', + // x2Value: '10', + modelType: 'logarithmic', + title: 'Total Cost', + // trendData: ['Min 190.0K', 'Max 4.84M', 'Median 2.28M', 'Average 2.15M'], + trendData: { + min: '190.0K', + max: '4.84M', + median: '2.28M', + average: '2.15M', + }, + localValue: '2.01M', +}); diff --git a/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/trend-tooltip.tsx b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/trend-tooltip.tsx new file mode 100644 index 00000000..a71abfa4 --- /dev/null +++ b/packages/sdk-ui/src/chart-options-processor/advanced-analytics/tooltips/trend-tooltip.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import ReactDOMServer from 'react-dom/server'; +import { useTranslation } from 'react-i18next'; +import { TFunction } from '@sisense/sdk-common'; +import AdvancedAnalyticsTooltipTitle from './tooltip-title'; +import AdvancedAnalyticsTooltipRow from './tooltip-row'; +import AdvancedAnalyticsTooltipFooter from './tooltip-footer'; + +const TrendTypesFromExpression = { + smooth: 'Advanced Smoothing', + linear: 'Linear Trend', + local: 'Local Estimates', + logarithmic: 'Logarithmic Trend', +}; + +type TrendToolipProps = { + x1Value?: string; + x2Value?: string; + modelType: keyof typeof TrendTypesFromExpression | string; + title: string; + trendData: { + min: string; + max: string; + median: string; + average: string; + }; + localValue: string; + translate?: TFunction; +}; + +export default function TrendToolip(props: TrendToolipProps) { + const { t } = useTranslation(); + const translate = props.translate || t; + const { localValue, trendData, modelType, title, x1Value, x2Value } = props; + + const trendDataFormatted = [ + `${translate('advanced.tooltip.trendData.min')} ${trendData.min}`, + `${translate('advanced.tooltip.trendData.max')} ${trendData.max}`, + `${translate('advanced.tooltip.trendData.median')} ${trendData.median}`, + `${translate('advanced.tooltip.trendData.average')} ${trendData.average}`, + ]; + return ( +
+ +
+ + + +
+ +
+ ); +} + +export const renderTrendTooltipString = (props: TrendToolipProps) => + ReactDOMServer.renderToString(); diff --git a/packages/sdk-ui/src/chart-options-processor/advanced-chart-options.ts b/packages/sdk-ui/src/chart-options-processor/advanced-chart-options.ts index de3f0b92..3e075698 100644 --- a/packages/sdk-ui/src/chart-options-processor/advanced-chart-options.ts +++ b/packages/sdk-ui/src/chart-options-processor/advanced-chart-options.ts @@ -1,4 +1,3 @@ -import { TFunction } from '@sisense/sdk-common'; import { SeriesType } from './chart-options-service'; import { AxisPlotBand, AxisSettings } from './translations/axis-section'; @@ -82,21 +81,63 @@ export const formatForecastPlotBands = ( }; export const formatTrendSeries = ( - s: SeriesType, + series: SeriesType, seriesHash: { [x: string]: SeriesType; }, - translate: TFunction, ) => { - const measureName = s.name.substring(TREND_PREFIX.length + 1); + const measureName = series.name.substring(TREND_PREFIX.length + 1); const measure = seriesHash[measureName]; - s.showInLegend = false; - s.dashStyle = 'ShortDot'; - s.color = measure.color; - measure.name = `${measure.name} (+${translate('advanced.tooltip.trend')})`; + series.showInLegend = false; + series.dashStyle = 'ShortDot'; + series.color = measure.color; + + let highestValue = 0; + let lowestValue = Number.MAX_VALUE; + + const trendDataValues: number[] = measure.data + .filter((dataPoint) => dataPoint.y) + .map((dataPoint) => { + highestValue = Math.max(highestValue, dataPoint.y || 0); + lowestValue = Math.min(lowestValue, dataPoint.y || 0); + return dataPoint.y!; + }); + + // if (trendDataValues.length === 0) { + // console.warn('No valid data points available to calculate trend data.'); + // return; + // } + + // Calculate the min, max, average, and median + const min = lowestValue; // lowest value of the series + const max = highestValue; // highest value of the series + const average = trendDataValues.reduce((acc, val) => acc + val, 0) / trendDataValues.length; // average value of the series + + const sortedData = [...trendDataValues].sort((a, b) => a - b); + const middle = Math.floor(sortedData.length / 2); + const median = + sortedData.length % 2 !== 0 + ? sortedData[middle] + : (sortedData[middle - 1] + sortedData[middle]) / 2; + + const trendData = { + min, + max, + median, + average, + }; + + // Apply trend data to each data point + series.data.forEach((dataPoint) => { + dataPoint.trend = trendData; + }); + + // this line is causing issues in tooltip as tooltip finds dataOption through name and name is changed here + // this line mainly makes the legend name to include the addition trend information + // measure.name = `${measure.name} (+${translate('advanced.tooltip.trend')})`; }; -export const formatAdvancedAnalyticsSeries = (series: SeriesType[], translate: TFunction) => { +export const formatAdvancedAnalyticsSeries = (series: SeriesType[]) => { // post process advanced analytics const seriesDataLookup: { [x: string]: SeriesType; @@ -107,7 +148,7 @@ export const formatAdvancedAnalyticsSeries = (series: SeriesType[], translate: T series.forEach((s) => { if (isTrendSeries(s.name)) { - formatTrendSeries(s, seriesDataLookup, translate); + formatTrendSeries(s, seriesDataLookup); } }); }; diff --git a/packages/sdk-ui/src/chart-options-processor/boxplot-chart-options.ts b/packages/sdk-ui/src/chart-options-processor/boxplot-chart-options.ts index fc5d94f2..9f479dfd 100644 --- a/packages/sdk-ui/src/chart-options-processor/boxplot-chart-options.ts +++ b/packages/sdk-ui/src/chart-options-processor/boxplot-chart-options.ts @@ -3,7 +3,7 @@ import { BoxplotChartData } from '../chart-data/types'; import { determineHighchartsChartType } from './translations/translations-to-highcharts'; import { BoxplotChartDataOptionsInternal } from '../chart-data-options/types'; import { HighchartsOptionsInternal } from './chart-options-service'; -import { HighchartsSelectEvent, OptionsWithAlerts } from '../types'; +import { CompleteThemeSettings, HighchartsSelectEvent, OptionsWithAlerts } from '../types'; import { buildBoxplotSeries } from './translations/boxplot/boxplot-series'; import { getBoxplotXAxisSettings, @@ -12,9 +12,10 @@ import { import { getBoxplotPlotOptions } from './translations/boxplot/boxplot-plot-options'; import { BoxplotChartDesignOptions } from './translations/design-options'; import { getLegendSettings } from './translations/legend-section'; -import { getNavigator } from './translations/navigator'; +import { getNavigator, setInitialScrollerPosition } from './translations/navigator'; import { getBoxplotTooltipSettings } from './translations/boxplot/boxplot-tooltip'; import { ChartDesignOptions } from './translations/types'; +import { NavigatorOptions } from '@sisense/sisense-charts'; /** * Convert intermediate chart data, data options, and design options @@ -25,11 +26,13 @@ export const getBoxplotChartOptions = ( chartDesignOptions: ChartDesignOptions, dataOptions: BoxplotChartDataOptionsInternal, translate: TFunction, + themeSettings?: CompleteThemeSettings, ): OptionsWithAlerts => { const sisenseChartType = determineHighchartsChartType('boxplot', chartDesignOptions); const { series, alerts } = buildBoxplotSeries( chartData, chartDesignOptions as BoxplotChartDesignOptions, + themeSettings?.palette.variantColors, ); const categories = chartData.xValues.map((xAxisValue) => xAxisValue.key); @@ -43,6 +46,23 @@ export const getBoxplotChartOptions = ( type: 'x', }, events: { + load: function () { + const chart = this as Highcharts.Chart; + + if (chartDesignOptions.autoZoom && chartDesignOptions.autoZoom.scrollerLocation) { + const { min, max } = chartDesignOptions.autoZoom.scrollerLocation; + setInitialScrollerPosition(chart, min, max); + } + const chartWidth = chart.chartWidth; + + const navigator = getNavigator( + sisenseChartType, + chartDesignOptions.autoZoom.enabled, + chartData.xValues.length, + chartWidth, + ) as NavigatorOptions; + chart.update({ navigator }, true); + }, // disables default zooming selection: (nativeEvent: HighchartsSelectEvent) => { nativeEvent.preventDefault(); @@ -56,11 +76,6 @@ export const getBoxplotChartOptions = ( yAxis: getBoxplotYAxisSettings(chartDesignOptions.yAxis, chartData, dataOptions.whiskerMax), series, plotOptions: getBoxplotPlotOptions(chartDesignOptions.valueLabel), - navigator: getNavigator( - sisenseChartType, - chartDesignOptions.autoZoom, - chartData.xValues.length, - ), tooltip: getBoxplotTooltipSettings(dataOptions, translate), }; return { options: boxplotOptions, alerts }; diff --git a/packages/sdk-ui/src/chart-options-processor/cartesian-chart-options.ts b/packages/sdk-ui/src/chart-options-processor/cartesian-chart-options.ts index 56d2a467..2991c9b6 100644 --- a/packages/sdk-ui/src/chart-options-processor/cartesian-chart-options.ts +++ b/packages/sdk-ui/src/chart-options-processor/cartesian-chart-options.ts @@ -40,12 +40,13 @@ import { ChartType, CompleteThemeSettings } from '../types'; import { CartesianChartDataOptionsInternal } from '../chart-data-options/types'; import { applyNumberFormatToPlotBands, getCategoriesIndexMapAndPlotBands } from './plot-bands'; import { HighchartsOptionsInternal } from './chart-options-service'; -import { getNavigator } from './translations/navigator'; +import { getNavigator, setInitialScrollerPosition } from './translations/navigator'; import { isDatetime } from '@sisense/sdk-data'; import { categoriesSliceWarning, seriesSliceWarning } from '../utils/data-limit-warning'; import { OptionsWithAlerts } from './../types'; import { getPaletteColor } from '../chart-data-options/coloring/utils'; import { TFunction } from '@sisense/sdk-common'; +import { NavigatorOptions } from '@sisense/sisense-charts'; /** * Convert intermediate chart data, data options, and design options @@ -178,6 +179,7 @@ export const getCartesianChartOptions = ( y2AxisMinMax, showTotal, dataOptions, + stacking, ); // if vertical x2 axis increase right spacing @@ -200,6 +202,28 @@ export const getCartesianChartOptions = ( spacing: [20, rightSpacing, 20, 20], alignTicks: false, polar: isPolarChart, + events: { + load: function () { + if (dataOptions.x.length === 2) return; + const chart = this as Highcharts.Chart; + + if (chartDesignOptions.autoZoom && chartDesignOptions.autoZoom.scrollerLocation) { + const { min, max } = chartDesignOptions.autoZoom.scrollerLocation; + setInitialScrollerPosition(chart, min, max); + } + const chartWidth = chart.chartWidth; + const chartHeight = chart.chartHeight; + + const navigator = getNavigator( + sisenseChartType, + chartDesignOptions.autoZoom.enabled, + chartData.xValues.length, + chartType === 'bar' ? chartHeight : chartWidth, + chartType === 'bar', + ) as NavigatorOptions; + chart.update({ navigator }, true); + }, + }, }, xAxis: xAxisSettings, yAxis: yAxisSettings, @@ -271,11 +295,6 @@ export const getCartesianChartOptions = ( connectNulls: false, }, }, - navigator: getNavigator( - sisenseChartType, - chartDesignOptions.autoZoom, - chartData.xValues.length, - ), tooltip: getTooltipSettings(undefined, dataOptions, translate), }, ); diff --git a/packages/sdk-ui/src/chart-options-processor/chart-options-service.test.ts b/packages/sdk-ui/src/chart-options-processor/chart-options-service.test.ts index 3c85c869..854a7801 100644 --- a/packages/sdk-ui/src/chart-options-processor/chart-options-service.test.ts +++ b/packages/sdk-ui/src/chart-options-processor/chart-options-service.test.ts @@ -268,7 +268,7 @@ it('renders a categorical line chart with two x axes', () => { expect(chartOptions).toMatchSnapshot(); }); -it('chart navigator is on if x axis count is greater than 70 and autoZoom true', () => { +it.skip('chart navigator is on if x axis count is greater than 70 and autoZoom true', () => { const chartData: CartesianChartData = { type: 'cartesian', xAxisCount: 1, @@ -290,7 +290,9 @@ it('chart navigator is on if x axis count is greater than 70 and autoZoom true', 'line', { ...baseChartDesignOptions, - autoZoom: true, + autoZoom: { + enabled: true, + }, }, TestChartDataOptions, translateMock, @@ -298,7 +300,7 @@ it('chart navigator is on if x axis count is greater than 70 and autoZoom true', expect(chartOptions?.navigator?.enabled).toBe(true); }); -it('chart navigator is off if x axis count is greater than 70 and autoZoom false', () => { +it.skip('chart navigator is off if x axis count is greater than 70 and autoZoom false', () => { const chartData: CartesianChartData = { type: 'cartesian', xAxisCount: 1, @@ -320,7 +322,9 @@ it('chart navigator is off if x axis count is greater than 70 and autoZoom false 'line', { ...baseChartDesignOptions, - autoZoom: false, + autoZoom: { + enabled: true, + }, }, TestChartDataOptions, translateMock, @@ -328,7 +332,7 @@ it('chart navigator is off if x axis count is greater than 70 and autoZoom false expect(chartOptions?.navigator?.enabled).toBe(false); }); -it('chart navigator is off if x axis count is less than 50 and autoZoom true', () => { +it.skip('chart navigator is off if x axis count is less than 50 and autoZoom true', () => { const chartData: CartesianChartData = { type: 'cartesian', xAxisCount: 1, @@ -350,7 +354,9 @@ it('chart navigator is off if x axis count is less than 50 and autoZoom true', ( 'line', { ...baseChartDesignOptions, - autoZoom: true, + autoZoom: { + enabled: true, + }, }, TestChartDataOptions, translateMock, @@ -380,7 +386,9 @@ it('for cartesian data, limit series to 50 and categories to 100', () => { 'line', { ...baseChartDesignOptions, - autoZoom: true, + autoZoom: { + enabled: true, + }, dataLimits: { seriesCapacity: 50, categoriesCapacity: 100 }, }, TestChartDataOptions, diff --git a/packages/sdk-ui/src/chart-options-processor/chart-options-service.ts b/packages/sdk-ui/src/chart-options-processor/chart-options-service.ts index b87902a9..9ac21560 100644 --- a/packages/sdk-ui/src/chart-options-processor/chart-options-service.ts +++ b/packages/sdk-ui/src/chart-options-processor/chart-options-service.ts @@ -1,4 +1,4 @@ -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import type { Options, DrilldownOptions, @@ -99,7 +99,7 @@ export const highchartsOptionsService = ( themeSettings, dateFormatter, ); - formatAdvancedAnalyticsSeries(optionsWithAlerts.options.series, translate); + formatAdvancedAnalyticsSeries(optionsWithAlerts.options.series); return optionsWithAlerts; } case 'categorical': { @@ -126,6 +126,7 @@ export const highchartsOptionsService = ( chartDesignOptions, dataOptions as BoxplotChartDataOptionsInternal, translate, + themeSettings, ); } default: diff --git a/packages/sdk-ui/src/chart-options-processor/range-chart-options.ts b/packages/sdk-ui/src/chart-options-processor/range-chart-options.ts index 25a8cf93..ef1007d8 100644 --- a/packages/sdk-ui/src/chart-options-processor/range-chart-options.ts +++ b/packages/sdk-ui/src/chart-options-processor/range-chart-options.ts @@ -6,12 +6,10 @@ import { ChartType, CompleteThemeSettings } from '../types'; import { CartesianChartDataOptionsInternal, RangeChartDataOptionsInternal, - StyledMeasureColumn, Value, } from '../chart-data-options/types'; import { TFunction } from '@sisense/sdk-common'; import { getCartesianChartOptions } from './cartesian-chart-options'; -import { AxisPlotBand } from './translations/axis-section'; import { SeriesType } from './chart-options-service'; import { formatForecastAdjustRangeStart, diff --git a/packages/sdk-ui/src/chart-options-processor/scatter-chart-options.test.ts b/packages/sdk-ui/src/chart-options-processor/scatter-chart-options.test.ts index af1e5eb0..96bff8b0 100644 --- a/packages/sdk-ui/src/chart-options-processor/scatter-chart-options.test.ts +++ b/packages/sdk-ui/src/chart-options-processor/scatter-chart-options.test.ts @@ -56,7 +56,9 @@ describe('getScatterChartOptions', () => { max: null, tickInterval: null, }, - autoZoom: true, + autoZoom: { + enabled: true, + }, dataLimits: { seriesCapacity: SERIES_CAPACITY, categoriesCapacity: customCategoriesCapacity, diff --git a/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/__snapshots__/prepare-design-options.test.ts.snap b/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/__snapshots__/prepare-design-options.test.ts.snap index dd6ca9cc..5ef6d4fc 100644 --- a/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/__snapshots__/prepare-design-options.test.ts.snap +++ b/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/__snapshots__/prepare-design-options.test.ts.snap @@ -2,7 +2,9 @@ exports[`prepareChartDesignOptions > should return design options for areamap chart 1`] = ` { - "autoZoom": true, + "autoZoom": { + "enabled": true, + }, "dataLimits": { "categoriesCapacity": 100000, "seriesCapacity": 50, @@ -81,7 +83,10 @@ exports[`prepareChartDesignOptions > should return design options for areamap ch exports[`prepareChartDesignOptions > should return design options for combo "line + area" chart 1`] = ` { - "autoZoom": true, + "autoZoom": { + "enabled": true, + "scrollerLocation": undefined, + }, "dataLimits": { "categoriesCapacity": 100000, "seriesCapacity": 50, @@ -172,7 +177,9 @@ exports[`prepareChartDesignOptions > should return design options for combo "lin exports[`prepareChartDesignOptions > should return design options for funnel chart 1`] = ` { - "autoZoom": true, + "autoZoom": { + "enabled": true, + }, "dataLimits": { "categoriesCapacity": 100000, "seriesCapacity": 3, @@ -250,7 +257,9 @@ exports[`prepareChartDesignOptions > should return design options for funnel cha exports[`prepareChartDesignOptions > should return design options for scattermap chart 1`] = ` { - "autoZoom": true, + "autoZoom": { + "enabled": true, + }, "dataLimits": { "categoriesCapacity": 100000, "seriesCapacity": 50, diff --git a/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/prepare-design-options.ts b/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/prepare-design-options.ts index 81126ec3..95b0c34c 100644 --- a/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/prepare-design-options.ts +++ b/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/prepare-design-options.ts @@ -6,7 +6,7 @@ import { } from '@/chart-data-options/types'; import { ChartStyleOptions, ChartType } from '@/types'; import { WithRequiredProp } from '@/utils/utility-types'; -import pick from 'lodash/pick'; +import pick from 'lodash-es/pick'; import merge from 'ts-deepmerge'; import { getDefaultStyleOptions } from '../chart-options-service'; import { DesignOptions, isCartesian, SeriesDesignOptions } from '../translations/types'; diff --git a/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/translate-to-highcharts-options.ts b/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/translate-to-highcharts-options.ts index adfb5c17..123073a7 100644 --- a/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/translate-to-highcharts-options.ts +++ b/packages/sdk-ui/src/chart-options-processor/style-to-design-options-translator/translate-to-highcharts-options.ts @@ -88,8 +88,11 @@ const getAxisLabel = (axis: AxisLabel | undefined, defaultAxis: Axis): Axis => { }; }; -const getNavigator = (navigator: Navigator | undefined): boolean => { - return navigator?.enabled || false; +const getNavigator = (navigator: Navigator | undefined): Navigator => { + return { + enabled: navigator?.enabled || false, + scrollerLocation: navigator?.scrollerLocation, + }; }; const getY2AxisLabel = (axisLabel: AxisLabel): Axis => { diff --git a/packages/sdk-ui/src/chart-options-processor/translations/axis-section.ts b/packages/sdk-ui/src/chart-options-processor/translations/axis-section.ts index bea4a30e..9bd30a64 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/axis-section.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/axis-section.ts @@ -11,7 +11,7 @@ import { lineColorDefault, } from '../defaults/cartesian'; import merge from 'deepmerge'; -import { Style } from '../chart-options-service'; +import { Stacking, Style } from '../chart-options-service'; import { applyFormatPlainText, getCompleteNumberFormatConfig } from './number-format-config'; import { DateLevels, isNumber } from '@sisense/sdk-data'; import { @@ -19,7 +19,7 @@ import { CartesianChartDataOptionsInternal, Category, } from '../../chart-data-options/types'; -import { ChartType } from '../../types'; +import { ChartType, CompleteNumberFormatConfig } from '../../types'; import { isPolar } from './types'; import { CategoricalXValues } from '../../chart-data/types'; import { AxisClipped } from './translations-to-highcharts'; @@ -407,6 +407,7 @@ export const getYAxisSettings = ( axis2MinMax: AxisMinMax | undefined, showTotal: boolean, chartDataOptions: ChartDataOptionsInternal, + stacking: Stacking | undefined, ): [AxisSettings[], AxisClipped[]] => { const cartesianChartDataOptions: CartesianChartDataOptionsInternal = chartDataOptions as CartesianChartDataOptionsInternal; @@ -420,6 +421,13 @@ export const getYAxisSettings = ( { minClipped: !!(axis.enabled && axis.min), maxClipped: !!(axis.enabled && axis.max) }, ]; + function getLabelsFormatter(numberFormatConfig: CompleteNumberFormatConfig, stacking?: Stacking) { + return function (this: { value: number }) { + const formattedValue = applyFormatPlainText(numberFormatConfig, this.value); + return stacking === 'percent' ? `${formattedValue}%` : formattedValue; + }; + } + const array: AxisSettings[] = [ merge(yAxisDefaults, { type: axis.type, @@ -433,9 +441,7 @@ export const getYAxisSettings = ( labels: { enabled: axis.enabled && axis.labels, style: fontStyleDefault, - formatter: function () { - return applyFormatPlainText(y1NumberFormatConfig, (this as any).value); - }, + formatter: getLabelsFormatter(y1NumberFormatConfig, stacking), }, startOnTick: axis.enabled && axis.min ? false : true, ...(axis.min && { minPadding: 0 }), @@ -470,9 +476,7 @@ export const getYAxisSettings = ( labels: { enabled: axis2.enabled && axis2.labels, style: fontStyleDefault, - formatter: function () { - return applyFormatPlainText(y2NumberFormatConfig, (this as any).value); - }, + formatter: getLabelsFormatter(y2NumberFormatConfig, stacking), }, tickInterval: axis2.enabled ? axis2.tickInterval : null, stackLabels: { enabled: showTotal }, diff --git a/packages/sdk-ui/src/chart-options-processor/translations/base-design-options.ts b/packages/sdk-ui/src/chart-options-processor/translations/base-design-options.ts index 3d0d328b..2ada638e 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/base-design-options.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/base-design-options.ts @@ -42,7 +42,9 @@ export const BaseDesignOptions: Merge = { max: null, tickInterval: null, }, - autoZoom: true, + autoZoom: { + enabled: true, + }, pieType: DefaultPieType, pieLabels: DefaultPieLabels, funnelType: DefaultFunnelType, diff --git a/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-axis.ts b/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-axis.ts index e72ee5b9..30e505cc 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-axis.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-axis.ts @@ -1,4 +1,4 @@ -import isNumber from 'lodash/isNumber'; +import isNumber from 'lodash-es/isNumber'; import { isNumber as isNumberType } from '@sisense/sdk-data'; import { BoxplotChartData } from '../../../chart-data/types'; import { Axis, AxisLabelsFormatterContextObject, AxisSettings } from '../axis-section'; diff --git a/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-series.ts b/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-series.ts index 394ce720..80e94f36 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-series.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-series.ts @@ -1,26 +1,38 @@ import { SeriesType } from '../../chart-options-service.js'; import { BoxplotChartData } from '../../../chart-data/types.js'; -import { SeriesWithAlerts } from '../../../types.js'; +import { Color, SeriesWithAlerts } from '../../../types.js'; import { BoxplotChartDesignOptions } from '../design-options.js'; +import { applyOpacity, scaleBrightness } from '@/utils/color/color-interpolation.js'; +import { getPaletteColor } from '@/chart-data-options/coloring/utils.js'; // eslint-disable-next-line max-lines-per-function export const buildBoxplotSeries = ( data: BoxplotChartData, chartDesignOptions: BoxplotChartDesignOptions, + paletteColors?: Color[], ): SeriesWithAlerts => { // todo: add outliers limit warning into alerts const alerts: SeriesWithAlerts['alerts'] = []; const [boxSerie, outliersSerie] = data.series; const { boxplotType } = chartDesignOptions; + const colorChangeCoefficient = 0.15; + + const baseColor = getPaletteColor(paletteColors, 0); + + const upperQuartileColor = baseColor; + const lowerQuartileColor = scaleBrightness(baseColor, -1 * colorChangeCoefficient); + const lineColor = scaleBrightness(baseColor, -2 * colorChangeCoefficient); + const blurredLineColor = applyOpacity(lineColor, 2 * colorChangeCoefficient); + const series: SeriesType[] = [ { ...boxSerie, data: boxSerie.data.map((item) => ({ ...item, - color: '#0090a1', - fillColor: boxplotType === 'hollow' ? 'transparent' : '#00cee6', - innerBoxColor: boxplotType === 'hollow' ? 'transparent' : '#00afc4', + color: lineColor, + fillColor: boxplotType === 'hollow' ? 'transparent' : upperQuartileColor, + innerBoxColor: boxplotType === 'hollow' ? 'transparent' : lowerQuartileColor, selected: item.blur ?? false, })), medianWidth: 1, @@ -33,7 +45,7 @@ export const buildBoxplotSeries = ( showInLegend: true, legendIndex: 0, yAxis: 0, - color: '#0090a1', + color: lineColor, }, ]; @@ -43,7 +55,7 @@ export const buildBoxplotSeries = ( data: outliersSerie.data.map((item) => ({ ...item, marker: { - lineColor: item.blur ? 'rgba(0, 144, 161, 0.3)' : '#0090a1', + lineColor: item.blur ? blurredLineColor : lineColor, }, })), type: 'scatter', @@ -53,9 +65,9 @@ export const buildBoxplotSeries = ( enabled: true, fillColor: 'transparent', lineWidth: 1, - lineColor: '#0090a1', + lineColor: lineColor, }, - color: '#0090a1', + color: lineColor, }); } diff --git a/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-tooltip.ts b/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-tooltip.ts index 5b62bb75..9e9278f6 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-tooltip.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/boxplot/boxplot-tooltip.ts @@ -8,7 +8,7 @@ import { formatTooltipXValue, } from '../tooltip-utils'; import { spanSegment, tooltipSeparator, tooltipWrapper } from '../scatter-tooltip'; -import isUndefined from 'lodash/isUndefined'; +import isUndefined from 'lodash-es/isUndefined'; import './boxplot-tooltip.scss'; // eslint-disable-next-line max-lines-per-function diff --git a/packages/sdk-ui/src/chart-options-processor/translations/design-options.ts b/packages/sdk-ui/src/chart-options-processor/translations/design-options.ts index a47cecae..3972c978 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/design-options.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/design-options.ts @@ -30,7 +30,13 @@ export type BaseDesignOptionsType = { yAxis: Axis; x2Axis?: Axis; y2Axis?: Axis; - autoZoom: boolean; + autoZoom: { + enabled: boolean; + scrollerLocation?: { + min: number; + max: number; + }; + }; dataLimits: DataLimits; }; diff --git a/packages/sdk-ui/src/chart-options-processor/translations/navigator.ts b/packages/sdk-ui/src/chart-options-processor/translations/navigator.ts index 91b0be1e..6d14e599 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/navigator.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/navigator.ts @@ -26,9 +26,19 @@ export const getNavigator = ( type: HighchartsType, enabled: boolean, xAxisCount: number, + dimension: number, //chart width or height depending on isVertical + isVertical = false, ): Navigator | { enabled: boolean } => { - const navigatorThreshold = 50; - if (!enabled || xAxisCount < navigatorThreshold) { + const verticalMinDimensionToDisplayNavigator = 200; + const horizontalMinDimensionToDisplayNavigator = 400; + const minDimensionToDisplayNavigator = isVertical + ? verticalMinDimensionToDisplayNavigator + : horizontalMinDimensionToDisplayNavigator; + const isBelowThreshold = dimension < minDimensionToDisplayNavigator; + const pxPerXAxis = 20; + const threshold = xAxisCount * pxPerXAxis; + const isAboveThreshold = dimension > threshold; + if (!enabled || isBelowThreshold || isAboveThreshold) { return { enabled: false }; } @@ -65,3 +75,13 @@ export const getNavigator = ( outlineWidth: 1, }; }; + +export function setInitialScrollerPosition( + chart: Highcharts.Chart, + scrollerStart: number, + scrollerEnd: number, +) { + const xAxis = chart.xAxis[0]; + // Directly set the extremes using the provided absolute values + xAxis.setExtremes(scrollerStart, scrollerEnd, false); +} diff --git a/packages/sdk-ui/src/chart-options-processor/translations/number-format-config.ts b/packages/sdk-ui/src/chart-options-processor/translations/number-format-config.ts index 3119b2d5..3c112a35 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/number-format-config.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/number-format-config.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-use-before-define */ import { numericFormatter } from 'react-number-format'; -import round from 'lodash/round'; +import round from 'lodash-es/round'; import { CompleteNumberFormatConfig, NumberFormatConfig } from '@/types'; const oneKilo = 1000; diff --git a/packages/sdk-ui/src/chart-options-processor/translations/tooltip-utils.ts b/packages/sdk-ui/src/chart-options-processor/translations/tooltip-utils.ts index 91bec9c8..89f8104f 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/tooltip-utils.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/tooltip-utils.ts @@ -86,6 +86,12 @@ export type InternalSeries = { }; upperPointName?: string; lowerPointName?: string; + trend?: { + min: number; + max: number; + median: number; + average: number; + }; }; percentage?: number; }; diff --git a/packages/sdk-ui/src/chart-options-processor/translations/tooltip.ts b/packages/sdk-ui/src/chart-options-processor/translations/tooltip.ts index 1a5d33c1..ac7b3466 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/tooltip.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/tooltip.ts @@ -13,6 +13,9 @@ import { import { spanSegment, tooltipSeparator, tooltipWrapper } from './scatter-tooltip'; import { TFunction } from '@sisense/sdk-common'; import { isForecastSeries, isTrendSeries } from '../advanced-chart-options'; +import { renderTrendTooltipString } from '../advanced-analytics/tooltips/trend-tooltip'; +import { renderForecastTooltipString } from '../advanced-analytics/tooltips/forecast-tooltip'; +import { DimensionalCalculatedMeasure } from '@sisense/sdk-data'; export const cartesianDataFormatter = function ( that: InternalSeries, @@ -58,22 +61,72 @@ export const cartesianDataFormatter = function ( const isTrend = isTrendSeries(that.point.name || that.series.name); const yName = translate && isForecast - ? `${translate('advanced.tooltip.forecast')} ${that.series.name.substring(10)}` + ? `${that.series.name.substring(10)}` : translate && isTrend - ? `${translate('advanced.tooltip.trend')} ${that.series.name.substring(7)}` + ? `${that.series.name.substring(7)}` : that.series.name; - const low = that.point?.low ? formatTooltipValue(dataOptionY, that.point?.low, '') : undefined; - const high = that.point?.high ? formatTooltipValue(dataOptionY, that.point?.high, '') : undefined; + const low = that.point?.low ? formatTooltipValue(dataOptionY, that.point?.low, '') : ''; + const high = that.point?.high ? formatTooltipValue(dataOptionY, that.point?.high, '') : ''; const displayValue = (value: string | undefined, labelPrefix: string, color: string) => { - if (!value) return ''; - if (!translate || !isForecast || !labelPrefix) return `
${translate(labelPrefix)} ${spanSegment(value, color)}`; }; const extra = translate ? `(+${translate('advanced.tooltip.trend')})` : ''; const labelPrefix = isForecast ? 'advanced.tooltip.forecastValue' : ''; + if (isTrend) { + const modelTypeFromExpressionRegex = /modelType=([^"]+)/; + const match = (dataOptionY as unknown as DimensionalCalculatedMeasure)?.expression.match( + modelTypeFromExpressionRegex, + ); + const modelTypeValue = match ? match[1] : null; + + const { min, max, median, average } = that.point.trend!; + const formattedMin = formatTooltipValue(dataOptionY, min, ''); + const formattedMax = formatTooltipValue(dataOptionY, max, ''); + const formattedMedian = formatTooltipValue(dataOptionY, median, ''); + const formattedAverage = formatTooltipValue(dataOptionY, average, ''); + const modelType = modelTypeValue!; + + return renderTrendTooltipString({ + title: yName, + modelType, + trendData: { + min: formattedMin, + max: formattedMax, + median: formattedMedian, + average: formattedAverage, + }, + localValue: value, + x1Value, + x2Value, + translate, + }); + } + + if (isForecast) { + const confidenceIntervalFromExpressionRegex = /confidenceInterval=([^"]+)/; + const match = (dataOptionY as unknown as DimensionalCalculatedMeasure)?.expression.match( + confidenceIntervalFromExpressionRegex, + ); + const confidenceValue = match ? match[1] : '0.8'; + const confidencePercentage = (parseFloat(confidenceValue) * 100).toFixed(0) + '%'; + + return renderForecastTooltipString({ + title: yName, + confidenceValue: confidencePercentage, + forecastValue: value, + x1Value, + x2Value, + translate, + upperValue: high, + lowerValue: low, + }); + } return tooltipWrapper(` ${yName.replace(extra, '')} ${displayValue(value, labelPrefix, color)} diff --git a/packages/sdk-ui/src/chart-options-processor/translations/translations-to-highcharts.ts b/packages/sdk-ui/src/chart-options-processor/translations/translations-to-highcharts.ts index 512e9fe5..a41ed082 100644 --- a/packages/sdk-ui/src/chart-options-processor/translations/translations-to-highcharts.ts +++ b/packages/sdk-ui/src/chart-options-processor/translations/translations-to-highcharts.ts @@ -60,6 +60,12 @@ export type SeriesPointStructure = { // range charts specific low?: number | null; high?: number | null; + trend?: { + min: number; + max: number; + median: number; + average: number; + }; }; export type AxisClipped = { minClipped: boolean; maxClipped: boolean }; diff --git a/packages/sdk-ui/src/chart/__snapshots__/advanced-chart.test.tsx.snap b/packages/sdk-ui/src/chart/__snapshots__/advanced-chart.test.tsx.snap index 448376f9..ef861a4e 100644 --- a/packages/sdk-ui/src/chart/__snapshots__/advanced-chart.test.tsx.snap +++ b/packages/sdk-ui/src/chart/__snapshots__/advanced-chart.test.tsx.snap @@ -15,7 +15,9 @@ exports[`Advanced Charts > should render trend chart 1`] = ` "duration": 300, }, "backgroundColor": "#FFFFFF", - "events": {}, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -70,35 +72,6 @@ exports[`Advanced Charts > should render trend chart 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": true, - "handles": { - "backgroundColor": "#CCCCCC", - "borderColor": "#FFFFFF", - "symbols": [ - "navigator-handle", - "navigator-handle", - ], - }, - "height": 40, - "margin": 30, - "maskFill": "rgba(91,99,114, 0.15)", - "maskInside": true, - "outlineColor": "#CCCCCC", - "outlineWidth": 1, - "series": { - "dataGrouping": { - "enabled": false, - }, - "type": "line", - }, - "tooltipFormatter": [Function], - "xAxis": { - "labels": { - "enabled": false, - }, - }, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -685,7 +658,7 @@ exports[`Advanced Charts > should render trend chart 1`] = ` }, "symbol": "circle", }, - "name": "Cost (+Trend)", + "name": "Cost", "showInNavigator": true, "stickyTracking": false, "turboThreshold": 0, @@ -705,6 +678,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 399877.66021296044, }, { @@ -715,6 +694,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 760254.7486363016, }, { @@ -725,6 +710,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 892589.3891729144, }, { @@ -735,6 +726,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 904228.5180767283, }, { @@ -745,6 +742,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 912866.4678721044, }, { @@ -755,6 +758,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 916526.9340331501, }, { @@ -765,6 +774,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 914095.3329283679, }, { @@ -775,6 +790,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 904960.4685997746, }, { @@ -785,6 +806,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 912084.7216383086, }, { @@ -795,6 +822,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 945423.4204832909, }, { @@ -805,6 +838,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1009017.2938368567, }, { @@ -815,6 +854,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1127908.0165300977, }, { @@ -825,6 +870,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1260348.35798684, }, { @@ -835,6 +886,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1301643.164863898, }, { @@ -845,6 +902,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1226332.721934023, }, { @@ -855,6 +918,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1175483.052081485, }, { @@ -865,6 +934,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1259954.2895959807, }, { @@ -875,6 +950,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1477513.9658073424, }, { @@ -885,6 +966,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1731745.1938052739, }, { @@ -895,6 +982,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1918408.774731447, }, { @@ -905,6 +998,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2019625.0977478286, }, { @@ -915,6 +1014,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2080349.5218863264, }, { @@ -925,6 +1030,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2160577.230230905, }, { @@ -935,6 +1046,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2330053.153545553, }, { @@ -945,6 +1062,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2515328.951597531, }, { @@ -955,6 +1078,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2571323.757848365, }, { @@ -965,6 +1094,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2455225.182035394, }, { @@ -975,6 +1110,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2372277.1257133014, }, { @@ -985,6 +1126,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2390716.0906670545, }, { @@ -995,6 +1142,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2454806.7004078142, }, { @@ -1005,6 +1158,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2509923.7089504977, }, { @@ -1015,6 +1174,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2529590.1527741267, }, { @@ -1025,6 +1190,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2580856.1512703863, }, { @@ -1035,6 +1206,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2713417.6342164744, }, { @@ -1045,6 +1222,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2969220.9206936043, }, { @@ -1055,6 +1238,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3328777.947662453, }, { @@ -1065,6 +1254,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3620949.4273355627, }, { @@ -1075,6 +1270,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3556054.100029769, }, { @@ -1085,6 +1286,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3180837.955961699, }, { @@ -1095,6 +1302,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2940071.145840517, }, { @@ -1105,6 +1318,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 2928282.3596065277, }, { @@ -1115,6 +1334,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3012322.5051070023, }, { @@ -1125,6 +1350,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3126610.365876169, }, { @@ -1135,6 +1366,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3213000.749829498, }, { @@ -1145,6 +1382,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3314632.0388838113, }, { @@ -1155,6 +1398,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3504006.725372224, }, { @@ -1165,6 +1414,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3819677.0195216006, }, { @@ -1175,6 +1430,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3984064.438412456, }, { @@ -1185,6 +1446,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 3403293.012026755, }, { @@ -1195,6 +1462,12 @@ exports[`Advanced Charts > should render trend chart 1`] = ` ], }, "selected": false, + "trend": { + "average": 2145450.77991468, + "max": 4844611.66696444, + "median": 2275735.8248855434, + "min": 189976.80757868662, + }, "y": 1735405.3318556482, }, ], diff --git a/packages/sdk-ui/src/chart/__snapshots__/chart.test.tsx.snap b/packages/sdk-ui/src/chart/__snapshots__/chart.test.tsx.snap index 21fbc6a5..16e1063a 100644 --- a/packages/sdk-ui/src/chart/__snapshots__/chart.test.tsx.snap +++ b/packages/sdk-ui/src/chart/__snapshots__/chart.test.tsx.snap @@ -16,6 +16,7 @@ exports[`Chart > add handlers to a chart 1`] = ` }, "backgroundColor": "#FFFFFF", "events": { + "load": [Function], "selection": [Function], }, "polar": false, @@ -73,9 +74,6 @@ exports[`Chart > add handlers to a chart 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -441,7 +439,9 @@ exports[`Chart > change theme of a chart 1`] = ` "duration": 300, }, "backgroundColor": "blue", - "events": {}, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -496,9 +496,6 @@ exports[`Chart > change theme of a chart 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -1257,7 +1254,9 @@ exports[`Chart > range charts > render a area range chart two y and two x 1`] = "duration": 300, }, "backgroundColor": "#FFFFFF", - "events": {}, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -1312,9 +1311,6 @@ exports[`Chart > range charts > render a area range chart two y and two x 1`] = "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -2396,7 +2392,9 @@ exports[`Chart > range charts > render a area range chart with break by 1`] = ` "duration": 300, }, "backgroundColor": "#FFFFFF", - "events": {}, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -2451,9 +2449,6 @@ exports[`Chart > range charts > render a area range chart with break by 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -4244,7 +4239,9 @@ exports[`Chart > render a bar chart with breakBy and two x-axes 1`] = ` "duration": 300, }, "backgroundColor": "#FFFFFF", - "events": {}, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -4299,9 +4296,6 @@ exports[`Chart > render a bar chart with breakBy and two x-axes 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -5195,7 +5189,9 @@ exports[`Chart > render a column chart with breakBy 1`] = ` "duration": 300, }, "backgroundColor": "#FFFFFF", - "events": {}, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -5250,9 +5246,6 @@ exports[`Chart > render a column chart with breakBy 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", @@ -5773,7 +5766,9 @@ exports[`Chart > render a line chart 1`] = ` "duration": 300, }, "backgroundColor": "#FFFFFF", - "events": {}, + "events": { + "load": [Function], + }, "polar": false, "spacing": [ 20, @@ -5828,9 +5823,6 @@ exports[`Chart > render a line chart 1`] = ` "symbolRadius": 0, "verticalAlign": "bottom", }, - "navigator": { - "enabled": false, - }, "plotOptions": { "area": { "className": "area-series--without-pointer-events", diff --git a/packages/sdk-ui/src/chart/advanced-chart.tsx b/packages/sdk-ui/src/chart/advanced-chart.tsx index 5be79fcd..d602e234 100644 --- a/packages/sdk-ui/src/chart/advanced-chart.tsx +++ b/packages/sdk-ui/src/chart/advanced-chart.tsx @@ -4,7 +4,7 @@ import { RegularChartProps } from '../props.js'; import './chart.css'; import { RegularChart } from './regular-chart.js'; import { isDataSource, Measure, measureFactory } from '@sisense/sdk-data'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { FORECAST_PREFIX, TREND_PREFIX } from '@/chart-options-processor/advanced-chart-options.js'; /** diff --git a/packages/sdk-ui/src/chart/regular-chart.tsx b/packages/sdk-ui/src/chart/regular-chart.tsx index dfde2707..585684fe 100644 --- a/packages/sdk-ui/src/chart/regular-chart.tsx +++ b/packages/sdk-ui/src/chart/regular-chart.tsx @@ -190,7 +190,12 @@ export const RegularChart = (props: RegularChartProps) => { if (isSisenseChartType(chartType) && isSisenseChartProps(chartRendererProps)) { return ( - + ); } diff --git a/packages/sdk-ui/src/charts/indicator/__mocks__/indicator-mocks.ts b/packages/sdk-ui/src/charts/indicator/__mocks__/indicator-mocks.ts index 0fafef19..377a55ae 100644 --- a/packages/sdk-ui/src/charts/indicator/__mocks__/indicator-mocks.ts +++ b/packages/sdk-ui/src/charts/indicator/__mocks__/indicator-mocks.ts @@ -43,7 +43,9 @@ export const chartDesignOptions: IndicatorChartDesignOptions = { max: null, tickInterval: null, }, - autoZoom: true, + autoZoom: { + enabled: true, + }, indicatorType: 'gauge', skin: 1, diff --git a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-data-options.ts b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-data-options.ts index 9f2dcddc..6499c137 100644 --- a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-data-options.ts +++ b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-data-options.ts @@ -19,7 +19,7 @@ import { ColoringService, getColoringServiceByColorOptions, } from '../../chart-data-options/coloring'; -import isNumber from 'lodash/isNumber'; +import isNumber from 'lodash-es/isNumber'; export type IndicatorLegacyChartDataOptions = ReturnType; diff --git a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/indicator-legacy-chart-options.ts b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/indicator-legacy-chart-options.ts index 089968d6..f2685fc5 100644 --- a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/indicator-legacy-chart-options.ts +++ b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/indicator-legacy-chart-options.ts @@ -13,7 +13,7 @@ import { overrideWithThemeSettings } from './override-with-theme-settings'; import { legacyOptionsToThemeSettingsDictionary } from './legacy-chart-options-to-theme-settings-dictionary'; import { IndicatorChartData } from '../../../chart-data/types'; import { getValueColorOptions, overrideWithValueColor } from './override-with-value-color'; -import isNumber from 'lodash/isNumber'; +import isNumber from 'lodash-es/isNumber'; export type ChartRenderingOptions = { chartData: IndicatorChartData; diff --git a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/override-with-value-color.test.ts b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/override-with-value-color.test.ts index 1776c447..9847a794 100644 --- a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/override-with-value-color.test.ts +++ b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/override-with-value-color.test.ts @@ -8,7 +8,7 @@ import { AllowedIndicatorColoringTypes, } from './override-with-value-color'; import { numericSimpleLegacyChartOptionsWithDarkTheme } from './__mocks__/legacy-chart-options'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import '../../../chart-data-options/coloring'; const getColorMock = vi.fn().mockReturnValue('red'); diff --git a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/prepare-ticker-options.ts b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/prepare-ticker-options.ts index 23d65736..e0b5af14 100644 --- a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/prepare-ticker-options.ts +++ b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/prepare-ticker-options.ts @@ -1,4 +1,4 @@ -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { defaultTickerOptions } from '@/charts/indicator/indicator-legacy-chart-options/default-options'; import { GaugeOptions, LegacyIndicatorChartOptions } from '@/charts/indicator/types'; diff --git a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/utils/override-with-custom-settings.ts b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/utils/override-with-custom-settings.ts index 6a283214..e9792934 100644 --- a/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/utils/override-with-custom-settings.ts +++ b/packages/sdk-ui/src/charts/indicator/indicator-legacy-chart-options/utils/override-with-custom-settings.ts @@ -1,4 +1,4 @@ -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; /** * Overrides the default options with custom settings based on a mapping dictionary. diff --git a/packages/sdk-ui/src/charts/map-charts/areamap/areamap-map.tsx b/packages/sdk-ui/src/charts/map-charts/areamap/areamap-map.tsx index 81e5677f..27028e7d 100644 --- a/packages/sdk-ui/src/charts/map-charts/areamap/areamap-map.tsx +++ b/packages/sdk-ui/src/charts/map-charts/areamap/areamap-map.tsx @@ -138,12 +138,13 @@ function getTooltipContent( originalValueTitle: string, ): string { const featureInfo = featureStylesDictionary[feature.id!]; + const { formattedOriginalValue } = featureInfo.geoDataElement || {}; return `
${featureInfo.displayName} ${ - featureInfo.geoDataElement - ? `
${originalValueTitle}: ${featureInfo.geoDataElement.formattedOriginalValue}` + featureInfo.geoDataElement && formattedOriginalValue !== undefined + ? `
${originalValueTitle}: ${formattedOriginalValue}` : '' }
`; diff --git a/packages/sdk-ui/src/charts/map-charts/areamap/areamap.tsx b/packages/sdk-ui/src/charts/map-charts/areamap/areamap.tsx index 00947799..031408fd 100644 --- a/packages/sdk-ui/src/charts/map-charts/areamap/areamap.tsx +++ b/packages/sdk-ui/src/charts/map-charts/areamap/areamap.tsx @@ -9,6 +9,9 @@ import { AreamapMap } from './areamap-map.js'; import { useGeoJson } from './use-geo-json.js'; import { AreamapDataPointEventHandler } from '../../../props'; import { ChartRendererProps } from '@/chart/types.js'; +import { useThemeContext } from '@/theme-provider'; +import { useMemo } from 'react'; +import { getPaletteColor } from '@/chart-data-options/coloring/utils'; export type AreamapProps = { chartData: AreamapData; @@ -23,15 +26,27 @@ export const Areamap: React.FC = ({ designOptions, onDataPointClick, }) => { + const { themeSettings } = useThemeContext(); const { geoJson } = useGeoJson(designOptions.mapType); + + const geoData = useMemo(() => { + if (!dataOptions.color) { + return chartData.geoData.map((dataItem) => ({ + ...dataItem, + color: getPaletteColor(themeSettings.palette.variantColors, 0), + })); + } + return chartData.geoData; + }, [chartData.geoData, dataOptions, themeSettings]); + return ( <> {geoJson && ( { const isAreamapDataOptions = ( dataOptions: ChartDataOptionsInternal, ): dataOptions is AreamapChartDataOptionsInternal => { - return 'geo' in dataOptions && 'color' in dataOptions; + return 'geo' in dataOptions; }; const isAreamapChartDesignOptions = ( diff --git a/packages/sdk-ui/src/charts/map-charts/areamap/use-geo-json.ts b/packages/sdk-ui/src/charts/map-charts/areamap/use-geo-json.ts index 97ea0ef9..6d998278 100644 --- a/packages/sdk-ui/src/charts/map-charts/areamap/use-geo-json.ts +++ b/packages/sdk-ui/src/charts/map-charts/areamap/use-geo-json.ts @@ -1,5 +1,5 @@ import { FeatureCollection as GeoJsonFeatureCollection } from 'geojson'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { useSisenseContext } from '../../../sisense-context/sisense-context'; import { useEffect, useState } from 'react'; import { useGetApi } from '../../../api/rest-api'; diff --git a/packages/sdk-ui/src/charts/map-charts/scattermap/hooks/use-tooltip-handler.tsx b/packages/sdk-ui/src/charts/map-charts/scattermap/hooks/use-tooltip-handler.tsx index f6e8665d..4f1aa4eb 100644 --- a/packages/sdk-ui/src/charts/map-charts/scattermap/hooks/use-tooltip-handler.tsx +++ b/packages/sdk-ui/src/charts/map-charts/scattermap/hooks/use-tooltip-handler.tsx @@ -1,5 +1,5 @@ import { useCallback } from 'react'; -import delay from 'lodash/delay'; +import delay from 'lodash-es/delay'; import { ScattermapChartLocation } from '../../../../chart-data/types'; import { useSisenseContext } from '../../../../sisense-context/sisense-context.js'; import { diff --git a/packages/sdk-ui/src/charts/map-charts/scattermap/utils/location.ts b/packages/sdk-ui/src/charts/map-charts/scattermap/utils/location.ts index 48456333..d9a5c629 100644 --- a/packages/sdk-ui/src/charts/map-charts/scattermap/utils/location.ts +++ b/packages/sdk-ui/src/charts/map-charts/scattermap/utils/location.ts @@ -1,4 +1,4 @@ -import trim from 'lodash/trim'; +import trim from 'lodash-es/trim'; import { ScattermapLocationLevel } from '@/chart-data-options/types'; import { ScattermapDataPoint } from '@/types'; import { ScattermapChartLocation } from '@/chart-data/types'; diff --git a/packages/sdk-ui/src/common-filters/cascading-utils.test.ts b/packages/sdk-ui/src/common-filters/cascading-utils.test.ts index 34dbda0c..b454863a 100644 --- a/packages/sdk-ui/src/common-filters/cascading-utils.test.ts +++ b/packages/sdk-ui/src/common-filters/cascading-utils.test.ts @@ -1,7 +1,7 @@ import { isCascadingFilter } from '@/utils/filters'; import * as DM from '@/__test-helpers__/sample-ecommerce'; import { filterFactory, CascadingFilter, Filter } from '@sisense/sdk-data'; -import omit from 'lodash/omit'; +import omit from 'lodash-es/omit'; import { flattenCascadingFilters, reassembleCascadingFilters, diff --git a/packages/sdk-ui/src/common-filters/common-filters-connector.tsx b/packages/sdk-ui/src/common-filters/common-filters-connector.tsx index d03a750a..65ad1076 100644 --- a/packages/sdk-ui/src/common-filters/common-filters-connector.tsx +++ b/packages/sdk-ui/src/common-filters/common-filters-connector.tsx @@ -1,5 +1,5 @@ import merge from 'ts-deepmerge'; -import partition from 'lodash/partition'; +import partition from 'lodash-es/partition'; import { Attribute, MembersFilter, type Filter } from '@sisense/sdk-data'; import { mergeFilters } from '@/dashboard-widget/utils'; import { WidgetHeaderClearSelectionButton } from './widget-header-clear-selection-button'; diff --git a/packages/sdk-ui/src/common-filters/selection-utils.ts b/packages/sdk-ui/src/common-filters/selection-utils.ts index a2803821..09448dbd 100644 --- a/packages/sdk-ui/src/common-filters/selection-utils.ts +++ b/packages/sdk-ui/src/common-filters/selection-utils.ts @@ -10,8 +10,8 @@ import { isScattermap, } from '@/chart-options-processor/translations/types'; import { Column, Attribute, Filter } from '@sisense/sdk-data'; -import uniq from 'lodash/uniq'; -import isUndefined from 'lodash/isUndefined'; +import uniq from 'lodash-es/uniq'; +import isUndefined from 'lodash-es/isUndefined'; import { AreamapChartDataOptions, AreamapDataPoint, diff --git a/packages/sdk-ui/src/common-filters/use-common-filters.tsx b/packages/sdk-ui/src/common-filters/use-common-filters.tsx index 412e42e7..4695fd71 100644 --- a/packages/sdk-ui/src/common-filters/use-common-filters.tsx +++ b/packages/sdk-ui/src/common-filters/use-common-filters.tsx @@ -1,5 +1,5 @@ import { useCallback, useState } from 'react'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { type Filter } from '@sisense/sdk-data'; import { mergeFilters } from '@/dashboard-widget/utils'; import { ChartDataOptions, WidgetModel } from '../index.js'; diff --git a/packages/sdk-ui/src/common-filters/utils.ts b/packages/sdk-ui/src/common-filters/utils.ts index 83264f10..6dc2915f 100644 --- a/packages/sdk-ui/src/common-filters/utils.ts +++ b/packages/sdk-ui/src/common-filters/utils.ts @@ -1,6 +1,6 @@ import { isSameAttribute, haveSameAttribute } from '@/utils/filters.js'; import { Filter, Attribute, filterFactory, MembersFilter } from '@sisense/sdk-data'; -import isEqual from 'lodash/isEqual'; +import isEqual from 'lodash-es/isEqual'; import { FiltersIgnoringRules, PureFilter } from './types.js'; export function getAllowedFilters( diff --git a/packages/sdk-ui/src/common/components/loading-indicator.tsx b/packages/sdk-ui/src/common/components/loading-indicator.tsx index d50109d8..9b04a945 100644 --- a/packages/sdk-ui/src/common/components/loading-indicator.tsx +++ b/packages/sdk-ui/src/common/components/loading-indicator.tsx @@ -19,14 +19,15 @@ export const LoadingIndicator = ({ const backgroundColor = themeSettings?.chart.backgroundColor ? { backgroundColor: themeSettings.chart.backgroundColor } : undefined; - const panelBackgroundColor = themeSettings?.chart.panelBackgroundColor - ? { backgroundColor: themeSettings.chart.panelBackgroundColor } - : undefined; return ( -
+
diff --git a/packages/sdk-ui/src/common/components/loading-overlay.tsx b/packages/sdk-ui/src/common/components/loading-overlay.tsx index 78231c11..d8673295 100644 --- a/packages/sdk-ui/src/common/components/loading-overlay.tsx +++ b/packages/sdk-ui/src/common/components/loading-overlay.tsx @@ -19,24 +19,20 @@ export const LoadingOverlay = ({ themeSettings: CompleteThemeSettings; children: ReactNode; }) => { - const panelBackgroundColor = themeSettings?.chart.panelBackgroundColor - ? { backgroundColor: themeSettings.chart.panelBackgroundColor } - : undefined; - return (
{isVisible && ( // z-index is set to 401, which is higher than max z-index of 400 on areamap
diff --git a/packages/sdk-ui/src/common/hooks/use-has-changed.ts b/packages/sdk-ui/src/common/hooks/use-has-changed.ts index 35a6c177..7ae2e146 100644 --- a/packages/sdk-ui/src/common/hooks/use-has-changed.ts +++ b/packages/sdk-ui/src/common/hooks/use-has-changed.ts @@ -1,4 +1,4 @@ -import isEqual from 'lodash/isEqual'; +import isEqual from 'lodash-es/isEqual'; import { usePrevious } from './use-previous'; /** diff --git a/packages/sdk-ui/src/dashboard-widget/dashboard-widget.tsx b/packages/sdk-ui/src/dashboard-widget/dashboard-widget.tsx index b994de67..1466ad5f 100644 --- a/packages/sdk-ui/src/dashboard-widget/dashboard-widget.tsx +++ b/packages/sdk-ui/src/dashboard-widget/dashboard-widget.tsx @@ -117,6 +117,7 @@ export const DashboardWidget: FunctionComponent = asSisens } const filterRelations = getFilterRelationsFromJaql( filters, + highlights, convertFilterRelationsModelToJaql( fetchedDashboard?.filterRelations?.length ? fetchedDashboard?.filterRelations[0].filterRelations @@ -138,7 +139,6 @@ export const DashboardWidget: FunctionComponent = asSisens /> ); } - return ( { - let dummyDashboard: DashboardDto; - let dummyWidget: WidgetDto; - - beforeEach(() => { - dummyDashboard = { - filters: [ - { - jaql: { - dim: '[Commerce.Age Range]', - filter: { - members: ['0-18', '19-24', '65+'], - }, +import { + extractCombinedFilters, + extractDashboardFiltersForWidget, +} from './translate-dashboard-filters'; +import { PanelItem, WidgetDashboardFilterMode, WidgetDto } from './types'; + +let dummyDashboard: DashboardDto; +let dummyWidget: WidgetDto; + +beforeEach(() => { + dummyDashboard = { + filters: [ + { + jaql: { + dim: '[Commerce.Age Range]', + filter: { + members: ['0-18', '19-24', '65+'], }, - instanceid: 'filter-1', }, - { - jaql: { - dim: '[Commerce.Gender]', - filter: { - members: ['Male', 'Female'], - }, + instanceid: 'filter-1', + }, + { + jaql: { + dim: '[Commerce.Gender]', + filter: { + members: ['Male', 'Female'], }, - instanceid: 'filter-2', }, - ], - } as DashboardDto; - - dummyWidget = { - type: 'chart/column', - metadata: { - ignore: { - all: false, - ids: ['not existed filter id'], - }, - panels: [ - { - name: 'categories', - items: [ - { - jaql: { - dim: '[Commerce.Age Range]', - }, + instanceid: 'filter-2', + }, + ], + } as DashboardDto; + + dummyWidget = { + type: 'chart/column', + metadata: { + ignore: { + all: false, + ids: ['not existed filter id'], + }, + panels: [ + { + name: 'categories', + items: [ + { + jaql: { + dim: '[Commerce.Age Range]', }, - { - jaql: { - dim: '[Commerce.Gender]', - }, + }, + { + jaql: { + dim: '[Commerce.Gender]', }, - ], - }, - ], - }, - options: { - dashboardFiltersMode: WidgetDashboardFilterMode.SELECT, + }, + ], + }, + ], + }, + options: { + dashboardFiltersMode: WidgetDashboardFilterMode.SELECT, + }, + } as WidgetDto; +}); + +describe('extractCombinedFilters', () => { + it('should extract and merge dashboard and widget filters', () => { + const widgetFilterJaql = { + dim: '[Commerce.Brand]', + filter: { + members: ['ABC'], }, - } as WidgetDto; + } as FilterJaql; + + dummyWidget.metadata.panels.push({ + name: 'filters', + items: [ + { + jaql: widgetFilterJaql, + } as PanelItem, + ], + }); + + const { filters, highlights } = extractCombinedFilters(dummyDashboard, dummyWidget); + expect(filters).toHaveLength(1); + expect(highlights).toHaveLength(2); + expect(filters[0].jaql().jaql).toMatchObject({ + dim: widgetFilterJaql.dim, + filter: widgetFilterJaql.filter, + }); + expect(highlights[0].jaql().jaql).toMatchObject({ + dim: (dummyDashboard.filters![0] as FilterDto).jaql.dim, + filter: (dummyDashboard.filters![0] as FilterDto).jaql.filter, + }); + expect(highlights[1].jaql().jaql).toMatchObject({ + dim: (dummyDashboard.filters![1] as FilterDto).jaql.dim, + filter: (dummyDashboard.filters![1] as FilterDto).jaql.filter, + }); }); +}); +describe('extractDashboardFiltersForWidget', () => { it('should extract all "highlight" filters', () => { const { filters, highlights } = extractDashboardFiltersForWidget(dummyDashboard, dummyWidget); diff --git a/packages/sdk-ui/src/dashboard-widget/translate-dashboard-filters.ts b/packages/sdk-ui/src/dashboard-widget/translate-dashboard-filters.ts index ba546f43..2726b6af 100644 --- a/packages/sdk-ui/src/dashboard-widget/translate-dashboard-filters.ts +++ b/packages/sdk-ui/src/dashboard-widget/translate-dashboard-filters.ts @@ -1,5 +1,5 @@ import { DashboardDto, FilterDto, CascadingFilterDto } from '../api/types/dashboard-dto'; -import { extractFilterModelFromJaql } from './translate-widget-filters'; +import { extractFilterModelFromJaql, extractWidgetFilters } from './translate-widget-filters'; import { FiltersIgnoringRules, PanelItem, @@ -7,7 +7,7 @@ import { WidgetDto, WidgetType, } from './types'; -import { getEnabledPanelItems } from './utils'; +import { getEnabledPanelItems, mergeFilters } from './utils'; import { BackgroundFilter, @@ -16,6 +16,28 @@ import { IncludeAllFilter, } from '@sisense/sdk-data'; +/** + * Extracts and merges dashboard and widget filters. This consolidates all + * filters applicable for a widget. + * + * @param dashboard - The dashboard containing the filters. + * @param widget - The widget containing the filters. + * @returns An object containing an array of filters and an array of highlights. + * @internal + */ +export function extractCombinedFilters(dashboard: DashboardDto, widget: WidgetDto) { + const { filters: dashboardFilters, highlights } = extractDashboardFiltersForWidget( + dashboard, + widget, + ); + const widgetFilters = extractWidgetFilters(widget.metadata.panels); + const filters = mergeFilters(dashboardFilters, widgetFilters); + return { + filters, + highlights, + }; +} + /** * Extracts dashboard filters applicable to a widget. * diff --git a/packages/sdk-ui/src/dashboard-widget/translate-widget-data-options.test.ts b/packages/sdk-ui/src/dashboard-widget/translate-widget-data-options.test.ts index d86c0e5e..fb048ee5 100644 --- a/packages/sdk-ui/src/dashboard-widget/translate-widget-data-options.test.ts +++ b/packages/sdk-ui/src/dashboard-widget/translate-widget-data-options.test.ts @@ -28,7 +28,7 @@ import { import { Panel, WidgetStyle } from './types'; import { createDataOptionsFromPanels, extractDataOptions } from './translate-widget-data-options'; import { jaqlMock } from './__mocks__/jaql-mock'; -import { isObject } from 'lodash'; +import isObject from 'lodash-es/isObject'; const styleMock = {} as WidgetStyle; @@ -532,7 +532,7 @@ describe('translate widget plugin data options from pluginPanels', () => { const dataOptions: any = createDataOptionsFromPanels(panels, ['red', 'blue', 'green']); verifyColumn(dataOptions.categories[0], panels[0].items[0]); verifyColumn(dataOptions.values[0], panels[1].items[0]); - verifyColumn(dataOptions['break by'][0], panels[2].items[0]); + verifyColumn(dataOptions.breakBy[0], panels[2].items[0]); }); }); }); diff --git a/packages/sdk-ui/src/dashboard-widget/translate-widget-data-options.ts b/packages/sdk-ui/src/dashboard-widget/translate-widget-data-options.ts index ff864b21..1e376701 100644 --- a/packages/sdk-ui/src/dashboard-widget/translate-widget-data-options.ts +++ b/packages/sdk-ui/src/dashboard-widget/translate-widget-data-options.ts @@ -1,4 +1,4 @@ -import mapValues from 'lodash/mapValues'; +import mapValues from 'lodash-es/mapValues'; import { MetadataTypes, DimensionalBaseMeasure, @@ -13,6 +13,8 @@ import { createFilterFromJaql, PivotJaql, Attribute, + ForecastFormulaOptions, + TrendFormulaOptions, } from '@sisense/sdk-data'; import { CartesianChartDataOptions, @@ -58,7 +60,8 @@ import { } from '../chart-data-options/types'; import { WidgetDataOptions } from '../models'; import { TranslatableError } from '../translation/translatable-error'; -import findKey from 'lodash/findKey'; +import findKey from 'lodash-es/findKey'; +import camelCase from 'lodash-es/camelCase'; export function createDimensionalElementFromJaql(jaql: Jaql, format?: PanelItem['format']) { const isFormulaJaql = 'formula' in jaql; @@ -150,7 +153,7 @@ function extractNumberFormat(item: PanelItem): NumberFormatConfig | null { million: numberFormat.abbreviations?.m, billion: numberFormat.abbreviations?.b, trillion: numberFormat.abbreviations?.t, - thousandSeparator: numberFormat.number?.separated, + thousandSeparator: numberFormat.number?.separated ?? numberFormat.separated, prefix: numberFormat.currency?.position === CurrencyPosition.PRE, symbol: numberFormat.currency?.symbol, name: getNumberFormatName(numberFormat), @@ -160,6 +163,51 @@ function extractNumberFormat(item: PanelItem): NumberFormatConfig | null { return null; } +/** @internal */ +export function applyStatisticalModels( + dataOption: StyledMeasureColumn, + statisticalModels?: { + forecast?: { + isEnabled: boolean; + isViewerDisabled: boolean; + confidence: number; + forecastPeriod: number; + }; + trend?: { + isEnabled: boolean; + isViewerDisabled: boolean; + trendType: string; + }; + }, +): StyledMeasureColumn { + if (!statisticalModels) return dataOption; + + const { forecast, trend } = statisticalModels; + let newDataOption = { ...dataOption }; // Create a shallow copy to avoid mutation + + if (forecast && !forecast.isViewerDisabled && forecast.isEnabled) { + newDataOption = { + ...newDataOption, + forecast: { + confidenceInterval: forecast.confidence / 100, + forecastHorizon: forecast.forecastPeriod, + modelType: 'auto', + } as ForecastFormulaOptions, + }; + } + + if (trend && !trend.isViewerDisabled && trend.isEnabled) { + newDataOption = { + ...newDataOption, + trend: { + modelType: trend.trendType as TrendFormulaOptions['modelType'], + }, + }; + } + + return newDataOption; +} + export function createDataColumn(item: PanelItem, customPaletteColors?: Color[]) { const element = createDimensionalElementFromJaql(item.jaql, item.format); const sortType = getSortType(item.jaql.sort ?? item.categoriesSorting); @@ -186,7 +234,7 @@ export function createDataColumn(item: PanelItem, customPaletteColors?: Color[]) const totalsCalculation = 'subtotalAgg' in item.jaql && item.jaql.subtotalAgg; const dataBars = item.format?.databars; - return { + const dataOption = { column: element, ...(color && { color }), ...(showOnRightAxis && { showOnRightAxis }), @@ -197,6 +245,8 @@ export function createDataColumn(item: PanelItem, customPaletteColors?: Color[]) ...(dataBars && { dataBars }), ...(width && { width }), } as StyledMeasureColumn; + + return applyStatisticalModels(dataOption, item.statisticalModels); } return { @@ -215,7 +265,7 @@ export const createDataOptionsFromPanels = (panels: Panel[], variantColors: Colo const dataOptions: { [key: string]: any[] } = {}; panels.forEach((panel) => { if (panel.name !== 'filters') { - dataOptions[panel.name.toLowerCase()] = createColumnsFromPanelItems( + dataOptions[camelCase(panel.name)] = createColumnsFromPanelItems( panels, panel.name, variantColors, @@ -522,13 +572,11 @@ function extractAreamapChartDataOptions( const geo: [StyledColumn] = [ createColumnsFromPanelItems(panels, 'geo', paletteColors)[0], ]; - const color: [StyledMeasureColumn] = [ - createColumnsFromPanelItems(panels, 'color', paletteColors)[0], - ]; + const color = createColumnsFromPanelItems(panels, 'color', paletteColors)[0]; return { geo, - color, + ...(color && { color: [color] }), }; } diff --git a/packages/sdk-ui/src/dashboard-widget/translate-widget-drilldown-options.ts b/packages/sdk-ui/src/dashboard-widget/translate-widget-drilldown-options.ts index f8c63c13..64c87c9c 100644 --- a/packages/sdk-ui/src/dashboard-widget/translate-widget-drilldown-options.ts +++ b/packages/sdk-ui/src/dashboard-widget/translate-widget-drilldown-options.ts @@ -5,7 +5,7 @@ import { getEnabledPanelItems } from './utils'; import { DataPoint, DrilldownOptions } from '../types'; import { applyDateFormat } from '../query/date-formats/apply-date-format'; import parseISO from 'date-fns/parseISO'; -import uniqBy from 'lodash/uniqBy'; +import uniqBy from 'lodash-es/uniqBy'; const getAvailableDrilldowns = (item: PanelItem): Attribute[] => item?.parent diff --git a/packages/sdk-ui/src/dashboard-widget/translate-widget-filters.test.ts b/packages/sdk-ui/src/dashboard-widget/translate-widget-filters.test.ts index 4ea39cb0..46fa6e47 100644 --- a/packages/sdk-ui/src/dashboard-widget/translate-widget-filters.test.ts +++ b/packages/sdk-ui/src/dashboard-widget/translate-widget-filters.test.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { MetadataTypes } from '@sisense/sdk-data'; -import { extractFilters } from './translate-widget-filters'; +import { extractWidgetFilters } from './translate-widget-filters'; import { Panel } from './types'; describe('extractFilters', () => { @@ -26,7 +26,7 @@ describe('extractFilters', () => { }, ] as Panel[]; - const filters = extractFilters(panels); + const filters = extractWidgetFilters(panels); expect(filters).toHaveLength(1); expect(filters[0].jaql().jaql).toEqual(panels[0].items[0].jaql); @@ -57,7 +57,7 @@ describe('extractFilters', () => { }, ] as Panel[]; - const filters = extractFilters(panels); + const filters = extractWidgetFilters(panels); // verifies filter expect(filters[0].jaql().jaql).toEqual({ @@ -95,7 +95,7 @@ describe('extractFilters', () => { }, ] as Panel[]; - const filters = extractFilters(panels); + const filters = extractWidgetFilters(panels); expect(filters[0].jaql().jaql).toEqual(panels[0].items[0].jaql); }); diff --git a/packages/sdk-ui/src/dashboard-widget/translate-widget-filters.ts b/packages/sdk-ui/src/dashboard-widget/translate-widget-filters.ts index 315738cf..9d5bc238 100644 --- a/packages/sdk-ui/src/dashboard-widget/translate-widget-filters.ts +++ b/packages/sdk-ui/src/dashboard-widget/translate-widget-filters.ts @@ -83,13 +83,14 @@ function getEnabledFilterPanelItems(panels: Panel[]): PanelItem[] { return filterItems; } + /** * Extracts filters from the widget panel. * * @param panels - The array of panels. * @returns The extracted filters. */ -export function extractFilters(panels: Panel[]) { +export function extractWidgetFilters(panels: Panel[]) { return getEnabledFilterPanelItems(panels).map((filterItem) => createFilterFromJaql(filterItem.jaql as FilterJaql, filterItem.instanceid), ); diff --git a/packages/sdk-ui/src/dashboard-widget/translate-widget-style-options.test.ts b/packages/sdk-ui/src/dashboard-widget/translate-widget-style-options.test.ts index 9ac682e9..4d6f9620 100644 --- a/packages/sdk-ui/src/dashboard-widget/translate-widget-style-options.test.ts +++ b/packages/sdk-ui/src/dashboard-widget/translate-widget-style-options.test.ts @@ -1,5 +1,5 @@ -import merge from 'lodash/merge'; -import cloneDeep from 'lodash/cloneDeep'; +import merge from 'lodash-es/merge'; +import cloneDeep from 'lodash-es/cloneDeep'; import { extractStyleOptions, getIndicatorTypeSpecificOptions, @@ -13,6 +13,7 @@ import { PolarWidgetStyle, ScatterWidgetStyle, TreemapWidgetStyle, + WidgetDto, WidgetSubtype, } from './types'; import { jaqlMock } from './__mocks__/jaql-mock'; @@ -37,6 +38,16 @@ function generateWidgetAxisOptions(options = {}) { return merge(cloneDeep(defaultOptions), options); } +const mockWidgetDto = (subtype: WidgetSubtype | string, style: any, panels: any): WidgetDto => { + return { + subtype, + style, + metadata: { + panels, + }, + } as WidgetDto; +}; + describe('translate widget style options', () => { describe('axes style options for cartesian chart', () => { const widgetPanels = [ @@ -91,9 +102,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'chart/column', - '' as WidgetSubtype, - widgetStyle, - widgetPanels, + mockWidgetDto('', widgetStyle, widgetPanels), ) as BaseStyleOptionsWithAxes; expect(styleOptions.xAxis).toEqual({ @@ -114,9 +123,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'chart/column', - '' as WidgetSubtype, - widgetStyle, - widgetPanels, + mockWidgetDto('', widgetStyle, widgetPanels), ) as BaseStyleOptionsWithAxes; expect(styleOptions.xAxis?.title?.text).toEqual(widgetPanels[0].items[1].jaql.title); @@ -132,9 +139,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'chart/area', - '' as WidgetSubtype, - widgetStyle, - [], + mockWidgetDto('', widgetStyle, []), ) as AreaStyleOptions; expect(styleOptions.markers).toEqual(widgetStyle.markers); @@ -147,9 +152,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'chart/area', - '' as WidgetSubtype, - widgetStyle, - [], + mockWidgetDto('', widgetStyle, []), ) as AreaStyleOptions; expect(styleOptions.lineWidth).toEqual(widgetStyle.lineWidth); @@ -180,9 +183,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'chart/polar', - '' as WidgetSubtype, - widgetStyle, - widgetPanels, + mockWidgetDto('', widgetStyle, widgetPanels), ) as BaseStyleOptionsWithAxes; expect(styleOptions.xAxis).toEqual(widgetStyle.categories); @@ -203,9 +204,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'chart/polar', - '' as WidgetSubtype, - widgetStyle, - widgetPanels, + mockWidgetDto('', widgetStyle, widgetPanels), ) as BaseStyleOptionsWithAxes; expect(styleOptions.xAxis?.title?.text).toEqual(widgetPanels[0].items[0].jaql.title); @@ -240,9 +239,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'chart/scatter', - '' as WidgetSubtype, - widgetStyle, - widgetPanels, + mockWidgetDto('', widgetStyle, widgetPanels), ) as BaseStyleOptionsWithAxes; expect(styleOptions.xAxis).toEqual(widgetStyle.xAxis); @@ -257,9 +254,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'chart/scatter', - '' as WidgetSubtype, - widgetStyle, - widgetPanels, + mockWidgetDto('', widgetStyle, widgetPanels), ) as BaseStyleOptionsWithAxes; expect(styleOptions.xAxis?.title?.text).toEqual(widgetPanels[0].items[0].jaql.title); @@ -288,9 +283,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'chart/funnel', - '' as WidgetSubtype, - widgetStyle, - [], + mockWidgetDto('', widgetStyle, []), ) as BaseStyleOptions; expect(styleOptions).toEqual({ @@ -316,10 +309,10 @@ describe('translate widget style options', () => { header: { color: { enabled: true } }, }; - expect(extractStyleOptions('tablewidget', '' as WidgetSubtype, widgetStyle, [])).toEqual( + expect(extractStyleOptions('tablewidget', mockWidgetDto('', widgetStyle, []))).toEqual( expectedOptions, ); - expect(extractStyleOptions('tablewidgetagg', '' as WidgetSubtype, widgetStyle, [])).toEqual( + expect(extractStyleOptions('tablewidgetagg', mockWidgetDto('', widgetStyle, []))).toEqual( expectedOptions, ); }); @@ -344,9 +337,7 @@ describe('translate widget style options', () => { const styleOptions = extractStyleOptions( 'indicator', - 'indicator/numeric' as WidgetSubtype, - widgetStyle, - [ + mockWidgetDto('indicator/numeric', widgetStyle, [ { name: 'value', items: [ @@ -367,7 +358,7 @@ describe('translate widget style options', () => { } as PanelItem, ], }, - ], + ]), ) as BaseStyleOptions; expect(styleOptions).toStrictEqual({ @@ -460,7 +451,7 @@ describe('translate widget style options', () => { mode: 'value', }, }; - const result = extractStyleOptions('treemap', 'treemap', widgetStyle, []); + const result = extractStyleOptions('treemap', mockWidgetDto('treemap', widgetStyle, [])); expect(result).toEqual(expected); }); @@ -481,7 +472,7 @@ describe('translate widget style options', () => { mode: 'contribution', }, }; - const result = extractStyleOptions('treemap', 'treemap', widgetStyle, []); + const result = extractStyleOptions('treemap', mockWidgetDto('treemap', widgetStyle, [])); expect(result).toEqual(expected); }); @@ -497,7 +488,7 @@ describe('translate widget style options', () => { mode: 'value', }, }; - const result = extractStyleOptions('treemap', 'treemap', widgetStyle, []); + const result = extractStyleOptions('treemap', mockWidgetDto('treemap', widgetStyle, [])); expect(result).toEqual(expected); }); diff --git a/packages/sdk-ui/src/dashboard-widget/translate-widget-style-options.ts b/packages/sdk-ui/src/dashboard-widget/translate-widget-style-options.ts index 83b530fa..3497fb5e 100644 --- a/packages/sdk-ui/src/dashboard-widget/translate-widget-style-options.ts +++ b/packages/sdk-ui/src/dashboard-widget/translate-widget-style-options.ts @@ -47,6 +47,7 @@ import { ScattermapWidgetStyle, PivotWidgetStyle, WidgetDesign, + WidgetDto, } from './types'; import { getEnabledPanelItems, getChartSubtype } from './utils'; @@ -251,7 +252,13 @@ function prepareBoxplotChartAxisOptions( return axisOptions; } -type CartesianChartStyleOptions = LineStyleOptions | AreaStyleOptions | StackableStyleOptions; +/** + * @internal + */ +export type CartesianChartStyleOptions = + | LineStyleOptions + | AreaStyleOptions + | StackableStyleOptions; function extractCartesianChartStyleOptions( widgetType: WidgetType, @@ -473,21 +480,29 @@ export function extractPivotTableStyleOptions( export function extractStyleOptions( widgetType: WType, - widgetSubtype: WidgetSubtype, - style: WidgetStyle, - panels: Panel[], + widget: WidgetDto, ): ChartStyleOptions | TableStyleOptions { + const { + subtype: widgetSubtype, + style, + metadata: { panels }, + } = widget as WidgetDto & { subtype: WidgetSubtype }; switch (widgetType) { case 'chart/line': case 'chart/area': case 'chart/bar': - case 'chart/column': - return extractCartesianChartStyleOptions( + case 'chart/column': { + const styleOptions = extractCartesianChartStyleOptions( widgetType, widgetSubtype, style as CartesianWidgetStyle, panels, ); + if (styleOptions.navigator) { + styleOptions.navigator.scrollerLocation = widget.options?.previousScrollerLocation; + } + return styleOptions; + } case 'chart/polar': return extractPolarChartStyleOptions(widgetSubtype, style as PolarWidgetStyle, panels); case 'chart/scatter': @@ -512,8 +527,17 @@ export function extractStyleOptions( style as IndicatorWidgetStyle, panels, ); - case 'chart/boxplot': - return extractBoxplotChartStyleOptions(widgetSubtype, style as BoxplotWidgetStyle, panels); + case 'chart/boxplot': { + const boxplotStyleOptions = extractBoxplotChartStyleOptions( + widgetSubtype, + style as BoxplotWidgetStyle, + panels, + ); + if (boxplotStyleOptions.navigator) { + boxplotStyleOptions.navigator.scrollerLocation = widget.options?.previousScrollerLocation; + } + return boxplotStyleOptions; + } case 'map/scatter': return extractScattermapChartStyleOptions(widgetSubtype, style as ScattermapWidgetStyle); case 'map/area': diff --git a/packages/sdk-ui/src/dashboard-widget/types.ts b/packages/sdk-ui/src/dashboard-widget/types.ts index 470ea137..297ce120 100644 --- a/packages/sdk-ui/src/dashboard-widget/types.ts +++ b/packages/sdk-ui/src/dashboard-widget/types.ts @@ -87,6 +87,8 @@ export type Datasource = { * * This is the (not-comprehensive) structure of the response from the * `/api/v1/dashboards/${dashboardOid}/widgets/${widgetOid}` endpoint. + * + * @internal */ export interface WidgetDto { oid: string; @@ -105,8 +107,16 @@ export interface WidgetDto { dashboardFiltersMode: `${WidgetDashboardFilterMode}`; selector: boolean; drillToAnywhere?: boolean; + previousScrollerLocation?: AutoZoomNavigatorScrollerLocation; }; } +/** + * @description the scroll location of the navigator scroller / auto zoom feature + */ +export type AutoZoomNavigatorScrollerLocation = { + min: number; + max: number; +}; export type WidgetDesign = { widgetBackgroundColor: string; @@ -170,6 +180,47 @@ export type DatetimeMask = { dateAndTime?: string; }; +export type StatisticalModels = { + forecast?: { + isEnabled: boolean; + isViewerDisabled: boolean; + explainVariable: null; + evaluation: { + type: string; + numLastPointsForEvaluation: number; + ignoreLast: number; + }; + forecastPeriod: number; + confidence: number; + modelType: string; + boundaries: { + upper: { + isEnabled: boolean; + value: null; + }; + lower: { + isEnabled: boolean; + value: null; + }; + isInt: { + isEnabled: boolean; + }; + }; + }; + trend?: { + isEnabled: boolean; + isViewerDisabled: boolean; + trendType: string; + ignoreAnomalies: boolean; + trendOnForecast: boolean; + compare: { + isEnabled: boolean; + period: string; + }; + isAccessible: boolean; + }; +}; + export type PanelItem = { instanceid?: string; format?: { @@ -190,6 +241,7 @@ export type PanelItem = { categoriesSorting?: JaqlSortDirection; isColored?: boolean; geoLevel?: 'country' | 'state' | 'city'; + statisticalModels?: StatisticalModels; field?: { id: string; index: number; diff --git a/packages/sdk-ui/src/dashboard-widget/utils.test.ts b/packages/sdk-ui/src/dashboard-widget/utils.test.ts index eb8c2d17..17bb9c75 100644 --- a/packages/sdk-ui/src/dashboard-widget/utils.test.ts +++ b/packages/sdk-ui/src/dashboard-widget/utils.test.ts @@ -110,19 +110,27 @@ describe('getFilterRelationsFromJaql', () => { it('should return filters if relations are undefined', () => { const filters = [mockFilter1, mockFilter2]; - expect(getFilterRelationsFromJaql(filters, undefined)).toEqual(filters); + expect(getFilterRelationsFromJaql(filters, [], undefined)).toEqual(filters); }); it('should replace filter relations nodes with filters', () => { const filters = [mockFilter1, mockFilter2, mockFilter3, mockFilter4]; - expect(getFilterRelationsFromJaql(filters, incomingFilterRelationsJaql)).toEqual( + expect(getFilterRelationsFromJaql(filters, [], incomingFilterRelationsJaql)).toEqual( expectedFilterRelations, ); }); it('should throw an error if filter relations contain unknown filter', () => { const filters = [mockFilter1, mockFilter2]; - expect(() => getFilterRelationsFromJaql(filters, incomingFilterRelationsJaql)).toThrow(); + expect(() => getFilterRelationsFromJaql(filters, [], incomingFilterRelationsJaql)).toThrow(); + }); + + it('should return filters if filter relations and highlights exist', () => { + const filters = [mockFilter1, mockFilter2]; + const highlights = [mockFilter3, mockFilter4]; + expect(getFilterRelationsFromJaql(filters, highlights, incomingFilterRelationsJaql)).toEqual( + filters, + ); }); }); diff --git a/packages/sdk-ui/src/dashboard-widget/utils.ts b/packages/sdk-ui/src/dashboard-widget/utils.ts index c307ce77..b88de3ad 100644 --- a/packages/sdk-ui/src/dashboard-widget/utils.ts +++ b/packages/sdk-ui/src/dashboard-widget/utils.ts @@ -19,7 +19,7 @@ import { WidgetSubtype, WidgetType, } from './types'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { TranslatableError } from '../translation/translatable-error'; import { isCascadingFilter } from '@/utils/filters'; @@ -228,18 +228,26 @@ export function mergeFiltersByStrategy( * Replaces nodes of filter reations tree with fetched filters by instance id. * * @param filters - The filters from the dashboard. + * @param highlights - The highlights from the dashboard * @param filterRelations - Fetched filter relations. * @returns {FilterRelations} Filter relations with filters in nodes. */ /* eslint-disable-next-line sonarjs/cognitive-complexity */ export function getFilterRelationsFromJaql( filters: Filter[], + highlights: Filter[], filterRelations: FilterRelationsJaql | undefined, ): FilterRelations | Filter[] { if (!filterRelations) { return filters; } + // If highlights are present, nodes in filter relations reference both filters and highlights + // and thus cannot be replaced with filters. Return filters in this case. + if (highlights.length) { + return filters; + } + const mergedFilterRelations = cloneDeep(filterRelations); function traverse( diff --git a/packages/sdk-ui/src/dashboard/dashboard-by-id.tsx b/packages/sdk-ui/src/dashboard/dashboard-by-id.tsx index 76dc7478..74ab6045 100644 --- a/packages/sdk-ui/src/dashboard/dashboard-by-id.tsx +++ b/packages/sdk-ui/src/dashboard/dashboard-by-id.tsx @@ -10,6 +10,24 @@ import { asSisenseComponent } from '@/decorators/component-decorators/as-sisense * * **Note:** Dashboard extensions based on JS scripts and add-ons in Fusion are not supported. * + * @example + * + * ```ts + * import { DashboardById } from '@sisense/sdk-ui'; + + const CodeExample = () => { + return ( + <> + + + ); + }; + + export default CodeExample; + * ``` + * * @group Fusion Embed * @fusionEmbed * @alpha diff --git a/packages/sdk-ui/src/dashboard/dashboard.tsx b/packages/sdk-ui/src/dashboard/dashboard.tsx index a416df74..286a089b 100644 --- a/packages/sdk-ui/src/dashboard/dashboard.tsx +++ b/packages/sdk-ui/src/dashboard/dashboard.tsx @@ -12,6 +12,40 @@ import { asSisenseComponent } from '@/decorators/component-decorators/as-sisense * * **Note:** Dashboard extensions based on JS scripts and add-ons in Fusion are not supported. * + * @example + * + * ```ts + * import { Dashboard, useGetDashboardModel } from '@sisense/sdk-ui'; + +const CodeExample = () => { + const { dashboard } = useGetDashboardModel({ + dashboardOid: '65a82171719e7f004018691c', + includeFilters: true, + includeWidgets: true, + }); + + return ( + <> + {dashboard && ( + + )} + + ); +}; + +export default CodeExample; + * ``` + * * @group Fusion Embed * @fusionEmbed * @alpha diff --git a/packages/sdk-ui/src/decorators/component-decorators/as-sisense-component.tsx b/packages/sdk-ui/src/decorators/component-decorators/as-sisense-component.tsx index c1b40093..9261694a 100644 --- a/packages/sdk-ui/src/decorators/component-decorators/as-sisense-component.tsx +++ b/packages/sdk-ui/src/decorators/component-decorators/as-sisense-component.tsx @@ -1,5 +1,5 @@ import type { FunctionComponent } from 'react'; -import flow from 'lodash/flow'; +import flow from 'lodash-es/flow'; import { withTracking } from './with-tracking'; import { withErrorBoundary } from './with-error-boundary'; import { withSisenseContextValidation } from './with-sisense-context-validation'; diff --git a/packages/sdk-ui/src/decorators/component-decorators/with-sisense-context-validation.tsx b/packages/sdk-ui/src/decorators/component-decorators/with-sisense-context-validation.tsx index 0238588f..d53c59f0 100644 --- a/packages/sdk-ui/src/decorators/component-decorators/with-sisense-context-validation.tsx +++ b/packages/sdk-ui/src/decorators/component-decorators/with-sisense-context-validation.tsx @@ -1,5 +1,5 @@ -import isBoolean from 'lodash/isBoolean'; -import isFunction from 'lodash/isFunction'; +import isBoolean from 'lodash-es/isBoolean'; +import isFunction from 'lodash-es/isFunction'; import { ComponentDecorator, SisenseComponentConfig } from './as-sisense-component'; import { TranslatableError } from '../../translation/translatable-error'; import { useSisenseContext } from '../../sisense-context/sisense-context'; diff --git a/packages/sdk-ui/src/decorators/component-decorators/with-tracking/with-tracking.tsx b/packages/sdk-ui/src/decorators/component-decorators/with-tracking/with-tracking.tsx index aa7f2d27..4cc0aa78 100644 --- a/packages/sdk-ui/src/decorators/component-decorators/with-tracking/with-tracking.tsx +++ b/packages/sdk-ui/src/decorators/component-decorators/with-tracking/with-tracking.tsx @@ -1,7 +1,7 @@ import { useTrackComponentInit, TrackingContextProvider } from './use-track-component-init'; import { ComponentDecorator } from '../as-sisense-component'; -import isBoolean from 'lodash/isBoolean'; -import isFunction from 'lodash/isFunction'; +import isBoolean from 'lodash-es/isBoolean'; +import isFunction from 'lodash-es/isFunction'; import { ErrorTracker } from './error-tracker'; import { useTracking } from '@/common/hooks/use-tracking'; diff --git a/packages/sdk-ui/src/dynamic-size-container/dynamic-size-container.tsx b/packages/sdk-ui/src/dynamic-size-container/dynamic-size-container.tsx index cf5f460b..85d09927 100644 --- a/packages/sdk-ui/src/dynamic-size-container/dynamic-size-container.tsx +++ b/packages/sdk-ui/src/dynamic-size-container/dynamic-size-container.tsx @@ -1,6 +1,6 @@ /* eslint-disable complexity */ import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'; -import isEqual from 'lodash/isEqual'; +import isEqual from 'lodash-es/isEqual'; export type ContainerSize = { width: number; diff --git a/packages/sdk-ui/src/filters/components/custom-filter-tile.tsx b/packages/sdk-ui/src/filters/components/custom-filter-tile.tsx index 90c80291..f3731462 100644 --- a/packages/sdk-ui/src/filters/components/custom-filter-tile.tsx +++ b/packages/sdk-ui/src/filters/components/custom-filter-tile.tsx @@ -1,6 +1,6 @@ import { Filter } from '@sisense/sdk-data'; import { FilterTile, FilterTileDesignOptions } from './filter-tile'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { useTranslation } from 'react-i18next'; import { asSisenseComponent } from '@/decorators/component-decorators/as-sisense-component'; diff --git a/packages/sdk-ui/src/filters/components/filters-panel/filters-panel.tsx b/packages/sdk-ui/src/filters/components/filters-panel/filters-panel.tsx index 566bec21..f8baa7d7 100644 --- a/packages/sdk-ui/src/filters/components/filters-panel/filters-panel.tsx +++ b/packages/sdk-ui/src/filters/components/filters-panel/filters-panel.tsx @@ -6,7 +6,7 @@ import { useThemeContext } from '@/theme-provider'; import { asSisenseComponent } from '@/decorators/component-decorators/as-sisense-component'; const PanelWrapper = styled.div` - background-color: ${({ theme }) => theme.chart.backgroundColor}; + background-color: ${({ theme }) => theme.filter.panel.backgroundColor}; border: 1px solid #dadada; width: fit-content; min-width: 240px; @@ -20,7 +20,7 @@ const PanelBody = styled.div` const PanelHeader = styled.div` background-color: transparent; - color: ${({ theme }) => theme.typography.primaryTextColor}; + color: ${({ theme }) => theme.filter.panel.titleColor}; margin: 0 9px; height: 48px; border-bottom: 1px solid #dadada; diff --git a/packages/sdk-ui/src/filters/components/member-filter-tile/basic-member-filter-tile.tsx b/packages/sdk-ui/src/filters/components/member-filter-tile/basic-member-filter-tile.tsx index fcb28045..46476b75 100644 --- a/packages/sdk-ui/src/filters/components/member-filter-tile/basic-member-filter-tile.tsx +++ b/packages/sdk-ui/src/filters/components/member-filter-tile/basic-member-filter-tile.tsx @@ -5,7 +5,7 @@ import { useMembers } from './use-members'; import { FilterTile } from '../filter-tile'; import { Member, SelectedMember } from './members-reducer'; import { useValidatedMembers } from './use-validate-members'; -import isEqual from 'lodash/isEqual'; +import isEqual from 'lodash-es/isEqual'; /** * Props for {@link BasicMemberFilterTile} diff --git a/packages/sdk-ui/src/filters/components/member-filter-tile/member-filter-tile.tsx b/packages/sdk-ui/src/filters/components/member-filter-tile/member-filter-tile.tsx index 58a9eab5..c6512d73 100644 --- a/packages/sdk-ui/src/filters/components/member-filter-tile/member-filter-tile.tsx +++ b/packages/sdk-ui/src/filters/components/member-filter-tile/member-filter-tile.tsx @@ -7,7 +7,7 @@ import { FilterTile, FilterTileDesignOptions } from '../filter-tile'; import { useSynchronizedFilter } from '@/filters/hooks/use-synchronized-filter'; import { PillSection } from './pill-section'; import { MemberList } from './member-list'; -import merge from 'lodash/merge'; +import merge from 'lodash-es/merge'; import { cloneFilterAndToggleDisabled } from '@/utils/filters'; /** diff --git a/packages/sdk-ui/src/filters/components/member-filter-tile/member-list.tsx b/packages/sdk-ui/src/filters/components/member-filter-tile/member-list.tsx index 21989b4c..a539e554 100644 --- a/packages/sdk-ui/src/filters/components/member-filter-tile/member-list.tsx +++ b/packages/sdk-ui/src/filters/components/member-filter-tile/member-list.tsx @@ -1,4 +1,4 @@ -import debounce from 'lodash/debounce'; +import debounce from 'lodash-es/debounce'; import { FunctionComponent, useMemo, useState } from 'react'; import { Checkbox } from '../common'; import { Member, SelectedMember } from './members-reducer'; diff --git a/packages/sdk-ui/src/filters/components/member-filter-tile/use-members.ts b/packages/sdk-ui/src/filters/components/member-filter-tile/use-members.ts index db694c33..e39df672 100644 --- a/packages/sdk-ui/src/filters/components/member-filter-tile/use-members.ts +++ b/packages/sdk-ui/src/filters/components/member-filter-tile/use-members.ts @@ -1,5 +1,5 @@ import { useEffect, useMemo, useReducer, useRef } from 'react'; -import isEqual from 'lodash/isEqual'; +import isEqual from 'lodash-es/isEqual'; import { Member, membersReducer } from './members-reducer'; interface Props { diff --git a/packages/sdk-ui/src/highcharts-memorized.tsx b/packages/sdk-ui/src/highcharts-memorized.tsx index e904fada..6e994f60 100644 --- a/packages/sdk-ui/src/highcharts-memorized.tsx +++ b/packages/sdk-ui/src/highcharts-memorized.tsx @@ -1,7 +1,7 @@ import { memo, useCallback } from 'react'; -import isEqualWith from 'lodash/isEqualWith'; -import isFunction from 'lodash/isFunction'; -import cloneDeep from 'lodash/cloneDeep'; +import isEqualWith from 'lodash-es/isEqualWith'; +import isFunction from 'lodash-es/isFunction'; +import cloneDeep from 'lodash-es/cloneDeep'; import Highcharts from '@sisense/sisense-charts'; import HighchartsReact from 'highcharts-react-official'; import { HighchartsEventOptions } from './chart-options-processor/apply-event-handlers'; diff --git a/packages/sdk-ui/src/index.ts b/packages/sdk-ui/src/index.ts index 595085d8..112fa346 100644 --- a/packages/sdk-ui/src/index.ts +++ b/packages/sdk-ui/src/index.ts @@ -79,6 +79,7 @@ export { type CommonFiltersApplyMode, type FiltersIgnoringRules, } from './models'; +export type { AutoZoomNavigatorScrollerLocation } from './dashboard-widget/types'; export { boxWhiskerProcessResult } from './boxplot-utils'; export { queryStateReducer } from './query-execution/query-state-reducer'; @@ -90,6 +91,9 @@ export * from './formulas'; export { trackHook } from './decorators/hook-decorators'; export * from './common/hooks/data-load-state-reducer'; export { createDataOptionsFromPanels } from './dashboard-widget/translate-widget-data-options'; +export { type DashboardDto } from './api/types/dashboard-dto'; +export { type WidgetDto } from './dashboard-widget/types'; +export { extractCombinedFilters } from './dashboard-widget/translate-dashboard-filters'; export { useThemeContext } from './theme-provider'; export { LoadingIndicator } from './common/components/loading-indicator'; export { LoadingOverlay } from './common/components/loading-overlay'; diff --git a/packages/sdk-ui/src/models/dashboard/__snapshots__/dashboard-model.test.ts.snap b/packages/sdk-ui/src/models/dashboard/__snapshots__/dashboard-model.test.ts.snap index 29d906ba..20b2c68e 100644 --- a/packages/sdk-ui/src/models/dashboard/__snapshots__/dashboard-model.test.ts.snap +++ b/packages/sdk-ui/src/models/dashboard/__snapshots__/dashboard-model.test.ts.snap @@ -21,7 +21,7 @@ DashboardModel { "members": [ "member", ], - "name": "aa97e8bdf02f3f25dda80a630616a17230ecb913", + "name": "e8e9681675b", "type": "filter", }, ], diff --git a/packages/sdk-ui/src/models/dashboard/get-dashboard-model.test.ts b/packages/sdk-ui/src/models/dashboard/get-dashboard-model.test.ts index 5122aa51..a55bdc86 100644 --- a/packages/sdk-ui/src/models/dashboard/get-dashboard-model.test.ts +++ b/packages/sdk-ui/src/models/dashboard/get-dashboard-model.test.ts @@ -7,7 +7,7 @@ import { type HttpClient } from '@sisense/sdk-rest-client'; import { sampleEcommerceDashboard as dashboardMock } from '../__mocks__/sample-ecommerce-dashboard'; import { type RestApi } from '../../api/rest-api'; import { WidgetModel } from '../widget'; -import zipObject from 'lodash/zipObject'; +import zipObject from 'lodash-es/zipObject'; const getDashboardMock = vi.fn>(() => { // eslint-disable-next-line no-unused-vars diff --git a/packages/sdk-ui/src/models/dashboard/get-dashboard-models.test.ts b/packages/sdk-ui/src/models/dashboard/get-dashboard-models.test.ts index b2df44a2..a928e9dc 100644 --- a/packages/sdk-ui/src/models/dashboard/get-dashboard-models.test.ts +++ b/packages/sdk-ui/src/models/dashboard/get-dashboard-models.test.ts @@ -10,7 +10,7 @@ import { sampleEcommerceDashboard } from '../__mocks__/sample-ecommerce-dashboar import { sampleHealthcareDashboard } from '../__mocks__/sample-healthcare-dashboard.js'; import { samplePivotDashboard } from '../__mocks__/sample-pivot-dashboard.js'; import { WidgetModel } from '../widget/widget-model.js'; -import zipObject from 'lodash/zipObject'; +import zipObject from 'lodash-es/zipObject'; const dashboardsMock: DashboardDto[] = [ sampleEcommerceDashboard, diff --git a/packages/sdk-ui/src/models/widget/__snapshots__/widget-model.test.ts.snap b/packages/sdk-ui/src/models/widget/__snapshots__/widget-model.test.ts.snap index ff8fb86c..55385b8a 100644 --- a/packages/sdk-ui/src/models/widget/__snapshots__/widget-model.test.ts.snap +++ b/packages/sdk-ui/src/models/widget/__snapshots__/widget-model.test.ts.snap @@ -40,7 +40,7 @@ exports[`WidgetModel > getExecutePivotQueryParams > getChartProps > should retur "name": "Numbers", "prefix": false, "symbol": undefined, - "thousandSeparator": undefined, + "thousandSeparator": true, "trillion": false, }, "sortType": "sortNone", @@ -107,7 +107,7 @@ exports[`WidgetModel > getExecutePivotQueryParams > getChartProps > should retur "sort": 0, "type": "basemeasure", }, - "name": "c4385b7c5e5cd228df086d36ae458779e1a7a768", + "name": "f1b3d268f61", "operator": "top", "type": "filter", }, diff --git a/packages/sdk-ui/src/models/widget/widget-model.ts b/packages/sdk-ui/src/models/widget/widget-model.ts index ee6d054f..f9de1106 100644 --- a/packages/sdk-ui/src/models/widget/widget-model.ts +++ b/packages/sdk-ui/src/models/widget/widget-model.ts @@ -1,6 +1,6 @@ import { getPivotQueryOptions } from '@/pivot-table/hooks/use-get-pivot-table-query'; import { Attribute, Filter, Measure } from '@sisense/sdk-data'; -import { over } from 'lodash'; +import over from 'lodash-es/over'; import { getTranslatedDataOptions } from '../../chart-data-options/get-translated-data-options'; import { translatePivotTableDataOptions, @@ -13,12 +13,12 @@ import { } from '../../chart-data-options/types'; import { extractDataOptions } from '../../dashboard-widget/translate-widget-data-options'; import { extractDrilldownOptions } from '../../dashboard-widget/translate-widget-drilldown-options'; -import { extractFilters } from '../../dashboard-widget/translate-widget-filters'; +import { extractWidgetFilters } from '../../dashboard-widget/translate-widget-filters'; import { extractStyleOptions, getStyleWithWigetDesign, } from '../../dashboard-widget/translate-widget-style-options'; -import { Panel, WidgetDto, WidgetSubtype, WidgetType } from '../../dashboard-widget/types'; +import { Panel, WidgetDto, WidgetType } from '../../dashboard-widget/types'; import { getChartType, isChartWidget, @@ -176,12 +176,7 @@ export class WidgetModel { themeSettings?.palette.variantColors, ); - const styleOptions = extractStyleOptions( - widgetType, - widgetDto.subtype as WidgetSubtype, - widgetDto.style, - widgetDto.metadata.panels, - ); + const styleOptions = extractStyleOptions(widgetType, widgetDto); // take into account widget design style feature flag const isWidgetDesignStyleEnabled = @@ -196,7 +191,7 @@ export class WidgetModel { // does not handle widget type plugin this.drilldownOptions = extractDrilldownOptions(this.widgetType, widgetDto.metadata.panels); - this.filters = extractFilters(widgetDto.metadata.panels); + this.filters = extractWidgetFilters(widgetDto.metadata.panels); this.chartType = isChartWidget(widgetType) ? getChartType(this.widgetType) : undefined; } diff --git a/packages/sdk-ui/src/pivot-table/hooks/use-apply-pivot-table-formatting.ts b/packages/sdk-ui/src/pivot-table/hooks/use-apply-pivot-table-formatting.ts index fc854aba..10bf802e 100644 --- a/packages/sdk-ui/src/pivot-table/hooks/use-apply-pivot-table-formatting.ts +++ b/packages/sdk-ui/src/pivot-table/hooks/use-apply-pivot-table-formatting.ts @@ -5,7 +5,7 @@ import { EVENT_DATA_CELL_FORMAT, EVENT_HEADER_CELL_FORMAT, } from '@sisense/sdk-pivot-client'; -import over from 'lodash/over'; +import over from 'lodash-es/over'; import { type PivotTableDataOptions } from '@/chart-data-options/types'; import { applyDateFormat } from '@/query/date-formats'; import { useSisenseContext } from '@/sisense-context/sisense-context'; diff --git a/packages/sdk-ui/src/pivot-table/hooks/use-get-pivot-table-query.ts b/packages/sdk-ui/src/pivot-table/hooks/use-get-pivot-table-query.ts index 20ac15ac..0c047985 100644 --- a/packages/sdk-ui/src/pivot-table/hooks/use-get-pivot-table-query.ts +++ b/packages/sdk-ui/src/pivot-table/hooks/use-get-pivot-table-query.ts @@ -3,7 +3,7 @@ import { type JaqlRequest } from '@sisense/sdk-pivot-client'; import type { DataSource, Filter, FilterRelations } from '@sisense/sdk-data'; import { normalizePivotSort } from '../sorting-utils'; -import isEqual from 'lodash/isEqual'; +import isEqual from 'lodash-es/isEqual'; import { ExecutePivotQueryParams } from '@/query-execution'; import { translateCategoryToAttribute, translateValueToMeasure } from '@/chart-data-options/utils'; import { Category, PivotTableDataOptionsInternal, Value } from '@/chart-data-options/types'; diff --git a/packages/sdk-ui/src/pivot-table/sorting-utils.ts b/packages/sdk-ui/src/pivot-table/sorting-utils.ts index 0668f443..f3fb4487 100644 --- a/packages/sdk-ui/src/pivot-table/sorting-utils.ts +++ b/packages/sdk-ui/src/pivot-table/sorting-utils.ts @@ -1,8 +1,8 @@ import { getSortType } from '@/dashboard-widget/utils'; import { JaqlSortDirection } from '@sisense/sdk-data'; import { type SortingSettingsChangePayload } from '@sisense/sdk-pivot-client'; -import isEqual from 'lodash/isEqual'; -import isString from 'lodash/isString'; +import isEqual from 'lodash-es/isEqual'; +import isString from 'lodash-es/isString'; import { PivotTableDataOptionsInternal } from '..'; import type { SortDirection, PivotRowsSort } from '../types'; diff --git a/packages/sdk-ui/src/props.tsx b/packages/sdk-ui/src/props.tsx index e79579c7..3e407c1c 100644 --- a/packages/sdk-ui/src/props.tsx +++ b/packages/sdk-ui/src/props.tsx @@ -125,6 +125,15 @@ export interface SisenseContextProviderProps { */ wat?: string | null; + /** + * Flag to delegate authentication to Fusion. + * + * Defaults to `false`. + * + * @category Sisense Authentication + */ + useFusionAuth?: boolean; + /** * Application specific configurations such as locale and date formats. * @@ -151,7 +160,6 @@ export interface SisenseContextProviderProps { * such as incorrect configuration, invalid authentication, or network-related issues. * * @param error - The error object containing details about the issue. - * * @category Sisense App Error Handling */ onError?: (error: Error) => void; diff --git a/packages/sdk-ui/src/query-execution/use-execute-pivot-query.test.ts b/packages/sdk-ui/src/query-execution/use-execute-pivot-query.test.ts index 160f8bf0..dd7e2ea8 100644 --- a/packages/sdk-ui/src/query-execution/use-execute-pivot-query.test.ts +++ b/packages/sdk-ui/src/query-execution/use-execute-pivot-query.test.ts @@ -1,7 +1,7 @@ /** @vitest-environment jsdom */ import { renderHook, waitFor } from '@testing-library/react'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { trackProductEvent } from '@sisense/sdk-tracking'; import { executePivotQueryMock } from '../query/__mocks__/execute-query'; import type { Mock } from 'vitest'; diff --git a/packages/sdk-ui/src/query-execution/use-execute-query-by-widget-id.test.ts b/packages/sdk-ui/src/query-execution/use-execute-query-by-widget-id.test.ts index e9cedc41..3079965a 100644 --- a/packages/sdk-ui/src/query-execution/use-execute-query-by-widget-id.test.ts +++ b/packages/sdk-ui/src/query-execution/use-execute-query-by-widget-id.test.ts @@ -1,7 +1,7 @@ /** @vitest-environment jsdom */ import { renderHook, waitFor } from '@testing-library/react'; import type { Mock } from 'vitest'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { QueryResultData, filterFactory, diff --git a/packages/sdk-ui/src/query/query-result-date-formatting.test.ts b/packages/sdk-ui/src/query/query-result-date-formatting.test.ts index 4d0bb0e3..78a78992 100644 --- a/packages/sdk-ui/src/query/query-result-date-formatting.test.ts +++ b/packages/sdk-ui/src/query/query-result-date-formatting.test.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { applyDateFormats } from './query-result-date-formatting'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import type { Cell, QueryResultData } from '@sisense/sdk-data'; describe('applyDateFormats', () => { diff --git a/packages/sdk-ui/src/sisense-context/sisense-context-provider.tsx b/packages/sdk-ui/src/sisense-context/sisense-context-provider.tsx index 523a4e76..2e328c2f 100644 --- a/packages/sdk-ui/src/sisense-context/sisense-context-provider.tsx +++ b/packages/sdk-ui/src/sisense-context/sisense-context-provider.tsx @@ -55,6 +55,7 @@ export const SisenseContextProvider: FunctionComponent< enableTracking = true, showRuntimeErrors = true, enableSilentPreAuth = false, + useFusionAuth = false, onError, }) => { const tracking = { @@ -89,6 +90,7 @@ export const SisenseContextProvider: FunctionComponent< ssoEnabled, appConfig, enableSilentPreAuth, + useFusionAuth, }) .then((newApp) => { if (!ignore) { @@ -104,7 +106,17 @@ export const SisenseContextProvider: FunctionComponent< return () => { ignore = true; }; - }, [defaultDataSource, url, token, wat, ssoEnabled, appConfig, enableSilentPreAuth, onError]); + }, [ + defaultDataSource, + url, + token, + wat, + ssoEnabled, + appConfig, + enableSilentPreAuth, + useFusionAuth, + onError, + ]); return ( diff --git a/packages/sdk-ui/src/theme-provider/default-theme-settings.ts b/packages/sdk-ui/src/theme-provider/default-theme-settings.ts index 48befb79..000be815 100644 --- a/packages/sdk-ui/src/theme-provider/default-theme-settings.ts +++ b/packages/sdk-ui/src/theme-provider/default-theme-settings.ts @@ -1,6 +1,6 @@ /* eslint-disable sonarjs/no-duplicate-string */ import { CompleteThemeSettings } from '@/types'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; export const DEFAULT_DIVIDER_COLOR = '#F2F2F2'; export const DEFAULT_DIVIDER_WIDTH = 4; @@ -53,6 +53,12 @@ const DEFAULT_THEME_SETTINGS_LIGHT: CompleteThemeSettings = { dividerLineWidth: DEFAULT_DIVIDER_WIDTH, dividerLineColor: DEFAULT_DIVIDER_COLOR, }, + filter: { + panel: { + titleColor: '#5B6372', + backgroundColor: '#F6F6F6', + }, + }, aiChat: { backgroundColor: 'rgba(244, 244, 248, 1)', primaryTextColor: 'rgba(38, 46, 61, 0.8)', @@ -198,6 +204,12 @@ const DEFAULT_THEME_SETTINGS_DARK: CompleteThemeSettings = { dividerLineWidth: DEFAULT_DIVIDER_WIDTH, dividerLineColor: DEFAULT_DIVIDER_COLOR, }, + filter: { + panel: { + titleColor: '#FFFFFF', + backgroundColor: '#313138', + }, + }, aiChat: { backgroundColor: 'rgba(23, 28, 38, 1)', primaryTextColor: 'rgba(242, 247, 255, 0.9)', diff --git a/packages/sdk-ui/src/theme-provider/use-theme-settings.ts b/packages/sdk-ui/src/theme-provider/use-theme-settings.ts index 0fa50234..9b4e1b0e 100644 --- a/packages/sdk-ui/src/theme-provider/use-theme-settings.ts +++ b/packages/sdk-ui/src/theme-provider/use-theme-settings.ts @@ -1,4 +1,4 @@ -import isEqual from 'lodash/isEqual'; +import isEqual from 'lodash-es/isEqual'; import merge from 'ts-deepmerge'; import { useState, useEffect } from 'react'; import { ThemeOid, ThemeSettings, isThemeOid, CompleteThemeSettings } from '../types'; diff --git a/packages/sdk-ui/src/themes/__mocks__/legacy-design-settings.mock.ts b/packages/sdk-ui/src/themes/__mocks__/legacy-design-settings.mock.ts index 77b0ad71..ca4bbc80 100644 --- a/packages/sdk-ui/src/themes/__mocks__/legacy-design-settings.mock.ts +++ b/packages/sdk-ui/src/themes/__mocks__/legacy-design-settings.mock.ts @@ -60,7 +60,7 @@ export const redThemeSettings: CompleteThemeSettings = { textColor: '#FFFFFF', backgroundColor: '#ec4646', secondaryTextColor: '#C5C8CF', - panelBackgroundColor: '#313138', + panelBackgroundColor: '#ec4646', animation: { init: { duration: 'auto', @@ -103,6 +103,12 @@ export const redThemeSettings: CompleteThemeSettings = { dividerLineColor: '#F2F2F2', dividerLineWidth: 4, }, + filter: { + panel: { + backgroundColor: '#313138', + titleColor: '#FFFFFF', + }, + }, aiChat: { backgroundColor: 'rgba(244, 244, 248, 1)', primaryTextColor: 'rgba(38, 46, 61, 0.8)', diff --git a/packages/sdk-ui/src/themes/legacy-design-settings.ts b/packages/sdk-ui/src/themes/legacy-design-settings.ts index 36a7175f..1002efa4 100644 --- a/packages/sdk-ui/src/themes/legacy-design-settings.ts +++ b/packages/sdk-ui/src/themes/legacy-design-settings.ts @@ -123,7 +123,7 @@ export function convertToThemeSettings( textColor: legacyDesignSettings.dashboards.widgetTextColor, backgroundColor: legacyDesignSettings.dashboards.widgetBackgroundColor, secondaryTextColor: legacyDesignSettings.dashboards.widgetSecondaryTextColor, - panelBackgroundColor: legacyDesignSettings.dashboards.panelBackgroundColor, + panelBackgroundColor: legacyDesignSettings.dashboards.widgetBackgroundColor, animation: { init: { duration: 'auto', @@ -170,6 +170,12 @@ export function convertToThemeSettings( dividerLineWidth: DEFAULT_DIVIDER_WIDTH, dividerLineColor: DEFAULT_DIVIDER_COLOR, }, + filter: { + panel: { + titleColor: legacyDesignSettings.dashboards.panelTitleTextColor, + backgroundColor: legacyDesignSettings.dashboards.panelBackgroundColor, + }, + }, }; return merge.withOptions({ mergeArrays: false }, getDefaultThemeSettings(), themeSettings); } diff --git a/packages/sdk-ui/src/translation/resources/en.ts b/packages/sdk-ui/src/translation/resources/en.ts index 1d406500..e890890d 100644 --- a/packages/sdk-ui/src/translation/resources/en.ts +++ b/packages/sdk-ui/src/translation/resources/en.ts @@ -105,6 +105,16 @@ export const translation = { forecastValue: 'Forecast Value', forecast: 'Forecast', trend: 'Trend', + trendLocalValue: 'Local Value', + confidenceInterval: 'Confidence Interval', + trendType: 'Type', + trendDataKey: 'Trend Data', + trendData: { + min: 'Min', + max: 'Max', + median: 'Median', + average: 'Average', + }, }, }, arearange: { diff --git a/packages/sdk-ui/src/translation/resources/uk.ts b/packages/sdk-ui/src/translation/resources/uk.ts index e0ac4ac1..373f0694 100644 --- a/packages/sdk-ui/src/translation/resources/uk.ts +++ b/packages/sdk-ui/src/translation/resources/uk.ts @@ -106,6 +106,16 @@ export const translation: TranslationDictionary = { forecastValue: 'Forecast Value', forecast: 'Forecast', trend: 'Trend', + trendLocalValue: 'Local Value', + confidenceInterval: 'Confidence Interval', + trendType: 'Type', + trendDataKey: 'Trend Data', + trendData: { + min: 'Min', + max: 'Max', + median: 'Median', + average: 'Average', + }, }, }, arearange: { diff --git a/packages/sdk-ui/src/types.ts b/packages/sdk-ui/src/types.ts index 1d0a88b9..3bee4909 100644 --- a/packages/sdk-ui/src/types.ts +++ b/packages/sdk-ui/src/types.ts @@ -1,3 +1,4 @@ +import { AutoZoomNavigatorScrollerLocation } from './dashboard-widget/types'; /* eslint-disable max-lines */ import type { Attribute, MembersFilter } from '@sisense/sdk-data'; import { DeepRequired } from 'ts-essentials'; @@ -100,6 +101,7 @@ export type Components = { export type Navigator = { /** Boolean flag that defines if navigator should be shown on the chart */ enabled: boolean; + scrollerLocation?: AutoZoomNavigatorScrollerLocation; }; /** Configuration that defines line width */ @@ -798,7 +800,11 @@ export interface ChartThemeSettings { secondaryTextColor?: string; /** Background color */ backgroundColor?: string; - /** Toolbar Background color, can be used as a secondary background color */ + /** + * Toolbar Background color, can be used as a secondary background color + * + * @deprecated + * */ panelBackgroundColor?: string; /** Animation options */ animation?: { @@ -1081,6 +1087,18 @@ export type DashboardThemeSettings = { dividerLineColor?: string; }; +/** + * Filter theme settings + */ +export type FilterThemeSettings = { + panel: { + /** Title color */ + titleColor?: string; + /** Background color */ + backgroundColor?: string; + }; +}; + /** Theme settings defining the look and feel of components. */ export interface ThemeSettings { /** Chart theme settings */ @@ -1105,6 +1123,9 @@ export interface ThemeSettings { */ dashboard?: DashboardThemeSettings; + /** Filter theme settings */ + filter?: FilterThemeSettings; + /** * Theme settings specific to the AI Chatbot component */ diff --git a/packages/sdk-ui/src/utils/check-and-notify-about-deprecated-prop.ts b/packages/sdk-ui/src/utils/check-and-notify-about-deprecated-prop.ts index ac84b2a7..f3dcd6c0 100644 --- a/packages/sdk-ui/src/utils/check-and-notify-about-deprecated-prop.ts +++ b/packages/sdk-ui/src/utils/check-and-notify-about-deprecated-prop.ts @@ -1,4 +1,4 @@ -import has from 'lodash/has'; +import has from 'lodash-es/has'; export function checkAndNotifyAboutDeprecatedProp(props: any, deprecatedProps: string[]): void { for (const deprecatedProp of deprecatedProps) { diff --git a/packages/sdk-ui/src/utils/combine-handlers.ts b/packages/sdk-ui/src/utils/combine-handlers.ts index 55dfbe07..0bd1d791 100644 --- a/packages/sdk-ui/src/utils/combine-handlers.ts +++ b/packages/sdk-ui/src/utils/combine-handlers.ts @@ -1,6 +1,6 @@ -import isFunction from 'lodash/isFunction'; -import flow from 'lodash/flow'; -import over from 'lodash/over'; +import isFunction from 'lodash-es/isFunction'; +import flow from 'lodash-es/flow'; +import over from 'lodash-es/over'; type AnyFunction = (...args: any[]) => any; diff --git a/packages/sdk-ui/src/utils/filters-comparator.ts b/packages/sdk-ui/src/utils/filters-comparator.ts index 342736c5..9065e9b5 100644 --- a/packages/sdk-ui/src/utils/filters-comparator.ts +++ b/packages/sdk-ui/src/utils/filters-comparator.ts @@ -6,8 +6,8 @@ import { FilterRelationsJaqlIdNode, FilterRelationsJaqlNode, } from '@sisense/sdk-data'; -import isEqual from 'lodash/isEqual'; -import isEqualWith from 'lodash/isEqualWith'; +import isEqual from 'lodash-es/isEqual'; +import isEqualWith from 'lodash-es/isEqualWith'; /** * Checks if the filters have changed by deep comparison. diff --git a/packages/sdk-ui/src/utils/filters.ts b/packages/sdk-ui/src/utils/filters.ts index 216ece27..917d3c81 100644 --- a/packages/sdk-ui/src/utils/filters.ts +++ b/packages/sdk-ui/src/utils/filters.ts @@ -6,7 +6,7 @@ import { filterFactory, MembersFilter, } from '@sisense/sdk-data'; -import { cloneDeep } from 'lodash'; +import cloneDeep from 'lodash-es/cloneDeep.js'; export function isCascadingFilter(filter: Filter): filter is CascadingFilter { return filter instanceof CascadingFilter; diff --git a/packages/sdk-ui/src/widgets/chart-widget.test.tsx b/packages/sdk-ui/src/widgets/chart-widget.test.tsx index 6359f610..7aad56af 100644 --- a/packages/sdk-ui/src/widgets/chart-widget.test.tsx +++ b/packages/sdk-ui/src/widgets/chart-widget.test.tsx @@ -1,7 +1,7 @@ /** @vitest-environment jsdom */ import { render } from '@testing-library/react'; import { measureFactory } from '@sisense/sdk-data'; -import cloneDeep from 'lodash/cloneDeep'; +import cloneDeep from 'lodash-es/cloneDeep'; import { mockChartWidgetPropsForTable, mockResolvedQuery } from './__mocks__/mocks'; import { useSisenseContextMock } from '../sisense-context/__mocks__/sisense-context'; import { ClientApplication } from '../app/client-application'; diff --git a/packages/sdk-ui/src/widgets/chart-widget.tsx b/packages/sdk-ui/src/widgets/chart-widget.tsx index d0f57c58..6e5f6518 100644 --- a/packages/sdk-ui/src/widgets/chart-widget.tsx +++ b/packages/sdk-ui/src/widgets/chart-widget.tsx @@ -60,7 +60,6 @@ export const ChartWidget: FunctionComponent = asSisenseCompone const defaultSize = getWidgetDefaultSize(chartType, { hasHeader: !styleOptions?.header?.hidden, }); - const [refreshCounter, setRefreshCounter] = useState(0); const isDrilldownEnabled = useMemo(() => { diff --git a/packages/sdk-ui/src/widgets/common/drilldown-breadcrumbs/use-theme-for-breadcrumbs.tsx b/packages/sdk-ui/src/widgets/common/drilldown-breadcrumbs/use-theme-for-breadcrumbs.tsx index cfb27ad7..482fe1c6 100644 --- a/packages/sdk-ui/src/widgets/common/drilldown-breadcrumbs/use-theme-for-breadcrumbs.tsx +++ b/packages/sdk-ui/src/widgets/common/drilldown-breadcrumbs/use-theme-for-breadcrumbs.tsx @@ -6,14 +6,11 @@ export const useThemeForBreadcrumbs = () => { themeSettings: { typography: { primaryTextColor, secondaryTextColor, fontFamily }, general: { backgroundColor, brandColor, primaryButtonTextColor }, - chart: { backgroundColor: chartBackgroundColor, panelBackgroundColor }, + chart: { backgroundColor: chartBackgroundColor }, }, } = useThemeContext(); - const activeDrillBackgroundColor: string = - panelBackgroundColor != chartBackgroundColor - ? panelBackgroundColor - : darken(panelBackgroundColor, 0.3); - const activeDrillHoverBackgroundColor = darken(activeDrillBackgroundColor, 0.1); + const activeDrillBackgroundColor: string = darken(chartBackgroundColor, 0.02); + const activeDrillHoverBackgroundColor = darken(activeDrillBackgroundColor, 0.05); return { primaryTextColor, secondaryTextColor, diff --git a/packages/sdk-ui/src/widgets/common/drilldown-connector.ts b/packages/sdk-ui/src/widgets/common/drilldown-connector.ts index 85d0a725..43fb7895 100644 --- a/packages/sdk-ui/src/widgets/common/drilldown-connector.ts +++ b/packages/sdk-ui/src/widgets/common/drilldown-connector.ts @@ -18,7 +18,7 @@ import { getSelectableWidgetAttributes } from '@/common-filters/selection-utils' import { ChartProps, CustomDrilldownResult, ScatterDataPoint, isMeasureColumn } from '../..'; import { PointClickEventObject } from '@sisense/sisense-charts'; import { ScatterCustomPointOptions } from '@/chart-options-processor/translations/scatter-tooltip'; -import camelCase from 'lodash/camelCase'; +import camelCase from 'lodash-es/camelCase'; export function getDrilldownInitialDimension(chartType: ChartType, dataOptions: ChartDataOptions) { return getSelectableWidgetAttributes(chartType, dataOptions)[0]; diff --git a/packages/sdk-ui/src/widgets/common/widget-container.tsx b/packages/sdk-ui/src/widgets/common/widget-container.tsx index b720b849..3c700d2d 100644 --- a/packages/sdk-ui/src/widgets/common/widget-container.tsx +++ b/packages/sdk-ui/src/widgets/common/widget-container.tsx @@ -3,7 +3,7 @@ import { ThemeProvider, useThemeContext } from '../../theme-provider'; import { WidgetContainerStyleOptions } from '../../types'; import { getShadowValue, WidgetCornerRadius, WidgetSpaceAround } from './widget-style-utils'; import { WidgetHeader } from './widget-header'; -import get from 'lodash/get'; +import get from 'lodash-es/get'; interface WidgetContainerProps { dataSetName?: string; diff --git a/packages/sdk-ui/src/widgets/common/widget-header.tsx b/packages/sdk-ui/src/widgets/common/widget-header.tsx index ad9515d8..712ce9d4 100644 --- a/packages/sdk-ui/src/widgets/common/widget-header.tsx +++ b/packages/sdk-ui/src/widgets/common/widget-header.tsx @@ -2,7 +2,7 @@ import Divider from '@mui/material/Divider'; import { useThemeContext } from '../../theme-provider'; import { AlignmentTypes, WidgetContainerStyleOptions } from '../../types'; import WidgetHeaderInfoButton from './widget-header-info-button'; -import get from 'lodash/get'; +import get from 'lodash-es/get'; interface WidgetHeaderProps { onRefresh: () => void; diff --git a/packages/sdk-ui/src/widgets/common/widget-style-utils.ts b/packages/sdk-ui/src/widgets/common/widget-style-utils.ts index 8346170c..79efb19e 100644 --- a/packages/sdk-ui/src/widgets/common/widget-style-utils.ts +++ b/packages/sdk-ui/src/widgets/common/widget-style-utils.ts @@ -1,4 +1,4 @@ -import get from 'lodash/get'; +import get from 'lodash-es/get'; import { CompleteThemeSettings, WidgetContainerStyleOptions } from '../../types'; export enum WidgetCornerRadius { diff --git a/yarn.lock b/yarn.lock index 6ff30249..b98b1aa7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5513,12 +5513,12 @@ __metadata: resolution: "@sisense/sdk-cli@workspace:packages/sdk-cli" dependencies: "@babel/preset-env": ^7.20.2 - "@sisense/sdk-common": ^1.17.1 - "@sisense/sdk-data": ^1.17.1 - "@sisense/sdk-modeling": ^1.17.1 - "@sisense/sdk-query-client": ^1.17.1 - "@sisense/sdk-rest-client": ^1.17.1 - "@sisense/sdk-tracking": ^1.17.1 + "@sisense/sdk-common": ^1.18.0 + "@sisense/sdk-data": ^1.18.0 + "@sisense/sdk-modeling": ^1.18.0 + "@sisense/sdk-query-client": ^1.18.0 + "@sisense/sdk-rest-client": ^1.18.0 + "@sisense/sdk-tracking": ^1.18.0 "@types/inquirer": 8.2.6 "@types/js-levenshtein": ^1.1.3 "@types/yargs": ^17.0.22 @@ -5536,7 +5536,7 @@ __metadata: languageName: unknown linkType: soft -"@sisense/sdk-common@^1.17.1, @sisense/sdk-common@workspace:packages/sdk-common": +"@sisense/sdk-common@^1.18.0, @sisense/sdk-common@workspace:packages/sdk-common": version: 0.0.0-use.local resolution: "@sisense/sdk-common@workspace:packages/sdk-common" dependencies: @@ -5546,39 +5546,38 @@ __metadata: languageName: unknown linkType: soft -"@sisense/sdk-data@^1.17.1, @sisense/sdk-data@workspace:^, @sisense/sdk-data@workspace:packages/sdk-data": +"@sisense/sdk-data@^1.18.0, @sisense/sdk-data@workspace:^, @sisense/sdk-data@workspace:packages/sdk-data": version: 0.0.0-use.local resolution: "@sisense/sdk-data@workspace:packages/sdk-data" dependencies: "@babel/preset-env": ^7.20.2 - "@sisense/sdk-common": ^1.17.1 - "@sisense/sdk-rest-client": ^1.17.1 + "@sisense/sdk-common": ^1.18.0 + "@sisense/sdk-rest-client": ^1.18.0 "@types/lodash": ^4.14.201 "@types/numeral": 2.0.2 - "@types/object-hash": ^3.0.5 eslint: ^8.40.0 guid-typescript: ^1.0.9 - lodash: ^4.17.21 + hash-it: ^6.0.0 + lodash-es: ^4.17.21 numeral: ^2.0.6 - object-hash: ^3.0.0 prettier: 2.8.4 typescript: 4.8.4 languageName: unknown linkType: soft -"@sisense/sdk-modeling@^1.17.1, @sisense/sdk-modeling@workspace:packages/sdk-modeling": +"@sisense/sdk-modeling@^1.18.0, @sisense/sdk-modeling@workspace:packages/sdk-modeling": version: 0.0.0-use.local resolution: "@sisense/sdk-modeling@workspace:packages/sdk-modeling" dependencies: "@babel/preset-env": ^7.20.2 - "@sisense/sdk-data": ^1.17.1 + "@sisense/sdk-data": ^1.18.0 eslint: ^8.40.0 prettier: ^3.2.5 typescript: 4.8.4 languageName: unknown linkType: soft -"@sisense/sdk-pivot-client@^1.17.1, @sisense/sdk-pivot-client@workspace:packages/sdk-pivot-client": +"@sisense/sdk-pivot-client@^1.18.0, @sisense/sdk-pivot-client@workspace:packages/sdk-pivot-client": version: 0.0.0-use.local resolution: "@sisense/sdk-pivot-client@workspace:packages/sdk-pivot-client" dependencies: @@ -5586,9 +5585,9 @@ __metadata: "@emotion/react": ^11.11.4 "@emotion/styled": ^11.11.5 "@mui/material": ^5.11.6 - "@sisense/sdk-data": ^1.17.1 - "@sisense/sdk-rest-client": ^1.17.1 - "@types/lodash": ^4.14.200 + "@sisense/sdk-data": ^1.18.0 + "@sisense/sdk-rest-client": ^1.18.0 + "@types/lodash-es": ^4.17.12 "@types/react": ^18.3.1 "@types/react-custom-scrollbars": ^4.0.13 "@types/react-dom": ^18.3.0 @@ -5598,7 +5597,7 @@ __metadata: dom-css: 2.1.0 eslint: ^8.40.0 immer: ^10.0.2 - lodash: ^4.17.21 + lodash-es: ^4.17.21 prettier: 2.8.4 raf: 3.4.0 rc-tooltip: ^6.2.0 @@ -5622,14 +5621,14 @@ __metadata: languageName: unknown linkType: soft -"@sisense/sdk-query-client@^1.17.1, @sisense/sdk-query-client@workspace:packages/sdk-query-client": +"@sisense/sdk-query-client@^1.18.0, @sisense/sdk-query-client@workspace:packages/sdk-query-client": version: 0.0.0-use.local resolution: "@sisense/sdk-query-client@workspace:packages/sdk-query-client" dependencies: - "@sisense/sdk-common": ^1.17.1 - "@sisense/sdk-data": ^1.17.1 - "@sisense/sdk-pivot-client": ^1.17.1 - "@sisense/sdk-rest-client": ^1.17.1 + "@sisense/sdk-common": ^1.18.0 + "@sisense/sdk-data": ^1.18.0 + "@sisense/sdk-pivot-client": ^1.18.0 + "@sisense/sdk-rest-client": ^1.18.0 "@sisense/task-manager": ^0.1.0 "@types/tar": ^6.1.4 "@types/uuid": ^9.0.0 @@ -5646,12 +5645,12 @@ __metadata: languageName: unknown linkType: soft -"@sisense/sdk-rest-client@^1.17.1, @sisense/sdk-rest-client@workspace:^, @sisense/sdk-rest-client@workspace:packages/sdk-rest-client": +"@sisense/sdk-rest-client@^1.18.0, @sisense/sdk-rest-client@workspace:^, @sisense/sdk-rest-client@workspace:packages/sdk-rest-client": version: 0.0.0-use.local resolution: "@sisense/sdk-rest-client@workspace:packages/sdk-rest-client" dependencies: "@babel/preset-env": ^7.20.2 - "@sisense/sdk-common": ^1.17.1 + "@sisense/sdk-common": ^1.18.0 eslint: ^8.40.0 fetch-intercept: ^2.4.0 prettier: 2.8.4 @@ -5659,7 +5658,7 @@ __metadata: languageName: unknown linkType: soft -"@sisense/sdk-tracking@^1.17.1, @sisense/sdk-tracking@workspace:^, @sisense/sdk-tracking@workspace:packages/sdk-tracking": +"@sisense/sdk-tracking@^1.18.0, @sisense/sdk-tracking@workspace:^, @sisense/sdk-tracking@workspace:packages/sdk-tracking": version: 0.0.0-use.local resolution: "@sisense/sdk-tracking@workspace:packages/sdk-tracking" dependencies: @@ -5704,7 +5703,7 @@ __metadata: dependencies: "@preact/preset-vite": 2.5.0 "@sisense/sdk-data": "workspace:^" - "@sisense/sdk-ui": ^1.17.1 + "@sisense/sdk-ui": ^1.18.0 "@types/node": ^18.16.0 eslint: ^8.40.0 preact: ^10.13.2 @@ -5722,7 +5721,7 @@ __metadata: dependencies: "@rushstack/eslint-patch": ^1.2.0 "@sisense/sdk-ui-preact": "workspace:^" - "@types/lodash": ^4.14.194 + "@types/lodash-es": ^4.17.12 "@types/node": ^18.14.2 "@vitejs/plugin-vue": ^4.0.0 "@vue/eslint-config-prettier": ^7.1.0 @@ -5731,7 +5730,7 @@ __metadata: deepmerge: ^4.3.1 eslint: ^8.40.0 eslint-plugin-vue: ^9.9.0 - lodash: ^4.17.21 + lodash-es: ^4.17.21 npm-run-all: ^4.1.5 prettier: ^2.8.4 typescript: ~4.8.4 @@ -5742,7 +5741,7 @@ __metadata: languageName: unknown linkType: soft -"@sisense/sdk-ui@^1.17.1, @sisense/sdk-ui@workspace:^, @sisense/sdk-ui@workspace:packages/sdk-ui": +"@sisense/sdk-ui@^1.18.0, @sisense/sdk-ui@workspace:^, @sisense/sdk-ui@workspace:packages/sdk-ui": version: 0.0.0-use.local resolution: "@sisense/sdk-ui@workspace:packages/sdk-ui" dependencies: @@ -5753,12 +5752,12 @@ __metadata: "@mui/material": ^5.15.16 "@mui/system": ^5.15.15 "@mui/x-data-grid": ^6.16.0 - "@sisense/sdk-common": ^1.17.1 - "@sisense/sdk-data": ^1.17.1 - "@sisense/sdk-pivot-client": ^1.17.1 - "@sisense/sdk-query-client": ^1.17.1 - "@sisense/sdk-rest-client": ^1.17.1 - "@sisense/sdk-tracking": ^1.17.1 + "@sisense/sdk-common": ^1.18.0 + "@sisense/sdk-data": ^1.18.0 + "@sisense/sdk-pivot-client": ^1.18.0 + "@sisense/sdk-query-client": ^1.18.0 + "@sisense/sdk-rest-client": ^1.18.0 + "@sisense/sdk-tracking": ^1.18.0 "@sisense/sisense-charts": 5.1.1 "@storybook/addon-actions": 7.0.24 "@storybook/addon-docs": 7.0.24 @@ -5798,7 +5797,7 @@ __metadata: immer: ^10.0.2 jsdom: ^22.1.0 leaflet: ^1.9.4 - lodash: ^4.17.21 + lodash-es: ^4.17.21 merge-deep: ^3.0.3 msw: 2.2.1 plotly.js: ^2.25.2 @@ -7559,7 +7558,23 @@ __metadata: languageName: node linkType: hard -"@types/lodash@npm:^4.14.167, @types/lodash@npm:^4.14.194, @types/lodash@npm:^4.14.200, @types/lodash@npm:^4.14.201": +"@types/lodash-es@npm:^4.17.12": + version: 4.17.12 + resolution: "@types/lodash-es@npm:4.17.12" + dependencies: + "@types/lodash": "*" + checksum: 990a99e2243bebe9505cb5ad19fbc172beb4a8e00f9075c99fc06c46c2801ffdb40bc2867271cf580d5f48994fc9fb076ec92cd60a20e621603bf22114e5b077 + languageName: node + linkType: hard + +"@types/lodash@npm:*": + version: 4.17.7 + resolution: "@types/lodash@npm:4.17.7" + checksum: 09e58a119cd8a70acfb33f8623dc2fc54f74cdce3b3429b879fc2daac4807fe376190a04b9e024dd300f9a3ee1876d6623979cefe619f70654ca0fe0c47679a7 + languageName: node + linkType: hard + +"@types/lodash@npm:^4.14.167, @types/lodash@npm:^4.14.194, @types/lodash@npm:^4.14.201": version: 4.17.1 resolution: "@types/lodash@npm:4.17.1" checksum: 01984d5b44c09ef45258f8ac6d0cf926900624064722d51a020ba179e5d4a293da0068fb278d87dc695586afe7ebd3362ec57f5c0e7c4f6c1fab9d04a80e77f5 @@ -7684,13 +7699,6 @@ __metadata: languageName: node linkType: hard -"@types/object-hash@npm:^3.0.5": - version: 3.0.6 - resolution: "@types/object-hash@npm:3.0.6" - checksum: 2c7979d4e540af817b99c09fb4c2fed1c0b0e14342df474d8dcde4165a82c440b038341fd66fe998d9f86acdd5cccc65ba8092315e39e7c2114f945fa70aaa56 - languageName: node - linkType: hard - "@types/parse-json@npm:^4.0.0": version: 4.0.2 resolution: "@types/parse-json@npm:4.0.2" @@ -15072,6 +15080,13 @@ __metadata: languageName: node linkType: hard +"hash-it@npm:^6.0.0": + version: 6.0.0 + resolution: "hash-it@npm:6.0.0" + checksum: 10ca948ff7902a752344c3975c1a5c76ba9e4aa0363032f347a7235cce98473dce60fe4399b05979596aedf649adaf5b3f792a55b9b64ad59ae686e43300c2d1 + languageName: node + linkType: hard + "hasha@npm:^5.0.0": version: 5.2.2 resolution: "hasha@npm:5.2.2"