@widergy/energy-ui 3.160.1 → 3.162.0

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +16 -3
  2. package/dist/components/UTBanner/README.md +41 -8
  3. package/dist/components/UTBanner/constants.js +36 -0
  4. package/dist/components/UTBanner/index.js +118 -15
  5. package/dist/components/UTBanner/stories/UTBanner.stories.js +164 -0
  6. package/dist/components/UTBanner/styles.module.scss +149 -5
  7. package/dist/components/UTBanner/types.js +20 -0
  8. package/dist/components/UTBanner/utils.js +148 -0
  9. package/dist/components/UTGraph/index.js +1 -1
  10. package/dist/components/UTHeader/index.js +3 -2
  11. package/dist/components/UTShortcutPanel/components/GroupingPanel/components/ExpandedPanelContent/components/ExpandedPanelContentCategory/components/ExpandedPanelContentCategoryItem/index.js +8 -3
  12. package/dist/components/UTShortcutPanel/components/GroupingPanel/components/ExpandedPanelContent/components/ExpandedPanelContentCategory/components/ExpandedPanelContentCategoryItem/layout.js +33 -3
  13. package/dist/components/UTShortcutPanel/components/GroupingPanel/components/ExpandedPanelContent/components/ExpandedPanelContentHeader/index.js +4 -0
  14. package/dist/components/UTShortcutPanel/index.js +33 -4
  15. package/dist/components/UTShortcutPanel/stories/UTShortcutPanel.stories.js +39 -0
  16. package/dist/components/UTShortcutPanel/stories/constants.json +2 -0
  17. package/dist/components/UTShortcutPanel/stories/props.schema.json +10 -1
  18. package/dist/components/UTShortcutPanel/styles.module.scss +11 -3
  19. package/dist/constants/testIds.js +3 -0
  20. package/dist/esm/components/UTBanner/README.md +41 -8
  21. package/dist/esm/components/UTBanner/constants.js +30 -0
  22. package/dist/esm/components/UTBanner/index.js +120 -16
  23. package/dist/esm/components/UTBanner/stories/UTBanner.stories.js +157 -0
  24. package/dist/esm/components/UTBanner/styles.module.scss +149 -5
  25. package/dist/esm/components/UTBanner/types.js +14 -0
  26. package/dist/esm/components/UTBanner/utils.js +137 -0
  27. package/dist/esm/components/UTGraph/index.js +2 -2
  28. package/dist/esm/components/UTHeader/index.js +3 -2
  29. package/dist/esm/components/UTShortcutPanel/components/GroupingPanel/components/ExpandedPanelContent/components/ExpandedPanelContentCategory/components/ExpandedPanelContentCategoryItem/index.js +7 -2
  30. package/dist/esm/components/UTShortcutPanel/components/GroupingPanel/components/ExpandedPanelContent/components/ExpandedPanelContentCategory/components/ExpandedPanelContentCategoryItem/layout.js +34 -4
  31. package/dist/esm/components/UTShortcutPanel/components/GroupingPanel/components/ExpandedPanelContent/components/ExpandedPanelContentHeader/index.js +5 -1
  32. package/dist/esm/components/UTShortcutPanel/index.js +33 -4
  33. package/dist/esm/components/UTShortcutPanel/stories/UTShortcutPanel.stories.js +39 -0
  34. package/dist/esm/components/UTShortcutPanel/stories/constants.json +2 -0
  35. package/dist/esm/components/UTShortcutPanel/stories/props.schema.json +10 -1
  36. package/dist/esm/components/UTShortcutPanel/styles.module.scss +11 -3
  37. package/dist/esm/constants/testIds.js +3 -0
  38. package/dist/esm/index.js +2 -1
  39. package/dist/esm/utils/hooks/useCSSVariables/constants.js +13 -0
  40. package/dist/index.js +7 -0
  41. package/dist/utils/hooks/useCSSVariables/constants.js +13 -0
  42. package/package.json +1 -1
  43. package/dist/components/UTBanner/theme.js +0 -18
  44. package/dist/esm/components/UTBanner/theme.js +0 -11
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getSecondaryLabelColorTheme = exports.getLabelStyles = exports.getLabelColorTheme = exports.getDefaultIconTheme = exports.getDefaultIconSize = exports.getDefaultButtonColorTheme = void 0;
7
+ var _constants = require("./constants");
8
+ /**
9
+ * Returns the default UTIcon colorTheme and shade for the banner icon based on the
10
+ * banner's colorTheme and variant. Matches the mobile implementation.
11
+ * @param {string} colorTheme - Banner color theme.
12
+ * @param {string} variant - Banner variant ('light' | 'dark').
13
+ * @returns {{ colorTheme: string, shade: string }}
14
+ */
15
+ const getDefaultIconTheme = (colorTheme, variant) => {
16
+ var _COLOR_THEMES$ERROR$C;
17
+ if (variant === _constants.VARIANTS.DARK) {
18
+ return colorTheme === _constants.COLOR_THEMES.NEGATIVE ? {
19
+ colorTheme: 'dark',
20
+ shade: '05'
21
+ } : {
22
+ colorTheme: 'light',
23
+ shade: '01'
24
+ };
25
+ }
26
+ return (_COLOR_THEMES$ERROR$C = {
27
+ [_constants.COLOR_THEMES.ERROR]: {
28
+ colorTheme: 'error',
29
+ shade: '04'
30
+ },
31
+ [_constants.COLOR_THEMES.GRAY]: {
32
+ colorTheme: 'accent',
33
+ shade: '04'
34
+ },
35
+ [_constants.COLOR_THEMES.INFORMATION]: {
36
+ colorTheme: 'information',
37
+ shade: '04'
38
+ },
39
+ [_constants.COLOR_THEMES.NEGATIVE]: {
40
+ colorTheme: 'light',
41
+ shade: '01'
42
+ },
43
+ [_constants.COLOR_THEMES.PRIMARY]: {
44
+ colorTheme: 'accent',
45
+ shade: '04'
46
+ },
47
+ [_constants.COLOR_THEMES.SUCCESS]: {
48
+ colorTheme: 'success',
49
+ shade: '04'
50
+ },
51
+ [_constants.COLOR_THEMES.WARNING]: {
52
+ colorTheme: 'warning',
53
+ shade: '04'
54
+ },
55
+ [_constants.COLOR_THEMES.WHITE]: {
56
+ colorTheme: 'accent',
57
+ shade: '04'
58
+ }
59
+ }[colorTheme]) !== null && _COLOR_THEMES$ERROR$C !== void 0 ? _COLOR_THEMES$ERROR$C : {
60
+ colorTheme: 'accent',
61
+ shade: '04'
62
+ };
63
+ };
64
+
65
+ /**
66
+ * Returns the default icon size in pixels based on the banner size.
67
+ * @param {string} size - One of SIZES values.
68
+ * @returns {number}
69
+ */
70
+ exports.getDefaultIconTheme = getDefaultIconTheme;
71
+ const getDefaultIconSize = size => size === _constants.SIZES.LARGE ? 24 : 20;
72
+
73
+ /**
74
+ * Returns the default colorTheme for buttons and the close button based on the
75
+ * banner variant. Dark variant uses 'negative'; light variant uses standard colors.
76
+ * @param {string} variant - Banner variant ('light' | 'dark').
77
+ * @returns {{ button: string, onClose: string, secondaryButton: string }}
78
+ */
79
+ exports.getDefaultIconSize = getDefaultIconSize;
80
+ const getDefaultButtonColorTheme = variant => {
81
+ const isDark = variant === _constants.VARIANTS.DARK;
82
+ return {
83
+ button: isDark ? 'negative' : 'secondary',
84
+ onClose: isDark ? 'negative' : 'gray',
85
+ secondaryButton: isDark ? 'negative' : 'secondary'
86
+ };
87
+ };
88
+
89
+ /**
90
+ * Returns the UTLabel variant and weight for the main text (children) based on
91
+ * the banner size.
92
+ * @param {string} size - One of SIZES values.
93
+ * @returns {{ variant: string, weight: string }}
94
+ */
95
+ exports.getDefaultButtonColorTheme = getDefaultButtonColorTheme;
96
+ const getLabelStyles = size => {
97
+ var _SIZES$LARGE$SIZES$ME;
98
+ return (_SIZES$LARGE$SIZES$ME = {
99
+ [_constants.SIZES.LARGE]: {
100
+ titleVariant: 'title3',
101
+ descriptionVariant: 'body'
102
+ },
103
+ [_constants.SIZES.MEDIUM]: {
104
+ titleVariant: 'subtitle1',
105
+ descriptionVariant: 'small'
106
+ },
107
+ [_constants.SIZES.SMALL]: {
108
+ titleVariant: 'small',
109
+ descriptionVariant: 'small'
110
+ }
111
+ }[size]) !== null && _SIZES$LARGE$SIZES$ME !== void 0 ? _SIZES$LARGE$SIZES$ME : {
112
+ titleVariant: 'small',
113
+ descriptionVariant: 'small'
114
+ };
115
+ };
116
+
117
+ /**
118
+ * Returns the UTLabel colorTheme for the banner's main text content based on the
119
+ * banner's colorTheme and variant. Negative+light and any dark variant use light
120
+ * (white) text; all other combinations use dark text.
121
+ * @param {string} colorTheme - Banner color theme.
122
+ * @param {string} variant - Banner variant ('light' | 'dark').
123
+ * @returns {string} UTLabel colorTheme value.
124
+ */
125
+ exports.getLabelStyles = getLabelStyles;
126
+ const getLabelColorTheme = (colorTheme, variant) => {
127
+ if (colorTheme === _constants.COLOR_THEMES.NEGATIVE) {
128
+ return variant === _constants.VARIANTS.LIGHT ? 'light' : 'dark';
129
+ }
130
+ return variant === _constants.VARIANTS.LIGHT ? 'dark' : 'light';
131
+ };
132
+
133
+ /**
134
+ * Returns the UTLabel colorTheme for the banner's secondary text content based on the
135
+ * banner's colorTheme and variant. Negative+light and any dark variant use light
136
+ * (white) text; all other combinations use gray text.
137
+ * @param {string} colorTheme - Banner color theme.
138
+ * @param {string} variant - Banner variant ('light' | 'gray').
139
+ * @returns {string} UTLabel colorTheme value.
140
+ */
141
+ exports.getLabelColorTheme = getLabelColorTheme;
142
+ const getSecondaryLabelColorTheme = (colorTheme, variant) => {
143
+ if (colorTheme === _constants.COLOR_THEMES.NEGATIVE) {
144
+ return variant === _constants.VARIANTS.LIGHT ? 'light' : 'gray';
145
+ }
146
+ return variant === _constants.VARIANTS.LIGHT ? 'gray' : 'light';
147
+ };
148
+ exports.getSecondaryLabelColorTheme = getSecondaryLabelColorTheme;
@@ -176,7 +176,7 @@ const UTGraph = _ref => {
176
176
  crossAxisLeft,
177
177
  crossAxisRight
178
178
  } = _ref2;
