@rh-support/manage 2.5.238 → 2.5.240

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.
@@ -1 +1 @@
1
- {"version":3,"file":"GroupSelect.d.ts","sourceRoot":"","sources":["../../../../../src/components/Groups/GroupSelect/GroupSelect.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,+CAA+C,CAAC;AAsC3E,OAAO,KAAmD,MAAM,OAAO,CAAC;AAMxE,UAAU,MAAM;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAKD,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,sBA2lBxC,CAAC"}
1
+ {"version":3,"file":"GroupSelect.d.ts","sourceRoot":"","sources":["../../../../../src/components/Groups/GroupSelect/GroupSelect.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,+CAA+C,CAAC;AAsC3E,OAAO,KAAmD,MAAM,OAAO,CAAC;AAMxE,UAAU,MAAM;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAKD,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,sBAmmBxC,CAAC"}
@@ -45,16 +45,24 @@ export const GroupSelect = (props) => {
45
45
  const { renameGroup: renameGroupMutation, loading: renameLoading } = useRenameCaseGroup();
46
46
  const { deleteGroup: deleteGroupMutation, loading: deleteLoading } = useDeleteCaseGroup();
47
47
  const hasFetchedFromGraphQL = useRef(false);
48
- // Always fetch groups from GraphQL — never rely on potentially stale Hydra data
48
+ const [groupsFetchCompleted, setGroupsFetchCompleted] = useState(false);
49
+ // Always fetch groups from GraphQL — never rely on potentially stale Hydra data.
50
+ // Auto-select only after this settles so members can load against real group data.
49
51
  useEffect(() => {
50
- if (!hasFetchedFromGraphQL.current && apolloClient && accountId) {
51
- hasFetchedFromGraphQL.current = true;
52
- fetchCaseGroupsForSSO(dispatch, loggedInUserJwtToken.preferred_username, apolloClient, accountId);
52
+ if (!apolloClient || !accountId) {
53
+ setGroupsFetchCompleted(true);
54
+ return;
53
55
  }
56
+ if (hasFetchedFromGraphQL.current)
57
+ return;
58
+ hasFetchedFromGraphQL.current = true;
59
+ Promise.resolve(fetchCaseGroupsForSSO(dispatch, loggedInUserJwtToken.preferred_username, apolloClient, accountId)).finally(() => setGroupsFetchCompleted(true));
54
60
  }, [dispatch, loggedInUserJwtToken.preferred_username, apolloClient, accountId]);
55
61
  // Set default group once groups are loaded
56
62
  useEffect(() => {
57
63
  var _a, _b;
64
+ if (!groupsFetchCompleted || caseGroups.isFetching)
65
+ return;
58
66
  if (isEmpty(selectedGroup) && !isEmpty(caseGroups) && ((_a = caseGroups === null || caseGroups === void 0 ? void 0 : caseGroups.data) === null || _a === void 0 ? void 0 : _a.length) > 0) {
59
67
  const defaultCaseGroup = find(caseGroups === null || caseGroups === void 0 ? void 0 : caseGroups.data, (g) => g.isDefault);
60
68
  const newSelectedGroup = (defaultCaseGroup === null || defaultCaseGroup === void 0 ? void 0 : defaultCaseGroup.groupNum) === '-1'
@@ -66,7 +74,7 @@ export const GroupSelect = (props) => {
66
74
  }
67
75
  }
68
76
  // eslint-disable-next-line react-hooks/exhaustive-deps
69
- }, [caseGroups]);
77
+ }, [caseGroups, groupsFetchCompleted]);
70
78
  // handle dropdown open/close toggle
71
79
  const [isOpen, setIsOpen] = useState(false);
72
80
  // handle group selection
@@ -1 +1 @@
1
- {"version":3,"file":"AddEditCaseLabelModal.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageCaseLabels/AddEditCaseLabelModal.tsx"],"names":[],"mappings":"AAeA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,MAAM,MAAM,mBAAmB,GAAG;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,UAAU,MAAM;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;CAClH;AAED,wBAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,qBA4G1G"}
1
+ {"version":3,"file":"AddEditCaseLabelModal.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageCaseLabels/AddEditCaseLabelModal.tsx"],"names":[],"mappings":"AAeA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,MAAM,MAAM,mBAAmB,GAAG;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,UAAU,MAAM;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;CAClH;AAED,wBAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,qBA0H1G"}
@@ -27,18 +27,30 @@ export function AddEditCaseLabelModal({ isOpen, addMode, label, isSaving = false
27
27
  }
28
28
  return '';
29
29
  };
