@rh-support/manage 0.2.23 → 0.2.24

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":"ManageTabs.d.ts","sourceRoot":"","sources":["../../src/ManageTabs.tsx"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAqBvD,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC;CACvC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,eAwIvC"}
1
+ {"version":3,"file":"ManageTabs.d.ts","sourceRoot":"","sources":["../../src/ManageTabs.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAsBvD,UAAU,MAAM;IACZ,UAAU,EAAE,mBAAmB,CAAC,EAAE,CAAC,CAAC;CACvC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,eAgKvC"}
@@ -1,9 +1,10 @@
1
1
  import { ErrorBoundary, useDocumentTitle } from '@rh-support/components';
2
2
  import { GlobalMetadataStateContext } from '@rh-support/react-context';
3
3
  import { ability, CaseDetailsFields, resourceActions, resources } from '@rh-support/user-permissions';
4
- import { CustomElements, getConfigField, PCM_CONFIG_FIELD_TYPE, requireCustomElement } from '@rh-support/utils';
4
+ import { CustomElements, getConfigField, getFieldInParts, PCM_CONFIG_FIELD_TYPE, requireCustomElement, } from '@rh-support/utils';
5
5
  import map from 'lodash/map';
6
6
  import React, { useContext } from 'react';
7
+ import { ConfigsTable } from './components/Configs/ConfigsTable';
7
8
  import { ManageGroupUsers } from './components/Groups/ManageGroupUsers';
8
9
  import { ManageBookmarkedAccountsTab, ManageGroupedBookmarkedAccountsTab, } from './components/ManageBookmarkedAccountsTab';
9
10
  import { ManagePreferences } from './components/ManagePreferences';
@@ -21,10 +22,11 @@ requireCustomElement([
21
22
  export function ManageTabs(props) {
22
23
  var _a, _b;
23
24
  const history = props.routeProps.history;
24
- const { groupsRoute, bookmarkedAccountsRoute, topContentRoute, notificationEmailsRoute, preferencesRoute } = Routes.getPaths();
25
- const { globalMetadataState: { pcmConfig }, } = useContext(GlobalMetadataStateContext);
25
+ const { groupsRoute, bookmarkedAccountsRoute, topContentRoute, notificationEmailsRoute, preferencesRoute, configsRoute, } = Routes.getPaths();
26
+ const { globalMetadataState: { pcmConfig, loggedInUserRights }, } = useContext(GlobalMetadataStateContext);
26
27
  const isGroupBookmarkEnabled = getConfigField(pcmConfig.data, 'isGroupBookmarkEnabled', PCM_CONFIG_FIELD_TYPE.FEATURE_FLAG);
27
28
  const isPreferencesPageEnabled = getConfigField(pcmConfig.data, 'allowPreferencesPage', PCM_CONFIG_FIELD_TYPE.FEATURE_FLAG);
29
+ const pcmConfigEditorsSSOList = getFieldInParts(pcmConfig.data, 'pcmConfigEditorsSSO', PCM_CONFIG_FIELD_TYPE.STRING_COMMA_SEPERATED);
28
30
  // Changes route and saves the current path to the url query params
29
31
  const isOnlyBasePath = history.location.pathname === Routes.basePath;
30
32
  useDocumentTitle(PageTitle.MANAGE);
@@ -38,6 +40,7 @@ export function ManageTabs(props) {
38
40
  const canManageBookmarkAccounts = ability.can(resourceActions.CREATE, resources.BOOKMARK_ACCOUNTS) && canViewManageTab;
39
41
  const canViewEmailNotificationTab = ability.can(resourceActions.READ, resources.NOTIFICATION_EMAIL);
40
42
  const canAddCustomNotification = ability.can(resourceActions.PATCH, resources.CASE_DETAILS, CaseDetailsFields.CASE_DETAILS_SEND_NOTIFICATIONS);
43
+ const canViewConfigs = pcmConfigEditorsSSOList.includes(loggedInUserRights.data.getSSOUsername());
41
44
  const tabsToRender = [];
42
45
  canManageBookmarkAccounts &&
43
46
  tabsToRender.push({
@@ -95,6 +98,17 @@ export function ManageTabs(props) {
95
98
  },
96
99
  component: React.createElement(TopContentManagement, null),
97
100
  });
101
+ canViewConfigs &&
102
+ tabsToRender.push({
103
+ title: 'Internal Configs',
104
+ key: 'pcm-internal-configs-tab',
105
+ 'data-tracking-id': 'pcm-config-admin-tab',
106
+ routePath: configsRoute,
107
+ onClick: () => {
108
+ changeRouteThunk(configsRoute);
109
+ },
110
+ component: React.createElement(ConfigsTable, null),
111
+ });
98
112
  /**
99
113
  * Render without tabs if there is only one element
100
114
  */
@@ -15,6 +15,7 @@ interface ManageRoutes {
15
15
  topContent: Route;
16
16
  preferences: Route;
17
17
  notificationEmails: Route;
18
+ configs: Route;
18
19
  }
19
20
  export declare const Routes: ManageRoutes;
20
21
  export {};
@@ -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;CAC7B;AAED,eAAO,MAAM,MAAM,EAAE,YA8DpB,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,kBAAkB,EAAE,KAAK,CAAC;IAC1B,OAAO,EAAE,KAAK,CAAC;CAClB;AAED,eAAO,MAAM,MAAM,EAAE,YAmEpB,CAAC"}
package/lib/esm/Routes.js CHANGED
@@ -42,6 +42,12 @@ export const Routes = {
42
42
  return getPath(this);
43
43
  },
44
44
  },
45
+ configs: {
46
+ path: '/configs',
47
+ getPath() {
48
+ return getPath(this);
49
+ },
50
+ },
45
51
  getPaths() {
46
52
  return Object.keys(this).reduce((accumulator, key) => {
47
53
  if (this[key].path) {
@@ -0,0 +1,10 @@
1
+ interface IProps {
2
+ id: number;
3
+ onSave: (fieldName: string, fieldValue: string, id: number) => void;
4
+ isUpdating: boolean;
5
+ fieldName: string;
6
+ fieldValue: string;
7
+ }
8
+ export declare function ConfigInLineEdit(props: IProps): JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=ConfigInLineEdit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigInLineEdit.d.ts","sourceRoot":"","sources":["../../../../src/components/Configs/ConfigInLineEdit.tsx"],"names":[],"mappings":"AAKA,UAAU,MAAM;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACpE,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,eAqD7C"}
@@ -0,0 +1,40 @@
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 { InlineEdit, LoadingIndicator, TextAreaAutosize } from '@rh-support/components';
11
+ import React, { useEffect, useState } from 'react';
12
+ import { CONFIG_FIELD_VALUE_LIMIT } from '../../constants/Configs';
13
+ export function ConfigInLineEdit(props) {
14
+ const [input, setInput] = useState(props.fieldValue);
15
+ const [hasLargeInput, setHasLargeInput] = useState(false);
16
+ const onSave = () => __awaiter(this, void 0, void 0, function* () {
17
+ props.onSave(props.fieldName, input, props.id);
18
+ });
19
+ const onCancel = () => {
20
+ setInput(props.fieldValue);
21
+ };
22
+ const onChange = (e) => {
23
+ var _a, _b;
24
+ const inputValue = (_b = (_a = e.target.value) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
25
+ setHasLargeInput(inputValue.length > CONFIG_FIELD_VALUE_LIMIT);
26
+ setInput(inputValue);
27
+ };
28
+ // when user filter search result if the textarea is open, need to update the internal state
29
+ // otherwise it shows wrong content
30
+ useEffect(() => {
31
+ setInput(props.fieldValue);
32
+ }, [props.fieldValue]);
33
+ return (React.createElement(React.Fragment, null,
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 }),
36
+ hasLargeInput && (React.createElement("p", { className: "form-instructions form-invalid" },
37
+ "Config value cannot be more than ",
38
+ CONFIG_FIELD_VALUE_LIMIT,
39
+ " characters")))));
40
+ }
@@ -0,0 +1,10 @@
1
+ interface IProps {
2
+ id: number;
3
+ onChange: (fieldName: string, fieldValue: string, id: number) => void;
4
+ isChecked: boolean;
5
+ isUpdating: boolean;
6
+ fieldName: string;
7
+ }
8
+ export declare function ConfigSwitch(props: IProps): JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=ConfigSwitch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigSwitch.d.ts","sourceRoot":"","sources":["../../../../src/components/Configs/ConfigSwitch.tsx"],"names":[],"mappings":"AAIA,UAAU,MAAM;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtE,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,eAiBzC"}
@@ -0,0 +1,20 @@
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 { Switch } from '@patternfly/react-core';
11
+ import { LoadingIndicator } from '@rh-support/components';
12
+ import React from 'react';
13
+ export function ConfigSwitch(props) {
14
+ const onSwitchChange = (isChecked) => __awaiter(this, void 0, void 0, function* () {
15
+ props.onChange(props.fieldName, isChecked ? '1' : '0', props.id);
16
+ });
17
+ return (React.createElement(React.Fragment, null,
18
+ React.createElement(Switch, { id: `${props.id}`, isChecked: props.isChecked, onChange: onSwitchChange, isDisabled: props.isUpdating, "aria-label": props.fieldName }),
19
+ props.isUpdating && React.createElement(LoadingIndicator, { isInline: true })));
20
+ }
@@ -0,0 +1,2 @@
1
+ export declare const ConfigsTable: () => JSX.Element;
2
+ //# sourceMappingURL=ConfigsTable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigsTable.d.ts","sourceRoot":"","sources":["../../../../src/components/Configs/ConfigsTable.tsx"],"names":[],"mappings":"AAaA,eAAO,MAAM,YAAY,mBAyJxB,CAAC"}
@@ -0,0 +1,124 @@
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 { configuration, maintenance } from '@cee-eng/hydrajs';
11
+ import { SearchInput } from '@patternfly/react-core';
12
+ import { defaultTableSortMethod, ErrorBoundary, ToastNotification, useFetch } from '@rh-support/components/';
13
+ import { formatDate } from '@rh-support/utils';
14
+ import isEmpty from 'lodash/isEmpty';
15
+ import React, { useEffect, useState } from 'react';
16
+ import { Trans } from 'react-i18next';
17
+ import { ManageTable } from '../ManageTable/ManageTable';
18
+ import { ConfigInLineEdit } from './ConfigInLineEdit';
19
+ import { ConfigSwitch } from './ConfigSwitch';
20
+ export const ConfigsTable = () => {
21
+ const [configValues, setConfigValues] = useState([]);
22
+ const [filteredValues, setFilteredValues] = useState([]);
23
+ const [searchString, setSearchString] = useState('');
24
+ const [keepPageNumberOnDataChange, setKeepPageNumberOnDataChange] = useState(undefined);
25
+ const { request: getConfigs, isFetching } = useFetch(configuration.getConfig);
26
+ const { request: updateConfig, isFetching: isUpdating } = useFetch(maintenance.updateHydraConfiguration, {
27
+ propgateErrors: true,
28
+ });
29
+ const configType = "pcm_configurations" /* pcm_configurations */;
30
+ const onSearchChange = (str) => {
31
+ setKeepPageNumberOnDataChange(false);
32
+ setSearchString(str);
33
+ };
34
+ const onUpdate = (fieldName, fieldValue, id) => __awaiter(void 0, void 0, void 0, function* () {
35
+ try {
36
+ yield updateConfig({
37
+ id,
38
+ type: configType,
39
+ fieldName,
40
+ fieldValue,
41
+ });
42
+ ToastNotification.addSuccessMessage('Successfully updated config');
43
+ const updatedData = configValues.map((config) => {
44
+ if (config.id === id) {
45
+ return Object.assign(Object.assign({}, config), { fieldValue });
46
+ }
47
+ return config;
48
+ });
49
+ setKeepPageNumberOnDataChange(true);
50
+ setConfigValues(updatedData);
51
+ }
52
+ catch (e) {
53
+ ToastNotification.addDangerMessage('Failed to update config');
54
+ }
55
+ });
56
+ const columns = [
57
+ {
58
+ accessor: (data) => data.fieldName,
59
+ id: 'config-name',
60
+ title: 'Configuration',
61
+ cellWidth: 20,
62
+ sortable: true,
63
+ sortMethod: (a, b) => {
64
+ const aname = a.toLowerCase();
65
+ const bname = b.toLowerCase();
66
+ return defaultTableSortMethod(aname, bname);
67
+ },
68
+ },
69
+ {
70
+ cell: (data) => () => {
71
+ const value = data.fieldValue;
72
+ const name = data.fieldName;
73
+ if (value === '0' || value === '1') {
74
+ return (React.createElement(ConfigSwitch, { id: data.id, isChecked: value === '1' ? true : false, onChange: onUpdate, isUpdating: isUpdating, fieldName: name }));
75
+ }
76
+ else {
77
+ return (React.createElement(ConfigInLineEdit, { id: data.id, onSave: onUpdate, isUpdating: isUpdating, fieldName: name, fieldValue: value }));
78
+ }
79
+ },
80
+ id: 'config-value',
81
+ title: 'Value',
82
+ },
83
+ {
84
+ accessor: (data) => formatDate(data.createdDate),
85
+ id: 'created-date',
86
+ title: 'Created Date',
87
+ cellWidth: 15,
88
+ sortable: true,
89
+ sortMethod: (a, b) => {
90
+ const aDate = new Date(a);
91
+ const bDate = new Date(b);
92
+ return defaultTableSortMethod(aDate, bDate);
93
+ },
94
+ },
95
+ ];
96
+ useEffect(() => {
97
+ const loadConfig = () => __awaiter(void 0, void 0, void 0, function* () {
98
+ const data = yield getConfigs(configType);
99
+ setConfigValues(data);
100
+ setFilteredValues(data);
101
+ });
102
+ loadConfig();
103
+ // eslint-disable-next-line react-hooks/exhaustive-deps
104
+ }, [configType]);
105
+ useEffect(() => {
106
+ if (!isEmpty(searchString)) {
107
+ const filteredValues = configValues.filter((c) => c.fieldName.toLowerCase().includes(searchString.toLowerCase()));
108
+ setFilteredValues(filteredValues);
109
+ }
110
+ else {
111
+ setFilteredValues(configValues);
112
+ }
113
+ }, [searchString, configValues]);
114
+ return (React.createElement("section", { id: "notification-emails" },
115
+ React.createElement("header", null,
116
+ React.createElement("h2", null, "Internal app configs"),
117
+ "Edit app configs that used as flags or other settings here."),
118
+ React.createElement("div", { className: "toolbar" },
119
+ React.createElement("div", { className: "toolbar-right" },
120
+ React.createElement("label", { htmlFor: "search-config-filelds" }, "Filter by"),
121
+ React.createElement(SearchInput, { className: "pf-u-flex-grow-1 pf-c-search-input pf-u-background-color-100", id: "search-config-filelds", placeholder: "Search for an existing config name", value: searchString, onChange: onSearchChange, onClear: () => onSearchChange(''), "aria-label": "Search for an existing config name" }))),
122
+ React.createElement(ErrorBoundary, { errorMsgInfo: { message: 'There was an error loading config page' } },
123
+ React.createElement(ManageTable, { sortInfo: { column: 'created-date', direction: 'desc' }, ariaLabel: 'Table to manage pcm config', columns: columns, data: filteredValues, isFetching: isFetching, isError: false, errorTitle: 'Config table error', errorComponent: React.createElement(Trans, null, "Could not get configs"), keepPageNumberOnDataChange: keepPageNumberOnDataChange }))));
124
+ };
@@ -0,0 +1,2 @@
1
+ export * from './ConfigsTable';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/Configs/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ export * from './ConfigsTable';
@@ -0,0 +1,3 @@
1
+ export declare const CONFIG_FIELD_VALUE_LIMIT = 1024;
2
+ export declare const CONFIG_FIELD_NAME_LIMIT = 100;
3
+ //# sourceMappingURL=Configs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Configs.d.ts","sourceRoot":"","sources":["../../../src/constants/Configs.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,uBAAuB,MAAM,CAAC"}
@@ -0,0 +1,2 @@
1
+ export const CONFIG_FIELD_VALUE_LIMIT = 1024;
2
+ export const CONFIG_FIELD_NAME_LIMIT = 100;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rh-support/manage",
3
- "version": "0.2.23",
3
+ "version": "0.2.24",
4
4
  "description": "Customer Support Manage App",
5
5
  "author": "Jordan Eudy <jeudy100@gmail.com>",
6
6
  "homepage": "",
@@ -96,13 +96,13 @@
96
96
  "@patternfly/pfe-tabs": "1.1.0",
97
97
  "@patternfly/react-core": "4.128.2",
98
98
  "@patternfly/react-table": "4.26.7",
99
- "@rh-support/api": "0.3.8",
100
- "@rh-support/components": "1.1.15",
101
- "@rh-support/configs": "0.2.2",
102
- "@rh-support/react-context": "0.2.17",
99
+ "@rh-support/api": "0.3.9",
100
+ "@rh-support/components": "1.1.16",
101
+ "@rh-support/configs": "0.2.3",
102
+ "@rh-support/react-context": "0.2.18",
103
103
  "@rh-support/types": "0.2.0",
104
- "@rh-support/user-permissions": "0.2.11",
105
- "@rh-support/utils": "0.2.11",
104
+ "@rh-support/user-permissions": "0.2.12",
105
+ "@rh-support/utils": "0.2.12",
106
106
  "@types/react-beautiful-dnd": "^13.0.0",
107
107
  "i18next": ">=17.0.1",
108
108
  "lodash": ">=4.17.15",
@@ -113,5 +113,5 @@
113
113
  "react-i18next": ">=10.11.0",
114
114
  "react-router-dom": ">=5.1.2"
115
115
  },
116
- "gitHead": "3dc034eff74761ebe67f6503a13ecf5a1d763071"
116
+ "gitHead": "52e20f580e4e077ecc84a1e40f8474795e013459"
117
117
  }