@plone/volto 17.0.0-alpha.24 → 17.0.0-alpha.26
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/.yarn/install-state.gz +0 -0
- package/CHANGELOG.md +92 -4
- package/CONTRIBUTING.md +5 -1
- package/README.md +9 -7
- package/cypress/support/commands.js +12 -9
- package/cypress.config.js +1 -0
- package/locales/ca/LC_MESSAGES/volto.po +41 -15
- package/locales/ca.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +41 -15
- package/locales/de.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +40 -14
- package/locales/en.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +69 -43
- package/locales/es.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +40 -14
- package/locales/eu.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +40 -14
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +41 -15
- package/locales/fr.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +40 -14
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +40 -14
- package/locales/ja.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +41 -15
- package/locales/nl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +41 -15
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +40 -14
- package/locales/pt_BR.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +41 -15
- package/locales/ro.json +1 -1
- package/locales/volto.pot +41 -15
- package/locales/zh_CN/LC_MESSAGES/volto.po +41 -15
- package/locales/zh_CN.json +1 -1
- package/package.json +4 -4
- package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +90 -0
- package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +6 -0
- package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +6 -0
- package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +6 -0
- package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +10 -0
- package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +10 -0
- package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +30 -0
- package/packages/volto-slate/build/messages/src/elementEditor/messages.json +10 -0
- package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +6 -0
- package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +6 -0
- package/packages/volto-slate/package.json +1 -1
- package/packages/volto-slate/src/editor/render.jsx +2 -3
- package/src/actions/index.js +4 -0
- package/src/actions/navroot/navroot.js +16 -0
- package/src/actions/navroot/navroot.test.js +15 -0
- package/src/actions/relations/relations.js +17 -0
- package/src/actions/site/site.js +16 -0
- package/src/actions/site/site.test.js +15 -0
- package/src/actions/userSession/userSession.js +17 -1
- package/src/components/manage/Blocks/Block/Settings.jsx +2 -0
- package/src/components/manage/Blocks/Block/Settings.test.jsx +90 -0
- package/src/components/manage/Blocks/Image/schema.js +5 -1
- package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +18 -11
- package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +42 -25
- package/src/components/manage/Blocks/ToC/View.jsx +75 -13
- package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.jsx +4 -13
- package/src/components/manage/Blocks/ToC/variations/DefaultTocRenderer.test.jsx +44 -0
- package/src/components/manage/Contents/Contents.jsx +27 -0
- package/src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx +65 -38
- package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +11 -9
- package/src/components/manage/Controlpanels/Relations/Relations.jsx +3 -3
- package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +8 -7
- package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +15 -9
- package/src/components/manage/Controlpanels/Rules/AddRule.jsx +1 -1
- package/src/components/manage/Controlpanels/Rules/EditRule.jsx +1 -1
- package/src/components/manage/Controlpanels/Users/RenderUsers.jsx +95 -5
- package/src/components/manage/Controlpanels/Users/UsersControlpanel.jsx +127 -99
- package/src/components/manage/Diff/DiffField.jsx +25 -1
- package/src/components/manage/Form/BlockDataForm.jsx +3 -2
- package/src/components/manage/Form/BlockDataForm.test.jsx +34 -2
- package/src/components/manage/LinksToItem/LinksToItem.jsx +1 -1
- package/src/components/manage/LinksToItem/LinksToItem.test.jsx +5 -2
- package/src/components/manage/Messages/Messages.jsx +32 -99
- package/src/components/manage/Messages/Messages.test.jsx +0 -1
- package/src/components/manage/Sharing/Sharing.jsx +50 -21
- package/src/components/manage/UniversalLink/UniversalLink.jsx +4 -6
- package/src/components/manage/Widgets/ArrayWidget.jsx +3 -1
- package/src/components/manage/Widgets/ArrayWidget.test.jsx +45 -1
- package/src/components/manage/Widgets/FormFieldWrapper.jsx +1 -1
- package/src/components/manage/Widgets/RegistryImageWidget.jsx +210 -0
- package/src/components/manage/Widgets/RegistryImageWidget.test.jsx +91 -0
- package/src/components/manage/Widgets/SelectWidget.jsx +15 -1
- package/src/components/manage/Widgets/SelectWidget.test.jsx +45 -1
- package/src/components/theme/Comments/Comment.stories.jsx +84 -0
- package/src/components/theme/Comments/Comments.jsx +273 -378
- package/src/components/theme/ContentMetadataTags/ContentMetadataTags.jsx +37 -3
- package/src/components/theme/Login/Login.jsx +159 -241
- package/src/components/theme/Logo/Logo.Multilingual.test.jsx +131 -1
- package/src/components/theme/Logo/Logo.jsx +35 -29
- package/src/components/theme/Logo/Logo.test.jsx +135 -1
- package/src/components/theme/Logout/Logout.jsx +36 -83
- package/src/components/theme/Navigation/Navigation.jsx +86 -171
- package/src/components/theme/Search/SearchTags.jsx +30 -60
- package/src/components/theme/SearchWidget/SearchWidget.jsx +15 -3
- package/src/components/theme/SearchWidget/SearchWidget.test.jsx +8 -0
- package/src/components/theme/Sitemap/Sitemap.jsx +24 -13
- package/src/components/theme/Sitemap/Sitemap.test.jsx +23 -2
- package/src/components/theme/View/View.jsx +2 -0
- package/src/config/ControlPanels.js +0 -1
- package/src/config/Widgets.jsx +2 -0
- package/src/config/index.js +15 -3
- package/src/constants/ActionTypes.js +4 -0
- package/src/express-middleware/images.js +1 -0
- package/src/helpers/MessageLabels/MessageLabels.js +26 -4
- package/src/helpers/Site/index.js +21 -0
- package/src/helpers/index.js +1 -0
- package/src/reducers/index.js +4 -0
- package/src/reducers/navroot/navroot.js +79 -0
- package/src/reducers/navroot/navroot.test.js +110 -0
- package/src/reducers/relations/relations.js +74 -46
- package/src/reducers/site/site.js +51 -0
- package/src/reducers/site/site.test.js +67 -0
- package/src/reducers/userSession/userSession.js +15 -1
- package/src/server.jsx +9 -0
- package/test-setup-config.js +1 -0
- package/theme/themes/pastanaga/collections/form.overrides +46 -0
- package/theme/themes/pastanaga/elements/input.overrides +10 -0
- package/theme/themes/pastanaga/elements/label.overrides +10 -0
- package/theme/themes/pastanaga/extras/login.less +3 -0
- package/webpack-plugins/webpack-less-plugin.js +19 -0
- package/.gitignore~ +0 -71
- package/news/4547.breaking~ +0 -1
- package/package.json~ +0 -444
- package/src/config/index.js~ +0 -223
|
@@ -96,6 +96,7 @@ class GroupsControlpanel extends Component {
|
|
|
96
96
|
this.updateGroupRole = this.updateGroupRole.bind(this);
|
|
97
97
|
this.state = {
|
|
98
98
|
search: '',
|
|
99
|
+
isLoading: false,
|
|
99
100
|
addGroupError: '',
|
|
100
101
|
showDelete: false,
|
|
101
102
|
groupToDelete: undefined,
|
|
@@ -173,8 +174,18 @@ class GroupsControlpanel extends Component {
|
|
|
173
174
|
* @returns {undefined}
|
|
174
175
|
*/
|
|
175
176
|
onSearchGroups(event) {
|
|
177
|
+
this.setState({ isLoading: true });
|
|
176
178
|
event.preventDefault();
|
|
177
|
-
this.props
|
|
179
|
+
this.props
|
|
180
|
+
.listGroups(this.state.search)
|
|
181
|
+
.then(() => {
|
|
182
|
+
this.setState({ isLoading: false });
|
|
183
|
+
})
|
|
184
|
+
.catch((error) => {
|
|
185
|
+
this.setState({ isLoading: false });
|
|
186
|
+
// eslint-disable-next-line no-console
|
|
187
|
+
console.error('Error searching group', error);
|
|
188
|
+
});
|
|
178
189
|
}
|
|
179
190
|
|
|
180
191
|
/**
|
|
@@ -487,7 +498,11 @@ class GroupsControlpanel extends Component {
|
|
|
487
498
|
<Form.Field>
|
|
488
499
|
<Input
|
|
489
500
|
name="SearchableText"
|
|
490
|
-
action={{
|
|
501
|
+
action={{
|
|
502
|
+
icon: 'search',
|
|
503
|
+
loading: this.state.isLoading,
|
|
504
|
+
disabled: this.state.isLoading,
|
|
505
|
+
}}
|
|
491
506
|
placeholder={this.props.intl.formatMessage(
|
|
492
507
|
messages.searchGroups,
|
|
493
508
|
)}
|
|
@@ -499,43 +514,55 @@ class GroupsControlpanel extends Component {
|
|
|
499
514
|
</Segment>
|
|
500
515
|
<Form>
|
|
501
516
|
<div className="table">
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
517
|
+
{((this.props.many_groups &&
|
|
518
|
+
this.state.groupEntries.length > 0) ||
|
|
519
|
+
!this.props.many_groups) && (
|
|
520
|
+
<Table padded striped attached unstackable>
|
|
521
|
+
<Table.Header>
|
|
522
|
+
<Table.Row>
|
|
523
|
+
<Table.HeaderCell>
|
|
524
|
+
<FormattedMessage
|
|
525
|
+
id="Groupname"
|
|
526
|
+
defaultMessage="Groupname"
|
|
527
|
+
/>
|
|
528
|
+
</Table.HeaderCell>
|
|
529
|
+
{this.props.roles.map((role) => (
|
|
530
|
+
<Table.HeaderCell key={role.id}>
|
|
531
|
+
{role.title}
|
|
532
|
+
</Table.HeaderCell>
|
|
533
|
+
))}
|
|
534
|
+
<Table.HeaderCell>
|
|
535
|
+
<FormattedMessage
|
|
536
|
+
id="Actions"
|
|
537
|
+
defaultMessage="Actions"
|
|
538
|
+
/>
|
|
514
539
|
</Table.HeaderCell>
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
540
|
+
</Table.Row>
|
|
541
|
+
</Table.Header>
|
|
542
|
+
<Table.Body data-group="groups">
|
|
543
|
+
{this.state.groupEntries
|
|
544
|
+
.slice(
|
|
545
|
+
this.state.currentPage * 10,
|
|
546
|
+
this.state.pageSize * (this.state.currentPage + 1),
|
|
547
|
+
)
|
|
548
|
+
.map((group) => (
|
|
549
|
+
<RenderGroups
|
|
550
|
+
key={group.id}
|
|
551
|
+
onDelete={this.deleteGroup}
|
|
552
|
+
roles={this.props.roles}
|
|
553
|
+
group={group}
|
|
554
|
+
updateGroups={this.updateGroupRole}
|
|
555
|
+
inheritedRole={this.state.authenticatedRole}
|
|
556
|
+
/>
|
|
557
|
+
))}
|
|
558
|
+
</Table.Body>
|
|
559
|
+
</Table>
|
|
560
|
+
)}
|
|
561
|
+
{this.state.groupEntries.length === 0 && this.state.search && (
|
|
562
|
+
<Segment>
|
|
563
|
+
{this.props.intl.formatMessage(messages.groupSearchNoResults)}
|
|
564
|
+
</Segment>
|
|
565
|
+
)}
|
|
539
566
|
</div>
|
|
540
567
|
<div className="contents-pagination">
|
|
541
568
|
<Pagination
|
|
@@ -5,15 +5,15 @@ import { useSelector, useDispatch } from 'react-redux';
|
|
|
5
5
|
import { Divider, Segment, Table } from 'semantic-ui-react';
|
|
6
6
|
import { queryRelations } from '@plone/volto/actions';
|
|
7
7
|
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
8
|
-
import {
|
|
8
|
+
import { ConditionalLink } from '@plone/volto/components';
|
|
9
9
|
|
|
10
10
|
const BrokenRelations = () => {
|
|
11
11
|
const dispatch = useDispatch();
|
|
12
12
|
const brokenRelationStats = useSelector(
|
|
13
|
-
(state) => state.relations?.stats?.broken || {},
|
|
13
|
+
(state) => state.relations?.stats?.data?.broken || {},
|
|
14
14
|
);
|
|
15
15
|
const brokenRelations = useSelector(
|
|
16
|
-
(state) => state.relations?.subrequests?.broken?.
|
|
16
|
+
(state) => state.relations?.subrequests?.broken?.data,
|
|
17
17
|
);
|
|
18
18
|
|
|
19
19
|
useEffect(() => {
|
|
@@ -60,20 +60,22 @@ const BrokenRelations = () => {
|
|
|
60
60
|
}).map((el, index) => (
|
|
61
61
|
<Table.Row key={index}>
|
|
62
62
|
<Table.Cell>
|
|
63
|
-
<
|
|
64
|
-
|
|
63
|
+
<ConditionalLink
|
|
64
|
+
to={`${el[0]}/edit`}
|
|
65
65
|
openLinkInNewTab={true}
|
|
66
|
+
condition={el[0].includes('http')}
|
|
66
67
|
>
|
|
67
68
|
{flattenToAppURL(el[0])}
|
|
68
|
-
</
|
|
69
|
+
</ConditionalLink>
|
|
69
70
|
</Table.Cell>
|
|
70
71
|
<Table.Cell>
|
|
71
|
-
<
|
|
72
|
-
|
|
72
|
+
<ConditionalLink
|
|
73
|
+
to={`${el[1]}/edit`}
|
|
73
74
|
openLinkInNewTab={true}
|
|
75
|
+
condition={el[1].includes('http')}
|
|
74
76
|
>
|
|
75
77
|
{flattenToAppURL(el[1])}
|
|
76
|
-
</
|
|
78
|
+
</ConditionalLink>
|
|
77
79
|
</Table.Cell>
|
|
78
80
|
</Table.Row>
|
|
79
81
|
))}
|
|
@@ -24,10 +24,10 @@ const RelationsControlPanel = () => {
|
|
|
24
24
|
const dispatch = useDispatch();
|
|
25
25
|
|
|
26
26
|
const brokenRelations = useSelector(
|
|
27
|
-
(state) => state.relations?.stats?.broken,
|
|
27
|
+
(state) => state.relations?.stats?.data?.broken,
|
|
28
28
|
);
|
|
29
29
|
|
|
30
|
-
const relations_stats = useSelector((state) => state.relations?.stats?.
|
|
30
|
+
const relations_stats = useSelector((state) => state.relations?.stats?.data);
|
|
31
31
|
const actions = useSelector((state) => state.actions?.actions ?? {});
|
|
32
32
|
const can_edit = find(actions.object, {
|
|
33
33
|
id: 'edit',
|
|
@@ -58,7 +58,7 @@ const RelationsControlPanel = () => {
|
|
|
58
58
|
<h1>
|
|
59
59
|
<FormattedMessage id="Relations" defaultMessage="Relations" />
|
|
60
60
|
</h1>
|
|
61
|
-
{
|
|
61
|
+
{relations_stats?.error ? (
|
|
62
62
|
<React.Fragment>
|
|
63
63
|
<Divider hidden />
|
|
64
64
|
<Message warning>
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
createRelations,
|
|
12
12
|
deleteRelations,
|
|
13
13
|
queryRelations,
|
|
14
|
+
resetSearchContent,
|
|
14
15
|
searchContent,
|
|
15
16
|
} from '@plone/volto/actions';
|
|
16
17
|
|
|
@@ -28,9 +29,10 @@ const ListingTemplate = ({
|
|
|
28
29
|
const MAX = 40; // Maximum of rows and columns
|
|
29
30
|
const MAX_RELATIONS = 1000;
|
|
30
31
|
|
|
31
|
-
const stats = useSelector((state) => state.relations?.stats || null);
|
|
32
|
+
const stats = useSelector((state) => state.relations?.stats?.data || null);
|
|
33
|
+
|
|
32
34
|
let relations = useSelector(
|
|
33
|
-
(state) => state.relations?.relations?.[relationtype]?.items || [],
|
|
35
|
+
(state) => state.relations?.relations?.data?.[relationtype]?.items || [],
|
|
34
36
|
);
|
|
35
37
|
|
|
36
38
|
let potential_targets_objects = useSelector(
|
|
@@ -49,7 +51,8 @@ const ListingTemplate = ({
|
|
|
49
51
|
|
|
50
52
|
// Editable if plone.api.relations available
|
|
51
53
|
const editable = useSelector(
|
|
52
|
-
(state) =>
|
|
54
|
+
(state) =>
|
|
55
|
+
state.relations?.relations?.data?.[relationtype]?.readonly !== true,
|
|
53
56
|
);
|
|
54
57
|
|
|
55
58
|
let relationMatrix = {};
|
|
@@ -192,8 +195,7 @@ const ListingTemplate = ({
|
|
|
192
195
|
),
|
|
193
196
|
);
|
|
194
197
|
} else {
|
|
195
|
-
|
|
196
|
-
dispatch(searchContent('/findstenichätsch', null, 'potential_targets'));
|
|
198
|
+
dispatch(resetSearchContent('potential_targets'));
|
|
197
199
|
}
|
|
198
200
|
|
|
199
201
|
// Fetch fresh potential sources
|
|
@@ -211,8 +213,7 @@ const ListingTemplate = ({
|
|
|
211
213
|
),
|
|
212
214
|
);
|
|
213
215
|
} else {
|
|
214
|
-
|
|
215
|
-
dispatch(searchContent('/findstenichätsch', null, 'potential_sources'));
|
|
216
|
+
dispatch(resetSearchContent('potential_sources'));
|
|
216
217
|
}
|
|
217
218
|
}, [
|
|
218
219
|
dispatch,
|
|
@@ -17,7 +17,11 @@ import {
|
|
|
17
17
|
import withObjectBrowser from '@plone/volto/components/manage/Sidebar/ObjectBrowser';
|
|
18
18
|
import { messages } from '@plone/volto/helpers';
|
|
19
19
|
import { Icon, Toast } from '@plone/volto/components';
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
getRelationStats,
|
|
22
|
+
queryRelations,
|
|
23
|
+
rebuildRelations,
|
|
24
|
+
} from '@plone/volto/actions';
|
|
21
25
|
import RelationsListing from './RelationsListing';
|
|
22
26
|
import BrokenRelations from './BrokenRelations';
|
|
23
27
|
import helpSVG from '@plone/volto/icons/help.svg';
|
|
@@ -39,12 +43,14 @@ const RelationsMatrix = (props) => {
|
|
|
39
43
|
id: 'plone_setup',
|
|
40
44
|
});
|
|
41
45
|
|
|
42
|
-
const relationtypes = useSelector(
|
|
46
|
+
const relationtypes = useSelector(
|
|
47
|
+
(state) => state.relations?.stats?.data?.stats,
|
|
48
|
+
);
|
|
43
49
|
const relationsListError = useSelector(
|
|
44
|
-
(state) => state.relations?.
|
|
50
|
+
(state) => state.relations?.stats?.error?.response?.body?.error,
|
|
45
51
|
);
|
|
46
52
|
const brokenRelations = useSelector(
|
|
47
|
-
(state) => state.relations?.stats?.broken,
|
|
53
|
+
(state) => state.relations?.stats?.data?.broken,
|
|
48
54
|
);
|
|
49
55
|
|
|
50
56
|
let filter_options = useSelector((state) => state.groups.filter_groups);
|
|
@@ -67,7 +73,7 @@ const RelationsMatrix = (props) => {
|
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
useEffect(() => {
|
|
70
|
-
dispatch(
|
|
76
|
+
dispatch(getRelationStats());
|
|
71
77
|
}, [dispatch]);
|
|
72
78
|
|
|
73
79
|
const onReset = (event) => {
|
|
@@ -128,9 +134,7 @@ const RelationsMatrix = (props) => {
|
|
|
128
134
|
const rebuildRelationsHandler = (flush = false) => {
|
|
129
135
|
dispatch(rebuildRelations(flush))
|
|
130
136
|
.then(() => {
|
|
131
|
-
dispatch(
|
|
132
|
-
})
|
|
133
|
-
.then(() => {
|
|
137
|
+
dispatch(getRelationStats());
|
|
134
138
|
dispatch(queryRelations(null, true, 'broken'));
|
|
135
139
|
})
|
|
136
140
|
.then(() => {
|
|
@@ -443,7 +447,9 @@ const RelationsMatrix = (props) => {
|
|
|
443
447
|
) : null}
|
|
444
448
|
</div>
|
|
445
449
|
) : (
|
|
446
|
-
<p>
|
|
450
|
+
<p>
|
|
451
|
+
<b>{relationsListError?.type}</b> {relationsListError?.message}
|
|
452
|
+
</p>
|
|
447
453
|
)}
|
|
448
454
|
</Tab.Pane>
|
|
449
455
|
),
|
|
@@ -179,7 +179,7 @@ class AddRule extends Component {
|
|
|
179
179
|
const { title, description, event, cascading, stop, enabled } = this.state;
|
|
180
180
|
const triggeringEvents =
|
|
181
181
|
this.props.events?.items && this.props.events?.items.length > 0
|
|
182
|
-
? this.props.events?.items.map((event) => [event.
|
|
182
|
+
? this.props.events?.items.map((event) => [event.token, event.title])
|
|
183
183
|
: '';
|
|
184
184
|
|
|
185
185
|
return (
|
|
@@ -209,7 +209,7 @@ class EditRule extends Component {
|
|
|
209
209
|
|
|
210
210
|
const triggeringEvents =
|
|
211
211
|
this.props.events?.items && this.props.events?.items.length > 0
|
|
212
|
-
? this.props.events?.items.map((event) => [event.
|
|
212
|
+
? this.props.events?.items.map((event) => [event.token, event.title])
|
|
213
213
|
: '';
|
|
214
214
|
|
|
215
215
|
return (
|
|
@@ -7,8 +7,14 @@ import React, { Component } from 'react';
|
|
|
7
7
|
import { FormattedMessage, injectIntl } from 'react-intl';
|
|
8
8
|
import { Dropdown, Table, Checkbox } from 'semantic-ui-react';
|
|
9
9
|
import trashSVG from '@plone/volto/icons/delete.svg';
|
|
10
|
-
import
|
|
10
|
+
import editSVG from '@plone/volto/icons/editing.svg';
|
|
11
|
+
import { Icon, ModalForm, Toast } from '@plone/volto/components';
|
|
12
|
+
import { updateUser } from '@plone/volto/actions';
|
|
11
13
|
import ploneSVG from '@plone/volto/icons/plone.svg';
|
|
14
|
+
import { compose } from 'redux';
|
|
15
|
+
import { connect } from 'react-redux';
|
|
16
|
+
import { messages } from '@plone/volto/helpers';
|
|
17
|
+
import { toast } from 'react-toastify';
|
|
12
18
|
|
|
13
19
|
/**
|
|
14
20
|
* UsersControlpanelUser class.
|
|
@@ -43,9 +49,14 @@ class RenderUsers extends Component {
|
|
|
43
49
|
*/
|
|
44
50
|
constructor(props) {
|
|
45
51
|
super(props);
|
|
46
|
-
this.state = {
|
|
52
|
+
this.state = {
|
|
53
|
+
user: {},
|
|
54
|
+
};
|
|
47
55
|
this.onChange = this.onChange.bind(this);
|
|
56
|
+
this.onEditUserError = this.onEditUserError.bind(this);
|
|
57
|
+
this.onEditUserSubmit = this.onEditUserSubmit.bind(this);
|
|
48
58
|
}
|
|
59
|
+
|
|
49
60
|
/**
|
|
50
61
|
* @param {*} event
|
|
51
62
|
* @param {*} { value }
|
|
@@ -56,6 +67,49 @@ class RenderUsers extends Component {
|
|
|
56
67
|
const [user, role] = value.split('&role=');
|
|
57
68
|
this.props.updateUser(user, role);
|
|
58
69
|
}
|
|
70
|
+
|
|
71
|
+
componentDidUpdate(prevProps) {
|
|
72
|
+
if (
|
|
73
|
+
prevProps.updateRequest.loading &&
|
|
74
|
+
this.props.updateRequest.loaded &&
|
|
75
|
+
this.state?.user?.id === this.props?.user?.id
|
|
76
|
+
) {
|
|
77
|
+
this.setState({ user: {} });
|
|
78
|
+
this.props.listUsers();
|
|
79
|
+
return toast.success(
|
|
80
|
+
<Toast
|
|
81
|
+
success
|
|
82
|
+
title={this.props.intl.formatMessage(messages.success)}
|
|
83
|
+
content={this.props.intl.formatMessage(messages.updateUserSuccess)}
|
|
84
|
+
/>,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
onEditUserSubmit(data, callback) {
|
|
90
|
+
// Do not handle groups and roles in this form
|
|
91
|
+
delete data.groups;
|
|
92
|
+
delete data.roles;
|
|
93
|
+
this.props.updateUserData(data.id, data);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
onEditUserError() {
|
|
97
|
+
return toast.error(
|
|
98
|
+
<Toast
|
|
99
|
+
error
|
|
100
|
+
title={this.props.intl.formatMessage(messages.error)}
|
|
101
|
+
content={this.props.intl.formatMessage(
|
|
102
|
+
messages.addUserFormPasswordAndSendPasswordTogetherNotAllowed,
|
|
103
|
+
)}
|
|
104
|
+
/>,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
onClickEdit(props) {
|
|
109
|
+
const { formData } = props;
|
|
110
|
+
this.setState({ user: { ...formData } });
|
|
111
|
+
}
|
|
112
|
+
|
|
59
113
|
/**
|
|
60
114
|
* Render method.
|
|
61
115
|
* @method render
|
|
@@ -67,7 +121,8 @@ class RenderUsers extends Component {
|
|
|
67
121
|
<Table.Cell className="fullname">
|
|
68
122
|
{this.props.user.fullname
|
|
69
123
|
? this.props.user.fullname
|
|
70
|
-
: this.props.user.username}
|
|
124
|
+
: this.props.user.username}{' '}
|
|
125
|
+
({this.props.user.username})
|
|
71
126
|
</Table.Cell>
|
|
72
127
|
{this.props.roles.map((role) => (
|
|
73
128
|
<Table.Cell key={role.id}>
|
|
@@ -91,7 +146,20 @@ class RenderUsers extends Component {
|
|
|
91
146
|
<Table.Cell textAlign="right">
|
|
92
147
|
<Dropdown icon="ellipsis horizontal">
|
|
93
148
|
<Dropdown.Menu className="left">
|
|
149
|
+
{this.props.userschema && (
|
|
150
|
+
<Dropdown.Item
|
|
151
|
+
id="edit-user-button"
|
|
152
|
+
onClick={() => {
|
|
153
|
+
this.onClickEdit({ formData: this.props.user });
|
|
154
|
+
}}
|
|
155
|
+
value={this.props.user['@id']}
|
|
156
|
+
>
|
|
157
|
+
<Icon name={editSVG} size="15px" />
|
|
158
|
+
<FormattedMessage id="Edit" defaultMessage="Edit" />
|
|
159
|
+
</Dropdown.Item>
|
|
160
|
+
)}
|
|
94
161
|
<Dropdown.Item
|
|
162
|
+
id="delete-user-button"
|
|
95
163
|
onClick={this.props.onDelete}
|
|
96
164
|
value={this.props.user['@id']}
|
|
97
165
|
>
|
|
@@ -101,9 +169,31 @@ class RenderUsers extends Component {
|
|
|
101
169
|
</Dropdown.Menu>
|
|
102
170
|
</Dropdown>
|
|
103
171
|
</Table.Cell>
|
|
172
|
+
{Object.keys(this.state.user).length > 0 &&
|
|
173
|
+
this.props.userschema.loaded && (
|
|
174
|
+
<ModalForm
|
|
175
|
+
className="modal"
|
|
176
|
+
onSubmit={this.onEditUserSubmit}
|
|
177
|
+
submitError={this.state.editUserError}
|
|
178
|
+
formData={this.state.user}
|
|
179
|
+
onCancel={() => this.setState({ user: {} })}
|
|
180
|
+
title={this.props.intl.formatMessage(
|
|
181
|
+
messages.updateUserFormTitle,
|
|
182
|
+
)}
|
|
183
|
+
loading={this.props.updateRequest.loading}
|
|
184
|
+
schema={this.props.userschema.userschema}
|
|
185
|
+
/>
|
|
186
|
+
)}
|
|
104
187
|
</Table.Row>
|
|
105
188
|
);
|
|
106
189
|
}
|
|
107
190
|
}
|
|
108
|
-
|
|
109
|
-
|
|
191
|
+
export default compose(
|
|
192
|
+
injectIntl,
|
|
193
|
+
connect(
|
|
194
|
+
(state, props) => ({
|
|
195
|
+
updateRequest: state.users?.update,
|
|
196
|
+
}),
|
|
197
|
+
{ updateUserData: updateUser },
|
|
198
|
+
),
|
|
199
|
+
)(RenderUsers);
|