@plone/volto 18.0.0-alpha.33 → 18.0.0-alpha.34

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 (74) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/locales/ca/LC_MESSAGES/volto.po +5 -0
  3. package/locales/ca.json +1 -1
  4. package/locales/de/LC_MESSAGES/volto.po +5 -0
  5. package/locales/de.json +1 -1
  6. package/locales/en/LC_MESSAGES/volto.po +5 -0
  7. package/locales/en.json +1 -1
  8. package/locales/es/LC_MESSAGES/volto.po +5 -0
  9. package/locales/es.json +1 -1
  10. package/locales/eu/LC_MESSAGES/volto.po +5 -0
  11. package/locales/eu.json +1 -1
  12. package/locales/fi/LC_MESSAGES/volto.po +5 -0
  13. package/locales/fi.json +1 -1
  14. package/locales/fr/LC_MESSAGES/volto.po +5 -0
  15. package/locales/fr.json +1 -1
  16. package/locales/hi/LC_MESSAGES/volto.po +5 -0
  17. package/locales/hi.json +1 -1
  18. package/locales/it/LC_MESSAGES/volto.po +5 -0
  19. package/locales/it.json +1 -1
  20. package/locales/ja/LC_MESSAGES/volto.po +5 -0
  21. package/locales/ja.json +1 -1
  22. package/locales/nl/LC_MESSAGES/volto.po +5 -0
  23. package/locales/nl.json +1 -1
  24. package/locales/pt/LC_MESSAGES/volto.po +5 -0
  25. package/locales/pt.json +1 -1
  26. package/locales/pt_BR/LC_MESSAGES/volto.po +5 -0
  27. package/locales/pt_BR.json +1 -1
  28. package/locales/ro/LC_MESSAGES/volto.po +5 -0
  29. package/locales/ro.json +1 -1
  30. package/locales/volto.pot +5 -0
  31. package/locales/zh_CN/LC_MESSAGES/volto.po +5 -0
  32. package/locales/zh_CN.json +1 -1
  33. package/package.json +9 -6
  34. package/razzle.config.js +13 -4
  35. package/src/actions/form/form.js +18 -2
  36. package/src/actions/index.js +1 -1
  37. package/src/components/manage/Blocks/Block/BlocksForm.jsx +157 -81
  38. package/src/components/manage/Blocks/Block/BlocksForm.test.jsx +8 -0
  39. package/src/components/manage/Blocks/Block/Edit.jsx +37 -4
  40. package/src/components/manage/Blocks/Block/Order/Item.jsx +122 -0
  41. package/src/components/manage/Blocks/Block/Order/Order.jsx +367 -0
  42. package/src/components/manage/Blocks/Block/Order/SortableItem.jsx +58 -0
  43. package/src/components/manage/Blocks/Block/Order/utilities.js +113 -0
  44. package/src/components/manage/Blocks/Container/Edit.jsx +1 -0
  45. package/src/components/manage/Blocks/Grid/Edit.jsx +6 -4
  46. package/src/components/manage/Blocks/Image/schema.js +2 -0
  47. package/src/components/manage/Controlpanels/Relations/RelationsListing.jsx +1 -1
  48. package/src/components/manage/Controlpanels/Relations/RelationsMatrix.jsx +1 -1
  49. package/src/components/manage/Form/Form.jsx +159 -151
  50. package/src/components/manage/Sidebar/Sidebar.jsx +28 -1
  51. package/src/components/manage/Widgets/InternalUrlWidget.jsx +10 -14
  52. package/src/components/theme/FormattedDate/FormattedDate.jsx +13 -1
  53. package/src/components/theme/Icon/Icon.jsx +4 -4
  54. package/src/config/Loadables.jsx +18 -0
  55. package/src/constants/ActionTypes.js +1 -0
  56. package/src/helpers/Blocks/Blocks.js +182 -1
  57. package/src/helpers/Blocks/Blocks.test.js +136 -0
  58. package/src/helpers/index.js +4 -0
  59. package/src/reducers/form/form.js +18 -1
  60. package/src/reducers/form/form.test.js +15 -1
  61. package/theme/themes/pastanaga/extras/blocks.less +7 -6
  62. package/theme/themes/pastanaga/extras/sidebar.less +145 -0
  63. package/types/actions/form/form.d.ts +8 -1
  64. package/types/actions/index.d.ts +1 -1
  65. package/types/components/manage/Blocks/Block/Order/Item.d.ts +2 -0
  66. package/types/components/manage/Blocks/Block/Order/Order.d.ts +13 -0
  67. package/types/components/manage/Blocks/Block/Order/SortableItem.d.ts +9 -0
  68. package/types/components/manage/Blocks/Block/Order/utilities.d.ts +9 -0
  69. package/types/components/manage/Blocks/Image/schema.d.ts +2 -0
  70. package/types/components/theme/Icon/Icon.d.ts +8 -8
  71. package/types/config/Loadables.d.ts +15 -162
  72. package/types/constants/ActionTypes.d.ts +1 -0
  73. package/types/helpers/Blocks/Blocks.d.ts +13 -0
  74. package/types/helpers/index.d.ts +2 -2