179
- return /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(_Bars.default, {
179
+ return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Bars.default, {
180
180
  crossAxisLeft: crossAxisLeft,
181
181
  crossAxisRight: crossAxisRight,
182
182
  dataset: dataset,
@@ -154,8 +154,9 @@ const UTHeader = _ref => {
154
154
  height: BANNER_ICON_SIZE,
155
155
  width: BANNER_ICON_SIZE
156
156
  },
157
- Icon: banner.Icon
158
- }, banner.text)));
157
+ Icon: banner.Icon,
158
+ title: banner.text
159
+ })));
159
160
  };
160
161
  UTHeader.propTypes = {
161
162
  actions: (0, _propTypes.arrayOf)(_propTypes.object),
@@ -4,14 +4,13 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
8
7
  var _react = _interopRequireWildcard(require("react"));
9
8
  var _propTypes = require("prop-types");
10
9
  var _context = _interopRequireDefault(require("../../../../../../../../context"));
11
10
  var _utils = require("../../../../../../../../utils");
12
11
  var _layout = _interopRequireDefault(require("./layout"));
13
- function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
15
14
  const ExpandedPanelContentCategoryItemContainer = _ref => {
16
15
  var _name$toLowerCase, _name$toLowerCase$spl, _name$toLowerCase$spl2;
17
16
  let {
@@ -22,11 +21,13 @@ const ExpandedPanelContentCategoryItemContainer = _ref => {
22
21
  classes,
23
22
  closePopper,
24
23
  handleSelectFilter,
24
+ invalidParamsConfig,
25
25
  onDeleteFilterGrouping,
26
26
  onEditFilterGrouping,
27
27
  openPopper,
28
28
  position,
29
29
  selectedFilter,
30
+ showActionsOnPinned,
30
31
  tooltipsContentMap: {
31
32
  editButton,
32
33
  deleteButton
@@ -34,10 +35,12 @@ const ExpandedPanelContentCategoryItemContainer = _ref => {
34
35
  } = (0, _react.useContext)(_context.default);
35
36
  const {
36
37
  description,
38
+ hasInvalidParams,
37
39
  name,
38
40
  pinned,
39
41
  category
40
42
  } = filter;
43
+ const resolvedHasInvalidParams = hasInvalidParams ? invalidParamsConfig !== null && invalidParamsConfig !== void 0 ? invalidParamsConfig : true : false;
41
44
  const id = "".concat(name === null || name === void 0 || (_name$toLowerCase = name.toLowerCase) === null || _name$toLowerCase === void 0 || (_name$toLowerCase = _name$toLowerCase.call(name)) === null || _name$toLowerCase === void 0 || (_name$toLowerCase$spl = _name$toLowerCase.split) === null || _name$toLowerCase$spl === void 0 || (_name$toLowerCase$spl = _name$toLowerCase$spl.call(_name$toLowerCase, ' ')) === null || _name$toLowerCase$spl === void 0 || (_name$toLowerCase$spl2 = _name$toLowerCase$spl.join) === null || _name$toLowerCase$spl2 === void 0 ? void 0 : _name$toLowerCase$spl2.call(_name$toLowerCase$spl, '_'), "_").concat(category);
42
45
  const deleteButtonTippyRef = (0, _react.useRef)(null);
43
46
  const editButtonTippyRef = (0, _react.useRef)(null);
@@ -65,12 +68,14 @@ const ExpandedPanelContentCategoryItemContainer = _ref => {
65
68
  handleDeleteFilterGrouping: onDeleteFilterGrouping ? () => onDeleteFilterGrouping(filter) : undefined,
66
69
  handleEditFilterGrouping: onEditFilterGrouping ? () => onEditFilterGrouping(filter) : undefined,
67
70
  handleSelectFilter: handleSelectFilters,
71
+ hasInvalidParams: resolvedHasInvalidParams,
68
72
  id: id,
69
73
  name: name,
70
74
  openItemDescription: handleOpenItemDescription,
71
75
  pinned: pinned,
72
76
  position: position,
73
- selected: (0, _isEqual.default)(selectedFilter, filter)
77
+ showActionsOnPinned: showActionsOnPinned,
78
+ selected: (selectedFilter === null || selectedFilter === void 0 ? void 0 : selectedFilter.id) != null && selectedFilter.id === (filter === null || filter === void 0 ? void 0 : filter.id) && selectedFilter.category === (filter === null || filter === void 0 ? void 0 : filter.category)
74
79
  });
75
80
  };
76
81
  ExpandedPanelContentCategoryItemContainer.propTypes = {
@@ -34,13 +34,19 @@ const ExpandedPanelContentCategoryItem = _ref => {
34
34
  handleDeleteFilterGrouping,
35
35
  handleEditFilterGrouping,
36
36
  handleSelectFilter,
37
+ hasInvalidParams,
37
38
  id,
38
39
  name,
39
40
  openItemDescription,
40
41
  pinned,
41
42
  position,
42
- selected
43
+ selected,
44
+ showActionsOnPinned
43
45
  } = _ref;
46
+ const isInvalidParamsObject = typeof hasInvalidParams === 'object';
47
+ const invalidIconName = (isInvalidParamsObject ? hasInvalidParams === null || hasInvalidParams === void 0 ? void 0 : hasInvalidParams.iconName : null) || 'IconAlertTriangle';
48
+ const invalidIconSize = (isInvalidParamsObject ? hasInvalidParams === null || hasInvalidParams === void 0 ? void 0 : hasInvalidParams.size : null) || '16';
49
+ const invalidTooltipText = isInvalidParamsObject ? hasInvalidParams === null || hasInvalidParams === void 0 ? void 0 : hasInvalidParams.tooltipText : undefined;
44
50
  return /*#__PURE__*/_react.default.createElement("article", {
45
51
  className: "".concat(classes.expandedPanelContentCategoryItem, " ").concat(selected ? classes.expandedPanelContentCategoryItemSelected : ''),
46
52
  id: id
@@ -63,7 +69,25 @@ const ExpandedPanelContentCategoryItem = _ref => {
63
69
  className: classes.expandedPanelContentCategoryItemTitleLabel,
64
70
  colorTheme: selected ? 'accent' : undefined,
65
71
  shade: selected ? '05' : undefined
66
- }, name))), !pinned && (handleEditFilterGrouping || handleDeleteFilterGrouping) && /*#__PURE__*/_react.default.createElement("section", {
72
+ }, name)), hasInvalidParams && (invalidTooltipText ? /*#__PURE__*/_react.default.createElement(_UTTooltip.default, {
73
+ content: invalidTooltipText,
74
+ tippyProps: {
75
+ appendTo: () => document.body,
76
+ placement: 'top'
77
+ }
78
+ }, /*#__PURE__*/_react.default.createElement("span", {
79
+ className: classes.hasInvalidParamsTooltipContainer
80
+ }, /*#__PURE__*/_react.default.createElement(_UTIcon.default, {
81
+ colorTheme: "warning",
82
+ dataTestId: "".concat(dataTestId, ".").concat(_testIds.ID_CONSTANTS.INVALID_PARAMS),
83
+ name: invalidIconName,
84
+ size: invalidIconSize
85
+ }))) : /*#__PURE__*/_react.default.createElement(_UTIcon.default, {
86
+ colorTheme: "warning",
87
+ dataTestId: "".concat(dataTestId, ".").concat(_testIds.ID_CONSTANTS.INVALID_PARAMS),
88
+ name: invalidIconName,
89
+ size: invalidIconSize
90
+ }))), (!pinned || showActionsOnPinned) && (handleEditFilterGrouping || handleDeleteFilterGrouping) && /*#__PURE__*/_react.default.createElement("section", {
67
91
  className: classes.expandedPanelContentCategoryItemActionsContainer,
68
92
  onAnimationEnd: animationEnd
69
93
  }, handleEditFilterGrouping && /*#__PURE__*/_react.default.createElement(_UTTooltip.default, {
@@ -118,11 +142,17 @@ ExpandedPanelContentCategoryItem.propTypes = {
118
142
  handleDeleteFilterGrouping: _propTypes.func,
119
143
  handleEditFilterGrouping: _propTypes.func,
120
144
  handleSelectFilter: _propTypes.func,
145
+ hasInvalidParams: (0, _propTypes.oneOfType)([_propTypes.bool, (0, _propTypes.shape)({
146
+ iconName: _propTypes.string,
147
+ size: _propTypes.string,
148
+ tooltipText: _propTypes.string
149
+ })]),
121
150
  id: _propTypes.string,
122
151
  name: _propTypes.string,
123
152
  openItemDescription: _propTypes.func,
124
153
  pinned: _propTypes.bool,
125
154
  position: _propTypes.string,
126
- selected: _propTypes.bool
155
+ selected: _propTypes.bool,
156
+ showActionsOnPinned: _propTypes.bool
127
157
  };
128
158
  var _default = exports.default = ExpandedPanelContentCategoryItem;
@@ -32,6 +32,7 @@ const ExpandedPanelContentHeaderContainer = _ref => {
32
32
  hideAddFilterButton,
33
33
  panelTitle,
34
34
  position,
35
+ searchResetTrigger,
35
36
  searchValue,
36
37
  tooltipsContentMap: {
37
38
  collapseButton,
@@ -39,6 +40,9 @@ const ExpandedPanelContentHeaderContainer = _ref => {
39
40
  }
40
41
  } = (0, _react.useContext)(_context.default);
41
42
  const [searchOpen, setSearchOpen] = (0, _react.useState)(false);
43
+ (0, _react.useEffect)(() => {
44
+ if (searchResetTrigger > 0) setSearchOpen(false);
45
+ }, [searchResetTrigger]);
42
46
  const handleSearchToggle = () => {
43
47
  handleFilterGroupSearch('');
44
48
  setSearchOpen(!searchOpen);
@@ -28,6 +28,7 @@ const UTShortcutPanelContainer = _ref => {
28
28
  handleSelectFilter,
29
29
  hideAddFilterButton = false,
30
30
  iconProps,
31
+ invalidParamsConfig,
31
32
  noFiltersText,
32
33
  noFiltersTitle,
33
34
  onDeleteFilterGrouping,
@@ -36,6 +37,8 @@ const UTShortcutPanelContainer = _ref => {
36
37
  panelTitle,
37
38
  position = _constants.PANEL_POSITIONS.LEFT,
38
39
  scrollProps,
40
+ searchResetKey,
41
+ showActionsOnPinned = false,
39
42
  selectedFilter,
40
43
  startOpen = false,
41
44
  tooltipsContentMap = {}
@@ -44,6 +47,7 @@ const UTShortcutPanelContainer = _ref => {
44
47
  const containerRef = (0, _react.useRef)(null);
45
48
  const [open, setOpen] = (0, _react.useState)(startOpen);
46
49
  const [filteredValues, setFilteredValues] = (0, _react.useState)(false);
50
+ const [searchTerm, setSearchTerm] = (0, _react.useState)('');
47
51
  const handleTogglePanel = () => {
48
52
  setOpen(!open);
49
53
  onTogglePanel === null || onTogglePanel === void 0 || onTogglePanel(!open);
@@ -52,8 +56,8 @@ const UTShortcutPanelContainer = _ref => {
52
56
 
53
57
  // TODO: desarrollo en otro PR
54
58
  const handleAddFilterGroup = () => {};
55
- const handleFilterGroupSearch = value => {
56
- const filteredResults = categories.map(category => {
59
+ const applySearch = (value, source) => {
60
+ const filteredResults = source.map(category => {
57
61
  const filters = category.filters.filter(filter => filter.name.toLowerCase().includes(value.toLowerCase()));
58
62
  return {
59
63
  ...category,
@@ -63,6 +67,10 @@ const UTShortcutPanelContainer = _ref => {
63
67
  setFilteredCategories(filteredResults);
64
68
  setFilteredValues(Boolean(value));
65
69
  };
70
+ const handleFilterGroupSearch = value => {
71
+ setSearchTerm(value);
72
+ applySearch(value, categories);
73
+ };
66
74
  const [popperState, setPopperState] = (0, _react.useState)({});
67
75
  const openPopper = _ref2 => {
68
76
  let {
@@ -82,8 +90,19 @@ const UTShortcutPanelContainer = _ref => {
82
90
  setPopperState({});
83
91
  };
84
92
  (0, _react.useEffect)(() => {
85
- setFilteredCategories(categories);
93
+ if (searchTerm) {
94
+ applySearch(searchTerm, categories);
95
+ } else {
96
+ setFilteredCategories(categories);
97
+ }
86
98
  }, [categories]);
99
+ const [searchResetTrigger, setSearchResetTrigger] = (0, _react.useState)(0);
100
+ (0, _react.useEffect)(() => {
101
+ setSearchTerm('');
102
+ setFilteredValues(false);
103
+ setFilteredCategories(categories);
104
+ setSearchResetTrigger(prev => prev + 1);
105
+ }, [searchResetKey]);
87
106
  const contextValue = (0, _react.useMemo)(() => ({
88
107
  categories: filteredCategories,
89
108
  categoriesConfig,
@@ -98,6 +117,7 @@ const UTShortcutPanelContainer = _ref => {
98
117
  handleTogglePanel,
99
118
  hideAddFilterButton,
100
119
  iconProps,
120
+ invalidParamsConfig,
101
121
  noFiltersText,
102
122
  noFiltersTitle,
103
123
  onDeleteFilterGrouping,
@@ -108,10 +128,12 @@ const UTShortcutPanelContainer = _ref => {
108
128
  popperState,
109
129
  position,
110
130
  scrollProps,
131
+ searchResetTrigger,
111
132
  selectedFilter,
133
+ showActionsOnPinned,
112
134
  theme,
113
135
  tooltipsContentMap
114
- }), [categories, categoriesConfig, classes, disableCollapsibleCategories, filteredCategories, filteredValues, hideAddFilterButton, iconProps, noFiltersText, noFiltersTitle, onDeleteFilterGrouping, onEditFilterGrouping, open, popperState, position, scrollProps, selectedFilter, theme, tooltipsContentMap]);
136
+ }), [categories, categoriesConfig, classes, disableCollapsibleCategories, filteredCategories, filteredValues, hideAddFilterButton, iconProps, invalidParamsConfig, noFiltersText, noFiltersTitle, onDeleteFilterGrouping, onEditFilterGrouping, showActionsOnPinned, open, popperState, position, scrollProps, searchResetTrigger, selectedFilter, theme, tooltipsContentMap]);
115
137
  return /*#__PURE__*/_react.default.createElement(_context.default.Provider, {
116
138
  value: contextValue
117
139
  }, /*#__PURE__*/_react.default.createElement("section", {
@@ -161,14 +183,21 @@ UTShortcutPanelContainer.propTypes = {
161
183
  handleSelectFilter: _propTypes.func,
162
184
  hideAddFilterButton: _propTypes.bool,
163
185
  iconProps: _iconTypes.iconPropTypes,
186
+ invalidParamsConfig: (0, _propTypes.shape)({
187
+ iconName: _propTypes.string,
188
+ size: _propTypes.string,
189
+ tooltipText: _propTypes.string
190
+ }),
164
191
  noFiltersText: _propTypes.string,
165
192
  noFiltersTitle: _propTypes.string,
166
193
  onDeleteFilterGrouping: _propTypes.func,
167
194
  onEditFilterGrouping: _propTypes.func,
168
195
  onTogglePanel: _propTypes.func,
196
+ showActionsOnPinned: _propTypes.bool,
169
197
  panelTitle: _propTypes.string,
170
198
  position: _propTypes.string,
171
199
  scrollProps: _propTypes.object,
200
+ searchResetKey: _propTypes.string,
172
201
  selectedFilter: (0, _propTypes.shape)({
173
202
  id: _propTypes.number,
174
203
  name: _propTypes.string,
@@ -32,6 +32,7 @@ var _default = exports.default = {
32
32
  handleSelectFilter: (0, _test.fn)(),
33
33
  hideAddFilterButton: false,
34
34
  iconProps: undefined,
35
+ invalidParamsConfig: undefined,
35
36
  noFiltersTitle: _constants2.default.NO_FILTERS_TITLE,
36
37
  noFiltersText: _constants2.default.NO_FILTERS_TEXT,
37
38
  onDeleteFilterGrouping: (0, _test.fn)(),
@@ -39,8 +40,10 @@ var _default = exports.default = {
39
40
  onTogglePanel: (0, _test.fn)(),
40
41
  panelTitle: _constants2.default.PANEL_TITLE,
41
42
  position: _constants2.default.POSITION,
43
+ searchResetKey: undefined,
42
44
  selectedFilter: undefined,
43
45
  scrollProps: undefined,
46
+ showActionsOnPinned: false,
44
47
  startOpen: true,
45
48
  tooltipsContentMap: _constants2.default.TOOLTIPS_CONTENT_MAP
46
49
  },
@@ -182,6 +185,18 @@ var _default = exports.default = {
182
185
  }
183
186
  }
184
187
  },
188
+ invalidParamsConfig: {
189
+ control: 'object',
190
+ description: 'Configuración del ícono de advertencia que se muestra en ítems con `hasInvalidParams: true`. Si se pasa `tooltipText`, el ícono muestra un tooltip al hacer hover. `iconName` e `size` son opcionales (defaults: `IconAlertTriangle`, `16`).',
191
+ table: {
192
+ defaultValue: {
193
+ summary: 'undefined'
194
+ },
195
+ type: {
196
+ summary: '{ iconName?: string; size?: string; tooltipText?: string }'
197
+ }
198
+ }
199
+ },
185
200
  noFiltersTitle: {
186
201
  control: 'text',
187
202
  description: 'Título para el componente de filtros vacíos.',
@@ -279,6 +294,18 @@ var _default = exports.default = {
279
294
  }
280
295
  }
281
296
  },
297
+ searchResetKey: {
298
+ control: 'text',
299
+ description: 'Cuando cambia de valor, resetea el estado de búsqueda interna del panel. Útil para limpiar el input al cambiar de tab o categoría.',
300
+ table: {
301
+ defaultValue: {
302
+ summary: 'undefined'
303
+ },
304
+ type: {
305
+ summary: 'string | number'
306
+ }
307
+ }
308
+ },
282
309
  selectedFilter: {
283
310
  control: 'none',
284
311
  description: 'Filtro seleccionado.',
@@ -291,6 +318,18 @@ var _default = exports.default = {
291
318
  }
292
319
  }
293
320
  },
321
+ showActionsOnPinned: {
322
+ control: 'boolean',
323
+ description: 'Si es `true`, los botones de editar y eliminar se muestran también en ítems con `pinned: true`. Por defecto son ocultados en filtros pinned.',
324
+ table: {
325
+ defaultValue: {
326
+ summary: 'false'
327
+ },
328
+ type: {
329
+ summary: 'boolean'
330
+ }
331
+ }
332
+ },
294
333
  startOpen: {
295
334
  control: 'boolean',
296
335
  description: 'Indica si el panel se renderiza abierto.',
@@ -107,6 +107,8 @@
107
107
  "name": "Filtro Custom 3",
108
108
  "order": 4,
109
109
  "pinned": false,
110
+ "filter_type": "private",
111
+ "hasInvalidParams": true,
110
112
  "visible": true
111
113
  }
112
114
  ],
@@ -65,7 +65,16 @@
65
65
  },
66
66
  "backoffice_user_id": {
67
67
  "type": ["string", "null"],
68
- "description": "ID of the backoffice user who created this filter, or null for system filters"
68
+ "description": "ID del agente propietario del filtro."
69
+ },
70
+ "filter_type": {
71
+ "type": "string",
72
+ "enum": ["private", "supervisor"],
73
+ "description": "Tipo de filtro: 'private' (solo visible para el creador) o 'supervisor' (visible para todos, implica pinned: true)."
74
+ },
75
+ "hasInvalidParams": {
76
+ "type": "boolean",
77
+ "description": "Cuando es true, el ítem muestra el ícono de advertencia. El ícono, su tamaño y el tooltip se configuran desde la prop invalidParamsConfig del panel (defaults: IconAlertTriangle, size 16, sin tooltip). Se computa en el selector makeSelectFilterCategoriesWithValidation."
69
78
  },
70
79
  "filter_params": {
71
80
  "type": "array",
@@ -11,7 +11,6 @@
11
11
  }
12
12
 
13
13
  %actionsContainer {
14
- animation-fill-mode: forwards;
15
14
  display: none;
16
15
  }
17
16
 
@@ -190,8 +189,12 @@
190
189
  overflow: hidden;
191
190
 
192
191
  .hoverableContainer {
193
- flex-grow: 1;
194
- overflow: hidden;
192
+ flex-grow: 1;
193
+ overflow: hidden;
194
+
195
+ &:first-child {
196
+ padding-left: var(--UT-shortcutPanel-item-no-icon-padding-left, 4px);
197
+ }
195
198
  }
196
199
  }
197
200
 
@@ -203,6 +206,11 @@
203
206
  @extend %actionsContainer;
204
207
  }
205
208
 
209
+ .hasInvalidParamsTooltipContainer {
210
+ align-items: center;
211
+ display: flex;
212
+ }
213
+
206
214
  .expandedPanelContentCategoryItemTitleContainerSelected {
207
215
  cursor: default;
208
216
  }
@@ -40,6 +40,7 @@ const ID_CONSTANTS = exports.ID_CONSTANTS = {
40
40
  HEADER: 'header',
41
41
  HELP_TEXT: 'helpText',
42
42
  ICON: 'icon',
43
+ INVALID_PARAMS: 'invalidParams',
43
44
  LABEL: 'label',
44
45
  MAIN_BUTTON: 'mainButton',
45
46
  NAME: 'name',
@@ -52,6 +53,7 @@ const ID_CONSTANTS = exports.ID_CONSTANTS = {
52
53
  PINNED: 'pinned',
53
54
  POPPER: 'popper',
54
55
  SEARCH_BUTTON: 'searchButton',
56
+ SECONDARY_ACTION: 'secondaryAction',
55
57
  SEARCH_BUTTON_TOOLTIP: 'searchButtonTooltip',
56
58
  SEARCH_FIELD: 'searchField',
57
59
  SELECTION_COMPONENT: 'selectionComponent',
@@ -59,6 +61,7 @@ const ID_CONSTANTS = exports.ID_CONSTANTS = {
59
61
  SIDEBAR_BUTTON: 'sidebarButton',
60
62
  STATUS_MESSAGE: 'statusMessage',
61
63
  TABLE: 'table',
64
+ TERTIARY_ACTION: 'tertiaryAction',
62
65
  TABLE_ROW: 'tableRow',
63
66
  TITLE: 'title',
64
67
  USER_FILTER: 'userFilter',
@@ -2,14 +2,47 @@
2
2
 
3
3
  ### Description
4
4
 
5
- This component displays a banner with information
5
+ Displays a banner with contextual information. Supports multiple color themes, sizes, icon/button placement, and optional close action.
6
6
 
7
7
  ## Props
8
8
 
9
- | Name | Type | Default | Description |
10
- | ---------- | ---------------- | ------- | --------------------------------------------------------------------------- |
11
- | children | element | | The contents that will be rendered inside the component. |
12
- | classes | object of string | | Classes returned by UTBanner's own [theme](./theme.js#L40) `retrieveStyle`. |
13
- | classNames | object of string | | Additional classes. |
14
- | Icon | element | | Icon to be displayed at the left side of the banner. |
15
- | iconProps | object | | Props to be passed onto the rendered icon. |
9
+ | Name | Type | Default | Description |
10
+ | ----------------- | --------------------------------------------------------------------------------- | -------------- | --------------------------------------------------------------------------- |
11
+ | button | object (UTButton props) | | Primary action button. All UTButton props are accepted. |
12
+ | buttonPlacement | `'horizontal'` \| `'vertical'` | `'horizontal'` | Alignment between the text group and the buttons group. |
13
+ | category | string | | Optional category label shown above the main text (xsmall, uppercase, gray). |
14
+ | children | node | | Main text content rendered inside the banner. |
15
+ | classes | object of string | | Classes returned by UTBanner's own [theme](./theme.js) `retrieveStyle`. |
16
+ | classNames | object of string | | Additional classes merged with the themed classes. |
17
+ | colorTheme | `'error'` \| `'gray'` \| `'information'` \| `'negative'` \| `'primary'` \| `'success'` \| `'warning'` \| `'white'` | `'gray'` | Color theme that determines the banner background. |
18
+ | helpText | string | | Optional secondary text shown below the main content (small, gray). |
19
+ | Icon | element type | | Icon component rendered at the start of the banner. |
20
+ | iconPlacement | `'horizontal'` \| `'vertical'` | `'horizontal'` | Alignment between the icon and the text group. |
21
+ | iconProps | object | | Props passed to the `Icon` component. |
22
+ | onClose | func | | If provided, renders a close button (gray, small, IconX) at the end. |
23
+ | secondaryButton | object (UTButton props) | | Secondary action button. Renders as `variant="text"` by default. |
24
+ | size | `'small'` \| `'medium'` \| `'large'` | `'medium'` | Controls padding, gap, and icon size. |
25
+ | variant | `'light'` \| `'dark'` | `'light'` | Light or dark tint of the color theme. |
26
+
27
+ ## Usage examples
28
+
29
+ ```jsx
30
+ // Basic
31
+ <UTBanner>Your account has been updated.</UTBanner>
32
+
33
+ // With color theme and close
34
+ <UTBanner colorTheme="success" onClose={() => dismiss()}>
35
+ Your changes were saved successfully.
36
+ </UTBanner>
37
+
38
+ // With category, helpText and actions
39
+ <UTBanner
40
+ category="Alert"
41
+ colorTheme="warning"
42
+ helpText="Contact support if the issue persists."
43
+ button={{ children: 'Retry', onClick: handleRetry }}
44
+ secondaryButton={{ children: 'Dismiss', onClick: handleDismiss }}
45
+ >
46
+ Something went wrong while loading your data.
47
+ </UTBanner>
48
+ ```