diff --git a/common/changes/@gooddata/sdk-ui-all/JSVA-GDAI-1081-accessibility-4_2026-01-14-07-49.json b/common/changes/@gooddata/sdk-ui-all/JSVA-GDAI-1081-accessibility-4_2026-01-14-07-49.json new file mode 100644 index 00000000000..c8b420ed044 --- /dev/null +++ b/common/changes/@gooddata/sdk-ui-all/JSVA-GDAI-1081-accessibility-4_2026-01-14-07-49.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "Fix `AppHeader` responsive measurement.", + "type": "none", + "packageName": "@gooddata/sdk-ui-all" + } + ], + "packageName": "@gooddata/sdk-ui-all", + "email": "jan.svager@gooddata.com" +} diff --git a/common/changes/@gooddata/sdk-ui-all/JSVA-GDAI-1081-accessibility-4_2026-01-14-14-29.json b/common/changes/@gooddata/sdk-ui-all/JSVA-GDAI-1081-accessibility-4_2026-01-14-14-29.json new file mode 100644 index 00000000000..dc109851e99 --- /dev/null +++ b/common/changes/@gooddata/sdk-ui-all/JSVA-GDAI-1081-accessibility-4_2026-01-14-14-29.json @@ -0,0 +1,11 @@ +{ + "changes": [ + { + "comment": "sdk-ui-kit: Fix mobile `UiDrawer` layout to render full-width.", + "type": "none", + "packageName": "@gooddata/sdk-ui-all" + } + ], + "packageName": "@gooddata/sdk-ui-all", + "email": "jan.svager@gooddata.com" +} diff --git a/common/changes/@gooddata/sdk-ui-all/JSVA-dialog-data-test-id_2026-01-15-12-21.json b/common/changes/@gooddata/sdk-ui-all/JSVA-dialog-data-test-id_2026-01-15-12-21.json new file mode 100644 index 00000000000..5e9f5931000 --- /dev/null +++ b/common/changes/@gooddata/sdk-ui-all/JSVA-dialog-data-test-id_2026-01-15-12-21.json @@ -0,0 +1,15 @@ +{ + "changes": [ + { + "packageName": "@gooddata/sdk-ui-all", + "comment": "sdk-ui-kit: Add support for `data-testid` attribute to `Dialog` component.", + "type": "none" + }, + { + "packageName": "@gooddata/sdk-ui-all", + "comment": "sdk-ui-dashboard: Add `data-testid` attributes to `KdaDialog` component.", + "type": "none" + } + ], + "packageName": "@gooddata/sdk-ui-all" +} diff --git a/common/changes/@gooddata/sdk-ui-all/SHA_master_2026-01-15-08-48.json b/common/changes/@gooddata/sdk-ui-all/SHA_master_2026-01-15-08-48.json new file mode 100644 index 00000000000..1aa4df257b4 --- /dev/null +++ b/common/changes/@gooddata/sdk-ui-all/SHA_master_2026-01-15-08-48.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@gooddata/sdk-ui-all", + "comment": "sdk-backend-tiger: add isLocked into memory item", + "type": "none" + } + ], + "packageName": "@gooddata/sdk-ui-all" +} diff --git a/common/changes/@gooddata/sdk-ui-all/jsc-f_1_2026-01-15-12-02.json b/common/changes/@gooddata/sdk-ui-all/jsc-f_1_2026-01-15-12-02.json new file mode 100644 index 00000000000..79ef861b917 --- /dev/null +++ b/common/changes/@gooddata/sdk-ui-all/jsc-f_1_2026-01-15-12-02.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@gooddata/sdk-ui-all", + "comment": "sdk-ui-kit: Enhance dropdown accessibility props.", + "type": "none" + } + ], + "packageName": "@gooddata/sdk-ui-all" +} diff --git a/common/changes/@gooddata/sdk-ui-all/vbar-GDAI-1213_2026-01-14-16-40.json b/common/changes/@gooddata/sdk-ui-all/vbar-GDAI-1213_2026-01-14-16-40.json new file mode 100644 index 00000000000..65ea306aae3 --- /dev/null +++ b/common/changes/@gooddata/sdk-ui-all/vbar-GDAI-1213_2026-01-14-16-40.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@gooddata/sdk-ui-all", + "comment": "sdk-ui-gen-ai: Change the logic for handling multiple interaction IDs in the assistant message stream.", + "type": "none" + } + ], + "packageName": "@gooddata/sdk-ui-all" +} diff --git a/common/config/rush/version-policies.json b/common/config/rush/version-policies.json index d4abe1dd168..17f1e824dfa 100644 --- a/common/config/rush/version-policies.json +++ b/common/config/rush/version-policies.json @@ -12,14 +12,14 @@ { "definitionName": "lockStepVersion", "policyName": "sdk", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "nextBump": "prerelease", "mainProject": "@gooddata/sdk-ui-all" }, { "definitionName": "lockStepVersion", "policyName": "sdk-examples", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "nextBump": "prerelease", "mainProject": "@gooddata/sdk-ui-all" } diff --git a/examples/sdk-interactive-examples/examples-template/package.json b/examples/sdk-interactive-examples/examples-template/package.json index 4e2f9e15308..05fc2189305 100644 --- a/examples/sdk-interactive-examples/examples-template/package.json +++ b/examples/sdk-interactive-examples/examples-template/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-examples-template", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "GoodData interactive example template", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-attributefilter/package.json b/examples/sdk-interactive-examples/examples/example-attributefilter/package.json index 5193ac682ef..c828910dde7 100644 --- a/examples/sdk-interactive-examples/examples/example-attributefilter/package.json +++ b/examples/sdk-interactive-examples/examples/example-attributefilter/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-attributefilter", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "This example demonstrates how to use the AttributeFilter component to filter data in a visualization.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-chartconfig/package.json b/examples/sdk-interactive-examples/examples/example-chartconfig/package.json index 4d069621513..61225494576 100644 --- a/examples/sdk-interactive-examples/examples/example-chartconfig/package.json +++ b/examples/sdk-interactive-examples/examples/example-chartconfig/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-chartconfig", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "This interactive example demonstrates how to manipulate the chart config.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-columnchart/package.json b/examples/sdk-interactive-examples/examples/example-columnchart/package.json index 2f2dd9fea8f..f49c1e12cce 100644 --- a/examples/sdk-interactive-examples/examples/example-columnchart/package.json +++ b/examples/sdk-interactive-examples/examples/example-columnchart/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-columnchart", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "This example demonstrates the usage of the ColumnChart component with the viewBy and stackBy properties.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-combochart/package.json b/examples/sdk-interactive-examples/examples/example-combochart/package.json index eb3f1a8f868..e3b75eeb965 100644 --- a/examples/sdk-interactive-examples/examples/example-combochart/package.json +++ b/examples/sdk-interactive-examples/examples/example-combochart/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-combochart", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "Example demonstrates ComboChart secondaryMeasures definition. ", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-dashboard/package.json b/examples/sdk-interactive-examples/examples/example-dashboard/package.json index f7c6dc9683a..dc4f8e1bddb 100644 --- a/examples/sdk-interactive-examples/examples/example-dashboard/package.json +++ b/examples/sdk-interactive-examples/examples/example-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-dashboard", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "This example shows how to use the Dashboard component.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-datefilter/package.json b/examples/sdk-interactive-examples/examples/example-datefilter/package.json index c4b63c758cd..82ea0604a5a 100644 --- a/examples/sdk-interactive-examples/examples/example-datefilter/package.json +++ b/examples/sdk-interactive-examples/examples/example-datefilter/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-datefilter", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "Example demonstrates usage of Date Filter component.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-dependentfilters/package.json b/examples/sdk-interactive-examples/examples/example-dependentfilters/package.json index 66fcfd1427e..7ddeaf69eb0 100644 --- a/examples/sdk-interactive-examples/examples/example-dependentfilters/package.json +++ b/examples/sdk-interactive-examples/examples/example-dependentfilters/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-dependentfilters", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "This example demonstrates how to use multiple attribute filters linked together to filter data in a visualization.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-execute/package.json b/examples/sdk-interactive-examples/examples/example-execute/package.json index 5c76bfaf27d..4b025550213 100644 --- a/examples/sdk-interactive-examples/examples/example-execute/package.json +++ b/examples/sdk-interactive-examples/examples/example-execute/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-execute", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "This example demonstrates using Execute component and build custom visualization.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-granularity/package.json b/examples/sdk-interactive-examples/examples/example-granularity/package.json index 6a2e485473e..269711d5889 100644 --- a/examples/sdk-interactive-examples/examples/example-granularity/package.json +++ b/examples/sdk-interactive-examples/examples/example-granularity/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-granularity", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "This example exmplains DateFilter granularity ", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-headline/package.json b/examples/sdk-interactive-examples/examples/example-headline/package.json index de77ba73c7f..395a4ebebe0 100644 --- a/examples/sdk-interactive-examples/examples/example-headline/package.json +++ b/examples/sdk-interactive-examples/examples/example-headline/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-headline", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "This example shows how to use the Headline component.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-pivottable/package.json b/examples/sdk-interactive-examples/examples/example-pivottable/package.json index 65759e49c26..1ca7765c95d 100644 --- a/examples/sdk-interactive-examples/examples/example-pivottable/package.json +++ b/examples/sdk-interactive-examples/examples/example-pivottable/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-pivottable", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "Basic PivotTable manipulation.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-relativedatefilter/package.json b/examples/sdk-interactive-examples/examples/example-relativedatefilter/package.json index ede74cb61d9..37898688e54 100644 --- a/examples/sdk-interactive-examples/examples/example-relativedatefilter/package.json +++ b/examples/sdk-interactive-examples/examples/example-relativedatefilter/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-relativedatefilter", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "Example demonstrates how to set relative DateFilter for visualization.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/examples/example-repeater/package.json b/examples/sdk-interactive-examples/examples/example-repeater/package.json index f6ce8044f3b..bb674518db8 100644 --- a/examples/sdk-interactive-examples/examples/example-repeater/package.json +++ b/examples/sdk-interactive-examples/examples/example-repeater/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-example-repeater", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "This example demonstrates how to use Repeater component.", "license": "LicenseRef-LICENSE", diff --git a/examples/sdk-interactive-examples/package.json b/examples/sdk-interactive-examples/package.json index cfd83678e76..014550a1fd9 100644 --- a/examples/sdk-interactive-examples/package.json +++ b/examples/sdk-interactive-examples/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-interactive-examples", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "private": false, "description": "GoodData React interactive examples", "license": "LicenseRef-LICENSE", diff --git a/libs/api-client-tiger/.eslintrc.cjs b/libs/api-client-tiger/.eslintrc.cjs index 04d42b08dcf..9b5dbd9a7a2 100644 --- a/libs/api-client-tiger/.eslintrc.cjs +++ b/libs/api-client-tiger/.eslintrc.cjs @@ -1,20 +1,17 @@ -// (C) 2020 GoodData Corporation +// (C) 2020-2026 GoodData Corporation const { tsOverride } = require("@gooddata/eslint-config/tsOverride"); module.exports = { extends: ["@gooddata/eslint-config/esm"], rules: { - "import/export": "off", + "import/export": "warn", }, overrides: [ tsOverride(__dirname, { - "@typescript-eslint/no-namespace": "off", - "@typescript-eslint/no-unsafe-assignment": "off", - "@typescript-eslint/naming-convention": "off", - "@typescript-eslint/no-unsafe-return": "off", - "@typescript-eslint/no-unsafe-member-access": "off", - "@typescript-eslint/no-unnecessary-type-assertion": "off", + "@typescript-eslint/no-unsafe-assignment": "warn", + "@typescript-eslint/no-unsafe-return": "warn", + "@typescript-eslint/no-unsafe-member-access": "warn", }), ], }; diff --git a/libs/api-client-tiger/api/api-client-tiger.api.md b/libs/api-client-tiger/api/api-client-tiger.api.md index d6f26ed3c86..58c164b75ab 100644 --- a/libs/api-client-tiger/api/api-client-tiger.api.md +++ b/libs/api-client-tiger/api/api-client-tiger.api.md @@ -23,29 +23,21 @@ import { VisualizationProperties } from '@gooddata/sdk-model'; // @public export interface AacAnalyticsModel { - // (undocumented) - [key: string]: unknown; - // (undocumented) - attribute_hierarchies?: unknown[]; - // (undocumented) - dashboards?: unknown[]; - // (undocumented) - metrics?: unknown[]; - // (undocumented) - plugins?: unknown[]; - // (undocumented) - visualizations?: unknown[]; + attribute_hierarchies?: Array; + dashboards?: Array; + metrics?: Array; + plugins?: Array; + visualizations?: Array; } // @public export class AACAnalyticsModelApi extends MetadataBaseApi implements AACAnalyticsModelApiInterface { - // Warning: (ae-forgotten-export) The symbol "AacAnalyticsModel_2" needs to be exported by the entry point index.d.ts - getAnalyticsModelAac(requestParameters: AACAnalyticsModelApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + getAnalyticsModelAac(requestParameters: AACAnalyticsModelApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; setAnalyticsModelAac(requestParameters: AACAnalyticsModelApiSetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; } // @public -export function AACAnalyticsModelApi_GetAnalyticsModelAac(axios: AxiosInstance, basePath: string, requestParameters: AACAnalyticsModelApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; +export function AACAnalyticsModelApi_GetAnalyticsModelAac(axios: AxiosInstance, basePath: string, requestParameters: AACAnalyticsModelApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; // @public export function AACAnalyticsModelApi_SetAnalyticsModelAac(axios: AxiosInstance, basePath: string, requestParameters: AACAnalyticsModelApiSetAnalyticsModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; @@ -54,7 +46,7 @@ export function AACAnalyticsModelApi_SetAnalyticsModelAac(axios: AxiosInstance, export function AACAnalyticsModelApiAxiosParamCreator_GetAnalyticsModelAac(workspaceId: string, exclude?: Array<"ACTIVITY_INFO">, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; // @public -export function AACAnalyticsModelApiAxiosParamCreator_SetAnalyticsModelAac(workspaceId: string, aacAnalyticsModel: AacAnalyticsModel_2, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; +export function AACAnalyticsModelApiAxiosParamCreator_SetAnalyticsModelAac(workspaceId: string, aacAnalyticsModel: AacAnalyticsModel, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; // @public export interface AACAnalyticsModelApiGetAnalyticsModelAacRequest { @@ -64,13 +56,13 @@ export interface AACAnalyticsModelApiGetAnalyticsModelAacRequest { // @public export interface AACAnalyticsModelApiInterface { - getAnalyticsModelAac(requestParameters: AACAnalyticsModelApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + getAnalyticsModelAac(requestParameters: AACAnalyticsModelApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; setAnalyticsModelAac(requestParameters: AACAnalyticsModelApiSetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; } // @public export interface AACAnalyticsModelApiSetAnalyticsModelAacRequest { - readonly aacAnalyticsModel: AacAnalyticsModel_2; + readonly aacAnalyticsModel: AacAnalyticsModel; readonly workspaceId: string; } @@ -79,28 +71,23 @@ export type AacAnalyticsModelExclude = "ACTIVITY_INFO"; // @public export class AacApi extends MetadataBaseApi implements AacApiInterface { - // Warning: (ae-forgotten-export) The symbol "AacApiGetAnalyticsModelAacRequest_2" needs to be exported by the entry point index.d.ts - getAnalyticsModelAac(requestParameters: AacApiGetAnalyticsModelAacRequest_2, options?: AxiosRequestConfig): AxiosPromise; - // Warning: (ae-forgotten-export) The symbol "AacApiGetLogicalModelAacRequest_2" needs to be exported by the entry point index.d.ts - // Warning: (ae-forgotten-export) The symbol "AacLogicalModel_2" needs to be exported by the entry point index.d.ts - getLogicalModelAac(requestParameters: AacApiGetLogicalModelAacRequest_2, options?: AxiosRequestConfig): AxiosPromise; - // Warning: (ae-forgotten-export) The symbol "AacApiSetAnalyticsModelAacRequest_2" needs to be exported by the entry point index.d.ts - setAnalyticsModelAac(requestParameters: AacApiSetAnalyticsModelAacRequest_2, options?: AxiosRequestConfig): AxiosPromise; - // Warning: (ae-forgotten-export) The symbol "AacApiSetLogicalModelAacRequest_2" needs to be exported by the entry point index.d.ts - setLogicalModelAac(requestParameters: AacApiSetLogicalModelAacRequest_2, options?: AxiosRequestConfig): AxiosPromise; + getAnalyticsModelAac(requestParameters: AacApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + getLogicalModelAac(requestParameters: AacApiGetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + setAnalyticsModelAac(requestParameters: AacApiSetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + setLogicalModelAac(requestParameters: AacApiSetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; } // @public (undocumented) -export function AacApi_GetAnalyticsModelAac(axios: AxiosInstance, basePath: string, requestParameters: AacApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; +export function AacApi_GetAnalyticsModelAac(axios: AxiosInstance, basePath: string, requestParameters: IAacApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; // @public (undocumented) -export function AacApi_GetLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: AacApiGetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; +export function AacApi_GetLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: IAacApiGetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; // @public (undocumented) -export function AacApi_SetAnalyticsModelAac(axios: AxiosInstance, basePath: string, requestParameters: AacApiSetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; +export function AacApi_SetAnalyticsModelAac(axios: AxiosInstance, basePath: string, requestParameters: IAacApiSetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; // @public (undocumented) -export function AacApi_SetLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: AacApiSetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; +export function AacApi_SetLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: IAacApiSetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; // @public export function AacApiAxiosParamCreator_GetAnalyticsModelAac(workspaceId: string, exclude?: Array<"ACTIVITY_INFO">, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; @@ -109,48 +96,40 @@ export function AacApiAxiosParamCreator_GetAnalyticsModelAac(workspaceId: string export function AacApiAxiosParamCreator_GetLogicalModelAac(workspaceId: string, includeParents?: boolean, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; // @public -export function AacApiAxiosParamCreator_SetAnalyticsModelAac(workspaceId: string, aacAnalyticsModel: AacAnalyticsModel_2, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; +export function AacApiAxiosParamCreator_SetAnalyticsModelAac(workspaceId: string, aacAnalyticsModel: AacAnalyticsModel, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; // @public -export function AacApiAxiosParamCreator_SetLogicalModelAac(workspaceId: string, aacLogicalModel: AacLogicalModel_2, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; +export function AacApiAxiosParamCreator_SetLogicalModelAac(workspaceId: string, aacLogicalModel: AacLogicalModel, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; -// @public (undocumented) +// @public export interface AacApiGetAnalyticsModelAacRequest { - // (undocumented) - readonly exclude?: Array; - // (undocumented) + readonly exclude?: Array<"ACTIVITY_INFO">; readonly workspaceId: string; } -// @public (undocumented) +// @public export interface AacApiGetLogicalModelAacRequest { - // (undocumented) readonly includeParents?: boolean; - // (undocumented) readonly workspaceId: string; } // @public export interface AacApiInterface { - getAnalyticsModelAac(requestParameters: AacApiGetAnalyticsModelAacRequest_2, options?: AxiosRequestConfig): AxiosPromise; - getLogicalModelAac(requestParameters: AacApiGetLogicalModelAacRequest_2, options?: AxiosRequestConfig): AxiosPromise; - setAnalyticsModelAac(requestParameters: AacApiSetAnalyticsModelAacRequest_2, options?: AxiosRequestConfig): AxiosPromise; - setLogicalModelAac(requestParameters: AacApiSetLogicalModelAacRequest_2, options?: AxiosRequestConfig): AxiosPromise; + getAnalyticsModelAac(requestParameters: AacApiGetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + getLogicalModelAac(requestParameters: AacApiGetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + setAnalyticsModelAac(requestParameters: AacApiSetAnalyticsModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + setLogicalModelAac(requestParameters: AacApiSetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; } -// @public (undocumented) +// @public export interface AacApiSetAnalyticsModelAacRequest { - // (undocumented) readonly aacAnalyticsModel: AacAnalyticsModel; - // (undocumented) readonly workspaceId: string; } -// @public (undocumented) +// @public export interface AacApiSetLogicalModelAacRequest { - // (undocumented) readonly aacLogicalModel: AacLogicalModel; - // (undocumented) readonly workspaceId: string; } @@ -344,12 +323,12 @@ export interface AacLabelTranslation { // @public export class AACLogicalDataModelApi extends MetadataBaseApi implements AACLogicalDataModelApiInterface { - getLogicalModelAac(requestParameters: AACLogicalDataModelApiGetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + getLogicalModelAac(requestParameters: AACLogicalDataModelApiGetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; setLogicalModelAac(requestParameters: AACLogicalDataModelApiSetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; } // @public -export function AACLogicalDataModelApi_GetLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: AACLogicalDataModelApiGetLogicalModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; +export function AACLogicalDataModelApi_GetLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: AACLogicalDataModelApiGetLogicalModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; // @public export function AACLogicalDataModelApi_SetLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: AACLogicalDataModelApiSetLogicalModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; @@ -358,7 +337,7 @@ export function AACLogicalDataModelApi_SetLogicalModelAac(axios: AxiosInstance, export function AACLogicalDataModelApiAxiosParamCreator_GetLogicalModelAac(workspaceId: string, includeParents?: boolean, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; // @public -export function AACLogicalDataModelApiAxiosParamCreator_SetLogicalModelAac(workspaceId: string, aacLogicalModel: AacLogicalModel_2, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; +export function AACLogicalDataModelApiAxiosParamCreator_SetLogicalModelAac(workspaceId: string, aacLogicalModel: AacLogicalModel, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; // @public export interface AACLogicalDataModelApiGetLogicalModelAacRequest { @@ -368,24 +347,20 @@ export interface AACLogicalDataModelApiGetLogicalModelAacRequest { // @public export interface AACLogicalDataModelApiInterface { - getLogicalModelAac(requestParameters: AACLogicalDataModelApiGetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + getLogicalModelAac(requestParameters: AACLogicalDataModelApiGetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; setLogicalModelAac(requestParameters: AACLogicalDataModelApiSetLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; } // @public export interface AACLogicalDataModelApiSetLogicalModelAacRequest { - readonly aacLogicalModel: AacLogicalModel_2; + readonly aacLogicalModel: AacLogicalModel; readonly workspaceId: string; } // @public export interface AacLogicalModel { - // (undocumented) - [key: string]: unknown; - // (undocumented) - datasets?: unknown[]; - // (undocumented) - date_datasets?: unknown[]; + datasets?: Array; + date_datasets?: Array; } // @public @@ -611,7 +586,7 @@ export class ActionsApi extends MetadataBaseApi implements ActionsApiInterface { deleteOrganizationAutomations(requestParameters: ActionsApiDeleteOrganizationAutomationsRequest, options?: AxiosRequestConfig): AxiosPromise; deleteWorkspaceAutomations(requestParameters: ActionsApiDeleteWorkspaceAutomationsRequest, options?: AxiosRequestConfig): AxiosPromise; generateLogicalModel(requestParameters: ActionsApiGenerateLogicalModelRequest, options?: AxiosRequestConfig): AxiosPromise; - generateLogicalModelAac(requestParameters: ActionsApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + generateLogicalModelAac(requestParameters: ActionsApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; getDependentEntitiesGraph(requestParameters: ActionsApiGetDependentEntitiesGraphRequest, options?: AxiosRequestConfig): AxiosPromise; getDependentEntitiesGraphFromEntryPoints(requestParameters: ActionsApiGetDependentEntitiesGraphFromEntryPointsRequest, options?: AxiosRequestConfig): AxiosPromise; getTranslationTags(requestParameters: ActionsApiGetTranslationTagsRequest, options?: AxiosRequestConfig): AxiosPromise; @@ -676,7 +651,7 @@ export function ActionsApi_DeleteWorkspaceAutomations(axios: AxiosInstance, base export function ActionsApi_GenerateLogicalModel(axios: AxiosInstance, basePath: string, requestParameters: ActionsApiGenerateLogicalModelRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; // @public -export function ActionsApi_GenerateLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: ActionsApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; +export function ActionsApi_GenerateLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: ActionsApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; // @public export function ActionsApi_GetDependentEntitiesGraph(axios: AxiosInstance, basePath: string, requestParameters: ActionsApiGetDependentEntitiesGraphRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; @@ -1145,7 +1120,7 @@ export interface ActionsApiInterface { deleteOrganizationAutomations(requestParameters: ActionsApiDeleteOrganizationAutomationsRequest, options?: AxiosRequestConfig): AxiosPromise; deleteWorkspaceAutomations(requestParameters: ActionsApiDeleteWorkspaceAutomationsRequest, options?: AxiosRequestConfig): AxiosPromise; generateLogicalModel(requestParameters: ActionsApiGenerateLogicalModelRequest, options?: AxiosRequestConfig): AxiosPromise; - generateLogicalModelAac(requestParameters: ActionsApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + generateLogicalModelAac(requestParameters: ActionsApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; getDependentEntitiesGraph(requestParameters: ActionsApiGetDependentEntitiesGraphRequest, options?: AxiosRequestConfig): AxiosPromise; getDependentEntitiesGraphFromEntryPoints(requestParameters: ActionsApiGetDependentEntitiesGraphFromEntryPointsRequest, options?: AxiosRequestConfig): AxiosPromise; getTranslationTags(requestParameters: ActionsApiGetTranslationTagsRequest, options?: AxiosRequestConfig): AxiosPromise>; @@ -13358,14 +13333,14 @@ export interface GenerateLdmRequest { // @public export class GenerateLogicalDataModelApi extends MetadataBaseApi implements GenerateLogicalDataModelApiInterface { generateLogicalModel(requestParameters: GenerateLogicalDataModelApiGenerateLogicalModelRequest, options?: AxiosRequestConfig): AxiosPromise; - generateLogicalModelAac(requestParameters: GenerateLogicalDataModelApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + generateLogicalModelAac(requestParameters: GenerateLogicalDataModelApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; } // @public export function GenerateLogicalDataModelApi_GenerateLogicalModel(axios: AxiosInstance, basePath: string, requestParameters: GenerateLogicalDataModelApiGenerateLogicalModelRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; // @public -export function GenerateLogicalDataModelApi_GenerateLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: GenerateLogicalDataModelApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; +export function GenerateLogicalDataModelApi_GenerateLogicalModelAac(axios: AxiosInstance, basePath: string, requestParameters: GenerateLogicalDataModelApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): AxiosPromise; // @public export function GenerateLogicalDataModelApiAxiosParamCreator_GenerateLogicalModel(dataSourceId: string, generateLdmRequest: GenerateLdmRequest, options?: AxiosRequestConfig, configuration?: MetadataConfiguration): Promise; @@ -13388,7 +13363,7 @@ export interface GenerateLogicalDataModelApiGenerateLogicalModelRequest { // @public export interface GenerateLogicalDataModelApiInterface { generateLogicalModel(requestParameters: GenerateLogicalDataModelApiGenerateLogicalModelRequest, options?: AxiosRequestConfig): AxiosPromise; - generateLogicalModelAac(requestParameters: GenerateLogicalDataModelApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; + generateLogicalModelAac(requestParameters: GenerateLogicalDataModelApiGenerateLogicalModelAacRequest, options?: AxiosRequestConfig): AxiosPromise; } // @public @@ -13526,6 +13501,64 @@ export interface HistogramProperties { bucketCount: number; } +// @public +export interface IAacAnalyticsModel { + // (undocumented) + [key: string]: unknown; + // (undocumented) + attribute_hierarchies?: unknown[]; + // (undocumented) + dashboards?: unknown[]; + // (undocumented) + metrics?: unknown[]; + // (undocumented) + plugins?: unknown[]; + // (undocumented) + visualizations?: unknown[]; +} + +// @public (undocumented) +export interface IAacApiGetAnalyticsModelAacRequest { + // (undocumented) + readonly exclude?: Array; + // (undocumented) + readonly workspaceId: string; +} + +// @public (undocumented) +export interface IAacApiGetLogicalModelAacRequest { + // (undocumented) + readonly includeParents?: boolean; + // (undocumented) + readonly workspaceId: string; +} + +// @public (undocumented) +export interface IAacApiSetAnalyticsModelAacRequest { + // (undocumented) + readonly aacAnalyticsModel: IAacAnalyticsModel; + // (undocumented) + readonly workspaceId: string; +} + +// @public (undocumented) +export interface IAacApiSetLogicalModelAacRequest { + // (undocumented) + readonly aacLogicalModel: IAacLogicalModel; + // (undocumented) + readonly workspaceId: string; +} + +// @public +export interface IAacLogicalModel { + // (undocumented) + [key: string]: unknown; + // (undocumented) + datasets?: unknown[]; + // (undocumented) + date_datasets?: unknown[]; +} + // @public @deprecated (undocumented) interface IAnalyticalDashboard { // (undocumented) @@ -20864,9 +20897,9 @@ export interface LocalIdentifier { } // @public -export interface LocationStyleApiInterface { +export type LocationStyleApiInterface = { getDefaultStyle(): Promise; -} +}; // @public export type LocationStyleDocument = Record; @@ -23842,12 +23875,10 @@ export interface PositiveAttributeFilterPositiveAttributeFilter { } // @public (undocumented) -export interface ProfileApiInterface { - // (undocumented) +export type ProfileApiInterface = { getCurrent: () => Promise; - // (undocumented) getCurrentWithDetails: () => Promise; -} +}; // @public (undocumented) interface Range_2 { diff --git a/libs/api-client-tiger/package.json b/libs/api-client-tiger/package.json index a17683458bc..7e649c2ca7c 100644 --- a/libs/api-client-tiger/package.json +++ b/libs/api-client-tiger/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/api-client-tiger", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "API Client for GoodData Cloud and GoodData.CN", "repository": { "type": "git", diff --git a/libs/api-client-tiger/src/client.ts b/libs/api-client-tiger/src/client.ts index 3e5d2c1efff..ace0c231f08 100644 --- a/libs/api-client-tiger/src/client.ts +++ b/libs/api-client-tiger/src/client.ts @@ -1,4 +1,4 @@ -// (C) 2019-2025 GoodData Corporation +// (C) 2019-2026 GoodData Corporation import { type AxiosInstance } from "axios"; diff --git a/libs/api-client-tiger/src/endpoints/aac/index.ts b/libs/api-client-tiger/src/endpoints/aac/index.ts index 7ca68ae37a4..8f62fcd580e 100644 --- a/libs/api-client-tiger/src/endpoints/aac/index.ts +++ b/libs/api-client-tiger/src/endpoints/aac/index.ts @@ -11,7 +11,7 @@ export type AacAnalyticsModelExclude = "ACTIVITY_INFO"; * permissive so we can expose the endpoint without requiring a full regenerated * OpenAPI client. */ -export interface AacAnalyticsModel { +export interface IAacAnalyticsModel { metrics?: unknown[]; visualizations?: unknown[]; dashboards?: unknown[]; @@ -27,30 +27,30 @@ export interface AacAnalyticsModel { * permissive so we can expose the endpoint without requiring a full regenerated * OpenAPI client. */ -export interface AacLogicalModel { +export interface IAacLogicalModel { datasets?: unknown[]; date_datasets?: unknown[]; [key: string]: unknown; } -export interface AacApiGetAnalyticsModelAacRequest { +export interface IAacApiGetAnalyticsModelAacRequest { readonly workspaceId: string; readonly exclude?: Array; } -export interface AacApiSetAnalyticsModelAacRequest { +export interface IAacApiSetAnalyticsModelAacRequest { readonly workspaceId: string; - readonly aacAnalyticsModel: AacAnalyticsModel; + readonly aacAnalyticsModel: IAacAnalyticsModel; } -export interface AacApiGetLogicalModelAacRequest { +export interface IAacApiGetLogicalModelAacRequest { readonly workspaceId: string; readonly includeParents?: boolean; } -export interface AacApiSetLogicalModelAacRequest { +export interface IAacApiSetLogicalModelAacRequest { readonly workspaceId: string; - readonly aacLogicalModel: AacLogicalModel; + readonly aacLogicalModel: IAacLogicalModel; } const toPathString = (url: URL): string => `${url.pathname}${url.search}${url.hash}`; @@ -84,18 +84,18 @@ const buildUrlWithParams = ( export function AacApi_GetAnalyticsModelAac( axios: AxiosInstance, basePath: string, - requestParameters: AacApiGetAnalyticsModelAacRequest, + requestParameters: IAacApiGetAnalyticsModelAacRequest, options: AxiosRequestConfig = {}, -): AxiosPromise { +): AxiosPromise { const path = `/api/v1/aac/workspaces/${encodeURIComponent(requestParameters.workspaceId)}/analyticsModel`; const url = `${basePath}${buildUrlWithParams(path, { exclude: requestParameters.exclude })}`; - return axios.request({ ...options, method: "GET", url }); + return axios.request({ ...options, method: "GET", url }); } export function AacApi_SetAnalyticsModelAac( axios: AxiosInstance, basePath: string, - requestParameters: AacApiSetAnalyticsModelAacRequest, + requestParameters: IAacApiSetAnalyticsModelAacRequest, options: AxiosRequestConfig = {}, ): AxiosPromise { const path = `/api/v1/aac/workspaces/${encodeURIComponent(requestParameters.workspaceId)}/analyticsModel`; @@ -115,18 +115,18 @@ export function AacApi_SetAnalyticsModelAac( export function AacApi_GetLogicalModelAac( axios: AxiosInstance, basePath: string, - requestParameters: AacApiGetLogicalModelAacRequest, + requestParameters: IAacApiGetLogicalModelAacRequest, options: AxiosRequestConfig = {}, -): AxiosPromise { +): AxiosPromise { const path = `/api/v1/aac/workspaces/${encodeURIComponent(requestParameters.workspaceId)}/logicalModel`; const url = `${basePath}${buildUrlWithParams(path, { includeParents: requestParameters.includeParents })}`; - return axios.request({ ...options, method: "GET", url }); + return axios.request({ ...options, method: "GET", url }); } export function AacApi_SetLogicalModelAac( axios: AxiosInstance, basePath: string, - requestParameters: AacApiSetLogicalModelAacRequest, + requestParameters: IAacApiSetLogicalModelAacRequest, options: AxiosRequestConfig = {}, ): AxiosPromise { const path = `/api/v1/aac/workspaces/${encodeURIComponent(requestParameters.workspaceId)}/logicalModel`; diff --git a/libs/api-client-tiger/src/index.ts b/libs/api-client-tiger/src/index.ts index 2ab07378bba..801c60ea6bc 100644 --- a/libs/api-client-tiger/src/index.ts +++ b/libs/api-client-tiger/src/index.ts @@ -626,13 +626,13 @@ export { AacApi_SetLogicalModelAac, } from "./endpoints/aac/index.js"; export type { - AacAnalyticsModel, + IAacAnalyticsModel, AacAnalyticsModelExclude, - AacLogicalModel, - AacApiGetAnalyticsModelAacRequest, - AacApiGetLogicalModelAacRequest, - AacApiSetAnalyticsModelAacRequest, - AacApiSetLogicalModelAacRequest, + IAacLogicalModel, + IAacApiGetAnalyticsModelAacRequest, + IAacApiGetLogicalModelAacRequest, + IAacApiSetAnalyticsModelAacRequest, + IAacApiSetLogicalModelAacRequest, } from "./endpoints/aac/index.js"; export const defaultTigerClient: ITigerClient = tigerClientFactory(defaultAxios); diff --git a/libs/api-client-tiger/src/locationStyle.ts b/libs/api-client-tiger/src/locationStyle.ts index f6b04ed0999..a202bade160 100644 --- a/libs/api-client-tiger/src/locationStyle.ts +++ b/libs/api-client-tiger/src/locationStyle.ts @@ -1,4 +1,4 @@ -// (C) 2025 GoodData Corporation +// (C) 2025-2026 GoodData Corporation import { type AxiosInstance } from "axios"; @@ -10,12 +10,12 @@ export type LocationStyleDocument = Record; /** * Interface describing available operations for location service style endpoint. */ -export interface LocationStyleApiInterface { +export type LocationStyleApiInterface = { /** * Loads the default MapLibre style document configured for the organization. */ getDefaultStyle(): Promise; -} +}; /** * Factory producing a typed client for interacting with the location style endpoint. diff --git a/libs/api-client-tiger/src/metadataUtilities.ts b/libs/api-client-tiger/src/metadataUtilities.ts index 65dc04422c5..74002d2b5f7 100644 --- a/libs/api-client-tiger/src/metadataUtilities.ts +++ b/libs/api-client-tiger/src/metadataUtilities.ts @@ -1,4 +1,4 @@ -// (C) 2019-2025 GoodData Corporation +// (C) 2019-2026 GoodData Corporation import { type AxiosInstance, type AxiosPromise, type GenericAbortSignal } from "axios"; import { merge, uniqBy } from "lodash-es"; @@ -261,7 +261,7 @@ export class MetadataUtilities { data: pages.flatMap((page: any) => page.data) as any, included: uniqBy( // we need the as any because the JsonApiDashboardPluginOutList does not have the "included" property - pages.flatMap((page: any) => (page as any).included ?? []), + pages.flatMap((page: any) => page.included ?? []), (item: any) => `${item.id}_${item.type}`, ) as any, } as T; diff --git a/libs/api-client-tiger/src/profile.ts b/libs/api-client-tiger/src/profile.ts index 886148a906a..cff61b376d2 100644 --- a/libs/api-client-tiger/src/profile.ts +++ b/libs/api-client-tiger/src/profile.ts @@ -1,4 +1,5 @@ -// (C) 2019-2025 GoodData Corporation +// (C) 2019-2026 GoodData Corporation + import { type AxiosInstance } from "axios"; import { type ApiEntitlement, EntitiesApi_GetEntityUsers } from "./generated/metadata-json-api/index.js"; @@ -64,10 +65,10 @@ export interface IUserProfile { deployment?: string; } -export interface ProfileApiInterface { +export type ProfileApiInterface = { getCurrent: () => Promise; getCurrentWithDetails: () => Promise; -} +}; export const tigerProfileClientFactory = (axios: AxiosInstance): ProfileApiInterface => { return { diff --git a/libs/sdk-backend-base/package.json b/libs/sdk-backend-base/package.json index 9058d953159..01efe3ac25d 100644 --- a/libs/sdk-backend-base/package.json +++ b/libs/sdk-backend-base/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-backend-base", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData.UI SDK - Base for backend implementations", "repository": { "type": "git", diff --git a/libs/sdk-backend-mockingbird/package.json b/libs/sdk-backend-mockingbird/package.json index 787cc00adde..8990a954e42 100644 --- a/libs/sdk-backend-mockingbird/package.json +++ b/libs/sdk-backend-mockingbird/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-backend-mockingbird", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "Mock GoodData Backend SPI implementation", "repository": { "type": "git", diff --git a/libs/sdk-backend-spi/package.json b/libs/sdk-backend-spi/package.json index 2ba368011fb..d2f072d119b 100644 --- a/libs/sdk-backend-spi/package.json +++ b/libs/sdk-backend-spi/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-backend-spi", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData Backend SPI abstraction interfaces", "repository": { "type": "git", diff --git a/libs/sdk-backend-tiger/api/sdk-backend-tiger.api.md b/libs/sdk-backend-tiger/api/sdk-backend-tiger.api.md index c0277865e04..05a05538812 100644 --- a/libs/sdk-backend-tiger/api/sdk-backend-tiger.api.md +++ b/libs/sdk-backend-tiger/api/sdk-backend-tiger.api.md @@ -4,8 +4,6 @@ ```ts -import { AacAnalyticsModel } from '@gooddata/api-client-tiger/endpoints/aac'; -import { AacLogicalModel } from '@gooddata/api-client-tiger/endpoints/aac'; import { ActionsApiProcessInvitationRequest } from '@gooddata/api-client-tiger'; import { AfmExecution } from '@gooddata/api-client-tiger'; import { AnalyzeCsvRequest } from '@gooddata/api-client-tiger'; @@ -24,6 +22,8 @@ import { DependentEntitiesResponse } from '@gooddata/api-client-tiger'; import { GdStorageFile } from '@gooddata/api-client-tiger'; import { GenerateLdmRequest } from '@gooddata/api-client-tiger'; import { HierarchyObjectIdentification } from '@gooddata/api-client-tiger'; +import { IAacAnalyticsModel } from '@gooddata/api-client-tiger/endpoints/aac'; +import { IAacLogicalModel } from '@gooddata/api-client-tiger/endpoints/aac'; import { IAnalyticalBackend } from '@gooddata/sdk-backend-spi'; import { IAnalyticalBackendConfig } from '@gooddata/sdk-backend-spi'; import { IAuthenticatedPrincipal } from '@gooddata/sdk-backend-spi'; @@ -464,10 +464,10 @@ export type TigerSpecificFunctions = { getWorkspaceEntitiesDatasets?: (id: string) => Promise; getEntitlements?: () => Promise>; putWorkspaceLayout?: (requestParameters: PutWorkspaceLayoutRequest) => Promise; - getWorkspaceAnalyticsModelAac?: (workspaceId: string, exclude?: Array<"ACTIVITY_INFO">) => Promise; - setWorkspaceAnalyticsModelAac?: (workspaceId: string, analyticsModel: AacAnalyticsModel) => Promise; - getWorkspaceLogicalModelAac?: (workspaceId: string, includeParents?: boolean) => Promise; - setWorkspaceLogicalModelAac?: (workspaceId: string, logicalModel: AacLogicalModel) => Promise; + getWorkspaceAnalyticsModelAac?: (workspaceId: string, exclude?: Array<"ACTIVITY_INFO">) => Promise; + setWorkspaceAnalyticsModelAac?: (workspaceId: string, analyticsModel: IAacAnalyticsModel) => Promise; + getWorkspaceLogicalModelAac?: (workspaceId: string, includeParents?: boolean) => Promise; + setWorkspaceLogicalModelAac?: (workspaceId: string, logicalModel: IAacLogicalModel) => Promise; getAllDataSources?: () => Promise; getDataSourceById?: (id: string) => Promise; getDataSourceIdentifierById?: (id: string) => Promise; diff --git a/libs/sdk-backend-tiger/package.json b/libs/sdk-backend-tiger/package.json index 135db054cae..ea3379b900c 100644 --- a/libs/sdk-backend-tiger/package.json +++ b/libs/sdk-backend-tiger/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-backend-tiger", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData Backend SPI implementation for GoodData Cloud and GoodData.CN", "repository": { "type": "git", diff --git a/libs/sdk-backend-tiger/src/backend/tigerSpecificFunctions.ts b/libs/sdk-backend-tiger/src/backend/tigerSpecificFunctions.ts index 7feccdfb459..b1842fda1bd 100644 --- a/libs/sdk-backend-tiger/src/backend/tigerSpecificFunctions.ts +++ b/libs/sdk-backend-tiger/src/backend/tigerSpecificFunctions.ts @@ -53,12 +53,12 @@ import { jsonApiHeaders, } from "@gooddata/api-client-tiger"; import { - type AacAnalyticsModel, AacApi_GetAnalyticsModelAac, AacApi_GetLogicalModelAac, AacApi_SetAnalyticsModelAac, AacApi_SetLogicalModelAac, - type AacLogicalModel, + type IAacAnalyticsModel, + type IAacLogicalModel, } from "@gooddata/api-client-tiger/endpoints/aac"; import { ActionsApi_AllPlatformUsage, @@ -461,10 +461,16 @@ export type TigerSpecificFunctions = { getWorkspaceAnalyticsModelAac?: ( workspaceId: string, exclude?: Array<"ACTIVITY_INFO">, - ) => Promise; - setWorkspaceAnalyticsModelAac?: (workspaceId: string, analyticsModel: AacAnalyticsModel) => Promise; - getWorkspaceLogicalModelAac?: (workspaceId: string, includeParents?: boolean) => Promise; - setWorkspaceLogicalModelAac?: (workspaceId: string, logicalModel: AacLogicalModel) => Promise; + ) => Promise; + setWorkspaceAnalyticsModelAac?: ( + workspaceId: string, + analyticsModel: IAacAnalyticsModel, + ) => Promise; + getWorkspaceLogicalModelAac?: ( + workspaceId: string, + includeParents?: boolean, + ) => Promise; + setWorkspaceLogicalModelAac?: (workspaceId: string, logicalModel: IAacLogicalModel) => Promise; getAllDataSources?: () => Promise; getDataSourceById?: (id: string) => Promise; getDataSourceIdentifierById?: (id: string) => Promise; @@ -1083,7 +1089,7 @@ export const buildTigerSpecificFunctions = ( throw convertApiError(error); } }, - setWorkspaceAnalyticsModelAac: async (workspaceId: string, analyticsModel: AacAnalyticsModel) => { + setWorkspaceAnalyticsModelAac: async (workspaceId: string, analyticsModel: IAacAnalyticsModel) => { try { return await authApiCall(async (sdk) => { await AacApi_SetAnalyticsModelAac(sdk.axios, sdk.basePath, { @@ -1108,7 +1114,7 @@ export const buildTigerSpecificFunctions = ( throw convertApiError(error); } }, - setWorkspaceLogicalModelAac: async (workspaceId: string, logicalModel: AacLogicalModel) => { + setWorkspaceLogicalModelAac: async (workspaceId: string, logicalModel: IAacLogicalModel) => { try { return await authApiCall(async (sdk) => { await AacApi_SetLogicalModelAac(sdk.axios, sdk.basePath, { diff --git a/libs/sdk-backend-tiger/src/convertors/fromBackend/MemoryItemConverter.ts b/libs/sdk-backend-tiger/src/convertors/fromBackend/MemoryItemConverter.ts index 1194f09c5a6..fcbdd698bdc 100644 --- a/libs/sdk-backend-tiger/src/convertors/fromBackend/MemoryItemConverter.ts +++ b/libs/sdk-backend-tiger/src/convertors/fromBackend/MemoryItemConverter.ts @@ -1,4 +1,4 @@ -// (C) 2024-2025 GoodData Corporation +// (C) 2024-2026 GoodData Corporation import { invariant } from "ts-invariant"; @@ -11,6 +11,7 @@ import { import { type IMemoryCreatedByUsers } from "@gooddata/sdk-backend-spi"; import { type IMemoryItemMetadataObject, type IUser, idRef } from "@gooddata/sdk-model"; +import { isInheritedObject } from "./ObjectInheritance.js"; import { type IIncludedWithUserIdentifier, convertUserIdentifier } from "./UsersConverter.js"; /** @@ -25,6 +26,7 @@ export function convertMemoryItem( return { id: memoryItem.id, type: "memoryItem", + isLocked: isInheritedObject(memoryItem), title: memoryItem.attributes?.title ?? "", description: memoryItem.attributes?.description ?? "", tags: memoryItem.attributes?.tags, diff --git a/libs/sdk-embedding/package.json b/libs/sdk-embedding/package.json index 4d5305464ee..4fe283d8459 100644 --- a/libs/sdk-embedding/package.json +++ b/libs/sdk-embedding/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-embedding", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData Embedding APIs", "repository": { "type": "git", diff --git a/libs/sdk-model/api/sdk-model.api.md b/libs/sdk-model/api/sdk-model.api.md index 624e1f5eaae..7cf08820050 100644 --- a/libs/sdk-model/api/sdk-model.api.md +++ b/libs/sdk-model/api/sdk-model.api.md @@ -2726,26 +2726,19 @@ export interface IMeasureValueFilterRangeOptions { // @public export interface IMemoryItemDefinition { - // (undocumented) description: string; - // (undocumented) instruction: string; - // (undocumented) isDisabled: boolean; - // (undocumented) keywords?: string[]; - // (undocumented) strategy: MemoryItemStrategy; - // (undocumented) tags?: string[]; - // (undocumented) title: string; } // @public export interface IMemoryItemMetadataObject extends IMetadataObject, IMemoryItemDefinition { - // (undocumented) createdBy: IUser | undefined; + isLocked?: boolean; // (undocumented) type: "memoryItem"; } diff --git a/libs/sdk-model/package.json b/libs/sdk-model/package.json index fbca62eafe5..59a0e5eabd0 100644 --- a/libs/sdk-model/package.json +++ b/libs/sdk-model/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-model", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData Model definitions used by UI components and Backend SPI", "repository": { "type": "git", diff --git a/libs/sdk-model/src/ldm/metadata/memoryItem/index.ts b/libs/sdk-model/src/ldm/metadata/memoryItem/index.ts index f50a985741c..9c82e2d71f9 100644 --- a/libs/sdk-model/src/ldm/metadata/memoryItem/index.ts +++ b/libs/sdk-model/src/ldm/metadata/memoryItem/index.ts @@ -1,4 +1,4 @@ -// (C) 2019-2025 GoodData Corporation +// (C) 2019-2026 GoodData Corporation import { type IUser } from "../../../user/index.js"; import { type IMetadataObject, isMetadataObject } from "../types.js"; @@ -14,12 +14,33 @@ export type MemoryItemStrategy = "ALWAYS" | "AUTO"; * @public */ export interface IMemoryItemDefinition { + /** + * Title associated with the memory item + */ title: string; + /** + * Description associated with the memory item + */ description: string; + /** + * Tags associated with the memory item + */ tags?: string[]; + /** + * Strategy associated with the memory item + */ strategy: MemoryItemStrategy; + /** + * Instructions associated with the memory item + */ instruction: string; + /** + * Whether the memory item is disabled + */ isDisabled: boolean; + /** + * Keywords associated with the memory item + */ keywords?: string[]; } @@ -30,6 +51,15 @@ export interface IMemoryItemDefinition { */ export interface IMemoryItemMetadataObject extends IMetadataObject, IMemoryItemDefinition { type: "memoryItem"; + + /** + * Whether the memory is locked for editing + */ + isLocked?: boolean; + + /** + * The user who created the memory item + */ createdBy: IUser | undefined; } diff --git a/libs/sdk-ui-all/package.json b/libs/sdk-ui-all/package.json index f6fb1de36ca..0a454c3cafd 100644 --- a/libs/sdk-ui-all/package.json +++ b/libs/sdk-ui-all/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-all", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK - All-In-One", "repository": { "type": "git", diff --git a/libs/sdk-ui-catalog/package.json b/libs/sdk-ui-catalog/package.json index 88687e53742..92070b01be1 100644 --- a/libs/sdk-ui-catalog/package.json +++ b/libs/sdk-ui-catalog/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-catalog", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK - Analytics Catalog", "repository": { "type": "git", diff --git a/libs/sdk-ui-catalog/src/catalogDetail/CatalogDetailContent.tsx b/libs/sdk-ui-catalog/src/catalogDetail/CatalogDetailContent.tsx index 77fa72c52d1..b2376abb750 100644 --- a/libs/sdk-ui-catalog/src/catalogDetail/CatalogDetailContent.tsx +++ b/libs/sdk-ui-catalog/src/catalogDetail/CatalogDetailContent.tsx @@ -183,6 +183,7 @@ export function CatalogDetailContent({ { onOpenClick?.(event, { item, diff --git a/libs/sdk-ui-catalog/src/localization/bundles/en-US.json b/libs/sdk-ui-catalog/src/localization/bundles/en-US.json index 0dfc9b7f4e7..53a4f388235 100644 --- a/libs/sdk-ui-catalog/src/localization/bundles/en-US.json +++ b/libs/sdk-ui-catalog/src/localization/bundles/en-US.json @@ -479,6 +479,14 @@ "text": "Last checked: {date}", "crowdinContext": "Text that is prepended to the date of the last check of the quality score card." }, + "analyticsCatalog.quality.severity.warning": { + "text": "{count, plural, one {warning} other {warnings}}", + "crowdinContext": "Semantic quality score card: Accessibility label for the warning severity icon. The number is displayed next to the icon; this label provides only the severity word. Example output: if count is 1, output is 'warning'; if count is 3, output is 'warnings'." + }, + "analyticsCatalog.quality.severity.suggestion": { + "text": "{count, plural, one {suggestion} other {suggestions}}", + "crowdinContext": "Semantic quality score card: Accessibility label for the suggestion severity icon. The number is displayed next to the icon; this label provides only the severity word. Example output: if count is 1, output is 'suggestion'; if count is 3, output is 'suggestions'." + }, "metricComponent.metricType.label": { "text": "Metric type", "crowdinContext": "Analytics Catalog detail drawer: Label for the dropdown that selects whether a measure is treated as currency or left unspecified." diff --git a/libs/sdk-ui-catalog/src/quality/QualityScoreCardScore.tsx b/libs/sdk-ui-catalog/src/quality/QualityScoreCardScore.tsx index 88c212347f1..f4f12d746b5 100644 --- a/libs/sdk-ui-catalog/src/quality/QualityScoreCardScore.tsx +++ b/libs/sdk-ui-catalog/src/quality/QualityScoreCardScore.tsx @@ -27,7 +27,7 @@ export function QualityScoreCardScore({ issues, isLoading }: Props) { return (
{issues.length} - +
); }) diff --git a/libs/sdk-ui-catalog/src/quality/QualitySeverityIcon.tsx b/libs/sdk-ui-catalog/src/quality/QualitySeverityIcon.tsx index fb4e962fcae..6bbd99fdc0f 100644 --- a/libs/sdk-ui-catalog/src/quality/QualitySeverityIcon.tsx +++ b/libs/sdk-ui-catalog/src/quality/QualitySeverityIcon.tsx @@ -1,5 +1,7 @@ // (C) 2025-2026 GoodData Corporation +import { useIntl } from "react-intl"; + import type { SemanticQualityIssueSeverity } from "@gooddata/sdk-model"; import { type ThemeColor, UiIcon } from "@gooddata/sdk-ui-kit"; @@ -8,9 +10,13 @@ type Props = { size?: number; backgroundSize?: number; backgroundColor?: ThemeColor; + /** Optional count of issues for this severity. Used for pluralized accessible label. */ + count?: number; }; -export function QualitySeverityIcon({ severity, size, backgroundSize, backgroundColor }: Props) { +export function QualitySeverityIcon({ severity, count = 1, size, backgroundSize, backgroundColor }: Props) { + const intl = useIntl(); + if (severity === "WARNING") { return ( ); } @@ -29,6 +41,12 @@ export function QualitySeverityIcon({ severity, size, backgroundSize, background size={size} backgroundSize={backgroundSize} backgroundColor={backgroundColor} + accessibilityConfig={{ + ariaLabel: intl.formatMessage( + { id: "analyticsCatalog.quality.severity.suggestion" }, + { count }, + ), + }} /> ); } diff --git a/libs/sdk-ui-catalog/styles/scss/detail.scss b/libs/sdk-ui-catalog/styles/scss/detail.scss index a5d5af18623..e61ade0e6e6 100644 --- a/libs/sdk-ui-catalog/styles/scss/detail.scss +++ b/libs/sdk-ui-catalog/styles/scss/detail.scss @@ -14,10 +14,13 @@ $content-font-size: 14px; .gd-analytics-catalog-detail { font-family: kit-variables.$gd-font-primary; font-size: $content-font-size; - min-width: $width; - max-width: $width; + width: $width; height: 100%; + @media #{kit-variables.$small-only} { + width: 100%; + } + &__loading, &__error { display: flex; diff --git a/libs/sdk-ui-catalog/styles/scss/main.scss b/libs/sdk-ui-catalog/styles/scss/main.scss index a466e7c1b2f..e0c03b9b841 100644 --- a/libs/sdk-ui-catalog/styles/scss/main.scss +++ b/libs/sdk-ui-catalog/styles/scss/main.scss @@ -103,6 +103,7 @@ $content-font-size: 14px; display: flex; gap: 10px; align-items: center; + flex-wrap: wrap; &__title { font-size: 11px; @@ -196,7 +197,9 @@ $content-font-size: 14px; } &__quality-score-card { - width: 280px; + box-sizing: border-box; + width: 100%; + max-width: 280px; display: grid; grid-template-columns: 1fr auto; align-items: center; diff --git a/libs/sdk-ui-charts/package.json b/libs/sdk-ui-charts/package.json index b284fa8e4c2..b43818c9185 100644 --- a/libs/sdk-ui-charts/package.json +++ b/libs/sdk-ui-charts/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-charts", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData.UI SDK - Charts", "repository": { "type": "git", diff --git a/libs/sdk-ui-charts/src/charts/headline/internal/headlines/baseHeadline/baseHeadlineDataItems/withTitle.tsx b/libs/sdk-ui-charts/src/charts/headline/internal/headlines/baseHeadline/baseHeadlineDataItems/withTitle.tsx index 3140acb626c..fb87cf6a9f5 100644 --- a/libs/sdk-ui-charts/src/charts/headline/internal/headlines/baseHeadline/baseHeadlineDataItems/withTitle.tsx +++ b/libs/sdk-ui-charts/src/charts/headline/internal/headlines/baseHeadline/baseHeadlineDataItems/withTitle.tsx @@ -1,4 +1,4 @@ -// (C) 2023-2025 GoodData Corporation +// (C) 2023-2026 GoodData Corporation import { type ComponentType } from "react"; @@ -12,9 +12,10 @@ export const withTitle = ( function WithTitle(props: T & IWithTitleProps) { const { shouldHideTitle, titleRef, dataItem } = props; return ( - <> - - {shouldHideTitle ? null : ( +
+ {shouldHideTitle ? ( +
{dataItem?.title}
+ ) : (
( {dataItem?.title}
)} - + +
); } return wrapDisplayName("withTitle", BaseHeadlineDataItem)(WithTitle); diff --git a/libs/sdk-ui-charts/styles/scss/headline.scss b/libs/sdk-ui-charts/styles/scss/headline.scss index 2ce70ac99de..564e242abd2 100644 --- a/libs/sdk-ui-charts/styles/scss/headline.scss +++ b/libs/sdk-ui-charts/styles/scss/headline.scss @@ -11,6 +11,17 @@ width: 100%; height: 100%; + // Wrapper for items with title and value + .headline-item-with-title { + display: contents; // Don't interfere with parent layout + } + + // In compare section, apply flex layout and reverse visual order + .headline-compare-section-item .headline-item-with-title { + display: flex; + flex-direction: column-reverse; + } + .primary-section { &.gd-flex-container { justify-content: center; diff --git a/libs/sdk-ui-dashboard/package.json b/libs/sdk-ui-dashboard/package.json index 2476a54b6e5..349f5c03b7c 100644 --- a/libs/sdk-ui-dashboard/package.json +++ b/libs/sdk-ui-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-dashboard", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK - Dashboard Component", "repository": { "type": "git", diff --git a/libs/sdk-ui-dashboard/src/kdaDialog/components/bars/AttributeBar.tsx b/libs/sdk-ui-dashboard/src/kdaDialog/components/bars/AttributeBar.tsx index 1766c8b682c..5dd732a4da8 100644 --- a/libs/sdk-ui-dashboard/src/kdaDialog/components/bars/AttributeBar.tsx +++ b/libs/sdk-ui-dashboard/src/kdaDialog/components/bars/AttributeBar.tsx @@ -1,4 +1,4 @@ -// (C) 2025 GoodData Corporation +// (C) 2025-2026 GoodData Corporation import { type MutableRefObject, useCallback, useId } from "react"; @@ -166,6 +166,8 @@ function KdaAttributeFilterDropdownButtonComponent( }} accessibilityConfig={{ isExpanded: props.isOpen, + popupId: props.dropdownId, + popupType: "dialog", deleteAriaLabel: props.deleteAriaLabel, ariaDescribedBy: attributeFilterTooltipId, }} diff --git a/libs/sdk-ui-dashboard/src/kdaDialog/components/bars/DateBar.tsx b/libs/sdk-ui-dashboard/src/kdaDialog/components/bars/DateBar.tsx index 158f4092ac9..b90a8a72318 100644 --- a/libs/sdk-ui-dashboard/src/kdaDialog/components/bars/DateBar.tsx +++ b/libs/sdk-ui-dashboard/src/kdaDialog/components/bars/DateBar.tsx @@ -1,4 +1,4 @@ -// (C) 2025 GoodData Corporation +// (C) 2025-2026 GoodData Corporation import { type RefObject, useMemo, useRef, useState } from "react"; @@ -21,6 +21,7 @@ export function DateBar(props: IDateBarProps) { const intl = useIntl(); const ref = useRef(null); const [isActive, setIsActive] = useState(false); + const listboxId = "kda-dialog-date-bar"; const splitter = intl.formatMessage({ id: "kdaDialog.dialog.bars.date.splitter" }); const label = intl.formatMessage( @@ -59,7 +60,19 @@ export function DateBar(props: IDateBarProps) { anchor={ } + anchor={ + + } title={intl.formatMessage({ id: "kdaDialog.dialog.bars.date.period.title" })} initialFocus={ref as RefObject} content={({ onClose }) => ( @@ -69,7 +82,7 @@ export function DateBar(props: IDateBarProps) { selectedItemId={props.options.period} items={items} ariaAttributes={{ - id: "kda-dialog-date-bar", + id: listboxId, }} onClose={onClose} onSelect={(item) => { diff --git a/libs/sdk-ui-dashboard/src/kdaDialog/composition/AddFilterButton.tsx b/libs/sdk-ui-dashboard/src/kdaDialog/composition/AddFilterButton.tsx index d6e41a7afe8..5215094c954 100644 --- a/libs/sdk-ui-dashboard/src/kdaDialog/composition/AddFilterButton.tsx +++ b/libs/sdk-ui-dashboard/src/kdaDialog/composition/AddFilterButton.tsx @@ -1,4 +1,4 @@ -// (C) 2025 GoodData Corporation +// (C) 2025-2026 GoodData Corporation import { type RefObject, useCallback, useId, useMemo } from "react"; @@ -45,7 +45,7 @@ export function AddFilterButton() { ref={buttonRef as RefObject} accessibilityConfig={{ ariaLabel: tooltipText, - ariaControls: attributesDropdownId, + ariaControls: isOpen ? attributesDropdownId : undefined, ariaExpanded: isOpen, ariaHaspopup: "dialog", }} diff --git a/libs/sdk-ui-dashboard/src/kdaDialog/dialog/KdaDialog.tsx b/libs/sdk-ui-dashboard/src/kdaDialog/dialog/KdaDialog.tsx index 2a643701408..19e115a2c3a 100644 --- a/libs/sdk-ui-dashboard/src/kdaDialog/dialog/KdaDialog.tsx +++ b/libs/sdk-ui-dashboard/src/kdaDialog/dialog/KdaDialog.tsx @@ -28,6 +28,9 @@ import { KdaErrorComponent, KdaErrorType } from "../components/KdaErrorComponent const overlayController = OverlayController.getInstance(KDA_DIALOG_OVERS_Z_INDEX); +const KDA_DIALOG_MINIMIZED_DATA_TEST_ID = "kda-dialog-minimized"; +const KDA_DIALOG_EXPANDED_DATA_TEST_ID = "kda-dialog-expanded"; + /** * @internal */ @@ -65,6 +68,7 @@ export function KdaDialog({ className, showCloseButton = true, onClose }: IKdaDi displayCloseButton={displayCloseButton} onClose={onClose} CloseButton={KdaDialogControls} + dataTestId={KDA_DIALOG_MINIMIZED_DATA_TEST_ID} > , + attributeFilterDisplayAsLabelMap: Map, +): boolean { + return drillIntersectionFilters.some(({ attributeFilter, primaryLabel }) => { + const displayForm = attributeFilter.attributeFilter.displayForm; + return ( + findMatchingVirtualFilter( + [virtualFilter], + attributeFilterDisplayAsLabelMap, + displayForm, + primaryLabel, + ) !== undefined + ); + }); +} + function shouldUpdateExistingFiltering( crossFilteringItemByWidget: { filterLocalIdentifiers: string[] } | undefined, - drillIntersectionFiltersLength: number, + drillIntersectionFilters: ReturnType, + currentVirtualFilters: IDashboardAttributeFilter[], + attributeFilterDisplayAsLabelMap: Map, ): boolean { - /** - * Intersection may have multiple lengths in pivot table so we need to make sure that when we are updating existing - * cross-filtering, the intersection length has to be larger or the same than the current virtual filters length. - * Otherwise we would want the cross-filtering to be reset together with all virtual filters. - */ - return ( - !isEmpty(crossFilteringItemByWidget) && - crossFilteringItemByWidget!.filterLocalIdentifiers.length <= drillIntersectionFiltersLength + if (isEmpty(crossFilteringItemByWidget)) { + return false; + } + + // Intersection may have multiple lengths in pivot table so we need to make sure that when we are updating existing + // cross-filtering, the intersection length has to be larger or the same than the current virtual filters length. + // Otherwise we would want the cross-filtering to be reset together with all virtual filters. + if (crossFilteringItemByWidget!.filterLocalIdentifiers.length > drillIntersectionFilters.length) { + return false; + } + + // Only update if every existing filter has a matching attribute in the new intersection. + // This prevents filter accumulation when clicking on different structures (e.g., different geo chart layers + // with different attributes) while still allowing updates when clicking on the same structure with different values. + return currentVirtualFilters.every((vf) => + virtualFilterHasMatchInIntersection(vf, drillIntersectionFilters, attributeFilterDisplayAsLabelMap), ); } @@ -134,7 +165,9 @@ export function* crossFilteringHandler(ctx: DashboardContext, cmd: CrossFilterin const shouldUpdateExisting = shouldUpdateExistingFiltering( crossFilteringItemByWidget, - drillIntersectionFilters.length, + drillIntersectionFilters, + currentVirtualFilters, + attributeFilterDisplayAsLabelMap, ); const virtualFilters = drillIntersectionFilters.map((drillFilterData, i) => { diff --git a/libs/sdk-ui-dashboard/src/presentation/automationFilters/components/AutomationFiltersSelect.tsx b/libs/sdk-ui-dashboard/src/presentation/automationFilters/components/AutomationFiltersSelect.tsx index 36c93d4f09a..4dc92644bdb 100644 --- a/libs/sdk-ui-dashboard/src/presentation/automationFilters/components/AutomationFiltersSelect.tsx +++ b/libs/sdk-ui-dashboard/src/presentation/automationFilters/components/AutomationFiltersSelect.tsx @@ -1,4 +1,4 @@ -// (C) 2025 GoodData Corporation +// (C) 2025-2026 GoodData Corporation import { type KeyboardEvent, type ReactElement, type ReactNode, useState } from "react"; @@ -419,7 +419,9 @@ export function AutomationFiltersSelect({ }} accessibilityConfig={{ ariaLabel: tabTooltipText, - ariaControls: `${AUTOMATION_FILTERS_DIALOG_ID}-${tab.tabId}`, + ariaControls: isOpen + ? `${AUTOMATION_FILTERS_DIALOG_ID}-${tab.tabId}` + : undefined, ariaExpanded: isOpen, ariaHaspopup: "dialog", }} @@ -534,7 +536,9 @@ export function AutomationFiltersSelect({ }} accessibilityConfig={{ ariaLabel: tooltipText, - ariaControls: AUTOMATION_FILTERS_DIALOG_ID, + ariaControls: isOpen + ? AUTOMATION_FILTERS_DIALOG_ID + : undefined, ariaExpanded: isOpen, ariaHaspopup: "dialog", }} diff --git a/libs/sdk-ui-dashboard/src/presentation/localization/bundles/en-US.json b/libs/sdk-ui-dashboard/src/presentation/localization/bundles/en-US.json index 0f8061f9b89..884bd0adaa9 100644 --- a/libs/sdk-ui-dashboard/src/presentation/localization/bundles/en-US.json +++ b/libs/sdk-ui-dashboard/src/presentation/localization/bundles/en-US.json @@ -396,8 +396,8 @@ "crowdinContext": "Label for viewing more details about drill interactions" }, "drill_modal_picker.drill_to_url.disabled.missing_attributes": { - "text": "Drill action unavailable. Missing attributes: {attributes}", - "crowdinContext": "Tooltip text shown when a drill to URL action is disabled because required attribute values are not present in the clicked data point. The {attributes} placeholder contains a comma-separated list of missing attribute names. Example output: 'Drill unavailable. Missing attributes: City, Region'" + "text": "Error: Drill unavailable. Select an item that includes: {attributes}.", + "crowdinContext": "Tooltip text shown when a drill to URL action is disabled because required attribute values are not present in the clicked data point. The {attributes} placeholder contains a comma-separated list of missing attribute names." }, "drill_modal_picker.label": { "text": "Choose drill action", diff --git a/libs/sdk-ui-dashboard/src/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogExportDropdown.tsx b/libs/sdk-ui-dashboard/src/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogExportDropdown.tsx index 8e499b10475..415c7587595 100644 --- a/libs/sdk-ui-dashboard/src/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogExportDropdown.tsx +++ b/libs/sdk-ui-dashboard/src/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogExportDropdown.tsx @@ -1,4 +1,4 @@ -// (C) 2021-2025 GoodData Corporation +// (C) 2021-2026 GoodData Corporation import { useCallback } from "react"; @@ -204,7 +204,10 @@ function DropdownTriggerButton({ label={formatMessage({ id: "dialogs.export.submit" })} variant="tertiary" isDisabled={isDisabled} - accessibilityConfig={accessibilityConfig} + accessibilityConfig={{ + ...accessibilityConfig, + ariaHaspopup: "menu", + }} /> ); } diff --git a/libs/sdk-ui-dashboard/src/presentation/widget/insightMenu/DefaultDashboardInsightMenu/DashboardInsightMenuButton.tsx b/libs/sdk-ui-dashboard/src/presentation/widget/insightMenu/DefaultDashboardInsightMenu/DashboardInsightMenuButton.tsx index 3668eebfbe5..9197b35420f 100644 --- a/libs/sdk-ui-dashboard/src/presentation/widget/insightMenu/DefaultDashboardInsightMenu/DashboardInsightMenuButton.tsx +++ b/libs/sdk-ui-dashboard/src/presentation/widget/insightMenu/DefaultDashboardInsightMenu/DashboardInsightMenuButton.tsx @@ -1,4 +1,4 @@ -// (C) 2021-2025 GoodData Corporation +// (C) 2021-2026 GoodData Corporation import { type KeyboardEvent, type ReactElement, useCallback } from "react"; @@ -40,6 +40,7 @@ export function DashboardInsightMenuButton({ } const widgetRefAsString = objRefToString(widgetRef(widget)); + const menuId = `insight-menu-${widgetRefAsString}`; const optionsIconClasses = cx( "dash-item-action-options", @@ -68,6 +69,9 @@ export function DashboardInsightMenuButton({ role="button" tabIndex={0} aria-label={intl.formatMessage({ id: "controlButtons.options.tooltip" })} + aria-expanded={isOpen} + aria-haspopup="menu" + aria-controls={isOpen ? menuId : undefined} >
diff --git a/libs/sdk-ui-ext/package.json b/libs/sdk-ui-ext/package.json index 79ed273bbd7..5f92c0a7075 100644 --- a/libs/sdk-ui-ext/package.json +++ b/libs/sdk-ui-ext/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-ext", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData.UI SDK - Extensions", "repository": { "type": "git", diff --git a/libs/sdk-ui-filters/package.json b/libs/sdk-ui-filters/package.json index f5fe1ea5f96..14088e14225 100644 --- a/libs/sdk-ui-filters/package.json +++ b/libs/sdk-ui-filters/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-filters", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData.UI SDK - Filter Components", "repository": { "type": "git", diff --git a/libs/sdk-ui-filters/src/MeasureValueFilter/AttributePicker.tsx b/libs/sdk-ui-filters/src/MeasureValueFilter/AttributePicker.tsx index 71b57ad2dec..d9d693a0279 100644 --- a/libs/sdk-ui-filters/src/MeasureValueFilter/AttributePicker.tsx +++ b/libs/sdk-ui-filters/src/MeasureValueFilter/AttributePicker.tsx @@ -14,6 +14,7 @@ import { UiIcon, UiIconButton, UiListbox, + UiSubmenuHeader, } from "@gooddata/sdk-ui-kit"; import { type IDateDatasetOption, type IDimensionalityItem } from "./typings.js"; @@ -244,21 +245,11 @@ export const AttributePicker = memo(function AttributePicker({ className="gd-mvf-attribute-picker-body s-mvf-attribute-picker" data-testid="mvf-attribute-picker" > -
-
- {intl.formatMessage({ id: "mvf.attributePicker.title" })} -
- -
+
{ +/** + * Get the user message before the assistant message, or undefined if there isn't one. + * This is useful for dynamically created assistant messages that don't have a preceding user message. + */ +const getUserMessageBeforeSafe = ( + state: MessagesSliceState, + assistantMessageId: string, +): UserMessage | undefined => { const messageIndex = state.messageOrder.indexOf(assistantMessageId); - const message = state.messages[state.messageOrder[messageIndex - 1]]; - if (!isUserMessage(message)) { - throw new Error(`Unexpected error during message evaluation.`); + if (messageIndex <= 0) { + return undefined; } - return message; + const message = state.messages[state.messageOrder[messageIndex - 1]]; + return isUserMessage(message) ? message : undefined; }; const messagesSlice = createSlice({ @@ -211,9 +218,13 @@ const messagesSlice = createSlice({ assistantMessage.content.push(...payload.contents); assistantMessage.cancelled = false; - // Also update the interaction id in the relevant user message - const userMessage = getUserMessageBeforeStrict(state, payload.assistantMessageId); - userMessage.id = payload.interactionId ?? userMessage.id; + // Also update the interaction id in the relevant user message (if one exists) + // Note: dynamically created assistant messages (for multi-interaction streams) + // may not have a preceding user message + const userMessage = getUserMessageBeforeSafe(state, payload.assistantMessageId); + if (userMessage) { + userMessage.id = payload.interactionId ?? userMessage.id; + } }, evaluateMessageCompleteAction: ( state, diff --git a/libs/sdk-ui-gen-ai/src/store/sideEffects/onUserMessage.ts b/libs/sdk-ui-gen-ai/src/store/sideEffects/onUserMessage.ts index 7e89df45799..3322d15a03b 100644 --- a/libs/sdk-ui-gen-ai/src/store/sideEffects/onUserMessage.ts +++ b/libs/sdk-ui-gen-ai/src/store/sideEffects/onUserMessage.ts @@ -1,4 +1,4 @@ -// (C) 2024-2025 GoodData Corporation +// (C) 2024-2026 GoodData Corporation import { type PayloadAction } from "@reduxjs/toolkit"; import { call, cancel, cancelled, getContext, put, select } from "redux-saga/effects"; @@ -34,7 +34,8 @@ import { * @internal */ export function* onUserMessage({ payload }: PayloadAction) { - let newAssistantMessage: AssistantMessage | undefined = undefined; + let initialAssistantMessage: AssistantMessage | undefined = undefined; + let lastAssistantMessage: AssistantMessage | undefined = undefined; try { // Make sure the message is a user message and it got text contents @@ -49,10 +50,10 @@ export function* onUserMessage({ payload }: PayloadAction) { } // Create a new empty assistant message - newAssistantMessage = makeAssistantMessage([]); + initialAssistantMessage = makeAssistantMessage([]); // Set evaluation state in store - yield put(evaluateMessageAction({ message: newAssistantMessage })); + yield put(evaluateMessageAction({ message: initialAssistantMessage })); // Retrieve backend from context const backend: IAnalyticalBackend = yield getContext("backend"); @@ -61,14 +62,23 @@ export function* onUserMessage({ payload }: PayloadAction) { // Make the request to start the evaluation const chatThreadQuery = backend.workspace(workspace).genAI().getChatThread().query(textContents); - yield call(evaluateUserMessage, newAssistantMessage, chatThreadQuery); + // evaluateUserMessage may create additional assistant messages if the stream contains + // multiple interaction IDs. It returns the last message that needs to be completed. + const result: EvaluateUserMessageResult = yield call( + evaluateUserMessage, + initialAssistantMessage, + chatThreadQuery, + ); + lastAssistantMessage = result.lastAssistantMessage; } catch (e) { const wasCanceled: boolean = yield cancelled(); - if (newAssistantMessage && !wasCanceled) { + // On error, mark the last known message (or initial if no result yet) + const messageToError = lastAssistantMessage ?? initialAssistantMessage; + if (messageToError && !wasCanceled) { yield put( evaluateMessageErrorAction({ - assistantMessageId: newAssistantMessage.localId, + assistantMessageId: messageToError.localId, error: extractError(e), }), ); @@ -76,22 +86,46 @@ export function* onUserMessage({ payload }: PayloadAction) { } finally { const wasCanceled: boolean = yield cancelled(); - if (newAssistantMessage && !wasCanceled) { - yield put( - evaluateMessageCompleteAction({ - assistantMessageId: newAssistantMessage.localId, - }), - ); + // Mark the last assistant message as complete + const messageToComplete = lastAssistantMessage ?? initialAssistantMessage; + if (messageToComplete && !wasCanceled) { + // Check if the message still exists before marking it complete + // (it may have been removed if the chat was cleared) + const currentMessages: Message[] = yield select(messagesSelector); + const messageExists = currentMessages.some((m) => m.localId === messageToComplete.localId); + + if (messageExists) { + yield put( + evaluateMessageCompleteAction({ + assistantMessageId: messageToComplete.localId, + }), + ); + } } } } +/** + * Result of evaluating a user message, containing all assistant messages created during the stream. + */ +type EvaluateUserMessageResult = { + /** + * The last assistant message that was being processed when the stream ended. + * This is the message that needs to be marked as complete by the caller. + */ + lastAssistantMessage: AssistantMessage; +}; + function* evaluateUserMessage(message: AssistantMessage, preparedChatThread: IChatThreadQuery) { let reader: ReadableStreamReader | undefined = undefined; const settings: IUserWorkspaceSettings | undefined = yield select(settingsSelector); const objectTypes: GenAIObjectType[] | undefined = yield select(objectTypesSelector); const showReasoning = Boolean(settings?.enableGenAIReasoningVisibility); + // Track interaction ID to assistant message mapping + let currentAssistantMessage = message; + let currentInteractionId: string | undefined = undefined; + try { const results: ReadableStream = yield call([ preparedChatThread @@ -112,15 +146,52 @@ function* evaluateUserMessage(message: AssistantMessage, preparedChatThread: ICh } if (value) { + const chunkInteractionId = value.chatHistoryInteractionId; + + // If we see a NEW interaction ID, create a new assistant message + if ( + chunkInteractionId && + currentInteractionId && + chunkInteractionId !== currentInteractionId + ) { + // Check if the current message still exists before marking it complete + // (it may have been removed if the chat was cleared) + const currentMessages: Message[] = yield select(messagesSelector); + const messageExists = currentMessages.some( + (m) => m.localId === currentAssistantMessage.localId, + ); + + if (messageExists) { + // Mark current message as complete + yield put( + evaluateMessageCompleteAction({ + assistantMessageId: currentAssistantMessage.localId, + }), + ); + } + + // Create new assistant message for the new interaction + currentAssistantMessage = makeAssistantMessage([]); + yield put(evaluateMessageAction({ message: currentAssistantMessage })); + } + + // Track the current interaction ID + if (chunkInteractionId) { + currentInteractionId = chunkInteractionId; + } + + // Dispatch streaming content to current message yield put( evaluateMessageStreamingAction({ - assistantMessageId: message.localId, - interactionId: value.chatHistoryInteractionId, + assistantMessageId: currentAssistantMessage.localId, + interactionId: chunkInteractionId, contents: processContents(value, true, { showReasoning }), }), ); } } + + return { lastAssistantMessage: currentAssistantMessage }; } finally { if (reader) { const wasCancelled: boolean = yield cancelled(); @@ -134,7 +205,7 @@ function* evaluateUserMessage(message: AssistantMessage, preparedChatThread: ICh //Cancel saga const messages: Message[] = yield select(messagesSelector); - const found = messages.find((m) => m.localId === message.localId); + const found = messages.find((m) => m.localId === currentAssistantMessage.localId); if (!found) { yield cancel(); } diff --git a/libs/sdk-ui-geo/package.json b/libs/sdk-ui-geo/package.json index ff292ed530a..5ab7f8aa61e 100644 --- a/libs/sdk-ui-geo/package.json +++ b/libs/sdk-ui-geo/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-geo", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData.UI SDK - Geo Charts", "repository": { "type": "git", diff --git a/libs/sdk-ui-kit/api/sdk-ui-kit.api.md b/libs/sdk-ui-kit/api/sdk-ui-kit.api.md index 71f82c16e02..99b32eabf10 100644 --- a/libs/sdk-ui-kit/api/sdk-ui-kit.api.md +++ b/libs/sdk-ui-kit/api/sdk-ui-kit.api.md @@ -1974,6 +1974,8 @@ export interface IDialogBaseProps { CloseButton?: ComponentType; containerClassName?: string; // (undocumented) + dataTestId?: string; + // (undocumented) displayCloseButton?: boolean; focusCheckFn?: (element: HTMLElement) => boolean; // (undocumented) diff --git a/libs/sdk-ui-kit/package.json b/libs/sdk-ui-kit/package.json index 065017a260d..8757d7c9ad1 100644 --- a/libs/sdk-ui-kit/package.json +++ b/libs/sdk-ui-kit/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-kit", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK - UI Building Components", "repository": { "type": "git", diff --git a/libs/sdk-ui-kit/src/@ui/UiAsyncTable/UiAsyncTable/UiAsyncTableRow.tsx b/libs/sdk-ui-kit/src/@ui/UiAsyncTable/UiAsyncTable/UiAsyncTableRow.tsx index ea0abdeb193..53b0fc98176 100644 --- a/libs/sdk-ui-kit/src/@ui/UiAsyncTable/UiAsyncTable/UiAsyncTableRow.tsx +++ b/libs/sdk-ui-kit/src/@ui/UiAsyncTable/UiAsyncTable/UiAsyncTableRow.tsx @@ -59,6 +59,7 @@ export function UiAsyncTableRow({ })} ref={isRowFocused ? (focusedElementRef as Ref) : undefined} role="row" + aria-rowindex={itemIndex + 1} aria-labelledby={getRowLabelId(itemIndex)} > {hasCheckbox && item ? ( diff --git a/libs/sdk-ui-kit/src/@ui/UiChip/ChipContent.tsx b/libs/sdk-ui-kit/src/@ui/UiChip/ChipContent.tsx index 5e2bc9e26a3..a0d19f7067d 100644 --- a/libs/sdk-ui-kit/src/@ui/UiChip/ChipContent.tsx +++ b/libs/sdk-ui-kit/src/@ui/UiChip/ChipContent.tsx @@ -22,12 +22,13 @@ export function ChipContent({ buttonRef, styleObj, }: IChipContentProps) { - const { isExpanded, popupId, ariaLabel, ariaLabelledBy, ariaControls } = accessibilityConfig ?? {}; + const { isExpanded, popupId, popupType, ariaHaspopup, ariaLabel, ariaLabelledBy, ariaControls } = + accessibilityConfig ?? {}; const ariaDropdownProps = { ...(popupId && isExpanded ? { "aria-controls": popupId } : {}), - ...(popupId ? { "aria-haspopup": !!popupId } : {}), + ...(!popupId && isExpanded && ariaControls ? { "aria-controls": ariaControls } : {}), + ...(popupId ? { "aria-haspopup": popupType ?? ariaHaspopup ?? !!popupId } : {}), ...(isExpanded === undefined ? {} : { "aria-expanded": isExpanded }), - ...(ariaControls ? { "aria-controls": ariaControls } : {}), }; return ( diff --git a/libs/sdk-ui-kit/src/@ui/UiDrawer/UiDrawer.scss b/libs/sdk-ui-kit/src/@ui/UiDrawer/UiDrawer.scss index feaaa3e86c2..bc8e6f37ee5 100644 --- a/libs/sdk-ui-kit/src/@ui/UiDrawer/UiDrawer.scss +++ b/libs/sdk-ui-kit/src/@ui/UiDrawer/UiDrawer.scss @@ -21,7 +21,7 @@ top: 0; left: 0; bottom: 0; - max-width: 80vw; + max-width: 100vw; transform: translateX(-105%); border-right: 1px solid variables.$gd-border-color; } @@ -45,7 +45,7 @@ top: 0; right: 0; bottom: 0; - max-width: 80vw; + max-width: 100vw; transform: translateX(105%); border-left: 1px solid variables.$gd-border-color; } @@ -60,6 +60,15 @@ } } + @media #{variables.$small-only} { + &--anchor-left, + &--anchor-right { + #{$root}__content { + width: 100vw; + } + } + } + &__backdrop { position: absolute; top: 0; diff --git a/libs/sdk-ui-kit/src/@ui/UiNavigationBypass/UiNavigationBypass.scss b/libs/sdk-ui-kit/src/@ui/UiNavigationBypass/UiNavigationBypass.scss index 1d21f155e9a..96f709448de 100644 --- a/libs/sdk-ui-kit/src/@ui/UiNavigationBypass/UiNavigationBypass.scss +++ b/libs/sdk-ui-kit/src/@ui/UiNavigationBypass/UiNavigationBypass.scss @@ -38,6 +38,7 @@ $navigation-bypass-item-line-height: 18px; } &__dropdown-item { + box-sizing: border-box; display: flex; align-items: center; align-self: stretch; diff --git a/libs/sdk-ui-kit/src/@ui/UiPagedVirtualList/UiPagedVirtualList.tsx b/libs/sdk-ui-kit/src/@ui/UiPagedVirtualList/UiPagedVirtualList.tsx index eedbad85566..864e0a78781 100644 --- a/libs/sdk-ui-kit/src/@ui/UiPagedVirtualList/UiPagedVirtualList.tsx +++ b/libs/sdk-ui-kit/src/@ui/UiPagedVirtualList/UiPagedVirtualList.tsx @@ -158,6 +158,7 @@ function UiPagedVirtualListNotWrapped( onKeyDown={ tabIndex < 0 ? undefined : (customKeyboardNavigationHandler ?? onKeyboardNavigation) } + role={representAs === "grid" ? "rowgroup" : undefined} {...listboxProps} > {virtualItems.map((virtualRow) => { diff --git a/libs/sdk-ui-kit/src/Dialog/DialogBase.tsx b/libs/sdk-ui-kit/src/Dialog/DialogBase.tsx index a5fe74701e9..bbf117536e9 100644 --- a/libs/sdk-ui-kit/src/Dialog/DialogBase.tsx +++ b/libs/sdk-ui-kit/src/Dialog/DialogBase.tsx @@ -1,4 +1,4 @@ -// (C) 2020-2025 GoodData Corporation +// (C) 2020-2026 GoodData Corporation import { type KeyboardEvent, type KeyboardEventHandler, memo, useCallback } from "react"; @@ -33,6 +33,7 @@ export const DialogBase = memo(function DialogBase({ onClose, accessibilityConfig, className, + dataTestId, autofocusOnOpen = true, refocusKey, children, @@ -74,6 +75,7 @@ export const DialogBase = memo(function DialogBase({
({ - ...prevState, - childrenWidth, - })); + setState((prevState) => { + // When responsive mode is active, the header DOM no longer contains the full set of + // elements used for width measurement (e.g. horizontal menu sections), so updating the + // measured width would be incorrect and could lead to mode thrashing. + if (prevState.responsiveMode) { + return prevState; + } + if (prevState.childrenWidth === childrenWidth) { + return prevState; + } + return { ...prevState, childrenWidth }; + }); }, []); + useEffect(() => { + // Re-measure the header content width whenever the rendered header content changes. + // + // This is important for apps that load header menu items/workspace picker content + // asynchronously after the header is mounted (e.g. permissions-driven menus). + if (!state.responsiveMode) { + measureChildren(); + } + }, [ + measureChildren, + state.responsiveMode, + menuItemsGroups, + accountMenuItems, + helpMenuItems, + search, + notificationsPanel, + badges, + showChatItem, + showUpsellButton, + expiredDate, + userName, + documentationUrl, + helpRedirectUrl, + disableHelpDropdown, + ]); + const measure = useCallback(() => { const currentDOMNode = nodeRef.current; if (!currentDOMNode) { @@ -183,6 +217,10 @@ export const AppHeader = withTheme(function AppHeader({ stylesheetRef.current = addCssToStylesheet(`header-css-${guid}`, css.join("\n"), true); }, [state, activeColor, headerColor, headerTextColor]); + useEffect(() => { + createStyles(); + }, [createStyles]); + const setOverlayMenu = useCallback((isOverlayMenuOpen: boolean) => { setState((prevState) => ({ ...prevState, @@ -235,17 +273,15 @@ export const AppHeader = withTheme(function AppHeader({ })); }, []); - const setHelpMenu = useCallback((isHelpMenuOpen: boolean) => { + const toggleHelpMenu = useCallback(() => { setState((prevState) => ({ ...prevState, - isHelpMenuOpen, + isHelpMenuOpen: !prevState.isHelpMenuOpen, isSearchMenuOpen: false, isNotificationsMenuOpen: false, })); }, []); - const toggleHelpMenu = useCallback(() => setHelpMenu(!state.isHelpMenuOpen), [setHelpMenu, state]); - const handleMenuItemClick = useCallback( (item: IHeaderMenuItem, event: MouseEvent) => { if (state.isHelpMenuOpen) { @@ -253,74 +289,64 @@ export const AppHeader = withTheme(function AppHeader({ } onMenuItemClick?.(item, event); }, - [state, setOverlayMenu, onMenuItemClick], + [state.isHelpMenuOpen, setOverlayMenu, onMenuItemClick], ); - const getHelpMenuLink = useCallback( - (icon = "gd-icon-header-help") => ({ + const getHelpMenuLink = (icon = "gd-icon-header-help") => { + const shouldOpenDropdown = state.responsiveMode && helpMenuItems.length > 0; + return { key: "gs.header.help", className: `s-menu-help ${icon}`, - href: state.responsiveMode && helpMenuItems ? undefined : documentationUrl, - onClick: state.responsiveMode && helpMenuItems ? toggleHelpMenu : undefined, - }), - [state, helpMenuItems, documentationUrl, toggleHelpMenu], - ); + href: shouldOpenDropdown ? undefined : documentationUrl, + onClick: shouldOpenDropdown ? toggleHelpMenu : undefined, + }; + }; - const addHelpItemGroup = useCallback( - (itemGroups: IHeaderMenuItem[][]): IHeaderMenuItem[][] => { - return documentationUrl ? [...itemGroups, [getHelpMenuLink()]] : itemGroups; - }, - [documentationUrl, getHelpMenuLink], - ); + const addHelpItemGroup = (itemGroups: IHeaderMenuItem[][]): IHeaderMenuItem[][] => { + return documentationUrl ? [...itemGroups, [getHelpMenuLink()]] : itemGroups; + }; - const addAdditionalItems = useCallback( - (itemGroups: IHeaderMenuItem[][]): IHeaderMenuItem[][] => { - const additionalItems = []; - if (search) { - additionalItems.push({ - key: messages.search.id, - className: "gd-icon-header-search", - onClick: toggleSearchMenu, - }); - } + const addAdditionalItems = (itemGroups: IHeaderMenuItem[][]): IHeaderMenuItem[][] => { + const additionalItems: IHeaderMenuItem[] = []; - if (showChatItem) { - const AiIcon = Icon["GenAI2"]; + if (search) { + additionalItems.push({ + key: messages.search.id, + className: "gd-icon-header-search", + onClick: toggleSearchMenu, + }); + } - additionalItems.push({ - key: messages.aiChatMobile.id, - className: "gd-icon-header-ai", - icon: , - onClick: toggleAiChat, - }); - } + if (showChatItem) { + const AiIcon = Icon["GenAI2"]; - if (notificationsPanel) { - const AlertIcon = Icon["Alert"]; + additionalItems.push({ + key: messages.aiChatMobile.id, + className: "gd-icon-header-ai", + icon: , + onClick: toggleAiChat, + }); + } - additionalItems.push({ - key: messages.notifications.id, - className: "gd-icon-header-notifications", - icon: , - onClick: toggleNotificationsMenu, - }); - } + if (notificationsPanel) { + const AlertIcon = Icon["Alert"]; - if (!additionalItems.length) { - return itemGroups; - } + additionalItems.push({ + key: messages.notifications.id, + className: "gd-icon-header-notifications", + icon: , + onClick: toggleNotificationsMenu, + }); + } - return [...itemGroups, additionalItems]; - }, - [search, showChatItem, notificationsPanel, toggleAiChat, toggleSearchMenu, toggleNotificationsMenu], - ); + if (!additionalItems.length) { + return itemGroups; + } - const getHelpMenu = useCallback( - () => [[getHelpMenuLink("gd-icon-header-help-back"), ...helpMenuItems]], - [getHelpMenuLink, helpMenuItems], - ); + return [...itemGroups, additionalItems]; + }; - const getTrialCountdown = useCallback((expiredDate: string) => { + const renderTrialCountdown = (expiredDate: string) => { // expiredDate is the last day that user can use the service const trialDaysLeft = differenceInCalendarDays(new Date(expiredDate), new Date()) + 1; if (trialDaysLeft === 1) { @@ -351,67 +377,53 @@ export const AppHeader = withTheme(function AppHeader({ ); } return ""; - }, []); - - const getClassNames = useCallback(() => { - return cx({ - "gd-header": true, - [state.guid]: true, - [className as string]: !!className, - }); - }, [state.guid, className]); + }; - const renderLogo = useCallback( - (logoLinkClassName: string) => { - return ( - - - - ); - }, - [logoHref, onLogoClick, logoUrl, logoTitle, measureChildren], - ); + const renderLogo = (logoLinkClassName: string) => { + return ( + + + + ); + }; - const renderAccessibilityLogo = useCallback( - (logoLinkClassName: string, organizationName: string) => { - const logoHrefAccesibilityText = intl.formatMessage({ - id: "gs.header.href.accessibility", - }); - const imageAltAccessibilityText = intl.formatMessage( - { - id: "gs.header.logo.title.accessibility", - }, - { organizationName: organizationName || "GoodData" }, - ); + const renderAccessibilityLogo = (logoLinkClassName: string, organizationName: string) => { + const logoHrefAccesibilityText = intl.formatMessage({ + id: "gs.header.href.accessibility", + }); + const imageAltAccessibilityText = intl.formatMessage( + { + id: "gs.header.logo.title.accessibility", + }, + { organizationName: organizationName || "GoodData" }, + ); - return ( - - {imageAltAccessibilityText} - - ); - }, - [intl, logoHref, onLogoClick, logoUrl, logoTitle, measureChildren], - ); + return ( + + {imageAltAccessibilityText} + + ); + }; - const renderSearchMenu = useCallback(() => { + const renderSearchMenu = () => { return (
@@ -422,9 +434,9 @@ export const AppHeader = withTheme(function AppHeader({
); - }, [state.isSearchMenuOpen, toggleSearchMenu, search]); + }; - const renderNotificationsOverlay = useCallback(() => { + const renderNotificationsOverlay = () => { if (!notificationsPanel) { return null; } @@ -439,14 +451,14 @@ export const AppHeader = withTheme(function AppHeader({ })}
); - }, [notificationsPanel, closeNotificationsMenu]); + }; - const renderTrialItems = useCallback(() => { + const renderTrialItems = () => { if (expiredDate || showUpsellButton) { return (
{expiredDate ? ( -
{getTrialCountdown(expiredDate)}
+
{renderTrialCountdown(expiredDate)}
) : null} {showUpsellButton ? ( @@ -456,9 +468,9 @@ export const AppHeader = withTheme(function AppHeader({ ); } return null; - }, [expiredDate, showUpsellButton, getTrialCountdown, onUpsellButtonClick]); + }; - const renderLogoutButton = useCallback(() => { + const renderLogoutButton = () => { const [logoutMenuItem] = accountMenuItems.filter((item) => item.key === "gs.header.logout"); const LogoutIcon = Icon["Logout"]; return logoutMenuItem ? ( @@ -476,11 +488,11 @@ export const AppHeader = withTheme(function AppHeader({ ) : ( false ); - }, [accountMenuItems, onMenuItemClick, theme?.palette?.complementary?.c0]); + }; - const renderVerticalMenu = useCallback(() => { + const renderVerticalMenu = () => { const menuItemsGroupsToRender = state.isHelpMenuOpen - ? getHelpMenu() + ? [[getHelpMenuLink("gd-icon-header-help-back"), ...helpMenuItems]] : showStaticHelpMenu ? [[getHelpMenuLink()]] : addHelpItemGroup(addAdditionalItems(menuItemsGroups)); @@ -507,22 +519,9 @@ export const AppHeader = withTheme(function AppHeader({
); - }, [ - state.isHelpMenuOpen, - showStaticHelpMenu, - getHelpMenuLink, - addHelpItemGroup, - addAdditionalItems, - menuItemsGroups, - getHelpMenu, - handleMenuItemClick, - renderTrialItems, - badges, - userName, - renderLogoutButton, - ]); + }; - const renderOverlayMenu = useCallback(() => { + const renderOverlayMenu = () => { let content: ReactElement | null = renderVerticalMenu(); if (state.isSearchMenuOpen) { content = renderSearchMenu(); @@ -549,17 +548,9 @@ export const AppHeader = withTheme(function AppHeader({ {content} ); - }, [ - renderVerticalMenu, - state.isSearchMenuOpen, - state.isNotificationsMenuOpen, - renderSearchMenu, - renderNotificationsOverlay, - state.isOverlayMenuOpen, - setOverlayMenu, - ]); + }; - const renderMobileNav = useCallback(() => { + const renderMobileNav = () => { const iconClasses = cx({ "hamburger-icon": true, "is-open": state.isOverlayMenuOpen, @@ -586,16 +577,9 @@ export const AppHeader = withTheme(function AppHeader({ {state.isOverlayMenuOpen ? renderOverlayMenu() : null} ); - }, [ - state.isOverlayMenuOpen, - state.isSearchMenuOpen, - state.isNotificationsMenuOpen, - setOverlayMenu, - renderOverlayMenu, - intl, - ]); + }; - const renderStandardNav = useCallback(() => { + const renderStandardNav = () => { return (
{badges}
: null} ); - }, [ - onMenuItemClick, - menuItemsGroups, - renderTrialItems, - showChatItem, - intl, - onChatItemClick, - notificationsPanel, - closeNotificationsMenu, - search, - state.isSearchMenuOpen, - toggleSearchMenu, - helpMenuItems, - helpDropdownAlign, - disableHelpDropdown, - onHelpClick, - helpRedirectUrl, - userName, - accountMenuItems, - badges, - ]); - - const renderNav = useCallback(() => { - return state.responsiveMode ? renderMobileNav() : renderStandardNav(); - }, [state.responsiveMode, renderMobileNav, renderStandardNav]); - - useEffect(() => { - createStyles(); - }, [createStyles]); - - const logoLinkClassName = useMemo( - () => - cx({ - "gd-header-logo": true, - "gd-header-measure": true, - "gd-header-shrink": state.responsiveMode, - }), - [state.responsiveMode], - ); + }; - const applicationHeaderAccessibilityLabel = useMemo( - () => - intl.formatMessage({ - id: "gs.header.accessibility.label", - }), - [intl], - ); + const logoLinkClassName = cx({ + "gd-header-logo": true, + "gd-header-measure": true, + "gd-header-shrink": state.responsiveMode, + }); return ( -
+
{isAccessibilityCompliant ? renderAccessibilityLogo(logoLinkClassName, organizationName ?? "") : renderLogo(logoLinkClassName)} - {workspacePicker} - {renderNav()} + {state.responsiveMode ? renderMobileNav() : renderStandardNav()}
); }); diff --git a/libs/sdk-ui-loaders/package.json b/libs/sdk-ui-loaders/package.json index b5bf4730f4b..91dfaaba333 100644 --- a/libs/sdk-ui-loaders/package.json +++ b/libs/sdk-ui-loaders/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-loaders", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK Runtime Component Loaders", "repository": { "type": "git", diff --git a/libs/sdk-ui-pivot/package.json b/libs/sdk-ui-pivot/package.json index 350b9113116..1c51daec50c 100644 --- a/libs/sdk-ui-pivot/package.json +++ b/libs/sdk-ui-pivot/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-pivot", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData.UI SDK - Pivot Table", "repository": { "type": "git", diff --git a/libs/sdk-ui-semantic-search/package.json b/libs/sdk-ui-semantic-search/package.json index a119cc90b17..233d06c2d7d 100644 --- a/libs/sdk-ui-semantic-search/package.json +++ b/libs/sdk-ui-semantic-search/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-semantic-search", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK TypeScript & React skeleton", "repository": { "type": "git", diff --git a/libs/sdk-ui-tests-e2e/cypress/support/featureHub.ts b/libs/sdk-ui-tests-e2e/cypress/support/featureHub.ts index 8ab5a6799e1..6b174366ab8 100644 --- a/libs/sdk-ui-tests-e2e/cypress/support/featureHub.ts +++ b/libs/sdk-ui-tests-e2e/cypress/support/featureHub.ts @@ -1,4 +1,4 @@ -// (C) 2021-2025 GoodData Corporation +// (C) 2021-2026 GoodData Corporation /** * Mocking FeatureHub request to remove dependency on it @@ -65,6 +65,15 @@ beforeEach(() => { value: true, v: "0d2K", }, + { + id: "78538cca-c3db-43a3-ac43-eb385b1ebea8", + key: "enableEmptyDateValuesFilter", + l: false, + version: 13, + type: "BOOLEAN", + value: true, + v: "NsVT", + }, ], }, ], diff --git a/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_compactSize_with_comparison_0_document_0_desktop.png b/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_compactSize_with_comparison_0_document_0_desktop.png index 326ad1c2f46..9c6d308b6aa 100644 Binary files a/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_compactSize_with_comparison_0_document_0_desktop.png and b/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_compactSize_with_comparison_0_document_0_desktop.png differ diff --git a/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_compactSize_with_multi_measure_0_document_0_desktop.png b/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_compactSize_with_multi_measure_0_document_0_desktop.png index 34c9c99af3f..7173e9a9203 100644 Binary files a/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_compactSize_with_multi_measure_0_document_0_desktop.png and b/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_compactSize_with_multi_measure_0_document_0_desktop.png differ diff --git a/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_responsive_with_comparison_0_document_0_desktop.png b/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_responsive_with_comparison_0_document_0_desktop.png index 6ff2037c5d0..8f06ded0469 100644 Binary files a/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_responsive_with_comparison_0_document_0_desktop.png and b/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_responsive_with_comparison_0_document_0_desktop.png differ diff --git a/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_responsive_with_multi_measures_0_document_0_desktop.png b/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_responsive_with_multi_measures_0_document_0_desktop.png index 19a30dfed44..da0d74afbe9 100644 Binary files a/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_responsive_with_multi_measures_0_document_0_desktop.png and b/libs/sdk-ui-tests/neobackstop/output/reference/storybook_chromium_02_Custom_Test_Stories_Headline_-_responsive_with_multi_measures_0_document_0_desktop.png differ diff --git a/libs/sdk-ui-theme-provider/package.json b/libs/sdk-ui-theme-provider/package.json index 0da20ffcbe0..5e257122329 100644 --- a/libs/sdk-ui-theme-provider/package.json +++ b/libs/sdk-ui-theme-provider/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-theme-provider", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK - Theme provider", "repository": { "type": "git", diff --git a/libs/sdk-ui-vis-commons/package.json b/libs/sdk-ui-vis-commons/package.json index 28ce5dc54f8..59469456ebd 100644 --- a/libs/sdk-ui-vis-commons/package.json +++ b/libs/sdk-ui-vis-commons/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui-vis-commons", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData.UI SDK - common functionality for different types of visualizations", "repository": { "type": "git", diff --git a/libs/sdk-ui-vis-commons/styles/scss/headlinePagination.scss b/libs/sdk-ui-vis-commons/styles/scss/headlinePagination.scss index eb2c2caff77..5799b3b6245 100644 --- a/libs/sdk-ui-vis-commons/styles/scss/headlinePagination.scss +++ b/libs/sdk-ui-vis-commons/styles/scss/headlinePagination.scss @@ -117,7 +117,7 @@ $legend-paging-background: #eee; &.gd-small, &.gd-shortened-label { display: flex; - flex-flow: column-reverse wrap; + flex-flow: column wrap; .headline-compare-section-item { width: 100%; @@ -155,12 +155,6 @@ $legend-paging-background: #eee; .headline-tertiary-item, .headline-compare-item:nth-child(1) { - padding: 10px 0 0; - text-align: center; - } - - .headline-secondary-item, - .headline-compare-item:nth-child(2) { border-left: 0; border-bottom: 1px dashed var( @@ -173,6 +167,13 @@ $legend-paging-background: #eee; padding: 0 0 10px; text-align: center; } + + .headline-secondary-item, + .headline-compare-item:nth-child(2) { + padding: 10px 0 0; + text-align: center; + border-left: none; + } } &.gd-shortened-label, diff --git a/libs/sdk-ui/package.json b/libs/sdk-ui/package.json index e15bee00e1d..137f07b07b7 100644 --- a/libs/sdk-ui/package.json +++ b/libs/sdk-ui/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/sdk-ui", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData.UI SDK - Core", "repository": { "type": "git", diff --git a/libs/util/package.json b/libs/util/package.json index d44658f8993..7ec8bb6be75 100644 --- a/libs/util/package.json +++ b/libs/util/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/util", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData Utility Functions", "repository": { "type": "git", diff --git a/tools/app-toolkit/package.json b/tools/app-toolkit/package.json index 91dbe2839dc..8551184cc43 100644 --- a/tools/app-toolkit/package.json +++ b/tools/app-toolkit/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/app-toolkit", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "CLI with useful tools for creating and maintaining GoodData web applications.", "repository": { "type": "git", diff --git a/tools/catalog-export/package.json b/tools/catalog-export/package.json index 3abf413c680..baeb9e80815 100644 --- a/tools/catalog-export/package.json +++ b/tools/catalog-export/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/catalog-export", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK Catalog Export tooling", "repository": { "type": "git", diff --git a/tools/eslint-config/package.json b/tools/eslint-config/package.json index 925c2894d7c..cce123ca083 100644 --- a/tools/eslint-config/package.json +++ b/tools/eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/eslint-config", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "repository": { "type": "git", "url": "https://github.com/gooddata/gooddata-ui-sdk.git", diff --git a/tools/i18n-toolkit/package.json b/tools/i18n-toolkit/package.json index 4a5f4b815ca..923e37e2363 100644 --- a/tools/i18n-toolkit/package.json +++ b/tools/i18n-toolkit/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/i18n-toolkit", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "Localization validator to validate localization complexity and intl and html format.", "repository": { "type": "git", diff --git a/tools/mock-handling/package.json b/tools/mock-handling/package.json index 462f523f43d..97d23b852bf 100644 --- a/tools/mock-handling/package.json +++ b/tools/mock-handling/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/mock-handling", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK Mock data capture and management tool", "repository": { "type": "git", diff --git a/tools/plugin-toolkit/package.json b/tools/plugin-toolkit/package.json index 9b753fae444..dbb7ab79881 100644 --- a/tools/plugin-toolkit/package.json +++ b/tools/plugin-toolkit/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/plugin-toolkit", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData Set of Tools for working with Plugins", "repository": { "type": "git", diff --git a/tools/reference-workspace/package.json b/tools/reference-workspace/package.json index 83f51ef2f63..566d2d6c41f 100644 --- a/tools/reference-workspace/package.json +++ b/tools/reference-workspace/package.json @@ -1,6 +1,6 @@ { "name": "@gooddata/reference-workspace", - "version": "11.17.0-alpha.0", + "version": "11.17.0-alpha.1", "description": "GoodData SDK - Reference Workspace for tests", "repository": { "type": "git",