@pranaysahith/decap-cms-core 3.9.1

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 (299) hide show
  1. package/README.md +9 -0
  2. package/dist/@pranaysahith/decap-cms-core.js +52 -0
  3. package/dist/@pranaysahith/decap-cms-core.js.LICENSE.txt +141 -0
  4. package/dist/@pranaysahith/decap-cms-core.js.map +1 -0
  5. package/dist/decap-cms-core.js +47 -0
  6. package/dist/decap-cms-core.js.LICENSE.txt +116 -0
  7. package/dist/decap-cms-core.js.map +1 -0
  8. package/dist/esm/actions/auth.js +97 -0
  9. package/dist/esm/actions/collections.js +15 -0
  10. package/dist/esm/actions/config.js +493 -0
  11. package/dist/esm/actions/deploys.js +79 -0
  12. package/dist/esm/actions/editorialWorkflow.js +480 -0
  13. package/dist/esm/actions/entries.js +865 -0
  14. package/dist/esm/actions/media.js +147 -0
  15. package/dist/esm/actions/mediaLibrary.js +552 -0
  16. package/dist/esm/actions/notifications.js +21 -0
  17. package/dist/esm/actions/search.js +149 -0
  18. package/dist/esm/actions/status.js +74 -0
  19. package/dist/esm/actions/waitUntil.js +32 -0
  20. package/dist/esm/backend.js +1082 -0
  21. package/dist/esm/bootstrap.js +101 -0
  22. package/dist/esm/components/App/App.js +289 -0
  23. package/dist/esm/components/App/Header.js +172 -0
  24. package/dist/esm/components/App/NotFoundPage.js +19 -0
  25. package/dist/esm/components/Collection/Collection.js +198 -0
  26. package/dist/esm/components/Collection/CollectionControls.js +46 -0
  27. package/dist/esm/components/Collection/CollectionSearch.js +222 -0
  28. package/dist/esm/components/Collection/CollectionTop.js +68 -0
  29. package/dist/esm/components/Collection/ControlButton.js +17 -0
  30. package/dist/esm/components/Collection/Entries/Entries.js +73 -0
  31. package/dist/esm/components/Collection/Entries/EntriesCollection.js +241 -0
  32. package/dist/esm/components/Collection/Entries/EntriesSearch.js +113 -0
  33. package/dist/esm/components/Collection/Entries/EntryCard.js +177 -0
  34. package/dist/esm/components/Collection/Entries/EntryListing.js +143 -0
  35. package/dist/esm/components/Collection/FilterControl.js +33 -0
  36. package/dist/esm/components/Collection/FolderRenameControl.js +403 -0
  37. package/dist/esm/components/Collection/GroupControl.js +33 -0
  38. package/dist/esm/components/Collection/NestedCollection.js +308 -0
  39. package/dist/esm/components/Collection/Sidebar.js +91 -0
  40. package/dist/esm/components/Collection/SortControl.js +59 -0
  41. package/dist/esm/components/Collection/ViewStyleControl.js +38 -0
  42. package/dist/esm/components/Editor/Editor.js +466 -0
  43. package/dist/esm/components/Editor/EditorControlPane/EditorControl.js +395 -0
  44. package/dist/esm/components/Editor/EditorControlPane/EditorControlPane.js +254 -0
  45. package/dist/esm/components/Editor/EditorControlPane/Widget.js +374 -0
  46. package/dist/esm/components/Editor/EditorInterface.js +386 -0
  47. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreview.js +47 -0
  48. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewContent.js +66 -0
  49. package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewPane.js +288 -0
  50. package/dist/esm/components/Editor/EditorPreviewPane/PreviewHOC.js +27 -0
  51. package/dist/esm/components/Editor/EditorToolbar.js +536 -0
  52. package/dist/esm/components/Editor/EntryPathEditor.js +272 -0
  53. package/dist/esm/components/Editor/withWorkflow.js +56 -0
  54. package/dist/esm/components/EditorWidgets/Unknown/UnknownControl.js +18 -0
  55. package/dist/esm/components/EditorWidgets/Unknown/UnknownPreview.js +20 -0
  56. package/dist/esm/components/EditorWidgets/index.js +4 -0
  57. package/dist/esm/components/MediaLibrary/EmptyMessage.js +22 -0
  58. package/dist/esm/components/MediaLibrary/MediaLibrary.js +446 -0
  59. package/dist/esm/components/MediaLibrary/MediaLibraryButtons.js +93 -0
  60. package/dist/esm/components/MediaLibrary/MediaLibraryCard.js +99 -0
  61. package/dist/esm/components/MediaLibrary/MediaLibraryCardGrid.js +198 -0
  62. package/dist/esm/components/MediaLibrary/MediaLibraryHeader.js +32 -0
  63. package/dist/esm/components/MediaLibrary/MediaLibraryModal.js +156 -0
  64. package/dist/esm/components/MediaLibrary/MediaLibrarySearch.js +51 -0
  65. package/dist/esm/components/MediaLibrary/MediaLibraryTop.js +123 -0
  66. package/dist/esm/components/UI/DragDrop.js +67 -0
  67. package/dist/esm/components/UI/ErrorBoundary.js +173 -0
  68. package/dist/esm/components/UI/FileUploadButton.js +27 -0
  69. package/dist/esm/components/UI/Modal.js +104 -0
  70. package/dist/esm/components/UI/Notifications.js +62 -0
  71. package/dist/esm/components/UI/SettingsDropdown.js +107 -0
  72. package/dist/esm/components/UI/index.js +6 -0
  73. package/dist/esm/components/Workflow/Workflow.js +133 -0
  74. package/dist/esm/components/Workflow/WorkflowCard.js +128 -0
  75. package/dist/esm/components/Workflow/WorkflowList.js +204 -0
  76. package/dist/esm/constants/collectionTypes.js +2 -0
  77. package/dist/esm/constants/collectionViews.js +2 -0
  78. package/dist/esm/constants/commitProps.js +2 -0
  79. package/dist/esm/constants/configSchema.js +644 -0
  80. package/dist/esm/constants/fieldInference.js +57 -0
  81. package/dist/esm/constants/publishModes.js +18 -0
  82. package/dist/esm/constants/validationErrorTypes.js +6 -0
  83. package/dist/esm/formats/formats.js +83 -0
  84. package/dist/esm/formats/frontmatter.js +146 -0
  85. package/dist/esm/formats/helpers.js +12 -0
  86. package/dist/esm/formats/json.js +8 -0
  87. package/dist/esm/formats/toml.js +32 -0
  88. package/dist/esm/formats/yaml.js +51 -0
  89. package/dist/esm/index.js +7 -0
  90. package/dist/esm/integrations/index.js +28 -0
  91. package/dist/esm/integrations/providers/algolia/implementation.js +174 -0
  92. package/dist/esm/integrations/providers/assetStore/implementation.js +165 -0
  93. package/dist/esm/lib/consoleError.js +3 -0
  94. package/dist/esm/lib/formatters.js +191 -0
  95. package/dist/esm/lib/i18n.js +367 -0
  96. package/dist/esm/lib/phrases.js +6 -0
  97. package/dist/esm/lib/polyfill.js +8 -0
  98. package/dist/esm/lib/registry.js +329 -0
  99. package/dist/esm/lib/serializeEntryValues.js +67 -0
  100. package/dist/esm/lib/stega.js +142 -0
  101. package/dist/esm/lib/textHelper.js +9 -0
  102. package/dist/esm/lib/urlHelper.js +111 -0
  103. package/dist/esm/mediaLibrary.js +37 -0
  104. package/dist/esm/reducers/auth.js +27 -0
  105. package/dist/esm/reducers/collections.js +428 -0
  106. package/dist/esm/reducers/combinedReducer.js +8 -0
  107. package/dist/esm/reducers/config.js +29 -0
  108. package/dist/esm/reducers/cursors.js +31 -0
  109. package/dist/esm/reducers/deploys.js +45 -0
  110. package/dist/esm/reducers/editorialWorkflow.js +83 -0
  111. package/dist/esm/reducers/entries.js +568 -0
  112. package/dist/esm/reducers/entryDraft.js +212 -0
  113. package/dist/esm/reducers/globalUI.js +25 -0
  114. package/dist/esm/reducers/index.js +66 -0
  115. package/dist/esm/reducers/integrations.js +53 -0
  116. package/dist/esm/reducers/mediaLibrary.js +252 -0
  117. package/dist/esm/reducers/medias.js +68 -0
  118. package/dist/esm/reducers/notifications.js +23 -0
  119. package/dist/esm/reducers/search.js +92 -0
  120. package/dist/esm/reducers/status.js +30 -0
  121. package/dist/esm/redux/index.js +7 -0
  122. package/dist/esm/redux/middleware/waitUntilAction.js +48 -0
  123. package/dist/esm/routing/history.js +12 -0
  124. package/dist/esm/types/diacritics.d.js +0 -0
  125. package/dist/esm/types/global.d.js +1 -0
  126. package/dist/esm/types/immutable.js +7 -0
  127. package/dist/esm/types/redux.js +14 -0
  128. package/dist/esm/types/tomlify-j0.4.d.js +0 -0
  129. package/dist/esm/valueObjects/AssetProxy.js +44 -0
  130. package/dist/esm/valueObjects/EditorComponent.js +34 -0
  131. package/dist/esm/valueObjects/Entry.js +20 -0
  132. package/index.d.ts +618 -0
  133. package/package.json +106 -0
  134. package/src/__tests__/backend.spec.js +1161 -0
  135. package/src/actions/__tests__/config.spec.js +1009 -0
  136. package/src/actions/__tests__/editorialWorkflow.spec.js +216 -0
  137. package/src/actions/__tests__/entries.spec.js +596 -0
  138. package/src/actions/__tests__/media.spec.ts +171 -0
  139. package/src/actions/__tests__/mediaLibrary.spec.js +327 -0
  140. package/src/actions/__tests__/search.spec.js +209 -0
  141. package/src/actions/auth.ts +127 -0
  142. package/src/actions/collections.ts +18 -0
  143. package/src/actions/config.ts +565 -0
  144. package/src/actions/deploys.ts +104 -0
  145. package/src/actions/editorialWorkflow.ts +567 -0
  146. package/src/actions/entries.ts +1055 -0
  147. package/src/actions/media.ts +139 -0
  148. package/src/actions/mediaLibrary.ts +574 -0
  149. package/src/actions/notifications.ts +36 -0
  150. package/src/actions/search.ts +221 -0
  151. package/src/actions/status.ts +99 -0
  152. package/src/actions/waitUntil.ts +49 -0
  153. package/src/backend.ts +1400 -0
  154. package/src/bootstrap.js +104 -0
  155. package/src/components/App/App.js +286 -0
  156. package/src/components/App/Header.js +266 -0
  157. package/src/components/App/NotFoundPage.js +23 -0
  158. package/src/components/Collection/Collection.js +210 -0
  159. package/src/components/Collection/CollectionControls.js +58 -0
  160. package/src/components/Collection/CollectionSearch.js +243 -0
  161. package/src/components/Collection/CollectionTop.js +81 -0
  162. package/src/components/Collection/ControlButton.js +27 -0
  163. package/src/components/Collection/Entries/Entries.js +82 -0
  164. package/src/components/Collection/Entries/EntriesCollection.js +277 -0
  165. package/src/components/Collection/Entries/EntriesSearch.js +102 -0
  166. package/src/components/Collection/Entries/EntryCard.js +246 -0
  167. package/src/components/Collection/Entries/EntryListing.js +151 -0
  168. package/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js +163 -0
  169. package/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap +46 -0
  170. package/src/components/Collection/FilterControl.js +39 -0
  171. package/src/components/Collection/GroupControl.js +39 -0
  172. package/src/components/Collection/NestedCollection.js +330 -0
  173. package/src/components/Collection/Sidebar.js +136 -0
  174. package/src/components/Collection/SortControl.js +68 -0
  175. package/src/components/Collection/ViewStyleControl.js +50 -0
  176. package/src/components/Collection/__tests__/Collection.spec.js +75 -0
  177. package/src/components/Collection/__tests__/NestedCollection.spec.js +445 -0
  178. package/src/components/Collection/__tests__/Sidebar.spec.js +87 -0
  179. package/src/components/Collection/__tests__/__snapshots__/Collection.spec.js.snap +144 -0
  180. package/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap +550 -0
  181. package/src/components/Collection/__tests__/__snapshots__/Sidebar.spec.js.snap +312 -0
  182. package/src/components/Editor/Editor.js +497 -0
  183. package/src/components/Editor/EditorControlPane/EditorControl.js +452 -0
  184. package/src/components/Editor/EditorControlPane/EditorControlPane.js +269 -0
  185. package/src/components/Editor/EditorControlPane/Widget.js +384 -0
  186. package/src/components/Editor/EditorInterface.js +444 -0
  187. package/src/components/Editor/EditorPreviewPane/EditorPreview.js +40 -0
  188. package/src/components/Editor/EditorPreviewPane/EditorPreviewContent.js +74 -0
  189. package/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +333 -0
  190. package/src/components/Editor/EditorPreviewPane/PreviewHOC.js +33 -0
  191. package/src/components/Editor/EditorToolbar.js +691 -0
  192. package/src/components/Editor/__tests__/Editor.spec.js +221 -0
  193. package/src/components/Editor/__tests__/EditorToolbar.spec.js +120 -0
  194. package/src/components/Editor/__tests__/__snapshots__/Editor.spec.js.snap +45 -0
  195. package/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +4233 -0
  196. package/src/components/Editor/withWorkflow.js +61 -0
  197. package/src/components/EditorWidgets/Unknown/UnknownControl.js +17 -0
  198. package/src/components/EditorWidgets/Unknown/UnknownPreview.js +19 -0
  199. package/src/components/EditorWidgets/index.js +5 -0
  200. package/src/components/MediaLibrary/EmptyMessage.js +28 -0
  201. package/src/components/MediaLibrary/MediaLibrary.js +411 -0
  202. package/src/components/MediaLibrary/MediaLibraryButtons.js +136 -0
  203. package/src/components/MediaLibrary/MediaLibraryCard.js +128 -0
  204. package/src/components/MediaLibrary/MediaLibraryCardGrid.js +199 -0
  205. package/src/components/MediaLibrary/MediaLibraryHeader.js +48 -0
  206. package/src/components/MediaLibrary/MediaLibraryModal.js +200 -0
  207. package/src/components/MediaLibrary/MediaLibrarySearch.js +61 -0
  208. package/src/components/MediaLibrary/MediaLibraryTop.js +143 -0
  209. package/src/components/MediaLibrary/__tests__/MediaLibraryButtons.spec.js +45 -0
  210. package/src/components/MediaLibrary/__tests__/MediaLibraryCard.spec.js +49 -0
  211. package/src/components/MediaLibrary/__tests__/__snapshots__/MediaLibraryCard.spec.js.snap +264 -0
  212. package/src/components/UI/DragDrop.js +66 -0
  213. package/src/components/UI/ErrorBoundary.js +214 -0
  214. package/src/components/UI/FileUploadButton.js +24 -0
  215. package/src/components/UI/Modal.js +112 -0
  216. package/src/components/UI/Notifications.tsx +83 -0
  217. package/src/components/UI/SettingsDropdown.js +103 -0
  218. package/src/components/UI/__tests__/ErrorBoundary.spec.js +57 -0
  219. package/src/components/UI/index.js +6 -0
  220. package/src/components/Workflow/Workflow.js +169 -0
  221. package/src/components/Workflow/WorkflowCard.js +177 -0
  222. package/src/components/Workflow/WorkflowList.js +272 -0
  223. package/src/constants/__tests__/configSchema.spec.js +611 -0
  224. package/src/constants/collectionTypes.ts +2 -0
  225. package/src/constants/collectionViews.js +2 -0
  226. package/src/constants/commitProps.ts +2 -0
  227. package/src/constants/configSchema.js +441 -0
  228. package/src/constants/fieldInference.tsx +78 -0
  229. package/src/constants/publishModes.ts +22 -0
  230. package/src/constants/validationErrorTypes.js +6 -0
  231. package/src/formats/__tests__/formats.spec.js +87 -0
  232. package/src/formats/__tests__/frontmatter.spec.js +429 -0
  233. package/src/formats/__tests__/toml.spec.js +9 -0
  234. package/src/formats/__tests__/yaml.spec.js +162 -0
  235. package/src/formats/formats.ts +97 -0
  236. package/src/formats/frontmatter.ts +150 -0
  237. package/src/formats/helpers.ts +14 -0
  238. package/src/formats/json.ts +9 -0
  239. package/src/formats/toml.ts +33 -0
  240. package/src/formats/yaml.ts +58 -0
  241. package/src/index.js +8 -0
  242. package/src/integrations/index.js +35 -0
  243. package/src/integrations/providers/algolia/implementation.js +176 -0
  244. package/src/integrations/providers/assetStore/implementation.js +148 -0
  245. package/src/lib/__tests__/formatters.spec.js +751 -0
  246. package/src/lib/__tests__/i18n.spec.js +792 -0
  247. package/src/lib/__tests__/phrases.spec.js +119 -0
  248. package/src/lib/__tests__/registry.spec.js +261 -0
  249. package/src/lib/__tests__/serializeEntryValues.spec.js +22 -0
  250. package/src/lib/__tests__/urlHelper.spec.js +138 -0
  251. package/src/lib/consoleError.js +7 -0
  252. package/src/lib/formatters.ts +286 -0
  253. package/src/lib/i18n.ts +454 -0
  254. package/src/lib/phrases.js +8 -0
  255. package/src/lib/polyfill.js +9 -0
  256. package/src/lib/registry.js +312 -0
  257. package/src/lib/serializeEntryValues.js +75 -0
  258. package/src/lib/stega.ts +145 -0
  259. package/src/lib/textHelper.js +11 -0
  260. package/src/lib/urlHelper.ts +128 -0
  261. package/src/mediaLibrary.ts +51 -0
  262. package/src/reducers/__tests__/auth.spec.ts +38 -0
  263. package/src/reducers/__tests__/collections.spec.js +610 -0
  264. package/src/reducers/__tests__/config.spec.js +38 -0
  265. package/src/reducers/__tests__/entries.spec.js +694 -0
  266. package/src/reducers/__tests__/entryDraft.spec.js +297 -0
  267. package/src/reducers/__tests__/globalUI.js +43 -0
  268. package/src/reducers/__tests__/integrations.spec.ts +76 -0
  269. package/src/reducers/__tests__/mediaLibrary.spec.js +154 -0
  270. package/src/reducers/__tests__/medias.spec.ts +49 -0
  271. package/src/reducers/auth.ts +46 -0
  272. package/src/reducers/collections.ts +535 -0
  273. package/src/reducers/combinedReducer.ts +11 -0
  274. package/src/reducers/config.ts +38 -0
  275. package/src/reducers/cursors.js +36 -0
  276. package/src/reducers/deploys.ts +52 -0
  277. package/src/reducers/editorialWorkflow.ts +163 -0
  278. package/src/reducers/entries.ts +819 -0
  279. package/src/reducers/entryDraft.js +260 -0
  280. package/src/reducers/globalUI.ts +45 -0
  281. package/src/reducers/index.ts +82 -0
  282. package/src/reducers/integrations.ts +59 -0
  283. package/src/reducers/mediaLibrary.ts +296 -0
  284. package/src/reducers/medias.ts +66 -0
  285. package/src/reducers/notifications.ts +52 -0
  286. package/src/reducers/search.ts +111 -0
  287. package/src/reducers/status.ts +40 -0
  288. package/src/redux/index.ts +18 -0
  289. package/src/redux/middleware/waitUntilAction.ts +64 -0
  290. package/src/routing/__tests__/history.spec.ts +49 -0
  291. package/src/routing/history.ts +17 -0
  292. package/src/types/diacritics.d.ts +1 -0
  293. package/src/types/global.d.ts +8 -0
  294. package/src/types/immutable.ts +49 -0
  295. package/src/types/redux.ts +827 -0
  296. package/src/types/tomlify-j0.4.d.ts +13 -0
  297. package/src/valueObjects/AssetProxy.ts +48 -0
  298. package/src/valueObjects/EditorComponent.js +38 -0
  299. package/src/valueObjects/Entry.ts +63 -0
