@rh-support/manage 2.5.279 → 2.5.281

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 (58) hide show
  1. package/lib/esm/ManageTabs.d.ts.map +1 -1
  2. package/lib/esm/ManageTabs.js +18 -46
  3. package/lib/esm/Routes.d.ts +0 -1
  4. package/lib/esm/Routes.d.ts.map +1 -1
  5. package/lib/esm/Routes.js +0 -6
  6. package/lib/esm/components/Groups/DefualtGroupSwitch/DefaultGroupSwitch.d.ts +3 -5
  7. package/lib/esm/components/Groups/DefualtGroupSwitch/DefaultGroupSwitch.d.ts.map +1 -1
  8. package/lib/esm/components/Groups/DefualtGroupSwitch/DefaultGroupSwitch.js +14 -21
  9. package/lib/esm/components/Groups/GroupSelect/GroupSelect.d.ts +0 -1
  10. package/lib/esm/components/Groups/GroupSelect/GroupSelect.d.ts.map +1 -1
  11. package/lib/esm/components/Groups/GroupSelect/GroupSelect.js +85 -169
  12. package/lib/esm/components/Groups/ManageGroupUsers/ManageGroupUsers.d.ts.map +1 -1
  13. package/lib/esm/components/Groups/ManageGroupUsers/ManageGroupUsers.js +42 -169
  14. package/lib/esm/components/ManagePreferences/PreferencesBody.d.ts.map +1 -1
  15. package/lib/esm/components/ManagePreferences/PreferencesBody.js +5 -1
  16. package/lib/esm/components/ManagePreferences/sections/PreferencesACL.d.ts.map +1 -1
  17. package/lib/esm/components/ManagePreferences/sections/PreferencesACL.js +4 -3
  18. package/lib/esm/components/ManagePreferences/sections/PreferencesCaseCreate.d.ts.map +1 -1
  19. package/lib/esm/components/ManagePreferences/sections/PreferencesCaseCreate.js +58 -73
  20. package/lib/esm/components/ManagePreferences/sections/PreferencesCaseView.d.ts.map +1 -1
  21. package/lib/esm/components/ManagePreferences/sections/PreferencesCaseView.js +98 -43
  22. package/lib/esm/constants/GroupSelectActions.d.ts +1 -2
  23. package/lib/esm/constants/GroupSelectActions.d.ts.map +1 -1
  24. package/lib/esm/constants/GroupSelectActions.js +0 -1
  25. package/lib/esm/hooks/useVersionsDiffer.d.ts.map +1 -1
  26. package/lib/esm/index.js +0 -1
  27. package/lib/esm/scss/_main.scss +0 -77
  28. package/package.json +8 -11
  29. package/lib/esm/components/Groups/AddMembersModal/AddMembersModal.d.ts +0 -12
  30. package/lib/esm/components/Groups/AddMembersModal/AddMembersModal.d.ts.map +0 -1
  31. package/lib/esm/components/Groups/AddMembersModal/AddMembersModal.js +0 -80
  32. package/lib/esm/components/Groups/AddMembersModal/index.d.ts +0 -2
  33. package/lib/esm/components/Groups/AddMembersModal/index.d.ts.map +0 -1
  34. package/lib/esm/components/Groups/AddMembersModal/index.js +0 -1
  35. package/lib/esm/components/ManageCaseLabels/AddEditCaseLabelModal.d.ts +0 -19
  36. package/lib/esm/components/ManageCaseLabels/AddEditCaseLabelModal.d.ts.map +0 -1
  37. package/lib/esm/components/ManageCaseLabels/AddEditCaseLabelModal.js +0 -97
  38. package/lib/esm/components/ManageCaseLabels/ManageCaseLabelsTab.d.ts +0 -3
  39. package/lib/esm/components/ManageCaseLabels/ManageCaseLabelsTab.d.ts.map +0 -1
  40. package/lib/esm/components/ManageCaseLabels/ManageCaseLabelsTab.js +0 -220
  41. package/lib/esm/components/ManageCaseLabels/index.d.ts +0 -2
  42. package/lib/esm/components/ManageCaseLabels/index.d.ts.map +0 -1
  43. package/lib/esm/components/ManageCaseLabels/index.js +0 -1
  44. package/lib/esm/components/ManageCaseLabels/types.d.ts +0 -6
  45. package/lib/esm/components/ManageCaseLabels/types.d.ts.map +0 -1
  46. package/lib/esm/components/ManageCaseLabels/types.js +0 -1
  47. package/lib/esm/hooks/useCaseGroupGraphQL.d.ts +0 -42
  48. package/lib/esm/hooks/useCaseGroupGraphQL.d.ts.map +0 -1
  49. package/lib/esm/hooks/useCaseGroupGraphQL.js +0 -117
  50. package/lib/esm/hooks/useCaseLabelGraphQL.d.ts +0 -26
  51. package/lib/esm/hooks/useCaseLabelGraphQL.d.ts.map +0 -1
  52. package/lib/esm/hooks/useCaseLabelGraphQL.js +0 -104
  53. package/lib/esm/hooks/useCurrentUserContact.d.ts +0 -8
  54. package/lib/esm/hooks/useCurrentUserContact.d.ts.map +0 -1
  55. package/lib/esm/hooks/useCurrentUserContact.js +0 -74
  56. package/lib/esm/utils/caseGroupMapper.d.ts +0 -18
  57. package/lib/esm/utils/caseGroupMapper.d.ts.map +0 -1
  58. package/lib/esm/utils/caseGroupMapper.js +0 -50
