@plone/volto 17.0.0-alpha.7 → 17.0.0-alpha.9

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 (82) hide show
  1. package/.yarn/install-state.gz +0 -0
  2. package/CHANGELOG.md +82 -0
  3. package/locales/ca/LC_MESSAGES/volto.po +146 -0
  4. package/locales/ca.json +1 -1
  5. package/locales/de/LC_MESSAGES/volto.po +146 -0
  6. package/locales/de.json +1 -1
  7. package/locales/en/LC_MESSAGES/volto.po +146 -0
  8. package/locales/en.json +1 -1
  9. package/locales/es/LC_MESSAGES/volto.po +146 -0
  10. package/locales/es.json +1 -1
  11. package/locales/eu/LC_MESSAGES/volto.po +146 -0
  12. package/locales/eu.json +1 -1
  13. package/locales/fi/LC_MESSAGES/volto.po +4762 -0
  14. package/locales/fi.json +1 -1
  15. package/locales/fr/LC_MESSAGES/volto.po +146 -0
  16. package/locales/fr.json +1 -1
  17. package/locales/it/LC_MESSAGES/volto.po +146 -0
  18. package/locales/it.json +1 -1
  19. package/locales/ja/LC_MESSAGES/volto.po +146 -0
  20. package/locales/ja.json +1 -1
  21. package/locales/nl/LC_MESSAGES/volto.po +801 -643
  22. package/locales/nl.json +1 -1
  23. package/locales/pt/LC_MESSAGES/volto.po +146 -0
  24. package/locales/pt.json +1 -1
  25. package/locales/pt_BR/LC_MESSAGES/volto.po +146 -0
  26. package/locales/pt_BR.json +1 -1
  27. package/locales/ro/LC_MESSAGES/volto.po +146 -0
  28. package/locales/ro.json +1 -1
  29. package/locales/volto.pot +147 -1
  30. package/locales/zh_CN/LC_MESSAGES/volto.po +146 -0
  31. package/locales/zh_CN.json +1 -1
  32. package/package.json +1 -1
  33. package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +1 -1
  34. package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +1 -1
  35. package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +1 -1
  36. package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +1 -1
  37. package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +1 -1
  38. package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +1 -1
  39. package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +1 -1
  40. package/packages/volto-slate/build/messages/src/elementEditor/messages.json +1 -1
  41. package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +1 -1
  42. package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +1 -1
  43. package/packages/volto-slate/package.json +1 -1
  44. package/packages/volto-slate/src/blocks/Text/SlashMenu.jsx +4 -3
  45. package/packages/volto-slate/src/editor/deserialize.js +0 -1
  46. package/razzle.config.js +5 -0
  47. package/src/actions/index.js +6 -0
  48. package/src/actions/relations/rebuild.js +25 -0
  49. package/src/actions/relations/relations.js +86 -0
  50. package/src/actions/relations/relations.test.js +15 -0
  51. package/src/components/index.js +1 -0
  52. package/src/components/manage/BlockChooser/BlockChooser.jsx +8 -3
  53. package/src/components/manage/BlockChooser/BlockChooser.test.jsx +5 -0
  54. package/src/components/manage/Contents/Contents.jsx +5 -1
  55. package/src/components/manage/Contents/ContentsItem.jsx +6 -0
  56. package/src/components/manage/Controlpanels/Controlpanels.jsx +9 -0
  57. package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +66 -0
  58. package/src/components/manage/Controlpanels/Relations/Relations.jsx +114 -0
  59. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +479 -0
  60. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +531 -0
  61. package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.jsx +3 -3
  62. package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +51 -82
  63. package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +79 -75
  64. package/src/components/manage/Toast/Toast.jsx +1 -1
  65. package/src/components/theme/NotFound/NotFound.jsx +55 -41
  66. package/src/components/theme/View/RenderBlocks.jsx +7 -1
  67. package/src/components/theme/Widgets/RelationsWidget.jsx +13 -11
  68. package/src/config/ControlPanels.js +2 -0
  69. package/src/constants/ActionTypes.js +4 -0
  70. package/src/constants/Languages.js +8 -4
  71. package/src/helpers/Api/Api.js +1 -1
  72. package/src/helpers/Html/Html.jsx +3 -1
  73. package/src/helpers/Html/Html.test.jsx +5 -0
  74. package/src/helpers/MessageLabels/MessageLabels.js +72 -0
  75. package/src/reducers/actions/actions.js +1 -1
  76. package/src/reducers/breadcrumbs/breadcrumbs.js +1 -1
  77. package/src/reducers/index.js +2 -0
  78. package/src/reducers/navigation/navigation.js +1 -1
  79. package/src/reducers/relations/relations.js +173 -0
  80. package/src/reducers/types/types.js +1 -1
  81. package/src/routes.js +5 -0
  82. package/theme/themes/pastanaga/extras/userscontrolpanel.less +99 -76