@@ -0,0 +1,260 @@
1
+ import { Map, List, fromJS } from 'immutable';
2
+ import { v4 as uuid } from 'uuid';
3
+ import get from 'lodash/get';
4
+ import { join } from 'path';
5
+
6
+ import {
7
+ DRAFT_CREATE_FROM_ENTRY,
8
+ DRAFT_CREATE_EMPTY,
9
+ DRAFT_DISCARD,
10
+ DRAFT_CHANGE_FIELD,
11
+ DRAFT_VALIDATION_ERRORS,
12
+ DRAFT_CLEAR_ERRORS,
13
+ DRAFT_LOCAL_BACKUP_RETRIEVED,
14
+ DRAFT_CREATE_FROM_LOCAL_BACKUP,
15
+ DRAFT_CREATE_DUPLICATE_FROM_ENTRY,
16
+ ENTRY_PERSIST_REQUEST,
17
+ ENTRY_PERSIST_SUCCESS,
18
+ ENTRY_PERSIST_FAILURE,
19
+ ENTRY_DELETE_SUCCESS,
20
+ ADD_DRAFT_ENTRY_MEDIA_FILE,
21
+ REMOVE_DRAFT_ENTRY_MEDIA_FILE,
22
+ } from '../actions/entries';
23
+ import {
24
+ UNPUBLISHED_ENTRY_PERSIST_REQUEST,
25
+ UNPUBLISHED_ENTRY_PERSIST_SUCCESS,
26
+ UNPUBLISHED_ENTRY_PERSIST_FAILURE,
27
+ UNPUBLISHED_ENTRY_STATUS_CHANGE_REQUEST,
28
+ UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS,
29
+ UNPUBLISHED_ENTRY_STATUS_CHANGE_FAILURE,
30
+ UNPUBLISHED_ENTRY_PUBLISH_REQUEST,
31
+ UNPUBLISHED_ENTRY_PUBLISH_SUCCESS,
32
+ UNPUBLISHED_ENTRY_PUBLISH_FAILURE,
33
+ } from '../actions/editorialWorkflow';
34
+ import { selectFolderEntryExtension, selectHasMetaPath } from './collections';
35
+ import { getDataPath, duplicateI18nFields } from '../lib/i18n';
36
+
37
+ const initialState = Map({
38
+ entry: Map(),
39
+ fieldsMetaData: Map(),
40
+ fieldsErrors: Map(),
41
+ hasChanged: false,
42
+ key: '',
43
+ });
44
+
45
+ function entryDraftReducer(state = Map(), action) {
46
+ switch (action.type) {
47
+ case DRAFT_CREATE_FROM_ENTRY:
48
+ // Existing Entry
49
+ return state.withMutations(state => {
50
+ state.set('entry', fromJS(action.payload.entry));
51
+ state.setIn(['entry', 'newRecord'], false);
52
+ state.set('fieldsMetaData', Map());
53
+ state.set('fieldsErrors', Map());
54
+ state.set('hasChanged', false);
55
+ state.set('key', uuid());
56
+ });
57
+ case DRAFT_CREATE_EMPTY:
58
+ // New Entry
59
+ return state.withMutations(state => {
60
+ state.set('entry', fromJS(action.payload));
61
+ state.setIn(['entry', 'newRecord'], true);
62
+ state.set('fieldsMetaData', Map());
63
+ state.set('fieldsErrors', Map());
64
+ state.set('hasChanged', false);
65
+ state.set('key', uuid());
66
+ });
67
+ case DRAFT_CREATE_FROM_LOCAL_BACKUP:
68
+ // Local Backup
69
+ return state.withMutations(state => {
70
+ const backupDraftEntry = state.get('localBackup');
71
+ const backupEntry = backupDraftEntry.get('entry');
72
+ state.delete('localBackup');
73
+ state.set('entry', backupEntry);
74
+ state.setIn(['entry', 'newRecord'], !backupEntry.get('path'));
75
+ state.set('fieldsMetaData', Map());
76
+ state.set('fieldsErrors', Map());
77
+ state.set('hasChanged', true);
78
+ state.set('key', uuid());
79
+ });
80
+ case DRAFT_CREATE_DUPLICATE_FROM_ENTRY:
81
+ // Duplicate Entry
82
+ return state.withMutations(state => {
83
+ state.set('entry', fromJS(action.payload));
84
+ state.setIn(['entry', 'newRecord'], true);
85
+ state.set('mediaFiles', List());
86
+ state.set('fieldsMetaData', Map());
87
+ state.set('fieldsErrors', Map());
88
+ state.set('hasChanged', true);
89
+ });
90
+ case DRAFT_DISCARD:
91
+ return initialState;
92
+ case DRAFT_LOCAL_BACKUP_RETRIEVED: {
93
+ const { entry } = action.payload;
94
+ const newState = new Map({
95
+ entry: fromJS(entry),
96
+ });
97
+ return state.set('localBackup', newState);
98
+ }
99
+ case DRAFT_CHANGE_FIELD: {
100
+ return state.withMutations(state => {
101
+ const { field, value, metadata, entries, i18n } = action.payload;
102
+ const name = field.get('name');
103
+ const meta = field.get('meta');
104
+
105
+ const dataPath = (i18n && getDataPath(i18n.currentLocale, i18n.defaultLocale)) || ['data'];
106
+ if (meta) {
107
+ state.setIn(['entry', 'meta', name], value);
108
+ } else {
109
+ state.setIn(['entry', ...dataPath, name], value);
110
+ if (i18n) {
111
+ state = duplicateI18nFields(state, field, i18n.locales, i18n.defaultLocale);
112
+ }
113
+ }
114
+ state.mergeDeepIn(['fieldsMetaData'], fromJS(metadata));
115
+ const newData = state.getIn(['entry', ...dataPath]);
116
+ const newMeta = state.getIn(['entry', 'meta']);
117
+ state.set(
118
+ 'hasChanged',
119
+ !entries.some(e => newData.equals(e.get(...dataPath))) ||
120
+ !entries.some(e => newMeta.equals(e.get('meta'))),
121
+ );
122
+ });
123
+ }
124
+ case DRAFT_VALIDATION_ERRORS:
125
+ if (action.payload.errors.length === 0) {
126
+ return state.deleteIn(['fieldsErrors', action.payload.uniquefieldId]);
127
+ } else {
128
+ return state.setIn(['fieldsErrors', action.payload.uniquefieldId], action.payload.errors);
129
+ }
130
+
131
+ case DRAFT_CLEAR_ERRORS: {
132
+ const { uniqueFieldId } = action.payload;
133
+ return state.deleteIn(['fieldsErrors', uniqueFieldId]);
134
+ }
135
+
136
+ case ENTRY_PERSIST_REQUEST:
137
+ case UNPUBLISHED_ENTRY_PERSIST_REQUEST: {
138
+ return state.setIn(['entry', 'isPersisting'], true);
139
+ }
140
+
141
+ case ENTRY_PERSIST_FAILURE:
142
+ case UNPUBLISHED_ENTRY_PERSIST_FAILURE: {
143
+ return state.deleteIn(['entry', 'isPersisting']);
144
+ }
145
+
146
+ case UNPUBLISHED_ENTRY_STATUS_CHANGE_REQUEST:
147
+ return state.setIn(['entry', 'isUpdatingStatus'], true);
148
+
149
+ case UNPUBLISHED_ENTRY_STATUS_CHANGE_FAILURE:
150
+ case UNPUBLISHED_ENTRY_STATUS_CHANGE_SUCCESS:
151
+ return state.deleteIn(['entry', 'isUpdatingStatus']);
152
+
153
+ case UNPUBLISHED_ENTRY_PUBLISH_REQUEST:
154
+ return state.setIn(['entry', 'isPublishing'], true);
155
+
156
+ case UNPUBLISHED_ENTRY_PUBLISH_SUCCESS:
157
+ case UNPUBLISHED_ENTRY_PUBLISH_FAILURE:
158
+ return state.deleteIn(['entry', 'isPublishing']);
159
+
160
+ case ENTRY_PERSIST_SUCCESS:
161
+ case UNPUBLISHED_ENTRY_PERSIST_SUCCESS:
162
+ return state.withMutations(state => {
163
+ state.deleteIn(['entry', 'isPersisting']);
164
+ state.set('hasChanged', false);
165
+ if (!state.getIn(['entry', 'slug'])) {
166
+ state.setIn(['entry', 'slug'], action.payload.slug);
167
+ }
168
+ });
169
+
170
+ case ENTRY_DELETE_SUCCESS:
171
+ return state.withMutations(state => {
172
+ state.deleteIn(['entry', 'isPersisting']);
173
+ state.set('hasChanged', false);
174
+ });
175
+
176
+ case ADD_DRAFT_ENTRY_MEDIA_FILE: {
177
+ return state.withMutations(state => {
178
+ const mediaFiles = state.getIn(['entry', 'mediaFiles']);
179
+
180
+ state.setIn(
181
+ ['entry', 'mediaFiles'],
182
+ mediaFiles
183
+ .filterNot(file => file.get('id') === action.payload.id)
184
+ .insert(0, fromJS(action.payload)),
185
+ );
186
+ state.set('hasChanged', true);
187
+ });
188
+ }
189
+
190
+ case REMOVE_DRAFT_ENTRY_MEDIA_FILE: {
191
+ return state.withMutations(state => {
192
+ const mediaFiles = state.getIn(['entry', 'mediaFiles']);
193
+
194
+ state.setIn(
195
+ ['entry', 'mediaFiles'],
196
+ mediaFiles.filterNot(file => file.get('id') === action.payload.id),
197
+ );
198
+ state.set('hasChanged', true);
199
+ });
200
+ }
201
+
202
+ default:
203
+ return state;
204
+ }
205
+ }
206
+
207
+ function cleanTitleForFilename(title) {
208
+ if (!title) return 'untitled';
209
+ // Convert to lowercase, replace spaces and special chars with hyphens
210
+ return title
211
+ .toString()
212
+ .toLowerCase()
213
+ .trim()
214
+ .replace(/[^\w\s-]/g, '') // Remove special characters
215
+ .replace(/[\s_]+/g, '-') // Replace spaces and underscores with hyphens
216
+ .replace(/^-+|-+$/g, ''); // Remove leading/trailing hyphens
217
+ }
218
+
219
+ export function selectCustomPath(collection, entryDraft) {
220
+ if (!selectHasMetaPath(collection)) {
221
+ return;
222
+ }
223
+ const meta = entryDraft.getIn(['entry', 'meta']);
224
+ const path = meta && meta.get('path');
225
+
226
+ if (!path) {
227
+ return;
228
+ }
229
+
230
+ const extension = selectFolderEntryExtension(collection);
231
+ const indexFile = get(collection.toJS(), ['meta', 'path', 'index_file']);
232
+
233
+ // If index_file is specified, use the old behavior for backward compatibility
234
+ if (indexFile) {
235
+ const customPath = join(collection.get('folder'), path, `${indexFile}.${extension}`);
236
+ return customPath;
237
+ }
238
+
239
+ // New behavior: generate filename from entry title
240
+ const isNewEntry = entryDraft.getIn(['entry', 'newRecord']);
241
+ const currentPath = entryDraft.getIn(['entry', 'path']);
242
+
243
+ let filename;
244
+ if (isNewEntry || !currentPath) {
245
+ // For new entries, generate filename from title
246
+ const entryData = entryDraft.getIn(['entry', 'data']);
247
+ const title = entryData && entryData.get('title');
248
+ filename = cleanTitleForFilename(title);
249
+ } else {
250
+ // For existing entries, preserve the current filename
251
+ const { basename: basenameFunc } = require('path');
252
+ const currentFilename = basenameFunc(currentPath, `.${extension}`);
253
+ filename = currentFilename;
254
+ }
255
+
256
+ const customPath = join(collection.get('folder'), path, `${filename}.${extension}`);
257
+ return customPath;
258
+ }
259
+
260
+ export default entryDraftReducer;
@@ -0,0 +1,45 @@
1
+ import { produce } from 'immer';
2
+
3
+ import { USE_OPEN_AUTHORING } from '../actions/auth';
4
+
5
+ import type { AnyAction } from 'redux';
6
+
7
+ export type GlobalUI = {
8
+ isFetching: boolean;
9
+ useOpenAuthoring: boolean;
10
+ };
11
+
12
+ const LOADING_IGNORE_LIST = [
13
+ 'DEPLOY_PREVIEW',
14
+ 'STATUS_REQUEST',
15
+ 'STATUS_SUCCESS',
16
+ 'STATUS_FAILURE',
17
+ ];
18
+
19
+ function ignoreWhenLoading(action: AnyAction) {
20
+ return LOADING_IGNORE_LIST.some(type => action.type.includes(type));
21
+ }
22
+
23
+ const defaultState: GlobalUI = {
24
+ isFetching: false,
25
+ useOpenAuthoring: false,
26
+ };
27
+
28
+ /**
29
+ * Reducer for some global UI state that we want to share between components
30
+ */
31
+ const globalUI = produce((state: GlobalUI, action: AnyAction) => {
32
+ // Generic, global loading indicator
33
+ if (!ignoreWhenLoading(action) && action.type.includes('REQUEST')) {
34
+ state.isFetching = true;
35
+ } else if (
36
+ !ignoreWhenLoading(action) &&
37
+ (action.type.includes('SUCCESS') || action.type.includes('FAILURE'))
38
+ ) {
39
+ state.isFetching = false;
40
+ } else if (action.type === USE_OPEN_AUTHORING) {
41
+ state.useOpenAuthoring = true;
42
+ }
43
+ }, defaultState);
44
+
45
+ export default globalUI;
@@ -0,0 +1,82 @@
1
+ import { List } from 'immutable';
2
+
3
+ import auth from './auth';
4
+ import config from './config';
5
+ import integrations, * as fromIntegrations from './integrations';
6
+ import entries, * as fromEntries from './entries';
7
+ import cursors from './cursors';
8
+ import editorialWorkflow, * as fromEditorialWorkflow from './editorialWorkflow';
9
+ import entryDraft from './entryDraft';
10
+ import collections from './collections';
11
+ import search from './search';
12
+ import medias from './medias';
13
+ import mediaLibrary from './mediaLibrary';
14
+ import deploys, * as fromDeploys from './deploys';
15
+ import globalUI from './globalUI';
16
+ import status from './status';
17
+ import notifications from './notifications';
18
+
19
+ import type { Status } from '../constants/publishModes';
20
+ import type { State, Collection } from '../types/redux';
21
+
22
+ const reducers = {
23
+ auth,
24
+ config,
25
+ collections,
26
+ search,
27
+ integrations,
28
+ entries,
29
+ cursors,
30
+ editorialWorkflow,
31
+ entryDraft,
32
+ medias,
33
+ mediaLibrary,
34
+ deploys,
35
+ globalUI,
36
+ status,
37
+ notifications,
38
+ };
39
+
40
+ export default reducers;
41
+
42
+ /*
43
+ * Selectors
44
+ */
45
+ export function selectEntry(state: State, collection: string, slug: string) {
46
+ return fromEntries.selectEntry(state.entries, collection, slug);
47
+ }
48
+
49
+ export function selectEntries(state: State, collection: Collection) {
50
+ return fromEntries.selectEntries(state.entries, collection);
51
+ }
52
+
53
+ export function selectPublishedSlugs(state: State, collection: string) {
54
+ return fromEntries.selectPublishedSlugs(state.entries, collection);
55
+ }
56
+
57
+ export function selectSearchedEntries(state: State, availableCollections: string[]) {
58
+ // only return search results for actually available collections
59
+ return List(state.search.entryIds)
60
+ .filter(entryId => availableCollections.indexOf(entryId!.collection) !== -1)
61
+ .map(entryId => fromEntries.selectEntry(state.entries, entryId!.collection, entryId!.slug));
62
+ }
63
+
64
+ export function selectDeployPreview(state: State, collection: string, slug: string) {
65
+ return fromDeploys.selectDeployPreview(state.deploys, collection, slug);
66
+ }
67
+
68
+ export function selectUnpublishedEntry(state: State, collection: string, slug: string) {
69
+ return fromEditorialWorkflow.selectUnpublishedEntry(state.editorialWorkflow, collection, slug);
70
+ }
71
+
72
+ export function selectUnpublishedEntriesByStatus(state: State, status: Status) {
73
+ return fromEditorialWorkflow.selectUnpublishedEntriesByStatus(state.editorialWorkflow, status);
74
+ }
75
+
76
+ export function selectUnpublishedSlugs(state: State, collection: string) {
77
+ return fromEditorialWorkflow.selectUnpublishedSlugs(state.editorialWorkflow, collection);
78
+ }
79
+
80
+ export function selectIntegration(state: State, collection: string | null, hook: string) {
81
+ return fromIntegrations.selectIntegration(state.integrations, collection, hook);
82
+ }
@@ -0,0 +1,59 @@
1
+ import { fromJS } from 'immutable';
2
+
3
+ import { CONFIG_SUCCESS } from '../actions/config';
4
+
5
+ import type { ConfigAction } from '../actions/config';
6
+ import type { Integrations, CmsConfig } from '../types/redux';
7
+
8
+ interface Acc {
9
+ providers: Record<string, {}>;
10
+ hooks: Record<string, string | Record<string, string>>;
11
+ }
12
+
13
+ export function getIntegrations(config: CmsConfig) {
14
+ const integrations = config.integrations || [];
15
+ const newState = integrations.reduce(
16
+ (acc, integration) => {
17
+ const { hooks, collections, provider, ...providerData } = integration;
18
+ acc.providers[provider] = { ...providerData };
19
+ if (!collections) {
20
+ hooks.forEach(hook => {
21
+ acc.hooks[hook] = provider;
22
+ });
23
+ return acc;
24
+ }
25
+ const integrationCollections =
26
+ collections === '*' ? config.collections.map(collection => collection.name) : collections;
27
+ integrationCollections.forEach(collection => {
28
+ hooks.forEach(hook => {
29
+ acc.hooks[collection]
30
+ ? ((acc.hooks[collection] as Record<string, string>)[hook] = provider)
31
+ : (acc.hooks[collection] = { [hook]: provider });
32
+ });
33
+ });
34
+ return acc;
35
+ },
36
+ { providers: {}, hooks: {} } as Acc,
37
+ );
38
+ return fromJS(newState);
39
+ }
40
+
41
+ const defaultState = fromJS({ providers: {}, hooks: {} });
42
+
43
+ function integrations(state = defaultState, action: ConfigAction): Integrations | null {
44
+ switch (action.type) {
45
+ case CONFIG_SUCCESS: {
46
+ return getIntegrations(action.payload);
47
+ }
48
+ default:
49
+ return state;
50
+ }
51
+ }
52
+
53
+ export function selectIntegration(state: Integrations, collection: string | null, hook: string) {
54
+ return collection
55
+ ? state.getIn(['hooks', collection, hook], false)
56
+ : state.getIn(['hooks', hook], false);
57
+ }
58
+
59
+ export default integrations;