strapi-plugin-comments 1.0.4 → 2.0.0-beta.4

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 (156) hide show
  1. package/.circleci/config.yml +2 -2
  2. package/README.md +53 -126
  3. package/admin/src/components/ConfirmationDialog/index.js +56 -0
  4. package/admin/src/components/DiscussionStatus/index.js +33 -0
  5. package/admin/src/components/DiscussionThread/index.js +59 -0
  6. package/admin/src/components/DiscussionThreadItem/index.js +87 -0
  7. package/admin/src/components/DiscussionThreadItem/styles.js +88 -0
  8. package/admin/src/components/DiscussionThreadItemActions/index.js +178 -0
  9. package/admin/src/components/DiscussionThreadItemActions/styles.js +22 -0
  10. package/admin/src/components/DiscussionThreadItemMeta/index.js +31 -0
  11. package/admin/src/components/DiscussionThreadItemWarnings/index.js +141 -0
  12. package/admin/src/components/DiscussionThreadItemWarnings/styles.js +7 -0
  13. package/admin/src/components/EntityDetails/index.js +53 -0
  14. package/admin/src/{containers → components}/Initializer/index.js +4 -4
  15. package/admin/src/components/LoadingIndicatorOverlay/index.js +15 -0
  16. package/admin/src/components/LoadingIndicatorOverlay/styles.js +20 -0
  17. package/admin/src/components/Nav/index.js +45 -0
  18. package/admin/src/components/PluginIcon/index.js +12 -0
  19. package/admin/src/components/ReportsReviewModal/index.js +43 -0
  20. package/admin/src/components/ReportsReviewTable/index.js +146 -0
  21. package/admin/src/components/TableFilters/index.js +53 -0
  22. package/admin/src/components/TablePagination/index.js +35 -0
  23. package/admin/src/components/icons/comments.js +9 -0
  24. package/admin/src/components/icons/index.js +6 -0
  25. package/admin/src/components/icons/lock.js +22 -0
  26. package/admin/src/components/icons/review.js +18 -0
  27. package/admin/src/components/icons/unlock.js +20 -0
  28. package/admin/src/index.js +58 -42
  29. package/admin/src/pages/App/index.js +71 -0
  30. package/admin/src/pages/App/reducer/actions.js +8 -0
  31. package/admin/src/pages/App/reducer/constants.js +4 -0
  32. package/admin/src/pages/App/reducer/index.js +26 -0
  33. package/admin/src/pages/App/reducer/init.js +7 -0
  34. package/admin/src/pages/App/reducer/selectors.js +35 -0
  35. package/admin/src/pages/App/utils/api.js +12 -0
  36. package/admin/src/pages/ComingSoonPage/index.js +25 -0
  37. package/admin/src/pages/Details/index.js +109 -0
  38. package/admin/src/pages/Details/utils/api.js +41 -0
  39. package/admin/src/pages/Discover/components/DiscoverTableRow/index.js +196 -0
  40. package/admin/src/pages/Discover/index.js +157 -0
  41. package/admin/src/pages/Discover/utils/api.js +14 -0
  42. package/admin/src/pages/Discover/utils/filtersSchema.js +9 -0
  43. package/admin/src/permissions.js +13 -37
  44. package/admin/src/pluginId.js +2 -4
  45. package/admin/src/reducers.js +8 -0
  46. package/admin/src/translations/en.json +73 -37
  47. package/admin/src/translations/fr.json +1 -0
  48. package/admin/src/utils/axiosInstance.js +35 -0
  49. package/admin/src/utils/constants.js +25 -6
  50. package/admin/src/utils/getApiUrl.js +5 -0
  51. package/admin/src/utils/getMessage.js +21 -0
  52. package/admin/src/utils/getRelatedGroups.js +5 -0
  53. package/admin/src/utils/getUrl.js +5 -0
  54. package/admin/src/utils/handleAPIError.js +15 -0
  55. package/admin/src/utils/index.js +6 -0
  56. package/codecov.yml +2 -1
  57. package/content-types/comment.js +97 -0
  58. package/content-types/index.js +11 -0
  59. package/content-types/report.js +54 -0
  60. package/package.json +11 -25
  61. package/server/bootstrap.js +5 -0
  62. package/server/config/index.js +10 -0
  63. package/server/controllers/admin.js +134 -0
  64. package/server/controllers/client.js +117 -0
  65. package/server/controllers/index.js +9 -0
  66. package/{controllers → server/controllers}/utils/__tests__/functions.test.js +0 -0
  67. package/{controllers → server/controllers}/utils/functions.js +1 -1
  68. package/server/destroy.js +5 -0
  69. package/server/index.js +22 -0
  70. package/server/register.js +5 -0
  71. package/server/routes/admin.js +92 -0
  72. package/server/routes/client.js +52 -0
  73. package/server/routes/index.js +15 -0
  74. package/server/services/admin.js +215 -0
  75. package/server/services/client.js +227 -0
  76. package/server/services/common.js +197 -0
  77. package/server/services/index.js +11 -0
  78. package/{services → server/services}/utils/__tests__/functions.test.js +0 -0
  79. package/{services → server/services}/utils/functions.js +17 -6
  80. package/server/utils/constants.js +16 -0
  81. package/{services → server}/utils/error.js +0 -0
  82. package/server/utils/functions.js +19 -0
  83. package/strapi-admin.js +3 -0
  84. package/strapi-server.js +9 -0
  85. package/admin/src/assets/images/icon-cross-blue.svg +0 -1
  86. package/admin/src/assets/images/icon_remove.svg +0 -19
  87. package/admin/src/assets/images/logo.svg +0 -5
  88. package/admin/src/components/AbuseReportsPopUp/ItemPreviewContainer.js +0 -8
  89. package/admin/src/components/AbuseReportsPopUp/ModalFooter.js +0 -31
  90. package/admin/src/components/AbuseReportsPopUp/TableContainer.js +0 -63
  91. package/admin/src/components/AbuseReportsPopUp/index.js +0 -148
  92. package/admin/src/components/Container/index.js +0 -7
  93. package/admin/src/components/EmptyView/index.js +0 -25
  94. package/admin/src/components/Filters/index.js +0 -151
  95. package/admin/src/components/Filters/index.styled.js +0 -82
  96. package/admin/src/components/Filters/utils.js +0 -21
  97. package/admin/src/components/Item/CardItem.js +0 -30
  98. package/admin/src/components/Item/CardWrapper.js +0 -10
  99. package/admin/src/components/Item/index.js +0 -107
  100. package/admin/src/components/ItemDetails/CardItem.js +0 -33
  101. package/admin/src/components/ItemDetails/CardLevelCounter.js +0 -46
  102. package/admin/src/components/ItemDetails/CardLevelCounterLink.js +0 -24
  103. package/admin/src/components/ItemDetails/CardLevelWrapper.js +0 -22
  104. package/admin/src/components/ItemDetails/CardWrapper.js +0 -52
  105. package/admin/src/components/ItemDetails/index.js +0 -167
  106. package/admin/src/components/ItemFooter/CardItemAuthor.js +0 -10
  107. package/admin/src/components/ItemFooter/CardItemRelation.js +0 -18
  108. package/admin/src/components/ItemFooter/Wrapper.js +0 -20
  109. package/admin/src/components/ItemFooter/index.js +0 -87
  110. package/admin/src/components/ItemHeader/CardHeaderBlocked.js +0 -24
  111. package/admin/src/components/ItemHeader/CardHeaderIndicator.js +0 -30
  112. package/admin/src/components/ItemHeader/CardHeaderIndicatorBlue.js +0 -11
  113. package/admin/src/components/ItemHeader/CardHeaderIndicatorRed.js +0 -11
  114. package/admin/src/components/ItemHeader/CardHeaderIndicatorsContainer.js +0 -18
  115. package/admin/src/components/ItemHeader/CardHeaderPending.js +0 -11
  116. package/admin/src/components/ItemHeader/CardHeaderReports.js +0 -40
  117. package/admin/src/components/ItemHeader/Wrapper.js +0 -16
  118. package/admin/src/components/ItemHeader/index.js +0 -97
  119. package/admin/src/components/ItemModeration/Wrapper.js +0 -19
  120. package/admin/src/components/ItemModeration/index.js +0 -84
  121. package/admin/src/components/List/Container.js +0 -20
  122. package/admin/src/components/List/index.js +0 -21
  123. package/admin/src/components/Search/index.js +0 -83
  124. package/admin/src/containers/App/Wrapper.js +0 -14
  125. package/admin/src/containers/App/index.js +0 -47
  126. package/admin/src/containers/DataManagerProvider/actions.js +0 -15
  127. package/admin/src/containers/DataManagerProvider/index.js +0 -332
  128. package/admin/src/containers/DataManagerProvider/init.js +0 -5
  129. package/admin/src/containers/DataManagerProvider/reducer.js +0 -59
  130. package/admin/src/containers/DetailsView/Wrapper.js +0 -18
  131. package/admin/src/containers/DetailsView/index.js +0 -106
  132. package/admin/src/containers/ListView/FadedWrapper.js +0 -42
  133. package/admin/src/containers/ListView/Footer.js +0 -53
  134. package/admin/src/containers/ListView/Wrapper.js +0 -17
  135. package/admin/src/containers/ListView/components.js +0 -138
  136. package/admin/src/containers/ListView/index.js +0 -45
  137. package/admin/src/containers/Panel/actions.js +0 -5
  138. package/admin/src/containers/Panel/index.js +0 -191
  139. package/admin/src/containers/Panel/index.styled.js +0 -6
  140. package/admin/src/containers/Panel/reducer.js +0 -44
  141. package/admin/src/contexts/DataManagerContext.js +0 -5
  142. package/admin/src/hooks/useDataManager.js +0 -6
  143. package/admin/src/lifecycles.js +0 -3
  144. package/admin/src/translations/index.js +0 -7
  145. package/admin/src/utils/getTrad.js +0 -5
  146. package/admin/src/utils/getTradId.js +0 -5
  147. package/config/functions/bootstrap.js +0 -62
  148. package/config/routes.json +0 -142
  149. package/config/schema.graphql.js +0 -268
  150. package/controllers/comments.js +0 -228
  151. package/models/comment.js +0 -8
  152. package/models/comment.settings.json +0 -102
  153. package/models/report.js +0 -8
  154. package/models/report.settings.json +0 -49
  155. package/services/comments.js +0 -539
  156. package/services/utils/constants.js +0 -9
