@rh-support/manage 1.0.42 → 1.0.100-beta.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 (50) hide show
  1. package/README.md +0 -2
  2. package/lib/esm/ManageTabs.d.ts.map +1 -1
  3. package/lib/esm/ManageTabs.js +21 -4
  4. package/lib/esm/Routes.d.ts +1 -0
  5. package/lib/esm/Routes.d.ts.map +1 -1
  6. package/lib/esm/Routes.js +6 -0
  7. package/lib/esm/components/Configs/ConfigInLineEdit.js +1 -1
  8. package/lib/esm/components/Groups/GroupUserPermissionsSelect/GroupUserPermissionsSelect.js +1 -1
  9. package/lib/esm/components/ManagePartnerships/NonOrgCustomerInfoModal.d.ts +2 -0
  10. package/lib/esm/components/ManagePartnerships/NonOrgCustomerInfoModal.d.ts.map +1 -0
  11. package/lib/esm/components/ManagePartnerships/NonOrgCustomerInfoModal.js +15 -0
  12. package/lib/esm/components/ManagePartnerships/PartnerLinkNameForm.d.ts +12 -0
  13. package/lib/esm/components/ManagePartnerships/PartnerLinkNameForm.d.ts.map +1 -0
  14. package/lib/esm/components/ManagePartnerships/PartnerLinkNameForm.js +21 -0
  15. package/lib/esm/components/ManagePartnerships/PartnershipsList.d.ts +2 -0
  16. package/lib/esm/components/ManagePartnerships/PartnershipsList.d.ts.map +1 -0
  17. package/lib/esm/components/ManagePartnerships/PartnershipsList.js +183 -0
  18. package/lib/esm/components/ManagePartnerships/PartnershipsTermsModal.d.ts +2 -0
  19. package/lib/esm/components/ManagePartnerships/PartnershipsTermsModal.d.ts.map +1 -0
  20. package/lib/esm/components/ManagePartnerships/PartnershipsTermsModal.js +97 -0
  21. package/lib/esm/components/ManagePartnerships/PendingRequests.d.ts +3 -0
  22. package/lib/esm/components/ManagePartnerships/PendingRequests.d.ts.map +1 -0
  23. package/lib/esm/components/ManagePartnerships/PendingRequests.js +195 -0
  24. package/lib/esm/components/ManagePartnerships/RequestCollaborationModal.d.ts +8 -0
  25. package/lib/esm/components/ManagePartnerships/RequestCollaborationModal.d.ts.map +1 -0
  26. package/lib/esm/components/ManagePartnerships/RequestCollaborationModal.js +130 -0
  27. package/lib/esm/components/ManagePartnerships/index.d.ts +2 -0
  28. package/lib/esm/components/ManagePartnerships/index.d.ts.map +1 -0
  29. package/lib/esm/components/ManagePartnerships/index.js +25 -0
  30. package/lib/esm/components/ManageTable/ManageTable.d.ts.map +1 -1
  31. package/lib/esm/components/ManageTable/ManageTable.js +3 -2
  32. package/lib/esm/components/NotificationEmails/NotificationEmailsModal.d.ts.map +1 -1
  33. package/lib/esm/components/NotificationEmails/NotificationEmailsModal.js +1 -0
  34. package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentCategoryContent/AddNewCategoryDropDown.d.ts.map +1 -1
  35. package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentCategoryContent/AddNewCategoryDropDown.js +29 -10
  36. package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentSuggestion/TopContentSuggestion.d.ts.map +1 -1
  37. package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentSuggestion/TopContentSuggestion.js +8 -4
  38. package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentSuggestion/TopContentSuggestionHint.d.ts.map +1 -1
  39. package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentSuggestion/TopContentSuggestionHint.js +23 -6
  40. package/lib/esm/components/TopContentManagement/TopContentProductVersionSelector.d.ts.map +1 -1
  41. package/lib/esm/components/TopContentManagement/TopContentProductVersionSelector.js +31 -30
  42. package/lib/esm/context/ManagePartnershipsProvider.d.ts +11 -0
  43. package/lib/esm/context/ManagePartnershipsProvider.d.ts.map +1 -0
  44. package/lib/esm/context/ManagePartnershipsProvider.js +26 -0
  45. package/lib/esm/reducers/ManagePartnershipsReducer.d.ts +16 -0
  46. package/lib/esm/reducers/ManagePartnershipsReducer.d.ts.map +1 -0
  47. package/lib/esm/reducers/ManagePartnershipsReducer.js +30 -0
  48. package/lib/esm/scss/_main.scss +12 -0
  49. package/lib/esm/scss/_pf4-overrides.scss +4 -0
  50. package/package.json +10 -10