@@ -1 +1 @@
1
- {"version":3,"file":"ManageTabs.d.ts","sourceRoot":"","sources":["../../src/ManageTabs.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,mBAAmB,EAAa,MAAM,kBAAkB,CAAC;AAiBlE,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,qBAgOvC"}
1
+ {"version":3,"file":"ManageTabs.d.ts","sourceRoot":"","sources":["../../src/ManageTabs.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,EAAE,mBAAmB,EAAa,MAAM,kBAAkB,CAAC;AAclE,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,qBAyMvC"}
@@ -1,6 +1,6 @@
1
1
  import { Tab, TabContent, Tabs, TabsComponent, TabTitleText } from '@patternfly/react-core';
2
- import { ErrorBoundary, LoadingIndicator, useDocumentTitle } from '@rh-support/components';
3
- import { ability, resourceActions, resources } from '@rh-support/user-permissions';
2
+ import { ErrorBoundary, useDocumentTitle } from '@rh-support/components';
3
+ import { ability, CaseDetailsFields, resourceActions, resources } from '@rh-support/user-permissions';
4
4
  import map from 'lodash/map';
5
5
  import React, { useState } from 'react';
6
6
  import { Trans, useTranslation } from 'react-i18next';
@@ -8,46 +8,29 @@ import { useParams } from 'react-router-dom';
8
8
  import { ConfigsTable } from './components/Configs/ConfigsTable';
9
9
  import { ManageGroupUsers } from './components/Groups/ManageGroupUsers';
10
10
  import { ManageGroupedBookmarkedAccountsTab } from './components/ManageBookmarkedAccountsTab';
11
- import { ManageCaseLabelsTab } from './components/ManageCaseLabels';
12
11
  import { ExpiredContentManagement } from './components/ManageExpiredContents/ExpiredContentManagement';
13
- // TODO: Uncomment when partnerships tab is re-implemented
14
- // import { ManagePartnerships } from './components/ManagePartnerships/index';
12
+ import { ManagePartnerships } from './components/ManagePartnerships/index';
15
13
  import { ManagePreferences } from './components/ManagePreferences';
16
14
  import { TagsManagement } from './components/ManageTags';
17
- // import { NotificationEmails } from './components/NotificationEmails/index';
15
+ import { NotificationEmails } from './components/NotificationEmails/index';
18
16
  import { TopContentManagement } from './components/TopContentManagement';
19
17
  import { PageTitle } from './constants/pageTitle';
20
- import { useCurrentUserContact } from './hooks/useCurrentUserContact';
21
18
  import { Routes } from './Routes';
22
19
  export function ManageTabs(props) {
23
20
  var _a, _b;
24
21
  const [activeTabKey, setActiveTabKey] = useState(0);
25
22
  const { activeTab } = useParams();
26
23
  const { t } = useTranslation();
27
- const { loading: contactLoading } = useCurrentUserContact();
28
- const { groupsRoute, bookmarkedAccountsRoute, caseLabelsRoute, topContentRoute,
29
- // notificationEmailsRoute,
30
- preferencesRoute, configsRoute,
31
- // partnershipsRoute, // TODO: Uncomment when partnerships tab is re-implemented
32
- tagsManagerRoute, expiredContentRoute, } = Routes.getPaths();
24
+ const { groupsRoute, bookmarkedAccountsRoute, topContentRoute, notificationEmailsRoute, preferencesRoute, configsRoute, partnershipsRoute, tagsManagerRoute, expiredContentRoute, } = Routes.getPaths();
33
25
  useDocumentTitle(PageTitle.MANAGE);
34
26
  const canViewManageTab = ability.can(resourceActions.READ, resources.MANAGE);
35
27
  const canViewManageTopContent = ability.can(resourceActions.READ, resources.TOP_CONTENT) && canViewManageTab;
36
28
  const canViewCaseGroups = ability.can(resourceActions.READ, resources.CASE_GROUPS) && canViewManageTab;
37
29
  const canManageBookmarkAccounts = ability.can(resourceActions.CREATE, resources.BOOKMARK_ACCOUNTS) && canViewManageTab;
38
- // const canViewEmailNotificationTab = ability.can(resourceActions.READ, resources.NOTIFICATION_EMAIL);
39
- // TODO: Uncomment when partnerships tab is re-implemented
40
- // const canViewPartnershipsTab = ability.can(resourceActions.READ, resources.PARTNERSHIPS);
41
- // const canAddCustomNotification = ability.can(
42
- // resourceActions.PATCH,
43
- // resources.CASE_DETAILS,
44
- // CaseDetailsFields.CASE_DETAILS_SEND_NOTIFICATIONS
45
- // );
30
+ const canViewEmailNotificationTab = ability.can(resourceActions.READ, resources.NOTIFICATION_EMAIL);
31
+ const canViewPartnershipsTab = ability.can(resourceActions.READ, resources.PARTNERSHIPS);
32
+ const canAddCustomNotification = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SEND_NOTIFICATIONS);
46
33
  const canViewConfigsTab = ability.can(resourceActions.READ, resources.APP_INTERNAL_CONFIGS);
47
- if (contactLoading) {
48
- return (React.createElement("div", { className: "grid-main manage" },
49
- React.createElement(LoadingIndicator, { show: true, size: "sm" })));
50
- }
51
34
  const tabsToRender = [];
52
35
  canManageBookmarkAccounts &&
53
36
  tabsToRender.push({
@@ -67,15 +50,6 @@ export function ManageTabs(props) {
67
50
  component: React.createElement(ManageGroupUsers, null),
68
51
  id: 'manage-groups',
69
52
  });
70
- tabsToRender.push({
71
- title: 'Case labels',
72
- key: 'case-labels-tab',
73
- 'data-tracking-id': 'manage-case-labels-tab',
74
- routePath: caseLabelsRoute,
75
- component: React.createElement(ManageCaseLabelsTab, null),
76
- id: 'manage-case-labels',
77
- });
78
- /* TODO: Re-enable notification emails tab when ready
79
53
  canViewEmailNotificationTab &&
80
54
  canAddCustomNotification &&
81
55
  tabsToRender.push({
@@ -83,20 +57,18 @@ export function ManageTabs(props) {
83
57
  key: 'notification-emails-tab',
84
58
  'data-tracking-id': 'notification-emails-tab',
85
59
  routePath: notificationEmailsRoute,
86
- component: <NotificationEmails />,
60
+ component: React.createElement(NotificationEmails, null),
87
61
  id: 'notification-emails',
88
62
  });
89
- */
90
- // TODO: Uncomment when partnerships tab is re-implemented
91
- // canViewPartnershipsTab &&
92
- // tabsToRender.push({
93
- // title: 'Partnerships',
94
- // key: 'partnerships-tab',
95
- // 'data-tracking-id': 'partnerships-tab',
96
- // routePath: partnershipsRoute,
97
- // component: <ManagePartnerships />,
98
- // id: 'partnerships',
99
- // });
63
+ canViewPartnershipsTab &&
64
+ tabsToRender.push({
65
+ title: 'Partnerships',
66
+ key: 'partnerships-tab',
67
+ 'data-tracking-id': 'partnerships-tab',
68
+ routePath: partnershipsRoute,
69
+ component: React.createElement(ManagePartnerships, null),
70
+ id: 'partnerships',
71
+ });
100
72
  tabsToRender.push({
101
73
  title: 'Preferences',
102
74
  key: 'preferences-tab',
@@ -11,7 +11,6 @@ interface ManageRoutes {
11
11
  };
12
12
  getPathsArray: () => string[];
13
13
  groups: Route;
14
- caseLabels: Route;
15
14
  savedSearches: Route;
16
15
  topContent: Route;
17
16
  expiredContent: Route;
@@ -1 +1 @@
1
- {"version":3,"file":"Routes.d.ts","sourceRoot":"","sources":["../../src/Routes.ts"],"names":[],"mappings":"AAAA,UAAU,KAAK;IACX,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,YAAY;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,KAAK,CAAC;IAC1B,eAAe,EAAE,KAAK,CAAC;IACvB,QAAQ,EAAE,MAAM;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC1C,aAAa,EAAE,MAAM,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,KAAK,CAAC;IACd,UAAU,EAAE,KAAK,CAAC;IAClB,aAAa,EAAE,KAAK,CAAC;IACrB,UAAU,EAAE,KAAK,CAAC;IAClB,cAAc,EAAE,KAAK,CAAC;IACtB,WAAW,EAAE,KAAK,CAAC;IACnB,WAAW,EAAE,KAAK,CAAC;IACnB,kBAAkB,EAAE,KAAK,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC;IACf,YAAY,EAAE,KAAK,CAAC;CACvB;AAED,eAAO,MAAM,MAAM,EAAE,YA2FpB,CAAC"}
1
+ {"version":3,"file":"Routes.d.ts","sourceRoot":"","sources":["../../src/Routes.ts"],"names":[],"mappings":"AAAA,UAAU,KAAK;IACX,QAAQ,CAAC,OAAO,EAAE,MAAM,MAAM,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,YAAY;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,KAAK,CAAC;IAC1B,eAAe,EAAE,KAAK,CAAC;IACvB,QAAQ,EAAE,MAAM;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC1C,aAAa,EAAE,MAAM,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,KAAK,CAAC;IACd,aAAa,EAAE,KAAK,CAAC;IACrB,UAAU,EAAE,KAAK,CAAC;IAClB,cAAc,EAAE,KAAK,CAAC;IACtB,WAAW,EAAE,KAAK,CAAC;IACnB,WAAW,EAAE,KAAK,CAAC;IACnB,kBAAkB,EAAE,KAAK,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC;IACf,YAAY,EAAE,KAAK,CAAC;CACvB;AAED,eAAO,MAAM,MAAM,EAAE,YAqFpB,CAAC"}
package/lib/esm/Routes.js CHANGED
@@ -12,12 +12,6 @@ export const Routes = {
12
12
  return getPath(this);
13
13
  },
14
14
  },
15
- caseLabels: {
16
- path: 'case-labels',
17
- getPath() {
18
- return getPath(this);
19
- },
20
- },
21
15
  fileDiagnostics: {
22
16
  path: 'file-diagnostics',
23
17
  getPath() {
@@ -1,12 +1,10 @@
1
- import { ICaseGroup } from '@cee-eng/hydrajs/@types/api/public/caseGroups';
1
+ import { ICaseGroup, IGroupUser } from '@cee-eng/hydrajs/@types/api/public/caseGroups';
2
2
  import React from 'react';
3
- import type { IGroupUserWithContactId } from '../../../utils/caseGroupMapper';
4
3
  interface IProps {
5
4
  group: ICaseGroup;
6
- user: IGroupUserWithContactId;
5
+ user: IGroupUser;
7
6
  id: string;
8
- onToggle: (user: IGroupUserWithContactId, isChecked: boolean) => void;
9
- onToggleSuccess?: (user: IGroupUserWithContactId, isChecked: boolean) => void;
7
+ onToggle: (user: IGroupUser, isChecked: boolean) => void;
10
8
  }
11
9
  export declare const DefaultGroupSwitch: (props: IProps) => React.JSX.Element;
12
10
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultGroupSwitch.d.ts","sourceRoot":"","sources":["../../../../../src/components/Groups/DefualtGroupSwitch/DefaultGroupSwitch.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+CAA+C,CAAC;AAG3E,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAE9E,UAAU,MAAM;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,uBAAuB,CAAC;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,CAAC,IAAI,EAAE,uBAAuB,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACtE,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,uBAAuB,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CACjF;AAED,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,sBAgD/C,CAAC"}
1
+ {"version":3,"file":"DefaultGroupSwitch.d.ts","sourceRoot":"","sources":["../../../../../src/components/Groups/DefualtGroupSwitch/DefaultGroupSwitch.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,+CAA+C,CAAC;AAIvF,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,UAAU,MAAM;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5D;AAED,eAAO,MAAM,kBAAkB,GAAI,OAAO,MAAM,sBA+C/C,CAAC"}
@@ -7,40 +7,33 @@ 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 { publicApi } from '@cee-eng/hydrajs';
10
11
  import { Switch } from '@patternfly/react-core';
11
- import { LoadingIndicator, ToastNotification } from '@rh-support/components';
12
+ import { LoadingIndicator, ToastNotification, useFetch } from '@rh-support/components';
13
+ import { useGlobalStateContext } from '@rh-support/react-context';
12
14
  import React from 'react';
13
15
  import { useTranslation } from 'react-i18next';
14
- import { useToggleDefaultGroup } from '../../../hooks/useCaseGroupGraphQL';
15
16
  export const DefaultGroupSwitch = (props) => {
16
- const { group, id, user, onToggle, onToggleSuccess } = props;
17
+ const { globalMetadataState: { loggedInUsersAccount }, } = useGlobalStateContext();
18
+ const { group, id, user, onToggle } = props;
17
19
  // @ts-ignore
18
20
  const { t } = useTranslation();
19
- const { toggleDefault, loading: isFetching } = useToggleDefaultGroup();
20
- const handleToggle = (isChecked) => __awaiter(void 0, void 0, void 0, function* () {
21
- if (!user.contactSfId) {
22
- ToastNotification.addDangerMessage(t('Cannot update default group: contact information is missing'));
23
- return;
24
- }
21
+ const toggleDefaultGroupFetch = useFetch(publicApi.caseGroups.toggleDefaultGroup, {
22
+ propgateErrors: true,
23
+ });
24
+ // Handle Toggle
25
+ const toggleDefault = (isChecked) => __awaiter(void 0, void 0, void 0, function* () {
25
26
  try {
26
27
  onToggle(user, isChecked);
27
- const groupId = isChecked ? group.groupNum : null;
28
- yield toggleDefault(user.contactSfId, groupId);
29
- onToggleSuccess === null || onToggleSuccess === void 0 ? void 0 : onToggleSuccess(user, isChecked);
28
+ yield toggleDefaultGroupFetch.request(group.groupNum, user.ssoUsername, isChecked, loggedInUsersAccount.data.secureSupport);
30
29
  ToastNotification.addSuccessMessage(t(`Default group updated successfully`));
31
30
  }
32
31
  catch (e) {
33
32
  onToggle(user, user.isDefault);
34
- const message = String((e === null || e === void 0 ? void 0 : e.message) || '');
35
- if (message.includes('insufficient access rights')) {
36
- ToastNotification.addDangerMessage(t('You do not have permission to change the default group for this user'));
37
- }
38
- else {
39
- ToastNotification.addDangerMessage(t('Could not toggle default status'));
40
- }
33
+ ToastNotification.addDangerMessage(t('Could not toggle default status'));
41
34
  }
42
35
  });
43
36
  return (React.createElement(React.Fragment, null,
44
- React.createElement(Switch, { "aria-label": "Toggle default group", "data-tracking-id": `group-user-toggle-default-${user.isDefault ? 'off' : 'on'}`, label: user.isDefault ? t('On') : t('Off'), id: id, isDisabled: isFetching || !user.contactSfId, isChecked: user.isDefault, onChange: (_event, isChecked) => handleToggle(isChecked) }),
45
- React.createElement(LoadingIndicator, { show: isFetching, size: "xs" })));
37
+ React.createElement(Switch, { "aria-label": "Toggle default group", "data-tracking-id": `group-user-toggle-default-${user.isDefault ? 'off' : 'on'}`, label: t('On'), id: id, isDisabled: user.access === false || user.write === false || toggleDefaultGroupFetch.isFetching, isChecked: user.isDefault, onChange: (_event, isChecked) => toggleDefault(isChecked) }),
38
+ React.createElement(LoadingIndicator, { show: toggleDefaultGroupFetch.isFetching, size: "xs" })));
46
39
  };
@@ -3,7 +3,6 @@ import React from 'react';
3
3
  interface IProps {
4
4
  isDisabled?: boolean;
5
5
  onSelect: (group: ICaseGroup | null) => void;
6
- onAddMembers?: () => void;
7
6
  }
8
7
  export declare const GroupSelect: (props: IProps) => React.JSX.Element;
9
8
  export {};
@@ -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;AAwC3E,OAAO,KAAmD,MAAM,OAAO,CAAC;AAWxE,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,sBAypBxC,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;AAwC3E,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,UAAU,MAAM;IACZ,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAC;CAChD;AAKD,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,sBAmjBxC,CAAC"}
@@ -7,30 +7,26 @@ 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 { useApolloClient } from '@apollo/client/react';
10
+ import { publicApi } from '@cee-eng/hydrajs';
11
11
  import { Button, Divider, Dropdown, MenuContent, MenuItem, MenuList, MenuToggle, Select, SelectList, SelectOption, Spinner, TextInput, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, } from '@patternfly/react-core';
12
12
  import CogIcon from '@patternfly/react-icons/dist/js/icons/cog-icon';
13
13
  import TimesIcon from '@patternfly/react-icons/dist/js/icons/times-icon';
14
- import { AlertMessage, AlertType, ToastNotification, useConfirmation, usePrevious, useSelectKeyboardNavigator, } from '@rh-support/components';
14
+ import { AlertMessage, AlertType, ToastNotification, useConfirmation, useFetch, usePrevious, useSelectKeyboardNavigator, } from '@rh-support/components';
15
15
  import { fetchCaseGroupsForSSO, setCaseGroups, useGlobalDispatchContext, useGlobalStateContext, } from '@rh-support/react-context';
16
16
  import { ability, resourceActions, resources } from '@rh-support/user-permissions';
17
- import { GET_CASE_GROUP_MEMBERS } from '@rh-support/utils';
17
+ import { haventLoadedMetadata } from '@rh-support/utils';
18
18
  import find from 'lodash/find';
19
19
  import isEmpty from 'lodash/isEmpty';
20
- import unescape from 'lodash/unescape';
21
20
  import React, { useCallback, useEffect, useRef, useState } from 'react';
22
21
  import { Trans, useTranslation } from 'react-i18next';
23
22
  import { GroupSelectActions } from '../../../constants/GroupSelectActions';
24
- import { useCreateCaseGroup, useCreateCaseGroupMember, useDeleteCaseGroup, useRenameCaseGroup, } from '../../../hooks/useCaseGroupGraphQL';
25
23
  const actions = GroupSelectActions;
26
24
  const unGroupedCaseGroupNumber = '-1';
27
25
  export const GroupSelect = (props) => {
28
- var _a;
29
26
  const { t } = useTranslation();
30
27
  const { onSelect: onSelectProp } = props;
31
28
  const manageActionsRef = useRef();
32
- const apolloClient = useApolloClient();
33
- const { globalMetadataState: { caseGroups, loggedInUsersAccount }, } = useGlobalStateContext();
29
+ const { globalMetadataState: { caseGroups, loggedInUserJwtToken }, } = useGlobalStateContext();
34
30
  const dispatch = useGlobalDispatchContext();
35
31
  const selectAGroupText = caseGroups.isFetching
36
32
  ? t('Loading groups')
@@ -41,45 +37,11 @@ export const GroupSelect = (props) => {
41
37
  const confirmation = useConfirmation();
42
38
  const [input, setInput] = useState('');
43
39
  const [shouldFilter, setShouldFilter] = useState(false);
44
- const accountId = (_a = loggedInUsersAccount === null || loggedInUsersAccount === void 0 ? void 0 : loggedInUsersAccount.data) === null || _a === void 0 ? void 0 : _a.salesforceAccountId;
45
- // GraphQL hooks for mutations
46
- const { createGroup: createGroupMutation, loading: createLoading } = useCreateCaseGroup();
47
- const { createMember: createMemberMutation } = useCreateCaseGroupMember();
48
- const { renameGroup: renameGroupMutation, loading: renameLoading } = useRenameCaseGroup();
49
- const { deleteGroup: deleteGroupMutation, loading: deleteLoading } = useDeleteCaseGroup();
50
- const hasFetchedFromGraphQL = useRef(false);
51
- const [groupsFetchCompleted, setGroupsFetchCompleted] = useState(false);
52
- const previousCaseGroupsIsError = usePrevious(caseGroups.isError);
53
- useEffect(() => {
54
- if (caseGroups.isError && !previousCaseGroupsIsError) {
55
- ToastNotification.addDangerMessage(t('Could not fetch groups. Please try again or refresh'));
56
- }
57
- }, [caseGroups.isError, previousCaseGroupsIsError, t]);
58
- // Always fetch groups from GraphQL — never rely on potentially stale Hydra data.
59
- // Auto-select only after this settles so members can load against real group data.
60
- useEffect(() => {
61
- if (!apolloClient || !accountId) {
62
- setGroupsFetchCompleted(true);
63
- return;
64
- }
65
- if (hasFetchedFromGraphQL.current)
66
- return;
67
- hasFetchedFromGraphQL.current = true;
68
- const fetchGroups = () => __awaiter(void 0, void 0, void 0, function* () {
69
- try {
70
- yield fetchCaseGroupsForSSO(dispatch, apolloClient, accountId);
71
- }
72
- finally {
73
- setGroupsFetchCompleted(true);
74
- }
75
- });
76
- fetchGroups();
77
- }, [dispatch, apolloClient, accountId]);
78
- // Set default group once groups are loaded
40
+ // Fetch groups on init
79
41
  useEffect(() => {
80
42
  var _a, _b;
81
- if (!groupsFetchCompleted || caseGroups.isFetching)
82
- return;
43
+ if (haventLoadedMetadata(caseGroups, (data) => data === undefined))
44
+ fetchCaseGroupsForSSO(dispatch, loggedInUserJwtToken.preferred_username);
83
45
  if (isEmpty(selectedGroup) && !isEmpty(caseGroups) && ((_a = caseGroups === null || caseGroups === void 0 ? void 0 : caseGroups.data) === null || _a === void 0 ? void 0 : _a.length) > 0) {
84
46
  const defaultCaseGroup = find(caseGroups === null || caseGroups === void 0 ? void 0 : caseGroups.data, (g) => g.isDefault);
85
47
  const newSelectedGroup = (defaultCaseGroup === null || defaultCaseGroup === void 0 ? void 0 : defaultCaseGroup.groupNum) === '-1'
@@ -91,7 +53,7 @@ export const GroupSelect = (props) => {
91
53
  }
92
54
  }
93
55
  // eslint-disable-next-line react-hooks/exhaustive-deps
94
- }, [caseGroups, groupsFetchCompleted]);
56
+ }, [dispatch, loggedInUserJwtToken, caseGroups]);
95
57
  // handle dropdown open/close toggle
96
58
  const [isOpen, setIsOpen] = useState(false);
97
59
  // handle group selection
@@ -119,7 +81,6 @@ export const GroupSelect = (props) => {
119
81
  // Group actions dropdown state
120
82
  const hasGroupPermissions = ability.can(resourceActions.CREATE, resources.CASE_GROUPS);
121
83
  const [showDropdown, setShowDropdown] = useState(hasGroupPermissions);
122
- useEffect(() => setShowDropdown(hasGroupPermissions), [hasGroupPermissions]);
123
84
  const [showInput, setShowInput] = useState(false);
124
85
  const [isDropdownOpen, setIsDropdownOpen] = useState(false);
125
86
  const toggleIsDropdownOpen = () => setIsDropdownOpen(!isDropdownOpen);
@@ -129,10 +90,19 @@ export const GroupSelect = (props) => {
129
90
  closeDropdown();
130
91
  setAction(action);
131
92
  };
93
+ // fetch objects for apis
132
94
  const [showErrorMessage] = useState(false);
95
+ const createGroupFetch = useFetch(publicApi.caseGroups.createGroup, { propgateErrors: true });
96
+ const renameGroupFetch = useFetch(publicApi.caseGroups.renameGroup, { propgateErrors: true });
97
+ const deleteGroupFetch = useFetch(publicApi.caseGroups.deleteGroup, { propgateErrors: true });
98
+ const duplicateGroupFetch = useFetch(publicApi.caseGroups.createGroup, { propgateErrors: true });
133
99
  // group actions input state
134
100
  const textInputRef = useRef();
135
- const disableOnFetch = caseGroups.isFetching || createLoading || renameLoading || deleteLoading;
101
+ const disableOnFetch = caseGroups.isFetching ||
102
+ createGroupFetch.isFetching ||
103
+ renameGroupFetch.isFetching ||
104
+ deleteGroupFetch.isFetching ||
105
+ duplicateGroupFetch.isFetching;
136
106
  const onChange = (e, value) => {
137
107
  if (!showInput) {
138
108
  setIsOpen(true);
@@ -154,78 +124,56 @@ export const GroupSelect = (props) => {
154
124
  // eslint-disable-next-line react-hooks/exhaustive-deps
155
125
  }, [input, showInput]);
156
126
  // group actions
157
- function createGroup(groupName) {
127
+ function setGroupOnFetch(groupName) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ yield fetchCaseGroupsForSSO(dispatch, loggedInUserJwtToken.preferred_username);
130
+ setSelectedGroup(groupName);
131
+ });
132
+ }
133
+ function createGroup(groupName, ssoUsername) {
158
134
  return __awaiter(this, void 0, void 0, function* () {
159
- if (!accountId) {
160
- ToastNotification.addDangerMessage(t('There was an error while creating this group'));
161
- return;
162
- }
163
135
  try {
164
- const response = yield createGroupMutation(groupName, accountId);
165
- const createdRecord = response.redhat_support_uiapi.CaseGroup__cCreate.RedHatSupportRecord;
136
+ yield createGroupFetch.request({ name: groupName, contactSsoName: ssoUsername });
166
137
  ToastNotification.addSuccessMessage(t('Group has been successfully created'));
167
- const newGroup = {
168
- groupNum: createdRecord.Id,
169
- name: unescape(createdRecord.Name.value),
170
- isPrivate: false,
171
- isDefault: false,
172
- defaultMembers: [],
173
- members: [],
174
- };
175
- const updatedGroups = [...(caseGroups.data || []), newGroup];
176
- setCaseGroups(dispatch, updatedGroups);
177
- setShowDropdown(true);
178
- setShowInput(false);
179
- setSelectedGroup(groupName);
180
- }
181
- catch (e) {
182
- const message = String((e === null || e === void 0 ? void 0 : e.message) || '');
183
- if (message.includes('insufficient access rights')) {
184
- ToastNotification.addDangerMessage(t('You do not have permission to create this group'));
138
+ try {
139
+ yield setGroupOnFetch(groupName);
140
+ setShowDropdown(true);
141
+ setShowInput(false);
142
+ setSelectedGroup(groupName);
185
143
  }
186
- else {
187
- ToastNotification.addDangerMessage(t('There was an error while creating this group'));
144
+ catch (error) {
145
+ ToastNotification.addDangerMessage(t("We're having an issue finding this group's users"));
146
+ onClear();
188
147
  }
189
148
  }
149
+ catch (e) {
150
+ ToastNotification.addDangerMessage(t('There was an error while creating this group'));
151
+ }
190
152
  });
191
153
  }
192
154
  const [action, setAction] = useState('');
193
155
  const isUserInputAGroup = () => (caseGroups.data || []).find((value) => value.name === input);
194
- const handleDeleteGroup = () => __awaiter(void 0, void 0, void 0, function* () {
195
- const groupToDelete = getGroup(selectedGroup);
196
- yield confirmation({
197
- catchOnCancel: true,
198
- title: t('Delete group'),
199
- description: (React.createElement(Trans, null,
200
- "Are you sure you want to delete ",
201
- React.createElement("strong", null, groupToDelete.name),
202
- "?")),
203
- });
204
- yield deleteGroupMutation(groupToDelete.groupNum);
205
- const index = (caseGroups.data || []).findIndex((value) => value.name === groupToDelete.name);
206
- (caseGroups.data || []).splice(index, 1);
207
- setCaseGroups(dispatch, caseGroups.data || []);
208
- onClear();
209
- ToastNotification.addSuccessMessage(t('Group has been successfully deleted'));
210
- });
211
156
  const onAction = () => __awaiter(void 0, void 0, void 0, function* () {
212
- var _a, _b, _c, _d;
213
- const needsUniqueName = action === actions.create || action === actions.rename || action === actions.duplicate;
214
- if (needsUniqueName && isUserInputAGroup()) {
215
- ToastNotification.addWarningMessage(t('Group already exists'));
216
- return;
217
- }
218
157
  switch (action) {
219
158
  case actions.create: {
220
- yield createGroup(input);
159
+ if (isUserInputAGroup()) {
160
+ ToastNotification.addWarningMessage(t('Group already exists'));
161
+ break;
162
+ }
163
+ yield createGroup(input, loggedInUserJwtToken.preferred_username);
221
164
  setAction('');
222
165
  break;
223
166
  }
224
167
  case actions.rename: {
168
+ if (isUserInputAGroup()) {
169
+ ToastNotification.addWarningMessage(t('Group already exists'));
170
+ break;
171
+ }
225
172
  const previousGroup = selectedGroup;
226
173
  const group = getGroup(previousGroup);
227
174
  try {
228
- yield renameGroupMutation(group.groupNum, input);
175
+ // change name in the current caseGroups list
176
+ yield renameGroupFetch.request(input, group.groupNum, group.isPrivate);
229
177
  const copyCaseGroups = [...(caseGroups.data || [])];
230
178
  const index = copyCaseGroups.findIndex((value) => value.name === previousGroup);
231
179
  copyCaseGroups[index].name = input;
@@ -237,13 +185,7 @@ export const GroupSelect = (props) => {
237
185
  ToastNotification.addSuccessMessage(t('Group has been renamed'));
238
186
  }
239
187
  catch (e) {
240
- const message = String((e === null || e === void 0 ? void 0 : e.message) || '');
241
- if (message.includes('insufficient access rights')) {
242
- ToastNotification.addDangerMessage(t('You do not have permission to rename this group'));
243
- }
244
- else {
245
- ToastNotification.addDangerMessage(t('There was an error renaming this group'));
246
- }
188
+ ToastNotification.addDangerMessage(t('There was an error renaming this group '));
247
189
  }
248
190
  finally {
249
191
  setAction('');
@@ -252,80 +194,56 @@ export const GroupSelect = (props) => {
252
194
  }
253
195
  case actions.delete: {
254
196
  try {
255
- yield handleDeleteGroup();
256
- }
257
- catch (e) {
258
- const message = String((e === null || e === void 0 ? void 0 : e.message) || '');
259
- if (message.includes('insufficient access rights')) {
260
- ToastNotification.addDangerMessage(t('You do not have permission to delete this group'));
197
+ const groupToDelete = getGroup(selectedGroup);
198
+ try {
199
+ // get confirmation on delete
200
+ yield confirmation({
201
+ catchOnCancel: true,
202
+ title: t('Delete group'),
203
+ description: (React.createElement(Trans, null,
204
+ "Are you sure you want to delete ",
205
+ React.createElement("strong", null, groupToDelete.name),
206
+ "?")),
207
+ });
208
+ // delete action is confirmed
209
+ yield deleteGroupFetch.request(groupToDelete.groupNum);
210
+ // remove group from list
211
+ const index = (caseGroups.data || []).findIndex((value) => value.name === groupToDelete.name);
212
+ (caseGroups.data || []).splice(index, 1);
213
+ setCaseGroups(dispatch, caseGroups.data || []);
214
+ onClear();
215
+ ToastNotification.addSuccessMessage(t('Group has been successfully deleted'));
261
216
  }
262
- else {
263
- ToastNotification.addDangerMessage(t('There was an error deleting this group'));
217
+ catch (_a) {
218
+ // user didn't confirm the delete action
264
219
  }
265
220
  }
221
+ catch (e) {
222
+ ToastNotification.addDangerMessage(t('There was an error deleting this group'));
223
+ }
266
224
  finally {
267
225
  setAction('');
268
226
  break;
269
227
  }
270
228
  }
271
229
  case actions.duplicate: {
272
- if (!accountId) {
273
- ToastNotification.addDangerMessage(t('There was an error while duplicating group'));
230
+ if (isUserInputAGroup()) {
231
+ ToastNotification.addWarningMessage(t('Group already exists'));
274
232
  break;
275
233
  }
276
234
  try {
277
- const sourceGroup = getGroup(selectedGroup);
278
- const dupResponse = yield createGroupMutation(input, accountId);
279
- const dupRecord = dupResponse.redhat_support_uiapi.CaseGroup__cCreate.RedHatSupportRecord;
280
- const newGroupId = dupRecord.Id;
281
- if (sourceGroup === null || sourceGroup === void 0 ? void 0 : sourceGroup.groupNum) {
282
- const membersResponse = yield apolloClient.query({
283
- query: GET_CASE_GROUP_MEMBERS,
284
- variables: {
285
- where: { Group__c: { eq: sourceGroup.groupNum } },
286
- first: 2000,
287
- },
288
- fetchPolicy: 'network-only',
289
- });
290
- const sourceMembers = ((_d = (_c = (_b = (_a = membersResponse.data) === null || _a === void 0 ? void 0 : _a.redhat_support_uiapi) === null || _b === void 0 ? void 0 : _b.query) === null || _c === void 0 ? void 0 : _c.RedHatSupportCaseGroupMember__c) === null || _d === void 0 ? void 0 : _d.edges) ||
291
- [];
292
- const contactIds = sourceMembers
293
- .filter(({ node }) => { var _a; return (_a = node.Contact__c) === null || _a === void 0 ? void 0 : _a.value; })
294
- .map(({ node }) => node.Contact__c.value);
295
- if (contactIds.length > 0) {
296
- const results = yield Promise.allSettled(contactIds.map((contactId) => createMemberMutation(contactId, newGroupId)));
297
- const failed = results.filter((r) => r.status === 'rejected');
298
- if (failed.length > 0) {
299
- ToastNotification.addWarningMessage(t('Group duplicated but {{count}} members could not be copied', {
300
- count: failed.length,
301
- }));
302
- }
303
- }
304
- }
305
- const dupGroup = {
306
- groupNum: newGroupId,
307
- name: unescape(dupRecord.Name.value),
308
- isPrivate: false,
309
- isDefault: false,
310
- defaultMembers: [],
311
- members: [],
312
- };
313
- const updatedDupGroups = [...(caseGroups.data || []), dupGroup];
314
- setCaseGroups(dispatch, updatedDupGroups);
235
+ yield duplicateGroupFetch.request({
236
+ name: input,
237
+ contactSsoName: loggedInUserJwtToken.preferred_username,
238
+ });
239
+ yield setGroupOnFetch(input);
315
240
  setShowDropdown(true);
316
241
  setShowInput(false);
317
- setSelectedGroup(input);
318
242
  setInput('');
319
243
  ToastNotification.addSuccessMessage(t('Group has been successfully duplicated'));
320
244
  }
321
245
  catch (e) {
322
- const message = String((e === null || e === void 0 ? void 0 : e.message) || '');
323
- if (message.includes('insufficient access rights')) {
324
- ToastNotification.addDangerMessage(t('You do not have permission to duplicate this group'));
325
- }
326
- else {
327
- ToastNotification.addDangerMessage(t('There was an error while duplicating group'));
328
- }
246
+ ToastNotification.addDangerMessage(t('There was an error while duplicating group'));
329
247
  }
330
248
  finally {
331
249
  setAction('');
@@ -366,17 +284,11 @@ export const GroupSelect = (props) => {
366
284
  setAction('');
367
285
  setInput(selectedGroup);
368
286
  };
369
- const handleAddMembers = () => {
370
- var _a;
371
- closeDropdown();
372
- (_a = props.onAddMembers) === null || _a === void 0 ? void 0 : _a.call(props);
373
- };
374
287
  const dropdownItems = [
375
288
  React.createElement(MenuItem, { className: "create-group-action", isDisabled: !ability.can(resourceActions.CREATE, resources.CASE_GROUPS), key: "create", onClick: onActionFocus(actions.create), "data-tracking-id": "manage-group-create" }, t('Create')),
376
289
  React.createElement(Divider, { component: "li" }),
377
290
  React.createElement(MenuItem, { className: "create-group-action", isDisabled: !selectedGroup || !ability.can(resourceActions.UPDATE, resources.CASE_GROUPS), key: "rename", onClick: onActionFocus(actions.rename), "data-tracking-id": "manage-group-rename" }, t('Rename')),
378
291
  React.createElement(MenuItem, { className: "create-group-action", isDisabled: !selectedGroup || !ability.can(resourceActions.CREATE, resources.CASE_GROUPS), key: "duplicate", onClick: onActionFocus(actions.duplicate), "data-tracking-id": "manage-group-duplicate" }, t('Duplicate')),
379
- React.createElement(MenuItem, { className: "create-group-action", isDisabled: !selectedGroup || !ability.can(resourceActions.CREATE, resources.CASE_GROUPS), key: "add-members", onClick: handleAddMembers, "data-tracking-id": "manage-group-add-members" }, t('Add members')),
380
292
  React.createElement(MenuItem, { isDanger: true, className: "create-group-action del-btn", isDisabled: !selectedGroup || !ability.can(resourceActions.DELETE, resources.CASE_GROUPS), key: "delete", onClick: onActionFocus(actions.delete), "data-tracking-id": "manage-group-delete" }, t('Delete')),
381
293
  ];
382
294
  const dropdownToggle = (toggleRef) => (React.createElement(MenuToggle, { isFullHeight: true, className: "pf-v6-u-ml-sm manage-group-actions-toggle-options pf-v6-u-p-md", ref: toggleRef, isDisabled: props.isDisabled || disableOnFetch, onClick: toggleIsDropdownOpen, isExpanded: isDropdownOpen, "data-tracking-id": "manage-group-toggle-options", "aria-label": "Group actions dropdown toggle", icon: React.createElement(CogIcon, null) }));
@@ -403,11 +315,14 @@ export const GroupSelect = (props) => {
403
315
  };
404
316
  const selectTypeahead = manageActionsRef.current.querySelector('input');
405
317
  if (!showInput) {
318
+ // adds event listeners that prevent using enter to select a group.
406
319
  selectTypeahead.addEventListener('keydown', dontSubmitOnEnterCb);
407
320
  selectTypeahead.addEventListener('keyup', dontSubmitOnEnterCb);
408
321
  selectTypeahead.addEventListener('keypress', dontSubmitOnEnterCb);
409
322
  }
410
323
  else {
324
+ // adds event listeners that allows submitting actions using enter on select
325
+ // inupt used for getting user input for actions.
411
326
  selectTypeahead.addEventListener('keydown', submitOnEnterCb);
412
327
  }
413
328
  return () => {
@@ -421,6 +336,7 @@ export const GroupSelect = (props) => {
421
336
  }
422
337
  };
423
338
  }, [manageActionsRef, showInput]);
339
+ //added for validation of new group name
424
340
  const containsOnlySpecialChars = (str) => {
425
341
  return /^[^a-zA-Z0-9]*$/.test(str);
426
342
  };