@gooddata/sdk-ui-catalog 11.53.0-alpha.6 → 11.53.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/asCode/tests/asCodeEditorBody.test.utils.d.ts +21 -0
- package/esm/asCode/tests/asCodeEditorBody.test.utils.d.ts.map +1 -0
- package/esm/asCode/tests/asCodeEditorBody.test.utils.js +25 -0
- package/esm/catalogItem/tests/catalogBackend.test.utils.d.ts +65 -0
- package/esm/catalogItem/tests/catalogBackend.test.utils.d.ts.map +1 -0
- package/esm/catalogItem/tests/catalogBackend.test.utils.js +139 -0
- package/esm/filter/FilterContext.d.ts +12 -1
- package/esm/filter/FilterContext.d.ts.map +1 -1
- package/esm/filter/FilterContext.js +11 -2
- package/esm/filter/TestFilterProvider.d.ts +17 -0
- package/esm/filter/TestFilterProvider.d.ts.map +1 -0
- package/esm/filter/TestFilterProvider.js +17 -0
- package/esm/quality/QualityContext.d.ts +12 -1
- package/esm/quality/QualityContext.d.ts.map +1 -1
- package/esm/quality/QualityContext.js +14 -5
- package/esm/quality/TestQualityProvider.d.ts +15 -0
- package/esm/quality/TestQualityProvider.d.ts.map +1 -0
- package/esm/quality/TestQualityProvider.js +19 -0
- package/package.json +15 -15
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A drop-in stand-in for {@link AsCodeEditorBody} that swaps its CodeMirror editor for a plain
|
|
3
|
+
* textarea, so a dialog test can read and type the YAML with `fireEvent.change`.
|
|
4
|
+
*
|
|
5
|
+
* The real body is `lazy()`-loaded by the dialog, and only for the editor half — nothing else in
|
|
6
|
+
* the dialog under test comes through it — so a test replaces just this module rather than the
|
|
7
|
+
* `@gooddata/sdk-ui-kit` barrel every other component also imports:
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* vi.mock("../AsCodeEditorBody.js", () => import("./asCodeEditorBody.test.utils.js"));
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Local state seeded from `initialValue` mirrors the real body: the dialog reads the current value
|
|
14
|
+
* from `onChange` and never drives it back in.
|
|
15
|
+
*/
|
|
16
|
+
export declare function AsCodeEditorBody({ initialValue, onChange, disabled }: {
|
|
17
|
+
initialValue: string;
|
|
18
|
+
onChange: (value: string) => void;
|
|
19
|
+
disabled: boolean;
|
|
20
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=asCodeEditorBody.test.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asCodeEditorBody.test.utils.d.ts","sourceRoot":"","sources":["../../../src/asCode/tests/asCodeEditorBody.test.utils.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,EAC7B,YAAY,EACZ,QAAQ,EACR,QAAQ,EACX,EAAE;IACC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,EAAE,OAAO,CAAC;CACrB,2CAcA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2026 GoodData Corporation
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
/**
|
|
5
|
+
* A drop-in stand-in for {@link AsCodeEditorBody} that swaps its CodeMirror editor for a plain
|
|
6
|
+
* textarea, so a dialog test can read and type the YAML with `fireEvent.change`.
|
|
7
|
+
*
|
|
8
|
+
* The real body is `lazy()`-loaded by the dialog, and only for the editor half — nothing else in
|
|
9
|
+
* the dialog under test comes through it — so a test replaces just this module rather than the
|
|
10
|
+
* `@gooddata/sdk-ui-kit` barrel every other component also imports:
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* vi.mock("../AsCodeEditorBody.js", () => import("./asCodeEditorBody.test.utils.js"));
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Local state seeded from `initialValue` mirrors the real body: the dialog reads the current value
|
|
17
|
+
* from `onChange` and never drives it back in.
|
|
18
|
+
*/
|
|
19
|
+
export function AsCodeEditorBody({ initialValue, onChange, disabled, }) {
|
|
20
|
+
const [value, setValue] = useState(initialValue);
|
|
21
|
+
return (_jsx("textarea", { "data-testid": "yaml-editor", value: value, disabled: disabled, onChange: (e) => {
|
|
22
|
+
setValue(e.target.value);
|
|
23
|
+
onChange(e.target.value);
|
|
24
|
+
} }));
|
|
25
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type Mock } from "vitest";
|
|
2
|
+
import type { IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
|
|
3
|
+
import type { ObjectType } from "../../objectType/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* A backend stub for the catalog feed and its semantic search companion.
|
|
6
|
+
*
|
|
7
|
+
* The feed hooks reach the backend through `catalogItem/query.js` and `useSemanticSearch`, both of
|
|
8
|
+
* which only chain `with*` calls onto a query builder and then `query()` it. Faking the builders
|
|
9
|
+
* rather than mocking those modules keeps the whole production chain — query construction, endpoint
|
|
10
|
+
* selection, pagination, entity conversion — under test, and keeps the suite runnable without
|
|
11
|
+
* per-file isolation: a `vi.mock` of a module that other test files load unmocked cannot be applied
|
|
12
|
+
* to a module graph they already evaluated.
|
|
13
|
+
*/
|
|
14
|
+
/** A page as {@link useEndpointPaginator} consumes it; `next()` yields the following page. */
|
|
15
|
+
export interface IStubPage {
|
|
16
|
+
items: unknown[];
|
|
17
|
+
offset: number;
|
|
18
|
+
limit: number;
|
|
19
|
+
totalCount: number;
|
|
20
|
+
next: Mock;
|
|
21
|
+
}
|
|
22
|
+
interface IStubPageSpec {
|
|
23
|
+
items: unknown[];
|
|
24
|
+
offset: number;
|
|
25
|
+
totalCount: number;
|
|
26
|
+
}
|
|
27
|
+
/** Builds a linked chain of pages where each `page.next()` returns the next page in the chain. */
|
|
28
|
+
export declare function chainPages(specs: IStubPageSpec[]): IStubPage;
|
|
29
|
+
/** A single empty page — what an endpoint serves unless a test points it elsewhere. */
|
|
30
|
+
export declare function emptyPage(): IStubPage;
|
|
31
|
+
/** A backend entity of the given type whose converted catalog item is identified by `id`. */
|
|
32
|
+
export declare function catalogEntity(type: ObjectType, id: string): unknown;
|
|
33
|
+
/** The `with*` calls `catalogItem/query.js` chains onto a query builder before `query()`. */
|
|
34
|
+
declare const CATALOG_BUILDER_METHODS: readonly ["withPage", "withSize", "withInclude", "withMetaInclude", "withSorting", "withOrigin", "withFilter", "withMethod"];
|
|
35
|
+
/** The `with*` calls `useSemanticSearch` chains onto the genAI semantic search builder. */
|
|
36
|
+
declare const SEMANTIC_BUILDER_METHODS: readonly ["withQuestion", "withDeepSearch", "withObjectTypes", "withLimit", "withAllowedRelationshipTypes", "withIncludeTags", "withExcludeTags"];
|
|
37
|
+
export type QueryBuilderStub<TMethod extends string> = Record<TMethod, Mock> & {
|
|
38
|
+
query: Mock;
|
|
39
|
+
};
|
|
40
|
+
type CatalogBuilderStub = QueryBuilderStub<(typeof CATALOG_BUILDER_METHODS)[number]>;
|
|
41
|
+
type SemanticBuilderStub = QueryBuilderStub<(typeof SEMANTIC_BUILDER_METHODS)[number]>;
|
|
42
|
+
/** The shape `useSemanticSearch` reads off its query result. */
|
|
43
|
+
interface ISemanticSearchResponseStub {
|
|
44
|
+
results: Array<{
|
|
45
|
+
id: string;
|
|
46
|
+
}>;
|
|
47
|
+
relationships: unknown[];
|
|
48
|
+
}
|
|
49
|
+
export interface ICatalogBackendStub {
|
|
50
|
+
backend: IAnalyticalBackend;
|
|
51
|
+
/** `getXQuery()` per object type — its call count says which endpoints were reached. */
|
|
52
|
+
queries: Record<ObjectType, Mock>;
|
|
53
|
+
/** The builder `getXQuery()` returns; `withFilter` records the effective query options. */
|
|
54
|
+
builders: Record<ObjectType, CatalogBuilderStub>;
|
|
55
|
+
/** The genAI search builder; `withQuestion` records the search term the hook sent. */
|
|
56
|
+
semanticSearchQuery: Mock;
|
|
57
|
+
semanticSearchBuilder: SemanticBuilderStub;
|
|
58
|
+
/** Points a type's endpoint at a page chain (or a rejection); default is one empty page. */
|
|
59
|
+
setPages(type: ObjectType, source: () => Promise<IStubPage>): void;
|
|
60
|
+
/** Points semantic search at a response (or a rejection); default is no results. */
|
|
61
|
+
setSemanticSearchResponse(source: () => Promise<ISemanticSearchResponseStub>): void;
|
|
62
|
+
}
|
|
63
|
+
export declare function createCatalogBackendStub(): ICatalogBackendStub;
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=catalogBackend.test.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalogBackend.test.utils.d.ts","sourceRoot":"","sources":["../../../src/catalogItem/tests/catalogBackend.test.utils.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,IAAI,EAAM,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAIpE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D;;;;;;;;;GASG;AAEH,8FAA8F;AAC9F,MAAM,WAAW,SAAS;IACtB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,IAAI,CAAC;CACd;AAED,UAAU,aAAa;IACnB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,kGAAkG;AAClG,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,SAAS,CAgB5D;AAED,yFAAuF;AACvF,wBAAgB,SAAS,IAAI,SAAS,CAErC;AAyCD,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAEnE;AAED,6FAA6F;AAC7F,QAAA,MAAM,uBAAuB,8HASnB,CAAC;AAEX,2FAA2F;AAC3F,QAAA,MAAM,wBAAwB,mJAQpB,CAAC;AAEX,MAAM,MAAM,gBAAgB,CAAC,OAAO,SAAS,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,CAAC;AAE/F,KAAK,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AACrF,KAAK,mBAAmB,GAAG,gBAAgB,CAAC,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAyBvF,gEAAgE;AAChE,UAAU,2BAA2B;IACjC,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/B,aAAa,EAAE,OAAO,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,0FAAwF;IACxF,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAClC,2FAA2F;IAC3F,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IACjD,sFAAsF;IACtF,mBAAmB,EAAE,IAAI,CAAC;IAC1B,qBAAqB,EAAE,mBAAmB,CAAC;IAC3C,4FAA4F;IAC5F,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IACnE,oFAAoF;IACpF,yBAAyB,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,2BAA2B,CAAC,GAAG,IAAI,CAAC;CACvF;AAED,wBAAgB,wBAAwB,IAAI,mBAAmB,CA4C9D"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { vi } from "vitest";
|
|
3
|
+
import { idRef } from "@gooddata/sdk-model";
|
|
4
|
+
import { ObjectTypes } from "../../objectType/constants.js";
|
|
5
|
+
/** Builds a linked chain of pages where each `page.next()` returns the next page in the chain. */
|
|
6
|
+
export function chainPages(specs) {
|
|
7
|
+
const pageAt = (index) => {
|
|
8
|
+
const spec = specs[index];
|
|
9
|
+
if (!spec) {
|
|
10
|
+
throw new Error("next() called beyond the configured page chain");
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
items: spec.items,
|
|
14
|
+
offset: spec.offset,
|
|
15
|
+
limit: spec.items.length,
|
|
16
|
+
totalCount: spec.totalCount,
|
|
17
|
+
next: vi.fn(async () => pageAt(index + 1)),
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
return pageAt(0);
|
|
21
|
+
}
|
|
22
|
+
/** A single empty page — what an endpoint serves unless a test points it elsewhere. */
|
|
23
|
+
export function emptyPage() {
|
|
24
|
+
return chainPages([{ items: [], offset: 0, totalCount: 0 }]);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Backend-shaped entities, i.e. ones the real `convertEntityToCatalogItem` accepts. Each carries
|
|
28
|
+
* only the fields its converter reads, plus whatever its `sdk-model` type guard requires.
|
|
29
|
+
*/
|
|
30
|
+
const ENTITY_FACTORIES = {
|
|
31
|
+
[ObjectTypes.DASHBOARD]: (id) => ({
|
|
32
|
+
ref: idRef(id, "analyticalDashboard"),
|
|
33
|
+
identifier: id,
|
|
34
|
+
title: id,
|
|
35
|
+
description: "",
|
|
36
|
+
tags: [],
|
|
37
|
+
// `isListedDashboard` keys off `availability`.
|
|
38
|
+
availability: "full",
|
|
39
|
+
}),
|
|
40
|
+
[ObjectTypes.VISUALIZATION]: (id) => ({
|
|
41
|
+
// `isInsight` keys off the `insight` wrapper.
|
|
42
|
+
insight: {
|
|
43
|
+
identifier: id,
|
|
44
|
+
title: id,
|
|
45
|
+
summary: "",
|
|
46
|
+
visualizationUrl: "local:bar",
|
|
47
|
+
tags: [],
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
[ObjectTypes.METRIC]: (id) => metadataEntity(id, "measure"),
|
|
51
|
+
[ObjectTypes.PARAMETER]: (id) => ({
|
|
52
|
+
...metadataEntity(id, "parameter"),
|
|
53
|
+
definition: { type: "NUMBER", defaultValue: 0 },
|
|
54
|
+
}),
|
|
55
|
+
[ObjectTypes.ATTRIBUTE]: (id) => metadataEntity(id, "attribute"),
|
|
56
|
+
[ObjectTypes.FACT]: (id) => metadataEntity(id, "fact"),
|
|
57
|
+
[ObjectTypes.DATASET]: (id) => metadataEntity(id, "dataSet"),
|
|
58
|
+
};
|
|
59
|
+
function metadataEntity(id, type) {
|
|
60
|
+
// `isMetadataObject` requires both `type` and `ref`.
|
|
61
|
+
return { type, ref: idRef(id, type), id, title: id, description: "", tags: [] };
|
|
62
|
+
}
|
|
63
|
+
/** A backend entity of the given type whose converted catalog item is identified by `id`. */
|
|
64
|
+
export function catalogEntity(type, id) {
|
|
65
|
+
return ENTITY_FACTORIES[type](id);
|
|
66
|
+
}
|
|
67
|
+
/** The `with*` calls `catalogItem/query.js` chains onto a query builder before `query()`. */
|
|
68
|
+
const CATALOG_BUILDER_METHODS = [
|
|
69
|
+
"withPage",
|
|
70
|
+
"withSize",
|
|
71
|
+
"withInclude",
|
|
72
|
+
"withMetaInclude",
|
|
73
|
+
"withSorting",
|
|
74
|
+
"withOrigin",
|
|
75
|
+
"withFilter",
|
|
76
|
+
"withMethod",
|
|
77
|
+
];
|
|
78
|
+
/** The `with*` calls `useSemanticSearch` chains onto the genAI semantic search builder. */
|
|
79
|
+
const SEMANTIC_BUILDER_METHODS = [
|
|
80
|
+
"withQuestion",
|
|
81
|
+
"withDeepSearch",
|
|
82
|
+
"withObjectTypes",
|
|
83
|
+
"withLimit",
|
|
84
|
+
"withAllowedRelationshipTypes",
|
|
85
|
+
"withIncludeTags",
|
|
86
|
+
"withExcludeTags",
|
|
87
|
+
];
|
|
88
|
+
function createBuilderStub(methods, run) {
|
|
89
|
+
const builder = { query: vi.fn(() => run()) };
|
|
90
|
+
for (const method of methods) {
|
|
91
|
+
builder[method] = vi.fn(() => builder);
|
|
92
|
+
}
|
|
93
|
+
return builder;
|
|
94
|
+
}
|
|
95
|
+
/** Which workspace service and query factory each object type's endpoint goes through. */
|
|
96
|
+
const QUERY_SERVICES = {
|
|
97
|
+
[ObjectTypes.DASHBOARD]: ["dashboards", "getDashboardsQuery"],
|
|
98
|
+
[ObjectTypes.VISUALIZATION]: ["insights", "getInsightsQuery"],
|
|
99
|
+
[ObjectTypes.METRIC]: ["measures", "getMeasuresQuery"],
|
|
100
|
+
[ObjectTypes.PARAMETER]: ["parameters", "getParametersQuery"],
|
|
101
|
+
[ObjectTypes.ATTRIBUTE]: ["attributes", "getAttributesQuery"],
|
|
102
|
+
[ObjectTypes.FACT]: ["facts", "getFactsQuery"],
|
|
103
|
+
[ObjectTypes.DATASET]: ["datasets", "getDatasetsQuery"],
|
|
104
|
+
};
|
|
105
|
+
export function createCatalogBackendStub() {
|
|
106
|
+
const pageSources = {};
|
|
107
|
+
const queries = {};
|
|
108
|
+
const builders = {};
|
|
109
|
+
const services = {};
|
|
110
|
+
for (const [type, [service, factoryName]] of Object.entries(QUERY_SERVICES)) {
|
|
111
|
+
const builder = createBuilderStub(CATALOG_BUILDER_METHODS, () => (pageSources[type] ?? (() => Promise.resolve(emptyPage())))());
|
|
112
|
+
const factory = vi.fn(() => builder);
|
|
113
|
+
builders[type] = builder;
|
|
114
|
+
queries[type] = factory;
|
|
115
|
+
services[service] = { ...services[service], [factoryName]: factory };
|
|
116
|
+
}
|
|
117
|
+
let semanticSearchResponse = () => Promise.resolve({ results: [], relationships: [] });
|
|
118
|
+
const semanticSearchBuilder = createBuilderStub(SEMANTIC_BUILDER_METHODS, () => semanticSearchResponse());
|
|
119
|
+
const semanticSearchQuery = vi.fn(() => semanticSearchBuilder);
|
|
120
|
+
const workspace = {
|
|
121
|
+
genAI: () => ({ getSemanticSearchQuery: semanticSearchQuery }),
|
|
122
|
+
};
|
|
123
|
+
for (const [service, api] of Object.entries(services)) {
|
|
124
|
+
workspace[service] = () => api;
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
backend: { workspace: () => workspace },
|
|
128
|
+
queries,
|
|
129
|
+
builders,
|
|
130
|
+
semanticSearchQuery,
|
|
131
|
+
semanticSearchBuilder,
|
|
132
|
+
setPages(type, source) {
|
|
133
|
+
pageSources[type] = source;
|
|
134
|
+
},
|
|
135
|
+
setSemanticSearchResponse(source) {
|
|
136
|
+
semanticSearchResponse = source;
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
@@ -14,7 +14,7 @@ interface IFilterStateBase {
|
|
|
14
14
|
isHidden: boolean | undefined;
|
|
15
15
|
certification: boolean | undefined;
|
|
16
16
|
}
|
|
17
|
-
interface IFilterState extends IFilterStateBase {
|
|
17
|
+
export interface IFilterState extends IFilterStateBase {
|
|
18
18
|
isModified: boolean;
|
|
19
19
|
}
|
|
20
20
|
interface IFilterActions {
|
|
@@ -28,6 +28,17 @@ interface IFilterActions {
|
|
|
28
28
|
reset: () => void;
|
|
29
29
|
toggleTag: (tag: string) => void;
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* The unfiltered state {@link useFilterState} falls back to outside a provider.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export declare const defaultFilterState: IFilterState;
|
|
36
|
+
/**
|
|
37
|
+
* The state context behind {@link useFilterState}. Exported so a test can mount a fixed filter
|
|
38
|
+
* state (see `TestFilterProvider`); production code goes through {@link FilterProvider}.
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export declare const FilterStateContext: import("react").Context<IFilterState>;
|
|
31
42
|
export declare function FilterProvider({ children }: PropsWithChildren): import("react/jsx-runtime").JSX.Element;
|
|
32
43
|
export declare function useFilterState(): IFilterState;
|
|
33
44
|
export declare function useFilterActions(): IFilterActions;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterContext.d.ts","sourceRoot":"","sources":["../../src/filter/FilterContext.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAAkD,MAAM,OAAO,CAAC;AAI/F,OAAO,EACH,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAEhC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIzD,UAAU,aAAa,CAAC,CAAC;IACrB,MAAM,EAAE,CAAC,CAAC;IACV,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,gBAAgB;IACtB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;IACnC,IAAI,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9B,YAAY,EAAE,aAAa,CAAC,wBAAwB,EAAE,CAAC,CAAC;IACxD,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;CACtC;AAED,
|
|
1
|
+
{"version":3,"file":"FilterContext.d.ts","sourceRoot":"","sources":["../../src/filter/FilterContext.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAAkD,MAAM,OAAO,CAAC;AAI/F,OAAO,EACH,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAEhC,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIzD,UAAU,aAAa,CAAC,CAAC;IACrB,MAAM,EAAE,CAAC,CAAC;IACV,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,gBAAgB;IACtB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;IACnC,IAAI,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9B,YAAY,EAAE,aAAa,CAAC,wBAAwB,EAAE,CAAC,CAAC;IACxD,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,YAAa,SAAQ,gBAAgB;IAElD,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,cAAc;IAEpB,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;IACxC,SAAS,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAC1C,YAAY,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IACxD,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IACnD,eAAe,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,wBAAwB,EAAE,CAAC,KAAK,IAAI,CAAC;IAC7E,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,KAAK,IAAI,CAAC;IACrD,gBAAgB,EAAE,CAAC,aAAa,EAAE,OAAO,GAAG,SAAS,KAAK,IAAI,CAAC;IAE/D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAuBD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,YAIhC,CAAC;AAgBF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,uCAAkD,CAAC;AAGlF,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CAiC7D;AAyDD,wBAAgB,cAAc,iBAE7B;AAED,wBAAgB,gBAAgB,mBAE/B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAAC,UAAU,EAAE,CAAC,GAAG,SAAS,CAqB1E"}
|
|
@@ -15,7 +15,11 @@ const initialState = {
|
|
|
15
15
|
isHidden: undefined,
|
|
16
16
|
certification: undefined,
|
|
17
17
|
};
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* The unfiltered state {@link useFilterState} falls back to outside a provider.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export const defaultFilterState = {
|
|
19
23
|
...initialState,
|
|
20
24
|
// Derived state
|
|
21
25
|
isModified: false,
|
|
@@ -33,7 +37,12 @@ const initialActions = {
|
|
|
33
37
|
reset: () => { },
|
|
34
38
|
toggleTag: () => { },
|
|
35
39
|
};
|
|
36
|
-
|
|
40
|
+
/**
|
|
41
|
+
* The state context behind {@link useFilterState}. Exported so a test can mount a fixed filter
|
|
42
|
+
* state (see `TestFilterProvider`); production code goes through {@link FilterProvider}.
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
export const FilterStateContext = createContext(defaultFilterState);
|
|
37
46
|
const FilterActionsContext = createContext(initialActions);
|
|
38
47
|
export function FilterProvider({ children }) {
|
|
39
48
|
const [filters, dispatch] = useReducer(filterReducer, initialState);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type PropsWithChildren } from "react";
|
|
2
|
+
import { type IFilterState } from "./FilterContext.js";
|
|
3
|
+
type Props = PropsWithChildren<{
|
|
4
|
+
state?: Partial<IFilterState>;
|
|
5
|
+
}>;
|
|
6
|
+
/**
|
|
7
|
+
* Test-only FilterProvider holding a fixed filter state, so a test can exercise a hook that reads
|
|
8
|
+
* the filters without driving the real reducer through its setters.
|
|
9
|
+
*
|
|
10
|
+
* The context value is memoized on `state`'s identity: the filter objects it hands out feed the
|
|
11
|
+
* feed's query-options memo, so a fresh value per render would re-query forever. Swap `state` for a
|
|
12
|
+
* new object to change the filters.
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export declare function TestFilterProvider({ children, state }: Props): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=TestFilterProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestFilterProvider.d.ts","sourceRoot":"","sources":["../../src/filter/TestFilterProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAAW,MAAM,OAAO,CAAC;AAExD,OAAO,EAAsB,KAAK,YAAY,EAAsB,MAAM,oBAAoB,CAAC;AAE/F,KAAK,KAAK,GAAG,iBAAiB,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CACjC,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,2CAI5D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2026 GoodData Corporation
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { FilterStateContext, defaultFilterState } from "./FilterContext.js";
|
|
5
|
+
/**
|
|
6
|
+
* Test-only FilterProvider holding a fixed filter state, so a test can exercise a hook that reads
|
|
7
|
+
* the filters without driving the real reducer through its setters.
|
|
8
|
+
*
|
|
9
|
+
* The context value is memoized on `state`'s identity: the filter objects it hands out feed the
|
|
10
|
+
* feed's query-options memo, so a fresh value per render would re-query forever. Swap `state` for a
|
|
11
|
+
* new object to change the filters.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export function TestFilterProvider({ children, state }) {
|
|
15
|
+
const value = useMemo(() => ({ ...defaultFilterState, ...state }), [state]);
|
|
16
|
+
return _jsx(FilterStateContext.Provider, { value: value, children: children });
|
|
17
|
+
}
|
|
@@ -2,7 +2,7 @@ import { type PropsWithChildren } from "react";
|
|
|
2
2
|
import type { IAnalyticalBackend } from "@gooddata/sdk-backend-spi";
|
|
3
3
|
import type { ISemanticQualityIssue, ISemanticQualityReport, Identifier } from "@gooddata/sdk-model";
|
|
4
4
|
import { type UseCancelablePromiseStatus } from "@gooddata/sdk-ui";
|
|
5
|
-
interface IQualityState {
|
|
5
|
+
export interface IQualityState {
|
|
6
6
|
status: UseCancelablePromiseStatus;
|
|
7
7
|
issues: ISemanticQualityIssue[];
|
|
8
8
|
updatedAt: ISemanticQualityReport["updatedAt"];
|
|
@@ -13,6 +13,17 @@ interface IQualityActions {
|
|
|
13
13
|
fetchQualityReport: () => void;
|
|
14
14
|
createQualityIssuesCalculation: () => void;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* The empty report {@link useQualityState} falls back to outside a provider.
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export declare const defaultQualityState: IQualityState;
|
|
21
|
+
/**
|
|
22
|
+
* The state context behind {@link useQualityState}. Exported so a test can mount a fixed report
|
|
23
|
+
* (see `TestQualityProvider`); production code goes through {@link QualityProvider}.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export declare const QualityStateContext: import("react").Context<IQualityState>;
|
|
16
27
|
type Props = PropsWithChildren<{
|
|
17
28
|
backend: IAnalyticalBackend;
|
|
18
29
|
workspace: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QualityContext.d.ts","sourceRoot":"","sources":["../../src/quality/QualityContext.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAA6D,MAAM,OAAO,CAAC;AAE1G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EACR,qBAAqB,EACrB,sBAAsB,EACtB,UAAU,EAEb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,0BAA0B,EAAwB,MAAM,kBAAkB,CAAC;AAOzF,
|
|
1
|
+
{"version":3,"file":"QualityContext.d.ts","sourceRoot":"","sources":["../../src/quality/QualityContext.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAA6D,MAAM,OAAO,CAAC;AAE1G,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EACR,qBAAqB,EACrB,sBAAsB,EACtB,UAAU,EAEb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,0BAA0B,EAAwB,MAAM,kBAAkB,CAAC;AAOzF,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,0BAA0B,CAAC;IACnC,MAAM,EAAE,qBAAqB,EAAE,CAAC;IAChC,SAAS,EAAE,sBAAsB,CAAC,WAAW,CAAC,CAAC;IAC/C,YAAY,EAAE,sBAAsB,CAAC,QAAQ,CAAC,CAAC;IAC/C,KAAK,CAAC,EAAE,KAAK,CAAC;CACjB;AAED,UAAU,eAAe;IACrB,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,8BAA8B,EAAE,MAAM,IAAI,CAAC;CAC9C;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,aAKjC,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,wCAAoD,CAAC;AAGrF,KAAK,KAAK,GAAG,iBAAiB,CAAC;IAC3B,OAAO,EAAE,kBAAkB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,KAAK,2CA2DtE;AAED,wBAAgB,eAAe,IAAI,aAAa,CAE/C;AAED,wBAAgB,qBAAqB,IAAI,aAAa,CAErD;AAED,wBAAgB,iBAAiB,IAAI,eAAe,CAEnD;AAED,wBAAgB,mBAAmB,IAAI,GAAG,CAAC,UAAU,EAAE,qBAAqB,EAAE,CAAC,CAmB9E;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,UAAU,GAAG,qBAAqB,EAAE,GAAG,SAAS,CAGxF"}
|
|
@@ -4,7 +4,11 @@ import { createContext, useCallback, useContext, useMemo, useState } from "react
|
|
|
4
4
|
import { useCancelablePromise } from "@gooddata/sdk-ui";
|
|
5
5
|
import { useIsCatalogQualityEnabled } from "./gate.js";
|
|
6
6
|
import { createQueryId, triggerQualityIssuesCalculationQuery, triggerQualityIssuesQuery } from "./query.js";
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* The empty report {@link useQualityState} falls back to outside a provider.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export const defaultQualityState = {
|
|
8
12
|
status: "pending",
|
|
9
13
|
issues: [],
|
|
10
14
|
updatedAt: undefined,
|
|
@@ -14,13 +18,18 @@ const initialActions = {
|
|
|
14
18
|
fetchQualityReport: () => { },
|
|
15
19
|
createQualityIssuesCalculation: () => { },
|
|
16
20
|
};
|
|
17
|
-
|
|
21
|
+
/**
|
|
22
|
+
* The state context behind {@link useQualityState}. Exported so a test can mount a fixed report
|
|
23
|
+
* (see `TestQualityProvider`); production code goes through {@link QualityProvider}.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export const QualityStateContext = createContext(defaultQualityState);
|
|
18
27
|
const QualityActionsContext = createContext(initialActions);
|
|
19
28
|
export function QualityProvider({ backend, workspace, children }) {
|
|
20
29
|
const enabled = useIsCatalogQualityEnabled();
|
|
21
30
|
const [queryType, setQueryType] = useState("fetch");
|
|
22
31
|
const [queryKey, setQueryKey] = useState(createQueryId);
|
|
23
|
-
const [lastReportStatus, setLastReportStatus] = useState(
|
|
32
|
+
const [lastReportStatus, setLastReportStatus] = useState(defaultQualityState.reportStatus);
|
|
24
33
|
const qualityReport = useCancelablePromise({
|
|
25
34
|
promise: enabled
|
|
26
35
|
? async (signal) => {
|
|
@@ -46,8 +55,8 @@ export function QualityProvider({ backend, workspace, children }) {
|
|
|
46
55
|
status: qualityReport.status,
|
|
47
56
|
error: qualityReport.error,
|
|
48
57
|
updatedAt: qualityReport.result?.updatedAt,
|
|
49
|
-
issues: qualityReport.result?.issues ??
|
|
50
|
-
reportStatus: qualityReport.result?.status ?? lastReportStatus ??
|
|
58
|
+
issues: qualityReport.result?.issues ?? defaultQualityState.issues,
|
|
59
|
+
reportStatus: qualityReport.result?.status ?? lastReportStatus ?? defaultQualityState.reportStatus,
|
|
51
60
|
}), [qualityReport, lastReportStatus]);
|
|
52
61
|
// Exposed actions
|
|
53
62
|
const actions = useMemo(() => ({ fetchQualityReport, createQualityIssuesCalculation }), [fetchQualityReport, createQualityIssuesCalculation]);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type PropsWithChildren } from "react";
|
|
2
|
+
import type { ISemanticQualityIssue } from "@gooddata/sdk-model";
|
|
3
|
+
type Props = PropsWithChildren<{
|
|
4
|
+
issues?: ISemanticQualityIssue[];
|
|
5
|
+
}>;
|
|
6
|
+
/**
|
|
7
|
+
* Test-only QualityProvider holding a fixed, already-loaded report, so a test can exercise the
|
|
8
|
+
* quality-derived filters without a backend serving the report.
|
|
9
|
+
*
|
|
10
|
+
* Memoized on `issues`' identity for the same reason as `TestFilterProvider`.
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare function TestQualityProvider({ children, issues }: Props): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=TestQualityProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestQualityProvider.d.ts","sourceRoot":"","sources":["../../src/quality/TestQualityProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAAW,MAAM,OAAO,CAAC;AAExD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAIjE,KAAK,KAAK,GAAG,iBAAiB,CAAC;IAC3B,MAAM,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACpC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,KAAK,2CAW9D"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2026 GoodData Corporation
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { QualityStateContext, defaultQualityState } from "./QualityContext.js";
|
|
5
|
+
/**
|
|
6
|
+
* Test-only QualityProvider holding a fixed, already-loaded report, so a test can exercise the
|
|
7
|
+
* quality-derived filters without a backend serving the report.
|
|
8
|
+
*
|
|
9
|
+
* Memoized on `issues`' identity for the same reason as `TestFilterProvider`.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export function TestQualityProvider({ children, issues }) {
|
|
13
|
+
const value = useMemo(() => ({
|
|
14
|
+
...defaultQualityState,
|
|
15
|
+
status: "success",
|
|
16
|
+
issues: issues ?? defaultQualityState.issues,
|
|
17
|
+
}), [issues]);
|
|
18
|
+
return _jsx(QualityStateContext.Provider, { value: value, children: children });
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gooddata/sdk-ui-catalog",
|
|
3
|
-
"version": "11.53.0-alpha.
|
|
3
|
+
"version": "11.53.0-alpha.7",
|
|
4
4
|
"description": "GoodData SDK - Analytics Catalog",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "GoodData Corporation",
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
"tslib": "2.8.1",
|
|
42
42
|
"yaml": "2.8.3",
|
|
43
43
|
"zod": "4.3.6",
|
|
44
|
-
"@gooddata/sdk-backend-spi": "11.53.0-alpha.
|
|
45
|
-
"@gooddata/sdk-code-schemas": "11.53.0-alpha.
|
|
46
|
-
"@gooddata/sdk-model": "11.53.0-alpha.
|
|
47
|
-
"@gooddata/sdk-ui": "11.53.0-alpha.
|
|
48
|
-
"@gooddata/sdk-ui
|
|
49
|
-
"@gooddata/sdk-ui-kit": "11.53.0-alpha.
|
|
50
|
-
"@gooddata/sdk-ui-
|
|
51
|
-
"@gooddata/
|
|
52
|
-
"@gooddata/
|
|
44
|
+
"@gooddata/sdk-backend-spi": "11.53.0-alpha.7",
|
|
45
|
+
"@gooddata/sdk-code-schemas": "11.53.0-alpha.7",
|
|
46
|
+
"@gooddata/sdk-model": "11.53.0-alpha.7",
|
|
47
|
+
"@gooddata/sdk-ui-ext": "11.53.0-alpha.7",
|
|
48
|
+
"@gooddata/sdk-ui": "11.53.0-alpha.7",
|
|
49
|
+
"@gooddata/sdk-ui-kit": "11.53.0-alpha.7",
|
|
50
|
+
"@gooddata/sdk-ui-theme-provider": "11.53.0-alpha.7",
|
|
51
|
+
"@gooddata/util": "11.53.0-alpha.7",
|
|
52
|
+
"@gooddata/sdk-ui-semantic-search": "11.53.0-alpha.7"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@microsoft/api-documenter": "^7.17.0",
|
|
@@ -89,11 +89,11 @@
|
|
|
89
89
|
"typescript": "5.9.3",
|
|
90
90
|
"vitest": "4.1.8",
|
|
91
91
|
"vitest-dom": "0.1.1",
|
|
92
|
-
"@gooddata/eslint-config": "11.53.0-alpha.
|
|
93
|
-
"@gooddata/
|
|
94
|
-
"@gooddata/
|
|
95
|
-
"@gooddata/sdk-backend-mockingbird": "11.53.0-alpha.
|
|
96
|
-
"@gooddata/stylelint-config": "11.53.0-alpha.
|
|
92
|
+
"@gooddata/eslint-config": "11.53.0-alpha.7",
|
|
93
|
+
"@gooddata/i18n-toolkit": "11.53.0-alpha.7",
|
|
94
|
+
"@gooddata/oxlint-config": "11.53.0-alpha.7",
|
|
95
|
+
"@gooddata/sdk-backend-mockingbird": "11.53.0-alpha.7",
|
|
96
|
+
"@gooddata/stylelint-config": "11.53.0-alpha.7"
|
|
97
97
|
},
|
|
98
98
|
"peerDependencies": {
|
|
99
99
|
"react": "^18.0.0 || ^19.0.0",
|