strapi-plugin-comments 1.0.1 → 2.0.0-beta.1

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 (142) hide show
  1. package/.circleci/config.yml +2 -2
  2. package/.nvmrc +1 -1
  3. package/README.md +71 -95
  4. package/admin/src/components/ConfirmationDialog/index.js +56 -0
  5. package/admin/src/components/DiscussionStatus/index.js +33 -0
  6. package/admin/src/components/DiscussionThread/index.js +58 -0
  7. package/admin/src/components/DiscussionThreadItem/index.js +87 -0
  8. package/admin/src/components/DiscussionThreadItem/styles.js +87 -0
  9. package/admin/src/components/DiscussionThreadItemActions/index.js +176 -0
  10. package/admin/src/components/DiscussionThreadItemActions/styles.js +22 -0
  11. package/admin/src/components/DiscussionThreadItemMeta/index.js +31 -0
  12. package/admin/src/components/DiscussionThreadItemWarnings/index.js +137 -0
  13. package/admin/src/components/DiscussionThreadItemWarnings/styles.js +7 -0
  14. package/admin/src/components/EntityDetails/index.js +53 -0
  15. package/admin/src/{containers → components}/Initializer/index.js +4 -4
  16. package/admin/src/components/LoadingIndicatorOverlay/index.js +15 -0
  17. package/admin/src/components/LoadingIndicatorOverlay/styles.js +20 -0
  18. package/admin/src/components/Nav/index.js +45 -0
  19. package/admin/src/components/PluginIcon/index.js +12 -0
  20. package/admin/src/components/ReportsReviewModal/index.js +45 -0
  21. package/admin/src/components/ReportsReviewTable/index.js +142 -0
  22. package/admin/src/components/TableFilters/index.js +53 -0
  23. package/admin/src/components/TablePagination/index.js +35 -0
  24. package/admin/src/components/icons/comments.js +9 -0
  25. package/admin/src/index.js +56 -42
  26. package/admin/src/pages/App/index.js +32 -0
  27. package/admin/src/pages/ComingSoonPage/index.js +25 -0
  28. package/admin/src/pages/Details/index.js +109 -0
  29. package/admin/src/pages/Details/utils/api.js +41 -0
  30. package/admin/src/pages/Discover/index.js +185 -0
  31. package/admin/src/pages/Discover/utils/api.js +23 -0
  32. package/admin/src/pages/Discover/utils/filtersSchema.js +9 -0
  33. package/admin/src/permissions.js +13 -33
  34. package/admin/src/pluginId.js +2 -4
  35. package/admin/src/translations/en.json +72 -33
  36. package/admin/src/translations/fr.json +1 -0
  37. package/admin/src/utils/axiosInstance.js +35 -0
  38. package/admin/src/utils/constants.js +28 -0
  39. package/admin/src/utils/getApiUrl.js +5 -0
  40. package/admin/src/utils/getMessage.js +14 -0
  41. package/admin/src/utils/getRelatedGroups.js +5 -0
  42. package/admin/src/utils/getUrl.js +5 -0
  43. package/admin/src/utils/handleAPIError.js +15 -0
  44. package/admin/src/utils/index.js +6 -0
  45. package/codecov.yml +2 -1
  46. package/content-types/comment.js +97 -0
  47. package/content-types/index.js +11 -0
  48. package/content-types/report.js +54 -0
  49. package/package.json +12 -26
  50. package/server/bootstrap.js +5 -0
  51. package/server/config/index.js +6 -0
  52. package/server/controllers/admin.js +150 -0
  53. package/server/controllers/client.js +109 -0
  54. package/server/controllers/index.js +9 -0
  55. package/{controllers → server/controllers}/utils/__tests__/functions.test.js +0 -0
  56. package/{controllers → server/controllers}/utils/functions.js +1 -1
  57. package/server/destroy.js +5 -0
  58. package/server/index.js +22 -0
  59. package/server/register.js +5 -0
  60. package/server/routes/admin.js +92 -0
  61. package/server/routes/client.js +52 -0
  62. package/server/routes/index.js +15 -0
  63. package/server/services/admin.js +180 -0
  64. package/server/services/client.js +227 -0
  65. package/server/services/common.js +191 -0
  66. package/server/services/index.js +11 -0
  67. package/{services → server/services}/utils/__tests__/functions.test.js +7 -9
  68. package/{services → server/services}/utils/functions.js +19 -8
  69. package/server/utils/constants.js +16 -0
  70. package/{services → server}/utils/error.js +0 -0
  71. package/server/utils/functions.js +19 -0
  72. package/strapi-admin.js +3 -0
  73. package/strapi-server.js +9 -0
  74. package/admin/src/assets/images/icon-cross-blue.svg +0 -1
  75. package/admin/src/assets/images/icon_remove.svg +0 -19
  76. package/admin/src/assets/images/logo.svg +0 -5
  77. package/admin/src/components/AbuseReportsPopUp/ItemPreviewContainer.js +0 -8
  78. package/admin/src/components/AbuseReportsPopUp/ModalFooter.js +0 -31
  79. package/admin/src/components/AbuseReportsPopUp/TableContainer.js +0 -63
  80. package/admin/src/components/AbuseReportsPopUp/index.js +0 -148
  81. package/admin/src/components/Container/index.js +0 -7
  82. package/admin/src/components/EmptyView/index.js +0 -25
  83. package/admin/src/components/Filters/index.js +0 -151
  84. package/admin/src/components/Filters/index.styled.js +0 -82
  85. package/admin/src/components/Filters/utils.js +0 -21
  86. package/admin/src/components/Item/CardItem.js +0 -30
  87. package/admin/src/components/Item/CardWrapper.js +0 -10
  88. package/admin/src/components/Item/index.js +0 -92
  89. package/admin/src/components/ItemDetails/CardItem.js +0 -33
  90. package/admin/src/components/ItemDetails/CardLevelCounter.js +0 -46
  91. package/admin/src/components/ItemDetails/CardLevelCounterLink.js +0 -24
  92. package/admin/src/components/ItemDetails/CardLevelWrapper.js +0 -22
  93. package/admin/src/components/ItemDetails/CardWrapper.js +0 -52
  94. package/admin/src/components/ItemDetails/index.js +0 -151
  95. package/admin/src/components/ItemFooter/CardItemAuthor.js +0 -10
  96. package/admin/src/components/ItemFooter/CardItemRelation.js +0 -18
  97. package/admin/src/components/ItemFooter/Wrapper.js +0 -20
  98. package/admin/src/components/ItemFooter/index.js +0 -87
  99. package/admin/src/components/ItemHeader/CardHeaderBlocked.js +0 -24
  100. package/admin/src/components/ItemHeader/CardHeaderIndicator.js +0 -30
  101. package/admin/src/components/ItemHeader/CardHeaderIndicatorBlue.js +0 -11
  102. package/admin/src/components/ItemHeader/CardHeaderIndicatorRed.js +0 -11
  103. package/admin/src/components/ItemHeader/CardHeaderIndicatorsContainer.js +0 -18
  104. package/admin/src/components/ItemHeader/CardHeaderReports.js +0 -40
  105. package/admin/src/components/ItemHeader/Wrapper.js +0 -16
  106. package/admin/src/components/ItemHeader/index.js +0 -80
  107. package/admin/src/components/ItemModeration/Wrapper.js +0 -19
  108. package/admin/src/components/ItemModeration/index.js +0 -47
  109. package/admin/src/components/List/Container.js +0 -20
  110. package/admin/src/components/List/index.js +0 -21
  111. package/admin/src/components/Search/index.js +0 -83
  112. package/admin/src/containers/App/Wrapper.js +0 -14
  113. package/admin/src/containers/App/index.js +0 -47
  114. package/admin/src/containers/DataManagerProvider/actions.js +0 -11
  115. package/admin/src/containers/DataManagerProvider/index.js +0 -280
  116. package/admin/src/containers/DataManagerProvider/init.js +0 -5
  117. package/admin/src/containers/DataManagerProvider/reducer.js +0 -59
  118. package/admin/src/containers/DetailsView/Wrapper.js +0 -18
  119. package/admin/src/containers/DetailsView/index.js +0 -100
  120. package/admin/src/containers/ListView/FadedWrapper.js +0 -42
  121. package/admin/src/containers/ListView/Footer.js +0 -53
  122. package/admin/src/containers/ListView/Wrapper.js +0 -17
  123. package/admin/src/containers/ListView/components.js +0 -138
  124. package/admin/src/containers/ListView/index.js +0 -45
  125. package/admin/src/containers/Panel/actions.js +0 -5
  126. package/admin/src/containers/Panel/index.js +0 -191
  127. package/admin/src/containers/Panel/index.styled.js +0 -6
  128. package/admin/src/containers/Panel/reducer.js +0 -44
  129. package/admin/src/contexts/DataManagerContext.js +0 -5
  130. package/admin/src/hooks/useDataManager.js +0 -6
  131. package/admin/src/lifecycles.js +0 -3
  132. package/admin/src/translations/index.js +0 -7
  133. package/admin/src/utils/getTrad.js +0 -5
  134. package/admin/src/utils/getTradId.js +0 -5
  135. package/config/functions/bootstrap.js +0 -48
  136. package/config/routes.json +0 -124
  137. package/controllers/comments.js +0 -215
  138. package/models/comment.js +0 -8
  139. package/models/comment.settings.json +0 -90
  140. package/models/report.js +0 -8
  141. package/models/report.settings.json +0 -41
  142. package/services/comments.js +0 -478