30
- const handleSave = (...args_1) => __awaiter(this, [...args_1], void 0, function* (keepOpen = false) {
30
+ const resetForm = () => {
31
+ setName('');
32
+ setError('');
33
+ };
34
+ const handleSave = () => __awaiter(this, void 0, void 0, function* () {
31
35
  const validationError = validate(name);
32
36
  if (!isEmpty(validationError)) {
33
37
  setError(validationError);
34
38
  return;
35
39
  }
36
- const result = yield onSave(name.trim(), { keepOpen });
40
+ const result = yield onSave(name.trim(), { keepOpen: false });
41
+ if (!result.success && result.fieldError) {
42
+ setError(result.fieldError);
43
+ }
44
+ });
45
+ const handleSaveAndNew = () => __awaiter(this, void 0, void 0, function* () {
46
+ const validationError = validate(name);
47
+ if (!isEmpty(validationError)) {
48
+ setError(validationError);
49
+ return;
50
+ }
51
+ const result = yield onSave(name.trim(), { keepOpen: true });
37
52
  if (result.success) {
38
- if (keepOpen) {
39
- setName('');
40
- setError('');
41
- }
53
+ resetForm();
42
54
  return;
43
55
  }
44
56
  if (result.fieldError) {
@@ -46,8 +58,7 @@ export function AddEditCaseLabelModal({ isOpen, addMode, label, isSaving = false
46
58
  }
47
59
  });
48
60
  const handleClose = () => {
49
- setName('');
50
- setError('');
61
+ resetForm();
51
62
  onClose();
52
63
  };
53
64
  return (React.createElement(Modal, { id: "add-edit-case-label-modal", "aria-describedby": "add-edit-case-label-modal", isOpen: isOpen, onClose: handleClose, variant: ModalVariant.small },
@@ -63,9 +74,9 @@ export function AddEditCaseLabelModal({ isOpen, addMode, label, isSaving = false
63
74
  React.createElement(HelperText, null,
64
75
  React.createElement(HelperTextItem, { variant: "error" }, error)))))),
65
76
  React.createElement(ModalFooter, null,
66
- React.createElement(Button, { key: "save", variant: ButtonVariant.primary, onClick: () => handleSave(false), isDisabled: isEmpty(name.trim()) || !isEmpty(error) || isSaving, isLoading: isSaving },
77
+ React.createElement(Button, { key: "save", variant: ButtonVariant.primary, onClick: handleSave, isDisabled: isEmpty(name.trim()) || !isEmpty(error) || isSaving, isLoading: isSaving },
67
78
  React.createElement(Trans, null, "Save")),
68
- addMode && (React.createElement(Button, { key: "save-and-new", variant: ButtonVariant.secondary, onClick: () => handleSave(true), isDisabled: isEmpty(name.trim()) || !isEmpty(error) || isSaving, isLoading: isSaving },
79
+ addMode && (React.createElement(Button, { key: "save-and-new", variant: ButtonVariant.secondary, onClick: handleSaveAndNew, isDisabled: isEmpty(name.trim()) || !isEmpty(error) || isSaving, isLoading: isSaving },
69
80
  React.createElement(Trans, null, "Save & New"))),
70
81
  React.createElement(Button, { key: "cancel", variant: ButtonVariant.link, onClick: handleClose, isDisabled: isSaving },
71
82
  React.createElement(Trans, null, "Cancel")))));
@@ -1 +1 @@
1
- {"version":3,"file":"ManageCaseLabelsTab.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageCaseLabels/ManageCaseLabelsTab.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAmC5D,wBAAgB,mBAAmB,sBAoQlC"}
1
+ {"version":3,"file":"ManageCaseLabelsTab.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageCaseLabels/ManageCaseLabelsTab.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAmC5D,wBAAgB,mBAAmB,sBA+SlC"}
@@ -7,7 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { ActionList, ActionListItem, AlertVariant, Button, ButtonVariant, ModalVariant, SearchInput, } from '@patternfly/react-core';
10
+ import { ActionList, ActionListItem, AlertVariant, Button, ButtonVariant, EmptyState, EmptyStateBody, EmptyStateFooter, EmptyStateVariant, ModalVariant, SearchInput, } from '@patternfly/react-core';
11
+ import CubesIcon from '@patternfly/react-icons/dist/js/icons/cubes-icon';
11
12
  import PencilAltIcon from '@patternfly/react-icons/dist/js/icons/pencil-alt-icon';
12
13
  import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon';
13
14
  import { ErrorBoundary, ToastNotification, useConfirmation } from '@rh-support/components';
@@ -57,6 +58,7 @@ export function ManageCaseLabelsTab() {
57
58
  }
58
59
  return labels.filter((label) => label.name.toLowerCase().includes(searchString.toLowerCase()));
59
60
  }, [labels, searchString]);
61
+ const hasNoLabels = !isFetchingLabels && !labelsError && labels.length === 0;
60
62
  const onOpenAddModal = () => {
61
63
  setIsInAddMode(true);
62
64
  setSelectedLabel(null);
@@ -183,17 +185,24 @@ export function ManageCaseLabelsTab() {
183
185
  React.createElement(Trans, null, "Case labels help you organize and categorize cases with custom tags, making them easier to find, filter, and manage."))),
184
186
  React.createElement("div", { className: "toolbar case-labels-toolbar" },
185
187
  React.createElement("div", { className: "toolbar-left" },
186
- React.createElement("label", { htmlFor: "search-case-label-input" },
187
- React.createElement(Trans, null, "Case labels")),
188
- React.createElement(SearchInput, { className: "pf-v6-u-flex-grow-1 pf-v6-c-search-input pf-v6-u-background-color-100", value: searchString, id: "search-case-label-input", placeholder: t('Search case label by name.'), "aria-label": t('Search case label by name'), onChange: (_, val) => setSearchString(val), onClear: () => setSearchString('') }),
189
- React.createElement("span", { className: "pf-v6-u-ml-sm" },
190
- React.createElement(Button, { variant: ButtonVariant.primary, isInline: true, onClick: onOpenAddModal, "data-tracking-id": "case-label-add-button" },
191
- React.createElement(Trans, null, "Add")))),
192
- React.createElement("div", { className: "toolbar-right case-labels-toolbar__loaded pf-v6-u-color-200" }, t('{{loaded}} of {{total}} loaded.', {
188
+ hasNoLabels ? (React.createElement("span", null,
189
+ React.createElement(Trans, null, "Case labels"))) : (React.createElement("label", { htmlFor: "search-case-label-input" },
190
+ React.createElement(Trans, null, "Case labels"))),
191
+ !hasNoLabels && (React.createElement(React.Fragment, null,
192
+ React.createElement(SearchInput, { className: "pf-v6-u-flex-grow-1 pf-v6-c-search-input pf-v6-u-background-color-100", value: searchString, id: "search-case-label-input", placeholder: t('Search case label by name.'), "aria-label": t('Search case label by name'), onChange: (_, val) => setSearchString(val), onClear: () => setSearchString('') }),
193
+ React.createElement("span", { className: "pf-v6-u-ml-sm" },
194
+ React.createElement(Button, { variant: ButtonVariant.primary, isInline: true, onClick: onOpenAddModal, "data-tracking-id": "case-label-add-button" },
195
+ React.createElement(Trans, null, "Add")))))),
196
+ !hasNoLabels && (React.createElement("div", { className: "toolbar-right case-labels-toolbar__loaded pf-v6-u-color-200" }, t('{{loaded}} of {{total}} loaded.', {
193
197
  loaded: filteredLabels.length,
194
198
  total: filteredLabels.length,
195
- }))),
199
+ })))),
196
200
  React.createElement(AddEditCaseLabelModal, { isOpen: isModalOpen, addMode: isInAddMode, label: selectedLabel, isSaving: isCreatingLabel || isUpdatingLabel, onClose: closeModal, onSave: onSaveLabel }),
197
- React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading case labels list') } },
198
- React.createElement(ManageTable, { ariaLabel: t('Table to manage case labels'), columns: columns, data: filteredLabels, errorVariant: AlertVariant.warning, isFetching: isFetchingLabels, isError: !!labelsError, errorTitle: t('Case labels error'), errorComponent: React.createElement(Trans, null, "Could not get case labels"), pagination: false, noResultText: t('There are no results to display. Try adding a case label or refining your search') }))));
201
+ React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading case labels list') } }, hasNoLabels ? (React.createElement("div", { className: "table-wrapper case-labels-empty-state" },
202
+ React.createElement(EmptyState, { headingLevel: "h2", icon: CubesIcon, titleText: t('Create your first case label'), variant: EmptyStateVariant.lg },
203
+ React.createElement(EmptyStateBody, null,
204
+ React.createElement(Trans, null, "Case labels help you organize and categorize cases with custom tags, making them easier to find, filter, and manage.")),
205
+ React.createElement(EmptyStateFooter, null,
206
+ React.createElement(Button, { variant: ButtonVariant.link, onClick: onOpenAddModal, "data-tracking-id": "case-label-empty-create-button" },
207
+ React.createElement(Trans, null, "Create label")))))) : (React.createElement(ManageTable, { ariaLabel: t('Table to manage case labels'), columns: columns, data: filteredLabels, errorVariant: AlertVariant.warning, isFetching: isFetchingLabels, isError: !!labelsError, errorTitle: t('Case labels error'), errorComponent: React.createElement(Trans, null, "Could not get case labels"), pagination: false, noResultText: t('There are no results to display. Try adding a case label or refining your search') })))));
199
208
  }