package/README.md CHANGED
@@ -9,5 +9,3 @@ const manage = require('manage');
9
9
 
10
10
  // TODO: DEMONSTRATE API
11
11
  ```
12
-
13
- .
@@ -1 +1 @@
1
- {"version":3,"file":"ManageTabs.d.ts","sourceRoot":"","sources":["../../src/ManageTabs.tsx"],"names":[],"mappings":"AAMA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAmBvD,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC;CACvC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,eAqIvC"}
1
+ {"version":3,"file":"ManageTabs.d.ts","sourceRoot":"","sources":["../../src/ManageTabs.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAoBvD,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC;CACvC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,eAgKvC"}
@@ -1,11 +1,13 @@
1
1
  import { ErrorBoundary, useDocumentTitle } from '@rh-support/components';
2
+ import { GlobalMetadataStateContext } from '@rh-support/react-context';
2
3
  import { ability, CaseDetailsFields, resourceActions, resources } from '@rh-support/user-permissions';
3
- import { CustomElements, requireCustomElement } from '@rh-support/utils';
4
+ import { CustomElements, getConfigField, PCM_CONFIG_FIELD_TYPE, requireCustomElement } from '@rh-support/utils';
4
5
  import map from 'lodash/map';
5
- import React from 'react';
6
+ import React, { useContext } from 'react';
6
7
  import { ConfigsTable } from './components/Configs/ConfigsTable';
7
8
  import { ManageGroupUsers } from './components/Groups/ManageGroupUsers';
8
9
  import { ManageGroupedBookmarkedAccountsTab } from './components/ManageBookmarkedAccountsTab';
10
+ import { ManagePartnerships } from './components/ManagePartnerships/index';
9
11
  import { ManagePreferences } from './components/ManagePreferences';
10
12
  import { NotificationEmails } from './components/NotificationEmails/index';
11
13
  import { TopContentManagement } from './components/TopContentManagement';
@@ -21,7 +23,9 @@ requireCustomElement([
21
23
  export function ManageTabs(props) {
22
24
  var _a, _b;
23
25
  const history = props.routeProps.history;
24
- const { groupsRoute, bookmarkedAccountsRoute, topContentRoute, notificationEmailsRoute, preferencesRoute, configsRoute, } = Routes.getPaths();
26
+ const { groupsRoute, bookmarkedAccountsRoute, topContentRoute, notificationEmailsRoute, preferencesRoute, configsRoute, partnershipsRoute, } = Routes.getPaths();
27
+ const { globalMetadataState: { pcmConfig }, } = useContext(GlobalMetadataStateContext);
28
+ const isPartnershipsEnabled = getConfigField(pcmConfig.data, 'isPartnershipEnabled', PCM_CONFIG_FIELD_TYPE.FEATURE_FLAG);
25
29
  // Changes route and saves the current path to the url query params
26
30
  const isOnlyBasePath = history.location.pathname === Routes.basePath;
27
31
  useDocumentTitle(PageTitle.MANAGE);
@@ -34,6 +38,7 @@ export function ManageTabs(props) {
34
38
  const canViewCaseGroups = ability.can(resourceActions.READ, resources.CASE_GROUPS) && canViewManageTab;
35
39
  const canManageBookmarkAccounts = ability.can(resourceActions.CREATE, resources.BOOKMARK_ACCOUNTS) && canViewManageTab;
36
40
  const canViewEmailNotificationTab = ability.can(resourceActions.READ, resources.NOTIFICATION_EMAIL);
41
+ const canViewPartnershipsTab = ability.can(resourceActions.READ, resources.PARTNERSHIPS);
37
42
  const canAddCustomNotification = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SEND_NOTIFICATIONS);
38
43
  const canViewConfigsTab = ability.can(resourceActions.READ, resources.APP_INTERNAL_CONFIGS);
39
44
  const tabsToRender = [];
@@ -71,6 +76,18 @@ export function ManageTabs(props) {
71
76
  },
72
77
  component: React.createElement(NotificationEmails, null),
73
78
  });
79
+ canViewPartnershipsTab &&
80
+ isPartnershipsEnabled &&
81
+ tabsToRender.push({
82
+ title: 'Partnerships',
83
+ key: 'partnerships-tab',
84
+ 'data-tracking-id': 'partnerships-tab',
85
+ routePath: partnershipsRoute,
86
+ onClick: () => {
87
+ changeRouteThunk(partnershipsRoute);
88
+ },
89
+ component: React.createElement(ManagePartnerships, null),
90
+ });
74
91
  tabsToRender.push({
75
92
  title: 'Preferences',
76
93
  key: 'preferences-tab',
@@ -112,7 +129,7 @@ export function ManageTabs(props) {
112
129
  const getSelectedIndex = () => {
113
130
  if (isOnlyBasePath)
114
131
  return 0;
115
- const tabIndex = tabsToRender.findIndex((tab) => tab.routePath === history.location.pathname);
132
+ const tabIndex = tabsToRender.findIndex((tab) => tab.routePath === history.location.pathname.substring(0, tab.routePath.length));
116
133
  return tabIndex > -1 ? tabIndex : 0;
117
134
  };
118
135
  /**
@@ -14,6 +14,7 @@ interface ManageRoutes {
14
14
  savedSearches: Route;
15
15
  topContent: Route;
16
16
  preferences: Route;
17
+ partnerships: Route;
17
18
  notificationEmails: Route;
18
19
  configs: Route;
19
20
  }
@@ -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,aAAa,EAAE,KAAK,CAAC;IACrB,UAAU,EAAE,KAAK,CAAC;IAClB,WAAW,EAAE,KAAK,CAAC;IACnB,kBAAkB,EAAE,KAAK,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC;CAClB;AAED,eAAO,MAAM,MAAM,EAAE,YAmEpB,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,WAAW,EAAE,KAAK,CAAC;IACnB,YAAY,EAAE,KAAK,CAAC;IACpB,kBAAkB,EAAE,KAAK,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC;CAClB;AAED,eAAO,MAAM,MAAM,EAAE,YAyEpB,CAAC"}
package/lib/esm/Routes.js CHANGED
@@ -36,6 +36,12 @@ export const Routes = {
36
36
  return getPath(this);
37
37
  },
38
38
  },
39
+ partnerships: {
40
+ path: '/partnerships',
41
+ getPath() {
42
+ return getPath(this);
43
+ },
44
+ },
39
45
  notificationEmails: {
40
46
  path: '/notification-emails',
41
47
  getPath() {
@@ -32,7 +32,7 @@ export function ConfigInLineEdit(props) {
32
32
  }, [props.fieldValue]);
33
33
  return (React.createElement(React.Fragment, null,
34
34
  React.createElement(InlineEdit, { labelProps: { htmlFor: 'case-details-custom-email' }, allowInlineEdit: true, initialIsEditing: false, onSave: onSave, onCancel: onCancel, saveDisabled: input === props.fieldValue || props.isUpdating || hasLargeInput, loadingIndicator: React.createElement(LoadingIndicator, { show: props.isUpdating, isInline: true }) },
35
- React.createElement(TextAreaAutosize, { id: `config-value-${props.id}`, name: `config-value-${props.id}`, "aria-invalid": hasLargeInput, className: `form-control${hasLargeInput ? ' form-invalid' : ''}`, value: input, "data-tracking-id": "open-case-describe-ktQ1-issue", onChange: onChange, disabled: props.isUpdating }),
35
+ React.createElement(TextAreaAutosize, { id: `config-value-${props.id}`, name: `config-value-${props.id}`, "aria-invalid": hasLargeInput, className: `form-control${hasLargeInput ? ' form-invalid' : ''}`, value: input, "data-tracking-id": "manage-case-describe-ktQ1-issue", onChange: onChange, disabled: props.isUpdating }),
36
36
  hasLargeInput && (React.createElement("p", { className: "form-instructions form-invalid" },
37
37
  "Config value cannot be more than ",
38
38
  CONFIG_FIELD_VALUE_LIMIT,
@@ -72,6 +72,6 @@ export const GroupUserPermissionsSelect = (props) => {
72
72
  * 4. Non-org admins cannot see the manage tab itself and thus that check is not added.
73
73
  */
74
74
  return (React.createElement(React.Fragment, null,
75
- React.createElement(Select, { isDisabled: updateUsersFetch.isFetching || !props.account.hasGroupACLs, className: "permissions-select", "aria-label": t('User permissions'), onToggle: onToggle, onSelect: onSelect, onClear: onClear, selections: option, isOpen: isOpen, "aria-labelledby": t('User permissions'), placeholderText: t('Select a permission') }, Object.keys(options).map((key) => (React.createElement(SelectOption, { key: key, value: options[key], "data-tracking-id": `group-user-permission-${key}` }, t(options[key]))))),
75
+ React.createElement(Select, { isDisabled: updateUsersFetch.isFetching, className: "permissions-select", "aria-label": t('User permissions'), onToggle: onToggle, onSelect: onSelect, onClear: onClear, selections: option, isOpen: isOpen, "aria-labelledby": t('User permissions'), placeholderText: t('Select a permission') }, Object.keys(options).map((key) => (React.createElement(SelectOption, { key: key, value: options[key], "data-tracking-id": `group-user-permission-${key}` }, t(options[key]))))),
76
76
  React.createElement(LoadingIndicator, { show: updateUsersFetch.isFetching, size: "xs" })));
77
77
  };
@@ -0,0 +1,2 @@
1
+ export declare const NonOrgCustomerInfoModal: () => JSX.Element;
2
+ //# sourceMappingURL=NonOrgCustomerInfoModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NonOrgCustomerInfoModal.d.ts","sourceRoot":"","sources":["../../../../src/components/ManagePartnerships/NonOrgCustomerInfoModal.tsx"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB,mBA2BnC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Button, ButtonVariant, Modal, ModalVariant } from '@patternfly/react-core';
2
+ import React from 'react';
3
+ import { Trans, useTranslation } from 'react-i18next';
4
+ export const NonOrgCustomerInfoModal = () => {
5
+ const [isModalOpen, setIsModalOpen] = React.useState(true);
6
+ const { t } = useTranslation();
7
+ const handleModalToggle = () => {
8
+ setIsModalOpen(!isModalOpen);
9
+ };
10
+ return (React.createElement(Modal, { variant: ModalVariant.small, title: t('Confirm partnership collaboration'), isOpen: isModalOpen, onClose: handleModalToggle, actions: [
11
+ React.createElement(Button, { key: "cancel", variant: ButtonVariant.primary, onClick: handleModalToggle, "data-tracking-id": "confirm-partnership-collaboration-no-org-admin" },
12
+ React.createElement(Trans, null, "Cancel")),
13
+ ] },
14
+ React.createElement(Trans, null, "Only org admin customers can confirm partnership collaboration")));
15
+ };
@@ -0,0 +1,12 @@
1
+ declare type validate = 'success' | 'warning' | 'error' | 'default';
2
+ interface IProps {
3
+ onLinkNameChange: (linkName: string) => void;
4
+ isDuplicateLinkName: boolean;
5
+ validated: validate;
6
+ currentLinkName?: string;
7
+ inputLabel?: string;
8
+ friendlyName?: string;
9
+ }
10
+ export declare function PartnerLinkNameForm(props: IProps): JSX.Element;
11
+ export {};
12
+ //# sourceMappingURL=PartnerLinkNameForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PartnerLinkNameForm.d.ts","sourceRoot":"","sources":["../../../../src/components/ManagePartnerships/PartnerLinkNameForm.tsx"],"names":[],"mappings":"AAKA,aAAK,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE5D,UAAU,MAAM;IACZ,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,mBAAmB,EAAE,OAAO,CAAC;IAC7B,SAAS,EAAE,QAAQ,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,eAgDhD"}
@@ -0,0 +1,21 @@
1
+ import { Form, FormGroup, FormHelperText, Grid, GridItem, TextInput } from '@patternfly/react-core';
2
+ import ExclamationCircleIcon from '@patternfly/react-icons/dist/js/icons/exclamation-circle-icon';
3
+ import React, { useState } from 'react';
4
+ import { Trans, useTranslation } from 'react-i18next';
5
+ export function PartnerLinkNameForm(props) {
6
+ const [localLinkName, setLocalLinkName] = useState('');
7
+ const { t } = useTranslation();
8
+ const handleLinkNameChange = (link, _event) => {
9
+ setLocalLinkName(link);
10
+ props.onLinkNameChange(link);
11
+ };
12
+ const partnershipLinkId = 'partnership-link-id';
13
+ return (React.createElement(Form, { className: "pf-u-my-md" },
14
+ React.createElement(Grid, { sm: 12, md: 6, lg: 6 },
15
+ React.createElement(GridItem, null,
16
+ React.createElement(FormGroup, { label: props.inputLabel || t('Name your link'), type: "string", helperText: React.createElement(FormHelperText, { isHidden: props.validated === 'error' },
17
+ React.createElement(Trans, null, "Please enter a name for your request")), helperTextInvalid: props.isDuplicateLinkName
18
+ ? t('Link name already used. Please enter a unique name')
19
+ : t('Please enter a name for your request'), helperTextInvalidIcon: React.createElement(ExclamationCircleIcon, null), fieldId: partnershipLinkId, validated: props.validated, isRequired: true },
20
+ React.createElement(TextInput, { isRequired: true, validated: props.validated, value: localLinkName || props.currentLinkName, id: partnershipLinkId, "aria-describedby": "age-1-helper", onChange: handleLinkNameChange, placeholder: t('e.g. Customer name') }))))));
21
+ }
@@ -0,0 +1,2 @@
1
+ export declare function PartnershipsList(): JSX.Element;
2
+ //# sourceMappingURL=PartnershipsList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PartnershipsList.d.ts","sourceRoot":"","sources":["../../../../src/components/ManagePartnerships/PartnershipsList.tsx"],"names":[],"mappings":"AA4BA,wBAAgB,gBAAgB,gBAmO/B"}
@@ -0,0 +1,183 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { pcm } from '@cee-eng/hydrajs';
11
+ import { AlertVariant, Button, ButtonVariant, Label, SearchInput } from '@patternfly/react-core';
12
+ import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon';
13
+ import { defaultTableSortMethod, LoadingIndicator, ToastNotification, useConfirmation, } from '@rh-support/components';
14
+ import { fetchAccountManagers, fetchManagedAccounts, GlobalMetadataDispatchContext, useGlobalStateContext, } from '@rh-support/react-context';
15
+ import { haventLoadedMetadata } from '@rh-support/utils';
16
+ import React, { useContext, useEffect, useState } from 'react';
17
+ import { Trans, useTranslation } from 'react-i18next';
18
+ import { useManagePartnershipsContext, useManagePartnershipsDispatchContext, } from '../../context/ManagePartnershipsProvider';
19
+ import { setIsUpdatingAccounts } from '../../reducers/ManagePartnershipsReducer';
20
+ import { ManageTable } from '../ManageTable';
21
+ import { RequestCollaborationModal } from './RequestCollaborationModal';
22
+ export function PartnershipsList() {
23
+ const { t } = useTranslation();
24
+ const confirmRemove = useConfirmation();
25
+ const [searchString, setSearchString] = useState('');
26
+ const [isRequestCollabModalOpen, setIsRequestCollabModalOpen] = useState(false);
27
+ const [accountList, setAccountList] = useState([]);
28
+ const [isFetching, setIsFetching] = useState(false);
29
+ const [hasError, setHasError] = useState(false);
30
+ const [isDeleting, setIsdeleting] = useState(false);
31
+ const [isDeletingAccountNum, setIsdeletingAccountNum] = useState('');
32
+ const { isUpdatingPartnerAccountList } = useManagePartnershipsContext();
33
+ const dispatch = useManagePartnershipsDispatchContext();
34
+ const { globalMetadataState: { loggedInUserRights, managedAccounts, accountManagers, loggedInUserJwtToken }, } = useGlobalStateContext();
35
+ const dispatchToGlobalMetadataReducer = useContext(GlobalMetadataDispatchContext);
36
+ const isPartner = () => loggedInUserRights.data.isPartner();
37
+ const isCustomerOrgAdmin = () => loggedInUserRights.data.isCustomerOrgAdmin();
38
+ const removePartnership = (data) => __awaiter(this, void 0, void 0, function* () {
39
+ try {
40
+ yield confirmRemove({
41
+ catchOnCancel: true,
42
+ title: t('Are you sure?'),
43
+ description: React.createElement(Trans, null, "You will not be able to undo this action after verifying."),
44
+ confirmText: t('Delete'),
45
+ confirmButtonVariant: ButtonVariant.danger,
46
+ });
47
+ try {
48
+ setIsdeleting(true);
49
+ setIsdeletingAccountNum(data.accountNum);
50
+ if (data.isCustomerAccount) {
51
+ yield pcm.partnerships.deleteCustomerAccountByPartner(data.accountNum);
52
+ }
53
+ else {
54
+ yield pcm.partnerships.deletePartnerAccountByCustomer(data.accountNum);
55
+ }
56
+ setAccountList(accountList.filter((a) => a.accountNum !== data.accountNum));
57
+ ToastNotification.addSuccessMessage(t('Partnership removed successfully'));
58
+ setIsdeleting(false);
59
+ setIsdeletingAccountNum('');
60
+ }
61
+ catch (e) {
62
+ ToastNotification.addDangerMessage(t('Partnership failed to be removed'));
63
+ setIsdeleting(false);
64
+ setIsdeletingAccountNum('');
65
+ }
66
+ }
67
+ catch (e) {
68
+ // on confirm modal, cancel button is clicked
69
+ }
70
+ });
71
+ const columns = [
72
+ {
73
+ accessor: (data) => isPartner() && data.isPartnerAccount ? (React.createElement(React.Fragment, null,
74
+ data.name,
75
+ ' ',
76
+ React.createElement(Label, null,
77
+ React.createElement(Trans, null, "Fellow partner")))) : (data.name),
78
+ sortable: true,
79
+ id: 'customer-account-name',
80
+ title: t('Account name'),
81
+ cellWidth: 40,
82
+ sortMethod: (a, b) => {
83
+ var _a, _b;
84
+ if (typeof a !== 'string') {
85
+ a = ((_a = a === null || a === void 0 ? void 0 : a.props) === null || _a === void 0 ? void 0 : _a.children[3]) || '';
86
+ }
87
+ if (typeof b !== 'string') {
88
+ b = ((_b = b === null || b === void 0 ? void 0 : b.props) === null || _b === void 0 ? void 0 : _b.children[3]) || '';
89
+ }
90
+ return defaultTableSortMethod(a.toLowerCase(), b.toLowerCase());
91
+ },
92
+ },
93
+ {
94
+ id: 'customer-account-number',
95
+ title: t('Account number'),
96
+ sortable: false,
97
+ cellWidth: 20,
98
+ cell: (data) => data.accountNum,
99
+ },
100
+ {
101
+ id: 'customer-partnership-access-level',
102
+ title: t('Access level'),
103
+ sortable: false,
104
+ cellWidth: 30,
105
+ cell: (data) => data.partnerCaseAccess,
106
+ },
107
+ {
108
+ id: 'partnership-delete',
109
+ title: ' ',
110
+ sortable: false,
111
+ cellWidth: 10,
112
+ cell: (data) => (React.createElement(Button, { variant: ButtonVariant.plain, "aria-label": t('Remove partnership'), onClick: () => removePartnership(data) },
113
+ React.createElement(LoadingIndicator, { isInline: true, show: isDeleting && data.accountNum === isDeletingAccountNum, size: "xs" }),
114
+ React.createElement(TrashIcon, null))),
115
+ },
116
+ ];
117
+ const requestCollaborationButton = () => (React.createElement("div", { className: "toolbar-right pf-u-mt-xs" },
118
+ React.createElement(Button, { variant: ButtonVariant.primary, isInline: true, onClick: () => setIsRequestCollabModalOpen(true), "data-tracking-id": "request-collaboration-button", isDisabled: false },
119
+ React.createElement(Trans, null, "Request Collaboration"))));
120
+ // Get Customer Accounts For A Partner
121
+ useEffect(() => {
122
+ if (!isPartner())
123
+ return;
124
+ const getManagedAccounts = () => __awaiter(this, void 0, void 0, function* () {
125
+ try {
126
+ setIsFetching(true);
127
+ setHasError(false);
128
+ yield fetchManagedAccounts(dispatchToGlobalMetadataReducer, loggedInUserJwtToken);
129
+ }
130
+ catch (e) {
131
+ setHasError(true);
132
+ }
133
+ setIsFetching(false);
134
+ });
135
+ if (isPartner() && haventLoadedMetadata(managedAccounts, (data) => data === undefined))
136
+ getManagedAccounts();
137
+ // eslint-disable-next-line react-hooks/exhaustive-deps
138
+ }, [managedAccounts]);
139
+ //Get Partner Accounts For A Customer
140
+ useEffect(() => {
141
+ const getAccountManagers = () => __awaiter(this, void 0, void 0, function* () {
142
+ try {
143
+ setIsFetching(true);
144
+ setHasError(false);
145
+ yield fetchAccountManagers(dispatchToGlobalMetadataReducer, loggedInUserJwtToken);
146
+ setIsUpdatingAccounts(dispatch, false);
147
+ }
148
+ catch (e) {
149
+ setHasError(true);
150
+ }
151
+ setIsFetching(false);
152
+ });
153
+ // when customer accepts a link, need to fetch account data
154
+ if (isCustomerOrgAdmin() &&
155
+ (haventLoadedMetadata(accountManagers, (data) => data === undefined) || isUpdatingPartnerAccountList))
156
+ getAccountManagers();
157
+ // eslint-disable-next-line react-hooks/exhaustive-deps
158
+ }, [isUpdatingPartnerAccountList]);
159
+ useEffect(() => {
160
+ if (isPartner()) {
161
+ // partner may be customer of another partner
162
+ // we need to dispaly both partner and customer data
163
+ setAccountList([
164
+ ...managedAccounts.data.map((i) => (Object.assign(Object.assign({}, i), { isCustomerAccount: true }))),
165
+ ...accountManagers.data.map((i) => (Object.assign(Object.assign({}, i), { isPartnerAccount: true }))),
166
+ ]);
167
+ }
168
+ else if (isCustomerOrgAdmin()) {
169
+ setAccountList(accountManagers.data.map((i) => (Object.assign(Object.assign({}, i), { isPartnerAccount: true }))));
170
+ }
171
+ // eslint-disable-next-line react-hooks/exhaustive-deps
172
+ }, [managedAccounts, accountManagers]);
173
+ return (React.createElement("section", { id: "manage-partnerships-list" },
174
+ React.createElement("div", { className: "toolbar" },
175
+ React.createElement("div", { className: "toolbar-left" },
176
+ React.createElement("label", { htmlFor: "search-partnerships" }, "Filter by"),
177
+ React.createElement(SearchInput, { className: "pf-u-flex-grow-1 pf-c-search-input pf-u-background-color-100 pf-u-mr-lg", id: "search-partnerships", placeholder: t('Search for an existing partnership'), value: searchString, onChange: setSearchString, onClear: () => setSearchString(''), "aria-label": t('Search for an existing partnership') })),
178
+ isPartner() && requestCollaborationButton()),
179
+ React.createElement(ManageTable, { ariaLabel: t('Partnerships list'), columns: columns, data: accountList.filter((account) => account.name.toLowerCase().includes(searchString.toLowerCase())), sortInfo: { column: 'customer-account-name', direction: 'asc' }, errorVariant: AlertVariant.warning, isFetching: isFetching, isError: hasError, errorTitle: t('Partnerships error'), errorComponent: React.createElement(Trans, null, "Could not get partnerships list"), noResultText: t('There are no results to display.') }),
180
+ React.createElement(RequestCollaborationModal, { isOpen: isRequestCollabModalOpen, onClose: () => {
181
+ setIsRequestCollabModalOpen(false);
182
+ } })));
183
+ }
@@ -0,0 +1,2 @@
1
+ export declare const PartnershipsTermsModal: () => JSX.Element;
2
+ //# sourceMappingURL=PartnershipsTermsModal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PartnershipsTermsModal.d.ts","sourceRoot":"","sources":["../../../../src/components/ManagePartnerships/PartnershipsTermsModal.tsx"],"names":[],"mappings":"AAsBA,eAAO,MAAM,sBAAsB,mBAkLlC,CAAC"}
@@ -0,0 +1,97 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { pcm } from '@cee-eng/hydrajs';
11
+ import { Button, ButtonVariant, Checkbox, Modal, ModalVariant, Text, TextContent, TextVariants, } from '@patternfly/react-core';
12
+ import { LoadingDots, ToastNotification } from '@rh-support/components';
13
+ import React, { useEffect, useState } from 'react';
14
+ import { Trans, useTranslation } from 'react-i18next';
15
+ import { useParams } from 'react-router-dom';
16
+ import { useManagePartnershipsDispatchContext } from '../../context/ManagePartnershipsProvider';
17
+ import { setIsUpdatingAccounts } from '../../reducers/ManagePartnershipsReducer';
18
+ export const PartnershipsTermsModal = () => {
19
+ const [isContinueClicked, setIsContinueClicked] = useState(false);
20
+ const [isTermsChecked, setIsTermsChecked] = useState(false);
21
+ const [isUpdating, setIsUpdating] = useState(false);
22
+ const [ackChoice, setAckChoice] = useState('');
23
+ const [isTermsModalOpen, setIsTermsModalOpen] = useState(true);
24
+ const [isVerifyingLink, setIsVerifyingLink] = useState(false);
25
+ const [linkAccountName, setLinkAccountName] = useState('');
26
+ const [verificationFailMessage, setVerificationFailMessage] = useState('');
27
+ const dispatch = useManagePartnershipsDispatchContext();
28
+ const onContinue = () => setIsContinueClicked(true);
29
+ const { t } = useTranslation();
30
+ const { linkHash } = useParams();
31
+ const onClose = () => {
32
+ setIsTermsModalOpen(false);
33
+ setIsContinueClicked(false);
34
+ setIsTermsChecked(false);
35
+ setAckChoice('');
36
+ setIsVerifyingLink(false);
37
+ setVerificationFailMessage('');
38
+ };
39
+ const termAck = (ackResponse) => __awaiter(void 0, void 0, void 0, function* () {
40
+ setIsUpdating(true);
41
+ setAckChoice(ackResponse);
42
+ try {
43
+ yield pcm.partnerships.partnerLinkAckResponse(linkHash, ackResponse);
44
+ setIsUpdating(false);
45
+ setIsUpdatingAccounts(dispatch, true);
46
+ }
47
+ catch (e) {
48
+ ToastNotification.addDangerMessage(ackResponse === 'accept' ? t('Failed to add partnership.') : t('Failed to decline partnership.'), React.createElement(Button, { variant: ButtonVariant.link, isInline: true, onClick: () => setIsTermsModalOpen(true) },
49
+ React.createElement(Trans, null, "Try again")));
50
+ setIsUpdating(false);
51
+ }
52
+ onClose();
53
+ });
54
+ const termAgrement = () => (React.createElement(React.Fragment, null,
55
+ React.createElement("h2", null, "Lorem Ipsum"),
56
+ React.createElement("p", null, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."),
57
+ React.createElement("p", null, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."),
58
+ React.createElement("p", null, "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."),
59
+ React.createElement(Checkbox, { className: "pf-u-mt-md", label: "I have read and agree to the terms", isChecked: isTermsChecked, onChange: () => setIsTermsChecked(!isTermsChecked), id: "terms-and-conditions-checkbox" })));
60
+ useEffect(() => {
61
+ const verifyLink = () => __awaiter(void 0, void 0, void 0, function* () {
62
+ try {
63
+ setIsVerifyingLink(true);
64
+ setVerificationFailMessage('');
65
+ const response = yield pcm.partnerships.verifyPartnerLink(linkHash);
66
+ setLinkAccountName(response.accountName);
67
+ setIsVerifyingLink(false);
68
+ }
69
+ catch (error) {
70
+ const errorCode = parseInt((error === null || error === void 0 ? void 0 : error.code) || (error === null || error === void 0 ? void 0 : error.status)) || '';
71
+ const errorMessage = errorCode === 400 ? (React.createElement(Trans, null, "You are not authorized to accept or reject partner link.")) : errorCode === 404 ? (React.createElement(Trans, null, "Partner link is invalid. The link has been used or expired.")) : (React.createElement(Trans, null, "There was a problem and partner link cannot be verified at this moment. Please try again later."));
72
+ setVerificationFailMessage(errorMessage);
73
+ }
74
+ });
75
+ verifyLink();
76
+ }, [linkHash]);
77
+ return (React.createElement(Modal, { id: "partnership-terms-and-conditions-modal", className: "pf-modal-overflow-visible", title: 'Confirm partnership collaboration', isOpen: isTermsModalOpen, onClose: onClose, showClose: true, onEscapePress: onClose, variant: ModalVariant.large, actions: [
78
+ ...(!isContinueClicked
79
+ ? [
80
+ React.createElement(Button, { key: "continue", variant: ButtonVariant.primary, onClick: onContinue, isDisabled: isVerifyingLink },
81
+ React.createElement(Trans, null, "Continue")),
82
+ ]
83
+ : [
84
+ React.createElement(Button, { key: "back-to-prev", variant: ButtonVariant.primary, onClick: () => setIsContinueClicked(false) },
85
+ React.createElement(Trans, null, "Back")),
86
+ React.createElement(Button, { key: "acccept-partnership", variant: ButtonVariant.primary, isDisabled: !isTermsChecked || isUpdating, onClick: () => termAck('accept'), isLoading: isUpdating && ackChoice === 'accept' },
87
+ React.createElement(Trans, null, "Accept")),
88
+ React.createElement(Button, { key: "reject-partnership", variant: ButtonVariant.danger, onClick: () => termAck('decline'), isDisabled: isUpdating, isLoading: isUpdating && ackChoice === 'decline' },
89
+ React.createElement(Trans, null, "Decline")),
90
+ ]),
91
+ ] },
92
+ React.createElement(React.Fragment, null, !isContinueClicked && isVerifyingLink ? (React.createElement(React.Fragment, null, verificationFailMessage ? (React.createElement("p", { className: "pf-u-mt-xs pf-u-danger-color-100" }, verificationFailMessage)) : (React.createElement("p", { className: "pf-u-mt-xs" },
93
+ React.createElement(LoadingDots, { show: true, message: t('Verifying partner link') }))))) : !isContinueClicked && !isVerifyingLink ? (React.createElement(React.Fragment, null,
94
+ React.createElement("p", null, "A partner would like to collaborate on your company's technical support cases in concert with Red Hat support engineers. Please accept the request with the enclosed URL."),
95
+ React.createElement(TextContent, { className: "pf-u-mt-lg" },
96
+ React.createElement(Text, { component: TextVariants.h3 }, linkAccountName)))) : (termAgrement()))));
97
+ };
@@ -0,0 +1,3 @@
1
+ export declare const daysFromNow: (date: string) => number;
2
+ export declare function PendingRequests(): JSX.Element;
3
+ //# sourceMappingURL=PendingRequests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PendingRequests.d.ts","sourceRoot":"","sources":["../../../../src/components/ManagePartnerships/PendingRequests.tsx"],"names":[],"mappings":"AA0BA,eAAO,MAAM,WAAW,SAAU,MAAM,WAMvC,CAAC;AACF,wBAAgB,eAAe,gBAsO9B"}