@@ -0,0 +1,185 @@
1
+ /*
2
+ *
3
+ * Discover
4
+ *
5
+ */
6
+
7
+ import React, { memo, useRef, useMemo } from 'react';
8
+ import { useIntl } from 'react-intl';
9
+ import { useQuery } from 'react-query';
10
+ import { useHistory } from 'react-router-dom';
11
+ import { isEmpty } from 'lodash';
12
+ import { Badge } from '@strapi/design-system/Badge';
13
+ import { BaseCheckbox } from '@strapi/design-system/BaseCheckbox';
14
+ import { Box } from '@strapi/design-system/Box';
15
+ import { Flex } from '@strapi/design-system/Flex';
16
+ import { IconButton } from '@strapi/design-system/IconButton';
17
+ import { Layout, HeaderLayout, ActionLayout, ContentLayout } from '@strapi/design-system/Layout';
18
+ import { Table, Thead, Tbody, Tr, Th, Td } from '@strapi/design-system/Table';
19
+ import { Typography } from '@strapi/design-system/Typography';
20
+ import { VisuallyHidden } from '@strapi/design-system/VisuallyHidden';
21
+ import { useNotifyAT } from '@strapi/design-system/LiveRegions';
22
+ import { Eye } from '@strapi/icons';
23
+
24
+ import {
25
+ EmptyStateLayout,
26
+ SearchURLQuery,
27
+ LoadingIndicatorPage,
28
+ useTracking,
29
+ useNotification,
30
+ useRBAC,
31
+ useFocusWhenNavigate,
32
+ useQueryParams,
33
+ } from '@strapi/helper-plugin';
34
+ import getMessage from '../../utils/getMessage';
35
+ import { fetchData } from './utils/api';
36
+ import pluginPermissions from '../../permissions';
37
+
38
+ import getUrl from '../../utils/getUrl';
39
+ import Nav from '../../components/Nav';
40
+ import { COMMENT_STATUS } from '../../utils/constants';
41
+ import TablePagination from '../../components/TablePagination';
42
+ import filtersSchema from './utils/filtersSchema';
43
+ import TableFilters from '../../components/TableFilters';
44
+
45
+ const Discover = () => {
46
+ useFocusWhenNavigate();
47
+
48
+ const { push } = useHistory();
49
+ const { notifyStatus } = useNotifyAT();
50
+ const { trackUsage } = useTracking();
51
+ const trackUsageRef = useRef(trackUsage);
52
+ const toggleNotification = useNotification();
53
+ const { formatDate } = useIntl();
54
+ const [{ query: queryParams }] = useQueryParams();
55
+ const _q = queryParams?._q || '';
56
+
57
+ const viewPermissions = useMemo(() => {
58
+ return { view: pluginPermissions.view };
59
+ }, []);
60
+
61
+ const {
62
+ isLoading: isLoadingForPermissions,
63
+ allowedActions: { canView },
64
+ } = useRBAC(viewPermissions);
65
+
66
+ const { isLoading: isLoadingForData, data: { result, pagination = {} }, isFetching } = useQuery(
67
+ ['get-providers', queryParams],
68
+ () => fetchData(queryParams, toggleNotification),
69
+ {
70
+ initialData: { },
71
+ }
72
+ );
73
+
74
+ const handleClickDisplay = id => {
75
+ push(getUrl(`discover/${id}`));
76
+ };
77
+
78
+ const isLoading = isLoadingForData || isFetching;
79
+ const { total } = pagination;
80
+
81
+ const emptyLayout = {
82
+ comments: {
83
+ id: getMessage('page.discover.table.empty'),
84
+ defaultMessage: "You don't have any comments yet.",
85
+ },
86
+ search: {
87
+ id: getMessage('page.discover.table.empty.search'),
88
+ defaultMessage: 'No comments match the search.',
89
+ },
90
+ };
91
+
92
+ const renderStatus = ({ blocked, blockedThread }) => {
93
+ const status = blocked || blockedThread ? COMMENT_STATUS.BLOCKED : COMMENT_STATUS.OPEN;
94
+ let color = 'secondary';
95
+ switch (status) {
96
+ case COMMENT_STATUS.OPEN:
97
+ color = 'success';
98
+ break;
99
+ case COMMENT_STATUS.BLOCKED:
100
+ color = 'danger';
101
+ };
102
+ return (<Badge backgroundColor={`${color}100`} textColor={`${color}600`}>{ getMessage(`page.discover.table.header.status.${status}`, status) }</Badge>);
103
+ };
104
+
105
+ const emptyContent = _q ? 'search' : 'comments';
106
+
107
+ const COL_COUNT = 7;
108
+
109
+ return <Box background="neutral100">
110
+ <Layout sideNav={<Nav />}>
111
+ {isLoading || isLoadingForPermissions ? (<LoadingIndicatorPage />) : (
112
+ <>
113
+ <HeaderLayout title={ getMessage('page.discover.header') } subtitle={ `${total} ${ getMessage('page.discover.header.count')}` } as="h2" />
114
+ <ActionLayout
115
+ startActions={<>
116
+ <SearchURLQuery
117
+ label={ getMessage('search.label', 'Search', false) }
118
+ />
119
+ <TableFilters displayedFilters={filtersSchema} />
120
+ </>} />
121
+ <ContentLayout>
122
+ { !isEmpty(result) ? (<>
123
+ <Table colCount={COL_COUNT} rowCount={result.length}>
124
+ <Thead>
125
+ <Tr>
126
+ <Th>
127
+ <BaseCheckbox aria-label="Select all entries" />
128
+ </Th>
129
+ <Th>
130
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.message') }</Typography>
131
+ </Th>
132
+ <Th>
133
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.thread') }</Typography>
134
+ </Th>
135
+ <Th>
136
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.entry') }</Typography>
137
+ </Th>
138
+ <Th>
139
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.lastUpdate') }</Typography>
140
+ </Th>
141
+ <Th>
142
+ <Typography variant="sigma">{ getMessage('page.discover.table.header.status') }</Typography>
143
+ </Th>
144
+ <Th>
145
+ <VisuallyHidden>{ getMessage('page.discover.table.header.actions') }</VisuallyHidden>
146
+ </Th>
147
+ </Tr>
148
+ </Thead>
149
+ <Tbody>
150
+ {result.map(entry => <Tr key={entry.id}>
151
+ <Td>
152
+ <BaseCheckbox aria-label={`Select ${entry.content}`} />
153
+ </Td>
154
+ <Td style={{ maxWidth: '40vw' }}>
155
+ <Typography textColor="neutral800" ellipsis>{entry.content}</Typography>
156
+ </Td>
157
+ <Td>
158
+ <Typography textColor="neutral800">{entry.threadOf?.id || '-'}</Typography>
159
+ </Td>
160
+ <Td>
161
+ <Typography textColor="neutral800">{entry.related?.id}</Typography>
162
+ </Td>
163
+ <Td>
164
+ <Typography textColor="neutral800">{ formatDate(entry.updatedAt || entry.createdAt, { dateStyle: 'long', timeStyle: 'short' }) }</Typography>
165
+ </Td>
166
+ <Td>
167
+ <Typography textColor="neutral800">{ renderStatus(entry) }</Typography>
168
+ </Td>
169
+ <Td>
170
+ <Flex direction="column" alignItems="flex-end">
171
+ <IconButton onClick={() => handleClickDisplay(entry.id)} label={ getMessage('page.discover.table.action.display') } icon={<Eye />} />
172
+ </Flex>
173
+ </Td>
174
+ </Tr>)}
175
+ </Tbody>
176
+ </Table>
177
+ <TablePagination pagination={{ pageCount: pagination?.pageCount || 1 }} />
178
+ </>) : (<EmptyStateLayout content={emptyLayout[emptyContent]} />) }
179
+ </ContentLayout>
180
+ </>) }
181
+ </Layout>
182
+ </Box>;
183
+ }
184
+
185
+ export default memo(Discover);
@@ -0,0 +1,23 @@
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
+ console.log('api');
10
+ console.log(queryParams);
11
+ console.log(getApiURL(`moderate/all${!isEmpty(queryParams) ? `?${stringify(queryParams, { encode: false })}` : ''}`));
12
+ const { data } = await axiosInstance.get(getApiURL(`moderate/all${queryParams ? `?${stringify(queryParams, { encode: false })}` : ''}`));
13
+
14
+ return data;
15
+ } catch (err) {
16
+ toggleNotification({
17
+ type: 'warning',
18
+ message: { id: 'notification.error' },
19
+ });
20
+
21
+ throw new Error('error');
22
+ }
23
+ };
@@ -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;
@@ -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
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Comments Collection Type
3
+ */
4
+
5
+ module.exports = {
6
+ info: {
7
+ tableName: 'plugin-comments-comments',
8
+ singularName: 'comment',
9
+ pluralName: 'comments',
10
+ displayName: 'Comment',
11
+ description: 'Comment content type',
12
+ kind: 'collectionType',
13
+ },
14
+ options: {
15
+ draftAndPublish: false,
16
+ },
17
+ pluginOptions: {
18
+ 'content-manager': {
19
+ visible: false
20
+ },
21
+ 'content-type-builder': {
22
+ visible: false
23
+ }
24
+ },
25
+ attributes: {
26
+ content: {
27
+ type: 'text',
28
+ configurable: false,
29
+ required: true
30
+ },
31
+ blocked: {
32
+ type: 'boolean',
33
+ default: false,
34
+ configurable: false
35
+ },
36
+ blockedThread: {
37
+ type: 'boolean',
38
+ default: false,
39
+ configurable: false
40
+ },
41
+ blockReason: {
42
+ type: 'string',
43
+ configurable: false
44
+ },
45
+ authorUser: {
46
+ type: 'relation',
47
+ relation: 'oneToOne',
48
+ target: 'plugin::users-permissions.user',
49
+ configurable: false,
50
+ },
51
+ authorType: {
52
+ type: 'string',
53
+ configurable: false
54
+ },
55
+ authorId: {
56
+ type: 'string',
57
+ configurable: false
58
+ },
59
+ authorName: {
60
+ type: 'string',
61
+ configurable: false
62
+ },
63
+ authorEmail: {
64
+ type: 'email',
65
+ configurable: false
66
+ },
67
+ authorAvatar: {
68
+ type: 'string',
69
+ configurable: false
70
+ },
71
+ removed: {
72
+ type: 'boolean',
73
+ configurable: false
74
+ },
75
+ approvalStatus: {
76
+ type: 'string',
77
+ configurable: false
78
+ },
79
+ related: {
80
+ type: 'string',
81
+ configurable: false
82
+ },
83
+ reports: {
84
+ type: 'relation',
85
+ relation: 'oneToMany',
86
+ target: 'plugin::comments.comment-report',
87
+ mappedBy: 'related',
88
+ configurable: false,
89
+ },
90
+ threadOf: {
91
+ type: 'relation',
92
+ relation: 'oneToOne',
93
+ target: 'plugin::comments.comment',
94
+ configurable: false,
95
+ },
96
+ },
97
+ };
@@ -0,0 +1,11 @@
1
+ const CommentCT = require('./comment');
2
+ const ReportCT = require('./report');
3
+
4
+ module.exports = {
5
+ 'comment': {
6
+ schema: CommentCT,
7
+ },
8
+ 'comment-report': {
9
+ schema: ReportCT,
10
+ },
11
+ };