@@ -480,6 +480,15 @@ svg.hostnameSpinner {
480
480
  gap: var(--pf-t--global--spacer--sm);
481
481
  margin-left: auto;
482
482
  }
483
+
484
+ .case-labels-empty-state {
485
+ display: flex;
486
+ align-items: center;
487
+ justify-content: center;
488
+ min-height: 20rem;
489
+ padding: var(--pf-t--global--spacer--2xl) var(--pf-t--global--spacer--lg);
490
+ background-color: var(--pf-t--global--background--color--primary--default);
491
+ }
483
492
  }
484
493
 
485
494
  .case-label-delete-description {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rh-support/manage",
3
- "version": "2.5.238",
3
+ "version": "2.5.240",
4
4
  "description": "Customer Support Manage App",
5
5
  "author": "Jordan Eudy <jeudy100@gmail.com>",
6
6
  "license": "ISC",
@@ -76,12 +76,12 @@
76
76
  "@patternfly/patternfly": "6.2.1",
77
77
  "@patternfly/react-core": "6.2.1",
78
78
  "@patternfly/react-table": "6.2.1",
79
- "@rh-support/components": "2.5.190",
79
+ "@rh-support/components": "2.5.192",
80
80
  "@rh-support/configs": "2.0.75",
81
- "@rh-support/react-context": "2.5.284",
81
+ "@rh-support/react-context": "2.5.286",
82
82
  "@rh-support/types": "2.0.26",
83
- "@rh-support/user-permissions": "2.5.136",
84
- "@rh-support/utils": "2.5.118",
83
+ "@rh-support/user-permissions": "2.5.138",
84
+ "@rh-support/utils": "2.5.120",
85
85
  "@types/react-beautiful-dnd": "^13.0.0",
86
86
  "i18next": "^23.15.0",
87
87
  "lodash": ">=4.17.15",
@@ -100,5 +100,5 @@
100
100
  "defaults and supports es6-module",
101
101
  "maintained node versions"
102
102
  ],
103
- "gitHead": "9017d17207b6357a27edbab889de8f10696e745b"
103
+ "gitHead": "84a00c5092469be74f67cb35e582d3120d0949b6"
104
104
  }