@nascentdigital/funnel-editor-contentful 4.6.7 → 5.0.2
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/Editor.d.ts +6 -1
- package/dist/Editor.js +17 -1
- package/dist/EditorApp.js +11 -9
- package/dist/EditorPageRouter.d.ts +1 -0
- package/dist/EditorPageRouter.js +40 -0
- package/dist/EntryEditor.js +43 -1
- package/dist/EntrySidebar.js +18 -1
- package/dist/asset/index.d.ts +1 -0
- package/dist/{page/hooks → asset}/index.js +1 -1
- package/dist/asset/repository/AssetRepository.d.ts +10 -0
- package/dist/asset/repository/AssetRepository.js +33 -0
- package/dist/asset/repository/index.d.ts +1 -0
- package/dist/{core/api → asset/repository}/index.js +1 -3
- package/dist/collection/controller/ContentfulCollectionController.d.ts +41 -0
- package/dist/collection/controller/ContentfulCollectionController.js +278 -0
- package/dist/collection/controller/ContentfulCollectionControllerContainer.d.ts +5 -0
- package/dist/collection/controller/ContentfulCollectionControllerContainer.js +28 -0
- package/dist/collection/controller/index.d.ts +3 -0
- package/dist/collection/controller/index.js +19 -0
- package/dist/collection/controller/useContentfulCollectionController.d.ts +2 -0
- package/dist/collection/controller/useContentfulCollectionController.js +8 -0
- package/dist/collection/domain/Collection.d.ts +108 -0
- package/dist/collection/domain/Collection.js +386 -0
- package/dist/collection/domain/index.d.ts +1 -0
- package/dist/collection/domain/index.js +17 -0
- package/dist/collection/index.d.ts +3 -0
- package/dist/collection/index.js +19 -0
- package/dist/collection/repository/CollectionRepository.d.ts +49 -0
- package/dist/collection/repository/CollectionRepository.js +210 -0
- package/dist/collection/repository/index.d.ts +1 -0
- package/dist/collection/repository/index.js +17 -0
- package/dist/collection/screens/CollectionEditor.d.ts +1 -0
- package/dist/collection/screens/CollectionEditor.js +59 -0
- package/dist/collection/screens/index.d.ts +1 -0
- package/dist/collection/screens/index.js +17 -0
- package/dist/core/bridge/AppBridgeContainer.d.ts +9 -0
- package/dist/core/bridge/AppBridgeContainer.js +55 -0
- package/dist/core/bridge/AppBridgeContext.d.ts +8 -0
- package/dist/core/bridge/AppBridgeContext.js +11 -0
- package/dist/core/bridge/AppMessage.d.ts +19 -0
- package/dist/core/bridge/AppMessage.js +19 -0
- package/dist/core/bridge/index.d.ts +4 -0
- package/dist/core/bridge/index.js +20 -0
- package/dist/core/bridge/useAppBridge.d.ts +8 -0
- package/dist/core/bridge/useAppBridge.js +24 -0
- package/dist/core/client/ContentfulClientContainer.d.ts +8 -0
- package/dist/core/client/ContentfulClientContainer.js +43 -0
- package/dist/core/client/ContentfulClientContext.d.ts +8 -0
- package/dist/core/client/ContentfulClientContext.js +8 -0
- package/dist/core/client/index.d.ts +3 -0
- package/dist/core/client/index.js +19 -0
- package/dist/core/client/useContentfulClient.d.ts +4 -0
- package/dist/core/client/useContentfulClient.js +24 -0
- package/dist/core/contentful/Contentful.d.ts +33 -0
- package/dist/core/contentful/Contentful.js +67 -0
- package/dist/core/contentful/ContentfulAsset.d.ts +23 -0
- package/dist/core/contentful/ContentfulAsset.js +89 -0
- package/dist/core/contentful/ContentfulCollection.d.ts +29 -0
- package/dist/core/contentful/ContentfulCollection.js +97 -0
- package/dist/core/contentful/ContentfulPage.d.ts +31 -0
- package/dist/core/contentful/ContentfulPage.js +84 -0
- package/dist/core/contentful/ContentfulRefs.d.ts +16 -0
- package/dist/core/contentful/ContentfulRefs.js +152 -0
- package/dist/core/contentful/index.d.ts +5 -0
- package/dist/core/contentful/index.js +21 -0
- package/dist/core/index.d.ts +3 -2
- package/dist/core/index.js +3 -2
- package/dist/core/repository/CollectionSerializer.d.ts +9 -0
- package/dist/core/repository/CollectionSerializer.js +41 -0
- package/dist/core/repository/LocalCollectionRepository.d.ts +27 -0
- package/dist/core/repository/LocalCollectionRepository.js +143 -0
- package/dist/core/repository/LocalPageRepository.d.ts +16 -0
- package/dist/core/repository/LocalPageRepository.js +153 -0
- package/dist/core/repository/PageSerializer.d.ts +3 -3
- package/dist/core/repository/PageSerializer.js +18 -14
- package/dist/core/repository/RemoteCollectionRepository.d.ts +19 -0
- package/dist/core/repository/RemoteCollectionRepository.js +236 -0
- package/dist/core/repository/RemotePageRepository.d.ts +14 -0
- package/dist/core/repository/RemotePageRepository.js +113 -0
- package/dist/core/repository/index.d.ts +4 -1
- package/dist/core/repository/index.js +4 -1
- package/dist/explore/components/Header.d.ts +26 -0
- package/dist/explore/components/Header.js +31 -0
- package/dist/explore/components/index.d.ts +1 -0
- package/dist/explore/components/index.js +17 -0
- package/dist/explore/index.d.ts +1 -0
- package/dist/explore/index.js +17 -0
- package/dist/explore/screens/Dashboard.d.ts +1 -0
- package/dist/explore/screens/Dashboard.js +22 -0
- package/dist/explore/screens/PageExplorer.d.ts +1 -0
- package/dist/explore/screens/PageExplorer.js +9 -0
- package/dist/explore/screens/SiteExplorer.d.ts +1 -0
- package/dist/explore/screens/SiteExplorer.js +24 -0
- package/dist/explore/screens/index.d.ts +3 -0
- package/dist/explore/screens/index.js +19 -0
- package/dist/page/{hooks/PageController.d.ts → controller/ContentfulPageController.d.ts} +17 -6
- package/dist/page/controller/ContentfulPageController.js +277 -0
- package/dist/page/controller/ContentfulPageControllerContainer.d.ts +5 -0
- package/dist/page/controller/ContentfulPageControllerContainer.js +28 -0
- package/dist/page/controller/index.d.ts +3 -0
- package/dist/page/controller/index.js +19 -0
- package/dist/page/controller/useContentfulPageController.d.ts +2 -0
- package/dist/page/controller/useContentfulPageController.js +8 -0
- package/dist/{core → page}/domain/Page.d.ts +71 -10
- package/dist/page/domain/Page.js +631 -0
- package/dist/page/index.d.ts +3 -0
- package/dist/page/index.js +3 -0
- package/dist/page/repository/PageRepository.d.ts +45 -0
- package/dist/page/repository/PageRepository.js +224 -0
- package/dist/page/repository/index.d.ts +1 -0
- package/dist/page/repository/index.js +17 -0
- package/dist/page/screens/PageEditor.js +29 -15
- package/package.json +10 -4
- package/dist/core/api/EditorApiClient.d.ts +0 -7
- package/dist/core/api/EditorApiClient.js +0 -29
- package/dist/core/api/EditorApiContainer.d.ts +0 -5
- package/dist/core/api/EditorApiContainer.js +0 -16
- package/dist/core/api/EditorApiContext.d.ts +0 -7
- package/dist/core/api/EditorApiContext.js +0 -6
- package/dist/core/api/index.d.ts +0 -3
- package/dist/core/api/useEditorApi.d.ts +0 -2
- package/dist/core/api/useEditorApi.js +0 -12
- package/dist/core/domain/Page.js +0 -180
- package/dist/core/repository/PageRepository.d.ts +0 -12
- package/dist/core/repository/PageRepository.js +0 -23
- package/dist/page/hooks/PageController.js +0 -107
- package/dist/page/hooks/index.d.ts +0 -1
- /package/dist/{core → page}/domain/index.d.ts +0 -0
- /package/dist/{core → page}/domain/index.js +0 -0
|
@@ -0,0 +1,631 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.Page = void 0;
|
|
15
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
16
|
+
const components_1 = require("@nascentdigital/funnel-editor/components");
|
|
17
|
+
const rxjs_1 = require("rxjs");
|
|
18
|
+
// class
|
|
19
|
+
class Page {
|
|
20
|
+
constructor(args) {
|
|
21
|
+
var _a, _b, _c;
|
|
22
|
+
// initialize instance variables
|
|
23
|
+
this.id = args.id;
|
|
24
|
+
this.template = args.template;
|
|
25
|
+
this.eventBus = args.eventBus;
|
|
26
|
+
this.groupId = args.groupId;
|
|
27
|
+
this.brand = args.brand;
|
|
28
|
+
this.language = args.language;
|
|
29
|
+
this.region = args.region;
|
|
30
|
+
this.publishedOn = args.publishedOn;
|
|
31
|
+
this.createdOn = args.createdOn;
|
|
32
|
+
this.settings = new components_1.PageSettings(this);
|
|
33
|
+
this._state = args.state;
|
|
34
|
+
this._initialErrors = args.errors;
|
|
35
|
+
this._initialName = this._name = args.name;
|
|
36
|
+
this._updatedOn = args.updatedOn;
|
|
37
|
+
this._discover = args.discover;
|
|
38
|
+
this._content = args.content;
|
|
39
|
+
this._url = args.url;
|
|
40
|
+
this._initialSlug = this._slug = args.slug;
|
|
41
|
+
this._initialPublication = this._publication = args.publication;
|
|
42
|
+
this._assets = (_a = args.files) !== null && _a !== void 0 ? _a : [];
|
|
43
|
+
this._pages = (_b = args.pages) !== null && _b !== void 0 ? _b : [];
|
|
44
|
+
this._collections = (_c = args.collections) !== null && _c !== void 0 ? _c : [];
|
|
45
|
+
this._initialTags = new Set(args.tags);
|
|
46
|
+
this._tags = new Set(args.tags);
|
|
47
|
+
this.references = args.references;
|
|
48
|
+
this._deletedBlocks = [];
|
|
49
|
+
this._syncing = false;
|
|
50
|
+
// bind content
|
|
51
|
+
this._discover.forEach(item => item.bind({ parent: this, area: 'discover' }));
|
|
52
|
+
this._content.forEach((item) => item.bind({ parent: this, area: 'content' }));
|
|
53
|
+
// listen to block/field changes
|
|
54
|
+
this._subscription = this.eventBus.events$
|
|
55
|
+
.pipe((0, rxjs_1.filter)(e => (funnel_core_1.Field.Event.filter(e) && e.type === 'changed' && !e.field.sandboxed)
|
|
56
|
+
|| (funnel_core_1.FieldList.Event.filter(e) && e.type === 'changed')
|
|
57
|
+
|| (funnel_core_1.ObjectField.Event.filter(e) && e.type === 'changed')
|
|
58
|
+
|| (components_1.Item.Event.filter(e) && e.type === 'changed')))
|
|
59
|
+
.subscribe(() => this.raiseEvent('changed'));
|
|
60
|
+
}
|
|
61
|
+
get events$() {
|
|
62
|
+
return this.eventBus.events$;
|
|
63
|
+
}
|
|
64
|
+
get stable$() {
|
|
65
|
+
return this.eventBus.events$.pipe((0, rxjs_1.map)(() => !this._syncing && !this.modified), (0, rxjs_1.distinctUntilChanged)());
|
|
66
|
+
}
|
|
67
|
+
get state() {
|
|
68
|
+
return this._state;
|
|
69
|
+
}
|
|
70
|
+
set state(state) {
|
|
71
|
+
// skip if unchanged
|
|
72
|
+
if (this._state === state) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// update state
|
|
76
|
+
this._state = state;
|
|
77
|
+
this._modifiedOn = Date.now();
|
|
78
|
+
// raise change
|
|
79
|
+
this.raiseEvent('changed');
|
|
80
|
+
}
|
|
81
|
+
get modified() {
|
|
82
|
+
const { _deletedBlocks, initialSlug, _slug, initialPublication, _publication, initialTags, _tags, items } = this;
|
|
83
|
+
return _deletedBlocks.length > 0
|
|
84
|
+
|| initialSlug !== _slug
|
|
85
|
+
|| initialPublication !== _publication
|
|
86
|
+
|| initialTags.symmetricDifference(_tags).size > 0
|
|
87
|
+
|| items.some(item => item.modified);
|
|
88
|
+
}
|
|
89
|
+
get updatedOn() {
|
|
90
|
+
return this._updatedOn;
|
|
91
|
+
}
|
|
92
|
+
get changes() {
|
|
93
|
+
return {
|
|
94
|
+
page: this,
|
|
95
|
+
items: this.items.filter(item => item instanceof components_1.Section
|
|
96
|
+
? item.changes.blocks.length > 0
|
|
97
|
+
: item.changes.fields.length > 0)
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
get published() {
|
|
101
|
+
return this.publishedOn !== undefined;
|
|
102
|
+
}
|
|
103
|
+
get type() {
|
|
104
|
+
return this.template.type;
|
|
105
|
+
}
|
|
106
|
+
get syncing() {
|
|
107
|
+
return this._syncing;
|
|
108
|
+
}
|
|
109
|
+
set syncing(syncing) {
|
|
110
|
+
this._syncing = syncing;
|
|
111
|
+
this.raiseEvent('changed');
|
|
112
|
+
}
|
|
113
|
+
repair() {
|
|
114
|
+
// repair all content blocks
|
|
115
|
+
this.blocks.forEach(block => block.repair());
|
|
116
|
+
}
|
|
117
|
+
get url() {
|
|
118
|
+
return this._url;
|
|
119
|
+
}
|
|
120
|
+
get initialSlug() {
|
|
121
|
+
return this._initialSlug;
|
|
122
|
+
}
|
|
123
|
+
get hasSlug() {
|
|
124
|
+
return this.template.variant === 'dynamic';
|
|
125
|
+
}
|
|
126
|
+
set slug(slug) {
|
|
127
|
+
// stop static pages from setting slugs
|
|
128
|
+
if (!this.hasSlug) {
|
|
129
|
+
throw new funnel_core_1.InvalidOperationError('Cannot set slug on static page');
|
|
130
|
+
}
|
|
131
|
+
// or from being unset
|
|
132
|
+
else if (!slug) {
|
|
133
|
+
throw new funnel_core_1.ArgumentError('Slug cannot be unset');
|
|
134
|
+
}
|
|
135
|
+
// ignore if unchanged
|
|
136
|
+
else if (this._slug === slug) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
// update slug
|
|
140
|
+
this._slug = slug;
|
|
141
|
+
this._modifiedOn = Date.now();
|
|
142
|
+
// raise change
|
|
143
|
+
this.raiseEvent('modified');
|
|
144
|
+
}
|
|
145
|
+
get slug() {
|
|
146
|
+
return this._slug;
|
|
147
|
+
}
|
|
148
|
+
get initialName() {
|
|
149
|
+
return this._initialName;
|
|
150
|
+
}
|
|
151
|
+
get name() {
|
|
152
|
+
return this._name;
|
|
153
|
+
}
|
|
154
|
+
set name(name) {
|
|
155
|
+
// ignore if unchanged
|
|
156
|
+
if (this._name === name) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
// update name
|
|
160
|
+
this._name = name;
|
|
161
|
+
this._modifiedOn = Date.now();
|
|
162
|
+
// raise change
|
|
163
|
+
this.raiseEvent('modified');
|
|
164
|
+
}
|
|
165
|
+
get initialPublication() {
|
|
166
|
+
return this._initialPublication;
|
|
167
|
+
}
|
|
168
|
+
get publication() {
|
|
169
|
+
return this._publication;
|
|
170
|
+
}
|
|
171
|
+
set publication(publication) {
|
|
172
|
+
// ignore if unchanged
|
|
173
|
+
if (this._publication === publication) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
// update name
|
|
177
|
+
this._publication = publication;
|
|
178
|
+
this._modifiedOn = Date.now();
|
|
179
|
+
// raise change
|
|
180
|
+
this.raiseEvent('modified');
|
|
181
|
+
}
|
|
182
|
+
get initialErrors() {
|
|
183
|
+
return this._initialErrors;
|
|
184
|
+
}
|
|
185
|
+
get errors() {
|
|
186
|
+
return {
|
|
187
|
+
page: this,
|
|
188
|
+
items: this.items.filter(item => (!item.activated && item.required)
|
|
189
|
+
|| (item.activated && !item.valid))
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
get valid() {
|
|
193
|
+
return this.errors.items.length === 0;
|
|
194
|
+
}
|
|
195
|
+
get hasErrors() {
|
|
196
|
+
return this.errors.items.length > 0;
|
|
197
|
+
}
|
|
198
|
+
get asRef() {
|
|
199
|
+
const { id, groupId, template, brand, region, language, slug, url, name, tags, state, hasErrors, createdOn, updatedOn, publishedOn } = this;
|
|
200
|
+
return {
|
|
201
|
+
id, groupId, template,
|
|
202
|
+
brand, region, language, slug, url, name, tags: Array.from(tags),
|
|
203
|
+
state, errors: hasErrors, createdOn, updatedOn, publishedOn
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
get discover() {
|
|
207
|
+
return this._discover;
|
|
208
|
+
}
|
|
209
|
+
get seo() {
|
|
210
|
+
// get seo (or blow up)
|
|
211
|
+
const seo = this.discover.find(block => block.key === 'seo');
|
|
212
|
+
if (!seo) {
|
|
213
|
+
throw new funnel_core_1.IllegalStateError('Failed to resolve SEO block - should always exist');
|
|
214
|
+
}
|
|
215
|
+
// return seo
|
|
216
|
+
return seo;
|
|
217
|
+
}
|
|
218
|
+
getPreviewBlock() {
|
|
219
|
+
// get preview block identifier
|
|
220
|
+
const previewBlockIdentifier = this.template.preview;
|
|
221
|
+
// bail if no identifier specified
|
|
222
|
+
if (!previewBlockIdentifier) {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
// otherwise try to get the preview block
|
|
226
|
+
return this.getBlock(previewBlockIdentifier);
|
|
227
|
+
}
|
|
228
|
+
get content() {
|
|
229
|
+
return this._content;
|
|
230
|
+
}
|
|
231
|
+
get blocks() {
|
|
232
|
+
return this.content
|
|
233
|
+
.flatMap((item) => item instanceof components_1.Section ? item.blocks : item);
|
|
234
|
+
}
|
|
235
|
+
get deleteBlocks() {
|
|
236
|
+
return this._deletedBlocks;
|
|
237
|
+
}
|
|
238
|
+
get firstBlock() {
|
|
239
|
+
// find first block
|
|
240
|
+
for (const item of this.content) {
|
|
241
|
+
// return item if it matches
|
|
242
|
+
if (item instanceof components_1.Block) {
|
|
243
|
+
return item;
|
|
244
|
+
}
|
|
245
|
+
// search deeply into sections
|
|
246
|
+
else {
|
|
247
|
+
const { blocks } = item;
|
|
248
|
+
if (blocks.length > 0) {
|
|
249
|
+
return blocks[0];
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// or return undefined
|
|
254
|
+
return undefined;
|
|
255
|
+
}
|
|
256
|
+
get firstItem() {
|
|
257
|
+
return this.content[0];
|
|
258
|
+
}
|
|
259
|
+
get items() {
|
|
260
|
+
return [...this._discover, ...this._content];
|
|
261
|
+
}
|
|
262
|
+
get assets() {
|
|
263
|
+
return this._assets;
|
|
264
|
+
}
|
|
265
|
+
get collections() {
|
|
266
|
+
return this._collections;
|
|
267
|
+
}
|
|
268
|
+
get pages() {
|
|
269
|
+
return this._pages;
|
|
270
|
+
}
|
|
271
|
+
get initialTags() {
|
|
272
|
+
return this._initialTags;
|
|
273
|
+
}
|
|
274
|
+
get tagGroups() {
|
|
275
|
+
return this.template.tags;
|
|
276
|
+
}
|
|
277
|
+
get tags() {
|
|
278
|
+
return this._tags;
|
|
279
|
+
}
|
|
280
|
+
hydrateStores(references) {
|
|
281
|
+
this._assets.push(...references.assets);
|
|
282
|
+
this._pages.push(...references.pages);
|
|
283
|
+
this._collections.push(...references.collections);
|
|
284
|
+
}
|
|
285
|
+
getItem(identifier) {
|
|
286
|
+
// skip if there's no identifier
|
|
287
|
+
if (!identifier) {
|
|
288
|
+
return undefined;
|
|
289
|
+
}
|
|
290
|
+
// or return settings
|
|
291
|
+
else if (identifier === components_1.PageSettings.id) {
|
|
292
|
+
return this.settings;
|
|
293
|
+
}
|
|
294
|
+
// search content for item
|
|
295
|
+
for (const item of this.items) {
|
|
296
|
+
// return item if it matches
|
|
297
|
+
if (item.identifier === identifier) {
|
|
298
|
+
return item;
|
|
299
|
+
}
|
|
300
|
+
// search deeply into sections
|
|
301
|
+
if (item instanceof components_1.Section) {
|
|
302
|
+
for (const block of item.blocks) {
|
|
303
|
+
// return block if it matches
|
|
304
|
+
if (block.identifier === identifier) {
|
|
305
|
+
return block;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// or return undefined
|
|
311
|
+
return undefined;
|
|
312
|
+
}
|
|
313
|
+
coerceItem(identifier) {
|
|
314
|
+
var _a, _b;
|
|
315
|
+
return (_b = (_a = this.getItem(identifier)) !== null && _a !== void 0 ? _a : this.firstBlock) !== null && _b !== void 0 ? _b : this.firstItem;
|
|
316
|
+
}
|
|
317
|
+
deleteBlock(area, key) {
|
|
318
|
+
// get parent
|
|
319
|
+
let parent;
|
|
320
|
+
switch (area) {
|
|
321
|
+
case 'discover':
|
|
322
|
+
parent = this._discover;
|
|
323
|
+
break;
|
|
324
|
+
case 'content':
|
|
325
|
+
parent = this._content;
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
// skip if item isn't in parent
|
|
329
|
+
const blockIndex = parent.findIndex(item => item.key === key);
|
|
330
|
+
if (!blockIndex) {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
// remove item
|
|
334
|
+
const [deletedBlock] = parent.splice(blockIndex, 1);
|
|
335
|
+
this._modifiedOn = Date.now();
|
|
336
|
+
// track deletion of top-level blocks
|
|
337
|
+
if (deletedBlock instanceof components_1.Block) {
|
|
338
|
+
console.debug('Removing deleted block', deletedBlock);
|
|
339
|
+
this._deletedBlocks.push(deletedBlock);
|
|
340
|
+
}
|
|
341
|
+
// raise change
|
|
342
|
+
this.raiseEvent('modified');
|
|
343
|
+
// indicate success
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
getAsset(assetId) {
|
|
347
|
+
return this._assets.find((asset) => asset.value.id === assetId);
|
|
348
|
+
}
|
|
349
|
+
getAssetScope(range) {
|
|
350
|
+
switch (range) {
|
|
351
|
+
case 'global':
|
|
352
|
+
return funnel_core_1.Schema.AssetScope.global;
|
|
353
|
+
case 'type':
|
|
354
|
+
return new funnel_core_1.Schema.PageTypeAssetScope(this.type);
|
|
355
|
+
case 'instance':
|
|
356
|
+
return new funnel_core_1.Schema.PageInstanceAssetScope(this.groupId);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
getSearchScope() {
|
|
360
|
+
return {
|
|
361
|
+
target: 'page',
|
|
362
|
+
type: this.type,
|
|
363
|
+
groupId: this.groupId
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
addAsset(asset) {
|
|
367
|
+
// replace asset if it exists
|
|
368
|
+
const { _assets } = this;
|
|
369
|
+
const { id } = asset.value;
|
|
370
|
+
const assetIndex = _assets.findIndex(asset => asset.value.id === id);
|
|
371
|
+
if (assetIndex >= 0) {
|
|
372
|
+
_assets[assetIndex] = asset;
|
|
373
|
+
}
|
|
374
|
+
// or add asset
|
|
375
|
+
else {
|
|
376
|
+
_assets.push(asset);
|
|
377
|
+
}
|
|
378
|
+
// raise event
|
|
379
|
+
this.raiseEvent('changed');
|
|
380
|
+
}
|
|
381
|
+
removeAsset(assetId) {
|
|
382
|
+
// skip if asset isn't there
|
|
383
|
+
const { _assets } = this;
|
|
384
|
+
const assetIndex = _assets.findIndex(asset => asset.value.id === assetId);
|
|
385
|
+
if (assetIndex < 0) {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
// remove asset
|
|
389
|
+
_assets.splice(assetIndex, 1);
|
|
390
|
+
// raise event
|
|
391
|
+
this.raiseEvent('changed');
|
|
392
|
+
// indicate success
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
getCollection(collectionId) {
|
|
396
|
+
return this._collections.find(collection => collection.id === collectionId);
|
|
397
|
+
}
|
|
398
|
+
addCollection(collection) {
|
|
399
|
+
// replace collection if it exists
|
|
400
|
+
const { _collections } = this;
|
|
401
|
+
const collectionId = collection.id;
|
|
402
|
+
const collectionIndex = _collections.findIndex(collection => collection.id === collectionId);
|
|
403
|
+
if (collectionIndex >= 0) {
|
|
404
|
+
_collections[collectionIndex] = collection;
|
|
405
|
+
}
|
|
406
|
+
// or add collection
|
|
407
|
+
else {
|
|
408
|
+
_collections.push(collection);
|
|
409
|
+
}
|
|
410
|
+
// raise event
|
|
411
|
+
this.raiseEvent('changed');
|
|
412
|
+
}
|
|
413
|
+
removeCollection(collectionId) {
|
|
414
|
+
// skip if collection isn't there
|
|
415
|
+
const { _collections } = this;
|
|
416
|
+
const collectionIndex = _collections.findIndex(collection => collection.id === collectionId);
|
|
417
|
+
if (collectionIndex < 0) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
// remove collection
|
|
421
|
+
const [collection] = _collections.splice(collectionIndex, 1);
|
|
422
|
+
// raise event
|
|
423
|
+
this.raiseEvent('changed');
|
|
424
|
+
// indicate success
|
|
425
|
+
return true;
|
|
426
|
+
}
|
|
427
|
+
getPageRef(pageId) {
|
|
428
|
+
return pageId && pageId !== funnel_core_1.Schema.Page.Id.draft
|
|
429
|
+
? this._pages.find((ref) => ref.id === pageId)
|
|
430
|
+
: undefined;
|
|
431
|
+
}
|
|
432
|
+
addPageRef(ref) {
|
|
433
|
+
// throw if page is a draft
|
|
434
|
+
if (ref.id === funnel_core_1.Schema.Page.Id.draft) {
|
|
435
|
+
throw new funnel_core_1.InvalidOperationError('Cannot add draft Page as reference');
|
|
436
|
+
}
|
|
437
|
+
// replace ref if it exists
|
|
438
|
+
const { _pages } = this;
|
|
439
|
+
const pageId = ref.id;
|
|
440
|
+
const refIndex = _pages.findIndex(ref => ref.id === pageId);
|
|
441
|
+
if (refIndex >= 0) {
|
|
442
|
+
_pages[refIndex] = ref;
|
|
443
|
+
}
|
|
444
|
+
// or add ref
|
|
445
|
+
else {
|
|
446
|
+
_pages.push(ref);
|
|
447
|
+
}
|
|
448
|
+
// raise event
|
|
449
|
+
this.raiseEvent('changed');
|
|
450
|
+
}
|
|
451
|
+
removePageRef(pageId) {
|
|
452
|
+
// skip if file isn't there
|
|
453
|
+
const { _pages } = this;
|
|
454
|
+
const refIndex = _pages.findIndex(ref => ref.id === pageId);
|
|
455
|
+
if (refIndex < 0) {
|
|
456
|
+
return false;
|
|
457
|
+
}
|
|
458
|
+
// remove file
|
|
459
|
+
_pages.splice(refIndex, 1);
|
|
460
|
+
// raise event
|
|
461
|
+
this.raiseEvent('changed');
|
|
462
|
+
// indicate success
|
|
463
|
+
return true;
|
|
464
|
+
}
|
|
465
|
+
addTag(tag) {
|
|
466
|
+
throw new Error('Method not implemented.');
|
|
467
|
+
}
|
|
468
|
+
removeTag(tag) {
|
|
469
|
+
throw new Error('Method not implemented.');
|
|
470
|
+
}
|
|
471
|
+
onSaveStart() {
|
|
472
|
+
this._savingOn = Date.now();
|
|
473
|
+
}
|
|
474
|
+
onSaveComplete(updatedOn) {
|
|
475
|
+
// update fundamentals
|
|
476
|
+
this._updatedOn = updatedOn;
|
|
477
|
+
this._state = 'draft';
|
|
478
|
+
// reset to values to match save
|
|
479
|
+
const { _modifiedOn, _savingOn } = this;
|
|
480
|
+
if (_savingOn && (!_modifiedOn || _savingOn >= _modifiedOn)) {
|
|
481
|
+
// sync data
|
|
482
|
+
this._initialErrors = !this.valid;
|
|
483
|
+
this._initialSlug = this._slug;
|
|
484
|
+
this._initialName = this._name;
|
|
485
|
+
this._initialTags = new Set(this._tags);
|
|
486
|
+
this._initialPublication = this._publication;
|
|
487
|
+
this._deletedBlocks = [];
|
|
488
|
+
}
|
|
489
|
+
// clear saving flag
|
|
490
|
+
delete this._savingOn;
|
|
491
|
+
}
|
|
492
|
+
getBlock(identifier) {
|
|
493
|
+
// try to find item
|
|
494
|
+
const item = this.getItem(identifier);
|
|
495
|
+
// make sure it is a block
|
|
496
|
+
if (item instanceof components_1.Block) {
|
|
497
|
+
return item;
|
|
498
|
+
}
|
|
499
|
+
// otherwise undefined
|
|
500
|
+
else {
|
|
501
|
+
return undefined;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
raiseEvent(type) {
|
|
505
|
+
this.eventBus.publish(components_1.IPage.Event.create({ type, page: this }));
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
exports.Page = Page;
|
|
509
|
+
// extension
|
|
510
|
+
(function (Page) {
|
|
511
|
+
function fromSchemaData({ data, references, eventBus }) {
|
|
512
|
+
// setup
|
|
513
|
+
const { snapshot, discover, content, tags } = data, pageArgs = __rest(data, ["snapshot", "discover", "content", "tags"]);
|
|
514
|
+
const { files = {}, collections = {}, pages = {} } = references !== null && references !== void 0 ? references : {};
|
|
515
|
+
const { discover: discoverSnapshot = {}, content: contentSnapshot = {} } = snapshot !== null && snapshot !== void 0 ? snapshot : {};
|
|
516
|
+
const template = funnel_core_1.Schema.Site.getPage(data.type, data.region);
|
|
517
|
+
eventBus = eventBus !== null && eventBus !== void 0 ? eventBus : new funnel_core_1.EventBus();
|
|
518
|
+
// create page
|
|
519
|
+
return new Page(Object.assign(Object.assign({}, pageArgs), { eventBus,
|
|
520
|
+
template, tags: components_1.TagSerializer.deserializeTags({
|
|
521
|
+
groups: template.tags,
|
|
522
|
+
tagsData: tags !== null && tags !== void 0 ? tags : []
|
|
523
|
+
}), discover: [
|
|
524
|
+
components_1.PageSerializer.deserializeBlock({
|
|
525
|
+
schema: funnel_core_1.Schema.Seo,
|
|
526
|
+
eventBus,
|
|
527
|
+
key: 'seo',
|
|
528
|
+
content: discover['seo'],
|
|
529
|
+
snapshot: discoverSnapshot['seo']
|
|
530
|
+
})
|
|
531
|
+
], content: Object.entries(template.content).map(([key, schema]) => components_1.PageSerializer.deserializeContent({
|
|
532
|
+
key,
|
|
533
|
+
schema: schema.unwrap(),
|
|
534
|
+
eventBus,
|
|
535
|
+
content: content[key],
|
|
536
|
+
snapshot: contentSnapshot[key],
|
|
537
|
+
})), files: Object.values(files), collections: Object.values(collections), pages: Object.values(pages) }));
|
|
538
|
+
}
|
|
539
|
+
Page.fromSchemaData = fromSchemaData;
|
|
540
|
+
function toUpdates(page, savables) {
|
|
541
|
+
var _a, _b;
|
|
542
|
+
// root page updates
|
|
543
|
+
const { id, discover, content } = page;
|
|
544
|
+
const rootPageUpdates = [];
|
|
545
|
+
// name
|
|
546
|
+
if (page.initialName !== page.name) {
|
|
547
|
+
rootPageUpdates.push({
|
|
548
|
+
type: 'page',
|
|
549
|
+
property: 'name',
|
|
550
|
+
value: page.name
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
// tags
|
|
554
|
+
if (page.initialTags.symmetricDifference(page.tags).size > 0) {
|
|
555
|
+
rootPageUpdates.push({
|
|
556
|
+
type: 'page',
|
|
557
|
+
property: 'tags',
|
|
558
|
+
value: Array.from(page.tags).map(tag => tag.data)
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
// slug + url
|
|
562
|
+
if (page.initialSlug !== page.slug) {
|
|
563
|
+
rootPageUpdates.push({
|
|
564
|
+
type: 'page',
|
|
565
|
+
property: 'slug',
|
|
566
|
+
value: (_a = page.slug) !== null && _a !== void 0 ? _a : null
|
|
567
|
+
});
|
|
568
|
+
rootPageUpdates.push({
|
|
569
|
+
type: 'page',
|
|
570
|
+
property: 'url',
|
|
571
|
+
value: page.url
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
// preview
|
|
575
|
+
const previewBlock = page.getPreviewBlock();
|
|
576
|
+
if (previewBlock && previewBlock.modified) {
|
|
577
|
+
rootPageUpdates.push({
|
|
578
|
+
type: 'page',
|
|
579
|
+
property: 'preview',
|
|
580
|
+
value: previewBlock.value
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
// errors
|
|
584
|
+
if (page.initialErrors !== !page.valid) {
|
|
585
|
+
rootPageUpdates.push({
|
|
586
|
+
type: 'page',
|
|
587
|
+
property: 'errors',
|
|
588
|
+
value: !page.valid
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
// publication
|
|
592
|
+
if (page.initialPublication !== page.publication) {
|
|
593
|
+
rootPageUpdates.push({
|
|
594
|
+
type: 'page',
|
|
595
|
+
property: 'publication',
|
|
596
|
+
value: (_b = page.publication) !== null && _b !== void 0 ? _b : null
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
// aggregate other updates
|
|
600
|
+
return {
|
|
601
|
+
id,
|
|
602
|
+
updatedOn: page.updatedOn,
|
|
603
|
+
updates: [
|
|
604
|
+
...rootPageUpdates,
|
|
605
|
+
...discover.reduce((updates, block) => {
|
|
606
|
+
// try to update block
|
|
607
|
+
components_1.SerializePageUpdate.serializeBlockUpdate(updates, block, 'discover', savables);
|
|
608
|
+
// keep reducing
|
|
609
|
+
return updates;
|
|
610
|
+
}, []),
|
|
611
|
+
...content.reduce((updates, item) => {
|
|
612
|
+
// handle block
|
|
613
|
+
if (item instanceof components_1.Block) {
|
|
614
|
+
components_1.SerializePageUpdate.serializeBlockUpdate(updates, item, 'content', savables);
|
|
615
|
+
}
|
|
616
|
+
// or section
|
|
617
|
+
else {
|
|
618
|
+
components_1.SerializePageUpdate.serializeSectionUpdate(updates, item, 'content', savables);
|
|
619
|
+
}
|
|
620
|
+
// keep reducing
|
|
621
|
+
return updates;
|
|
622
|
+
}, []),
|
|
623
|
+
...page.deleteBlocks.map(block => ({
|
|
624
|
+
type: 'block.delete',
|
|
625
|
+
path: [block.area, block.key]
|
|
626
|
+
}))
|
|
627
|
+
]
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
Page.toUpdates = toUpdates;
|
|
631
|
+
})(Page || (exports.Page = Page = {}));
|
package/dist/page/index.d.ts
CHANGED
package/dist/page/index.js
CHANGED
|
@@ -14,4 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./domain"), exports);
|
|
18
|
+
__exportStar(require("./repository"), exports);
|
|
17
19
|
__exportStar(require("./screens"), exports);
|
|
20
|
+
__exportStar(require("./controller"), exports);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { EditorAppSDK, EntrySys } from '@contentful/app-sdk';
|
|
2
|
+
import { ContentfulContentClient } from '@nascentdigital/funnel-cms/contentful';
|
|
3
|
+
import { Schema } from '@nascentdigital/funnel-core';
|
|
4
|
+
import { IPage, IPageRepository, PageSummary } from '@nascentdigital/funnel-editor/components';
|
|
5
|
+
import { Page } from '../domain';
|
|
6
|
+
export declare class PageRepository implements IPageRepository {
|
|
7
|
+
readonly sdk: EditorAppSDK;
|
|
8
|
+
readonly contentfulClient: ContentfulContentClient;
|
|
9
|
+
constructor(args: PageRepository.ConstructorArgs);
|
|
10
|
+
search(args: IPageRepository.Search.Args): Promise<IPageRepository.Search.Result>;
|
|
11
|
+
getOverview({ region }: IPageRepository.GetOverview.Args): Promise<IPageRepository.GetOverview.Result>;
|
|
12
|
+
create(args: IPageRepository.Create.Args): Promise<IPageRepository.Create.Result>;
|
|
13
|
+
createLanguage(args: IPageRepository.CreateLang.Args): Promise<IPageRepository.CreateLang.Result>;
|
|
14
|
+
load(sys?: EntrySys): Promise<PageRepository.Load.Result>;
|
|
15
|
+
save(page: Page): Promise<Page>;
|
|
16
|
+
sync({ page, sys }: PageRepository.Sync.Args): Promise<PageRepository.Sync.Result>;
|
|
17
|
+
unpublish(page: IPage): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
export declare namespace PageRepository {
|
|
20
|
+
type ConstructorArgs = {
|
|
21
|
+
sdk: EditorAppSDK;
|
|
22
|
+
contentfulClient: ContentfulContentClient;
|
|
23
|
+
};
|
|
24
|
+
namespace Load {
|
|
25
|
+
type Args = {
|
|
26
|
+
pageId?: Schema.Page.Id;
|
|
27
|
+
};
|
|
28
|
+
type Result = {
|
|
29
|
+
pageSummary: PageSummary;
|
|
30
|
+
page: Page;
|
|
31
|
+
sys: EntrySys;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
namespace Sync {
|
|
35
|
+
type Args = {
|
|
36
|
+
page: Page;
|
|
37
|
+
sys: EntrySys;
|
|
38
|
+
};
|
|
39
|
+
type Result = {
|
|
40
|
+
pageSummary?: PageSummary;
|
|
41
|
+
page: Page;
|
|
42
|
+
sys: EntrySys;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|