strapi-plugin-comments 1.0.2-beta.1 → 2.0.0-beta.2

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 (149) hide show
  1. package/.circleci/config.yml +2 -2
  2. package/README.md +71 -95
  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 +58 -0
  6. package/admin/src/components/DiscussionThreadItem/index.js +87 -0
  7. package/admin/src/components/DiscussionThreadItem/styles.js +87 -0
  8. package/admin/src/components/DiscussionThreadItemActions/index.js +176 -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 +137 -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 +45 -0
  20. package/admin/src/components/ReportsReviewTable/index.js +142 -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/index.js +58 -42
  25. package/admin/src/pages/App/index.js +60 -0
  26. package/admin/src/pages/App/reducer/actions.js +8 -0
  27. package/admin/src/pages/App/reducer/constants.js +4 -0
  28. package/admin/src/pages/App/reducer/index.js +27 -0
  29. package/admin/src/pages/App/reducer/init.js +7 -0
  30. package/admin/src/pages/App/reducer/selectors.js +35 -0
  31. package/admin/src/pages/App/utils/api.js +20 -0
  32. package/admin/src/pages/ComingSoonPage/index.js +25 -0
  33. package/admin/src/pages/Details/index.js +109 -0
  34. package/admin/src/pages/Details/utils/api.js +41 -0
  35. package/admin/src/pages/Discover/index.js +203 -0
  36. package/admin/src/pages/Discover/utils/api.js +20 -0
  37. package/admin/src/pages/Discover/utils/filtersSchema.js +9 -0
  38. package/admin/src/permissions.js +13 -33
  39. package/admin/src/pluginId.js +2 -4
  40. package/admin/src/reducers.js +8 -0
  41. package/admin/src/translations/en.json +72 -33
  42. package/admin/src/translations/fr.json +1 -0
  43. package/admin/src/utils/axiosInstance.js +35 -0
  44. package/admin/src/utils/constants.js +28 -0
  45. package/admin/src/utils/getApiUrl.js +5 -0
  46. package/admin/src/utils/getMessage.js +14 -0
  47. package/admin/src/utils/getRelatedGroups.js +5 -0
  48. package/admin/src/utils/getUrl.js +5 -0
  49. package/admin/src/utils/handleAPIError.js +15 -0
  50. package/admin/src/utils/index.js +6 -0
  51. package/codecov.yml +2 -1
  52. package/content-types/comment.js +97 -0
  53. package/content-types/index.js +11 -0
  54. package/content-types/report.js +54 -0
  55. package/package.json +11 -25
  56. package/server/bootstrap.js +5 -0
  57. package/server/config/index.js +10 -0
  58. package/server/controllers/admin.js +134 -0
  59. package/server/controllers/client.js +109 -0
  60. package/server/controllers/index.js +9 -0
  61. package/{controllers → server/controllers}/utils/__tests__/functions.test.js +0 -0
  62. package/{controllers → server/controllers}/utils/functions.js +1 -1
  63. package/server/destroy.js +5 -0
  64. package/server/index.js +22 -0
  65. package/server/register.js +5 -0
  66. package/server/routes/admin.js +92 -0
  67. package/server/routes/client.js +52 -0
  68. package/server/routes/index.js +15 -0
  69. package/server/services/admin.js +186 -0
  70. package/server/services/client.js +227 -0
  71. package/server/services/common.js +191 -0
  72. package/server/services/index.js +11 -0
  73. package/{services → server/services}/utils/__tests__/functions.test.js +7 -9
  74. package/{services → server/services}/utils/functions.js +19 -8
  75. package/server/utils/constants.js +16 -0
  76. package/{services → server}/utils/error.js +0 -0
  77. package/server/utils/functions.js +19 -0
  78. package/strapi-admin.js +3 -0
  79. package/strapi-server.js +9 -0
  80. package/admin/src/assets/images/icon-cross-blue.svg +0 -1
  81. package/admin/src/assets/images/icon_remove.svg +0 -19
  82. package/admin/src/assets/images/logo.svg +0 -5
  83. package/admin/src/components/AbuseReportsPopUp/ItemPreviewContainer.js +0 -8
  84. package/admin/src/components/AbuseReportsPopUp/ModalFooter.js +0 -31
  85. package/admin/src/components/AbuseReportsPopUp/TableContainer.js +0 -63
  86. package/admin/src/components/AbuseReportsPopUp/index.js +0 -148
  87. package/admin/src/components/Container/index.js +0 -7
  88. package/admin/src/components/EmptyView/index.js +0 -25
  89. package/admin/src/components/Filters/index.js +0 -151
  90. package/admin/src/components/Filters/index.styled.js +0 -82
  91. package/admin/src/components/Filters/utils.js +0 -21
  92. package/admin/src/components/Item/CardItem.js +0 -30
  93. package/admin/src/components/Item/CardWrapper.js +0 -10
  94. package/admin/src/components/Item/index.js +0 -92
  95. package/admin/src/components/ItemDetails/CardItem.js +0 -33
  96. package/admin/src/components/ItemDetails/CardLevelCounter.js +0 -46
  97. package/admin/src/components/ItemDetails/CardLevelCounterLink.js +0 -24
  98. package/admin/src/components/ItemDetails/CardLevelWrapper.js +0 -22
  99. package/admin/src/components/ItemDetails/CardWrapper.js +0 -52
  100. package/admin/src/components/ItemDetails/index.js +0 -151
  101. package/admin/src/components/ItemFooter/CardItemAuthor.js +0 -10
  102. package/admin/src/components/ItemFooter/CardItemRelation.js +0 -18
  103. package/admin/src/components/ItemFooter/Wrapper.js +0 -20
  104. package/admin/src/components/ItemFooter/index.js +0 -87
  105. package/admin/src/components/ItemHeader/CardHeaderBlocked.js +0 -24
  106. package/admin/src/components/ItemHeader/CardHeaderIndicator.js +0 -30
  107. package/admin/src/components/ItemHeader/CardHeaderIndicatorBlue.js +0 -11
  108. package/admin/src/components/ItemHeader/CardHeaderIndicatorRed.js +0 -11
  109. package/admin/src/components/ItemHeader/CardHeaderIndicatorsContainer.js +0 -18
  110. package/admin/src/components/ItemHeader/CardHeaderReports.js +0 -40
  111. package/admin/src/components/ItemHeader/Wrapper.js +0 -16
  112. package/admin/src/components/ItemHeader/index.js +0 -80
  113. package/admin/src/components/ItemModeration/Wrapper.js +0 -19
  114. package/admin/src/components/ItemModeration/index.js +0 -47
  115. package/admin/src/components/List/Container.js +0 -20
  116. package/admin/src/components/List/index.js +0 -21
  117. package/admin/src/components/Search/index.js +0 -83
  118. package/admin/src/containers/App/Wrapper.js +0 -14
  119. package/admin/src/containers/App/index.js +0 -47
  120. package/admin/src/containers/DataManagerProvider/actions.js +0 -11
  121. package/admin/src/containers/DataManagerProvider/index.js +0 -280
  122. package/admin/src/containers/DataManagerProvider/init.js +0 -5
  123. package/admin/src/containers/DataManagerProvider/reducer.js +0 -59
  124. package/admin/src/containers/DetailsView/Wrapper.js +0 -18
  125. package/admin/src/containers/DetailsView/index.js +0 -100
  126. package/admin/src/containers/ListView/FadedWrapper.js +0 -42
  127. package/admin/src/containers/ListView/Footer.js +0 -53
  128. package/admin/src/containers/ListView/Wrapper.js +0 -17
  129. package/admin/src/containers/ListView/components.js +0 -138
  130. package/admin/src/containers/ListView/index.js +0 -45
  131. package/admin/src/containers/Panel/actions.js +0 -5
  132. package/admin/src/containers/Panel/index.js +0 -191
  133. package/admin/src/containers/Panel/index.styled.js +0 -6
  134. package/admin/src/containers/Panel/reducer.js +0 -44
  135. package/admin/src/contexts/DataManagerContext.js +0 -5
  136. package/admin/src/hooks/useDataManager.js +0 -6
  137. package/admin/src/lifecycles.js +0 -3
  138. package/admin/src/translations/index.js +0 -7
  139. package/admin/src/utils/getTrad.js +0 -5
  140. package/admin/src/utils/getTradId.js +0 -5
  141. package/config/functions/bootstrap.js +0 -48
  142. package/config/routes.json +0 -116
  143. package/config/schema.graphql.js +0 -270
  144. package/controllers/comments.js +0 -211
  145. package/models/comment.js +0 -8
  146. package/models/comment.settings.json +0 -98
  147. package/models/report.js +0 -8
  148. package/models/report.settings.json +0 -49
  149. package/services/comments.js +0 -486
