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,18 +0,0 @@
1
- import styled from 'styled-components';
2
-
3
- import { colors } from 'strapi-helper-plugin';
4
-
5
- const Wrapper = styled.div`
6
- display: flex;
7
- flex-direction: column;
8
- width: 100%;
9
- background-color: ${colors.leftMenu.mediumGrey};
10
- padding-top: 1.8rem;
11
- padding-left: 2rem;
12
- padding-right: 2rem;
13
-
14
- overflow-x: hidden;
15
- overflow-y: auto;
16
- `;
17
-
18
- export default Wrapper;
@@ -1,106 +0,0 @@
1
- /*
2
- *
3
- * DetailsView
4
- *
5
- */
6
-
7
- import React from 'react';
8
- import { useHistory } from 'react-router-dom';
9
- import { FormattedMessage } from 'react-intl';
10
- import { isNil } from 'lodash';
11
- import { useGlobalContext, LoadingIndicatorPage } from 'strapi-helper-plugin';
12
- import { Header } from '@buffetjs/custom';
13
-
14
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
15
- import { faComments } from '@fortawesome/free-solid-svg-icons';
16
-
17
- import Wrapper from './Wrapper';
18
- import ItemDetails from '../../components/ItemDetails';
19
- import CardWrapper from '../../components/ItemDetails/CardWrapper';
20
- import CardLevelWrapper from '../../components/ItemDetails/CardLevelWrapper';
21
- import EmptyView from '../../components/EmptyView';
22
-
23
- import pluginId from '../../pluginId';
24
- import getTradId from '../../utils/getTradId';
25
- import getTrad from '../../utils/getTrad';
26
-
27
- import useDataManager from '../../hooks/useDataManager';
28
-
29
- const DetailsView = () => {
30
- const {
31
- activeItem,
32
- isLoadingForDetailsDataToBeSet,
33
- blockComment,
34
- blockCommentThread,
35
- resolveAbuseReport,
36
- approveComment,
37
- rejectComment,
38
- } = useDataManager();
39
-
40
- const { formatMessage } = useGlobalContext();
41
- const { push } = useHistory();
42
-
43
- const onCommentClick = (e, id) => {
44
- e.preventDefault();
45
- e.stopPropagation();
46
- push(`/plugins/${pluginId}/display/${id}`)
47
- }
48
-
49
- const renderCommentsTree = (selected, items) => {
50
- return (<CardLevelWrapper>
51
- {
52
- items.map((item, n) => {
53
- const active = item.id === selected.id;
54
- const threadsCount = item.children && item.children.length;
55
- const hasThreads = threadsCount > 0;
56
- const clickable = !active && hasThreads && !isNil(selected.threadOf);
57
- return (<ItemDetails
58
- key={`list-item-details-${item.id || n}`}
59
- {...item}
60
- active={active}
61
- root={selected.threadOf === null}
62
- clickable={clickable}
63
- threadsCount={threadsCount}
64
- onAbuseReportResolve={resolveAbuseReport}
65
- onBlockClick={blockComment}
66
- onBlockThreadClick={blockCommentThread}
67
- onClick={e => onCommentClick(e, hasThreads ? item.children[0].id : item.id)}
68
- onApproveCommentClick={approveComment}
69
- onRejectCommentClick={rejectComment}
70
- />)
71
- })
72
- }
73
- </CardLevelWrapper>)
74
- }
75
-
76
- const { selected, level } = activeItem || {};
77
-
78
- return (
79
- <Wrapper className="col-md-8">
80
- {isLoadingForDetailsDataToBeSet && <LoadingIndicatorPage />}
81
- {!isLoadingForDetailsDataToBeSet && !activeItem && (<EmptyView fixPosition>
82
- <FontAwesomeIcon icon={faComments} size="5x" />
83
- <FormattedMessage id={getTrad('moderation.content.empty')} />
84
- </EmptyView>)}
85
- {activeItem && (<>
86
- {selected.threadOf && (<CardLevelWrapper>
87
- <ItemDetails
88
- {...selected.threadOf}
89
- clickable={true}
90
- root={true}
91
- onAbuseReportResolve={resolveAbuseReport}
92
- onClick={e => onCommentClick(e, selected.threadOf.id)}
93
- onApproveCommentClick={approveComment}
94
- onRejectCommentClick={rejectComment}
95
- />
96
- <CardWrapper root={true}>
97
- {renderCommentsTree(selected, level)}
98
- </CardWrapper>
99
- </CardLevelWrapper>)}
100
- {!selected.threadOf && renderCommentsTree(selected, level)}
101
- </>)}
102
- </Wrapper>
103
- );
104
- };
105
-
106
- export default DetailsView;
@@ -1,42 +0,0 @@
1
- import styled from 'styled-components';
2
-
3
- import { colors, sizes } from 'strapi-helper-plugin';
4
-
5
- const FadedWrapper = styled.div`
6
- display: flex;
7
- flex-direction: column;
8
- flex-grow: 1;
9
- padding: 0;
10
- margin: ${-2*sizes.margin}px;
11
-
12
- position: relative;
13
- z-index: 0;
14
-
15
- overflow: hidden;
16
-
17
- &:before,
18
- &:after {
19
- display: block;
20
- content: '';
21
- height: ${4*sizes.margin}px;
22
-
23
- position: absolute;
24
- left: 0;
25
- right: 0;
26
- z-index: 1;
27
-
28
- background: #ffffff;
29
- }
30
-
31
- &:before {
32
- top: 0;
33
- background: linear-gradient(180deg, rgba(250,250,251,1) 0%, rgba(250,250,251,0) 100%);
34
- }
35
-
36
- &:after {
37
- bottom: 0;
38
- background: linear-gradient(0deg, rgba(250,250,251,1) 0%, rgba(250,250,251,0) 100%);
39
- }
40
- `;
41
-
42
- export default FadedWrapper;
@@ -1,53 +0,0 @@
1
- import React, { memo } from 'react';
2
- import { FormattedMessage } from 'react-intl';
3
- import { GlobalPagination, InputSelect, sizes } from 'strapi-helper-plugin';
4
- import useDataManager from '../../hooks/useDataManager';
5
- import { FooterWrapper, SelectWrapper, Label } from './components';
6
-
7
- function Footer() {
8
- const {
9
- search: { _limit, _page },
10
- itemsTotal,
11
- handleChangeParams
12
- } = useDataManager();
13
-
14
- return (
15
- <FooterWrapper className="row">
16
- <div className="col-6">
17
- <SelectWrapper style={{ marginBottom: `${2*sizes.margin}px` }}>
18
- <InputSelect
19
- style={{ width: '75px', height: '32px', marginTop: '-1px' }}
20
- name="_limit"
21
- onChange={handleChangeParams}
22
- selectOptions={['10', '20', '50', '100']}
23
- value={_limit}
24
- />
25
- <Label htmlFor="_limit" style={{
26
- textOverflow: 'ellipsis',
27
- overflow: 'hidden',
28
- display: 'inline-block',
29
- whiteSpace: 'nowrap'
30
- }}>
31
- <FormattedMessage id="components.PageFooter.select" />
32
- </Label>
33
- </SelectWrapper>
34
- </div>
35
- <div className="col-6">
36
- <GlobalPagination
37
- style={{ marginBottom: `${2*sizes.margin}px` }}
38
- count={itemsTotal}
39
- onChangeParams={({ target: { value } }) => {
40
- handleChangeParams({ target: { name: '_page', value } });
41
- }}
42
- params={{
43
- currentPage: parseInt(_page, 10),
44
- _limit: parseInt(_limit, 10),
45
- _page: parseInt(_page, 10),
46
- }}
47
- />
48
- </div>
49
- </FooterWrapper>
50
- );
51
- }
52
-
53
- export default memo(Footer);
@@ -1,17 +0,0 @@
1
- import styled from 'styled-components';
2
-
3
- import { sizes } from 'strapi-helper-plugin';
4
-
5
- const Wrapper = styled.div`
6
- display: flex;
7
- flex-direction: column;
8
- width: 100%;
9
- height: calc(100vh - ${sizes.header.height} - 15rem);
10
- min-height: calc(100vh - ${sizes.header.height} - 15rem);
11
- max-height: calc(100vh - ${sizes.header.height});
12
- padding-top: 1.8rem;
13
- padding-left: 2rem;
14
- padding-right: 2rem;
15
- `;
16
-
17
- export default Wrapper;
@@ -1,138 +0,0 @@
1
- import styled from 'styled-components';
2
- import { Button, FilterIcon as Filter } from 'strapi-helper-plugin';
3
- import RemoveIcon from '../../assets/images/icon-cross-blue.svg';
4
-
5
- const Wrapper = styled.div`
6
- padding-top: 1px;
7
- `;
8
-
9
- const FilterIcon = styled(Filter)`
10
- padding: 0 !important;
11
- margin: auto !important;
12
- > g {
13
- stroke: #282b2c;
14
- }
15
- `;
16
-
17
- const AddFilterCta = styled(Button)`
18
- display: flex;
19
- height: 30px;
20
- margin-right: 10px;
21
- padding: 0 10px;
22
- text-align: center;
23
- background-color: #ffffff;
24
- border: 1px solid #e3e9f3;
25
- border-radius: 2px;
26
- line-height: 28px;
27
- font-size: 13px;
28
- font-weight: 500;
29
- font-family: Lato;
30
- -webkit-font-smoothing: antialiased;
31
- cursor: pointer;
32
- &:hover {
33
- background: #f7f8f8;
34
- }
35
- &:focus,
36
- &:active {
37
- outline: 0;
38
- }
39
- > span {
40
- margin-left: 10px;
41
- }
42
- `;
43
-
44
- const Img = styled.img`
45
- height: 7px;
46
- margin: auto;
47
- margin-right: 0px;
48
- font-size: 12px;
49
- `;
50
-
51
- const FooterWrapper = styled.div`
52
- padding-top: 3rem;
53
- `;
54
-
55
- const Label = styled.label`
56
- display: inline-block;
57
- height: 32px;
58
- margin-left: 10px;
59
- line-height: 32px;
60
- color: #787e8f;
61
- font-size: 13px;
62
- font-style: italic;
63
- `;
64
-
65
- const SelectWrapper = styled.div`
66
- display: flex;
67
- `;
68
-
69
- const FilterWrapper = styled.div`
70
- display: inline-block;
71
- height: 30px;
72
- margin-bottom: 6px;
73
- margin-right: 10px;
74
- padding: 0 10px;
75
- background: rgba(0, 126, 255, 0.08);
76
- border: 1px solid rgba(0, 126, 255, 0.24);
77
- border-radius: 2px;
78
- line-height: 28px;
79
- color: #007eff;
80
- font-size: 13px;
81
-
82
- > span {
83
- display: inline-block;
84
- margin-top: -1px;
85
- }
86
-
87
- > span:nth-child(2) {
88
- font-weight: 700;
89
- }
90
-
91
- > span:nth-child(3) {
92
- cursor: pointer;
93
- }
94
-
95
- -webkit-font-smoothing: antialiased;
96
- `;
97
-
98
- const Separator = styled.span`
99
- height: 30px;
100
- margin-left: 10px;
101
- margin-right: 10px;
102
- line-height: 30px;
103
- &:after {
104
- content: '';
105
- height: 15px;
106
- border-left: 1px solid #007eff;
107
- opacity: 0.1;
108
- }
109
- `;
110
-
111
- const Remove = styled.span`
112
- height: 28px;
113
- cursor: pointer;
114
- vertical-align: middle;
115
-
116
- &:after {
117
- display: inline-block;
118
- content: '';
119
- width: 8px;
120
- height: 8px;
121
- margin: auto;
122
- margin-top: -3px;
123
- background-image: url(${RemoveIcon});
124
- }
125
- `;
126
-
127
- export {
128
- AddFilterCta,
129
- FilterIcon,
130
- FooterWrapper,
131
- Img,
132
- Label,
133
- SelectWrapper,
134
- FilterWrapper,
135
- Separator,
136
- Remove,
137
- Wrapper,
138
- };
@@ -1,45 +0,0 @@
1
- /*
2
- *
3
- * ListView
4
- *
5
- */
6
-
7
- import React from 'react';
8
- import { LoadingIndicatorPage } from 'strapi-helper-plugin';
9
- import { FormattedMessage } from 'react-intl';
10
- import { isEmpty } from 'lodash';
11
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
12
- import { faSearch } from '@fortawesome/free-solid-svg-icons';
13
-
14
- import Footer from './Footer';
15
- import Wrapper from './Wrapper';
16
- import FadedWrapper from './FadedWrapper';
17
-
18
- import List from '../../components/List';
19
- import EmptyView from '../../components/EmptyView';
20
-
21
- import useDataManager from '../../hooks/useDataManager';
22
-
23
- import getTrad from '../../utils/getTrad';
24
-
25
- const ListView = ({ relatedContentTypes }) => {
26
- const { items, isLoadingForDataToBeSet } = useDataManager();
27
-
28
- return (
29
- <Wrapper className="col-md-4">
30
- {isLoadingForDataToBeSet && <LoadingIndicatorPage />}
31
- <FadedWrapper>
32
- {isEmpty(items) && (
33
- <EmptyView>
34
- <FontAwesomeIcon icon={faSearch} size="5x" />
35
- <FormattedMessage id={getTrad('list.content.empty')} />
36
- </EmptyView>
37
- )}
38
- {!isEmpty(items) && <List items={[...items]} relatedContentTypes={relatedContentTypes} />}
39
- </FadedWrapper>
40
- <Footer />
41
- </Wrapper>
42
- );
43
- };
44
-
45
- export default ListView;
@@ -1,5 +0,0 @@
1
- export const GET_CONFIG = 'GET_CONFIG';
2
- export const GET_CONFIG_SUCCESS = 'GET_CONFIG_SUCCESS';
3
-
4
- export const GET_CONTENT_LIST_CONTENT_TYPE = 'GET_CONTENT_LIST_CONTENT_TYPE';
5
- export const GET_CONTENT_LIST_CONTENT_TYPE_SUCCEEDED = 'GET_CONTENT_LIST_CONTENT_TYPE_SUCCEEDED'
@@ -1,191 +0,0 @@
1
- /*
2
- *
3
- * CommentsPanel
4
- *
5
- */
6
-
7
- import React, { memo, useEffect, useReducer, useState } from 'react';
8
- import { useHistory } from 'react-router-dom';
9
- import { generateSearchFromFilters, PluginHeader, request, useGlobalContext } from 'strapi-helper-plugin';
10
- import { camelCase, get, isEmpty } from 'lodash';
11
-
12
- import ListView from '../ListView';
13
- import DetailsView from '../DetailsView';
14
- import Filters from '../../components/Filters';
15
- import { initFilters, isRelatedFilter } from '../../components/Filters/utils';
16
- import getTradId from '../../utils/getTradId';
17
- import useDataManager from '../../hooks/useDataManager';
18
- import { Container } from './index.styled';
19
- import {
20
- GET_CONTENT_LIST_CONTENT_TYPE,
21
- GET_CONTENT_LIST_CONTENT_TYPE_SUCCEEDED,
22
- GET_CONFIG,
23
- GET_CONFIG_SUCCESS,
24
- } from './actions';
25
- import pluginId from '../../pluginId';
26
- import reducer, { initialState } from './reducer';
27
- import getTrad from '../../utils/getTrad';
28
-
29
- const getContentTypes = async (dispatch) => {
30
- try {
31
- dispatch({ type: GET_CONFIG });
32
- const { contentsTypes , relatedContentTypes } = await request(`/${pluginId}/moderation/config`, { method: 'GET' });
33
- dispatch({ type: GET_CONFIG_SUCCESS, contentsTypes, relatedContentTypes });
34
- } catch (err) {
35
- console.log('err', err);
36
- }
37
- };
38
-
39
- const fetchContentTypeList = async (dispatch, contentTypeName, prev) => {
40
- try {
41
- dispatch({ type: GET_CONTENT_LIST_CONTENT_TYPE });
42
- if (contentTypeName) {
43
- const { list } = await request(
44
- `/${pluginId}/moderation/contents-types/${contentTypeName}`,
45
- );
46
- dispatch({
47
- type: GET_CONTENT_LIST_CONTENT_TYPE_SUCCEEDED,
48
- payload: {
49
- ...prev,
50
- [contentTypeName]: list,
51
- },
52
- });
53
- }
54
- } catch (err) {
55
- console.log('err', err);
56
- }
57
- };
58
-
59
- const Panel = () => {
60
- const [reducerState, dispatch] = useReducer(reducer, initialState);
61
- const {
62
- contentsTypes,
63
- relatedContentTypes,
64
- isLoadingContentsTypes,
65
- isLoadingEntries,
66
- availableEntriesMap,
67
- } = reducerState.toJS();
68
- const { formatMessage } = useGlobalContext();
69
- const { getSearchParams, search, items } = useDataManager();
70
- const newItemsCount = items.filter(_ => _.isNew).length;
71
-
72
- const { push } = useHistory();
73
-
74
- const { filters: queryFilters } = getSearchParams();
75
- const [filters, setFilters] = useState(initFilters(queryFilters));
76
-
77
- const [isOpenFilter, setIsOpenFilter] = useState(false);
78
-
79
- useEffect(
80
- () => {
81
- getContentTypes(dispatch);
82
- },
83
- [dispatch],
84
- );
85
-
86
- useEffect(() => {
87
- fetchContentTypeList(dispatch, get(filters, 'related.value'), availableEntriesMap || {});
88
- }, [filters, dispatch]);
89
-
90
- const onToggleOpen = () => {
91
- if (isEmpty(filters)) {
92
- setFilters(initFilters([]));
93
- }
94
- setIsOpenFilter(prevState => !prevState);
95
- };
96
- const onClose = () => setIsOpenFilter(false);
97
-
98
- const onRemoveFilter = ({ name }) => () => {
99
- onChangeFilter({ target: { name: `${name}.value`, value: '' } });
100
- onSubmit(isRelatedFilter(name) ? [name, 'entity'] : [name]);
101
- };
102
-
103
- const onChangeFilter = ({ target: { name, value } }) => {
104
- setFilters(prevState => {
105
- const [filterName, property] = name.split('-').map(camelCase);
106
- const filter = { ...(prevState[camelCase(filterName)] || {}) };
107
- if (filter) {
108
- if (isRelatedFilter(filterName) && prevState.entity) {
109
- prevState.entity.prevValue = prevState.entity.value;
110
- prevState.entity.value = '';
111
- }
112
- filter[property] = value;
113
- return { ...prevState, [camelCase(filterName)]: filter };
114
- }
115
- return { ...prevState };
116
- });
117
- };
118
-
119
- const onSubmit = (ignoreFilterNames = []) => {
120
- const searchParams = getSearchParams();
121
- searchParams.filters = Object
122
- .values(filters)
123
- .filter(({ value, name }) => !!value && !ignoreFilterNames.some(_ => _ === name));
124
- const newSearchParams = generateSearchFromFilters(searchParams);
125
- push({ search: newSearchParams });
126
- };
127
-
128
- const clearAll = () => {
129
- const searchParams = getSearchParams();
130
- searchParams.filters = [];
131
- const newSearchParams = generateSearchFromFilters(searchParams);
132
- setFilters(initFilters([]));
133
- push({ search: newSearchParams });
134
- };
135
-
136
- const filterPickerActions = [
137
- {
138
- label: getTrad(`list.header.filters.clearAll`),
139
- kind: 'secondary',
140
- onClick: () => {
141
- onClose();
142
- clearAll();
143
- },
144
- },
145
- {
146
- label: getTrad(`list.header.filters.apply`),
147
- kind: 'primary',
148
- type: 'button',
149
- onClick: () => {
150
- onClose();
151
- onSubmit();
152
- },
153
- },
154
- ];
155
-
156
- const isFilters = search.filters.length > 0;
157
-
158
- return (
159
- <>
160
- <Container isOpenFilter={isOpenFilter}>
161
- <PluginHeader
162
- title={formatMessage(getTradId('list.header.title'))}
163
- description={formatMessage(
164
- getTradId(isFilters ? 'list.header.filters.message' : 'list.header.description'),
165
- { count: isFilters ? items.length : newItemsCount })
166
- }
167
- actions={isOpenFilter ? filterPickerActions : []}
168
- />
169
- <Filters
170
- contentsTypes={contentsTypes}
171
- isLoadingContentsTypes={isLoadingContentsTypes}
172
- isLoadingEntries={isLoadingEntries}
173
- availableEntriesMap={availableEntriesMap}
174
- filters={filters}
175
- isOpenFilter={isOpenFilter}
176
- onToggleOpen={onToggleOpen}
177
- onChangeFilter={onChangeFilter}
178
- onRemoveFilter={onRemoveFilter}
179
- />
180
- </Container>
181
- <div className="container-fluid">
182
- <div className="row">
183
- <ListView relatedContentTypes={relatedContentTypes} />
184
- <DetailsView />
185
- </div>
186
- </div>
187
- </>
188
- );
189
- };
190
-
191
- export default memo(Panel);
@@ -1,6 +0,0 @@
1
- import styled from 'styled-components';
2
-
3
- export const Container = styled.div`
4
- padding: 2.5rem 30px 2.5rem 15px;
5
- background-color: ${({ isOpenFilter }) => isOpenFilter ? 'white' : ''}
6
- `;
@@ -1,44 +0,0 @@
1
- import { fromJS, Set } from 'immutable';
2
- import {
3
- GET_CONFIG,
4
- GET_CONFIG_SUCCESS,
5
- GET_CONTENT_LIST_CONTENT_TYPE,
6
- GET_CONTENT_LIST_CONTENT_TYPE_SUCCEEDED,
7
- } from './actions';
8
-
9
- export const initialState = fromJS({
10
- isLoadingContentsTypes: false,
11
- isLoadingEntries: false,
12
- contentsTypes: [],
13
- relatedContentTypes: {},
14
- availableEntriesMap: Set(),
15
- });
16
-
17
- const reducer = (state, action) => {
18
- switch (action.type) {
19
- case GET_CONFIG: {
20
- return state
21
- .update('isLoadingContentsTypes', () => true);
22
- }
23
- case GET_CONFIG_SUCCESS: {
24
- return state
25
- .update('isLoadingContentsTypes', () => false)
26
- .update('contentsTypes', () => action.contentsTypes)
27
- .update('relatedContentTypes', () => action.relatedContentTypes);
28
- }
29
- case GET_CONTENT_LIST_CONTENT_TYPE: {
30
- return state
31
- .update('isLoadingEntries', () => true)
32
- .update('availableEntriesMap', () => ({}));
33
- }
34
- case GET_CONTENT_LIST_CONTENT_TYPE_SUCCEEDED: {
35
- return state
36
- .update('isLoadingEntries', () => false)
37
- .update('availableEntriesMap', () => action.payload);
38
- }
39
- default:
40
- return state;
41
- }
42
- };
43
-
44
- export default reducer;
@@ -1,5 +0,0 @@
1
- import { createContext } from 'react';
2
-
3
- const DataManagerContext = createContext();
4
-
5
- export default DataManagerContext;
@@ -1,6 +0,0 @@
1
- import { useContext } from 'react';
2
- import DataManagerContext from '../contexts/DataManagerContext';
3
-
4
- const useDataManager = () => useContext(DataManagerContext);
5
-
6
- export default useDataManager;
@@ -1,3 +0,0 @@
1
- function lifecycles() {}
2
-
3
- export default lifecycles;