@plone/volto 17.0.0-alpha.0 → 17.0.0-alpha.10
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 +451 -19
- package/CONTRIBUTING.md +1 -1
- package/README.md +12 -15
- package/addon-registry.js +34 -0
- package/create-theme-addons-loader.js +79 -0
- package/cypress/support/commands.js +25 -0
- package/locales/ca/LC_MESSAGES/volto.po +187 -6
- package/locales/ca.json +1 -1
- package/locales/de/LC_MESSAGES/volto.po +206 -25
- package/locales/de.json +1 -1
- package/locales/en/LC_MESSAGES/volto.po +186 -5
- package/locales/en.json +1 -1
- package/locales/es/LC_MESSAGES/volto.po +187 -6
- package/locales/es.json +1 -1
- package/locales/eu/LC_MESSAGES/volto.po +187 -6
- package/locales/eu.json +1 -1
- package/locales/fi/LC_MESSAGES/volto.po +4792 -0
- package/locales/fi.json +1 -1
- package/locales/fr/LC_MESSAGES/volto.po +187 -6
- package/locales/fr.json +1 -1
- package/locales/it/LC_MESSAGES/volto.po +187 -6
- package/locales/it.json +1 -1
- package/locales/ja/LC_MESSAGES/volto.po +187 -6
- package/locales/ja.json +1 -1
- package/locales/nl/LC_MESSAGES/volto.po +842 -649
- package/locales/nl.json +1 -1
- package/locales/pt/LC_MESSAGES/volto.po +187 -6
- package/locales/pt.json +1 -1
- package/locales/pt_BR/LC_MESSAGES/volto.po +195 -14
- package/locales/pt_BR.json +1 -1
- package/locales/ro/LC_MESSAGES/volto.po +187 -6
- package/locales/ro.json +1 -1
- package/locales/volto.pot +187 -6
- package/locales/zh_CN/LC_MESSAGES/volto.po +187 -6
- package/locales/zh_CN.json +1 -1
- package/package-why.json +0 -1
- package/package.json +9 -8
- package/packages/volto-slate/build/messages/src/blocks/Table/TableBlockEdit.json +1 -1
- package/packages/volto-slate/build/messages/src/blocks/Text/DefaultTextBlockEditor.json +1 -1
- package/packages/volto-slate/build/messages/src/blocks/Text/DetachedTextBlockEditor.json +1 -1
- package/packages/volto-slate/build/messages/src/blocks/Text/SlashMenu.json +1 -1
- package/packages/volto-slate/build/messages/src/editor/plugins/AdvancedLink/index.json +1 -1
- package/packages/volto-slate/build/messages/src/editor/plugins/Link/index.json +1 -1
- package/packages/volto-slate/build/messages/src/editor/plugins/Table/index.json +1 -1
- package/packages/volto-slate/build/messages/src/elementEditor/messages.json +1 -1
- package/packages/volto-slate/build/messages/src/widgets/HtmlSlateWidget.json +1 -1
- package/packages/volto-slate/build/messages/src/widgets/RichTextWidgetView.json +1 -1
- package/packages/volto-slate/package.json +1 -1
- package/packages/volto-slate/src/blocks/Table/TableBlockView.jsx +4 -4
- package/packages/volto-slate/src/blocks/Table/index.js +2 -0
- package/packages/volto-slate/src/blocks/Text/SlashMenu.jsx +4 -3
- package/packages/volto-slate/src/editor/deserialize.js +0 -1
- package/packages/volto-slate/src/editor/plugins/StyleMenu/StyleMenu.jsx +14 -4
- package/razzle.config.js +28 -0
- package/src/actions/index.js +6 -0
- package/src/actions/language/language.js +9 -8
- package/src/actions/querystringsearch/querystringsearch.js +20 -14
- package/src/actions/relations/rebuild.js +25 -0
- package/src/actions/relations/relations.js +86 -0
- package/src/actions/relations/relations.test.js +15 -0
- package/src/components/index.js +1 -0
- package/src/components/manage/Add/Add.jsx +2 -2
- package/src/components/manage/BlockChooser/BlockChooser.jsx +14 -5
- package/src/components/manage/BlockChooser/BlockChooser.test.jsx +5 -0
- package/src/components/manage/BlockChooser/BlockChooserButton.jsx +63 -29
- package/src/components/manage/BlockChooser/BlockChooserSearch.jsx +0 -1
- package/src/components/manage/Blocks/Listing/Edit.jsx +0 -19
- package/src/components/manage/Blocks/Listing/ListingBody.jsx +77 -61
- package/src/components/manage/Blocks/Listing/View.jsx +0 -4
- package/src/components/manage/Blocks/Listing/getAsyncData.js +10 -2
- package/src/components/manage/Blocks/Listing/withQuerystringResults.jsx +18 -13
- package/src/components/manage/Blocks/Search/SearchBlockEdit.jsx +5 -4
- package/src/components/manage/Blocks/Search/SearchBlockView.jsx +2 -1
- package/src/components/manage/Blocks/Search/components/DateRangeFacet.jsx +4 -1
- package/src/components/manage/Blocks/Search/components/Facets.jsx +58 -2
- package/src/components/manage/Blocks/Search/hocs/withSearch.jsx +24 -11
- package/src/components/manage/Blocks/Search/layout/LeftColumnFacets.jsx +17 -5
- package/src/components/manage/Blocks/Search/layout/RightColumnFacets.jsx +17 -5
- package/src/components/manage/Blocks/Search/layout/TopSideFacets.jsx +21 -5
- package/src/components/manage/Blocks/Search/schema.js +16 -1
- package/src/components/manage/Blocks/ToC/Edit.jsx +1 -0
- package/src/components/manage/Contents/Contents.jsx +69 -33
- package/src/components/manage/Contents/ContentsItem.jsx +6 -0
- package/src/components/manage/Controlpanels/AddonsControlpanel.jsx +3 -3
- package/src/components/manage/Controlpanels/Controlpanels.jsx +199 -224
- package/src/components/manage/Controlpanels/Controlpanels.test.jsx +46 -7
- package/src/components/manage/Controlpanels/Relations/BrokenRelations.jsx +66 -0
- package/src/components/manage/Controlpanels/Relations/Relations.jsx +114 -0
- package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +479 -0
- package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +531 -0
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipControlPanel.jsx +3 -3
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipListing.jsx +51 -82
- package/src/components/manage/Controlpanels/Users/UserGroupMembershipMatrix.jsx +79 -75
- package/src/components/manage/DragDropList/DragDropList.jsx +63 -42
- package/src/components/manage/Form/BlocksToolbar.jsx +5 -1
- package/src/components/manage/Form/Form.jsx +11 -5
- package/src/components/manage/Form/InlineForm.jsx +39 -9
- package/src/components/manage/Form/InlineFormState.js +8 -0
- package/src/components/manage/History/History.jsx +35 -18
- package/src/components/manage/Multilingual/CreateTranslation.jsx +2 -2
- package/src/components/manage/Multilingual/TranslationObject.jsx +4 -3
- package/src/components/manage/Preferences/ChangePassword.jsx +2 -2
- package/src/components/manage/Preferences/PersonalPreferences.jsx +2 -2
- package/src/components/manage/Toast/Toast.jsx +1 -1
- package/src/components/manage/Toolbar/Types.jsx +2 -2
- package/src/components/manage/Widgets/DatetimeWidget.jsx +9 -5
- package/src/components/manage/Widgets/ObjectListWidget.jsx +3 -8
- package/src/components/manage/Widgets/RecurrenceWidget/ByDayField.jsx +2 -1
- package/src/components/manage/Widgets/RecurrenceWidget/MonthOfTheYearField.jsx +2 -1
- package/src/components/manage/Widgets/RecurrenceWidget/Occurences.jsx +2 -1
- package/src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx +7 -2
- package/src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthField.jsx +2 -1
- package/src/components/manage/Widgets/SelectUtils.js +1 -1
- package/src/components/manage/Widgets/SelectWidget.jsx +1 -1
- package/src/components/theme/Footer/Footer.jsx +2 -13
- package/src/components/theme/Header/Header.jsx +37 -63
- package/src/components/theme/Header/Header.test.jsx +18 -0
- package/src/components/theme/Icon/Icon.jsx +2 -2
- package/src/components/theme/LanguageSelector/LanguageSelector.js +8 -3
- package/src/components/theme/Login/Login.jsx +1 -0
- package/src/components/theme/Logo/Logo.jsx +2 -1
- package/src/components/theme/MultilingualRedirector/MultilingualRedirector.jsx +2 -2
- package/src/components/theme/Navigation/NavItem.jsx +4 -2
- package/src/components/theme/NotFound/NotFound.jsx +55 -41
- package/src/components/theme/PasswordReset/PasswordReset.jsx +7 -4
- package/src/components/theme/PasswordReset/RequestPasswordReset.jsx +1 -1
- package/src/components/theme/Sitemap/Sitemap.jsx +5 -3
- package/src/components/theme/View/DefaultView.jsx +1 -1
- package/src/components/theme/View/EventDatesInfo.jsx +2 -1
- package/src/components/theme/View/EventView.jsx +1 -1
- package/src/components/theme/View/NewsItemView.jsx +1 -1
- package/src/components/theme/View/RenderBlocks.jsx +7 -1
- package/src/components/theme/Widgets/DateWidget.jsx +2 -1
- package/src/components/theme/Widgets/DatetimeWidget.jsx +2 -1
- package/src/components/theme/Widgets/RelationsWidget.jsx +13 -11
- package/src/config/ControlPanels.js +2 -0
- package/src/config/Widgets.jsx +1 -0
- package/src/config/index.js +3 -0
- package/src/config/server.js +19 -0
- package/src/constants/ActionTypes.js +4 -0
- package/src/constants/Languages.js +8 -4
- package/src/express-middleware/devproxy.js +4 -2
- package/src/express-middleware/sitemap.js +36 -4
- package/src/express-middleware/static.js +32 -0
- package/src/helpers/Api/Api.js +1 -1
- package/src/helpers/FormValidation/FormValidation.js +11 -2
- package/src/helpers/FormValidation/FormValidation.test.js +73 -0
- package/src/helpers/Html/Html.jsx +3 -1
- package/src/helpers/Html/Html.test.jsx +5 -0
- package/src/helpers/MessageLabels/MessageLabels.js +72 -0
- package/src/helpers/Robots/Robots.js +24 -6
- package/src/helpers/Sitemap/Sitemap.js +44 -2
- package/src/helpers/Url/Url.js +27 -6
- package/src/helpers/Url/Url.test.js +26 -0
- package/src/helpers/Utils/Utils.js +38 -13
- package/src/helpers/Utils/Utils.test.js +4 -4
- package/src/helpers/index.js +7 -2
- package/src/hooks/userSession/useToken.js +5 -0
- package/src/middleware/Api.test.js +54 -0
- package/src/middleware/api.js +8 -4
- package/src/reducers/actions/actions.js +1 -1
- package/src/reducers/breadcrumbs/breadcrumbs.js +1 -1
- package/src/reducers/index.js +2 -0
- package/src/reducers/navigation/navigation.js +1 -1
- package/src/reducers/relations/relations.js +173 -0
- package/src/reducers/types/types.js +1 -1
- package/src/routes.js +5 -0
- package/src/server.jsx +29 -30
- package/src/start-server.js +4 -2
- package/test-setup-config.js +1 -0
- package/theme/themes/pastanaga/extras/blocks.less +0 -9
- package/theme/themes/pastanaga/extras/contents.less +1 -0
- package/theme/themes/pastanaga/extras/main.less +80 -1
- package/theme/themes/pastanaga/extras/search.less +6 -0
- package/theme/themes/pastanaga/extras/sidebar.less +4 -0
- package/theme/themes/pastanaga/extras/userscontrolpanel.less +99 -76
- package/.changelog.draft +0 -22
- package/.editorconfig +0 -36
- package/.storybook/main.js +0 -127
- package/.storybook/manager.js +0 -15
- package/.storybook/preview.js +0 -21
- package/.storybook/static/previewImage.svg +0 -48
- package/.yarnrc.yml +0 -5
- package/jsdoc.json +0 -16
- package/netlify.toml +0 -5
- package/pyvenv.cfg +0 -3
- package/share/man/man1/ttx.1 +0 -225
- package/src/components/theme/Header/Header.md +0 -27
- package/towncrier.toml +0 -33
|
@@ -9,8 +9,6 @@ import { listGroups } from '@plone/volto/actions';
|
|
|
9
9
|
import { Icon, Toast } from '@plone/volto/components';
|
|
10
10
|
import { updateGroup, listUsers } from '@plone/volto/actions';
|
|
11
11
|
|
|
12
|
-
import add from '@plone/volto/icons/add.svg';
|
|
13
|
-
import remove from '@plone/volto/icons/remove.svg';
|
|
14
12
|
import down_key from '@plone/volto/icons/down-key.svg';
|
|
15
13
|
|
|
16
14
|
const ListingTemplate = ({
|
|
@@ -116,7 +114,7 @@ const ListingTemplate = ({
|
|
|
116
114
|
}
|
|
117
115
|
}, [dispatch, query_group, show_matrix_options, groups_filter]);
|
|
118
116
|
|
|
119
|
-
const onSelectOptionHandler = (
|
|
117
|
+
const onSelectOptionHandler = (selectedvalue, checked, singleClick) => {
|
|
120
118
|
singleClick = singleClick ?? false;
|
|
121
119
|
let group = selectedvalue.y;
|
|
122
120
|
let username = selectedvalue.x;
|
|
@@ -150,17 +148,14 @@ const ListingTemplate = ({
|
|
|
150
148
|
});
|
|
151
149
|
};
|
|
152
150
|
|
|
153
|
-
const onSelectAllHandler = (
|
|
154
|
-
let elements = document.querySelectorAll(`div.checkbox_${mtxoption} input`);
|
|
155
|
-
let identifier;
|
|
151
|
+
const onSelectAllHandler = (group, items_ids, checked) => {
|
|
156
152
|
let usersgroupmapping = {};
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
usersgroupmapping[identifier[1]] = checked ? true : false;
|
|
153
|
+
items_ids.forEach((el) => {
|
|
154
|
+
usersgroupmapping[el] = checked ? true : false;
|
|
160
155
|
});
|
|
161
156
|
|
|
162
157
|
dispatch(
|
|
163
|
-
updateGroup(
|
|
158
|
+
updateGroup(group, {
|
|
164
159
|
users: usersgroupmapping,
|
|
165
160
|
}),
|
|
166
161
|
)
|
|
@@ -188,93 +183,68 @@ const ListingTemplate = ({
|
|
|
188
183
|
<div className="administration_matrix">
|
|
189
184
|
{matrix_options && matrix_options?.length > 0 && (
|
|
190
185
|
<div className="label-options">
|
|
191
|
-
|
|
192
|
-
<div
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
>
|
|
196
|
-
|
|
197
|
-
<
|
|
186
|
+
<div className="target-labels">
|
|
187
|
+
<div>
|
|
188
|
+
<h3>{items.length} users</h3>
|
|
189
|
+
</div>
|
|
190
|
+
<div>
|
|
191
|
+
{matrix_options?.map((matrix_option) => (
|
|
192
|
+
<div
|
|
193
|
+
className="label-options-label inclined"
|
|
194
|
+
key={matrix_option.value}
|
|
195
|
+
>
|
|
196
|
+
<div>
|
|
197
|
+
<span className="label">{matrix_option.label}</span>
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
))}
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
<div className="listing-row selectall" key="selectall">
|
|
204
|
+
<div className="listing-item">
|
|
205
|
+
<div />
|
|
206
|
+
<div className="matrix_options">
|
|
207
|
+
{matrix_options?.map((matrix_option) => (
|
|
208
|
+
<div key={matrix_option.value}>
|
|
209
|
+
<Checkbox
|
|
210
|
+
className="toggle-target"
|
|
211
|
+
defaultChecked={false}
|
|
212
|
+
onChange={(event, { checked }) =>
|
|
213
|
+
onSelectAllHandler(
|
|
214
|
+
matrix_option.value,
|
|
215
|
+
items.map((el) => el.id),
|
|
216
|
+
checked,
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
/>
|
|
220
|
+
</div>
|
|
221
|
+
))}
|
|
198
222
|
</div>
|
|
199
223
|
</div>
|
|
200
|
-
|
|
224
|
+
</div>
|
|
201
225
|
</div>
|
|
202
226
|
)}
|
|
203
227
|
|
|
204
228
|
<div className="items">
|
|
205
229
|
{items.length > 0 ? (
|
|
206
230
|
<>
|
|
207
|
-
<div className="listing-row selectall" key="selectall">
|
|
208
|
-
<div className="listing-item">
|
|
209
|
-
<div />
|
|
210
|
-
<div className="matrix_options">
|
|
211
|
-
{matrix_options?.map((matrix_option) => (
|
|
212
|
-
<div key={matrix_option.value}>
|
|
213
|
-
<Button
|
|
214
|
-
icon
|
|
215
|
-
basic
|
|
216
|
-
onClick={() =>
|
|
217
|
-
onSelectAllHandler(matrix_option.value, true)
|
|
218
|
-
}
|
|
219
|
-
className="add-button"
|
|
220
|
-
aria-label={
|
|
221
|
-
intl.formatMessage(messages.addUsersToGroup) +
|
|
222
|
-
` ${matrix_option.label}`
|
|
223
|
-
}
|
|
224
|
-
title={
|
|
225
|
-
intl.formatMessage(messages.addUsersToGroup) +
|
|
226
|
-
` ${matrix_option.label}`
|
|
227
|
-
}
|
|
228
|
-
>
|
|
229
|
-
<Icon
|
|
230
|
-
name={add}
|
|
231
|
-
size="10px"
|
|
232
|
-
className="circled"
|
|
233
|
-
color="unset"
|
|
234
|
-
/>
|
|
235
|
-
</Button>
|
|
236
|
-
<Button
|
|
237
|
-
icon
|
|
238
|
-
basic
|
|
239
|
-
onClick={() =>
|
|
240
|
-
onSelectAllHandler(matrix_option.value, false)
|
|
241
|
-
}
|
|
242
|
-
className="remove-button"
|
|
243
|
-
aria-label={
|
|
244
|
-
intl.formatMessage(messages.removeUsersFromGroup) +
|
|
245
|
-
` ${matrix_option.label}`
|
|
246
|
-
}
|
|
247
|
-
title={
|
|
248
|
-
intl.formatMessage(messages.removeUsersFromGroup) +
|
|
249
|
-
` ${matrix_option.label}`
|
|
250
|
-
}
|
|
251
|
-
>
|
|
252
|
-
<Icon
|
|
253
|
-
name={remove}
|
|
254
|
-
size="10px"
|
|
255
|
-
className="circled"
|
|
256
|
-
color="unset"
|
|
257
|
-
/>
|
|
258
|
-
</Button>
|
|
259
|
-
</div>
|
|
260
|
-
))}
|
|
261
|
-
</div>
|
|
262
|
-
</div>
|
|
263
|
-
</div>
|
|
264
|
-
|
|
265
|
-
<h3>{items.length} users </h3>
|
|
266
231
|
{items.map((item) => (
|
|
267
|
-
<div
|
|
232
|
+
<div
|
|
233
|
+
className="listing-row"
|
|
234
|
+
key={item.id}
|
|
235
|
+
id={`source-row-${item.id}`}
|
|
236
|
+
>
|
|
268
237
|
<div className="listing-item" key={item['@id']}>
|
|
269
238
|
<div>
|
|
270
|
-
<h4>
|
|
271
|
-
{item.fullname
|
|
239
|
+
<h4 title={`${item.fullname} ${item.id}`}>
|
|
240
|
+
{item.fullname?.length > 25
|
|
241
|
+
? item.fullname.slice(0, 22) + '...'
|
|
242
|
+
: item.fullname || item.id}
|
|
272
243
|
</h4>
|
|
273
244
|
</div>
|
|
274
245
|
<div className="matrix_options">
|
|
275
246
|
{matrix_options?.map((matrix_option) => (
|
|
276
247
|
<Checkbox
|
|
277
|
-
name={`member_-_${item.id}_-_${matrix_option.value}`}
|
|
278
248
|
className={`checkbox_${matrix_option.value}`}
|
|
279
249
|
key={matrix_option.value}
|
|
280
250
|
title={matrix_option.title}
|
|
@@ -283,7 +253,6 @@ const ListingTemplate = ({
|
|
|
283
253
|
.includes(matrix_option.value)}
|
|
284
254
|
onChange={(event, { checked }) => {
|
|
285
255
|
onSelectOptionHandler(
|
|
286
|
-
item,
|
|
287
256
|
{ y: matrix_option.value, x: item.id },
|
|
288
257
|
checked,
|
|
289
258
|
true,
|
|
@@ -122,83 +122,87 @@ const UserGroupMembershipMatrix = ({ many_users, many_groups }) => {
|
|
|
122
122
|
|
|
123
123
|
return (
|
|
124
124
|
<div className="controlpanel_matrix">
|
|
125
|
-
<div className="
|
|
126
|
-
<
|
|
127
|
-
<Form
|
|
128
|
-
<
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
125
|
+
<div className="controlpanel_search_wrapper">
|
|
126
|
+
<div className="controlpanel_search_y">
|
|
127
|
+
<Form className="search_users" onSubmit={onReset}>
|
|
128
|
+
<Form.Field>
|
|
129
|
+
<Input
|
|
130
|
+
name="SearchUser"
|
|
131
|
+
action={{ icon: 'delete' }}
|
|
132
|
+
placeholder={intl.formatMessage(messages.searchUsers)}
|
|
133
|
+
onChange={onChangeSearchUsers}
|
|
134
|
+
onKeyDown={onChangeSearchUsers}
|
|
135
|
+
id="user-search-input"
|
|
136
|
+
/>
|
|
137
|
+
</Form.Field>
|
|
138
|
+
</Form>
|
|
139
|
+
</div>
|
|
140
|
+
<div className="controlpanel_search_x">
|
|
141
|
+
<Form className="search_groups" onSubmit={onReset}>
|
|
142
|
+
<Form.Field>
|
|
143
|
+
<Input
|
|
144
|
+
name="SearchGroup"
|
|
145
|
+
action={{ icon: 'delete' }}
|
|
146
|
+
placeholder={intl.formatMessage(messages.searchGroups)}
|
|
147
|
+
onChange={onChangeSearchGroups}
|
|
148
|
+
onKeyDown={onChangeSearchGroups}
|
|
149
|
+
id="group-search-input"
|
|
150
|
+
/>
|
|
151
|
+
</Form.Field>
|
|
152
|
+
<Form.Field>
|
|
153
|
+
<Checkbox
|
|
154
|
+
name="addJoinedGroups"
|
|
155
|
+
label={intl.formatMessage(messages.addJoinedGroups)}
|
|
156
|
+
title={intl.formatMessage(messages.addJoinedGroups)}
|
|
157
|
+
defaultChecked={false}
|
|
158
|
+
onChange={(event, { checked }) => {
|
|
159
|
+
onToggleJoinedGroups(checked);
|
|
160
|
+
}}
|
|
161
|
+
/>
|
|
162
|
+
</Form.Field>
|
|
163
|
+
</Form>
|
|
164
|
+
</div>
|
|
138
165
|
</div>
|
|
139
|
-
<div className="
|
|
140
|
-
<
|
|
141
|
-
<
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
166
|
+
<div className="controlpanel_listing_wrapper">
|
|
167
|
+
<div className="controlpanel_filter">
|
|
168
|
+
<h3>{intl.formatMessage(messages.filterByGroups)}</h3>
|
|
169
|
+
<Form className="search_filter_groups" onSubmit={onReset}>
|
|
170
|
+
<Form.Field>
|
|
171
|
+
<Input
|
|
172
|
+
name="SearchGroupFilter"
|
|
173
|
+
action={{ icon: 'delete' }}
|
|
174
|
+
placeholder={intl.formatMessage(messages.searchGroups)}
|
|
175
|
+
onChange={onChangeSearchGroupsFilter}
|
|
176
|
+
onKeyDown={onChangeSearchGroupsFilter}
|
|
177
|
+
id="groupfilter-search-input"
|
|
178
|
+
/>
|
|
179
|
+
</Form.Field>
|
|
180
|
+
</Form>
|
|
181
|
+
{(!many_groups || query_group_filter.length > 1) &&
|
|
182
|
+
filter_options?.map((filter_option) => (
|
|
183
|
+
<Form.Field>
|
|
184
|
+
<Checkbox
|
|
185
|
+
name={`filter_option_${filter_option.value}`}
|
|
186
|
+
key={filter_option.value}
|
|
187
|
+
title={filter_option.label}
|
|
188
|
+
label={filter_option.label}
|
|
189
|
+
defaultChecked={false}
|
|
190
|
+
onChange={(event, { checked }) => {
|
|
191
|
+
onSelectOptionHandler(filter_option, checked);
|
|
192
|
+
}}
|
|
193
|
+
/>
|
|
194
|
+
</Form.Field>
|
|
195
|
+
))}
|
|
196
|
+
</div>
|
|
197
|
+
<UserGroupMembershipListing
|
|
198
|
+
query_user={query_user}
|
|
199
|
+
query_group={query_group}
|
|
200
|
+
groups_filter={groups_filter}
|
|
201
|
+
add_joined_groups={add_joined_groups}
|
|
202
|
+
many_users={many_users}
|
|
203
|
+
many_groups={many_groups}
|
|
204
|
+
/>
|
|
163
205
|
</div>
|
|
164
|
-
<div className="controlpanel_filter">
|
|
165
|
-
<h3>{intl.formatMessage(messages.filterByGroups)}</h3>
|
|
166
|
-
|
|
167
|
-
<Form className="search_filter_groups" onSubmit={onReset}>
|
|
168
|
-
<Form.Field>
|
|
169
|
-
<Input
|
|
170
|
-
name="SearchGroupFilter"
|
|
171
|
-
action={{ icon: 'delete' }}
|
|
172
|
-
placeholder={intl.formatMessage(messages.searchGroups)}
|
|
173
|
-
onChange={onChangeSearchGroupsFilter}
|
|
174
|
-
onKeyDown={onChangeSearchGroupsFilter}
|
|
175
|
-
id="groupfilter-search-input"
|
|
176
|
-
/>
|
|
177
|
-
</Form.Field>
|
|
178
|
-
</Form>
|
|
179
|
-
|
|
180
|
-
{(!many_groups || query_group_filter.length > 1) &&
|
|
181
|
-
filter_options?.map((filter_option) => (
|
|
182
|
-
<Checkbox
|
|
183
|
-
name={`filter_option_${filter_option.value}`}
|
|
184
|
-
key={filter_option.value}
|
|
185
|
-
title={filter_option.label}
|
|
186
|
-
label={filter_option.label}
|
|
187
|
-
defaultChecked={false}
|
|
188
|
-
onChange={(event, { checked }) => {
|
|
189
|
-
onSelectOptionHandler(filter_option, checked);
|
|
190
|
-
}}
|
|
191
|
-
/>
|
|
192
|
-
))}
|
|
193
|
-
</div>
|
|
194
|
-
<UserGroupMembershipListing
|
|
195
|
-
query_user={query_user}
|
|
196
|
-
query_group={query_group}
|
|
197
|
-
groups_filter={groups_filter}
|
|
198
|
-
add_joined_groups={add_joined_groups}
|
|
199
|
-
many_users={many_users}
|
|
200
|
-
many_groups={many_groups}
|
|
201
|
-
/>
|
|
202
206
|
</div>
|
|
203
207
|
);
|
|
204
208
|
};
|
|
@@ -3,7 +3,7 @@ import { isEmpty } from 'lodash';
|
|
|
3
3
|
import { injectLazyLibs } from '@plone/volto/helpers/Loadable/Loadable';
|
|
4
4
|
import { v4 as uuid } from 'uuid';
|
|
5
5
|
|
|
6
|
-
const getPlaceholder = (draggedDOM, sourceIndex, destinationIndex) => {
|
|
6
|
+
const getPlaceholder = (draggedDOM, sourceIndex, destinationIndex, uid) => {
|
|
7
7
|
// Because of the margin rendering rules, there is no easy
|
|
8
8
|
// way to calculate the offset of the placeholder.
|
|
9
9
|
//
|
|
@@ -13,12 +13,16 @@ const getPlaceholder = (draggedDOM, sourceIndex, destinationIndex) => {
|
|
|
13
13
|
//
|
|
14
14
|
// To get a placeholder that looks good in all cases, we
|
|
15
15
|
// fill up the space between the previous and the next element.
|
|
16
|
-
const
|
|
16
|
+
const queryAttr = 'data-rbd-droppable-id';
|
|
17
|
+
const domQuery = `[${queryAttr}='${uid}']`;
|
|
18
|
+
const parentDOM = document.querySelector(domQuery);
|
|
19
|
+
|
|
20
|
+
const childrenArray = [...parentDOM.children];
|
|
17
21
|
// Remove the source element
|
|
18
22
|
childrenArray.splice(sourceIndex, 1);
|
|
19
23
|
// Also remove the placeholder that the library always inserts at the end
|
|
20
24
|
childrenArray.splice(-1, 1);
|
|
21
|
-
const parentRect =
|
|
25
|
+
const parentRect = parentDOM.getBoundingClientRect();
|
|
22
26
|
const prevNode = childrenArray[destinationIndex - 1];
|
|
23
27
|
const nextNode = childrenArray[destinationIndex];
|
|
24
28
|
let top, bottom;
|
|
@@ -40,9 +44,7 @@ const getPlaceholder = (draggedDOM, sourceIndex, destinationIndex) => {
|
|
|
40
44
|
return {
|
|
41
45
|
clientY: top,
|
|
42
46
|
clientHeight: bottom - top,
|
|
43
|
-
clientX: parseFloat(
|
|
44
|
-
window.getComputedStyle(draggedDOM.parentNode).paddingLeft,
|
|
45
|
-
),
|
|
47
|
+
clientX: parseFloat(window.getComputedStyle(parentDOM).paddingLeft),
|
|
46
48
|
clientWidth: draggedDOM.clientWidth,
|
|
47
49
|
};
|
|
48
50
|
};
|
|
@@ -63,17 +65,22 @@ const DragDropList = (props) => {
|
|
|
63
65
|
// queueing timed action
|
|
64
66
|
const timer = useRef(null);
|
|
65
67
|
|
|
66
|
-
const onDragStart = React.useCallback(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
68
|
+
const onDragStart = React.useCallback(
|
|
69
|
+
(event) => {
|
|
70
|
+
clearTimeout(timer.current);
|
|
71
|
+
const queryAttr = 'data-rbd-draggable-id';
|
|
72
|
+
const domQuery = `[${queryAttr}='${event.draggableId}']`;
|
|
73
|
+
const draggedDOM = document.querySelector(domQuery);
|
|
74
|
+
if (!draggedDOM) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const sourceIndex = event.source.index;
|
|
78
|
+
setPlaceholderProps(
|
|
79
|
+
getPlaceholder(draggedDOM, sourceIndex, sourceIndex, uid),
|
|
80
|
+
);
|
|
81
|
+
},
|
|
82
|
+
[uid],
|
|
83
|
+
);
|
|
77
84
|
|
|
78
85
|
const onDragEnd = React.useCallback(
|
|
79
86
|
(result) => {
|
|
@@ -84,30 +91,33 @@ const DragDropList = (props) => {
|
|
|
84
91
|
[onMoveItem],
|
|
85
92
|
);
|
|
86
93
|
|
|
87
|
-
const onDragUpdate = React.useCallback(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
94
|
+
const onDragUpdate = React.useCallback(
|
|
95
|
+
(update) => {
|
|
96
|
+
clearTimeout(timer.current);
|
|
97
|
+
setPlaceholderProps({});
|
|
98
|
+
if (!update.destination) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const draggableId = update.draggableId;
|
|
102
|
+
const queryAttr = 'data-rbd-draggable-id';
|
|
103
|
+
const domQuery = `[${queryAttr}='${draggableId}']`;
|
|
104
|
+
const draggedDOM = document.querySelector(domQuery);
|
|
105
|
+
if (!draggedDOM) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const sourceIndex = update.source.index;
|
|
109
|
+
const destinationIndex = update.destination.index;
|
|
110
|
+
// Wait until the animations have finished, to make it look good.
|
|
111
|
+
timer.current = setTimeout(
|
|
112
|
+
() =>
|
|
113
|
+
setPlaceholderProps(
|
|
114
|
+
getPlaceholder(draggedDOM, sourceIndex, destinationIndex, uid),
|
|
115
|
+
),
|
|
116
|
+
250,
|
|
117
|
+
);
|
|
118
|
+
},
|
|
119
|
+
[uid],
|
|
120
|
+
);
|
|
111
121
|
|
|
112
122
|
const AsDomComponent = as;
|
|
113
123
|
return (
|
|
@@ -116,7 +126,18 @@ const DragDropList = (props) => {
|
|
|
116
126
|
onDragUpdate={onDragUpdate}
|
|
117
127
|
onDragEnd={onDragEnd}
|
|
118
128
|
>
|
|
119
|
-
<Droppable
|
|
129
|
+
<Droppable
|
|
130
|
+
droppableId={uid}
|
|
131
|
+
renderClone={(provided, snapshot, rubric) => {
|
|
132
|
+
const index = rubric.source.index;
|
|
133
|
+
return children({
|
|
134
|
+
child: childList[index][1],
|
|
135
|
+
childId: childList[index][0],
|
|
136
|
+
index,
|
|
137
|
+
draginfo: provided,
|
|
138
|
+
});
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
120
141
|
{(provided, snapshot) => (
|
|
121
142
|
<AsDomComponent
|
|
122
143
|
ref={provided.innerRef}
|
|
@@ -177,7 +177,11 @@ export class BlocksToolbarComponent extends React.Component {
|
|
|
177
177
|
''
|
|
178
178
|
)}
|
|
179
179
|
{selectedBlock && (blocksClipboard?.cut || blocksClipboard?.copy) && (
|
|
180
|
-
<Plug
|
|
180
|
+
<Plug
|
|
181
|
+
pluggable="main.toolbar.bottom"
|
|
182
|
+
id="block-paste-btn"
|
|
183
|
+
dependencies={[selectedBlock]}
|
|
184
|
+
>
|
|
181
185
|
<button
|
|
182
186
|
aria-label={intl.formatMessage(messages.pasteBlocks)}
|
|
183
187
|
onClick={this.pasteBlocks}
|
|
@@ -31,7 +31,7 @@ import { Portal } from 'react-portal';
|
|
|
31
31
|
import { connect } from 'react-redux';
|
|
32
32
|
import {
|
|
33
33
|
Button,
|
|
34
|
-
Container,
|
|
34
|
+
Container as SemanticContainer,
|
|
35
35
|
Form as UiForm,
|
|
36
36
|
Message,
|
|
37
37
|
Segment,
|
|
@@ -258,7 +258,11 @@ class Form extends Component {
|
|
|
258
258
|
* Tab selection is done only by setting activeIndex in state
|
|
259
259
|
*/
|
|
260
260
|
onTabChange(e, { activeIndex }) {
|
|
261
|
-
this.
|
|
261
|
+
const defaultFocus = this.props.schema.fieldsets[activeIndex].fields[0];
|
|
262
|
+
this.setState({
|
|
263
|
+
activeIndex,
|
|
264
|
+
...(defaultFocus ? { inFocus: { [defaultFocus]: true } } : {}),
|
|
265
|
+
});
|
|
262
266
|
}
|
|
263
267
|
|
|
264
268
|
/**
|
|
@@ -541,12 +545,14 @@ class Form extends Component {
|
|
|
541
545
|
const { schema: originalSchema, onCancel, onSubmit } = this.props;
|
|
542
546
|
const { formData } = this.state;
|
|
543
547
|
const schema = this.removeBlocksLayoutFields(originalSchema);
|
|
548
|
+
const Container =
|
|
549
|
+
config.getComponent({ name: 'Container' }).component || SemanticContainer;
|
|
544
550
|
|
|
545
551
|
return this.props.visual ? (
|
|
546
552
|
// Removing this from SSR is important, since react-beautiful-dnd supports SSR,
|
|
547
553
|
// but draftJS don't like it much and the hydration gets messed up
|
|
548
554
|
this.state.isClient && (
|
|
549
|
-
<
|
|
555
|
+
<Container>
|
|
550
556
|
<BlocksToolbar
|
|
551
557
|
formData={this.state.formData}
|
|
552
558
|
selectedBlock={this.state.selected}
|
|
@@ -635,7 +641,7 @@ class Form extends Component {
|
|
|
635
641
|
</UiForm>
|
|
636
642
|
</Portal>
|
|
637
643
|
)}
|
|
638
|
-
</
|
|
644
|
+
</Container>
|
|
639
645
|
)
|
|
640
646
|
) : (
|
|
641
647
|
<Container>
|
|
@@ -686,7 +692,7 @@ class Form extends Component {
|
|
|
686
692
|
id={field}
|
|
687
693
|
formData={this.state.formData}
|
|
688
694
|
fieldSet={item.title.toLowerCase()}
|
|
689
|
-
focus={
|
|
695
|
+
focus={this.state.inFocus[field]}
|
|
690
696
|
value={this.state.formData?.[field]}
|
|
691
697
|
required={schema.required.indexOf(field) !== -1}
|
|
692
698
|
onChange={this.onChangeField}
|
|
@@ -4,13 +4,21 @@ import { Accordion, Segment, Message } from 'semantic-ui-react';
|
|
|
4
4
|
import { defineMessages, injectIntl } from 'react-intl';
|
|
5
5
|
import AnimateHeight from 'react-animate-height';
|
|
6
6
|
import { keys, map, isEqual } from 'lodash';
|
|
7
|
-
|
|
7
|
+
import { useAtom } from 'jotai';
|
|
8
|
+
import { inlineFormFieldsetsState } from './InlineFormState';
|
|
9
|
+
import {
|
|
10
|
+
insertInArray,
|
|
11
|
+
removeFromArray,
|
|
12
|
+
arrayRange,
|
|
13
|
+
} from '@plone/volto/helpers/Utils/Utils';
|
|
8
14
|
import { Field, Icon } from '@plone/volto/components';
|
|
9
15
|
import { applySchemaDefaults } from '@plone/volto/helpers';
|
|
10
16
|
|
|
11
17
|
import upSVG from '@plone/volto/icons/up-key.svg';
|
|
12
18
|
import downSVG from '@plone/volto/icons/down-key.svg';
|
|
13
19
|
|
|
20
|
+
import config from '@plone/volto/registry';
|
|
21
|
+
|
|
14
22
|
const messages = defineMessages({
|
|
15
23
|
editValues: {
|
|
16
24
|
id: 'Edit values',
|
|
@@ -70,12 +78,34 @@ const InlineForm = (props) => {
|
|
|
70
78
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
71
79
|
}, []);
|
|
72
80
|
|
|
73
|
-
const [currentActiveFieldset, setCurrentActiveFieldset] =
|
|
81
|
+
const [currentActiveFieldset, setCurrentActiveFieldset] = useAtom(
|
|
82
|
+
inlineFormFieldsetsState({
|
|
83
|
+
name: block,
|
|
84
|
+
fielsetList: other,
|
|
85
|
+
initialState: config.settings.blockSettingsTabFieldsetsInitialStateOpen
|
|
86
|
+
? arrayRange(0, other.length - 1, 1)
|
|
87
|
+
: [],
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
|
|
74
91
|
function handleCurrentActiveFieldset(e, blockProps) {
|
|
75
92
|
const { index } = blockProps;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
93
|
+
if (currentActiveFieldset.includes(index)) {
|
|
94
|
+
setCurrentActiveFieldset(
|
|
95
|
+
removeFromArray(
|
|
96
|
+
currentActiveFieldset,
|
|
97
|
+
currentActiveFieldset.indexOf(index),
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
} else {
|
|
101
|
+
setCurrentActiveFieldset(
|
|
102
|
+
insertInArray(
|
|
103
|
+
currentActiveFieldset,
|
|
104
|
+
index,
|
|
105
|
+
currentActiveFieldset.length + 1,
|
|
106
|
+
),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
79
109
|
}
|
|
80
110
|
|
|
81
111
|
return (
|
|
@@ -136,22 +166,22 @@ const InlineForm = (props) => {
|
|
|
136
166
|
<Accordion fluid styled className="form" key={fieldset.id}>
|
|
137
167
|
<div key={fieldset.id} id={`blockform-fieldset-${fieldset.id}`}>
|
|
138
168
|
<Accordion.Title
|
|
139
|
-
active={currentActiveFieldset
|
|
169
|
+
active={currentActiveFieldset.includes(index)}
|
|
140
170
|
index={index}
|
|
141
171
|
onClick={handleCurrentActiveFieldset}
|
|
142
172
|
>
|
|
143
173
|
{fieldset.title && <>{fieldset.title}</>}
|
|
144
|
-
{currentActiveFieldset
|
|
174
|
+
{currentActiveFieldset.includes(index) ? (
|
|
145
175
|
<Icon name={upSVG} size="20px" />
|
|
146
176
|
) : (
|
|
147
177
|
<Icon name={downSVG} size="20px" />
|
|
148
178
|
)}
|
|
149
179
|
</Accordion.Title>
|
|
150
|
-
<Accordion.Content active={currentActiveFieldset
|
|
180
|
+
<Accordion.Content active={currentActiveFieldset.includes(index)}>
|
|
151
181
|
<AnimateHeight
|
|
152
182
|
animateOpacity
|
|
153
183
|
duration={500}
|
|
154
|
-
height={currentActiveFieldset
|
|
184
|
+
height={currentActiveFieldset.includes(index) ? 'auto' : 0}
|
|
155
185
|
>
|
|
156
186
|
<Segment className="attached">
|
|
157
187
|
{map(fieldset.fields, (field) => (
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { atom } from 'jotai';
|
|
2
|
+
import { atomFamily } from 'jotai/utils';
|
|
3
|
+
import { isEqual } from 'lodash';
|
|
4
|
+
|
|
5
|
+
export const inlineFormFieldsetsState = atomFamily(
|
|
6
|
+
({ name, initialState }) => atom(initialState),
|
|
7
|
+
(a, b) => a.name === b.name && isEqual(a.fielsetList, b.fielsetList),
|
|
8
|
+
);
|