@@ -260,4 +260,76 @@ export const messages = defineMessages({
260
260
  id: 'Show groups of users below',
261
261
  defaultMessage: 'Show groups of users below',
262
262
  },
263
+ inspectRelations: {
264
+ id: 'Inspect relations',
265
+ defaultMessage: 'Inspect relations',
266
+ },
267
+ relations: {
268
+ id: 'Relations',
269
+ defaultMessage: 'Relations',
270
+ },
271
+ fixRelations: {
272
+ id: 'Fix relations',
273
+ defaultMessage: 'Fix relations',
274
+ },
275
+ searchRelationSource: {
276
+ id: 'Search sources by title or path',
277
+ defaultMessage: 'Search sources by title or path',
278
+ },
279
+ searchRelationTarget: {
280
+ id: 'Search targets by title or path',
281
+ defaultMessage: 'Search targets by title or path',
282
+ },
283
+ createOrDeleteRelationsToTarget: {
284
+ id: 'Create or delete relations to target',
285
+ defaultMessage: 'Create or delete relations to target',
286
+ },
287
+ relationName: {
288
+ id: 'Relation name',
289
+ defaultMessage: 'relation',
290
+ },
291
+ selectRelation: {
292
+ id: 'Select relation',
293
+ defaultMessage: 'Select relation',
294
+ },
295
+ norelationfound: {
296
+ id: 'No relation found',
297
+ defaultMessage: 'No relation found',
298
+ },
299
+ toomanyrelationsfound: {
300
+ id: 'Many relations found. Please search.',
301
+ defaultMessage: 'Many relations found. Please search.',
302
+ },
303
+ rebuildRelations: {
304
+ id: 'rebuild relations',
305
+ defaultMessage: 'rebuild relations',
306
+ },
307
+ flushAndRebuildRelations: {
308
+ id: 'flush intIds and rebuild relations',
309
+ defaultMessage: 'flush intIds and rebuild relations',
310
+ },
311
+ addPotentialTargetsPath: {
312
+ id: 'target path',
313
+ defaultMessage: 'target path',
314
+ },
315
+ addPotentialSourcesPath: {
316
+ id: 'sources path',
317
+ defaultMessage: 'sources path',
318
+ },
319
+ relationsUpdated: {
320
+ id: 'Relations updated',
321
+ defaultMessage: 'Relations updated',
322
+ },
323
+ select: {
324
+ id: 'Select',
325
+ defaultMessage: 'Select',
326
+ },
327
+ selected: {
328
+ id: 'Selected',
329
+ defaultMessage: 'Selected',
330
+ },
331
+ filter: {
332
+ id: 'Filter',
333
+ defaultMessage: 'Filter',
334
+ },
263
335
  });
@@ -46,7 +46,7 @@ export default function actions(state = initialState, action = {}) {
46
46
  'actions',
47
47
  getBaseUrl(flattenToAppURL(action.result['@id'])),
48
48
  );
