@rh-support/manage 2.1.94 → 2.1.96
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.
- package/lib/esm/ManageTabs.d.ts.map +1 -1
- package/lib/esm/ManageTabs.js +11 -1
- package/lib/esm/Routes.d.ts +1 -0
- package/lib/esm/Routes.d.ts.map +1 -1
- package/lib/esm/Routes.js +6 -0
- package/lib/esm/components/ManageBookmarkedAccountsTab/BookmarkAccountSelector.d.ts.map +1 -1
- package/lib/esm/components/ManageBookmarkedAccountsTab/BookmarkAccountSelector.js +6 -1
- package/lib/esm/components/ManageExpiredContents/ExpiredContentCategory.d.ts +9 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentCategory.d.ts.map +1 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentCategory.js +18 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentHeader.d.ts +3 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentHeader.d.ts.map +1 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentHeader.js +9 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentManagement.d.ts +3 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentManagement.d.ts.map +1 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentManagement.js +13 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentManager.d.ts +3 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentManager.d.ts.map +1 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentManager.js +70 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentSingleItem.d.ts +9 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentSingleItem.d.ts.map +1 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentSingleItem.js +77 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentSingleItemView.d.ts +14 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentSingleItemView.d.ts.map +1 -0
- package/lib/esm/components/ManageExpiredContents/ExpiredContentSingleItemView.js +141 -0
- package/lib/esm/components/ManageExpiredContents/index.d.ts +2 -0
- package/lib/esm/components/ManageExpiredContents/index.d.ts.map +1 -0
- package/lib/esm/components/ManageExpiredContents/index.js +1 -0
- package/lib/esm/components/ManageTags/TagsManager.d.ts.map +1 -1
- package/lib/esm/components/ManageTags/TagsManager.js +20 -7
- package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentCategoryContent/TopContentSingleItem.d.ts +2 -0
- package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentCategoryContent/TopContentSingleItem.d.ts.map +1 -1
- package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentCategoryContent/TopContentSingleItem.js +75 -20
- package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentEditor.d.ts.map +1 -1
- package/lib/esm/components/TopContentManagement/TopContentEditor/TopContentEditor.js +7 -5
- package/lib/esm/context/ExpiredContentContextProvider.d.ts +8 -0
- package/lib/esm/context/ExpiredContentContextProvider.d.ts.map +1 -0
- package/lib/esm/context/ExpiredContentContextProvider.js +10 -0
- package/lib/esm/context/TopContentProvider.d.ts.map +1 -1
- package/lib/esm/context/TopContentProvider.js +1 -0
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +1 -0
- package/lib/esm/reducers/ExpiredContentReducer.d.ts +35 -0
- package/lib/esm/reducers/ExpiredContentReducer.d.ts.map +1 -0
- package/lib/esm/reducers/ExpiredContentReducer.js +190 -0
- package/lib/esm/reducers/TopContentReducer.d.ts +5 -1
- package/lib/esm/reducers/TopContentReducer.d.ts.map +1 -1
- package/lib/esm/reducers/TopContentReducer.js +23 -7
- package/package.json +8 -8
|
@@ -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;
|
|
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,qBAqMvC"}
|
package/lib/esm/ManageTabs.js
CHANGED
|
@@ -8,6 +8,7 @@ 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 { ExpiredContentManagement } from './components/ManageExpiredContents/ExpiredContentManagement';
|
|
11
12
|
import { ManagePartnerships } from './components/ManagePartnerships/index';
|
|
12
13
|
import { ManagePreferences } from './components/ManagePreferences';
|
|
13
14
|
import { TagsManagement } from './components/ManageTags';
|
|
@@ -20,7 +21,7 @@ export function ManageTabs(props) {
|
|
|
20
21
|
const [activeTabKey, setActiveTabKey] = useState(0);
|
|
21
22
|
const { activeTab } = useParams();
|
|
22
23
|
const { t } = useTranslation();
|
|
23
|
-
const { groupsRoute, bookmarkedAccountsRoute, topContentRoute, notificationEmailsRoute, preferencesRoute, configsRoute, partnershipsRoute, tagsManagerRoute, } = Routes.getPaths();
|
|
24
|
+
const { groupsRoute, bookmarkedAccountsRoute, topContentRoute, notificationEmailsRoute, preferencesRoute, configsRoute, partnershipsRoute, tagsManagerRoute, expiredContentRoute, } = Routes.getPaths();
|
|
24
25
|
useDocumentTitle(PageTitle.MANAGE);
|
|
25
26
|
const canViewManageTab = ability.can(resourceActions.READ, resources.MANAGE);
|
|
26
27
|
const canViewManageTopContent = ability.can(resourceActions.READ, resources.TOP_CONTENT) && canViewManageTab;
|
|
@@ -85,6 +86,15 @@ export function ManageTabs(props) {
|
|
|
85
86
|
component: React.createElement(TopContentManagement, null),
|
|
86
87
|
id: 'manage-top-content',
|
|
87
88
|
});
|
|
89
|
+
canViewManageTopContent &&
|
|
90
|
+
tabsToRender.push({
|
|
91
|
+
title: 'Expired Content',
|
|
92
|
+
key: 'expired-content-tab',
|
|
93
|
+
'data-tracking-id': 'manage-expired-content-tab',
|
|
94
|
+
routePath: expiredContentRoute,
|
|
95
|
+
id: 'manage-expired-content',
|
|
96
|
+
component: React.createElement(ExpiredContentManagement, null),
|
|
97
|
+
});
|
|
88
98
|
canViewManageTopContent &&
|
|
89
99
|
tabsToRender.push({
|
|
90
100
|
title: 'Tags Manager',
|
package/lib/esm/Routes.d.ts
CHANGED
package/lib/esm/Routes.d.ts.map
CHANGED
|
@@ -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,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,
|
|
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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BookmarkAccountSelector.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageBookmarkedAccountsTab/BookmarkAccountSelector.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAIhF,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"BookmarkAccountSelector.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageBookmarkedAccountsTab/BookmarkAccountSelector.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAIhF,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAQtD,OAAO,KAAsC,MAAM,OAAO,CAAC;AAG3D,UAAU,MAAM;IACZ,uBAAuB,EAAE,SAAS,EAAE,CAAC;IACrC,iBAAiB,CAAC,EAAE,kBAAkB,CAAC;IACvC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yBAAyB,CAAC,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,qBA6PpD;yBA7Pe,uBAAuB"}
|
|
@@ -11,6 +11,7 @@ import { accounts } from '@cee-eng/hydrajs';
|
|
|
11
11
|
import { Label, LabelGroup, Tooltip } from '@patternfly/react-core';
|
|
12
12
|
import { Select, SelectOption, SelectVariant } from '@patternfly/react-core/deprecated';
|
|
13
13
|
import InfoCircleIcon from '@patternfly/react-icons/dist/js/icons/info-circle-icon';
|
|
14
|
+
import { sortAccountsByQuery } from '@rh-support/react-context/src/utils/utils';
|
|
14
15
|
import assign from 'lodash/assign';
|
|
15
16
|
import compact from 'lodash/compact';
|
|
16
17
|
import debounce from 'lodash/debounce';
|
|
@@ -41,12 +42,15 @@ export function BookmarkAccountSelector(props) {
|
|
|
41
42
|
limit: 60,
|
|
42
43
|
accountNumberNotNull: true,
|
|
43
44
|
};
|
|
45
|
+
let queryKey;
|
|
44
46
|
// query as number is a hack to get around TS, isNaN can take a string but it was throwing error here
|
|
45
47
|
if (isNaN(query)) {
|
|
46
48
|
params.nameLike = query;
|
|
49
|
+
queryKey = 'name';
|
|
47
50
|
}
|
|
48
51
|
else {
|
|
49
52
|
params.accountNumberLike = query;
|
|
53
|
+
queryKey = 'accountNumber';
|
|
50
54
|
}
|
|
51
55
|
const queryParams = !isEmpty(props.accountListParams)
|
|
52
56
|
? assign({}, props.accountListParams, params)
|
|
@@ -67,7 +71,8 @@ export function BookmarkAccountSelector(props) {
|
|
|
67
71
|
return bookmarksMatch.length > 0
|
|
68
72
|
? Object.assign(Object.assign({}, account), { bookmarkGroupName: acountGroups, isBookmarked: true, isBookmarkedAndHasGroup: acountGroups.length > 0 }) : Object.assign(Object.assign({}, account), { bookmarkGroupName: [], isBookmarked: false, isBookmarkedAndHasGroup: false });
|
|
69
73
|
});
|
|
70
|
-
|
|
74
|
+
const sortedOptions = sortAccountsByQuery(accountsResponse, query, queryKey);
|
|
75
|
+
setOptions(sortedOptions);
|
|
71
76
|
setIsSearching(false);
|
|
72
77
|
}
|
|
73
78
|
catch (err) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { IExpiredContentEditState } from '../../reducers/ExpiredContentReducer';
|
|
3
|
+
interface IProps {
|
|
4
|
+
category: IExpiredContentEditState;
|
|
5
|
+
isCategoryExpanded?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export default function ExpiredContentCategory({ category, isCategoryExpanded }: IProps): React.JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=ExpiredContentCategory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpiredContentCategory.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageExpiredContents/ExpiredContentCategory.tsx"],"names":[],"mappings":"AACA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAGhF,UAAU,MAAM;IACZ,QAAQ,EAAE,wBAAwB,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAAE,QAAQ,EAAE,kBAA0B,EAAE,EAAE,MAAM,qBA0B9F"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AccordionContent, AccordionItem, AccordionToggle } from '@patternfly/react-core';
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
import ExpiredContentSingleItem from './ExpiredContentSingleItem';
|
|
4
|
+
export default function ExpiredContentCategory({ category, isCategoryExpanded = false }) {
|
|
5
|
+
const [isExpanded, setIsExpanded] = useState(isCategoryExpanded);
|
|
6
|
+
const toggleExpanded = () => {
|
|
7
|
+
setIsExpanded((pre) => !pre);
|
|
8
|
+
};
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
isCategoryExpanded !== isExpanded && setIsExpanded(isCategoryExpanded);
|
|
11
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12
|
+
}, [isCategoryExpanded]);
|
|
13
|
+
return (React.createElement(AccordionItem, null,
|
|
14
|
+
React.createElement(AccordionToggle, { id: category.categoryName, onClick: toggleExpanded, isExpanded: isExpanded },
|
|
15
|
+
React.createElement("h3", null, category.categoryName)),
|
|
16
|
+
React.createElement(AccordionContent, { isHidden: !isExpanded },
|
|
17
|
+
React.createElement("ul", { className: "list-flat list-flushleft" }, category.content.map((content, i) => (React.createElement(ExpiredContentSingleItem, { key: content.topContentId, content: content, category: category })))))));
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpiredContentHeader.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageExpiredContents/ExpiredContentHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,CAAC,OAAO,UAAU,oBAAoB,sBAW3C"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Trans } from 'react-i18next';
|
|
3
|
+
export default function ExpiredContentHeader() {
|
|
4
|
+
return (React.createElement("header", null,
|
|
5
|
+
React.createElement("h2", null,
|
|
6
|
+
React.createElement(Trans, null, "Outdated Content")),
|
|
7
|
+
React.createElement("p", { className: "pf-v5-u-mt-md pf-v5-u-mb-sm" },
|
|
8
|
+
React.createElement(Trans, null))));
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpiredContentManagement.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageExpiredContents/ExpiredContentManagement.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,wBAAgB,wBAAwB,sBAWvC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ErrorBoundary } from '@rh-support/components';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { ExpiredContentContextProvider } from '../../context/ExpiredContentContextProvider';
|
|
5
|
+
import { TagManagementContextProvider } from '../../context/TagManagementContextProvider';
|
|
6
|
+
import ExipredContentManager from './ExpiredContentManager';
|
|
7
|
+
export function ExpiredContentManagement() {
|
|
8
|
+
const { t } = useTranslation();
|
|
9
|
+
return (React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading contents') } },
|
|
10
|
+
React.createElement(TagManagementContextProvider, null,
|
|
11
|
+
React.createElement(ExpiredContentContextProvider, null,
|
|
12
|
+
React.createElement(ExipredContentManager, null)))));
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpiredContentManager.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageExpiredContents/ExpiredContentManager.tsx"],"names":[],"mappings":"AAeA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAUhF,MAAM,CAAC,OAAO,UAAU,qBAAqB,sBAoH5C"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Accordion, Bullseye, EmptyState, EmptyStateBody, EmptyStateHeader, EmptyStateIcon, EmptyStateVariant, Spinner, Switch, } from '@patternfly/react-core';
|
|
2
|
+
import SearchIcon from '@patternfly/react-icons/dist/js/icons/search-icon';
|
|
3
|
+
import { TagsSelector, TopContentSearch } from '@rh-support/components';
|
|
4
|
+
import isEmpty from 'lodash/isEmpty';
|
|
5
|
+
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
|
+
import { Trans, useTranslation } from 'react-i18next';
|
|
7
|
+
import { ExpiredContentDispatchContext, ExpiredContentStateContext } from '../../context/ExpiredContentContextProvider';
|
|
8
|
+
import { TagManagementDispatchContext, TagManagementStateContext } from '../../context/TagManagementContextProvider';
|
|
9
|
+
import { fetchExpiredContent, setExpiredContentFilteredTags } from '../../reducers/ExpiredContentReducer';
|
|
10
|
+
import { fetchTopContentTags } from '../../reducers/TagManagmentReducer';
|
|
11
|
+
import ExpiredContentCategory from './ExpiredContentCategory';
|
|
12
|
+
import ExpiredContentHeader from './ExpiredContentHeader';
|
|
13
|
+
export default function ExipredContentManager() {
|
|
14
|
+
const expiredContentResultsRef = useRef(null);
|
|
15
|
+
const { t } = useTranslation();
|
|
16
|
+
const [showApprochingExpiry, setShowApprochingExpiry] = useState(false);
|
|
17
|
+
const { expiredContentEditState, expiredContentResponse, filteredTags } = useContext(ExpiredContentStateContext);
|
|
18
|
+
const { tags: availableTags } = useContext(TagManagementStateContext);
|
|
19
|
+
const dispatch = useContext(ExpiredContentDispatchContext);
|
|
20
|
+
const tagManagerDispatch = useContext(TagManagementDispatchContext);
|
|
21
|
+
const [contentFilteredByQuery, setContentFilteredByQuery] = useState(expiredContentEditState);
|
|
22
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
23
|
+
const onSearch = (searchTerm, searchResults) => {
|
|
24
|
+
setContentFilteredByQuery(searchResults);
|
|
25
|
+
};
|
|
26
|
+
const filteredEC = useMemo(() => {
|
|
27
|
+
if (isEmpty(filteredTags))
|
|
28
|
+
return contentFilteredByQuery;
|
|
29
|
+
const filteredTagsIds = filteredTags.map((tag) => tag.id);
|
|
30
|
+
//filter top contents on basis of tags
|
|
31
|
+
const filteredData = contentFilteredByQuery.flatMap((item) => {
|
|
32
|
+
const contents = item.content.filter((content) => (content.tags || []).some((tag) => filteredTagsIds.includes(tag.id)));
|
|
33
|
+
if (!isEmpty(contents))
|
|
34
|
+
return [Object.assign(Object.assign({}, item), { content: contents })];
|
|
35
|
+
return [];
|
|
36
|
+
});
|
|
37
|
+
return filteredData;
|
|
38
|
+
}, [contentFilteredByQuery, filteredTags]);
|
|
39
|
+
const handleChange = (_event, checked) => {
|
|
40
|
+
setShowApprochingExpiry(checked);
|
|
41
|
+
fetchExpiredContent(dispatch, checked);
|
|
42
|
+
};
|
|
43
|
+
const onTagFilterChange = (tags) => {
|
|
44
|
+
setExpiredContentFilteredTags(dispatch, tags);
|
|
45
|
+
};
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
fetchExpiredContent(dispatch);
|
|
48
|
+
fetchTopContentTags(tagManagerDispatch, false);
|
|
49
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
|
+
}, []);
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
setContentFilteredByQuery(expiredContentEditState);
|
|
53
|
+
}, [expiredContentEditState]);
|
|
54
|
+
return (React.createElement(React.Fragment, null,
|
|
55
|
+
React.createElement(ExpiredContentHeader, null),
|
|
56
|
+
React.createElement("div", { className: "toolbar" },
|
|
57
|
+
React.createElement(TopContentSearch, { dataTrackingId: "expired-content-filter-manage", topContentData: expiredContentEditState, onSearch: onSearch, topContentResultsWrapperRef: expiredContentResultsRef, className: "toolbar-content", isDisabled: expiredContentResponse.isFetching, searchQuery: searchQuery, setSearchQuery: setSearchQuery }),
|
|
58
|
+
React.createElement("div", { className: "toolbar-content pf-v5-u-ml-md" },
|
|
59
|
+
React.createElement("label", { htmlFor: 'tag-selector' },
|
|
60
|
+
React.createElement(Trans, null, "All tags")),
|
|
61
|
+
React.createElement(TagsSelector, { tagOptions: availableTags, onChange: onTagFilterChange, selectedTags: filteredTags, disabled: expiredContentResponse.isFetching })),
|
|
62
|
+
React.createElement("div", { className: "toolbar-content pf-v5-u-mt-md" },
|
|
63
|
+
React.createElement(Switch, { id: "content-approaching-expiry-", label: t('Show approaching expiry'), isChecked: showApprochingExpiry, onChange: handleChange }))),
|
|
64
|
+
React.createElement("div", { className: "expired-content-manage-wrapper pf-v5-u-pt-md", ref: expiredContentResultsRef }, expiredContentResponse.isFetching ? (React.createElement(Bullseye, null,
|
|
65
|
+
React.createElement(EmptyState, { variant: EmptyStateVariant.full },
|
|
66
|
+
React.createElement(Spinner, { size: "lg" })))) : isEmpty(filteredEC) ? (React.createElement(EmptyState, { variant: EmptyStateVariant.xs },
|
|
67
|
+
React.createElement(EmptyStateHeader, { titleText: React.createElement(Trans, null, "No contents found"), icon: React.createElement(EmptyStateIcon, { icon: SearchIcon }) }),
|
|
68
|
+
React.createElement(EmptyStateBody, null,
|
|
69
|
+
React.createElement(Trans, null, "There are no contents to display")))) : (React.createElement(Accordion, null, filteredEC.map((category, i) => (React.createElement(ExpiredContentCategory, { key: category.id, category: category, isCategoryExpanded: !isEmpty(searchQuery) || !isEmpty(filteredTags) }))))))));
|
|
70
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { IExpiredContent, IExpiredContentEditState } from '../../reducers/ExpiredContentReducer';
|
|
3
|
+
interface IProps {
|
|
4
|
+
content: IExpiredContent;
|
|
5
|
+
category: IExpiredContentEditState;
|
|
6
|
+
}
|
|
7
|
+
export default function ExpiredContentSingleItem({ content, category }: IProps): React.JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=ExpiredContentSingleItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpiredContentSingleItem.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageExpiredContents/ExpiredContentSingleItem.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA+B,MAAM,OAAO,CAAC;AAIpD,OAAO,EAEH,eAAe,EACf,wBAAwB,EAE3B,MAAM,sCAAsC,CAAC;AAG9C,UAAU,MAAM;IACZ,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,wBAAwB,CAAC;CACtC;AAED,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,qBA2G7E"}
|
|
@@ -0,0 +1,77 @@
|
|
|
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 { Button, Label } from '@patternfly/react-core';
|
|
11
|
+
import EditAltIcon from '@patternfly/react-icons/dist/js/icons/edit-alt-icon';
|
|
12
|
+
import { ToastNotification } from '@rh-support/components';
|
|
13
|
+
import { formatDate, isFutureDate } from '@rh-support/utils';
|
|
14
|
+
import React, { useContext, useState } from 'react';
|
|
15
|
+
import { useTranslation } from 'react-i18next';
|
|
16
|
+
import { ExpiredContentDispatchContext, ExpiredContentStateContext } from '../../context/ExpiredContentContextProvider';
|
|
17
|
+
import { deleteExpiredContent, updateExpiredContent, } from '../../reducers/ExpiredContentReducer';
|
|
18
|
+
import ExpiredContentSingleItemView from './ExpiredContentSingleItemView';
|
|
19
|
+
export default function ExpiredContentSingleItem({ content, category }) {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
const { t } = useTranslation();
|
|
22
|
+
const { expiredContentEditState, filteredTags } = useContext(ExpiredContentStateContext);
|
|
23
|
+
const dispatch = useContext(ExpiredContentDispatchContext);
|
|
24
|
+
const [isPreview, setIsPreview] = useState(true);
|
|
25
|
+
const [isSaving, setIsSaving] = useState(false);
|
|
26
|
+
const [isDeleting, setIsDeleting] = useState(false);
|
|
27
|
+
const editToggle = () => {
|
|
28
|
+
setIsPreview(!isPreview);
|
|
29
|
+
};
|
|
30
|
+
const onSave = (updatedContent, deletedTags) => __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
try {
|
|
32
|
+
setIsSaving(true);
|
|
33
|
+
yield updateExpiredContent(dispatch, expiredContentEditState, category.categoryId, updatedContent, deletedTags);
|
|
34
|
+
editToggle();
|
|
35
|
+
ToastNotification.addSuccessMessage(t('Content updated successfully'));
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
ToastNotification.addDangerMessage(t('There was an error updating content'));
|
|
39
|
+
}
|
|
40
|
+
finally {
|
|
41
|
+
setIsSaving(false);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
const onDelete = () => __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
try {
|
|
46
|
+
setIsDeleting(true);
|
|
47
|
+
yield deleteExpiredContent(dispatch, expiredContentEditState, category.id, content.topContentId);
|
|
48
|
+
editToggle();
|
|
49
|
+
ToastNotification.addSuccessMessage(t('Content deleted successfully'));
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
ToastNotification.addDangerMessage(t('There was an error deleting content'));
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
setIsDeleting(false);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
const lastModifiedBy = t(`Last modified {{created}} by {{by}}`, {
|
|
59
|
+
created: formatDate(content.updatedOn || content.createdOn),
|
|
60
|
+
by: content.updatedBy || content.createdBy,
|
|
61
|
+
});
|
|
62
|
+
const expiredText = t(` ${isFutureDate(content.expiryDate) ? 'Expires' : 'Expired'} on {{expired}}`, {
|
|
63
|
+
expired: formatDate(content.expiryDate),
|
|
64
|
+
});
|
|
65
|
+
return (React.createElement(React.Fragment, null, isPreview ? (React.createElement("li", { className: `push-bottom-narrow` },
|
|
66
|
+
React.createElement("a", { className: 'pcm-manage-top-content', "data-tracking-id": "pcm-manage-top-content", href: content.contentUrl, target: "_blank", rel: "noopener noreferrer" }, content.contentTitle),
|
|
67
|
+
React.createElement(Button, { variant: "link", isInline: true, icon: React.createElement(EditAltIcon, null), onClick: editToggle, title: 'Edit', "data-tracking-id": "edit-expired-top-content" }),
|
|
68
|
+
React.createElement("div", null,
|
|
69
|
+
lastModifiedBy,
|
|
70
|
+
" | ",
|
|
71
|
+
expiredText,
|
|
72
|
+
" | ",
|
|
73
|
+
content.product,
|
|
74
|
+
" ", (_a = content.majorVersion) !== null && _a !== void 0 ? _a : '',
|
|
75
|
+
content.minorVersion ? `.${content.minorVersion}` : ''),
|
|
76
|
+
React.createElement("div", null, (_b = content.tags) === null || _b === void 0 ? void 0 : _b.map((tag) => (React.createElement(Label, { isCompact: true, className: "pf-v5-u-mr-xs pf-v5-u-mt-sm", key: tag.id, color: filteredTags.some((t) => t.id === tag.id) ? 'gold' : 'grey' }, tag.tagName)))))) : (React.createElement(ExpiredContentSingleItemView, { category: category, content: content, onCancel: editToggle, onSave: onSave, onDelete: onDelete, isDeleting: isDeleting, isSaving: isSaving }))));
|
|
77
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { IExpiredContent, IExpiredContentEditState } from '../../reducers/ExpiredContentReducer';
|
|
3
|
+
interface IProps {
|
|
4
|
+
content: IExpiredContent;
|
|
5
|
+
category: IExpiredContentEditState;
|
|
6
|
+
onCancel: () => void;
|
|
7
|
+
onSave: (updatedContent: any, deletedTags: any[]) => void;
|
|
8
|
+
onDelete: () => void;
|
|
9
|
+
isSaving?: boolean;
|
|
10
|
+
isDeleting?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export default function ExpiredContentSingleItemView({ category, content, onCancel, onSave, onDelete, isSaving, isDeleting, }: IProps): React.JSX.Element;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=ExpiredContentSingleItemView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExpiredContentSingleItemView.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageExpiredContents/ExpiredContentSingleItemView.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAwC,MAAM,OAAO,CAAC;AAI7D,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAIjG,UAAU,MAAM;IACZ,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,wBAAwB,CAAC;IACnC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAC1D,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,CAAC,OAAO,UAAU,4BAA4B,CAAC,EACjD,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,UAAU,GACb,EAAE,MAAM,qBAmNR"}
|
|
@@ -0,0 +1,141 @@
|
|
|
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 { Button, DatePicker, Flex, FlexItem, FormGroup, TextInput, ValidatedOptions } from '@patternfly/react-core';
|
|
11
|
+
import { TagsSelector, ToastNotification } from '@rh-support/components';
|
|
12
|
+
import { getDrupalResIdIfTypeFromUrl, getText, isValidDate, isValidUrl } from '@rh-support/utils';
|
|
13
|
+
import { isEqual } from 'lodash';
|
|
14
|
+
import differenceBy from 'lodash/differenceBy';
|
|
15
|
+
import isEmpty from 'lodash/isEmpty';
|
|
16
|
+
import React, { useContext, useMemo, useState } from 'react';
|
|
17
|
+
import { Trans, useTranslation } from 'react-i18next';
|
|
18
|
+
import { TagManagementStateContext } from '../../context/TagManagementContextProvider';
|
|
19
|
+
import { getTopContentUrl } from '../../reducers/TopContentHelpers';
|
|
20
|
+
import { getDocsFromUrl } from '../TopContentManagement/TopContentEditor/TopContentCategoryContent/TopContentSingleItem';
|
|
21
|
+
export default function ExpiredContentSingleItemView({ category, content, onCancel, onSave, onDelete, isSaving, isDeleting, }) {
|
|
22
|
+
var _a, _b;
|
|
23
|
+
const { t } = useTranslation();
|
|
24
|
+
const tagManagementEditState = useContext(TagManagementStateContext);
|
|
25
|
+
const { tags: tagOptions } = tagManagementEditState;
|
|
26
|
+
const [isFetchingSolrSearch, setIsFetchingSolrSearch] = useState(false);
|
|
27
|
+
const [localContentUrl, setLocalContentUrl] = useState(content.contentUrl);
|
|
28
|
+
const [localContentTitle, setLocalContentTitle] = useState(content.contentTitle);
|
|
29
|
+
const [localSelectedTags, setLocalSelectedTags] = useState(content.tags || []);
|
|
30
|
+
const [localExpiryDate, setLocalExpiryDate] = useState((content === null || content === void 0 ? void 0 : content.expiryDate) || '');
|
|
31
|
+
const [contentTitleIsValid, setContentTitleIsValid] = useState(true);
|
|
32
|
+
const [contentUrlIsValid, setContentUrlIsValid] = useState(true);
|
|
33
|
+
const oldTagsIds = useMemo(() => { var _a; return ((_a = content === null || content === void 0 ? void 0 : content.tags) === null || _a === void 0 ? void 0 : _a.map((t) => t.id)) || []; }, [content === null || content === void 0 ? void 0 : content.tags]);
|
|
34
|
+
const localTagsIds = useMemo(() => localSelectedTags === null || localSelectedTags === void 0 ? void 0 : localSelectedTags.map((t) => t.id), [localSelectedTags]);
|
|
35
|
+
const onSubmit = (e) => e.preventDefault();
|
|
36
|
+
const updateContentTitleFromUrl = (contentUrl) => __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
var _c, _d;
|
|
38
|
+
// throws toast warning and clears it after 4 seconds
|
|
39
|
+
const throwWarningMessage = () => {
|
|
40
|
+
const message = getText('Unable to automatically fetch title. Please enter manually');
|
|
41
|
+
ToastNotification.addWarningMessage(message, '', { autoClose: 4000 });
|
|
42
|
+
};
|
|
43
|
+
try {
|
|
44
|
+
const nodeId = getDrupalResIdIfTypeFromUrl(contentUrl);
|
|
45
|
+
if (!nodeId)
|
|
46
|
+
return;
|
|
47
|
+
const docs = yield getDocsFromUrl(contentUrl);
|
|
48
|
+
const contentTitle = ((_c = docs[0]) === null || _c === void 0 ? void 0 : _c.publishedTitle) || ((_d = docs[0]) === null || _d === void 0 ? void 0 : _d.allTitle);
|
|
49
|
+
if (docs.length > 0 && docs[0].id === nodeId + '' && contentTitle) {
|
|
50
|
+
setLocalContentTitle(contentTitle);
|
|
51
|
+
setContentTitleIsValid(true);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
throwWarningMessage();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
throwWarningMessage();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
const onLocalContentUrlChange = () => __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
if (localContentUrl === content.contentUrl)
|
|
63
|
+
return;
|
|
64
|
+
setIsFetchingSolrSearch(true);
|
|
65
|
+
yield updateContentTitleFromUrl(localContentUrl);
|
|
66
|
+
setIsFetchingSolrSearch(false);
|
|
67
|
+
});
|
|
68
|
+
const checkDuplicateUrls = (url) => {
|
|
69
|
+
//
|
|
70
|
+
onLocalContentUrlChange();
|
|
71
|
+
};
|
|
72
|
+
const onContentUrlChange = (contentUrl, event) => __awaiter(this, void 0, void 0, function* () {
|
|
73
|
+
setContentUrlIsValid(isValidUrl(contentUrl));
|
|
74
|
+
checkDuplicateUrls(contentUrl);
|
|
75
|
+
setLocalContentUrl(contentUrl);
|
|
76
|
+
});
|
|
77
|
+
const onContentTitleChange = (contentTitle, event) => {
|
|
78
|
+
const contentTitleIsValid = event.target.validity.valid;
|
|
79
|
+
setContentTitleIsValid(contentTitleIsValid);
|
|
80
|
+
setLocalContentTitle(contentTitle);
|
|
81
|
+
};
|
|
82
|
+
const handleLocalTagChange = (tags) => {
|
|
83
|
+
setLocalSelectedTags(tags);
|
|
84
|
+
};
|
|
85
|
+
const onExpiryDateChange = (event, str, date) => {
|
|
86
|
+
setLocalExpiryDate(str);
|
|
87
|
+
};
|
|
88
|
+
const expiryDateValidator = (date) => {
|
|
89
|
+
if (date < new Date())
|
|
90
|
+
return t('Invalid expiry date');
|
|
91
|
+
return '';
|
|
92
|
+
};
|
|
93
|
+
const onContentSave = () => {
|
|
94
|
+
const newTags = differenceBy(localTagsIds, oldTagsIds);
|
|
95
|
+
const deletedTags = differenceBy(oldTagsIds, localTagsIds);
|
|
96
|
+
const updatedContent = Object.assign(Object.assign({}, content), { contentTitle: localContentTitle, contentUrl: localContentUrl, tagList: newTags, tags: localSelectedTags.map((t) => ({ id: t.id, tagName: t.tagName })), expiryDate: localExpiryDate });
|
|
97
|
+
onSave(updatedContent, deletedTags);
|
|
98
|
+
};
|
|
99
|
+
const doesInputHasSpaces = isEmpty(localContentTitle.trim());
|
|
100
|
+
const isSaveButtonDisabled = doesInputHasSpaces ||
|
|
101
|
+
!(contentTitleIsValid &&
|
|
102
|
+
contentUrlIsValid &&
|
|
103
|
+
localContentTitle &&
|
|
104
|
+
localContentUrl &&
|
|
105
|
+
((isValidDate(localExpiryDate) && isEmpty(expiryDateValidator(new Date(localExpiryDate)))) ||
|
|
106
|
+
(isEmpty(localExpiryDate) && isEmpty((_a = content.expiryDate) !== null && _a !== void 0 ? _a : '')))) ||
|
|
107
|
+
(localContentUrl === content.contentUrl &&
|
|
108
|
+
localContentTitle === content.contentTitle &&
|
|
109
|
+
isEqual(localTagsIds, oldTagsIds) &&
|
|
110
|
+
isEqual(localExpiryDate.split('T')[0], ((_b = content.expiryDate) === null || _b === void 0 ? void 0 : _b.split('T')[0]) || ''));
|
|
111
|
+
return (React.createElement("form", { noValidate: true, onSubmit: onSubmit, className: "card card-light push-bottom" },
|
|
112
|
+
React.createElement("div", { className: "form-group" },
|
|
113
|
+
React.createElement("label", { htmlFor: localContentTitle },
|
|
114
|
+
"Heading",
|
|
115
|
+
' ',
|
|
116
|
+
React.createElement("span", { className: "form-required", "aria-hidden": true }, "*")),
|
|
117
|
+
React.createElement(TextInput, { isRequired: true, type: "text", maxLength: 254, required: true, value: localContentTitle, isDisabled: isFetchingSolrSearch, "aria-label": t('Copy and paste the heading for consistency'), placeholder: t('Copy and paste the heading for consistency'), onChange: (e, v) => onContentTitleChange(v, e), validated: contentTitleIsValid ? ValidatedOptions.default : ValidatedOptions.error })),
|
|
118
|
+
React.createElement("div", { className: "form-group" },
|
|
119
|
+
React.createElement("label", { htmlFor: localContentUrl },
|
|
120
|
+
"Link to content",
|
|
121
|
+
' ',
|
|
122
|
+
React.createElement("span", { className: "form-required", "aria-hidden": true }, "*")),
|
|
123
|
+
React.createElement(TextInput, { type: "url", maxLength: 254, isRequired: true, pattern: "^(http(s)?:\\/\\/)+[\\w\\-\\._~:\\/?#[\\]@!\\$&'\\(\\)\\*\\+,;=.]+$", value: getTopContentUrl(localContentUrl), "aria-label": t('Entering a solution or article link first will automatically generate the heading for you'), placeholder: t('Entering a solution or article link first will automatically generate the heading for you'), onChange: (evt, val) => onContentUrlChange(val, evt), validated: contentUrlIsValid ? ValidatedOptions.default : ValidatedOptions.error })),
|
|
124
|
+
React.createElement(Flex, { className: "pf-v5-u-my-lg" },
|
|
125
|
+
React.createElement(FlexItem, { flex: { default: 'flex_1' } },
|
|
126
|
+
React.createElement(FormGroup, { label: t('Tags') },
|
|
127
|
+
React.createElement("div", { className: "pf-v5-c-form-control" },
|
|
128
|
+
React.createElement(TagsSelector, { tagOptions: tagOptions, onChange: handleLocalTagChange, selectedTags: localSelectedTags, placeholder: t('Select tags to improve discoverability') })))),
|
|
129
|
+
React.createElement(FlexItem, null,
|
|
130
|
+
React.createElement(FormGroup, { label: t('Expiry date') },
|
|
131
|
+
React.createElement(DatePicker, { onBlur: onExpiryDateChange, onChange: onExpiryDateChange, value: !isEmpty(localExpiryDate) ? localExpiryDate.split('T')[0] : '', validators: [expiryDateValidator] })))),
|
|
132
|
+
React.createElement("span", { className: "top-content-single-item-footer" },
|
|
133
|
+
React.createElement("span", null,
|
|
134
|
+
React.createElement(Button, { variant: "primary", onClick: onContentSave, isDisabled: isSaveButtonDisabled || isSaving, isLoading: isSaving },
|
|
135
|
+
React.createElement(Trans, null, "Save")),
|
|
136
|
+
' ',
|
|
137
|
+
React.createElement(Button, { variant: "tertiary", onClick: onCancel, "data-tracking-id": "cancel-button-top-content" },
|
|
138
|
+
React.createElement(Trans, null, "Cancel"))),
|
|
139
|
+
React.createElement("span", { className: "content-actions" },
|
|
140
|
+
React.createElement(Button, { variant: "danger", "aria-label": t('Delete content'), onClick: onDelete, isDisabled: isDeleting }, "Delete")))));
|
|
141
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageExpiredContents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ExpiredContentManagement } from './ExpiredContentManagement';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TagsManager.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageTags/TagsManager.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TagsManager.d.ts","sourceRoot":"","sources":["../../../../src/components/ManageTags/TagsManager.tsx"],"names":[],"mappings":"AA6BA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAOxE,MAAM,CAAC,OAAO,UAAU,WAAW,sBAuYlC"}
|
|
@@ -7,8 +7,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { ActionList, ActionListItem, Bullseye, Button, ButtonVariant, EmptyState, EmptyStateVariant, Flex, FormGroup, FormHelperText, HelperText, HelperTextItem, Modal,
|
|
10
|
+
import { ActionList, ActionListItem, Bullseye, Button, ButtonVariant, EmptyState, EmptyStateVariant, Flex, FormGroup, FormHelperText, HelperText, HelperTextItem, Modal, Spinner, TextInput, TextInputGroup, TextInputGroupMain, TextInputGroupUtilities, } from '@patternfly/react-core';
|
|
11
11
|
import PencilAltIcon from '@patternfly/react-icons/dist/js/icons/pencil-alt-icon';
|
|
12
|
+
import SearchIcon from '@patternfly/react-icons/dist/js/icons/search-icon';
|
|
13
|
+
import TimesIcon from '@patternfly/react-icons/dist/js/icons/times-icon';
|
|
12
14
|
import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon';
|
|
13
15
|
import { ErrorBoundary, ToastNotification } from '@rh-support/components';
|
|
14
16
|
import { formatDate } from '@rh-support/utils';
|
|
@@ -78,6 +80,7 @@ export default function TagsManager() {
|
|
|
78
80
|
try {
|
|
79
81
|
setIsCreatingNewTag(true);
|
|
80
82
|
yield createNewTags(dispatch, [{ tagName: newTagName.trim(), isActive: true }]);
|
|
83
|
+
setTagSearchTerm('');
|
|
81
84
|
ToastNotification.addSuccessMessage(t('Successfully created tag'));
|
|
82
85
|
}
|
|
83
86
|
catch (err) {
|
|
@@ -86,10 +89,10 @@ export default function TagsManager() {
|
|
|
86
89
|
}
|
|
87
90
|
finally {
|
|
88
91
|
setIsCreatingNewTag(false);
|
|
89
|
-
|
|
92
|
+
onCancelCreateNewTag();
|
|
90
93
|
}
|
|
91
94
|
});
|
|
92
|
-
const
|
|
95
|
+
const onCancelCreateNewTag = () => {
|
|
93
96
|
setCreateTagError('');
|
|
94
97
|
setCreateTagModalOpen(false);
|
|
95
98
|
setNewTagName('');
|
|
@@ -149,6 +152,9 @@ export default function TagsManager() {
|
|
|
149
152
|
setSelectedDeleteTag(null);
|
|
150
153
|
}
|
|
151
154
|
});
|
|
155
|
+
const onSearchClear = () => {
|
|
156
|
+
setTagSearchTerm('');
|
|
157
|
+
};
|
|
152
158
|
const columns = [
|
|
153
159
|
{
|
|
154
160
|
accessor: (id) => tagsByIds[id].tagName,
|
|
@@ -192,10 +198,10 @@ export default function TagsManager() {
|
|
|
192
198
|
React.createElement(TrashIcon, null))))),
|
|
193
199
|
},
|
|
194
200
|
];
|
|
195
|
-
const CreateTagModel = (React.createElement(Modal, { title: t('Create a tag'), onClose:
|
|
201
|
+
const CreateTagModel = (React.createElement(Modal, { title: t('Create a tag'), onClose: onCancelCreateNewTag, isOpen: createTagModalOpen, actions: [
|
|
196
202
|
React.createElement(Button, { key: "create-tag", variant: ButtonVariant.primary, onClick: onCreateNewTag, isLoading: isCreatingNewTag, isDisabled: !isEmpty(createTagError) || isCreatingNewTag },
|
|
197
203
|
React.createElement(Trans, null, "Create")),
|
|
198
|
-
React.createElement(Button, { key: "cancel-create-tag", variant: ButtonVariant.link, onClick:
|
|
204
|
+
React.createElement(Button, { key: "cancel-create-tag", variant: ButtonVariant.link, onClick: onCancelCreateNewTag }, "Cancel"),
|
|
199
205
|
] },
|
|
200
206
|
React.createElement(FormGroup, { label: "Tag name", isRequired: true },
|
|
201
207
|
React.createElement(TextInput, { isRequired: true, type: "text", id: "create-new-tag-text-input", value: newTagName, onChange: (e, v) => {
|
|
@@ -237,9 +243,16 @@ export default function TagsManager() {
|
|
|
237
243
|
React.createElement("label", { htmlFor: "tag-search-input" },
|
|
238
244
|
React.createElement(Trans, null, "Search Tag")),
|
|
239
245
|
React.createElement("div", { className: "pf-v5-u-flex-grow-1" },
|
|
240
|
-
React.createElement(
|
|
246
|
+
React.createElement(TextInputGroup, null,
|
|
247
|
+
React.createElement(TextInputGroupMain, { type: "text", id: "tag-search-input", placeholder: t('Search for a tag'), icon: React.createElement(SearchIcon, null), value: tagSearchTerm, onChange: (e, v) => setTagSearchTerm(v) }),
|
|
248
|
+
React.createElement(TextInputGroupUtilities, null,
|
|
249
|
+
React.createElement(Button, { variant: "plain", onClick: onSearchClear, "aria-label": "Clear button and input" },
|
|
250
|
+
React.createElement(TimesIcon, null))))),
|
|
241
251
|
React.createElement("span", { className: "pf-v5-u-ml-sm" },
|
|
242
|
-
React.createElement(Button, { variant: ButtonVariant.primary, isInline: true, onClick: () =>
|
|
252
|
+
React.createElement(Button, { variant: ButtonVariant.primary, isInline: true, onClick: () => {
|
|
253
|
+
setCreateTagModalOpen(true);
|
|
254
|
+
setNewTagName(tagSearchTerm);
|
|
255
|
+
}, "data-tracking-id": "tag-create-button" },
|
|
243
256
|
React.createElement(Trans, null, "Create tag"))))),
|
|
244
257
|
React.createElement("div", { className: "tags-manager-wrapper" },
|
|
245
258
|
React.createElement(ErrorBoundary, { errorMsgInfo: { message: t('There was an error loading tags list') } }, tagResponse.isFetching ? (React.createElement(Bullseye, null,
|