diff --git a/libs/sdk-ui-charts/src/forecast.ts b/libs/sdk-ui-charts/src/forecast.ts index e6503f183c8..929a5373b93 100644 --- a/libs/sdk-ui-charts/src/forecast.ts +++ b/libs/sdk-ui-charts/src/forecast.ts @@ -19,10 +19,14 @@ export function isForecastEnabled( const buckets = insightBuckets(insight); const measures = bucketsFind(buckets, (b) => b.localIdentifier === BucketNames.MEASURES); const trends = bucketsFind(buckets, (b) => b.localIdentifier === BucketNames.TREND); + const segments = bucketsFind(buckets, (b) => b.localIdentifier === BucketNames.SEGMENT); //TODO: s.hacker check if the trend is date attribute somehow return { - enabled: measures?.items.length === 1 && trends?.items.length === 1, + enabled: + measures?.items.length === 1 && + trends?.items.length === 1 && + (segments?.items.length ?? 0) === 0, visible: true, }; } diff --git a/libs/sdk-ui-charts/src/tests/forecast.test.ts b/libs/sdk-ui-charts/src/tests/forecast.test.ts index 1a05df89723..fcd8f2bc9a2 100644 --- a/libs/sdk-ui-charts/src/tests/forecast.test.ts +++ b/libs/sdk-ui-charts/src/tests/forecast.test.ts @@ -166,4 +166,46 @@ describe("isForecastEnabled", () => { visible: true, }); }); + + it("should be disabled if more buckets 3", () => { + const res = isForecastEnabled( + { + ...insight, + insight: { + ...insight.insight, + buckets: [ + ...insight.insight.buckets, + { + localIdentifier: "segment", + items: [ + { + attribute: { + localIdentifier: "date", + alias: "", + displayForm: { + uri: "dateUri", + }, + }, + }, + { + attribute: { + localIdentifier: "date1", + alias: "", + displayForm: { + uri: "dateUri1", + }, + }, + }, + ], + }, + ], + }, + }, + "line", + ); + expect(res).toEqual({ + enabled: false, + visible: true, + }); + }); }); diff --git a/libs/sdk-ui-ext/src/internal/components/configurationControls/forecast/ForecastSection.tsx b/libs/sdk-ui-ext/src/internal/components/configurationControls/forecast/ForecastSection.tsx index 02ce4f5d57f..a555ce17b32 100644 --- a/libs/sdk-ui-ext/src/internal/components/configurationControls/forecast/ForecastSection.tsx +++ b/libs/sdk-ui-ext/src/internal/components/configurationControls/forecast/ForecastSection.tsx @@ -7,6 +7,8 @@ import InputControl from "../InputControl.js"; import { messages } from "../../../../locales.js"; import noop from "lodash/noop.js"; import CheckboxControl from "../CheckboxControl.js"; +import { Message } from "@gooddata/sdk-ui-kit"; +import { FormattedMessage } from "react-intl"; export interface IForecastSection { controlsDisabled: boolean; @@ -35,6 +37,7 @@ class ForecastSection extends React.PureComponent { const forecastPeriod = this.props.properties?.controls?.forecast?.period ?? 3; const forecastSeasonal = this.props.properties?.controls?.forecast?.seasonal ?? false; const forecastToggleDisabledByVisualization = !(this.props.propertiesMeta?.forecast_enabled ?? true); + const slicedForecast = this.props.propertiesMeta?.slicedForecast ?? false; const toggleDisabled = controlsDisabled || forecastToggleDisabledByVisualization || !enabled; const forecastControlsDisabled = !forecastEnabled || toggleDisabled; @@ -44,6 +47,7 @@ class ForecastSection extends React.PureComponent { { properties={properties} pushData={pushData} /> + + {slicedForecast && ( + + + + + )} ); } diff --git a/libs/sdk-ui-ext/src/internal/translations/en-US.json b/libs/sdk-ui-ext/src/internal/translations/en-US.json index a903a456614..172f1e6385d 100644 --- a/libs/sdk-ui-ext/src/internal/translations/en-US.json +++ b/libs/sdk-ui-ext/src/internal/translations/en-US.json @@ -1016,6 +1016,16 @@ "comment": "", "limit": 0 }, + "properties.forecastSliced.title": { + "value": "Displaying partial results.", + "comment": "", + "limit": 0 + }, + "properties.forecastSliced.description": { + "value": "Try changing the visualization settings to display all results.", + "comment": "", + "limit": 0 + }, "properties.canvas.totalLabels": { "value": "Total Labels", "comment": "", diff --git a/libs/sdk-ui-ext/src/locales.ts b/libs/sdk-ui-ext/src/locales.ts index d6e4d985da2..80e868ed3ad 100644 --- a/libs/sdk-ui-ext/src/locales.ts +++ b/libs/sdk-ui-ext/src/locales.ts @@ -239,6 +239,8 @@ export const messages: Record = defineMessages({ forecastConfidence85: { id: "properties.forecastConfidence.85" }, forecastConfidence90: { id: "properties.forecastConfidence.90" }, forecastConfidence95: { id: "properties.forecastConfidence.95" }, + forecastSlicedWarningTitle: { id: "properties.forecastSliced.title" }, + forecastSlicedWarningDescription: { id: "properties.forecastSliced.description" }, }); export const comparisonMessages: Record = defineMessages({ diff --git a/libs/sdk-ui-ext/styles/internal/scss/config_panel.scss b/libs/sdk-ui-ext/styles/internal/scss/config_panel.scss index b0a6cba903c..6d7c6af0b0d 100644 --- a/libs/sdk-ui-ext/styles/internal/scss/config_panel.scss +++ b/libs/sdk-ui-ext/styles/internal/scss/config_panel.scss @@ -1,4 +1,4 @@ -// (C) 2007-2021 GoodData Corporation +// (C) 2007-2024 GoodData Corporation @use "sass:color"; @use "variables.scss"; @use "@gooddata/sdk-ui-kit/styles/scss/colorPicker"; @@ -161,3 +161,9 @@ $color-picker-spacing: 5px; .gd-table-canvas-section.adi-bucket-configuration { padding: 0; } + +.gd-forecast-section.adi-bucket-configuration { + .gd-slicedForecast-message { + margin-top: 15px; + } +} diff --git a/libs/sdk-ui/src/base/react/legacy/withEntireDataView.tsx b/libs/sdk-ui/src/base/react/legacy/withEntireDataView.tsx index 6fbc097a30d..552909d5fe9 100644 --- a/libs/sdk-ui/src/base/react/legacy/withEntireDataView.tsx +++ b/libs/sdk-ui/src/base/react/legacy/withEntireDataView.tsx @@ -262,7 +262,7 @@ export function withEntireDataView( return; } - if (dataView.forecastConfig) { + if (dataView.forecastConfig && forecastConfig) { try { const forecastResult = await executionResult.readForecastAll(dataView.forecastConfig); const updatedDataView = dataView.withForecast( @@ -271,7 +271,14 @@ export function withEntireDataView( ); this.setState((s) => ({ ...s, dataView: updatedDataView })); if (pushData) { - pushData({ dataView: updatedDataView }); + pushData({ + dataView: updatedDataView, + propertiesMeta: { + slicedForecast: + forecastConfig.forecastPeriod !== + dataView.forecastConfig?.forecastPeriod, + }, + }); } } catch (e) { const updatedDataView = dataView.withForecast(undefined);