@gooddata/sdk-ui-dashboard 11.48.0-alpha.2 → 11.48.0-alpha.3
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/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/kdaDialog/composition/KdaAttributesDropdown.d.ts +15 -0
- package/esm/kdaDialog/composition/KdaAttributesDropdown.d.ts.map +1 -0
- package/esm/kdaDialog/composition/KdaAttributesDropdown.js +66 -0
- package/esm/kdaDialog/composition/KdaAttributesSelectItem.d.ts +14 -0
- package/esm/kdaDialog/composition/KdaAttributesSelectItem.d.ts.map +1 -0
- package/esm/kdaDialog/composition/KdaAttributesSelectItem.js +33 -0
- package/esm/kdaDialog/composition/KeyDriversFooter.d.ts.map +1 -1
- package/esm/kdaDialog/composition/KeyDriversFooter.js +24 -78
- package/esm/kdaDialog/composition/hooks/useKdaAttributesSelection.d.ts +15 -0
- package/esm/kdaDialog/composition/hooks/useKdaAttributesSelection.d.ts.map +1 -0
- package/esm/kdaDialog/composition/hooks/useKdaAttributesSelection.js +51 -0
- package/esm/kdaDialog/composition/hooks/useKdaValidAttributes.d.ts +9 -0
- package/esm/kdaDialog/composition/hooks/useKdaValidAttributes.d.ts.map +1 -0
- package/esm/kdaDialog/composition/hooks/useKdaValidAttributes.js +45 -0
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.d.ts +20 -0
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.d.ts.map +1 -0
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.js +16 -0
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.d.ts.map +1 -1
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.js +12 -8
- package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/selectionMode/SelectionModeItem.js +1 -1
- package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/selectionType/SelectionTypeItem.js +1 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +13 -1
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +17 -5
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-419.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +5 -2
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +4 -1
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +4 -1
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +4 -1
- package/package.json +21 -21
- package/styles/css/kdaDialog.css +30 -9
- package/styles/css/kdaDialog.css.map +1 -1
- package/styles/css/main.css +30 -9
- package/styles/css/main.css.map +1 -1
- package/styles/scss/kdaDialog.scss +30 -9
package/esm/__version.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "11.48.0-alpha.
|
|
1
|
+
export declare const LIB_VERSION = "11.48.0-alpha.3";
|
|
2
2
|
export declare const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
|
|
3
3
|
export declare const LIB_NAME = "@gooddata/sdk-ui-dashboard";
|
|
4
4
|
//# sourceMappingURL=__version.d.ts.map
|
package/esm/__version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// (C) 2021 GoodData Corporation
|
|
2
2
|
// DO NOT CHANGE THIS FILE, IT IS RE-GENERATED ON EVERY BUILD
|
|
3
|
-
export const LIB_VERSION = "11.48.0-alpha.
|
|
3
|
+
export const LIB_VERSION = "11.48.0-alpha.3";
|
|
4
4
|
export const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
|
|
5
5
|
export const LIB_NAME = "@gooddata/sdk-ui-dashboard";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ICatalogAttribute } from "@gooddata/sdk-model";
|
|
2
|
+
import { type IKdaItemGroup } from "../internalTypes.js";
|
|
3
|
+
export interface IKdaAttributesDropdownProps {
|
|
4
|
+
buttonLabel: string;
|
|
5
|
+
attributesCount: number;
|
|
6
|
+
validAttributes: ICatalogAttribute[];
|
|
7
|
+
initialAttributes: ICatalogAttribute[];
|
|
8
|
+
mapAttributes: Map<string, IKdaItemGroup | undefined>;
|
|
9
|
+
isSearchBarVisible: boolean;
|
|
10
|
+
onApply: (selected: ICatalogAttribute[]) => void;
|
|
11
|
+
onOpen: () => void;
|
|
12
|
+
onClose: () => void;
|
|
13
|
+
}
|
|
14
|
+
export declare function KdaAttributesDropdown({ buttonLabel, attributesCount, validAttributes, initialAttributes, mapAttributes, isSearchBarVisible, onApply, onOpen, onClose }: IKdaAttributesDropdownProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
//# sourceMappingURL=KdaAttributesDropdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KdaAttributesDropdown.d.ts","sourceRoot":"","sources":["../../../src/kdaDialog/composition/KdaAttributesDropdown.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAW7D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAYzD,MAAM,WAAW,2BAA2B;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,iBAAiB,EAAE,CAAC;IACrC,iBAAiB,EAAE,iBAAiB,EAAE,CAAC;IACvC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC;IACtD,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,CAAC,QAAQ,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IACjD,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,wBAAgB,qBAAqB,CAAC,EAClC,WAAW,EACX,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,OAAO,EACP,MAAM,EACN,OAAO,EACV,EAAE,2BAA2B,2CA0K7B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2025-2026 GoodData Corporation
|
|
3
|
+
import { useId } from "react";
|
|
4
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
5
|
+
import { Dropdown, InvertableSelectSearchBar, InvertableSelectVirtualised, SeparatorLine, UiButton, useIdPrefixed, } from "@gooddata/sdk-ui-kit";
|
|
6
|
+
import { getAttributeKey, getAttributeTitle, useKdaAttributesSelection, } from "./hooks/useKdaAttributesSelection.js";
|
|
7
|
+
import { KdaAttributesSelectItem } from "./KdaAttributesSelectItem.js";
|
|
8
|
+
const ITEM_HEIGHT = 28;
|
|
9
|
+
const ALIGN_POINTS = [{ align: "tl bl" }];
|
|
10
|
+
export function KdaAttributesDropdown({ buttonLabel, attributesCount, validAttributes, initialAttributes, mapAttributes, isSearchBarVisible, onApply, onOpen, onClose, }) {
|
|
11
|
+
const intl = useIntl();
|
|
12
|
+
const labelKeyDriversId = useId();
|
|
13
|
+
const dropdownButtonId = useIdPrefixed("kda-attributes-dropdown-button");
|
|
14
|
+
const { searchString, setSearchString, selection, isInverted, filteredOptions, resolvedSelection, isApplyDisabled, onSelect, resetSelection, } = useKdaAttributesSelection(validAttributes, initialAttributes);
|
|
15
|
+
const popupLabel = intl.formatMessage({
|
|
16
|
+
id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.popupLabel",
|
|
17
|
+
});
|
|
18
|
+
return (_jsx(Dropdown, { className: "gd-kda-attributes-dropdown", closeOnEscape: true, autofocusOnOpen: true, overlayPositionType: "sameAsTarget", alignPoints: ALIGN_POINTS, returnFocusTo: dropdownButtonId, onOpenStateChanged: (isOpen) => {
|
|
19
|
+
if (isOpen) {
|
|
20
|
+
resetSelection();
|
|
21
|
+
onOpen();
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
onClose();
|
|
25
|
+
}
|
|
26
|
+
}, renderButton: ({ toggleDropdown, isOpen, buttonRef, dropdownId }) => (_jsx(UiButton, { id: dropdownButtonId, dataTestId: `${attributesCount}_attributes`, ref: buttonRef, variant: "tertiary", iconAfter: "settings", isSelected: isOpen, label: buttonLabel, onClick: toggleDropdown, accessibilityConfig: {
|
|
27
|
+
ariaHaspopup: "dialog",
|
|
28
|
+
ariaExpanded: isOpen,
|
|
29
|
+
ariaControls: isOpen ? dropdownId : undefined,
|
|
30
|
+
} })), renderBody: ({ closeDropdown, ariaAttributes }) => {
|
|
31
|
+
const handleApply = () => {
|
|
32
|
+
onApply(resolvedSelection);
|
|
33
|
+
closeDropdown();
|
|
34
|
+
};
|
|
35
|
+
return (_jsxs("div", { ...ariaAttributes, "aria-labelledby": undefined, "aria-label": popupLabel, className: "gd-kda-attributes-dropdown__body", children: [
|
|
36
|
+
_jsx("div", { className: "gd-kda-attributes-dropdown__header", children: popupLabel }), _jsx(InvertableSelectVirtualised, { className: "gd-kda-attributes-select", adaptiveWidth: true, items: filteredOptions, totalItemsCount: filteredOptions.length, itemHeight: ITEM_HEIGHT, getItemKey: getAttributeKey, getItemTitle: getAttributeTitle, isItemQuestionMarkEnabled: () => false, isInverted: isInverted, selectedItems: selection, canSubmitOnKeyDown: !isApplyDisabled, onApplyButtonClick: handleApply, onSelect: onSelect, searchString: searchString, onSearch: setSearchString, renderItem: (itemProps) => {
|
|
37
|
+
const group = mapAttributes.get(itemProps.item.attribute.id);
|
|
38
|
+
const driverCount = group?.significantDrivers.length ?? 0;
|
|
39
|
+
const count = driverCount > 0 ? `(${driverCount})` : "-";
|
|
40
|
+
const countAriaLabel = driverCount > 0
|
|
41
|
+
? intl.formatMessage({
|
|
42
|
+
id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.countLabel",
|
|
43
|
+
}, { count: driverCount })
|
|
44
|
+
: intl.formatMessage({
|
|
45
|
+
id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.noDrivers",
|
|
46
|
+
});
|
|
47
|
+
return (_jsx(KdaAttributesSelectItem, { ...itemProps, right: _jsx("span", { className: "gd-kda-attributes-dropdown__key_drivers", "aria-label": countAriaLabel, children: count }) }));
|
|
48
|
+
}, renderSearchBar: isSearchBarVisible
|
|
49
|
+
? ({ onSearch, searchString: search, searchPlaceholder }) => (_jsx(InvertableSelectSearchBar, { onSearch: onSearch, searchString: search, searchPlaceholder: searchPlaceholder, isSmall: true, onEscKeyPress: (e) => {
|
|
50
|
+
if (search) {
|
|
51
|
+
e.stopPropagation();
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
closeDropdown();
|
|
55
|
+
}
|
|
56
|
+
} }))
|
|
57
|
+
: () => _jsx("div", { className: "gd-kda-attributes-dropdown__no-search" }), renderActions: () => (_jsxs("div", { className: "gd-kda-attributes-dropdown__subheader", children: [
|
|
58
|
+
_jsx("div", { className: "gd-kda-attributes-dropdown__subheader__attribute", children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.detail.table.attribute" }) }), _jsx("div", { className: "gd-kda-attributes-dropdown__subheader__key_drivers", id: labelKeyDriversId, children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.detail.table.drivers" }) })
|
|
59
|
+
] })) }), _jsxs("div", { className: "gd-kda-attributes-dropdown__actions", children: [
|
|
60
|
+
_jsx(SeparatorLine, {}), _jsxs("div", { className: "gd-kda-attributes-dropdown__actions-buttons", children: [
|
|
61
|
+
_jsx(UiButton, { variant: "secondary", size: "small", onClick: closeDropdown, label: intl.formatMessage({ id: "gs.list.cancel" }) }), _jsx(UiButton, { variant: "primary", size: "small", isDisabled: isApplyDisabled, onClick: handleApply, label: intl.formatMessage({ id: "gs.list.apply" }) })
|
|
62
|
+
] })
|
|
63
|
+
] })
|
|
64
|
+
] }));
|
|
65
|
+
} }));
|
|
66
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
export interface IKdaAttributesSelectItemProps<T> {
|
|
3
|
+
item: T;
|
|
4
|
+
title: string;
|
|
5
|
+
isSelected: boolean;
|
|
6
|
+
focusedAction?: string;
|
|
7
|
+
index?: number;
|
|
8
|
+
onSelect: () => void;
|
|
9
|
+
onDeselect: () => void;
|
|
10
|
+
onSelectOnly: () => void;
|
|
11
|
+
right?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
export declare function KdaAttributesSelectItem<T>({ item, title, isSelected, focusedAction, index, onSelect, onDeselect, onSelectOnly, right }: IKdaAttributesSelectItemProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=KdaAttributesSelectItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KdaAttributesSelectItem.d.ts","sourceRoot":"","sources":["../../../src/kdaDialog/composition/KdaAttributesSelectItem.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmB,KAAK,SAAS,EAAe,MAAM,OAAO,CAAC;AASrE,MAAM,WAAW,6BAA6B,CAAC,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,SAAS,CAAC;CACrB;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,EACvC,IAAI,EACJ,KAAK,EACL,UAAU,EACV,aAAa,EACb,KAAK,EACL,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,KAAK,EACR,EAAE,6BAA6B,CAAC,CAAC,CAAC,2CAkFlC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// (C) 2025-2026 GoodData Corporation
|
|
3
|
+
import { useCallback } from "react";
|
|
4
|
+
import cx from "classnames";
|
|
5
|
+
import { FormattedMessage, useIntl } from "react-intl";
|
|
6
|
+
import { SELECT_ITEM_ACTION, ScopedIdStore, UiLink } from "@gooddata/sdk-ui-kit";
|
|
7
|
+
const ONLY_ACTION = "only";
|
|
8
|
+
export function KdaAttributesSelectItem({ item, title, isSelected, focusedAction, index, onSelect, onDeselect, onSelectOnly, right, }) {
|
|
9
|
+
const intl = useIntl();
|
|
10
|
+
const makeId = ScopedIdStore.useContextStoreOptional((ctx) => ctx.makeId);
|
|
11
|
+
const onItemClick = useCallback(() => {
|
|
12
|
+
if (isSelected) {
|
|
13
|
+
onDeselect();
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
onSelect();
|
|
17
|
+
}
|
|
18
|
+
}, [isSelected, onSelect, onDeselect]);
|
|
19
|
+
const onOnlyClick = useCallback((event) => {
|
|
20
|
+
event.stopPropagation();
|
|
21
|
+
onSelectOnly();
|
|
22
|
+
}, [onSelectOnly]);
|
|
23
|
+
const classes = cx("gd-kda-attributes-select-item", "gd-attribute-filter-elements-select-item__next", "gd-list-item", "has-only-visible", { "is-selected": isSelected }, {
|
|
24
|
+
"gd-attribute-filter-list-item--isFocused": !!focusedAction,
|
|
25
|
+
"gd-attribute-filter-list-item--isFocusedSelectItem": focusedAction === SELECT_ITEM_ACTION,
|
|
26
|
+
});
|
|
27
|
+
return (_jsxs("div", { className: classes, onClick: onItemClick, role: "row", tabIndex: -1, "aria-rowindex": index, "aria-label": title, children: [
|
|
28
|
+
_jsx("div", { role: "gridcell", className: "gd-attribute-filter-list-item-label", children: _jsxs("label", { className: "input-checkbox-label", children: [
|
|
29
|
+
_jsx("input", { tabIndex: focusedAction === SELECT_ITEM_ACTION ? 0 : -1, id: makeId?.({ item, specifier: SELECT_ITEM_ACTION }), type: "checkbox", className: "input-checkbox", readOnly: true, checked: isSelected }), _jsx("span", { className: "input-label-text", children: title })
|
|
30
|
+
] }) }), _jsx("div", { className: cx("gd-list-item-only", {
|
|
31
|
+
"gd-list-item-only--isFocusedSelectItem": focusedAction === ONLY_ACTION,
|
|
32
|
+
}), role: "gridcell", children: _jsx(UiLink, { onClick: onOnlyClick, id: makeId?.({ item, specifier: ONLY_ACTION }), variant: "primary", flipUnderline: true, role: "button", "aria-label": intl.formatMessage({ id: "attributesDropdown.onlyLabel" }, { itemTitle: title }), tabIndex: focusedAction === ONLY_ACTION ? 0 : -1, children: _jsx(FormattedMessage, { id: "gs.list.only" }) }) }), right ? (_jsx("div", { role: "gridcell", className: "gd-kda-attributes-select-item__right", children: right })) : null] }));
|
|
33
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"KeyDriversFooter.d.ts","sourceRoot":"","sources":["../../../src/kdaDialog/composition/KeyDriversFooter.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"KeyDriversFooter.d.ts","sourceRoot":"","sources":["../../../src/kdaDialog/composition/KeyDriversFooter.tsx"],"names":[],"mappings":"AAgBA,wBAAgB,gBAAgB,mDA2E/B"}
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2025-2026 GoodData Corporation
|
|
3
|
-
import {
|
|
4
|
-
import { FormattedMessage
|
|
3
|
+
import { useCallback } from "react";
|
|
4
|
+
import { FormattedMessage } from "react-intl";
|
|
5
5
|
import { areObjRefsEqual } from "@gooddata/sdk-model";
|
|
6
|
-
import {
|
|
6
|
+
import { UiSkeleton } from "@gooddata/sdk-ui-kit";
|
|
7
7
|
import { useDashboardSelector } from "../../model/react/DashboardStoreProvider.js";
|
|
8
|
-
import {
|
|
9
|
-
import { useSummaryDrivers } from "../hooks/useSummaryDrivers.js";
|
|
8
|
+
import { selectCatalogIsLoaded } from "../../model/store/catalog/catalogSelectors.js";
|
|
10
9
|
import { useKdaState } from "../providers/KdaState.js";
|
|
10
|
+
import { useKdaValidAttributes } from "./hooks/useKdaValidAttributes.js";
|
|
11
|
+
import { KdaAttributesDropdown } from "./KdaAttributesDropdown.js";
|
|
11
12
|
export function KeyDriversFooter() {
|
|
12
13
|
const { state, setState } = useKdaState();
|
|
13
|
-
const list = useSummaryDrivers();
|
|
14
|
-
const intl = useIntl();
|
|
15
|
-
const labelAttributeId = useId();
|
|
16
|
-
const labelKeyDriversId = useId();
|
|
17
14
|
const isCatalogLoaded = useDashboardSelector(selectCatalogIsLoaded);
|
|
18
15
|
const isLoading = !isCatalogLoaded ||
|
|
19
16
|
state.itemsStatus === "pending" ||
|
|
@@ -21,34 +18,22 @@ export function KeyDriversFooter() {
|
|
|
21
18
|
state.relevantStatus === "pending" ||
|
|
22
19
|
state.relevantStatus === "loading";
|
|
23
20
|
const isError = state.itemsStatus === "error";
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
})
|
|
41
|
-
.map(([a]) => a);
|
|
42
|
-
return { validAttributes, mapAttributes };
|
|
43
|
-
}, [allAttributes, list, state.relevantAttributes]);
|
|
44
|
-
const initialAttributes = useMemo(() => {
|
|
45
|
-
return state.selectedAttributes
|
|
46
|
-
.map((attr) => {
|
|
47
|
-
return validAttributes.find((a) => a.displayForms.some((df) => areObjRefsEqual(df.ref, attr)));
|
|
48
|
-
})
|
|
49
|
-
.filter(Boolean);
|
|
50
|
-
}, [state.selectedAttributes, validAttributes]);
|
|
51
|
-
const isSearchBarVisible = validAttributes.length > 7;
|
|
21
|
+
const { validAttributes, mapAttributes, initialAttributes, isSearchBarVisible } = useKdaValidAttributes();
|
|
22
|
+
const onApply = useCallback((selected) => {
|
|
23
|
+
setState({
|
|
24
|
+
selectedAttributes: selected.map((item) => {
|
|
25
|
+
const existingRef = state.selectedAttributes.find((ref) => item.displayForms.some((df) => areObjRefsEqual(df.ref, ref)));
|
|
26
|
+
return existingRef ?? item.defaultDisplayForm.ref;
|
|
27
|
+
}),
|
|
28
|
+
selectedUpdated: Date.now(),
|
|
29
|
+
});
|
|
30
|
+
}, [setState, state.selectedAttributes]);
|
|
31
|
+
const onOpen = useCallback(() => {
|
|
32
|
+
setState({ attributesDropdownOpen: true });
|
|
33
|
+
}, [setState]);
|
|
34
|
+
const onClose = useCallback(() => {
|
|
35
|
+
setState({ attributesDropdownOpen: false });
|
|
36
|
+
}, [setState]);
|
|
52
37
|
//Do not show footer when kda is not loaded at all
|
|
53
38
|
if (isError) {
|
|
54
39
|
return null;
|
|
@@ -60,46 +45,7 @@ export function KeyDriversFooter() {
|
|
|
60
45
|
const buttonLabel = chunks
|
|
61
46
|
.filter((chunk) => typeof chunk === "string")
|
|
62
47
|
.join("");
|
|
63
|
-
return (_jsx(
|
|
64
|
-
triggerRole: "button",
|
|
65
|
-
popupRole: "dialog",
|
|
66
|
-
popupLabel: intl.formatMessage({
|
|
67
|
-
id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.popupLabel",
|
|
68
|
-
}),
|
|
69
|
-
}, className: "gd-kda-attributes-dropdown", initialValue: initialAttributes, overlayPositionType: "sameAsTarget", initialIsInverted: false, options: validAttributes, onOpen: () => {
|
|
70
|
-
setState({
|
|
71
|
-
attributesDropdownOpen: true,
|
|
72
|
-
});
|
|
73
|
-
}, onClose: () => {
|
|
74
|
-
setState({
|
|
75
|
-
attributesDropdownOpen: false,
|
|
76
|
-
});
|
|
77
|
-
}, alignPoints: [{ align: "tl bl" }], getItemTitle: (item) => item.attribute.title, getItemKey: (item) => item.attribute.id, onChange: (selectedItems, isInverted) => {
|
|
78
|
-
const selected = isInverted
|
|
79
|
-
? validAttributes.filter((a) => !selectedItems.includes(a))
|
|
80
|
-
: selectedItems;
|
|
81
|
-
setState({
|
|
82
|
-
selectedAttributes: selected.map((item) => item.defaultDisplayForm.ref),
|
|
83
|
-
selectedUpdated: Date.now(),
|
|
84
|
-
});
|
|
85
|
-
}, header: _jsx("div", { className: "gd-kda-attributes-dropdown__header", children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.summary.drivers.attributes" }) }), renderSearchBar: isSearchBarVisible
|
|
86
|
-
? undefined
|
|
87
|
-
: () => _jsx("div", { className: "gd-kda-attributes-dropdown__no-search" }), renderItem: (props) => (_jsx(InvertableSelectItem, { title: props.title, isSelected: props.isSelected, onClick: props.isSelected ? props.onDeselect : props.onSelect, onOnly: props.onSelectOnly, accessibilityConfig: {
|
|
88
|
-
ariaLabelledBy: labelAttributeId,
|
|
89
|
-
}, renderRight: () => {
|
|
90
|
-
const group = mapAttributes.get(props.item.attribute.ref);
|
|
91
|
-
if (!group || group.significantDrivers.length === 0) {
|
|
92
|
-
return (_jsx("span", { className: "gd-kda-attributes-dropdown__key_drivers", "aria-labelledby": labelKeyDriversId, children: "-" }));
|
|
93
|
-
}
|
|
94
|
-
return (_jsxs("span", { className: "gd-kda-attributes-dropdown__key_drivers", "aria-labelledby": labelKeyDriversId, children: ["(", group.significantDrivers.length, ")"] }));
|
|
95
|
-
} })), renderButton: ({ buttonRef, isOpen, toggleDropdown, accessibilityConfig, }) => (_jsx(UiButton, { ref: buttonRef, variant: "tertiary", iconAfter: "settings", isSelected: isOpen, label: buttonLabel, onClick: toggleDropdown, accessibilityConfig: {
|
|
96
|
-
...accessibilityConfig,
|
|
97
|
-
ariaHaspopup: "dialog",
|
|
98
|
-
} })), renderListActions: () => {
|
|
99
|
-
return (_jsx(_Fragment, { children: _jsxs("div", { className: "gd-kda-attributes-dropdown__subheader", children: [
|
|
100
|
-
_jsx("div", { className: "gd-kda-attributes-dropdown__subheader__attribute", id: labelAttributeId, children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.detail.table.attribute" }) }), _jsx("div", { className: "gd-kda-attributes-dropdown__subheader__key_drivers", id: labelKeyDriversId, children: _jsx(FormattedMessage, { id: "kdaDialog.dialog.keyDrives.overview.detail.table.drivers" }) })
|
|
101
|
-
] }) }));
|
|
102
|
-
} }));
|
|
48
|
+
return (_jsx(KdaAttributesDropdown, { buttonLabel: buttonLabel, attributesCount: state.selectedAttributes.length, validAttributes: validAttributes, initialAttributes: initialAttributes, mapAttributes: mapAttributes, isSearchBarVisible: isSearchBarVisible, onApply: onApply, onOpen: onOpen, onClose: onClose }));
|
|
103
49
|
},
|
|
104
50
|
} })) }));
|
|
105
51
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ICatalogAttribute } from "@gooddata/sdk-model";
|
|
2
|
+
export declare const getAttributeKey: (item: ICatalogAttribute) => string;
|
|
3
|
+
export declare const getAttributeTitle: (item: ICatalogAttribute) => string;
|
|
4
|
+
export declare function useKdaAttributesSelection(validAttributes: ICatalogAttribute[], initialAttributes: ICatalogAttribute[]): {
|
|
5
|
+
searchString: string;
|
|
6
|
+
setSearchString: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
7
|
+
selection: ICatalogAttribute[];
|
|
8
|
+
isInverted: boolean;
|
|
9
|
+
filteredOptions: ICatalogAttribute[];
|
|
10
|
+
resolvedSelection: ICatalogAttribute[];
|
|
11
|
+
isApplyDisabled: boolean;
|
|
12
|
+
onSelect: (selectedItems: ICatalogAttribute[], inverted: boolean) => void;
|
|
13
|
+
resetSelection: () => void;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useKdaAttributesSelection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useKdaAttributesSelection.d.ts","sourceRoot":"","sources":["../../../../src/kdaDialog/composition/hooks/useKdaAttributesSelection.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,eAAO,MAAM,eAAe,qCAAiD,CAAC;AAC9E,eAAO,MAAM,iBAAiB,qCAAoD,CAAC;AAEnF,wBAAgB,yBAAyB,CACrC,eAAe,EAAE,iBAAiB,EAAE,EACpC,iBAAiB,EAAE,iBAAiB,EAAE;;;;;;;;;;EAuDzC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// (C) 2025-2026 GoodData Corporation
|
|
2
|
+
import { useCallback, useMemo, useState } from "react";
|
|
3
|
+
export const getAttributeKey = (item) => item.attribute.id;
|
|
4
|
+
export const getAttributeTitle = (item) => item.attribute.title;
|
|
5
|
+
export function useKdaAttributesSelection(validAttributes, initialAttributes) {
|
|
6
|
+
const [searchString, setSearchString] = useState("");
|
|
7
|
+
const [selection, setSelection] = useState(initialAttributes);
|
|
8
|
+
const [isInverted, setIsInverted] = useState(false);
|
|
9
|
+
const resetSelection = useCallback(() => {
|
|
10
|
+
setSelection(initialAttributes);
|
|
11
|
+
setIsInverted(false);
|
|
12
|
+
setSearchString("");
|
|
13
|
+
}, [initialAttributes]);
|
|
14
|
+
const filteredOptions = useMemo(() => {
|
|
15
|
+
if (!searchString) {
|
|
16
|
+
return validAttributes;
|
|
17
|
+
}
|
|
18
|
+
const lowerSearch = searchString.toLowerCase();
|
|
19
|
+
return validAttributes.filter((option) => getAttributeTitle(option).toLowerCase().includes(lowerSearch));
|
|
20
|
+
}, [validAttributes, searchString]);
|
|
21
|
+
const resolvedSelection = useMemo(() => {
|
|
22
|
+
if (!isInverted) {
|
|
23
|
+
return selection;
|
|
24
|
+
}
|
|
25
|
+
const selectedIds = new Set(selection.map(getAttributeKey));
|
|
26
|
+
return validAttributes.filter((a) => !selectedIds.has(getAttributeKey(a)));
|
|
27
|
+
}, [isInverted, selection, validAttributes]);
|
|
28
|
+
const isApplyDisabled = useMemo(() => {
|
|
29
|
+
if (resolvedSelection.length === 0) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
const currentIds = new Set(resolvedSelection.map(getAttributeKey));
|
|
33
|
+
const committedIds = new Set(initialAttributes.map(getAttributeKey));
|
|
34
|
+
return currentIds.size === committedIds.size && [...currentIds].every((id) => committedIds.has(id));
|
|
35
|
+
}, [resolvedSelection, initialAttributes]);
|
|
36
|
+
const onSelect = useCallback((selectedItems, inverted) => {
|
|
37
|
+
setSelection(selectedItems);
|
|
38
|
+
setIsInverted(inverted);
|
|
39
|
+
}, []);
|
|
40
|
+
return {
|
|
41
|
+
searchString,
|
|
42
|
+
setSearchString,
|
|
43
|
+
selection,
|
|
44
|
+
isInverted,
|
|
45
|
+
filteredOptions,
|
|
46
|
+
resolvedSelection,
|
|
47
|
+
isApplyDisabled,
|
|
48
|
+
onSelect,
|
|
49
|
+
resetSelection,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ICatalogAttribute } from "@gooddata/sdk-model";
|
|
2
|
+
import { type IKdaItemGroup } from "../../internalTypes.js";
|
|
3
|
+
export declare function useKdaValidAttributes(): {
|
|
4
|
+
validAttributes: ICatalogAttribute[];
|
|
5
|
+
mapAttributes: Map<string, IKdaItemGroup | undefined>;
|
|
6
|
+
initialAttributes: ICatalogAttribute[];
|
|
7
|
+
isSearchBarVisible: boolean;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=useKdaValidAttributes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useKdaValidAttributes.d.ts","sourceRoot":"","sources":["../../../../src/kdaDialog/composition/hooks/useKdaValidAttributes.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,qBAAqB,CAAC;AAK9E,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAK5D,wBAAgB,qBAAqB;;;;;EA4CpC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// (C) 2025-2026 GoodData Corporation
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { areObjRefsEqual } from "@gooddata/sdk-model";
|
|
4
|
+
import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
|
|
5
|
+
import { selectCatalogAttributes } from "../../../model/store/catalog/catalogSelectors.js";
|
|
6
|
+
import { useSummaryDrivers } from "../../hooks/useSummaryDrivers.js";
|
|
7
|
+
import { useKdaState } from "../../providers/KdaState.js";
|
|
8
|
+
const SEARCH_BAR_THRESHOLD = 7;
|
|
9
|
+
export function useKdaValidAttributes() {
|
|
10
|
+
const { state } = useKdaState();
|
|
11
|
+
const list = useSummaryDrivers();
|
|
12
|
+
const allAttributes = useDashboardSelector(selectCatalogAttributes);
|
|
13
|
+
const { validAttributes, mapAttributes } = useMemo(() => {
|
|
14
|
+
const mapAttributes = new Map();
|
|
15
|
+
const validAttributes = allAttributes
|
|
16
|
+
.filter((a) => {
|
|
17
|
+
return state.relevantAttributes.some((attr) => areObjRefsEqual(attr, a.attribute.ref));
|
|
18
|
+
})
|
|
19
|
+
.map((a) => {
|
|
20
|
+
const group = list.find((item) => a.displayForms.some((df) => areObjRefsEqual(df.ref, item.displayForm)));
|
|
21
|
+
mapAttributes.set(a.attribute.id, group);
|
|
22
|
+
return [a, group];
|
|
23
|
+
})
|
|
24
|
+
.sort(([, a], [, b]) => {
|
|
25
|
+
const aIndex = a ? list.indexOf(a) : Number.MAX_VALUE;
|
|
26
|
+
const bIndex = b ? list.indexOf(b) : Number.MAX_VALUE;
|
|
27
|
+
return aIndex - bIndex;
|
|
28
|
+
})
|
|
29
|
+
.map(([a]) => a);
|
|
30
|
+
return { validAttributes, mapAttributes };
|
|
31
|
+
}, [allAttributes, list, state.relevantAttributes]);
|
|
32
|
+
const initialAttributes = useMemo(() => {
|
|
33
|
+
return state.selectedAttributes
|
|
34
|
+
.map((attr) => {
|
|
35
|
+
return validAttributes.find((a) => a.displayForms.some((df) => areObjRefsEqual(df.ref, attr)));
|
|
36
|
+
})
|
|
37
|
+
.filter((a) => a !== undefined);
|
|
38
|
+
}, [state.selectedAttributes, validAttributes]);
|
|
39
|
+
return {
|
|
40
|
+
validAttributes,
|
|
41
|
+
mapAttributes,
|
|
42
|
+
initialAttributes,
|
|
43
|
+
isSearchBarVisible: validAttributes.length > SEARCH_BAR_THRESHOLD,
|
|
44
|
+
};
|
|
45
|
+
}
|
package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Dispatch, type SetStateAction } from "react";
|
|
2
|
+
import { type IAlertRelativeArithmeticOperator, type IAlertRelativeOperator, type IAttribute, type IAutomationMetadataObjectDefinition, type IMeasure } from "@gooddata/sdk-model";
|
|
3
|
+
import { type AlertAttribute, type AlertMetric } from "../../types.js";
|
|
4
|
+
export interface IUseAlertThresholdProps {
|
|
5
|
+
setEditedAutomation: Dispatch<SetStateAction<IAutomationMetadataObjectDefinition | undefined>>;
|
|
6
|
+
editedAutomation: IAutomationMetadataObjectDefinition | undefined;
|
|
7
|
+
getMetricValue: (measure?: IMeasure, attr?: IAttribute, value?: string | null) => number | undefined;
|
|
8
|
+
isNewAlert: boolean;
|
|
9
|
+
selectedRelativeOperator: [IAlertRelativeOperator, IAlertRelativeArithmeticOperator] | undefined;
|
|
10
|
+
selectedMeasure: AlertMetric | undefined;
|
|
11
|
+
selectedAttribute: AlertAttribute | undefined;
|
|
12
|
+
selectedValue: string | null | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare function useAlertThreshold({ setEditedAutomation, editedAutomation, getMetricValue, isNewAlert, selectedRelativeOperator, selectedMeasure, selectedAttribute, selectedValue }: IUseAlertThresholdProps): {
|
|
15
|
+
value: number | undefined;
|
|
16
|
+
onChange: (e: string | number, event?: import("react").ChangeEvent<HTMLInputElement> | undefined) => void;
|
|
17
|
+
onBlur: (event: import("react").FocusEvent<HTMLInputElement, Element>) => void;
|
|
18
|
+
thresholdErrorMessage: string | undefined;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=useAlertThreshold.d.ts.map
|
package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAlertThreshold.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAe,MAAM,OAAO,CAAC;AAExE,OAAO,EACH,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EAEf,KAAK,mCAAmC,EACxC,KAAK,QAAQ,EAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKvE,MAAM,WAAW,uBAAuB;IACpC,mBAAmB,EAAE,QAAQ,CAAC,cAAc,CAAC,mCAAmC,GAAG,SAAS,CAAC,CAAC,CAAC;IAC/F,gBAAgB,EAAE,mCAAmC,GAAG,SAAS,CAAC;IAClE,cAAc,EAAE,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,MAAM,GAAG,SAAS,CAAC;IACrG,UAAU,EAAE,OAAO,CAAC;IACpB,wBAAwB,EAAE,CAAC,sBAAsB,EAAE,gCAAgC,CAAC,GAAG,SAAS,CAAC;IACjG,eAAe,EAAE,WAAW,GAAG,SAAS,CAAC;IACzC,iBAAiB,EAAE,cAAc,GAAG,SAAS,CAAC;IAC9C,aAAa,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAC5C;AAED,wBAAgB,iBAAiB,CAAC,EAC9B,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EACjB,aAAa,EAChB,EAAE,uBAAuB;;;;;EAgCzB"}
|
package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useAlertThreshold.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
import { transformAlertByValue } from "../utils/transformation.js";
|
|
4
|
+
import { useThresholdValue } from "./useThresholdValue.js";
|
|
5
|
+
export function useAlertThreshold({ setEditedAutomation, editedAutomation, getMetricValue, isNewAlert, selectedRelativeOperator, selectedMeasure, selectedAttribute, selectedValue, }) {
|
|
6
|
+
const onValueChange = useCallback((value) => {
|
|
7
|
+
setEditedAutomation((alert) => alert ? transformAlertByValue(alert, value) : undefined);
|
|
8
|
+
}, [setEditedAutomation]);
|
|
9
|
+
const { value, onChange, onBlur, errorMessage: thresholdErrorMessage, } = useThresholdValue(onValueChange, getMetricValue, isNewAlert, editedAutomation?.alert, selectedRelativeOperator, selectedMeasure, selectedAttribute, selectedValue);
|
|
10
|
+
return {
|
|
11
|
+
value,
|
|
12
|
+
onChange,
|
|
13
|
+
onBlur,
|
|
14
|
+
thresholdErrorMessage,
|
|
15
|
+
};
|
|
16
|
+
}
|
package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEditAlert.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.ts"],"names":[],"mappings":"AAMA,OAAO,EACH,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,iCAAiC,EACtC,KAAK,iCAAiC,EACtC,KAAK,wBAAwB,EAC7B,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EAEb,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EACvC,KAAK,OAAO,EACZ,KAAK,cAAc,EACtB,MAAM,qBAAqB,CAAC;AAgB7B,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"useEditAlert.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.ts"],"names":[],"mappings":"AAMA,OAAO,EACH,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,iCAAiC,EACtC,KAAK,iCAAiC,EACtC,KAAK,wBAAwB,EAC7B,KAAK,gCAAgC,EACrC,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EAEb,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EACvC,KAAK,OAAO,EACZ,KAAK,cAAc,EACtB,MAAM,qBAAqB,CAAC;AAgB7B,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAkBvG,MAAM,WAAW,kBAAkB;IAC/B,WAAW,CAAC,EAAE,yBAAyB,CAAC;IACxC,oBAAoB,EAAE,8BAA8B,EAAE,GAAG,kCAAkC,EAAE,CAAC;IAC9F,wBAAwB,EAAE,MAAM,CAAC;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,uBAAuB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAE9C,0BAA0B,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IACnE,gCAAgC,CAAC,EAAE,wBAAwB,EAAE,GAAG,SAAS,CAAC;IAC1E,uBAAuB,EAAE,iBAAiB,EAAE,CAAC;IAC7C,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,wBAAgB,YAAY,CAAC,EACzB,WAAW,EACX,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,KAAK,EACL,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,gCAAgC,EAChC,uBAAuB,EACvB,yBAAyB,EAC5B,EAAE,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyiBpB"}
|
|
@@ -8,11 +8,11 @@ import { useAutomationAlertParameters } from "../../../shared/automationFilters/
|
|
|
8
8
|
import { getAppliedWidgetFilters, getVisibleFiltersByFilters, resolveMvfDimensionalityLocalRefs, } from "../../../shared/automationFilters/utils.js";
|
|
9
9
|
import { convertCurrentUserToAutomationRecipient, convertCurrentUserToWorkspaceUser, convertExternalRecipientToAutomationRecipient, } from "../../../shared/utils/automationUtils.js";
|
|
10
10
|
import { createDefaultAlert } from "../utils/convertors.js";
|
|
11
|
-
import { transformAlertByAnomalyDetection, transformAlertByAttribute, transformAlertByComparisonOperator, transformAlertByDestination, transformAlertByGranularity, transformAlertByMetric, transformAlertByRelativeOperator, transformAlertBySensitivity,
|
|
11
|
+
import { transformAlertByAnomalyDetection, transformAlertByAttribute, transformAlertByComparisonOperator, transformAlertByDestination, transformAlertByGranularity, transformAlertByMetric, transformAlertByRelativeOperator, transformAlertBySensitivity, } from "../utils/transformation.js";
|
|
12
12
|
import { useAlertFormValidation } from "./useAlertFormValidation.js";
|
|
13
13
|
import { useAlertSelectedValues } from "./useAlertSelectedValues.js";
|
|
14
14
|
import { useAlertSupportedMetrics } from "./useAlertSupportedMetrics.js";
|
|
15
|
-
import {
|
|
15
|
+
import { useAlertThreshold } from "./useAlertThreshold.js";
|
|
16
16
|
export function useEditAlert({ alertToEdit, notificationChannels, insight, widget, users, editedAutomationFilters, maxAutomationsRecipients, setEditedAutomationFilters, availableFiltersAsVisibleFilters, filtersForNewAutomation, externalRecipientOverride, }) {
|
|
17
17
|
const intl = useIntl();
|
|
18
18
|
const { catalogDateDatasets, catalogAttributes, currentUser, separators, weekStart, timezone, settings, allowHourlyRecurrence, features: { enableAlertOncePerInterval }, } = useAutomationsContext();
|
|
@@ -20,8 +20,6 @@ export function useEditAlert({ alertToEdit, notificationChannels, insight, widge
|
|
|
20
20
|
const { dashboardId, hiddenFilters: dashboardHiddenFilters, commonDateFilterId, dashboardEvaluationFrequency, widgetLocalIdToTabIdMap: widgetTabMap, parameterValues, } = useAlertingDialogContext();
|
|
21
21
|
// Determine target tab ID if widget is present
|
|
22
22
|
const targetTabIdentifier = widget?.localIdentifier ? widgetTabMap[widget.localIdentifier] : undefined;
|
|
23
|
-
// Computed values
|
|
24
|
-
const isNewAlert = !alertToEdit;
|
|
25
23
|
const { measureFormatMap, supportedMeasures, supportedAttributes, isResultLoading, getAttributeValues, getMetricValue, } = useAlertSupportedMetrics({ insight, widget, alertToEdit });
|
|
26
24
|
// Default values
|
|
27
25
|
const defaultMeasure = supportedMeasures[0];
|
|
@@ -99,9 +97,6 @@ export function useEditAlert({ alertToEdit, notificationChannels, insight, widge
|
|
|
99
97
|
? transformAlertByAttribute(supportedAttributes, alert, attribute, value)
|
|
100
98
|
: undefined);
|
|
101
99
|
}, [supportedAttributes]);
|
|
102
|
-
const onValueChange = useCallback((value) => {
|
|
103
|
-
setEditedAutomation((alert) => alert ? transformAlertByValue(alert, value) : undefined);
|
|
104
|
-
}, []);
|
|
105
100
|
const onComparisonOperatorChange = useCallback((measure, comparisonOperator) => {
|
|
106
101
|
setEditedAutomation((alert) => alert
|
|
107
102
|
? transformAlertByComparisonOperator(supportedMeasures, alert, measure, comparisonOperator)
|
|
@@ -237,7 +232,16 @@ export function useEditAlert({ alertToEdit, notificationChannels, insight, widge
|
|
|
237
232
|
const onApplyCurrentFilters = useCallback(() => {
|
|
238
233
|
onFiltersChange(filtersForNewAutomation);
|
|
239
234
|
}, [filtersForNewAutomation, onFiltersChange]);
|
|
240
|
-
const { value, onChange, onBlur,
|
|
235
|
+
const { value, onChange, onBlur, thresholdErrorMessage } = useAlertThreshold({
|
|
236
|
+
setEditedAutomation,
|
|
237
|
+
editedAutomation,
|
|
238
|
+
getMetricValue,
|
|
239
|
+
isNewAlert: !alertToEdit,
|
|
240
|
+
selectedRelativeOperator,
|
|
241
|
+
selectedMeasure,
|
|
242
|
+
selectedAttribute,
|
|
243
|
+
selectedValue,
|
|
244
|
+
});
|
|
241
245
|
const { isSubmitDisabled, validationErrorMessage, isParentValid } = useAlertFormValidation({
|
|
242
246
|
editedAutomation,
|
|
243
247
|
originalAutomation,
|
|
@@ -9,5 +9,5 @@ export function SelectionModeItem({ item, itemTitle, tooltip, selected, disabled
|
|
|
9
9
|
}, "s-selection-mode-dropdown-item", `s-selection-mode-dropdown-item-${item}`);
|
|
10
10
|
const tooltipText = disabled ? disabledTooltip : tooltip;
|
|
11
11
|
return (_jsxs("div", { className: className, onClick: () => !disabled && onClick(), children: [
|
|
12
|
-
_jsx("span", { className: "selection-kind-dropdown-item-title", children: itemTitle }), tooltipText ? (_jsx(UiTooltip, { anchor: _jsx("span", { className: "selection-kind-dropdown-item-help gd-icon-circle-question" }), content: tooltipText, arrowPlacement: "left", triggerBy: ["hover"], width: TOOLTIP_WIDTH_MEDIUM,
|
|
12
|
+
_jsx("span", { className: "selection-kind-dropdown-item-title", children: itemTitle }), tooltipText ? (_jsx(UiTooltip, { anchor: _jsx("span", { className: "selection-kind-dropdown-item-help gd-icon-circle-question" }), content: tooltipText, arrowPlacement: "left", triggerBy: ["hover"], width: TOOLTIP_WIDTH_MEDIUM, inlineAnchor: true })) : null] }));
|
|
13
13
|
}
|
|
@@ -8,7 +8,7 @@ export function SelectionTypeItem({ item, itemTitle, tooltip, selected, disabled
|
|
|
8
8
|
"is-disabled": disabled,
|
|
9
9
|
}, "s-selection-kind-dropdown-item", `s-selection-kind-dropdown-item-${item}`);
|
|
10
10
|
const itemContent = (_jsxs("div", { className: className, onClick: () => !disabled && onClick(), children: [
|
|
11
|
-
_jsx("span", { className: "selection-kind-dropdown-item-title", children: itemTitle }), disabled ? null : (_jsx(UiTooltip, { anchor: _jsx("span", { className: "selection-kind-dropdown-item-help gd-icon-circle-question" }), content: _jsx("span", { style: { whiteSpace: "pre-line", maxWidth: 240 }, children: tooltip }), arrowPlacement: "left", triggerBy: ["hover"],
|
|
11
|
+
_jsx("span", { className: "selection-kind-dropdown-item-title", children: itemTitle }), disabled ? null : (_jsx(UiTooltip, { anchor: _jsx("span", { className: "selection-kind-dropdown-item-help gd-icon-circle-question" }), content: _jsx("span", { style: { whiteSpace: "pre-line", maxWidth: 240 }, children: tooltip }), arrowPlacement: "left", triggerBy: ["hover"], inlineAnchor: true }))] }));
|
|
12
12
|
if (disabled && disabledTooltip) {
|
|
13
13
|
return (_jsx(UiTooltip, { anchor: itemContent, content: _jsx("span", { style: { maxWidth: 240 }, children: disabledTooltip }), arrowPlacement: "left", triggerBy: ["hover"], anchorWrapperStyles: { width: "100%", height: "100%" } }));
|
|
14
14
|
}
|
|
@@ -4,6 +4,8 @@ export declare const de_DE: {
|
|
|
4
4
|
empty_value: string;
|
|
5
5
|
"gs.list.cancel": string;
|
|
6
6
|
"gs.list.apply": string;
|
|
7
|
+
"gs.list.only": string;
|
|
8
|
+
"attributesDropdown.onlyLabel": string;
|
|
7
9
|
"messages.dashboardSaveSuccess": string;
|
|
8
10
|
"options.menu.save.as": string;
|
|
9
11
|
"options.menu.save.as.tooltip": string;
|
|
@@ -829,7 +831,8 @@ export declare const de_DE: {
|
|
|
829
831
|
"kdaDialog.dialog.keyDrives.overview.summary.title": string;
|
|
830
832
|
"kdaDialog.dialog.keyDrives.overview.summary.drivers.description": string;
|
|
831
833
|
"kdaDialog.dialog.keyDrives.overview.summary.drivers.popupLabel": string;
|
|
832
|
-
"kdaDialog.dialog.keyDrives.overview.summary.drivers.
|
|
834
|
+
"kdaDialog.dialog.keyDrives.overview.summary.drivers.countLabel": string;
|
|
835
|
+
"kdaDialog.dialog.keyDrives.overview.summary.drivers.noDrivers": string;
|
|
833
836
|
"kdaDialog.dialog.keyDrives.overview.diff.title": string;
|
|
834
837
|
"kdaDialog.dialog.keyDrives.overview.detail.tip": string;
|
|
835
838
|
"kdaDialog.dialog.keyDrives.overview.detail.title": string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"de-DE.localization-bundle.d.ts","sourceRoot":"","sources":["../../../../src/presentation/localization/bundles/de-DE.localization-bundle.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK
|
|
1
|
+
{"version":3,"file":"de-DE.localization-bundle.d.ts","sourceRoot":"","sources":["../../../../src/presentation/localization/bundles/de-DE.localization-bundle.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAs2BjB,CAAC"}
|
|
@@ -6,6 +6,8 @@ export const de_DE = {
|
|
|
6
6
|
"empty_value": "leerer Wert",
|
|
7
7
|
"gs.list.cancel": "Abbrechen",
|
|
8
8
|
"gs.list.apply": "Anwenden",
|
|
9
|
+
"gs.list.only": "Nur",
|
|
10
|
+
"attributesDropdown.onlyLabel": "Nur {itemTitle} auswählen",
|
|
9
11
|
"messages.dashboardSaveSuccess": "Großartig. Wir haben Ihr Dashboard gespeichert.",
|
|
10
12
|
"options.menu.save.as": "Als neu speichern",
|
|
11
13
|
"options.menu.save.as.tooltip": "Ein leeres Dashboard kann nicht gespeichert werden.",
|
|
@@ -831,7 +833,8 @@ export const de_DE = {
|
|
|
831
833
|
"kdaDialog.dialog.keyDrives.overview.summary.title": "Analysezusammenfassung",
|
|
832
834
|
"kdaDialog.dialog.keyDrives.overview.summary.drivers.description": "Getestete {combinations} Varianten mit <button>{attributes} Attributen</button>",
|
|
833
835
|
"kdaDialog.dialog.keyDrives.overview.summary.drivers.popupLabel": "Attributauswahl ändern",
|
|
834
|
-
"kdaDialog.dialog.keyDrives.overview.summary.drivers.
|
|
836
|
+
"kdaDialog.dialog.keyDrives.overview.summary.drivers.countLabel": "{count, plural, one {# Treiber} other {# Treiber}}",
|
|
837
|
+
"kdaDialog.dialog.keyDrives.overview.summary.drivers.noDrivers": "Keine Treiber",
|
|
835
838
|
"kdaDialog.dialog.keyDrives.overview.diff.title": "Diff",
|
|
836
839
|
"kdaDialog.dialog.keyDrives.overview.detail.tip": "Klicken Sie auf die Spalte, um die wichtigsten Treiber für die angegebene {category}",
|
|
837
840
|
"kdaDialog.dialog.keyDrives.overview.detail.title": "Änderung in {title} bis {category}",
|