decap-cms-core 3.13.0 → 3.14.0
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/dist/decap-cms-core.js +18 -18
- package/dist/decap-cms-core.js.map +1 -1
- package/dist/esm/actions/config.js +14 -1
- package/dist/esm/actions/entries.js +15 -4
- package/dist/esm/backend.js +2 -0
- package/dist/esm/bootstrap.js +2 -2
- package/dist/esm/components/App/App.js +12 -5
- package/dist/esm/components/App/Header.js +18 -18
- package/dist/esm/components/Collection/Entries/EntryCard.js +30 -15
- package/dist/esm/components/Collection/NestedCollection.js +20 -11
- package/dist/esm/components/Editor/EditorPreviewPane/EditorPreviewPane.js +22 -6
- package/dist/esm/components/UI/ErrorBoundary.js +2 -2
- package/dist/esm/components/UI/SettingsDropdown.js +25 -27
- package/dist/esm/constants/configSchema.js +1 -1
- package/dist/esm/lib/registry.js +4 -1
- package/dist/esm/reducers/entryDraft.js +36 -3
- package/index.d.ts +17 -1
- package/package.json +2 -2
- package/src/__tests__/backend.spec.js +214 -0
- package/src/actions/__tests__/config.spec.js +14 -0
- package/src/actions/__tests__/entries.spec.js +36 -1
- package/src/actions/config.ts +13 -1
- package/src/actions/entries.ts +22 -7
- package/src/backend.ts +2 -0
- package/src/components/App/App.js +22 -13
- package/src/components/App/Header.js +36 -11
- package/src/components/Collection/Entries/EntryCard.js +13 -3
- package/src/components/Collection/NestedCollection.js +14 -7
- package/src/components/Collection/__tests__/NestedCollection.spec.js +1 -1
- package/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap +0 -68
- package/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +6 -5
- package/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +104 -72
- package/src/components/UI/SettingsDropdown.js +36 -9
- package/src/constants/__tests__/configSchema.spec.js +9 -6
- package/src/constants/configSchema.js +1 -1
- package/src/lib/__tests__/formatters.spec.js +16 -4
- package/src/lib/__tests__/registry.spec.js +3 -3
- package/src/lib/registry.js +4 -1
- package/src/reducers/__tests__/entryDraft.spec.js +117 -0
- package/src/reducers/entryDraft.js +43 -3
- package/src/types/redux.ts +19 -2
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Map, List, fromJS } from 'immutable';
|
|
2
2
|
import { v4 as uuid } from 'uuid';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
|
-
import { join } from 'path';
|
|
4
|
+
import { join, basename } from 'path';
|
|
5
5
|
|
|
6
|
+
import { sanitizeSlug } from '../lib/urlHelper';
|
|
6
7
|
import {
|
|
7
8
|
DRAFT_CREATE_FROM_ENTRY,
|
|
8
9
|
DRAFT_CREATE_EMPTY,
|
|
@@ -204,15 +205,54 @@ function entryDraftReducer(state = Map(), action) {
|
|
|
204
205
|
}
|
|
205
206
|
}
|
|
206
207
|
|
|
208
|
+
function cleanTitleForFilename(title) {
|
|
209
|
+
if (!title) return 'untitled';
|
|
210
|
+
|
|
211
|
+
const cleanedTitle = sanitizeSlug(title.toString().toLowerCase().trim(), {
|
|
212
|
+
sanitize_replacement: '-',
|
|
213
|
+
encoding: 'unicode',
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
return cleanedTitle || 'untitled';
|
|
217
|
+
}
|
|
218
|
+
|
|
207
219
|
export function selectCustomPath(collection, entryDraft) {
|
|
208
220
|
if (!selectHasMetaPath(collection)) {
|
|
209
221
|
return;
|
|
210
222
|
}
|
|
211
223
|
const meta = entryDraft.getIn(['entry', 'meta']);
|
|
212
224
|
const path = meta && meta.get('path');
|
|
213
|
-
|
|
225
|
+
|
|
226
|
+
if (!path) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
|
|
214
230
|
const extension = selectFolderEntryExtension(collection);
|
|
215
|
-
const
|
|
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 currentFilename = basename(currentPath, `.${extension}`);
|
|
252
|
+
filename = currentFilename;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const customPath = join(collection.get('folder'), path, `${filename}.${extension}`);
|
|
216
256
|
return customPath;
|
|
217
257
|
}
|
|
218
258
|
|
package/src/types/redux.ts
CHANGED
|
@@ -185,6 +185,21 @@ export interface CmsFieldMarkdown {
|
|
|
185
185
|
editorComponents?: string[];
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
export interface CmsFieldRichText {
|
|
189
|
+
widget: 'richtext';
|
|
190
|
+
default?: string;
|
|
191
|
+
|
|
192
|
+
minimal?: boolean;
|
|
193
|
+
buttons?: CmsMarkdownWidgetButton[];
|
|
194
|
+
editor_components?: string[];
|
|
195
|
+
modes?: ('raw' | 'rich_text')[];
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @deprecated Use editor_components instead
|
|
199
|
+
*/
|
|
200
|
+
editorComponents?: string[];
|
|
201
|
+
}
|
|
202
|
+
|
|
188
203
|
export interface CmsFieldNumber {
|
|
189
204
|
widget: 'number';
|
|
190
205
|
default?: string | number;
|
|
@@ -258,7 +273,7 @@ export interface CmsFieldMeta {
|
|
|
258
273
|
label: string;
|
|
259
274
|
widget: string;
|
|
260
275
|
required: boolean;
|
|
261
|
-
index_file
|
|
276
|
+
index_file?: string;
|
|
262
277
|
meta: boolean;
|
|
263
278
|
}
|
|
264
279
|
|
|
@@ -272,6 +287,7 @@ export type CmsField = CmsFieldBase &
|
|
|
272
287
|
| CmsFieldList
|
|
273
288
|
| CmsFieldMap
|
|
274
289
|
| CmsFieldMarkdown
|
|
290
|
+
| CmsFieldRichText
|
|
275
291
|
| CmsFieldNumber
|
|
276
292
|
| CmsFieldObject
|
|
277
293
|
| CmsFieldRelation
|
|
@@ -340,7 +356,7 @@ export interface CmsCollection {
|
|
|
340
356
|
depth: number;
|
|
341
357
|
};
|
|
342
358
|
type: typeof FOLDER | typeof FILES;
|
|
343
|
-
meta?: { path?: { label: string; widget: string; index_file
|
|
359
|
+
meta?: { path?: { label: string; widget: string; index_file?: string } };
|
|
344
360
|
|
|
345
361
|
/**
|
|
346
362
|
* It accepts the following values: yml, yaml, toml, json, md, markdown, html
|
|
@@ -580,6 +596,7 @@ export type EntryField = StaticallyTypedRecord<{
|
|
|
580
596
|
name: string;
|
|
581
597
|
default: string | null | boolean | List<unknown>;
|
|
582
598
|
media_folder?: string;
|
|
599
|
+
multiple?: boolean;
|
|
583
600
|
public_folder?: string;
|
|
584
601
|
comment?: string;
|
|
585
602
|
meta?: boolean;
|