@nascentdigital/funnel-editor 4.6.7 → 5.0.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.
- package/dist/EditorApp.js +1 -1
- package/dist/EditorRoutes.js +7 -5
- package/dist/changesets/screens/ChangeSetViewer.js +1 -1
- package/dist/changesets/screens/ChangeSetsExplorer.js +1 -2
- package/dist/collection/hooks/CollectionController.d.ts +5 -16
- package/dist/collection/hooks/CollectionController.js +18 -37
- package/dist/collection/hooks/ICollectionController.d.ts +24 -0
- package/dist/collection/hooks/ICollectionController.js +20 -0
- package/dist/collection/hooks/index.d.ts +1 -0
- package/dist/collection/hooks/index.js +1 -0
- package/dist/collection/hooks/useCollectionController.d.ts +3 -3
- package/dist/collection/screens/CollectionEditor.js +2 -2
- package/dist/components.d.ts +14 -3
- package/dist/components.js +17 -3
- package/dist/core/components/feedback/dialog/MinimalDialogLayout.js +1 -1
- package/dist/core/components/fields/BooleanField.d.ts +2 -1
- package/dist/core/components/fields/BooleanField.js +2 -2
- package/dist/core/components/fields/DateField.d.ts +2 -1
- package/dist/core/components/fields/DateField.js +2 -2
- package/dist/core/components/fields/DynamicPagesEditor.d.ts +2 -1
- package/dist/core/components/fields/DynamicPagesEditor.js +1 -1
- package/dist/core/components/fields/EnumField.d.ts +2 -1
- package/dist/core/components/fields/EnumField.js +2 -2
- package/dist/core/components/fields/FieldCard.d.ts +1 -0
- package/dist/core/components/fields/FieldCard.js +8 -1
- package/dist/core/components/fields/FieldEditor.d.ts +2 -1
- package/dist/core/components/fields/FieldEditor.js +11 -11
- package/dist/core/components/fields/FieldLayout.d.ts +2 -1
- package/dist/core/components/fields/FieldLayout.js +3 -3
- package/dist/core/components/fields/ListEditor.d.ts +2 -1
- package/dist/core/components/fields/ListEditor.js +5 -6
- package/dist/core/components/fields/OptInField.d.ts +2 -1
- package/dist/core/components/fields/OptInField.js +2 -2
- package/dist/core/components/fields/RichTextEditor.js +1 -1
- package/dist/core/components/fields/RichTextField.d.ts +2 -1
- package/dist/core/components/fields/RichTextField.js +3 -5
- package/dist/core/components/fields/TextField.d.ts +2 -0
- package/dist/core/components/fields/TextField.js +2 -2
- package/dist/core/components/fields/TimestampField.d.ts +2 -1
- package/dist/core/components/fields/TimestampField.js +3 -3
- package/dist/core/components/fields/asset/AssetEditor.js +12 -44
- package/dist/core/components/fields/asset/AssetPicker.js +6 -6
- package/dist/core/components/fields/asset/AssetUploader.js +23 -31
- package/dist/core/components/fields/asset/preview/VideoPreview.js +16 -11
- package/dist/core/components/fields/asset/useAssetFields.d.ts +2 -17
- package/dist/core/components/fields/asset/useAssetFields.js +0 -21
- package/dist/core/components/fields/collection/CollectionEditor.js +1 -1
- package/dist/core/components/fields/collection/CollectionPicker.d.ts +2 -2
- package/dist/core/components/fields/collection/CollectionPicker.js +3 -4
- package/dist/core/components/fields/dynamicPages/PagePriorityDialog.js +1 -1
- package/dist/core/components/fields/embed/EmbeddedVideoEditor.js +34 -27
- package/dist/core/components/fields/factories/FieldValueFactory.js +11 -4
- package/dist/core/components/fields/factories/MediaFactory.d.ts +13 -0
- package/dist/core/components/fields/factories/MediaFactory.js +256 -0
- package/dist/core/components/fields/list/CreateFieldButton.js +1 -1
- package/dist/core/components/fields/media/MediaCard.d.ts +7 -0
- package/dist/core/components/fields/media/MediaCard.js +92 -0
- package/dist/core/components/fields/media/MediaEditor.d.ts +37 -0
- package/dist/core/components/fields/media/MediaEditor.js +235 -0
- package/dist/core/components/fields/media/MediaPicker.d.ts +15 -0
- package/dist/core/components/fields/media/MediaPicker.js +251 -0
- package/dist/core/components/fields/media/index.d.ts +3 -0
- package/dist/core/components/fields/media/index.js +19 -0
- package/dist/core/components/fields/object/ObjectEditor.js +1 -1
- package/dist/core/components/fields/page/PagePicker.js +1 -1
- package/dist/core/components/interaction/Combobox.js +1 -1
- package/dist/core/components/interaction/MultiSelectControls.js +2 -5
- package/dist/core/components/interaction/QuickEditor.js +1 -1
- package/dist/core/components/interaction/QuickPicker.js +1 -1
- package/dist/core/components/interaction/SideSheet.js +1 -1
- package/dist/core/components/interaction/centersheet/CenterSheet.js +7 -1
- package/dist/core/components/interaction/centersheet/CenterSheetContainer.js +3 -1
- package/dist/core/components/transitions/FadeIn.js +1 -1
- package/dist/core/components/visuals/Icon.d.ts +1 -1
- package/dist/core/components/visuals/Icon.js +3 -0
- package/dist/core/containers/AssetRepositoryContainer.d.ts +2 -0
- package/dist/core/containers/AssetRepositoryContainer.js +18 -0
- package/dist/core/containers/CollectionRepositoryContainer.d.ts +2 -0
- package/dist/core/containers/CollectionRepositoryContainer.js +18 -0
- package/dist/core/containers/PageRepositoryContainer.d.ts +2 -0
- package/dist/core/containers/PageRepositoryContainer.js +18 -0
- package/dist/core/containers/index.d.ts +3 -0
- package/dist/core/containers/index.js +19 -0
- package/dist/core/domain/Block.js +2 -1
- package/dist/core/domain/BlockConfiguration.d.ts +4 -1
- package/dist/core/domain/BlockConfiguration.js +59 -3
- package/dist/core/domain/Collection.d.ts +7 -25
- package/dist/core/domain/Collection.js +2 -16
- package/dist/core/domain/CollectionBrowser.d.ts +3 -2
- package/dist/core/domain/CollectionBrowser.js +3 -3
- package/dist/core/domain/CollectionFieldProxy.d.ts +12 -8
- package/dist/core/domain/CollectionFieldProxy.js +14 -8
- package/dist/core/domain/CollectionGroup.d.ts +0 -5
- package/dist/core/domain/CollectionGroup.js +0 -7
- package/dist/core/domain/CollectionSummary.d.ts +2 -2
- package/dist/core/domain/Collections.d.ts +3 -3
- package/dist/core/domain/Collections.js +4 -4
- package/dist/core/domain/ICollection.d.ts +71 -0
- package/dist/core/domain/ICollection.js +20 -0
- package/dist/core/domain/IPage.d.ts +14 -0
- package/dist/core/domain/Page.js +2 -2
- package/dist/core/domain/Pages.js +4 -6
- package/dist/core/domain/SectionBlock.js +2 -1
- package/dist/core/domain/Site.d.ts +4 -4
- package/dist/core/domain/Site.js +3 -3
- package/dist/core/domain/index.d.ts +1 -1
- package/dist/core/domain/index.js +1 -1
- package/dist/core/hooks/index.d.ts +4 -3
- package/dist/core/hooks/index.js +4 -3
- package/dist/core/hooks/useAssetRepository.d.ts +3 -0
- package/dist/core/hooks/useAssetRepository.js +11 -0
- package/dist/core/hooks/useCollection.d.ts +4 -4
- package/dist/core/hooks/useCollectionRepository.d.ts +3 -2
- package/dist/core/hooks/useCollectionRepository.js +4 -4
- package/dist/core/hooks/usePageRepository.d.ts +3 -2
- package/dist/core/hooks/usePageRepository.js +4 -4
- package/dist/core/hooks/useTempFields.d.ts +2 -3
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +1 -0
- package/dist/core/repository/AssetRepository.d.ts +10 -0
- package/dist/core/repository/AssetRepository.js +22 -0
- package/dist/core/repository/CollectionRepository.d.ts +21 -20
- package/dist/core/repository/CollectionRepository.js +23 -161
- package/dist/core/repository/CollectionSerializer.d.ts +4 -1
- package/dist/core/repository/CollectionSerializer.js +3 -3
- package/dist/core/repository/IAssetRepository.d.ts +25 -0
- package/dist/core/repository/ICollectionRepository.d.ts +62 -0
- package/dist/core/repository/ICollectionRepository.js +2 -0
- package/dist/core/repository/IPageRepository.d.ts +40 -0
- package/dist/core/repository/IPageRepository.js +2 -0
- package/dist/core/repository/PageRepository.d.ts +5 -8
- package/dist/core/repository/PageRepository.js +7 -280
- package/dist/core/repository/SerializeCollectionUpdate.d.ts +8 -0
- package/dist/core/repository/SerializeCollectionUpdate.js +168 -0
- package/dist/core/repository/SerializePageUpdate.d.ts +11 -0
- package/dist/core/repository/SerializePageUpdate.js +292 -0
- package/dist/core/repository/index.d.ts +4 -0
- package/dist/core/repository/index.js +4 -0
- package/dist/dashboard/screens/Dashboard.js +1 -1
- package/dist/devtools/screens/Devtools.js +1 -1
- package/dist/explore/components/CreatePageDialog.d.ts +2 -2
- package/dist/explore/screens/CollectionExplorer.js +1 -1
- package/dist/explore/screens/CollectionsExplorer.js +1 -1
- package/dist/explore/screens/PageExplorer.js +1 -1
- package/dist/explore/screens/SiteExplorer.js +1 -1
- package/dist/page/components/BlockEditor.js +1 -1
- package/dist/page/components/SettingsEditor.js +0 -7
- package/dist/page/components/config/BlockConfigButton.js +71 -14
- package/dist/page/screens/PageEditor.js +1 -1
- package/dist/styles/index.css +24 -20
- package/dist/styles/tailwind.js +1 -0
- package/dist/users/screens/UserExplorer.js +1 -1
- package/package.json +2 -2
- package/dist/core/domain/TranslateSchema.d.ts +0 -7
- /package/dist/core/{domain/TranslateSchema.js → repository/IAssetRepository.js} +0 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { CollectionClient } from '@nascentdigital/funnel-cms';
|
|
2
|
+
import { EventBus, FieldModel, Schema } from '@nascentdigital/funnel-core';
|
|
3
|
+
import { CollectionFieldProxy, ICollection } from '../domain';
|
|
4
|
+
export interface ICollectionRepository {
|
|
5
|
+
create(args: ICollectionRepository.Create.Args): Promise<ICollectionRepository.Create.Result>;
|
|
6
|
+
createRaw(args: ICollectionRepository.CreateRaw.Args): Promise<ICollectionRepository.CreateRaw.Result>;
|
|
7
|
+
createLanguage(args: ICollectionRepository.CreateLang.Args): Promise<ICollectionRepository.CreateLang.Result>;
|
|
8
|
+
save(collection: ICollection): Promise<ICollection>;
|
|
9
|
+
unpublish(collection: ICollection): Promise<void>;
|
|
10
|
+
getOverview(args: ICollectionRepository.GetOverview.Args): Promise<ICollectionRepository.GetOverview.Result>;
|
|
11
|
+
getItems(args: ICollectionRepository.GetItems.Args): Promise<ICollectionRepository.GetItems.Result>;
|
|
12
|
+
get(args: ICollectionRepository.Get.Args): Promise<ICollectionRepository.Get.Result>;
|
|
13
|
+
update(args: ICollectionRepository.Update.Args): Promise<ICollectionRepository.Update.Result>;
|
|
14
|
+
serializeUpdate(collection: ICollection | CollectionFieldProxy, savables: ICollectionRepository.Savable[]): ICollectionRepository.SerializeUpdates.Result;
|
|
15
|
+
}
|
|
16
|
+
export declare namespace ICollectionRepository {
|
|
17
|
+
type Savable = FieldModel;
|
|
18
|
+
namespace Create {
|
|
19
|
+
type Args = Omit<CollectionClient.Create.NewArgs, 'brand' | 'type' | 'version'> & {
|
|
20
|
+
template: Schema.Collection;
|
|
21
|
+
eventBus?: EventBus;
|
|
22
|
+
};
|
|
23
|
+
type Result = ICollection.WithGroup;
|
|
24
|
+
}
|
|
25
|
+
namespace CreateRaw {
|
|
26
|
+
type Args = Omit<CollectionClient.Create.NewArgs, 'brand' | 'type' | 'version'> & {
|
|
27
|
+
template: Schema.Collection;
|
|
28
|
+
};
|
|
29
|
+
type Result = Schema.Collection.Data.AsGroup;
|
|
30
|
+
}
|
|
31
|
+
namespace CreateLang {
|
|
32
|
+
type Args = Omit<CollectionClient.Create.NewLanguageArgs, 'brand'> & {
|
|
33
|
+
template: Schema.Collection;
|
|
34
|
+
eventBus: EventBus;
|
|
35
|
+
};
|
|
36
|
+
type Result = ICollection.WithGroup;
|
|
37
|
+
}
|
|
38
|
+
namespace GetOverview {
|
|
39
|
+
type Args = Omit<CollectionClient.GetOverview.Args, 'brand'>;
|
|
40
|
+
type Item = {
|
|
41
|
+
template: Schema.Collection;
|
|
42
|
+
type: Schema.Collection.Type;
|
|
43
|
+
count: number;
|
|
44
|
+
};
|
|
45
|
+
type Result = Item[];
|
|
46
|
+
}
|
|
47
|
+
namespace GetItems {
|
|
48
|
+
type Args = Omit<CollectionClient.GetItems.Args, 'brand'>;
|
|
49
|
+
type Result = CollectionClient.GetItems.Result;
|
|
50
|
+
}
|
|
51
|
+
namespace Get {
|
|
52
|
+
type Args = Omit<CollectionClient.Get.Args, 'brand'>;
|
|
53
|
+
type Result = CollectionClient.Get.Result;
|
|
54
|
+
}
|
|
55
|
+
namespace Update {
|
|
56
|
+
type Args = CollectionClient.Update.Args;
|
|
57
|
+
type Result = CollectionClient.Update.Result;
|
|
58
|
+
}
|
|
59
|
+
namespace SerializeUpdates {
|
|
60
|
+
type Result = CollectionClient.Update.Args;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { PageClient, Pagination } from '@nascentdigital/funnel-cms';
|
|
2
|
+
import { EventBus, PartialBy, Schema } from '@nascentdigital/funnel-core';
|
|
3
|
+
import { IPage, PageOverview } from '../domain';
|
|
4
|
+
export interface IPageRepository {
|
|
5
|
+
search(args: IPageRepository.Search.Args): Promise<IPageRepository.Search.Result>;
|
|
6
|
+
create(args: IPageRepository.Create.Args): Promise<IPageRepository.Create.Result>;
|
|
7
|
+
createLanguage(args: IPageRepository.CreateLang.Args): Promise<IPageRepository.CreateLang.Result>;
|
|
8
|
+
save(page: IPage): Promise<IPage>;
|
|
9
|
+
unpublish(page: IPage): Promise<void>;
|
|
10
|
+
getOverview(args: IPageRepository.GetOverview.Args): Promise<IPageRepository.GetOverview.Result>;
|
|
11
|
+
}
|
|
12
|
+
export declare namespace IPageRepository {
|
|
13
|
+
namespace Search {
|
|
14
|
+
type Args = Omit<PageClient.Search.Args, 'version' | 'brand' | 'type' | 'region'> & {
|
|
15
|
+
template: Schema.Page;
|
|
16
|
+
region: string;
|
|
17
|
+
};
|
|
18
|
+
type Result = Pagination.Paginated<IPage.Ref>;
|
|
19
|
+
}
|
|
20
|
+
namespace Create {
|
|
21
|
+
type Args = PartialBy<Omit<PageClient.Create.NewArgs, 'brand' | 'type' | 'route'>, 'name'> & {
|
|
22
|
+
template: Schema.Page;
|
|
23
|
+
eventBus?: EventBus;
|
|
24
|
+
};
|
|
25
|
+
type Result = IPage.WithSummary;
|
|
26
|
+
}
|
|
27
|
+
namespace CreateLang {
|
|
28
|
+
type Args = Omit<PageClient.Create.NewLanguageArgs, 'brand' | 'route'> & {
|
|
29
|
+
template: Schema.Page;
|
|
30
|
+
eventBus: EventBus;
|
|
31
|
+
};
|
|
32
|
+
type Result = IPage.WithSummary;
|
|
33
|
+
}
|
|
34
|
+
namespace GetOverview {
|
|
35
|
+
type Args = {
|
|
36
|
+
region: string;
|
|
37
|
+
};
|
|
38
|
+
type Result = PageOverview[];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { PageClient, Pagination } from '@nascentdigital/funnel-cms';
|
|
2
2
|
import { EventBus, PartialBy } from '@nascentdigital/funnel-core';
|
|
3
3
|
import { EditorApiClient } from '../client';
|
|
4
|
-
import {
|
|
4
|
+
import { IPage, Page } from '../domain';
|
|
5
|
+
import { IPageRepository } from './IPageRepository';
|
|
5
6
|
import { PageTarget } from './PageTarget';
|
|
6
|
-
export declare class PageRepository {
|
|
7
|
+
export declare class PageRepository implements IPageRepository {
|
|
7
8
|
readonly editorApi: EditorApiClient;
|
|
8
9
|
constructor(editorApi: EditorApiClient);
|
|
9
10
|
search(args: PageRepository.SearchArgs): Promise<Pagination.Paginated<IPage.Ref>>;
|
|
@@ -12,13 +13,8 @@ export declare class PageRepository {
|
|
|
12
13
|
createLanguage(args: PageRepository.CreateLanguageArgs): Promise<Page.WithSummary>;
|
|
13
14
|
save(page: Page): Promise<Page>;
|
|
14
15
|
unpublish(page: Page): Promise<void>;
|
|
16
|
+
getOverview(args: IPageRepository.GetOverview.Args): Promise<IPageRepository.GetOverview.Result>;
|
|
15
17
|
private serializePageUpdate;
|
|
16
|
-
private serializeSectionUpdate;
|
|
17
|
-
private serializeBlockUpdate;
|
|
18
|
-
private serializeFieldsUpdate;
|
|
19
|
-
private serializeObjectFieldUpdate;
|
|
20
|
-
private serializeFieldUpdate;
|
|
21
|
-
private serializeListUpdate;
|
|
22
18
|
}
|
|
23
19
|
export declare namespace PageRepository {
|
|
24
20
|
type SearchArgs = Omit<PageClient.Search.Args, 'version' | 'brand' | 'type' | 'region'> & Pick<Page.ConstructorArgs, 'template' | 'region'>;
|
|
@@ -29,4 +25,5 @@ export declare namespace PageRepository {
|
|
|
29
25
|
type CreateLanguageArgs = Omit<PageClient.Create.NewLanguageArgs, 'brand' | 'route'> & Pick<Page.ConstructorArgs, 'template'> & {
|
|
30
26
|
eventBus: EventBus;
|
|
31
27
|
};
|
|
28
|
+
type GetOverviewArgs = Omit<PageClient.GetOverview.Args, 'brand'>;
|
|
32
29
|
}
|
|
@@ -15,6 +15,7 @@ exports.PageRepository = void 0;
|
|
|
15
15
|
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
16
16
|
const domain_1 = require("../domain");
|
|
17
17
|
const PageSerializer_1 = require("./PageSerializer");
|
|
18
|
+
const SerializePageUpdate_1 = require("./SerializePageUpdate");
|
|
18
19
|
// class
|
|
19
20
|
class PageRepository {
|
|
20
21
|
constructor(editorApi) {
|
|
@@ -91,6 +92,9 @@ class PageRepository {
|
|
|
91
92
|
// unpublish page
|
|
92
93
|
await this.editorApi.unpublishPage(page.id);
|
|
93
94
|
}
|
|
95
|
+
async getOverview(args) {
|
|
96
|
+
return this.editorApi.getPagesOverview(Object.assign(Object.assign({}, args), { version: 'draft' }));
|
|
97
|
+
}
|
|
94
98
|
serializePageUpdate(page, savables) {
|
|
95
99
|
var _a, _b;
|
|
96
100
|
// root page updates
|
|
@@ -158,18 +162,18 @@ class PageRepository {
|
|
|
158
162
|
...rootPageUpdates,
|
|
159
163
|
...discover.reduce((updates, block) => {
|
|
160
164
|
// try to update block
|
|
161
|
-
|
|
165
|
+
SerializePageUpdate_1.SerializePageUpdate.serializeBlockUpdate(updates, block, 'discover', savables);
|
|
162
166
|
// keep reducing
|
|
163
167
|
return updates;
|
|
164
168
|
}, []),
|
|
165
169
|
...content.reduce((updates, item) => {
|
|
166
170
|
// handle block
|
|
167
171
|
if (item instanceof domain_1.Block) {
|
|
168
|
-
|
|
172
|
+
SerializePageUpdate_1.SerializePageUpdate.serializeBlockUpdate(updates, item, 'content', savables);
|
|
169
173
|
}
|
|
170
174
|
// or section
|
|
171
175
|
else {
|
|
172
|
-
|
|
176
|
+
SerializePageUpdate_1.SerializePageUpdate.serializeSectionUpdate(updates, item, 'content', savables);
|
|
173
177
|
}
|
|
174
178
|
// keep reducing
|
|
175
179
|
return updates;
|
|
@@ -181,282 +185,5 @@ class PageRepository {
|
|
|
181
185
|
]
|
|
182
186
|
};
|
|
183
187
|
}
|
|
184
|
-
serializeSectionUpdate(updates, section, parentPath, savables) {
|
|
185
|
-
// track insert/update
|
|
186
|
-
let sectionChanged = false;
|
|
187
|
-
const path = [parentPath, section.key];
|
|
188
|
-
const { blocks, initialBlocks = [] } = section;
|
|
189
|
-
const blockIds = [];
|
|
190
|
-
blocks.forEach((sectionBlock, index) => {
|
|
191
|
-
// track id
|
|
192
|
-
const { id, block } = sectionBlock;
|
|
193
|
-
blockIds.push(id);
|
|
194
|
-
// track insert
|
|
195
|
-
const originalIndex = initialBlocks.findIndex(item => item.id === id);
|
|
196
|
-
if (originalIndex < 0) {
|
|
197
|
-
// add as insertion
|
|
198
|
-
updates.push({
|
|
199
|
-
type: 'section.insert',
|
|
200
|
-
path,
|
|
201
|
-
index,
|
|
202
|
-
section: {
|
|
203
|
-
type: 'section',
|
|
204
|
-
version: section.schema.version
|
|
205
|
-
},
|
|
206
|
-
block: sectionBlock.value
|
|
207
|
-
});
|
|
208
|
-
// mark changed
|
|
209
|
-
sectionChanged = true;
|
|
210
|
-
// track nested savables for section-block insertion
|
|
211
|
-
const fields = [...block.config, ...block.fields];
|
|
212
|
-
fields.forEach(field => {
|
|
213
|
-
if (field.modified) {
|
|
214
|
-
savables.push(field);
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
// recurse update if it's set
|
|
219
|
-
else if (block.modified) {
|
|
220
|
-
// track name field
|
|
221
|
-
if (block.nameField.modified) {
|
|
222
|
-
// send update
|
|
223
|
-
updates.push({
|
|
224
|
-
type: 'section.blockName',
|
|
225
|
-
path,
|
|
226
|
-
id,
|
|
227
|
-
value: funnel_core_1.Schema.TextField.Value.fromData(block.nameField.value) || null
|
|
228
|
-
});
|
|
229
|
-
// track change
|
|
230
|
-
savables.push(block.nameField);
|
|
231
|
-
}
|
|
232
|
-
// serialize config fields
|
|
233
|
-
this.serializeFieldsUpdate(updates, block.config, [...path, id, 'config'], savables);
|
|
234
|
-
// serialize content fields
|
|
235
|
-
this.serializeFieldsUpdate(updates, block.fields, [...path, id, 'fields'], savables);
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
// track delete/reorder
|
|
239
|
-
let reordered = false;
|
|
240
|
-
initialBlocks.forEach(({ id }, index) => {
|
|
241
|
-
// add to deleted list if the original doesn't exist anymore
|
|
242
|
-
const blockIndex = blockIds.findIndex(blockId => blockId === id);
|
|
243
|
-
if (blockIndex < 0) {
|
|
244
|
-
// delete
|
|
245
|
-
updates.push({
|
|
246
|
-
type: 'section.delete',
|
|
247
|
-
path,
|
|
248
|
-
id
|
|
249
|
-
});
|
|
250
|
-
// track reorder
|
|
251
|
-
sectionChanged = true;
|
|
252
|
-
}
|
|
253
|
-
// or mark reorder if index isn't the same
|
|
254
|
-
else if (blockIndex !== index) {
|
|
255
|
-
reordered = true;
|
|
256
|
-
sectionChanged = true;
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
// track reorder
|
|
260
|
-
if (reordered) {
|
|
261
|
-
updates.push({
|
|
262
|
-
type: 'section.reorder',
|
|
263
|
-
path,
|
|
264
|
-
ids: blockIds
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
// track section change (if any)
|
|
268
|
-
if (sectionChanged) {
|
|
269
|
-
savables.push(section);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
serializeBlockUpdate(updates, block, parentPath, savables) {
|
|
273
|
-
// ignore if block isn't activated
|
|
274
|
-
if (!block.activated) {
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
// create a new block if it's new
|
|
278
|
-
else if (block.isNew) {
|
|
279
|
-
// create update
|
|
280
|
-
updates.push({
|
|
281
|
-
type: 'block.create',
|
|
282
|
-
path: [parentPath, block.key],
|
|
283
|
-
block: block.value
|
|
284
|
-
});
|
|
285
|
-
// track block
|
|
286
|
-
savables.push(block);
|
|
287
|
-
// track nested savables for block insertion
|
|
288
|
-
const fields = [...block.config, ...block.fields];
|
|
289
|
-
fields.forEach(field => {
|
|
290
|
-
if (field.modified) {
|
|
291
|
-
savables.push(field);
|
|
292
|
-
}
|
|
293
|
-
});
|
|
294
|
-
}
|
|
295
|
-
// or just track updated fields
|
|
296
|
-
else {
|
|
297
|
-
// serialize config fields
|
|
298
|
-
this.serializeFieldsUpdate(updates, block.config, [parentPath, block.key, 'config'], savables);
|
|
299
|
-
// serialize content fields
|
|
300
|
-
this.serializeFieldsUpdate(updates, block.fields, [parentPath, block.key, 'fields'], savables);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
serializeFieldsUpdate(updates, fields, parentPath, savables) {
|
|
304
|
-
// handle fields in block
|
|
305
|
-
fields.forEach(field => {
|
|
306
|
-
if (field instanceof funnel_core_1.Field) {
|
|
307
|
-
this.serializeFieldUpdate(updates, field, parentPath, savables);
|
|
308
|
-
}
|
|
309
|
-
else if (field instanceof funnel_core_1.ObjectField) {
|
|
310
|
-
this.serializeObjectFieldUpdate(updates, field, parentPath, savables);
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
this.serializeListUpdate(updates, field, parentPath, savables);
|
|
314
|
-
}
|
|
315
|
-
});
|
|
316
|
-
// return changes (for chaining)
|
|
317
|
-
return updates;
|
|
318
|
-
}
|
|
319
|
-
serializeObjectFieldUpdate(updates, field, parentPath, savables) {
|
|
320
|
-
var _a;
|
|
321
|
-
// create object if it's new
|
|
322
|
-
if (field.isNew) {
|
|
323
|
-
// add insert
|
|
324
|
-
updates.push({
|
|
325
|
-
type: 'object.insert',
|
|
326
|
-
path: [...parentPath, field.id],
|
|
327
|
-
value: (_a = field.value) !== null && _a !== void 0 ? _a : null
|
|
328
|
-
});
|
|
329
|
-
// track save
|
|
330
|
-
savables.push(field);
|
|
331
|
-
}
|
|
332
|
-
// or process subfields
|
|
333
|
-
else if (field.exists) {
|
|
334
|
-
// save fields
|
|
335
|
-
this.serializeFieldsUpdate(updates, field.fields, [...parentPath, field.id], savables);
|
|
336
|
-
// track save
|
|
337
|
-
savables.push(field);
|
|
338
|
-
}
|
|
339
|
-
// or process opted out field
|
|
340
|
-
else if (field.optedOut) {
|
|
341
|
-
// remove field
|
|
342
|
-
updates.push({
|
|
343
|
-
type: 'value',
|
|
344
|
-
path: [...parentPath, field.id],
|
|
345
|
-
value: null
|
|
346
|
-
});
|
|
347
|
-
// track save
|
|
348
|
-
savables.push(field);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
serializeFieldUpdate(updates, field, parentPath, savables) {
|
|
352
|
-
var _a;
|
|
353
|
-
// track change if modified (ignore if field is sandboxed)
|
|
354
|
-
if (field.modified && !field.sandboxed) {
|
|
355
|
-
// set field
|
|
356
|
-
updates.push({
|
|
357
|
-
type: 'value',
|
|
358
|
-
path: [...parentPath, field.id],
|
|
359
|
-
value: ((_a = field.value) !== null && _a !== void 0 ? _a : null)
|
|
360
|
-
});
|
|
361
|
-
// track save
|
|
362
|
-
savables.push(field);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
serializeListUpdate(updates, list, parentPath, savables) {
|
|
366
|
-
var _a, _b;
|
|
367
|
-
// create list if it's new
|
|
368
|
-
if (list.isNew) {
|
|
369
|
-
// add new list
|
|
370
|
-
updates.push({
|
|
371
|
-
type: 'value',
|
|
372
|
-
path: [...parentPath, list.id],
|
|
373
|
-
value: funnel_core_1.Schema.Field.Data.newValue('list')
|
|
374
|
-
});
|
|
375
|
-
// track save
|
|
376
|
-
savables.push(list);
|
|
377
|
-
}
|
|
378
|
-
// or drop list on opt-out
|
|
379
|
-
else if (list.optedOut) {
|
|
380
|
-
// drop list
|
|
381
|
-
updates.push({
|
|
382
|
-
type: 'value',
|
|
383
|
-
path: [...parentPath, list.id],
|
|
384
|
-
value: null
|
|
385
|
-
});
|
|
386
|
-
// track save
|
|
387
|
-
savables.push(list);
|
|
388
|
-
}
|
|
389
|
-
// or if it is modified (otherwise ignore)
|
|
390
|
-
else if (list.modified) {
|
|
391
|
-
// add new list if there's nothing and it's new
|
|
392
|
-
const path = [...parentPath, list.id];
|
|
393
|
-
const { value: currentValue, items: fields, initialValue } = list;
|
|
394
|
-
const currentItems = (_a = currentValue === null || currentValue === void 0 ? void 0 : currentValue.value) !== null && _a !== void 0 ? _a : [];
|
|
395
|
-
const initialItems = (_b = initialValue === null || initialValue === void 0 ? void 0 : initialValue.value) !== null && _b !== void 0 ? _b : [];
|
|
396
|
-
const fieldIds = [];
|
|
397
|
-
// track inserts/updates of elements
|
|
398
|
-
currentItems.forEach((item, index) => {
|
|
399
|
-
// track id
|
|
400
|
-
const { id, field } = fields[index];
|
|
401
|
-
fieldIds.push(item.id);
|
|
402
|
-
// track insert
|
|
403
|
-
const originalIndex = initialItems.findIndex(initialItem => initialItem.id === id);
|
|
404
|
-
if (originalIndex < 0) {
|
|
405
|
-
updates.push({
|
|
406
|
-
type: 'array.insert',
|
|
407
|
-
path,
|
|
408
|
-
index,
|
|
409
|
-
id,
|
|
410
|
-
value: item
|
|
411
|
-
});
|
|
412
|
-
}
|
|
413
|
-
// track update
|
|
414
|
-
else if (field.modified) {
|
|
415
|
-
// object field updates should be recursed and indexed
|
|
416
|
-
if (field instanceof funnel_core_1.ObjectField) {
|
|
417
|
-
this.serializeFieldsUpdate(updates, field.fields, [...path, id], savables);
|
|
418
|
-
}
|
|
419
|
-
// basic field updates can be done inline
|
|
420
|
-
else {
|
|
421
|
-
updates.push({
|
|
422
|
-
type: 'value',
|
|
423
|
-
path: [...path, id],
|
|
424
|
-
value: item
|
|
425
|
-
});
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
});
|
|
429
|
-
// track delete/reorder
|
|
430
|
-
let reordered = false;
|
|
431
|
-
let deleted = 0;
|
|
432
|
-
initialItems.forEach(({ id }, index) => {
|
|
433
|
-
// add to deleted list if the original doesn't exist anymore
|
|
434
|
-
const fieldIndex = fieldIds.findIndex(fieldId => fieldId === id) + deleted;
|
|
435
|
-
if (fieldIndex < 0) {
|
|
436
|
-
updates.push({
|
|
437
|
-
type: 'array.delete',
|
|
438
|
-
path,
|
|
439
|
-
id
|
|
440
|
-
});
|
|
441
|
-
// track deletion
|
|
442
|
-
++deleted;
|
|
443
|
-
}
|
|
444
|
-
// or mark reorder if index isn't the same
|
|
445
|
-
else if (fieldIndex !== index) {
|
|
446
|
-
reordered = true;
|
|
447
|
-
}
|
|
448
|
-
});
|
|
449
|
-
// track reorder
|
|
450
|
-
if (reordered) {
|
|
451
|
-
updates.push({
|
|
452
|
-
type: 'array.reorder',
|
|
453
|
-
path,
|
|
454
|
-
ids: fieldIds
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
// track save
|
|
458
|
-
savables.push(list);
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
188
|
}
|
|
462
189
|
exports.PageRepository = PageRepository;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Field, FieldList, FieldModel, ObjectField, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { ICollectionRepository } from './ICollectionRepository';
|
|
3
|
+
export declare namespace SerializeCollectionUpdate {
|
|
4
|
+
function serializeFieldsUpdate(updates: Schema.Collection.Update[], fields: ReadonlyArray<FieldModel>, parentPath: ReadonlyArray<string>, savables: ICollectionRepository.Savable[]): Schema.Collection.Update[];
|
|
5
|
+
function serializeObjectFieldUpdate(updates: Schema.Collection.Update[], field: ObjectField, parentPath: ReadonlyArray<string>, savables: ICollectionRepository.Savable[]): void;
|
|
6
|
+
function serializeFieldUpdate(updates: Schema.Collection.Update[], field: Field, parentPath: ReadonlyArray<string>, savables: ICollectionRepository.Savable[]): void;
|
|
7
|
+
function serializeListUpdate(updates: Schema.Collection.Update[], list: FieldList, parentPath: ReadonlyArray<string>, savables: ICollectionRepository.Savable[]): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SerializeCollectionUpdate = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
// namespace
|
|
6
|
+
var SerializeCollectionUpdate;
|
|
7
|
+
(function (SerializeCollectionUpdate) {
|
|
8
|
+
// helper
|
|
9
|
+
function serializeFieldsUpdate(updates, fields, parentPath, savables) {
|
|
10
|
+
// handle fields in block
|
|
11
|
+
fields.forEach(field => {
|
|
12
|
+
if (field instanceof funnel_core_1.Field) {
|
|
13
|
+
serializeFieldUpdate(updates, field, parentPath, savables);
|
|
14
|
+
}
|
|
15
|
+
else if (field instanceof funnel_core_1.ObjectField) {
|
|
16
|
+
serializeObjectFieldUpdate(updates, field, parentPath, savables);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
serializeListUpdate(updates, field, parentPath, savables);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
// return changes (for chaining)
|
|
23
|
+
return updates;
|
|
24
|
+
}
|
|
25
|
+
SerializeCollectionUpdate.serializeFieldsUpdate = serializeFieldsUpdate;
|
|
26
|
+
function serializeObjectFieldUpdate(updates, field, parentPath, savables) {
|
|
27
|
+
var _a;
|
|
28
|
+
// create object if it's new
|
|
29
|
+
if (field.isNew) {
|
|
30
|
+
updates.push({
|
|
31
|
+
type: 'object.insert',
|
|
32
|
+
path: [...parentPath, field.id],
|
|
33
|
+
value: (_a = field.value) !== null && _a !== void 0 ? _a : null
|
|
34
|
+
});
|
|
35
|
+
// track save
|
|
36
|
+
savables.push(field);
|
|
37
|
+
}
|
|
38
|
+
// or process subfields
|
|
39
|
+
else if (field.exists) {
|
|
40
|
+
// save fields
|
|
41
|
+
serializeFieldsUpdate(updates, field.fields, [...parentPath, field.id], savables);
|
|
42
|
+
// track save
|
|
43
|
+
savables.push(field);
|
|
44
|
+
}
|
|
45
|
+
// or process opted out field
|
|
46
|
+
else if (field.optedOut) {
|
|
47
|
+
updates.push({
|
|
48
|
+
type: 'value',
|
|
49
|
+
path: [...parentPath, field.id],
|
|
50
|
+
value: null
|
|
51
|
+
});
|
|
52
|
+
// track save
|
|
53
|
+
savables.push(field);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
SerializeCollectionUpdate.serializeObjectFieldUpdate = serializeObjectFieldUpdate;
|
|
57
|
+
function serializeFieldUpdate(updates, field, parentPath, savables) {
|
|
58
|
+
var _a;
|
|
59
|
+
// track change if modified (ignore if field is sandboxed)
|
|
60
|
+
if (field.modified && !field.sandboxed) {
|
|
61
|
+
// set field
|
|
62
|
+
updates.push({
|
|
63
|
+
type: 'value',
|
|
64
|
+
path: [...parentPath, field.id],
|
|
65
|
+
value: ((_a = field.value) !== null && _a !== void 0 ? _a : null)
|
|
66
|
+
});
|
|
67
|
+
// track save
|
|
68
|
+
savables.push(field);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
SerializeCollectionUpdate.serializeFieldUpdate = serializeFieldUpdate;
|
|
72
|
+
function serializeListUpdate(updates, list, parentPath, savables) {
|
|
73
|
+
var _a, _b;
|
|
74
|
+
// create list if it's new
|
|
75
|
+
if (list.isNew) {
|
|
76
|
+
// add new list
|
|
77
|
+
updates.push({
|
|
78
|
+
type: 'value',
|
|
79
|
+
path: [...parentPath, list.id],
|
|
80
|
+
value: funnel_core_1.Schema.Field.Data.newValue('list')
|
|
81
|
+
});
|
|
82
|
+
// track save
|
|
83
|
+
savables.push(list);
|
|
84
|
+
}
|
|
85
|
+
// or drop list on opt-out
|
|
86
|
+
else if (list.optedOut) {
|
|
87
|
+
// drop list
|
|
88
|
+
updates.push({
|
|
89
|
+
type: 'value',
|
|
90
|
+
path: [...parentPath, list.id],
|
|
91
|
+
value: null
|
|
92
|
+
});
|
|
93
|
+
// track save
|
|
94
|
+
savables.push(list);
|
|
95
|
+
}
|
|
96
|
+
// or skip if not modified
|
|
97
|
+
else if (list.modified) {
|
|
98
|
+
// track insert/update
|
|
99
|
+
const path = [...parentPath, list.id];
|
|
100
|
+
const { value: currentValue, items: fields, initialValue } = list;
|
|
101
|
+
const currentItems = (_a = currentValue === null || currentValue === void 0 ? void 0 : currentValue.value) !== null && _a !== void 0 ? _a : [];
|
|
102
|
+
const initialItems = (_b = initialValue === null || initialValue === void 0 ? void 0 : initialValue.value) !== null && _b !== void 0 ? _b : [];
|
|
103
|
+
const fieldIds = [];
|
|
104
|
+
currentItems.forEach((item, index) => {
|
|
105
|
+
// track id
|
|
106
|
+
const { id, field } = fields[index];
|
|
107
|
+
fieldIds.push(item.id);
|
|
108
|
+
// track insert
|
|
109
|
+
const originalIndex = initialItems.findIndex(initialItem => initialItem.id === id);
|
|
110
|
+
if (originalIndex < 0) {
|
|
111
|
+
updates.push({
|
|
112
|
+
type: 'array.insert',
|
|
113
|
+
path,
|
|
114
|
+
index,
|
|
115
|
+
id,
|
|
116
|
+
value: item
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
// track update
|
|
120
|
+
else if (field.modified) {
|
|
121
|
+
// object field updates should be recursed and indexed
|
|
122
|
+
if (field instanceof funnel_core_1.ObjectField) {
|
|
123
|
+
serializeFieldsUpdate(updates, field.fields, [...path, id], savables);
|
|
124
|
+
}
|
|
125
|
+
// basic field updates can be done inline
|
|
126
|
+
else {
|
|
127
|
+
updates.push({
|
|
128
|
+
type: 'value',
|
|
129
|
+
path: [...path, id],
|
|
130
|
+
value: item
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
// track delete/reorder
|
|
136
|
+
let reordered = false;
|
|
137
|
+
let deleted = 0;
|
|
138
|
+
initialItems.forEach(({ id }, index) => {
|
|
139
|
+
// add to deleted list if the original doesn't exist anymore
|
|
140
|
+
const fieldIndex = fieldIds.findIndex(fieldId => fieldId === id) + deleted;
|
|
141
|
+
if (fieldIndex < 0) {
|
|
142
|
+
updates.push({
|
|
143
|
+
type: 'array.delete',
|
|
144
|
+
path,
|
|
145
|
+
id
|
|
146
|
+
});
|
|
147
|
+
// track deletion
|
|
148
|
+
++deleted;
|
|
149
|
+
}
|
|
150
|
+
// or mark reorder if index isn't the same
|
|
151
|
+
else if (fieldIndex !== index) {
|
|
152
|
+
reordered = true;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
// track reorder
|
|
156
|
+
if (reordered) {
|
|
157
|
+
updates.push({
|
|
158
|
+
type: 'array.reorder',
|
|
159
|
+
path,
|
|
160
|
+
ids: fieldIds
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
// track save
|
|
164
|
+
savables.push(list);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
SerializeCollectionUpdate.serializeListUpdate = serializeListUpdate;
|
|
168
|
+
})(SerializeCollectionUpdate || (exports.SerializeCollectionUpdate = SerializeCollectionUpdate = {}));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Field, FieldList, FieldModel, ObjectField, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
+
import type { Block, Section } from '../domain';
|
|
3
|
+
export declare namespace SerializePageUpdate {
|
|
4
|
+
type Savable = Section | Block | FieldModel;
|
|
5
|
+
function serializeSectionUpdate(updates: Schema.Page.Update[], section: Section, parentPath: string, savables: Savable[]): void;
|
|
6
|
+
function serializeBlockUpdate(updates: Schema.Page.Update[], block: Block, parentPath: string, savables: Savable[]): void;
|
|
7
|
+
function serializeFieldsUpdate(updates: Schema.Page.Update[], fields: ReadonlyArray<FieldModel>, parentPath: ReadonlyArray<string>, savables: Savable[]): Schema.Page.Update[];
|
|
8
|
+
function serializeObjectFieldUpdate(updates: Schema.Page.Update[], field: ObjectField, parentPath: ReadonlyArray<string>, savables: Savable[]): void;
|
|
9
|
+
function serializeFieldUpdate(updates: Schema.Page.Update[], field: Field, parentPath: ReadonlyArray<string>, savables: Savable[]): void;
|
|
10
|
+
function serializeListUpdate(updates: Schema.Page.Update[], list: FieldList, parentPath: ReadonlyArray<string>, savables: Savable[]): void;
|
|
11
|
+
}
|