@@ -52,6 +52,7 @@ import {
52
52
  resetMetadataFocus,
53
53
  setSidebarTab,
54
54
  setFormData,
55
+ setUIState,
55
56
  } from '@plone/volto/actions';
56
57
  import { compose } from 'redux';
57
58
  import config from '@plone/volto/registry';
@@ -230,13 +231,17 @@ class Form extends Component {
230
231
  this.props.setFormData(formData);
231
232
  }
232
233
 
234
+ this.props.setUIState({
235
+ selected: selectedBlock,
236
+ multiSelected: [],
237
+ hovered: null,
238
+ });
239
+
233
240
  // Set initial state
234
241
  this.state = {
235
242
  formData,
236
243
  initialFormData,
237
244
  errors: {},
238
- selected: selectedBlock,
239
- multiSelected: [],
240
245
  isClient: false,
241
246
  // Ensure focus remain in field after change
242
247
  inFocus: {},
@@ -263,6 +268,12 @@ class Form extends Component {
263
268
  let errors = {};
264
269
  let activeIndex = 0;
265
270
 
271
+ if (!this.props.isFormSelected && prevProps.isFormSelected) {
272
+ this.props.setUIState({
273
+ selected: null,
274
+ });
275
+ }
276
+
266
277
  if (requestError && prevProps.requestError !== requestError) {
267
278
  errors =
268
279
  FormValidation.giveServerErrorsToCorrespondingFields(requestError);
@@ -376,15 +387,6 @@ class Form extends Component {
376
387
  this.setState({ isClient: true });
377
388
  }
378
389
 
379
- static getDerivedStateFromProps(props, state) {
380
- let newState = { ...state };
381
- if (!props.isFormSelected) {
382
- newState.selected = null;
383
- }
384
-
385
- return newState;
386
- }
387
-
388
390
  /**
389
391
  * Change field handler
390
392
  * Remove errors for changed field
@@ -439,9 +441,9 @@ class Form extends Component {
439
441
 
440
442
  if (event.shiftKey) {
441
443
  const anchor =
442
- this.state.multiSelected.length > 0
443
- ? blocks_layout.indexOf(this.state.multiSelected[0])
444
- : blocks_layout.indexOf(this.state.selected);
444
+ this.props.uiState.multiSelected.length > 0
445
+ ? blocks_layout.indexOf(this.props.uiState.multiSelected[0])
446
+ : blocks_layout.indexOf(this.props.uiState.selected);
445
447
  const focus = blocks_layout.indexOf(id);
446
448
 
447
449
  if (anchor === focus) {
@@ -451,15 +453,16 @@ class Form extends Component {
451
453
  } else {
452
454
  multiSelected = [...blocks_layout.slice(focus, anchor + 1)];
453
455
  }
456
+ window.getSelection().empty();
454
457
  }
455
458
 
456
459
  if ((event.ctrlKey || event.metaKey) && !event.shiftKey) {
457
- multiSelected = this.state.multiSelected || [];
458
- if (!this.state.multiSelected.includes(this.state.selected)) {
459
- multiSelected = [...multiSelected, this.state.selected];
460
+ multiSelected = this.props.uiState.multiSelected || [];
461
+ if (!this.props.uiState.multiSelected.includes(this.state.selected)) {
462
+ multiSelected = [...multiSelected, this.props.uiState.selected];
460
463
  selected = null;
461
464
  }
462
- if (this.state.multiSelected.includes(id)) {
465
+ if (this.props.uiState.multiSelected.includes(id)) {
463
466
  selected = null;
464
467
  multiSelected = without(multiSelected, id);
465
468
  } else {
@@ -468,9 +471,10 @@ class Form extends Component {
468
471
  }
469
472
  }
470
473
 
471
- this.setState({
474
+ this.props.setUIState({
472
475
  selected,
473
476
  multiSelected,
477
+ gridSelected: null,
474
478
  });
475
479
 
476
480
  if (this.props.onSelectForm) {
@@ -660,141 +664,143 @@ class Form extends Component {
660
664
  />
661
665
 
662
666
  <Container>
663
- <BlocksToolbar
664
- formData={formData}
665
- selectedBlock={this.state.selected}
666
- selectedBlocks={this.state.multiSelected}
667
- onChangeBlocks={(newBlockData) => {
668
- const newFormData = {
669
- ...formData,
670
- ...newBlockData,
671
- };
672
- this.setState({
673
- formData: newFormData,
674
- });
675
- if (this.props.global) {
676
- this.props.setFormData(newFormData);
677
- }
678
- }}
679
- onSetSelectedBlocks={(blockIds) =>
680
- this.setState({ multiSelected: blockIds })
681
- }
682
- onSelectBlock={this.onSelectBlock}
683
- />
684
- <UndoToolbar
685
- state={{
686
- formData,
687
- selected: this.state.selected,
688
- multiSelected: this.state.multiSelected,
689
- }}
690
- enableHotKeys
691
- onUndoRedo={({ state }) => {
692
- if (this.props.global) {
693
- this.props.setFormData(state.formData);
667
+ <>
668
+ <BlocksToolbar
669
+ formData={formData}
670
+ selectedBlock={this.props.uiState.selected}
671
+ selectedBlocks={this.props.uiState.multiSelected}
672
+ onChangeBlocks={(newBlockData) => {
673
+ const newFormData = {
674
+ ...formData,
675
+ ...newBlockData,
676
+ };
677
+ this.setState({
678
+ formData: newFormData,
679
+ });
680
+ if (this.props.global) {
681
+ this.props.setFormData(newFormData);
682
+ }
683
+ }}
684
+ onSetSelectedBlocks={(blockIds) =>
685
+ this.props.setUIState({ multiSelected: blockIds })
694
686
  }
695
- return this.setState(state);
696
- }}
697
- />
698
- <BlocksForm
699
- onChangeFormData={(newData) => {
700
- const newFormData = {
701
- ...formData,
702
- ...newData,
703
- };
704
- this.setState({
705
- formData: newFormData,
706
- });
707
- if (this.props.global) {
708
- this.props.setFormData(newFormData);
709
- }
710
- }}
711
- onChangeField={this.onChangeField}
712
- onSelectBlock={this.onSelectBlock}
713
- properties={formData}
714
- navRoot={navRoot}
715
- type={type}
716
- pathname={this.props.pathname}
717
- selectedBlock={this.state.selected}
718
- multiSelected={this.state.multiSelected}
719
- manage={this.props.isAdminForm}
720
- allowedBlocks={this.props.allowedBlocks}
721
- showRestricted={this.props.showRestricted}
722
- editable={this.props.editable}
723
- isMainForm={this.props.editable}
724
- // Properties to pass to the BlocksForm to match the View ones
725
- history={this.props.history}
726
- location={this.props.location}
727
- token={this.props.token}
728
- />
729
- {this.state.isClient &&
730
- this.state.sidebarMetadataIsAvailable &&
731
- this.props.editable &&
732
- createPortal(
733
- <UiForm
734
- method="post"
735
- onSubmit={this.onSubmit}
736
- error={keys(this.state.errors).length > 0}
737
- >
738
- {schema &&
739
- map(schema.fieldsets, (fieldset) => (
740
- <Accordion
741
- fluid
742
- styled
743
- className="form"
744
- key={fieldset.title}
745
- >
746
- <div
747
- key={fieldset.id}
748
- id={`metadataform-fieldset-${fieldset.id}`}
687
+ onSelectBlock={this.onSelectBlock}
688
+ />
689
+ <UndoToolbar
690
+ state={{
691
+ formData,
692
+ selected: this.props.uiState.selected,
693
+ multiSelected: this.props.uiState.multiSelected,
694
+ }}
695
+ enableHotKeys
696
+ onUndoRedo={({ state }) => {
697
+ if (this.props.global) {
698
+ this.props.setFormData(state.formData);
699
+ }
700
+ return this.setState(state);
701
+ }}
702
+ />
703
+ <BlocksForm
704
+ onChangeFormData={(newData) => {
705
+ const newFormData = {
706
+ ...formData,
707
+ ...newData,
708
+ };
709
+ this.setState({
710
+ formData: newFormData,
711
+ });
712
+ if (this.props.global) {
713
+ this.props.setFormData(newFormData);
714
+ }
715
+ }}
716
+ onChangeField={this.onChangeField}
717
+ onSelectBlock={this.onSelectBlock}
718
+ properties={formData}
719
+ navRoot={navRoot}
720
+ type={type}
721
+ pathname={this.props.pathname}
722
+ selectedBlock={this.props.uiState.selected}
723
+ multiSelected={this.props.uiState.multiSelected}
724
+ manage={this.props.isAdminForm}
725
+ allowedBlocks={this.props.allowedBlocks}
726
+ showRestricted={this.props.showRestricted}
727
+ editable={this.props.editable}
728
+ isMainForm={this.props.editable}
729
+ // Properties to pass to the BlocksForm to match the View ones
730
+ history={this.props.history}
731
+ location={this.props.location}
732
+ token={this.props.token}
733
+ />
734
+ {this.state.isClient &&
735
+ this.state.sidebarMetadataIsAvailable &&
736
+ this.props.editable &&
737
+ createPortal(
738
+ <UiForm
739
+ method="post"
740
+ onSubmit={this.onSubmit}
741
+ error={keys(this.state.errors).length > 0}
742
+ >
743
+ {schema &&
744
+ map(schema.fieldsets, (fieldset) => (
745
+ <Accordion
746
+ fluid
747
+ styled
748
+ className="form"
749
+ key={fieldset.title}
749
750
  >
750
- <Accordion.Title
751
- active={metadataFieldsets.includes(fieldset.id)}
752
- index={fieldset.id}
753
- onClick={this.onToggleMetadataFieldset}
754
- >
755
- {fieldset.title}
756
- {metadataFieldsets.includes(fieldset.id) ? (
757
- <Icon name={upSVG} size="20px" />
758
- ) : (
759
- <Icon name={downSVG} size="20px" />
760
- )}
761
- </Accordion.Title>
762
- <Accordion.Content
763
- active={metadataFieldsets.includes(fieldset.id)}
751
+ <div
752
+ key={fieldset.id}
753
+ id={`metadataform-fieldset-${fieldset.id}`}
764
754
  >
765
- <Segment className="attached">
766
- {map(fieldset.fields, (field, index) => (
767
- <Field
768
- {...schema.properties[field]}
769
- id={field}
770
- fieldSet={fieldset.title.toLowerCase()}
771
- formData={formData}
772
- focus={this.state.inFocus[field]}
773
- value={formData?.[field]}
774
- required={
775
- schema.required.indexOf(field) !== -1
776
- }
777
- onChange={this.onChangeField}
778
- onBlur={this.onBlurField}
779
- onClick={this.onClickInput}
780
- key={field}
781
- error={this.state.errors[field]}
782
- />
783
- ))}
784
- </Segment>
785
- </Accordion.Content>
786
- </div>
787
- </Accordion>
788
- ))}
789
- </UiForm>,
790
- document.getElementById('sidebar-metadata'),
791
- )}
792
-
793
- <SlotRenderer
794
- name="belowContent"
795
- content={this.props.content}
796
- navRoot={navRoot}
797
- />
755
+ <Accordion.Title
756
+ active={metadataFieldsets.includes(fieldset.id)}
757
+ index={fieldset.id}
758
+ onClick={this.onToggleMetadataFieldset}
759
+ >
760
+ {fieldset.title}
761
+ {metadataFieldsets.includes(fieldset.id) ? (
762
+ <Icon name={upSVG} size="20px" />
763
+ ) : (
764
+ <Icon name={downSVG} size="20px" />
765
+ )}
766
+ </Accordion.Title>
767
+ <Accordion.Content
768
+ active={metadataFieldsets.includes(fieldset.id)}
769
+ >
770
+ <Segment className="attached">
771
+ {map(fieldset.fields, (field, index) => (
772
+ <Field
773
+ {...schema.properties[field]}
774
+ id={field}
775
+ fieldSet={fieldset.title.toLowerCase()}
776
+ formData={formData}
777
+ focus={this.state.inFocus[field]}
778
+ value={formData?.[field]}
779
+ required={
780
+ schema.required.indexOf(field) !== -1
781
+ }
782
+ onChange={this.onChangeField}
783
+ onBlur={this.onBlurField}
784
+ onClick={this.onClickInput}
785
+ key={field}
786
+ error={this.state.errors[field]}
787
+ />
788
+ ))}
789
+ </Segment>
790
+ </Accordion.Content>
791
+ </div>
792
+ </Accordion>
793
+ ))}
794
+ </UiForm>,
795
+ document.getElementById('sidebar-metadata'),
796
+ )}
797
+
798
+ <SlotRenderer
799
+ name="belowContent"
800
+ content={this.props.content}
801
+ navRoot={navRoot}
802
+ />
803
+ </>
798
804
  </Container>
799
805
  </>
800
806
  )
@@ -964,6 +970,7 @@ export default compose(
964
970
  (state, props) => ({
965
971
  content: state.content.data,
966
972
  globalData: state.form?.global,
973
+ uiState: state.form?.ui,
967
974
  metadataFieldsets: state.sidebar?.metadataFieldsets,
968
975
  metadataFieldFocus: state.sidebar?.metadataFieldFocus,
969
976
  }),
@@ -971,6 +978,7 @@ export default compose(
971
978
  setMetadataFieldsets,
972
979
  setSidebarTab,
973
980
  setFormData,
981
+ setUIState,
974
982
  resetMetadataFocus,
975
983
  },
976
984
  null,
@@ -34,12 +34,23 @@ const messages = defineMessages({
34
34
  id: 'Expand sidebar',
35
35
  defaultMessage: 'Expand sidebar',
36
36
  },
37
+ order: {
38
+ id: 'Order',
39
+ defaultMessage: 'Order',
40
+ },
37
41
  });
38
42
 
39
43
  const Sidebar = (props) => {
40
44
  const dispatch = useDispatch();
41
45
  const intl = useIntl();
42
- const { cookies, content, documentTab, blockTab, settingsTab } = props;
46
+ const {
47
+ cookies,
48
+ content,
49
+ documentTab,
50
+ blockTab,
51
+ settingsTab,
52
+ orderTab = true,
53
+ } = props;
43
54
  const [expanded, setExpanded] = useState(
44
55
  cookies.get('sidebar_expanded') !== 'false',
45
56
  );
@@ -172,6 +183,22 @@ const Sidebar = (props) => {
172
183
  </Tab.Pane>
173
184
  ),
174
185
  },
186
+ !!orderTab && {
187
+ menuItem: intl.formatMessage(messages.order),
188
+ pane: (
189
+ <Tab.Pane
190
+ key="order"
191
+ className="tab-wrapper"
192
+ id="sidebar-order"
193
+ >
194
+ <Icon
195
+ className="tab-forbidden"
196
+ name={forbiddenSVG}
197
+ size="48px"
198
+ />
199
+ </Tab.Pane>
200
+ ),
201
+ },
175
202
  !!settingsTab && {
176
203
  menuItem: intl.formatMessage(messages.settings),
177
204
  pane: (
@@ -15,13 +15,13 @@ import navTreeSVG from '@plone/volto/icons/nav.svg';
15
15
 
16
16
  /** Widget to edit urls
17
17
  *
18
- * This is the default widget used for the `remoteUrl` field. You can also use
18
+ * This is a widget used for getting and setting an internal url. You can also use
19
19
  * it by declaring a field like:
20
20
  *
21
21
  * ```jsx
22
22
  * {
23
23
  * title: "URL",
24
- * widget: 'url',
24
+ * widget: 'internal_url',
25
25
  * }
26
26
  * ```
27
27
  */
@@ -35,20 +35,20 @@ export const InternalUrlWidget = (props) => {
35
35
  maxLength,
36
36
  placeholder,
37
37
  isDisabled,
38
+ value,
38
39
  } = props;
39
40
  const inputId = `field-${id}`;
40
41
 
41
- const [value, setValue] = useState(flattenToAppURL(props.value));
42
42
  const [isInvalid, setIsInvalid] = useState(false);
43
+
43
44
  /**
44
45
  * Clear handler
45
46
  * @method clear
46
47
  * @param {Object} value Value
47
- * @returns {undefined}
48
+ * @returns {string} Empty string
48
49
  */
49
50
  const clear = () => {
50
- setValue('');
51
- onChange(id, undefined);
51
+ onChange(id, '');
52
52
  };
53
53
 
54
54
  const onChangeValue = (_value) => {
@@ -63,8 +63,6 @@ export const InternalUrlWidget = (props) => {
63
63
  }
64
64
  }
65
65
 
66
- setValue(newValue);
67
-
68
66
  newValue = isInternalURL(newValue) ? flattenToAppURL(newValue) : newValue;
69
67
 
70
68
  if (!isInternalURL(newValue) && newValue.length > 0) {
@@ -75,7 +73,7 @@ export const InternalUrlWidget = (props) => {
75
73
  }
76
74
  }
77
75
 
78
- onChange(id, newValue === '' ? undefined : newValue);
76
+ onChange(id, newValue);
79
77
  };
80
78
 
81
79
  return (
@@ -89,12 +87,10 @@ export const InternalUrlWidget = (props) => {
89
87
  disabled={isDisabled}
90
88
  placeholder={placeholder}
91
89
  onChange={({ target }) => onChangeValue(target.value)}
92
- onBlur={({ target }) =>
93
- onBlur(id, target.value === '' ? undefined : target.value)
94
- }
90
+ onBlur={({ target }) => onBlur(id, target.value)}
95
91
  onClick={() => onClick()}
96
- minLength={minLength || null}
97
- maxLength={maxLength || null}
92
+ minLength={minLength}
93
+ maxLength={maxLength}
98
94
  error={isInvalid}
99
95
  />
100
96
  {value?.length > 0 ? (
@@ -18,13 +18,25 @@ const FormattedDate = ({
18
18
  const language = useSelector((state) => locale || state.intl.locale);
19
19
  const toDate = (d) => (typeof d === 'string' ? new Date(d) : d);
20
20
  const args = { date, long, includeTime, format, locale: language };
21
+ const new_date = new Date(toDate(date));
22
+ // Dat check taken from https://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript#1353711
23
+ if (Object.prototype.toString.call(new_date) === '[object Date]') {
24
+ // it is a date
25
+ if (isNaN(new_date)) {
26
+ // date object is not valid
27
+ return <span>bad date</span>;
28
+ }
29
+ } else {
30
+ // not a date object
31
+ return <span>not a date</span>;
32
+ }
21
33
 
22
34
  return (
23
35
  <time
24
36
  className={className}
25
37
  dateTime={date}
26
38
  title={new Intl.DateTimeFormat(language, long_date_format)
27
- .format(new Date(toDate(date)))
39
+ .format(new_date)
28
40
  .replace('\u202F', ' ')}
29
41
  >
30
42
  {children
@@ -12,10 +12,10 @@ const defaultSize = '36px';
12
12
  * @function Field
13
13
  * @param {Object} props Component properties.
14
14
  * @param {string} props.name Name source object.
15
- * @param {string} props.size Size of the Icon (in px).
16
- * @param {string} props.color Color of the Icon.
17
- * @param {string} props.className className to add to the component.
18
- * @param {string} props.title Title (a11y).
15
+ * @param {string} [props.size] Size of the Icon (in px).
16
+ * @param {string} [props.color] Color of the Icon.
17
+ * @param {string} [props.className] className to add to the component.
18
+ * @param {string} [props.title] Title (a11y).
19
19
  * @returns {string} Markup of the component.
20
20
  *
21
21
  * Use:
@@ -1,5 +1,20 @@
1
1
  import loadable from '@loadable/component';
2
2
 
3
+ // This is to make happy the types declaration extractor (tsc) that is not able to
4
+ // extract one private method the types from `@dnd-kit` library:
5
+ // error TS9006: Declaration emit for this file requires using private name
6
+ // 'DefaultDropAnimationSideEffectsOptions' from module '".../node_modules/@dnd-kit/core/dist/components/DragOverlay/hooks/useDropAnimation"'.
7
+ // An explicit type annotation may unblock declaration emit
8
+
9
+ /**
10
+ * @typedef {Object} LoadableLib
11
+ * @property {() => Promise<any>} import
12
+ * @property {Object} [options]
13
+ */
14
+
15
+ /**
16
+ * @type {{ [key: string]: LoadableLib }}
17
+ */
3
18
  export const loadables = {
4
19
  prettierStandalone: loadable.lib(() => import('prettier/standalone')),
5
20
  prettierParserHtml: loadable.lib(() => import('prettier/plugins/html')),
@@ -35,4 +50,7 @@ export const loadables = {
35
50
  reactDndHtml5Backend: loadable.lib(() => import('react-dnd-html5-backend')),
36
51
  reactBeautifulDnd: loadable.lib(() => import('react-beautiful-dnd')),
37
52
  rrule: loadable.lib(() => import('rrule')),
53
+ dndKitCore: loadable.lib(() => import('@dnd-kit/core')),
54
+ dndKitSortable: loadable.lib(() => import('@dnd-kit/sortable')),
55
+ dndKitUtilities: loadable.lib(() => import('@dnd-kit/utilities')),
38
56
  };
@@ -145,4 +145,5 @@ export const RESET_LOGIN_REQUEST = 'RESET_LOGIN_REQUEST';
145
145
  export const GET_SITE = 'GET_SITE';
146
146
  export const GET_NAVROOT = 'GET_NAVROOT';
147
147
  export const SET_FORM_DATA = 'SET_FORM_DATA';
148
+ export const SET_UI_STATE = 'SET_UI_STATE';
148
149
  export const UPDATE_UPLOADED_FILES = 'UPDATE_UPLOADED_FILES';