@@ -0,0 +1,41 @@
1
+ import { getApiURL, axiosInstance, handleAPIError } from '../../../utils';
2
+
3
+ // eslint-disable-next-line import/prefer-default-export
4
+ export const fetchDetailsData = async (id, toggleNotification) => {
5
+ try {
6
+ const { data } = await axiosInstance.get(getApiURL(`moderate/single/${id}`));
7
+
8
+ return data;
9
+ } catch (err) {
10
+ handleAPIError(err, toggleNotification);
11
+ }
12
+ };
13
+
14
+ export const fetchContentTypeData = async (uid, toggleNotification) => {
15
+ try {
16
+ const { data } = await axiosInstance.get(`/content-type-builder/content-types/${uid}`);
17
+ return data?.data;
18
+ } catch (err) {
19
+ handleAPIError(err, toggleNotification);
20
+ }
21
+ };
22
+
23
+ export const blockItem = id => {
24
+ return axiosInstance.patch(getApiURL(`moderate/single/${id}/block`));
25
+ };
26
+
27
+ export const unblockItem = id => {
28
+ return axiosInstance.patch(getApiURL(`moderate/single/${id}/unblock`));
29
+ };
30
+
31
+ export const blockItemThread = id => {
32
+ return axiosInstance.patch(getApiURL(`moderate/thread/${id}/block`));
33
+ };
34
+
35
+ export const unblockItemThread = id => {
36
+ return axiosInstance.patch(getApiURL(`moderate/thread/${id}/unblock`));
37
+ };
38
+
39
+ export const resolveReport = ({ id, reportId }) => {
40
+ return axiosInstance.patch(getApiURL(`moderate/single/${id}/report/${reportId}/resolve`));
41
+ };
@@ -0,0 +1,203 @@
1
+ /*
2
+ *
3
+ * Discover
4
+ *
5
+ */
6
+
7
+ import React, { memo, useRef, useMemo } from 'react';
8
+ import { connect } from 'react-redux';
9
+ import { bindActionCreators, compose } from 'redux';
10
+ import isEqual from 'react-fast-compare';
11
+ import { useIntl } from 'react-intl';
12
+ import { useQuery } from 'react-query';
13
+ import { useHistory } from 'react-router-dom';
14
+ import { isEmpty } from 'lodash';
15
+ import { Badge } from '@strapi/design-system/Badge';
16
+ import { BaseCheckbox } from '@strapi/design-system/BaseCheckbox';
17
+ import { Box } from '@strapi/design-system/Box';
18
+ import { Flex } from '@strapi/design-system/Flex';
19
+ import { IconButton } from '@strapi/design-system/IconButton';
20
+ import { Layout, HeaderLayout, ActionLayout, ContentLayout } from '@strapi/design-system/Layout';
21
+ import { Table, Thead, Tbody, Tr, Th, Td } from '@strapi/design-system/Table';
22
+ import { Typography } from '@strapi/design-system/Typography';
23
+ import { VisuallyHidden } from '@strapi/design-system/VisuallyHidden';
24
+ import { useNotifyAT } from '@strapi/design-system/LiveRegions';
25
+ import { Eye } from '@strapi/icons';
26
+
27
+ import {
28
+ EmptyStateLayout,
29
+ SearchURLQuery,
30
+ LoadingIndicatorPage,
31
+ useTracking,
32
+ useNotification,
33
+ useRBAC,
34
+ useFocusWhenNavigate,
35
+ useQueryParams,
36
+ } from '@strapi/helper-plugin';
37
+ import getMessage from '../../utils/getMessage';
38
+ import { fetchData } from './utils/api';
39
+ import pluginPermissions from '../../permissions';
40
+
41
+ import getUrl from '../../utils/getUrl';
42
+ import Nav from '../../components/Nav';
43
+ import { COMMENT_STATUS } from '../../utils/constants';
44
+ import TablePagination from '../../components/TablePagination';
45
+ import filtersSchema from './utils/filtersSchema';
46
+ import TableFilters from '../../components/TableFilters';
47
+ import appReducer from '../App/reducer';
48
+ import makeAppView, { selectConfig } from '../App/reducer/selectors';
49
+
50
+ const Discover = ({ config }) => {
51
+ useFocusWhenNavigate();
52
+
53
+ const { push } = useHistory();
54
+ const { notifyStatus } = useNotifyAT();
55
+ const { trackUsage } = useTracking();
56
+ const trackUsageRef = useRef(trackUsage);
57
+ const toggleNotification = useNotification();
58
+ const { formatDate } = useIntl();
59
+ const [{ query: queryParams }] = useQueryParams();
60
+ const _q = queryParams?._q || '';
61
+
62
+ const viewPermissions = useMemo(() => {
63
+ return { view: pluginPermissions.view };
64
+ }, []);
65
+
66
+ const {
67
+ isLoading: isLoadingForPermissions,
68
+ allowedActions: { canView },
69
+ } = useRBAC(viewPermissions);
70
+
71
+ const { isLoading: isLoadingForData, data: { result, pagination = {} }, isFetching } = useQuery(
72
+ ['get-providers', queryParams],
73
+ () => fetchData(queryParams, toggleNotification),
74
+ {
75
+ initialData: { },
76
+ }
77
+ );
78
+
79
+ const handleClickDisplay = id => {
80
+ push(getUrl(`discover/${id}`));
81
+ };
82
+
83
+ const isLoading = isLoadingForData || isFetching;
84
+ const { total } = pagination;
85
+
86
+ const emptyLayout = {
87
+ comments: {
88
+ id: getMessage('page.discover.table.empty'),
89
+ defaultMessage: "You don't have any comments yet.",
90
+ },
91
+ search: {
92
+ id: getMessage('page.discover.table.empty.search'),
93
+ defaultMessage: 'No comments match the search.',
94
+ },
95
+ };
96
+
97
+ const renderStatus = ({ blocked, blockedThread }) => {
98
+ const status = blocked || blockedThread ? COMMENT_STATUS.BLOCKED : COMMENT_STATUS.OPEN;
99
+ let color = 'secondary';
100
+ switch (status) {
101
+ case COMMENT_STATUS.OPEN:
102
+ color = 'success';
103
+ break;
104
+ case COMMENT_STATUS.BLOCKED:
105
+ color = 'danger';
106
+ };
107
+ return (<Badge backgroundColor={`${color}100`} textColor={`${color}600`}>{ getMessage(`page.discover.table.header.status.${status}`, status) }</Badge>);
108
+ };
109
+
110
+ const emptyContent = _q ? 'search' : 'comments';
111
+
112
+ const COL_COUNT = 7;
113
+
114
+ return <Box background="neutral100">
115
+ <Layout sideNav={<Nav />}>
116
+ {isLoading || isLoadingForPermissions ? (<LoadingIndicatorPage />) : (
117
+ <>
118
+ <HeaderLayout title={ getMessage('page.discover.header') } subtitle={ `${total} ${ getMessage('page.discover.header.count')}` } as="h2" />
119
+ <ActionLayout
120
+ startActions={<>
121
+ <SearchURLQuery
122
+ label={ getMessage('search.label', 'Search', false) }
123
+ />
124
+ <TableFilters displayedFilters={filtersSchema} />
125
+ </>} />
126
+ <ContentLayout>
127
+ { !isEmpty(result) ? (<>
128
+ <Table colCount={COL_COUNT} rowCount={result.length}>
129
+ <Thead>
130
+ <Tr>
131
+ <Th>
132
+ <BaseCheckbox aria-label="Select all entries" />
133
+ </Th>
134
+ <Th>
135
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.message') }</Typography>
136
+ </Th>
137
+ <Th>
138
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.thread') }</Typography>
139
+ </Th>
140
+ <Th>
141
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.entry') }</Typography>
142
+ </Th>
143
+ <Th>
144
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.lastUpdate') }</Typography>
145
+ </Th>
146
+ <Th>
147
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.status') }</Typography>
148
+ </Th>
149
+ <Th>
150
+ <VisuallyHidden>{ getMessage('page.discover.table.header.actions') }</VisuallyHidden>
151
+ </Th>
152
+ </Tr>
153
+ </Thead>
154
+ <Tbody>
155
+ {result.map(entry => <Tr key={entry.id}>
156
+ <Td>
157
+ <BaseCheckbox aria-label={`Select ${entry.content}`} />
158
+ </Td>
159
+ <Td style={{ maxWidth: '40vw' }}>
160
+ <Typography textColor="neutral800" ellipsis>{entry.content}</Typography>
161
+ </Td>
162
+ <Td>
163
+ <Typography textColor="neutral800">{entry.threadOf?.id || '-'}</Typography>
164
+ </Td>
165
+ <Td>
166
+ <Typography textColor="neutral800">{entry.related?.id}</Typography>
167
+ </Td>
168
+ <Td>
169
+ <Typography textColor="neutral800">{ formatDate(entry.updatedAt || entry.createdAt, { dateStyle: 'long', timeStyle: 'short' }) }</Typography>
170
+ </Td>
171
+ <Td>
172
+ <Typography textColor="neutral800">{ renderStatus(entry) }</Typography>
173
+ </Td>
174
+ <Td>
175
+ <Flex direction="column" alignItems="flex-end">
176
+ <IconButton onClick={() => handleClickDisplay(entry.id)} label={ getMessage('page.discover.table.action.display') } icon={<Eye />} />
177
+ </Flex>
178
+ </Td>
179
+ </Tr>)}
180
+ </Tbody>
181
+ </Table>
182
+ <TablePagination pagination={{ pageCount: pagination?.pageCount || 1 }} />
183
+ </>) : (<EmptyStateLayout content={emptyLayout[emptyContent]} />) }
184
+ </ContentLayout>
185
+ </>) }
186
+ </Layout>
187
+ </Box>;
188
+ }
189
+
190
+ const mapStateToProps = makeAppView();
191
+
192
+ export function mapDispatchToProps(dispatch) {
193
+ return bindActionCreators(
194
+ { },
195
+ dispatch
196
+ );
197
+ }
198
+ const withConnect = connect(
199
+ mapStateToProps,
200
+ mapDispatchToProps
201
+ );
202
+
203
+ export default compose(withConnect)(memo(Discover, isEqual));
@@ -0,0 +1,20 @@
1
+ import { stringify } from 'qs';
2
+ import { isEmpty } from 'lodash';
3
+
4
+ import { getApiURL, axiosInstance } from '../../../utils';
5
+
6
+ // eslint-disable-next-line import/prefer-default-export
7
+ export const fetchData = async (queryParams, toggleNotification) => {
8
+ try {
9
+ const { data } = await axiosInstance.get(getApiURL(`moderate/all${queryParams ? `?${stringify(queryParams, { encode: false })}` : ''}`));
10
+
11
+ return data;
12
+ } catch (err) {
13
+ toggleNotification({
14
+ type: 'warning',
15
+ message: { id: 'notification.error' },
16
+ });
17
+
18
+ throw new Error('error');
19
+ }
20
+ };
@@ -0,0 +1,9 @@
1
+ const filtersSchema = [
2
+ {
3
+ name: 'content',
4
+ metadatas: { label: 'Message' },
5
+ fieldSchema: { type: 'string' },
6
+ },
7
+ ];
8
+
9
+ export default filtersSchema;
@@ -1,34 +1,14 @@
1
1
  const pluginPermissions = {
2
- // This permission regards the main component (App) and is used to tell
3
- // If the plugin link should be displayed in the menu
4
- // And also if the plugin is accessible. This use case is found when a user types the url of the
5
- // plugin directly in the browser
6
- main: [
7
- { action: 'plugins::comments.read', subject: null },
8
- { action: 'plugins::comments.moderate.block.comment', subject: null },
9
- { action: 'plugins::comments.moderate.block.thread', subject: null },
10
- { action: 'plugins::comments.moderate.reports', subject: null },
11
- ],
12
- open: [
13
- { action: 'plugins::comments.read', subject: null },
14
- ],
15
- moderate: [
16
- { action: 'plugins::comments.read', subject: null },
17
- { action: 'plugins::comments.moderate.block.comment', subject: null },
18
- { action: 'plugins::comments.moderate.block.thread', subject: null },
19
- ],
20
- moderateComments: [
21
- { action: 'plugins::comments.read', subject: null },
22
- { action: 'plugins::comments.moderate.block.comment', subject: null },
23
- ],
24
- moderateThreads: [
25
- { action: 'plugins::comments.read', subject: null },
26
- { action: 'plugins::comments.moderate.block.thread', subject: null },
27
- ],
28
- moderateReports: [
29
- { action: 'plugins::comments.read', subject: null },
30
- { action: 'plugins::comments.moderate.reports', subject: null },
31
- ],
32
- };
33
-
34
- export default pluginPermissions;
2
+ access: [
3
+ { action: 'plugin::comments.read', subject: null },
4
+ { action: 'plugin::comments.reports.read', subject: null },
5
+ { action: 'plugin::comments.discovery.read', subject: null },
6
+ { action: 'plugin::comments.settings.read', subject: null },
7
+ ],
8
+ discover: [{ action: 'plugin::comments.read', subject: null }],
9
+ moderate: [{ action: 'plugin::comments.moderate', subject: null }],
10
+ reports: [{ action: 'plugin::comments.reports.read', subject: null }],
11
+ reportsReview: [{ action: 'plugin::comments.reports.action', subject: null }],
12
+ };
13
+
14
+ export default pluginPermissions;
@@ -1,7 +1,5 @@
1
1
  const pluginPkg = require('../../package.json');