49
- if (hasExpander) {
49
+ if (hasExpander && !action.subrequest) {
50
50
  return {
51
51
  ...state,
52
52
  error: null,
@@ -45,7 +45,7 @@ export default function breadcrumbs(state = initialState, action = {}) {
45
45
  'breadcrumbs',
46
46
  getBaseUrl(flattenToAppURL(action.result['@id'])),
47
47
  );
48
- if (hasExpander) {
48
+ if (hasExpander && !action.subrequest) {
49
49
  return {
50
50
  ...state,
51
51
  error: null,
@@ -25,6 +25,7 @@ import messages from '@plone/volto/reducers/messages/messages';
25
25
  import navigation from '@plone/volto/reducers/navigation/navigation';
26
26
  import querystring from '@plone/volto/reducers/querystring/querystring';
27
27
  import querystringsearch from '@plone/volto/reducers/querystringsearch/querystringsearch';
28
+ import relations from '@plone/volto/reducers/relations/relations';
28
29
  import roles from '@plone/volto/reducers/roles/roles';
29
30
  import rules from '@plone/volto/reducers/rules/rules';
30
31
  import controlpanelrule from '@plone/volto/reducers/controlPanelRule/controlPanelRule';
@@ -80,6 +81,7 @@ const reducers = {
80
81
  navigation,
81
82
  querystring,
82
83
  querystringsearch,
84
+ relations,
83
85
  roles,
84
86
  rules,
85
87
  controlpanelrule,
@@ -60,7 +60,7 @@ export default function navigation(state = initialState, action = {}) {
60
60
  'navigation',
61
61
  getBaseUrl(flattenToAppURL(action.result['@id'])),
62
62
  );
63
- if (hasExpander) {
63
+ if (hasExpander && !action.subrequest) {
64
64
  return {
65
65
  ...state,
66
66
  error: null,
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Relations reducer.
3
+ * @module reducers/relations/relations
4
+ */
5
+
6
+ import {
7
+ CREATE_RELATIONS,
8
+ DELETE_RELATIONS,
9
+ LIST_RELATIONS,
10
+ REBUILD_RELATIONS,
11
+ } from '@plone/volto/constants/ActionTypes';
12
+
13
+ const initialState = {
14
+ relations: null,
15
+ stats: null,
16
+ create: {
17
+ error: null,
18
+ loaded: false,
19
+ loading: false,
20
+ },
21
+ delete: {
22
+ error: null,
23
+ loaded: false,
24
+ loading: false,
25
+ },
26
+ list: {
27
+ error: null,
28
+ loaded: false,
29
+ loading: false,
30
+ },
31
+ rebuild: {
32
+ error: null,
33
+ loaded: false,
34
+ loading: false,
35
+ },
36
+ subrequests: {},
37
+ };
38
+
39
+ /**
40
+ * Get request key
41
+ * @function getRequestKey
42
+ * @param {string} actionType Action type.
43
+ * @returns {string} Request key.
44
+ */
45
+ function getRequestKey(actionType) {
46
+ return actionType.split('_')[0].toLowerCase();
47
+ }
48
+
49
+ /**
50
+ * Relations reducer.
51
+ * @function relations
52
+ * @param {Object} state Current state.
53
+ * @param {Object} action Action to be handled.
54
+ * @returns {Object} New state.
55
+ */
56
+ export default function relations(state = initialState, action = {}) {
57
+ switch (action.type) {
58
+ case `${CREATE_RELATIONS}_PENDING`:
59
+ case `${DELETE_RELATIONS}_PENDING`:
60
+ case `${REBUILD_RELATIONS}_PENDING`:
61
+ return {
62
+ ...state,
63
+ [getRequestKey(action.type)]: {
64
+ loading: true,
65
+ loaded: false,
66
+ error: null,
67
+ },
68
+ };
69
+ case `${LIST_RELATIONS}_PENDING`:
70
+ return action.subrequest
71
+ ? {
72
+ ...state,
73
+ subrequests: {
74
+ ...state.subrequests,
75
+ [action.subrequest]: {
76
+ ...(state.subrequests[action.subrequest] || {
77
+ relations: null,
78
+ stats: null,
79
+ }),
80
+ loaded: false,
81
+ loading: true,
82
+ error: null,
83
+ },
84
+ },
85
+ }
86
+ : {
87
+ ...state,
88
+ [getRequestKey(action.type)]: {
89
+ loading: true,
90
+ loaded: false,
91
+ error: null,
92
+ },
93
+ };
94
+ case `${LIST_RELATIONS}_SUCCESS`:
95
+ return action.subrequest
96
+ ? {
97
+ ...state,
98
+ subrequests: {
99
+ ...state.subrequests,
100
+ [action.subrequest]: {
101
+ loading: false,
102
+ loaded: true,
103
+ error: null,
104
+ relations: action.result.relations
105
+ ? action.result.relations
106
+ : state.relations,
107
+ stats: null,
108
+ },
109
+ },
110
+ }
111
+ : {
112
+ ...state,
113
+ relations: action.result.relations
114
+ ? action.result.relations
115
+ : state.relations,
116
+ stats: action.result.stats ? action.result : state.stats,
117
+ [getRequestKey(action.type)]: {
118
+ loading: false,
119
+ loaded: true,
120
+ error: null,
121
+ },
122
+ };
123
+ case `${CREATE_RELATIONS}_SUCCESS`:
124
+ case `${DELETE_RELATIONS}_SUCCESS`:
125
+ case `${REBUILD_RELATIONS}_SUCCESS`:
126
+ return {
127
+ ...state,
128
+ [getRequestKey(action.type)]: {
129
+ loading: false,
130
+ loaded: true,
131
+ error: null,
132
+ },
133
+ };
134
+ case `${LIST_RELATIONS}_FAIL`:
135
+ return action.subrequest
136
+ ? {
137
+ ...state,
138
+ subrequests: {
139
+ ...state.subrequests,
140
+ [action.subrequest]: {
141
+ relations: null,
142
+ stats: null,
143
+ loading: false,
144
+ loaded: false,
145
+ error: action.error,
146
+ },
147
+ },
148
+ }
149
+ : {
150
+ ...state,
151
+ relations: null,
152
+ stats: null,
153
+ [getRequestKey(action.type)]: {
154
+ loading: false,
155
+ loaded: false,
156
+ error: action.error,
157
+ },
158
+ };
159
+ case `${CREATE_RELATIONS}_FAIL`:
160
+ case `${DELETE_RELATIONS}_FAIL`:
161
+ case `${REBUILD_RELATIONS}_FAIL`:
162
+ return {
163
+ ...state,
164
+ [getRequestKey(action.type)]: {
165
+ loading: false,
166
+ loaded: false,
167
+ error: action.error,
168
+ },
169
+ };
170
+ default:
171
+ return state;
172
+ }
173
+ }
@@ -39,7 +39,7 @@ export default function types(state = initialState, action = {}) {
39
39
  'types',
40
40
  getBaseUrl(flattenToAppURL(action.result['@id'])),
41
41
  );
42
- if (hasExpander) {
42
+ if (hasExpander && !action.subrequest) {
43
43
  return {
44
44
  ...state,
45
45
  error: null,
package/src/routes.js CHANGED
@@ -29,6 +29,7 @@ import {
29
29
  ModerateComments,
30
30
  NotFound,
31
31
  PasswordReset,
32
+ Relations,
32
33
  Register,
33
34
  Rules,
34
35
  RequestPasswordReset,
@@ -224,6 +225,10 @@ export const defaultRoutes = [
224
225
  path: '/controlpanel/rules',
225
226
  component: RulesControlpanel,
226
227
  },
228
+ {
229
+ path: '/controlpanel/relations',
230
+ component: Relations,
231
+ },
227
232
  {
228
233
  path: '/controlpanel/:id',
229
234
  component: Controlpanel,
@@ -27,45 +27,48 @@
27
27
  }
28
28
 
29
29
  .controlpanel_matrix {
30
- display: grid;
31
- grid-gap: 2rem;
32
- grid-template-columns: 5fr 5fr 2fr;
30
+ .ui.action.input button.ui.icon.button {
31
+ background-color: transparent;
32
+ }
33
33
 
34
34
  .controlpanel_select_relation {
35
- grid-column: 1;
36
- grid-row: 1;
35
+ margin-bottom: 2rem;
37
36
  }
38
37
 
39
- .controlpanel_search_y {
40
- grid-column: 1;
41
- grid-row: 1;
38
+ .controlpanel_search_wrapper {
39
+ display: flex;
40
+ flex-wrap: wrap;
41
+ row-gap: 3rem;
42
+ column-gap: 5rem;
43
+ justify-content: flex-start;
44
+ margin-bottom: 2rem;
45
+ & > * {
46
+ min-width: 30rem;
47
+ }
42
48
  }
43
49
 
44
- .controlpanel_search_x {
45
- grid-column: 2;
46
- grid-row: 1;
50
+ .add_potential_sources .field,
51
+ .add_potential_targets .field,
52
+ .controlpanel_search_x .field,
53
+ .controlpanel_search_y .field {
54
+ display: flex;
47
55
  }
48
56
 
49
- .controlpanel_filter {
57
+ .controlpanel_listing_wrapper {
50
58
  display: flex;
51
- flex-direction: column;
52
- grid-column: 3;
53
- grid-row: 2;
54
-
55
- .ui.checkbox {
56
- margin-top: 0.5rem;
59
+ gap: 1rem;
60
+ justify-content: flex-end;
61
+ flex-wrap: wrap;
62
+ flex-direction: row-reverse;
63
+ margin-bottom: 2rem;
64
+ .administration_matrix {
65
+ flex-grow: 2;
66
+ min-width: 30rem;
67
+ }
68
+ .controlpanel_filter {
69
+ display: flex;
70
+ flex-direction: column;
57
71
  }
58
- }
59
-
60
- .administration_matrix {
61
- display: grid;
62
- height: 60rem;
63
- padding-right: 0;
64
- grid-column-end: 3;
65
- grid-column-start: 1;
66
- grid-row: 2;
67
- grid-template-rows: 14rem 1fr;
68
- overflow-x: scroll;
69
72
  }
70
73
  }
71
74
 
@@ -75,71 +78,91 @@
75
78
  }
76
79
 
77
80
  .label-options {
81
+ // display: flex;
82
+ // justify-content: start;
78
83
  position: sticky;
79
- z-index: 1000;
80
84
  top: 0;
81
- left: 0;
82
- display: flex;
83
- height: 14rem;
84
- align-items: baseline;
85
- justify-content: flex-end;
86
- padding-right: 2rem;
85
+ z-index: 100;
87
86
  .stickyLabelLayerBackground();
88
87
 
89
- .label-options-label {
88
+ .target-labels {
89
+ z-index: 2;
90
+ top: 0;
91
+ left: 0;
90
92
  display: flex;
91
- align-items: flex-end;
93
+ height: 14rem;
94
+ align-items: baseline;
95
+ // justify-content: flex-end;
96
+ // padding-right: 5rem;
97
+ @media only screen and (max-width: (@largestMobileScreen)) {
98
+ flex-direction: column;
99
+ }
100
+ & > div:first-child {
101
+ min-width: 15rem;
102
+ }
103
+ & > div:nth-child(2) {
104
+ flex-grow: 2;
105
+ display: flex;
106
+ }
92
107
 
93
- &.inclined {
94
- width: 3.5rem;
95
- height: 13rem;
96
- white-space: nowrap;
108
+ .label-options-label {
109
+ display: flex;
110
+ align-items: flex-end;
111
+
112
+ &.inclined {
113
+ width: 3.5rem;
114
+ height: 13rem;
115
+ white-space: nowrap;
97
116
 
98
- div {
99
- transform: rotate(315deg);
100
- transform-origin: top left;
117
+ div {
118
+ transform: rotate(315deg);
119
+ transform-origin: top left;
120
+ }
101
121
  }
102
122
  }
103
123
  }
104
124
  }
105
125
 
106
- .items {
107
- padding-top: 0.5rem;
108
-
109
- .listing-row {
110
- padding-right: 2rem;
111
-
112
- &:nth-child(2n) {
113
- background-color: rgba(0, 0, 50, 0.05);
126
+ .listing-row {
127
+ &:nth-child(2n) {
128
+ background-color: rgba(0, 0, 50, 0.05);
129
+ }
130
+ .listing-item {
131
+ display: flex;
132
+ width: 100%;
133
+ align-items: baseline;
134
+ justify-content: space-between;
135
+ padding: 0.5rem 0.1rem;
136
+ margin: 0.2rem 0;
137
+
138
+ & > div:first-child {
139
+ min-width: 15rem;
114
140
  }
141
+ .matrix_options {
142
+ flex-grow: 2;
143
+ display: flex;
144
+ flex-direction: row;
115
145
 
116
- &.selectall {
117
- margin-bottom: 1rem;
118
- }
146
+ & > div {
147
+ width: 3rem;
148
+ padding: 0.3rem 0.1rem;
149
+ margin-left: 0.5rem;
119
150
 
120
- .listing-item {
121
- display: flex;
122
- width: 100%;
123
- align-items: baseline;
124
- justify-content: space-between;
125
- padding: 0.5rem 0.1rem;
126
- margin: 0.2rem 0;
127
-
128
- .matrix_options {
129
- display: flex;
130
- flex-direction: row;
131
-
132
- & > div {
133
- width: 3rem;
134
- padding: 0.3rem 0.1rem;
135
- margin-left: 0.5rem;
136
-
137
- .ui.checkbox {
138
- margin: auto;
139
- }
151
+ .ui.checkbox {
152
+ margin: auto;
140
153
  }
141
154
  }
155
+ .ui.checkbox.toggle-target label:before {
156
+ border: 3px solid #826a6a;
157
+ }
142
158
  }
143
159
  }
144
160
  }
161
+
162
+ // Rows
163
+ .items {
164
+ .not-published {
165
+ opacity: 0.6;
166
+ }
167
+ }
145
168
  }