strapi-plugin-comments 1.0.2 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.circleci/config.yml +2 -2
- package/README.md +70 -109
- package/admin/src/components/ConfirmationDialog/index.js +56 -0
- package/admin/src/components/DiscussionStatus/index.js +33 -0
- package/admin/src/components/DiscussionThread/index.js +59 -0
- package/admin/src/components/DiscussionThreadItem/index.js +87 -0
- package/admin/src/components/DiscussionThreadItem/styles.js +88 -0
- package/admin/src/components/DiscussionThreadItemActions/index.js +178 -0
- package/admin/src/components/DiscussionThreadItemActions/styles.js +22 -0
- package/admin/src/components/DiscussionThreadItemMeta/index.js +31 -0
- package/admin/src/components/DiscussionThreadItemWarnings/index.js +141 -0
- package/admin/src/components/DiscussionThreadItemWarnings/styles.js +7 -0
- package/admin/src/components/EntityDetails/index.js +53 -0
- package/admin/src/{containers → components}/Initializer/index.js +4 -4
- package/admin/src/components/LoadingIndicatorOverlay/index.js +15 -0
- package/admin/src/components/LoadingIndicatorOverlay/styles.js +20 -0
- package/admin/src/components/Nav/index.js +45 -0
- package/admin/src/components/PluginIcon/index.js +12 -0
- package/admin/src/components/ReportsReviewModal/index.js +43 -0
- package/admin/src/components/ReportsReviewTable/index.js +146 -0
- package/admin/src/components/TableFilters/index.js +53 -0
- package/admin/src/components/TablePagination/index.js +35 -0
- package/admin/src/components/icons/comments.js +9 -0
- package/admin/src/components/icons/index.js +6 -0
- package/admin/src/components/icons/lock.js +22 -0
- package/admin/src/components/icons/review.js +18 -0
- package/admin/src/components/icons/unlock.js +20 -0
- package/admin/src/index.js +58 -42
- package/admin/src/pages/App/index.js +71 -0
- package/admin/src/pages/App/reducer/actions.js +8 -0
- package/admin/src/pages/App/reducer/constants.js +4 -0
- package/admin/src/pages/App/reducer/index.js +26 -0
- package/admin/src/pages/App/reducer/init.js +7 -0
- package/admin/src/pages/App/reducer/selectors.js +35 -0
- package/admin/src/pages/App/utils/api.js +12 -0
- package/admin/src/pages/ComingSoonPage/index.js +25 -0
- package/admin/src/pages/Details/index.js +109 -0
- package/admin/src/pages/Details/utils/api.js +41 -0
- package/admin/src/pages/Discover/components/DiscoverTableRow/index.js +196 -0
- package/admin/src/pages/Discover/index.js +157 -0
- package/admin/src/pages/Discover/utils/api.js +14 -0
- package/admin/src/pages/Discover/utils/filtersSchema.js +9 -0
- package/admin/src/permissions.js +13 -33
- package/admin/src/pluginId.js +2 -4
- package/admin/src/reducers.js +8 -0
- package/admin/src/translations/en.json +73 -33
- package/admin/src/translations/fr.json +1 -0
- package/admin/src/utils/axiosInstance.js +35 -0
- package/admin/src/utils/constants.js +28 -0
- package/admin/src/utils/getApiUrl.js +5 -0
- package/admin/src/utils/getMessage.js +21 -0
- package/admin/src/utils/getRelatedGroups.js +5 -0
- package/admin/src/utils/getUrl.js +5 -0
- package/admin/src/utils/handleAPIError.js +15 -0
- package/admin/src/utils/index.js +6 -0
- package/codecov.yml +2 -1
- package/content-types/comment.js +97 -0
- package/content-types/index.js +11 -0
- package/content-types/report.js +54 -0
- package/package.json +11 -25
- package/server/bootstrap.js +5 -0
- package/server/config/index.js +10 -0
- package/server/controllers/admin.js +134 -0
- package/server/controllers/client.js +117 -0
- package/server/controllers/index.js +9 -0
- package/{controllers → server/controllers}/utils/__tests__/functions.test.js +0 -0
- package/{controllers → server/controllers}/utils/functions.js +1 -1
- package/server/destroy.js +5 -0
- package/server/index.js +22 -0
- package/server/register.js +5 -0
- package/server/routes/admin.js +92 -0
- package/server/routes/client.js +52 -0
- package/server/routes/index.js +15 -0
- package/server/services/admin.js +215 -0
- package/server/services/client.js +227 -0
- package/server/services/common.js +197 -0
- package/server/services/index.js +11 -0
- package/{services → server/services}/utils/__tests__/functions.test.js +7 -9
- package/{services → server/services}/utils/functions.js +19 -8
- package/server/utils/constants.js +16 -0
- package/{services → server}/utils/error.js +0 -0
- package/server/utils/functions.js +19 -0
- package/strapi-admin.js +3 -0
- package/strapi-server.js +9 -0
- package/admin/src/assets/images/icon-cross-blue.svg +0 -1
- package/admin/src/assets/images/icon_remove.svg +0 -19
- package/admin/src/assets/images/logo.svg +0 -5
- package/admin/src/components/AbuseReportsPopUp/ItemPreviewContainer.js +0 -8
- package/admin/src/components/AbuseReportsPopUp/ModalFooter.js +0 -31
- package/admin/src/components/AbuseReportsPopUp/TableContainer.js +0 -63
- package/admin/src/components/AbuseReportsPopUp/index.js +0 -148
- package/admin/src/components/Container/index.js +0 -7
- package/admin/src/components/EmptyView/index.js +0 -25
- package/admin/src/components/Filters/index.js +0 -151
- package/admin/src/components/Filters/index.styled.js +0 -82
- package/admin/src/components/Filters/utils.js +0 -21
- package/admin/src/components/Item/CardItem.js +0 -30
- package/admin/src/components/Item/CardWrapper.js +0 -10
- package/admin/src/components/Item/index.js +0 -92
- package/admin/src/components/ItemDetails/CardItem.js +0 -33
- package/admin/src/components/ItemDetails/CardLevelCounter.js +0 -46
- package/admin/src/components/ItemDetails/CardLevelCounterLink.js +0 -24
- package/admin/src/components/ItemDetails/CardLevelWrapper.js +0 -22
- package/admin/src/components/ItemDetails/CardWrapper.js +0 -52
- package/admin/src/components/ItemDetails/index.js +0 -151
- package/admin/src/components/ItemFooter/CardItemAuthor.js +0 -10
- package/admin/src/components/ItemFooter/CardItemRelation.js +0 -18
- package/admin/src/components/ItemFooter/Wrapper.js +0 -20
- package/admin/src/components/ItemFooter/index.js +0 -87
- package/admin/src/components/ItemHeader/CardHeaderBlocked.js +0 -24
- package/admin/src/components/ItemHeader/CardHeaderIndicator.js +0 -30
- package/admin/src/components/ItemHeader/CardHeaderIndicatorBlue.js +0 -11
- package/admin/src/components/ItemHeader/CardHeaderIndicatorRed.js +0 -11
- package/admin/src/components/ItemHeader/CardHeaderIndicatorsContainer.js +0 -18
- package/admin/src/components/ItemHeader/CardHeaderReports.js +0 -40
- package/admin/src/components/ItemHeader/Wrapper.js +0 -16
- package/admin/src/components/ItemHeader/index.js +0 -80
- package/admin/src/components/ItemModeration/Wrapper.js +0 -19
- package/admin/src/components/ItemModeration/index.js +0 -47
- package/admin/src/components/List/Container.js +0 -20
- package/admin/src/components/List/index.js +0 -21
- package/admin/src/components/Search/index.js +0 -83
- package/admin/src/containers/App/Wrapper.js +0 -14
- package/admin/src/containers/App/index.js +0 -47
- package/admin/src/containers/DataManagerProvider/actions.js +0 -11
- package/admin/src/containers/DataManagerProvider/index.js +0 -280
- package/admin/src/containers/DataManagerProvider/init.js +0 -5
- package/admin/src/containers/DataManagerProvider/reducer.js +0 -59
- package/admin/src/containers/DetailsView/Wrapper.js +0 -18
- package/admin/src/containers/DetailsView/index.js +0 -100
- package/admin/src/containers/ListView/FadedWrapper.js +0 -42
- package/admin/src/containers/ListView/Footer.js +0 -53
- package/admin/src/containers/ListView/Wrapper.js +0 -17
- package/admin/src/containers/ListView/components.js +0 -138
- package/admin/src/containers/ListView/index.js +0 -45
- package/admin/src/containers/Panel/actions.js +0 -5
- package/admin/src/containers/Panel/index.js +0 -191
- package/admin/src/containers/Panel/index.styled.js +0 -6
- package/admin/src/containers/Panel/reducer.js +0 -44
- package/admin/src/contexts/DataManagerContext.js +0 -5
- package/admin/src/hooks/useDataManager.js +0 -6
- package/admin/src/lifecycles.js +0 -3
- package/admin/src/translations/index.js +0 -7
- package/admin/src/utils/getTrad.js +0 -5
- package/admin/src/utils/getTradId.js +0 -5
- package/config/functions/bootstrap.js +0 -48
- package/config/routes.json +0 -116
- package/config/schema.graphql.js +0 -270
- package/controllers/comments.js +0 -211
- package/models/comment.js +0 -8
- package/models/comment.settings.json +0 -98
- package/models/report.js +0 -8
- package/models/report.settings.json +0 -49
- package/services/comments.js +0 -486
|
@@ -1,100 +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
|
-
} = useDataManager();
|
|
37
|
-
|
|
38
|
-
const { formatMessage } = useGlobalContext();
|
|
39
|
-
const { push } = useHistory();
|
|
40
|
-
|
|
41
|
-
const onCommentClick = (e, id) => {
|
|
42
|
-
e.preventDefault();
|
|
43
|
-
e.stopPropagation();
|
|
44
|
-
push(`/plugins/${pluginId}/display/${id}`)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const renderCommentsTree = (selected, items) => {
|
|
48
|
-
return (<CardLevelWrapper>
|
|
49
|
-
{
|
|
50
|
-
items.map((item, n) => {
|
|
51
|
-
const active = item.id === selected.id;
|
|
52
|
-
const threadsCount = item.children && item.children.length;
|
|
53
|
-
const hasThreads = threadsCount > 0;
|
|
54
|
-
const clickable = !active && hasThreads && !isNil(selected.threadOf);
|
|
55
|
-
return (<ItemDetails
|
|
56
|
-
key={`list-item-details-${item.id || n}`}
|
|
57
|
-
{...item}
|
|
58
|
-
active={active}
|
|
59
|
-
root={selected.threadOf === null}
|
|
60
|
-
clickable={clickable}
|
|
61
|
-
threadsCount={threadsCount}
|
|
62
|
-
onAbuseReportResolve={resolveAbuseReport}
|
|
63
|
-
onBlockClick={blockComment}
|
|
64
|
-
onBlockThreadClick={blockCommentThread}
|
|
65
|
-
onClick={e => onCommentClick(e, hasThreads ? item.children[0].id : item.id)}
|
|
66
|
-
/>)
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
</CardLevelWrapper>)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const { selected, level } = activeItem || {};
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<Wrapper className="col-md-8">
|
|
76
|
-
{ isLoadingForDetailsDataToBeSet && <LoadingIndicatorPage />}
|
|
77
|
-
{ !isLoadingForDetailsDataToBeSet && !activeItem && (<EmptyView fixPosition>
|
|
78
|
-
<FontAwesomeIcon icon={faComments} size="5x" />
|
|
79
|
-
<FormattedMessage id={getTrad('moderation.content.empty')} />
|
|
80
|
-
</EmptyView>)}
|
|
81
|
-
{ activeItem && (<>
|
|
82
|
-
{ selected.threadOf && (<CardLevelWrapper>
|
|
83
|
-
<ItemDetails
|
|
84
|
-
{...selected.threadOf}
|
|
85
|
-
clickable={true}
|
|
86
|
-
root={true}
|
|
87
|
-
onAbuseReportResolve={resolveAbuseReport}
|
|
88
|
-
onClick={e => onCommentClick(e, selected.threadOf.id)}
|
|
89
|
-
/>
|
|
90
|
-
<CardWrapper root={true}>
|
|
91
|
-
{renderCommentsTree(selected, level)}
|
|
92
|
-
</CardWrapper>
|
|
93
|
-
</CardLevelWrapper>)}
|
|
94
|
-
{!selected.threadOf && renderCommentsTree(selected, level)}
|
|
95
|
-
</>)}
|
|
96
|
-
</Wrapper>
|
|
97
|
-
);
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
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,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;
|
package/admin/src/lifecycles.js
DELETED