2
- const pluginId = pluginPkg.name.replace(
3
- /^strapi-plugin-/i,
4
- ''
5
- );
2
+
3
+ const pluginId = pluginPkg.name.replace(/^strapi-plugin-/i, '');
6
4
 
7
5
  module.exports = pluginId;
@@ -0,0 +1,8 @@
1
+ import appReducer from './pages/App/reducer';
2
+ import { REDUCER_NAME } from './pages/App/reducer/constants';
3
+
4
+ const reducers = {
5
+ [`${REDUCER_NAME}`]: appReducer,
6
+ };
7
+
8
+ export default reducers;
@@ -1,35 +1,74 @@
1
1
  {
2
2
  "plugin.name": "Comments",
3
- "components.Search.placeholder": "Search for an entry...",
4
- "list.header.title": "Comments",
5
- "list.header.description": "{count, plural, =0 {All available} one {# new comment} other {# new comments}}",
6
- "list.content.empty": "Nothing found, lift your search criteria and try again",
7
- "list.item.header.blocked": "This comment has been blocked",
8
- "list.item.header.blocked.thread": "This comment and thread have been blocked",
9
- "list.item.header.removed": "This comment and thread have been removed by author",
10
- "list.item.indication.new": "New comment",
11
- "list.item.indication.abuse": "Abuse reported",
12
- "list.item.threads.drilldown": "Drilldown",
13
- "list.item.threads.count": "{count, plural, =0 {There is no threads} one {# thread} other {# threads}}",
14
- "list.item.header.abuse": "{count, plural, =0 {Nothing reported} one {# report waits for review} other {# reports waits for review}}",
15
- "list.item.moderation.button.comment.restore": "Restore comment",
16
- "list.item.moderation.button.comment.hide": "Hide comment",
17
- "list.item.moderation.button.thread.restore": "Restore thread",
18
- "list.item.moderation.button.thread.hide": "Hide thread",
19
- "moderation.header.title": "Moderation",
20
- "moderation.header.description": "Discussion thread",
21
- "moderation.content.empty": "Choose a comment to start moderating",
22
- "popup.reports.header": "Review - Abuse reports",
23
- "popup.reports.item.header.date": "Issue date",
24
- "popup.reports.item.header.reason": "Reason",
25
- "popup.reports.item.header.message": "Message",
26
- "popup.reports.item.reason.other": "Other",
27
- "popup.reports.item.reason.discrimination": "Discrimination",
28
- "popup.reports.item.reason.bad_language": "Bad language used",
29
- "popup.reports.item.button": "Resolve",
30
- "popup.reports.footer.actions": "Moderator actions:",
31
- "popup.reports.empty": "All good, no issues reported",
32
- "notification.comment.visibility": "Comment visibility has been changed",
33
- "notification.thread.visibility": "Comment thread visibility has been changed",
34
- "notification.abuse-report.resolution": "Abuse report has been resolved"
35
- }
3
+ "common.button.back": "Go back",
4
+ "nav.header.moderation": "Moderation",
5
+ "nav.header.settings": "Settings",
6
+ "nav.item.updates": "Updates",
7
+ "nav.item.discover": "Discover",
8
+ "nav.item.reports": "Reports",
9
+ "nav.item.settings": "Settings",
10
+ "page.updates.header": "Recent updates",
11
+ "page.discover.header": "Discover threads",
12
+ "page.discover.header.count": "entries found",
13
+ "page.discover.table.header.message": "Message",
14
+ "page.discover.table.header.thread": "Thread of",
15
+ "page.discover.table.header.entry": "Entry",
16
+ "page.discover.table.header.lastUpdate": "Last update",
17
+ "page.discover.table.header.status": "Status",
18
+ "page.discover.table.header.status.OPEN": "OPEN",
19
+ "page.discover.table.header.status.BLOCKED": "BLOCKED",
20
+ "page.discover.table.header.status.TO_REVIEW": "TO REVIEW",
21
+ "page.discover.table.header.actions": "Status",
22
+ "page.discover.table.action.display": "Display",
23
+ "page.discover.table.action.reports": "Reports",
24
+ "page.discover.table.empty": "You don't have any comments yet.",
25
+ "page.discover.table.empty.search": "No comments match the search.",
26
+ "page.discover.table.filters": "Filtering",
27
+ "page.details.header": "Discussion panel",
28
+ "page.details.header.description": "Drilldown and manage discussion related to the entity",
29
+ "page.details.panel.discussion": "Discussion",
30
+ "page.details.panel.discussion.nav.drilldown": "Drilldown",
31
+ "page.details.panel.discussion.nav.back": "Go top",
32
+ "page.details.panel.discussion.warnings.reports.description": "open reports",
33
+ "page.details.panel.discussion.warnings.reports.review": "Review",
34
+ "page.details.panel.discussion.warnings.reports.dialog.list": "Reports",
35
+ "page.details.panel.discussion.warnings.reports.dialog.header": "Moderation: Review open reports",
36
+ "page.details.panel.discussion.warnings.reports.dialog.reason": "Reason",
37
+ "page.details.panel.discussion.warnings.reports.dialog.reason.BAD_LANGUAGE": "Bad language",
38
+ "page.details.panel.discussion.warnings.reports.dialog.reason.DISCRIMINATION": "Discrimination",
39
+ "page.details.panel.discussion.warnings.reports.dialog.reason.OTHER": "Other",
40
+ "page.details.panel.discussion.warnings.reports.dialog.content": "Content",
41
+ "page.details.panel.discussion.warnings.reports.dialog.createdAt": "Issue date",
42
+ "page.details.panel.discussion.warnings.reports.dialog.status": "Status",
43
+ "page.details.panel.discussion.warnings.reports.dialog.status.OPEN": "OPEN",
44
+ "page.details.panel.discussion.warnings.reports.dialog.status.RESOLVED": "RESOLVED",
45
+ "page.details.panel.discussion.warnings.reports.dialog.actions": "Actions",
46
+ "page.details.panel.discussion.warnings.reports.dialog.actions.resolve": "Resolve",
47
+ "page.details.panel.discussion.warnings.reports.dialog.confirmation.success": "Open report has been resolved",
48
+ "page.details.panel.discussion.status.blocked": "BLOCKED",
49
+ "page.details.panel.entity": "Entity details",
50
+ "page.details.panel.status": "Discussion is",
51
+ "page.details.panel.status.open": "OPEN",
52
+ "page.details.panel.status.blocked": "BLOCKED",
53
+ "page.details.panel.status.pending": "PENDING",
54
+ "page.details.actions.comment.block": "Block comment",
55
+ "page.details.actions.comment.block.confirmation.header": "Moderation: Block comment",
56
+ "page.details.actions.comment.block.confirmation.description": "Do you really want to block this comment?",
57
+ "page.details.actions.comment.block.confirmation.button.confirm": "Yes, block it",
58
+ "page.details.actions.comment.block.confirmation.success": "Comment has been blocked",
59
+ "page.details.actions.comment.unblock": "Unblock comment",
60
+ "page.details.actions.comment.unblock.confirmation.success": "Comment has been unblocked",
61
+ "page.details.actions.comment.reports.review": "Review",
62
+ "page.details.actions.thread.block": "Block thread",
63
+ "page.details.actions.thread.block.confirmation.header": "Moderation: Block thread",
64
+ "page.details.actions.thread.block.confirmation.description": "Do you really want to block whole thread? No further discussions are going to be allowed.",
65
+ "page.details.actions.thread.block.confirmation.button.confirm": "Yes, block it",
66
+ "page.details.actions.thread.block.confirmation.success": "Thread has been blocked",
67
+ "page.details.actions.thread.unblock": "Unblock thread",
68
+ "page.details.actions.thread.unblock.confirmation.success": "Thread has been unblocked",
69
+ "page.coming.soon": "Wait for what is coming soon...",
70
+ "compontents.confirmation.dialog.header": "Confirmation",
71
+ "compontents.confirmation.dialog.description": "Do you really want to perform this action?",
72
+ "compontents.confirmation.dialog.button.confirm": "Yes, I do",
73
+ "compontents.confirmation.dialog.button.cancel": "Cancel"
74
+ }
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1,35 @@
1
+ import axios from 'axios';
2
+ import { auth } from '@strapi/helper-plugin';
3
+
4
+ const instance = axios.create({
5
+ baseURL: process.env.STRAPI_ADMIN_BACKEND_URL,
6
+ });
7
+
8
+ instance.interceptors.request.use(
9
+ async config => {
10
+ config.headers = {
11
+ Authorization: `Bearer ${auth.getToken()}`,
12
+ Accept: 'application/json',
13
+ 'Content-Type': 'application/json',
14
+ };
15
+
16
+ return config;
17
+ },
18
+ error => {
19
+ Promise.reject(error);
20
+ }
21
+ );
22
+
23
+ instance.interceptors.response.use(
24
+ response => response,
25
+ error => {
26
+ if (error.response?.status === 401) {
27
+ auth.clearAppStorage();
28
+ window.location.reload();
29
+ }
30
+
31
+ throw error;
32
+ }
33
+ );
34
+
35
+ export default instance;
@@ -0,0 +1,28 @@
1
+ export const APPROVAL_STATUS = {
2
+ PENDING: "PENDING",
3
+ APPROVED: "APPROVED",
4
+ REJECTED: "REJECTED",
5
+ };
6
+
7
+ export const REPORT_STATUS = {
8
+ 'RESOLVED': 'RESOLVED',
9
+ 'OPEN': 'OPEN',
10
+ };
11
+
12
+ export const REPORT_REASON = {
13
+ 'BAD_LANGUAGE': 'BAD_LANGUAGE',
14
+ 'DISCRIMINATION': 'DISCRIMINATION',
15
+ 'OTHER': 'OTHER',
16
+ };
17
+
18
+ export const COMMENT_STATUS = {
19
+ 'BLOCKED': 'BLOCKED',
20
+ 'OPEN': 'OPEN',
21
+ 'TO_REVIEW': 'TO_REVIEW',
22
+ };
23
+
24
+ export const REGEX = {
25
+ uid: new RegExp(/^(?<type>[a-z]+)\:{2}(?<api>[a-z]+)\.{1}(?<contentType>[a-z]+)$/gmi),
26
+ relatedUid: new RegExp(/^(?<uid>[a-z]+\:{2}[a-z]+\.[a-z]+)\:{1}(?<id>[0-9]+)$/gmi),
27
+ email: new RegExp(/\S+@\S+\.\S+/),
28
+ };
@@ -0,0 +1,5 @@
1
+ import pluginId from '../pluginId';
2
+
3
+ const getApiURL = endPoint => `/${pluginId}/${endPoint}`;
4
+
5
+ export default getApiURL;
@@ -0,0 +1,14 @@
1
+
2
+ import { useIntl } from 'react-intl';
3
+
4
+ import pluginId from '../pluginId';
5
+
6
+ const getMessage = (id, defaultMessage, inPluginScope = true) => {
7
+ const { formatMessage } = useIntl();
8
+ return formatMessage({
9
+ id: `${inPluginScope ? pluginId : 'app.component'}.${id}`,
10
+ defaultMessage,
11
+ })
12
+ };
13
+
14
+ export default getMessage;
@@ -0,0 +1,5 @@
1
+ import { REGEX } from "./constants";
2
+
3
+ const getRelatedGroups = related => related.split(REGEX.relatedUid).filter(s => s && s.length > 0);
4
+
5
+ export default getRelatedGroups;
@@ -0,0 +1,5 @@
1
+ import pluginId from '../pluginId';
2
+
3
+ const getUrl = (path = '') => `/plugins/${pluginId}/${path}`;
4
+
5
+ export default getUrl;
@@ -0,0 +1,15 @@
1
+
2
+ const handleAPIError = (err = null, toggleNotification = null) => {
3
+ toggleNotification({
4
+ type: 'warning',
5
+ message: { id: 'notification.error' },
6
+ });
7
+
8
+ if (err) {
9
+ throw err;
10
+ } else {
11
+ throw new Error('error');
12
+ }
13
+ }
14
+
15
+ export default handleAPIError;
@@ -0,0 +1,6 @@
1
+ export { default as axiosInstance } from './axiosInstance';
2
+ export { default as getApiURL } from './getApiURL';
3
+ export { default as getUrl } from './getUrl';
4
+ export { default as getMessage } from './getMessage';
5
+ export { default as handleAPIError } from './handleAPIError';
6
+ export { default as getRelatedGroups } from './getRelatedGroups';
package/codecov.yml CHANGED
@@ -1,3 +1,4 @@
1
1
  comment:
2
2
  branches:
3
- - master
3
+ - master
4
+ - feat/strapi-v4