@@ -1,84 +0,0 @@
1
- import React, { useMemo } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { useGlobalContext, CheckPermissions } from 'strapi-helper-plugin';
4
- import { Button } from '@buffetjs/core';
5
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6
- import { faComment, faCommentSlash, faComments, faExclamationCircle } from '@fortawesome/free-solid-svg-icons';
7
- import Wrapper from './Wrapper';
8
- import pluginId from '../../pluginId';
9
- import pluginPermissions from '../../permissions';
10
- import { APPROVAL_STATUS } from '../../utils/constants';
11
-
12
- const ItemModeration = ({ id, blocked, blockedThread, onBlockClick, onBlockThreadClick, onApproveCommentClick, onRejectCommentClick, approvalStatus }) => {
13
- const { formatMessage } = useGlobalContext();
14
- const canBeApproved =
15
- approvalStatus === APPROVAL_STATUS.PENDING ||
16
- approvalStatus === APPROVAL_STATUS.REJECTED;
17
- const approvalButtonProps = useMemo(
18
- () =>
19
- canBeApproved
20
- ? {
21
- onClick: onApproveCommentClick.bind(null, id),
22
- color: 'primary',
23
- label: formatMessage({
24
- id: `${pluginId}.list.item.moderation.button.comment.approval.approve`,
25
- }),
26
- }
27
- : {
28
- onClick: onRejectCommentClick.bind(null, id),
29
- color: 'delete',
30
- label: formatMessage({
31
- id: `${pluginId}.list.item.moderation.button.comment.approval.reject`,
32
- }),
33
- },
34
- [canBeApproved, id],
35
- );
36
-
37
- return (
38
- <CheckPermissions permissions={pluginPermissions.moderate}>
39
- <Wrapper>
40
- {approvalStatus ? (
41
- <CheckPermissions permissions={pluginPermissions.moderateComments}>
42
- <Button
43
- {...approvalButtonProps}
44
- icon={<FontAwesomeIcon icon={faExclamationCircle} />}
45
- />
46
- </CheckPermissions>
47
- ) : null}
48
- {!blockedThread && (
49
- <CheckPermissions permissions={pluginPermissions.moderateComments}>
50
- <Button
51
- onClick={e => onBlockClick(id)}
52
- color={blocked ? 'primary' : 'delete'}
53
- icon={<FontAwesomeIcon icon={blocked ? faComment : faCommentSlash} />}
54
- label={formatMessage({ id: `${pluginId}.list.item.moderation.button.comment.${blocked ? 'restore' : 'hide'}` })} />
55
- </CheckPermissions>
56
- )}
57
- <CheckPermissions permissions={pluginPermissions.moderateThreads}>
58
- <Button
59
- onClick={e => onBlockThreadClick(id)}
60
- color={blockedThread ? 'primary' : 'delete'}
61
- icon={<FontAwesomeIcon icon={faComments} />}
62
- label={formatMessage({ id: `${pluginId}.list.item.moderation.button.thread.${blockedThread ? 'restore' : 'hide'}` })} />
63
- </CheckPermissions>
64
- </Wrapper>
65
- </CheckPermissions>
66
- );
67
- };
68
-
69
- ItemModeration.propTypes = {
70
- id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
71
- blocked: PropTypes.bool,
72
- blockedThread: PropTypes.bool,
73
- onBlockClick: PropTypes.func.isRequired,
74
- onBlockThreadClick: PropTypes.func.isRequired,
75
- approvalStatus: PropTypes.oneOf([
76
- APPROVAL_STATUS.APPROVED,
77
- APPROVAL_STATUS.PENDING,
78
- APPROVAL_STATUS
79
- ]),
80
- onApproveCommentClick: PropTypes.func,
81
- onRejectCommentClick: PropTypes.func,
82
- };
83
-
84
- export default ItemModeration;
@@ -1,20 +0,0 @@
1
- import styled from 'styled-components';
2
-
3
- import { colors, sizes } from 'strapi-helper-plugin';
4
-
5
- const Container = styled.ul`
6
- display: flex;
7
- padding: ${2*sizes.margin}px;
8
- flex-direction: column;
9
- flex-grow: 1;
10
- margin: 0;
11
-
12
- z-index: 0;
13
-
14
- overflow-x: hidden;
15
- overflow-y: auto;
16
-
17
- list-style: none;
18
- `;
19
-
20
- export default Container;
@@ -1,21 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import Item from '../Item';
4
- import Container from './Container';
5
-
6
- const List = ({ items, relatedContentTypes }) => (
7
- <Container>
8
- {items.map((item, n) => (
9
- <Item
10
- key={`list-item-${item.id || n}`}
11
- relatedContentTypes={relatedContentTypes}
12
- {...item}
13
- />))}
14
- </Container>
15
- );
16
-
17
- List.propTypes = {
18
- items: PropTypes.array,
19
- };
20
-
21
- export default List;
@@ -1,83 +0,0 @@
1
- /*
2
- *
3
- * Search
4
- *
5
- */
6
-
7
- import React, { memo } from 'react';
8
- import { isEmpty, upperFirst } from 'lodash';
9
- import PropTypes from 'prop-types';
10
- import { FormattedMessage } from 'react-intl';
11
- import { HeaderSearch } from 'strapi-helper-plugin';
12
- import getTrad from '../../utils/getTrad';
13
-
14
- const WAIT = 400;
15
-
16
- class Search extends React.Component {
17
- state = { value: this.props.initValue };
18
-
19
- timer = null;
20
-
21
- componentDidUpdate(prevProps) {
22
- const { model, value } = this.props;
23
-
24
- if (prevProps.model !== model || (!isEmpty(prevProps.value) && isEmpty(value))) {
25
- this.resetState();
26
- }
27
- }
28
-
29
- resetState = () => this.setState({ value: '' });
30
-
31
- handleChange = ({ target }) => {
32
- clearTimeout(this.timer);
33
- this.setState({ value: target.value });
34
- this.timer = setTimeout(() => this.triggerChange(target.value), WAIT);
35
- };
36
-
37
- handleClick = () => {
38
- this.setState({ value: '' });
39
- this.triggerChange('');
40
- };
41
-
42
- triggerChange = value =>
43
- this.props.changeParams({
44
- target: {
45
- name: '_q',
46
- value,
47
- },
48
- });
49
-
50
- render() {
51
- const { model } = this.props;
52
- const { value } = this.state;
53
-
54
- return (
55
- <FormattedMessage id={getTrad('components.Search.placeholder')}>
56
- {placeholder => (
57
- <HeaderSearch
58
- label={upperFirst(model)}
59
- onChange={this.handleChange}
60
- onClear={this.handleClick}
61
- placeholder={placeholder}
62
- value={value}
63
- />
64
- )}
65
- </FormattedMessage>
66
- );
67
- }
68
- }
69
-
70
- Search.defaultProps = {
71
- changeParams: () => {},
72
- model: '',
73
- value: '',
74
- };
75
-
76
- Search.propTypes = {
77
- changeParams: PropTypes.func,
78
- initValue: PropTypes.string.isRequired,
79
- model: PropTypes.string,
80
- value: PropTypes.string,
81
- };
82
-
83
- export default memo(Search);
@@ -1,14 +0,0 @@
1
- import styled from 'styled-components';
2
-
3
- import { sizes } from 'strapi-helper-plugin';
4
-
5
- const Wrapper = styled.div`
6
- min-height: calc(100vh - ${sizes.header.height});
7
- .centered {
8
- position: fixed;
9
- top: calc(50% - 13px);
10
- right: calc(50% - 13px);
11
- }
12
- `;
13
-
14
- export default Wrapper;
@@ -1,47 +0,0 @@
1
- /**
2
- *
3
- * This component is the skeleton around the actual pages, and should only
4
- * contain code that should be seen on all pages. (e.g. navigation bar)
5
- *
6
- */
7
-
8
- import React, { Suspense, lazy }from 'react';
9
- import { Switch, Route } from 'react-router-dom';
10
- import { NotFound, LoadingIndicatorPage, CheckPagePermissions } from 'strapi-helper-plugin';
11
- import Wrapper from './Wrapper';
12
- // Utils
13
- import pluginId from '../../pluginId';
14
- import DataManagerProvider from '../DataManagerProvider';
15
- import pluginPermissions from '../../permissions';
16
- // Containers
17
-
18
-
19
- const Panel = lazy(() => import('../Panel'));
20
-
21
- const App = () => {
22
- return (
23
- <CheckPagePermissions permissions={pluginPermissions.main}>
24
- <Wrapper>
25
- <DataManagerProvider>
26
- <Suspense fallback={<LoadingIndicatorPage />}>
27
- <Switch>
28
- <Route
29
- path={`/plugins/${pluginId}`}
30
- component={Panel}
31
- exact
32
- />
33
- <Route
34
- path={`/plugins/${pluginId}/display/:id`}
35
- component={Panel}
36
- exact
37
- />
38
- <Route component={NotFound} />
39
- </Switch>
40
- </Suspense>
41
- </DataManagerProvider>
42
- </Wrapper>
43
- </CheckPagePermissions>
44
- );
45
- };
46
-
47
- export default App;
@@ -1,15 +0,0 @@
1
- export const GET_DATA = 'GET_DATA';
2
- export const GET_DATA_SUCCEEDED = 'GET_DATA_SUCCEEDED';
3
- export const GET_SINGLE_DATA = 'GET_SINGLE_DATA';
4
- export const BLOCK_COMMENT = 'BLOCK_COMMENT';
5
- export const BLOCK_COMMENT_THREAD = 'BLOCK_COMMENT_THREAD';
6
- export const GET_SINGLE_DATA_SUCCEEDED = 'GET_SINGLE_DATA_SUCCEEDED';
7
- export const RELOAD_PLUGIN = 'RELOAD_PLUGIN';
8
- export const BLOCK_COMMENT_SUCCESS = 'BLOCK_COMMENT_SUCCESS';
9
- export const BLOCK_COMMENT_THREAD_SUCCESS = 'BLOCK_COMMENT_THREAD_SUCCESS';
10
- export const RESOLVE_ABUSE_REPORT = 'RESOLVE_ABUSE_REPORT';
11
- export const RESOLVE_ABUSE_REPORT_SUCCESS = 'RESOLVE_ABUSE_REPORT_SUCCESS';
12
- export const APPROVE_COMMENT = 'APPROVE_COMMENT';
13
- export const REJECT_COMMENT = 'REJECT_COMMENT';
14
- export const APPROVE_COMMENT_SUCCESS = 'APPROVE_COMMENT_SUCCESS';
15
- export const REJECT_COMMENT_SUCCESS = 'REJECT_COMMENT_SUCCESS';
@@ -1,332 +0,0 @@
1
- import React, { memo, useCallback, useEffect, useReducer, useRef } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { get } from 'lodash';
4
- import {
5
- request,
6
- storeData,
7
- LoadingIndicatorPage,
8
- useGlobalContext,
9
- generateFiltersFromSearch,
10
- generateSearchFromFilters,
11
- generateSearchFromObject,
12
- getQueryParameters,
13
- } from 'strapi-helper-plugin';
14
- import { useHistory, useLocation, useRouteMatch } from 'react-router-dom';
15
- import moment from 'moment';
16
- import DataManagerContext from '../../contexts/DataManagerContext';
17
- import Container from '../../components/Container';
18
- import Search from '../../components/Search';
19
- import getTrad from '../../utils/getTrad';
20
- import pluginId from '../../pluginId';
21
- import init from './init';
22
- import reducer, { initialState } from './reducer';
23
- import {
24
- BLOCK_COMMENT,
25
- BLOCK_COMMENT_SUCCESS,
26
- BLOCK_COMMENT_THREAD,
27
- BLOCK_COMMENT_THREAD_SUCCESS,
28
- GET_DATA,
29
- GET_DATA_SUCCEEDED,
30
- GET_SINGLE_DATA,
31
- GET_SINGLE_DATA_SUCCEEDED,
32
- RESOLVE_ABUSE_REPORT,
33
- RESOLVE_ABUSE_REPORT_SUCCESS,
34
- APPROVE_COMMENT,
35
- APPROVE_COMMENT_SUCCESS,
36
- REJECT_COMMENT,
37
- REJECT_COMMENT_SUCCESS,
38
- } from './actions';
39
-
40
- const RECENTLY_VIEVEW_KEY = `${pluginId}-recently-viewed`;
41
-
42
- const getCurrent = async (dispatch, searchParams = {}, recentlyViewed = undefined) => {
43
- try {
44
- const generatedSearch = generateSearchFromObject(searchParams);
45
- dispatch({
46
- type: GET_DATA,
47
- });
48
- const result = await request(`/${pluginId}/moderation/all?${generatedSearch}`, {
49
- method: 'GET',
50
- });
51
- const { items, total: itemsTotal } = result;
52
-
53
- dispatch({
54
- type: GET_DATA_SUCCEEDED,
55
- items,
56
- itemsTotal,
57
- recentlyViewed,
58
- });
59
- } catch (err) {
60
- console.error({ err });
61
- strapi.notification.error('notification.error');
62
- }
63
- };
64
-
65
- const getDetails = async (dispatch, activeId) => {
66
- try {
67
- if (activeId) {
68
- dispatch({
69
- type: GET_SINGLE_DATA,
70
- });
71
-
72
- const activeItem = await request(`/${pluginId}/moderation/single/${activeId}`, {
73
- method: 'GET',
74
- });
75
-
76
- dispatch({
77
- type: GET_SINGLE_DATA_SUCCEEDED,
78
- activeItem,
79
- });
80
- }
81
- } catch (err) {
82
- console.error({ err });
83
- strapi.notification.error('notification.error');
84
- }
85
- };
86
-
87
- const DataManagerProvider = ({ children }) => {
88
- const [reducerState, dispatch] = useReducer(reducer, initialState, init);
89
- const {
90
- autoReload,
91
- currentEnvironment,
92
- emitEvent,
93
- formatMessage,
94
- } = useGlobalContext();
95
- const {
96
- items,
97
- itemsTotal,
98
- activeItem,
99
- isLoading,
100
- isLoadingForDetailsDataToBeSet,
101
- initialData,
102
- } = reducerState.toJS();
103
- const { pathname, search } = useLocation();
104
- const { push } = useHistory();
105
-
106
- const formatMessageRef = useRef();
107
- formatMessageRef.current = formatMessage;
108
-
109
- const isInDevelopmentMode = currentEnvironment === 'development' && autoReload;
110
-
111
- const detailsViewMatch = useRouteMatch(`/plugins/${pluginId}/display/:id`);
112
- const activeId = get(detailsViewMatch, 'params.id', null);
113
-
114
- useEffect(() => {
115
- getCurrent(dispatch, getSearchParams(), moment(storeData.get(RECENTLY_VIEVEW_KEY) || undefined));
116
- storeData.set(RECENTLY_VIEVEW_KEY, moment().toString());
117
- }, [search, dispatch]);
118
-
119
- useEffect(() => {
120
- // We need to set the modifiedData after the data has been retrieved
121
- // and also on pathname change
122
- if (!isLoading) {
123
- getDetails(dispatch, activeId);
124
- }
125
- // eslint-disable-next-line react-hooks/exhaustive-deps
126
- }, [isLoading, pathname, dispatch, activeId]);
127
-
128
- useEffect(() => {
129
- if (currentEnvironment === 'development' && !autoReload) {
130
- strapi.notification.info(
131
- formatMessageRef.current({
132
- id: getTrad('notification.info.autoreaload-disable'),
133
- }),
134
- );
135
- }
136
- }, [autoReload, currentEnvironment]);
137
-
138
- const blockComment = async (id) => {
139
- try {
140
- emitEvent('willBlockComment');
141
- dispatch({ type: BLOCK_COMMENT });
142
-
143
- await request(`/${pluginId}/moderation/block/${id}`, {
144
- method: 'PUT',
145
- });
146
-
147
- getCurrent(dispatch, getSearchParams());
148
- getDetails(dispatch, activeId);
149
-
150
- emitEvent('didBlockComment');
151
- dispatch({ type: BLOCK_COMMENT_SUCCESS });
152
-
153
- strapi.notification.success(`${pluginId}.notification.comment.visibility`);
154
-
155
- } catch (err) {
156
- emitEvent('didNotBlockComment');
157
- console.error({ err: err.response });
158
- strapi.notification.error('notification.error');
159
- }
160
- };
161
-
162
- const blockCommentThread = async (id) => {
163
- try {
164
- emitEvent('willBlockCommentThread');
165
- dispatch({ type: BLOCK_COMMENT_THREAD });
166
-
167
- await request(`/${pluginId}/moderation/block-thread/${id}`, {
168
- method: 'PUT',
169
- });
170
-
171
- getCurrent(dispatch, getSearchParams());
172
- getDetails(dispatch, activeId);
173
-
174
- emitEvent('didBlockCommentThread');
175
- dispatch({ type: BLOCK_COMMENT_THREAD_SUCCESS });
176
-
177
- strapi.notification.success(`${pluginId}.notification.thread.visibility`);
178
-
179
- } catch (err) {
180
- emitEvent('didNotBlockCommentThread');
181
- console.error({ err: err.response });
182
- strapi.notification.error('notification.error');
183
- }
184
- };
185
-
186
- const resolveAbuseReport = async (id, commentId) => {
187
- try {
188
- emitEvent('willResolveAbuseReport');
189
- dispatch({ type: RESOLVE_ABUSE_REPORT });
190
-
191
- await request(`/${pluginId}/moderation/abuse-reports/${commentId}/resolve/${id}`, {
192
- method: 'PATCH',
193
- });
194
-
195
- getCurrent(dispatch, getSearchParams());
196
- getDetails(dispatch, activeId);
197
-
198
- emitEvent('didResolveAbuseReport');
199
- dispatch({ type: RESOLVE_ABUSE_REPORT_SUCCESS });
200
-
201
- strapi.notification.success(`${pluginId}.notification.abuse-report.resolution`);
202
-
203
- } catch (err) {
204
- emitEvent('didNotResolveAbuseReport');
205
- console.error({ err: err.response });
206
- strapi.notification.error('notification.error');
207
- }
208
- };
209
-
210
- const approveComment = async (id) => {
211
- try {
212
- dispatch({ type: APPROVE_COMMENT });
213
- emitEvent('willApprove');
214
-
215
- await request(`/${pluginId}/moderation/approve/${id}`, {
216
- method: 'PUT',
217
- });
218
-
219
- getCurrent(dispatch, getSearchParams());
220
- getDetails(dispatch, activeId);
221
-
222
- dispatch({ type: APPROVE_COMMENT_SUCCESS });
223
- emitEvent('didApprove');
224
-
225
- strapi.notification.success(`${pluginId}.notification.comment.approval`);
226
- } catch (err) {
227
- console.error({ err: err.response });
228
- strapi.notification.error('notification.error');
229
- emitEvent('didNotApprove');
230
- }
231
- };
232
-
233
- const rejectComment = async (id) => {
234
- try {
235
- dispatch({ type: REJECT_COMMENT });
236
- emitEvent('willReject');
237
-
238
- await request(`/${pluginId}/moderation/reject/${id}`, {
239
- method: 'PUT',
240
- });
241
-
242
- getCurrent(dispatch, getSearchParams());
243
- getDetails(dispatch, activeId);
244
-
245
- dispatch({ type: REJECT_COMMENT_SUCCESS });
246
- emitEvent('didReject');
247
-
248
- strapi.notification.success(`${pluginId}.notification.comment.approval`);
249
- } catch (err) {
250
- console.error({ err: err.response });
251
- strapi.notification.error('notification.error');
252
- emitEvent('didNotReject');
253
- }
254
- };
255
-
256
- const getSearchParams = useCallback(
257
- (updatedParams = {}) => {
258
- return {
259
- _limit: getQueryParameters(search, '_limit') || 10,
260
- _page: getQueryParameters(search, '_page') || 1,
261
- _q: getQueryParameters(search, '_q') || '',
262
- filters: generateFiltersFromSearch(search),
263
- ...updatedParams,
264
- };
265
- },
266
- [search],
267
- );
268
-
269
- const handleChangeParams = ({ target: { name, value } }) => {
270
- const currentParams = getSearchParams();
271
- const updatedParams = {
272
- ...currentParams,
273
- [name]: value,
274
- };
275
- const updatedSearch = getSearchParams({
276
- ...updatedParams,
277
- _start: name === '_q' ? 0 : updatedParams._start,
278
- _page: name === '_q' ? 1 : updatedParams._page,
279
- });
280
- const newSearch = generateSearchFromFilters(updatedSearch);
281
-
282
- if (name === '_limit') {
283
- emitEvent('willChangeNumberOfEntriesPerPage');
284
- }
285
-
286
- push({ search: newSearch });
287
- };
288
-
289
- return (
290
- <DataManagerContext.Provider
291
- value={{
292
- items,
293
- itemsTotal,
294
- search: getSearchParams(),
295
- getSearchParams,
296
- activeItem,
297
- initialData,
298
- isLoading,
299
- isLoadingForDetailsDataToBeSet,
300
- blockComment,
301
- blockCommentThread,
302
- resolveAbuseReport,
303
- isInDevelopmentMode,
304
- handleChangeParams,
305
- approveComment,
306
- rejectComment,
307
- }}
308
- >
309
- {isLoading ? (
310
- <LoadingIndicatorPage />
311
- ) : (
312
- <>
313
- <Container>
314
- <Search
315
- changeParams={handleChangeParams}
316
- initValue={getQueryParameters(search, '_q') || ''}
317
- model="Comments"
318
- value={getQueryParameters(search, '_q') || ''}
319
- />
320
- </Container>
321
- {children}
322
- </>
323
- )}
324
- </DataManagerContext.Provider>
325
- );
326
- };
327
-
328
- DataManagerProvider.propTypes = {
329
- children: PropTypes.node.isRequired,
330
- };
331
-
332
- export default memo(DataManagerProvider);
@@ -1,5 +0,0 @@
1
- function init(initialState) {
2
- return initialState;
3
- }
4
-
5
- export default init;
@@ -1,59 +0,0 @@
1
- import { fromJS } from 'immutable';
2
- import moment from 'moment';
3
- import {
4
- BLOCK_COMMENT,
5
- BLOCK_COMMENT_THREAD,
6
- GET_DATA,
7
- GET_DATA_SUCCEEDED,
8
- GET_SINGLE_DATA,
9
- GET_SINGLE_DATA_SUCCEEDED,
10
- RELOAD_PLUGIN,
11
- } from './actions';
12
-
13
- const initialState = fromJS({
14
- items: [],
15
- itemsTotal: 0,
16
- activeItem: undefined,
17
- isLoading: true,
18
- isLoadingForDataToBeSet: false,
19
- isLoadingForDetailsDataToBeSet: false,
20
- });
21
-
22
- const reducer = (state, action) => {
23
- switch (action.type) {
24
- case GET_DATA: {
25
- return state
26
- .removeIn('items')
27
- .update('isLoadingForDataToBeSet', () => true);
28
- }
29
- case GET_DATA_SUCCEEDED: {
30
- return state
31
- .update('items', () => fromJS(action.items.map(_ => ({
32
- ..._,
33
- isNew: moment(_.created_at).diff(moment(action.recentlyViewed), 'seconds') > 0,
34
- }))))
35
- .update('itemsTotal', () => fromJS(action.itemsTotal))
36
- .update('isLoading', () => false)
37
- .update('isLoadingForDataToBeSet', () => false);
38
- }
39
- case GET_SINGLE_DATA:
40
- case BLOCK_COMMENT:
41
- case BLOCK_COMMENT_THREAD: {
42
- return state
43
- .removeIn('activeItem')
44
- .update('isLoadingForDetailsDataToBeSet', () => true);
45
- }
46
- case GET_SINGLE_DATA_SUCCEEDED: {
47
- return state
48
- .update('activeItem', () => fromJS(action.activeItem))
49
- .update('isLoadingForDetailsDataToBeSet', () => false);
50
- }
51
- case RELOAD_PLUGIN:
52
- return initialState;
53
- default:
54
- return state;
55
- }
56
- };
57
-
58
- export default reducer;
59
- export { initialState };