@nascentdigital/funnel-editor-contentful 5.0.1 → 5.0.3
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 +11 -9
- package/dist/EditorPageRouter.d.ts +1 -0
- package/dist/EditorPageRouter.js +34 -0
- package/dist/EditorPageRoutes.d.ts +1 -0
- package/dist/EditorPageRoutes.js +16 -0
- package/dist/EntryEditor.js +30 -29
- package/dist/EntrySidebar.js +26 -5
- package/dist/NotFound.d.ts +1 -0
- package/dist/NotFound.js +18 -0
- package/dist/asset/index.d.ts +1 -0
- package/dist/{core/api → asset}/index.js +1 -3
- package/dist/{core → asset}/repository/AssetRepository.d.ts +11 -3
- package/dist/{core → asset}/repository/AssetRepository.js +6 -5
- package/dist/asset/repository/index.d.ts +1 -0
- package/dist/{core → asset}/repository/index.js +0 -4
- package/dist/collection/controller/{LocalCollectionController.d.ts → ContentfulCollectionController.d.ts} +17 -11
- 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 -4
- package/dist/collection/controller/index.js +3 -4
- package/dist/collection/controller/useContentfulCollectionController.d.ts +2 -0
- package/dist/collection/controller/useContentfulCollectionController.js +8 -0
- package/dist/{core → collection}/domain/Collection.d.ts +11 -2
- package/dist/{core → collection}/domain/Collection.js +76 -0
- package/dist/{core → collection}/domain/index.d.ts +0 -1
- package/dist/{core → collection}/domain/index.js +0 -1
- package/dist/collection/index.d.ts +1 -0
- package/dist/collection/index.js +1 -0
- package/dist/collection/repository/CollectionRepository.d.ts +49 -0
- package/dist/collection/repository/CollectionRepository.js +223 -0
- package/dist/collection/repository/index.d.ts +1 -0
- package/dist/{core/contentful → collection/repository}/index.js +1 -5
- package/dist/collection/screens/CollectionEditor.js +23 -6
- package/dist/core/bridge/AppBridge.d.ts +31 -0
- package/dist/core/bridge/AppBridge.js +160 -0
- package/dist/core/bridge/AppBridgeContainer.d.ts +3 -3
- package/dist/core/bridge/AppBridgeContainer.js +8 -44
- package/dist/core/bridge/AppBridgeContext.d.ts +7 -8
- package/dist/core/bridge/AppBridgeContext.js +1 -6
- package/dist/core/bridge/BridgeLifecycleMessage.d.ts +7 -0
- package/dist/core/bridge/BridgeLifecycleMessage.js +12 -0
- package/dist/core/bridge/IAppBridgeMessage.d.ts +16 -0
- package/dist/core/bridge/IAppBridgeMessage.js +12 -0
- package/dist/core/bridge/index.d.ts +2 -1
- package/dist/core/bridge/index.js +2 -1
- package/dist/core/bridge/useAppBridge.d.ts +2 -8
- package/dist/core/bridge/useAppBridge.js +24 -15
- 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/index.d.ts +1 -4
- package/dist/core/index.js +1 -4
- package/dist/explore/components/header/Header.d.ts +14 -0
- package/dist/explore/components/header/Header.js +33 -0
- package/dist/explore/components/header/HeaderActions.d.ts +8 -0
- package/dist/explore/components/header/HeaderActions.js +37 -0
- package/dist/explore/components/header/HeaderContainer.d.ts +2 -0
- package/dist/explore/components/header/HeaderContainer.js +15 -0
- package/dist/explore/components/header/HeaderContext.d.ts +7 -0
- package/dist/{core/api/EditorApiContext.js → explore/components/header/HeaderContext.js} +2 -2
- package/dist/explore/components/header/HeaderController.d.ts +39 -0
- package/dist/explore/components/header/HeaderController.js +100 -0
- package/dist/explore/components/header/HeaderOptions.d.ts +10 -0
- package/dist/explore/components/header/HeaderOptions.js +26 -0
- package/dist/explore/components/header/index.d.ts +5 -0
- package/dist/explore/components/header/index.js +21 -0
- package/dist/explore/components/header/useHeader.d.ts +2 -0
- package/dist/explore/components/header/useHeader.js +30 -0
- package/dist/explore/components/index.d.ts +2 -0
- package/dist/explore/components/index.js +18 -0
- package/dist/explore/components/pages/PagesExplorerLayout.d.ts +4 -0
- package/dist/explore/components/pages/PagesExplorerLayout.js +28 -0
- package/dist/explore/components/pages/index.d.ts +1 -0
- package/dist/explore/components/pages/index.js +17 -0
- package/dist/explore/index.d.ts +2 -0
- package/dist/explore/index.js +18 -0
- package/dist/explore/screens/Dashboard.d.ts +4 -0
- package/dist/explore/screens/Dashboard.js +55 -0
- package/dist/explore/screens/PageExplorer.d.ts +11 -0
- package/dist/explore/screens/PageExplorer.js +129 -0
- package/dist/explore/screens/PagesExplorer.d.ts +7 -0
- package/dist/explore/screens/PagesExplorer.js +98 -0
- package/dist/explore/screens/index.d.ts +3 -0
- package/dist/explore/screens/index.js +19 -0
- package/dist/page/bridge/BlockChangedMessage.d.ts +25 -0
- package/dist/page/bridge/BlockChangedMessage.js +18 -0
- package/dist/page/bridge/PageBridgeHub.d.ts +8 -0
- package/dist/page/bridge/PageBridgeHub.js +51 -0
- package/dist/page/bridge/index.d.ts +2 -0
- package/dist/page/bridge/index.js +18 -0
- package/dist/page/controller/{LocalPageController.d.ts → ContentfulPageController.d.ts} +15 -9
- 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 -3
- package/dist/page/controller/index.js +3 -3
- 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 +23 -12
- package/dist/{core → page}/domain/Page.js +139 -0
- package/dist/page/domain/index.d.ts +1 -0
- package/dist/page/domain/index.js +17 -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 +241 -0
- package/dist/page/repository/index.d.ts +1 -0
- package/dist/page/repository/index.js +17 -0
- package/dist/page/screens/PageEditor.js +36 -12
- package/package.json +9 -5
- package/dist/collection/controller/LocalCollectionController.js +0 -200
- package/dist/collection/controller/LocalCollectionControllerContainer.d.ts +0 -8
- package/dist/collection/controller/LocalCollectionControllerContainer.js +0 -36
- package/dist/collection/controller/LocalCollectionControllerContext.d.ts +0 -7
- package/dist/collection/controller/LocalCollectionControllerContext.js +0 -6
- package/dist/collection/controller/useLocalCollectionController.d.ts +0 -2
- package/dist/collection/controller/useLocalCollectionController.js +0 -10
- 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/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/bridge/AppMessage.d.ts +0 -19
- package/dist/core/bridge/AppMessage.js +0 -19
- package/dist/core/contentful/Contentful.d.ts +0 -33
- package/dist/core/contentful/Contentful.js +0 -67
- package/dist/core/contentful/ContentfulAsset.d.ts +0 -23
- package/dist/core/contentful/ContentfulAsset.js +0 -88
- package/dist/core/contentful/ContentfulCollection.d.ts +0 -29
- package/dist/core/contentful/ContentfulCollection.js +0 -97
- package/dist/core/contentful/ContentfulPage.d.ts +0 -31
- package/dist/core/contentful/ContentfulPage.js +0 -84
- package/dist/core/contentful/ContentfulRefs.d.ts +0 -16
- package/dist/core/contentful/ContentfulRefs.js +0 -152
- package/dist/core/contentful/index.d.ts +0 -5
- package/dist/core/repository/CollectionSerializer.d.ts +0 -9
- package/dist/core/repository/CollectionSerializer.js +0 -41
- package/dist/core/repository/LocalCollectionRepository.d.ts +0 -27
- package/dist/core/repository/LocalCollectionRepository.js +0 -143
- package/dist/core/repository/LocalPageRepository.d.ts +0 -16
- package/dist/core/repository/LocalPageRepository.js +0 -153
- package/dist/core/repository/PageSerializer.d.ts +0 -9
- package/dist/core/repository/PageSerializer.js +0 -47
- package/dist/core/repository/RemoteCollectionRepository.d.ts +0 -19
- package/dist/core/repository/RemoteCollectionRepository.js +0 -236
- package/dist/core/repository/RemotePageRepository.d.ts +0 -14
- package/dist/core/repository/RemotePageRepository.js +0 -113
- package/dist/core/repository/index.d.ts +0 -5
- package/dist/page/controller/LocalPageController.js +0 -190
- package/dist/page/controller/LocalPageControllerContainer.d.ts +0 -8
- package/dist/page/controller/LocalPageControllerContainer.js +0 -36
- package/dist/page/controller/LocalPageControllerContext.d.ts +0 -7
- package/dist/page/controller/LocalPageControllerContext.js +0 -6
- package/dist/page/controller/useLocalPageController.d.ts +0 -2
- package/dist/page/controller/useLocalPageController.js +0 -10
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentfulPageController = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
const components_1 = require("@nascentdigital/funnel-editor/components");
|
|
6
|
+
const rxjs_1 = require("rxjs");
|
|
7
|
+
// class
|
|
8
|
+
class ContentfulPageController {
|
|
9
|
+
constructor(args) {
|
|
10
|
+
// initialize instance variables
|
|
11
|
+
this.pageRepository = args.pageRepository;
|
|
12
|
+
this._eventBus = new funnel_core_1.EventBus();
|
|
13
|
+
this._state = 'uninitialized';
|
|
14
|
+
}
|
|
15
|
+
get events$() {
|
|
16
|
+
return this._eventBus.events$.pipe((0, rxjs_1.filter)((e) => components_1.IPageController.Event.filter(e) || components_1.IPage.Event.filter(e)));
|
|
17
|
+
}
|
|
18
|
+
get saved$() {
|
|
19
|
+
return this._eventBus.events$.pipe((0, rxjs_1.filter)(components_1.IPageController.StateChangedEvent.filter), (0, rxjs_1.pairwise)(), (0, rxjs_1.filter)(([previous, current]) => previous.state === 'saving' && current.state === 'ready'));
|
|
20
|
+
}
|
|
21
|
+
get state() {
|
|
22
|
+
return this._state;
|
|
23
|
+
}
|
|
24
|
+
set state(value) {
|
|
25
|
+
// skip if unchanged
|
|
26
|
+
if (this._state === value) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// or update
|
|
30
|
+
this._state = value;
|
|
31
|
+
// raise event
|
|
32
|
+
this._eventBus.publish(components_1.IPageController.StateChangedEvent.create({
|
|
33
|
+
state: value,
|
|
34
|
+
controller: this
|
|
35
|
+
}));
|
|
36
|
+
// process queues if ready (might be noop)
|
|
37
|
+
if (value === 'ready') {
|
|
38
|
+
this.processQueues().catch(console.error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
get ready() {
|
|
42
|
+
const { _state } = this;
|
|
43
|
+
return _state !== 'uninitialized' && _state !== 'initializing';
|
|
44
|
+
}
|
|
45
|
+
get languages() {
|
|
46
|
+
var _a, _b;
|
|
47
|
+
return (_b = (_a = this._pageSummary) === null || _a === void 0 ? void 0 : _a.pages.map(page => page.language)) !== null && _b !== void 0 ? _b : [];
|
|
48
|
+
}
|
|
49
|
+
get pageSummary() {
|
|
50
|
+
return this._pageSummary;
|
|
51
|
+
}
|
|
52
|
+
set pageSummary(pageSummary) {
|
|
53
|
+
// skip if summary is the same
|
|
54
|
+
if (this._pageSummary === pageSummary) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// update summary
|
|
58
|
+
this._pageSummary = pageSummary;
|
|
59
|
+
// raise event
|
|
60
|
+
this.raiseEvent('pageSummary.changed');
|
|
61
|
+
}
|
|
62
|
+
get page() {
|
|
63
|
+
return this._page;
|
|
64
|
+
}
|
|
65
|
+
set page(page) {
|
|
66
|
+
// skip if page is the same
|
|
67
|
+
if (this._page === page) {
|
|
68
|
+
console.debug('[ContentfulPageController/setPage] skipping page set, same instance');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// unbind previous page subscription (if any)
|
|
72
|
+
if (this._pageSubscription) {
|
|
73
|
+
this._pageSubscription.unsubscribe();
|
|
74
|
+
delete this._pageSubscription;
|
|
75
|
+
}
|
|
76
|
+
console.debug('[ContentfulPageController/setPage] new page instance set');
|
|
77
|
+
// update page
|
|
78
|
+
this._page = page;
|
|
79
|
+
// subscribe to page changes
|
|
80
|
+
if (page) {
|
|
81
|
+
// subscribe to page events
|
|
82
|
+
this._pageSubscription = page.events$
|
|
83
|
+
.pipe((0, rxjs_1.filter)(e => {
|
|
84
|
+
// handle page events
|
|
85
|
+
if (components_1.IPage.Event.filter(e)) {
|
|
86
|
+
return e.type === 'modified';
|
|
87
|
+
}
|
|
88
|
+
// or item/object/list events
|
|
89
|
+
else if (components_1.Item.Event.filter(e)
|
|
90
|
+
|| components_1.Item.Event.filter(e)
|
|
91
|
+
|| funnel_core_1.ObjectField.Event.filter(e)
|
|
92
|
+
|| funnel_core_1.FieldList.Event.filter(e)) {
|
|
93
|
+
return e.type === 'changed';
|
|
94
|
+
}
|
|
95
|
+
// or field
|
|
96
|
+
else {
|
|
97
|
+
return funnel_core_1.Field.Event.filter(e) && (e.type === 'changed' || e.type === 'reset');
|
|
98
|
+
}
|
|
99
|
+
}), (0, rxjs_1.debounce)(e => {
|
|
100
|
+
return (0, rxjs_1.interval)(1000);
|
|
101
|
+
}))
|
|
102
|
+
.subscribe(async (e) => {
|
|
103
|
+
if (page.modified && this._page === page) {
|
|
104
|
+
await this.save(page);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// raise state change
|
|
109
|
+
this.raiseEvent('page.changed');
|
|
110
|
+
}
|
|
111
|
+
get pageSys() {
|
|
112
|
+
return this._pageSys;
|
|
113
|
+
}
|
|
114
|
+
set pageSys(sys) {
|
|
115
|
+
this._pageSys = sys;
|
|
116
|
+
}
|
|
117
|
+
async sync(updatedSys) {
|
|
118
|
+
// skip if there's no active page/sys
|
|
119
|
+
const { page, pageSys, state, pageRepository } = this;
|
|
120
|
+
if (!page || !pageSys) {
|
|
121
|
+
console.warn('[ContentfulPageController/sync] ignoring update before initial load');
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// or skip if page version is unchanged
|
|
125
|
+
else if (page.id === updatedSys.id && pageSys.version >= updatedSys.version) {
|
|
126
|
+
console.debug('[ContentfulPageController/sync] ignoring update - current version is fresh');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// or ignore if booting up
|
|
130
|
+
else if (state === 'uninitialized' || state === 'initializing' || state === 'loading') {
|
|
131
|
+
console.debug('[ContentfulPageController/sync] ignoring sync while loading');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// or queue if saving
|
|
135
|
+
else if (this.state === 'saving') {
|
|
136
|
+
console.debug('[ContentfulPageController/sync] queueing page sync - updated while saving');
|
|
137
|
+
this._queuedSync = updatedSys;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
// try to sync
|
|
141
|
+
try {
|
|
142
|
+
console.debug('[ContentfulPageController/sync] starting sync');
|
|
143
|
+
// update state
|
|
144
|
+
this.state = 'loading';
|
|
145
|
+
// perform sync
|
|
146
|
+
const result = await pageRepository.sync({ page, sys: updatedSys });
|
|
147
|
+
// update sys
|
|
148
|
+
this.pageSys = result.sys;
|
|
149
|
+
// update page (if unchanged)
|
|
150
|
+
if (this.page !== result.page) {
|
|
151
|
+
this.page = result.page;
|
|
152
|
+
}
|
|
153
|
+
// update summary (if any)
|
|
154
|
+
if (result.pageSummary) {
|
|
155
|
+
this.pageSummary = result.pageSummary;
|
|
156
|
+
}
|
|
157
|
+
console.debug('[ContentfulPageController/sync] sync complete');
|
|
158
|
+
// clear state
|
|
159
|
+
this.state = 'ready';
|
|
160
|
+
}
|
|
161
|
+
// catch error
|
|
162
|
+
catch (e) {
|
|
163
|
+
console.error('[ContentfulPageController/sync] sync failed', e);
|
|
164
|
+
this.state = 'error';
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async load() {
|
|
168
|
+
// mark as loading (or initialing if loading for first time)
|
|
169
|
+
this.state = this._state === 'uninitialized'
|
|
170
|
+
? 'initializing'
|
|
171
|
+
: 'loading';
|
|
172
|
+
// try to load page
|
|
173
|
+
try {
|
|
174
|
+
// fetch page
|
|
175
|
+
const { pageSummary, page, sys } = await this.pageRepository.load();
|
|
176
|
+
console.debug('[ContentfulPageController/load] fetched page', { pageSummary, page, sys });
|
|
177
|
+
// set page/summary
|
|
178
|
+
this.pageSummary = pageSummary;
|
|
179
|
+
this.page = page;
|
|
180
|
+
this._pageSys = sys;
|
|
181
|
+
// update state
|
|
182
|
+
this.state = 'ready';
|
|
183
|
+
}
|
|
184
|
+
// handle error
|
|
185
|
+
catch (e) {
|
|
186
|
+
console.error('[ContentfulPageController/load] failed to load page', e);
|
|
187
|
+
// set error state
|
|
188
|
+
this.state = 'error';
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async create(target) {
|
|
192
|
+
throw new funnel_core_1.NotImplementedError();
|
|
193
|
+
}
|
|
194
|
+
async save(page) {
|
|
195
|
+
// ignore if not ready
|
|
196
|
+
if (this._state !== 'ready') {
|
|
197
|
+
console.debug(`[ContentfulPageController/save] queuing save while in "${this._state}" state`);
|
|
198
|
+
this._queuedSave = page;
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
// clear save if queued
|
|
202
|
+
delete this._queuedSave;
|
|
203
|
+
// skip if page isn't modified
|
|
204
|
+
if (!page.modified) {
|
|
205
|
+
console.debug('[ContentfulPageController/save] ignore unmodified page');
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
// try to save page
|
|
209
|
+
try {
|
|
210
|
+
console.debug('[ContentfulPageController/save] starting save');
|
|
211
|
+
// mark as syncing
|
|
212
|
+
page.syncing = true;
|
|
213
|
+
// update state
|
|
214
|
+
this.state = 'saving';
|
|
215
|
+
// save page
|
|
216
|
+
this.page = await this.pageRepository.save(page);
|
|
217
|
+
// update state
|
|
218
|
+
this.state = 'ready';
|
|
219
|
+
console.debug('[ContentfulPageController/save] save finished');
|
|
220
|
+
}
|
|
221
|
+
// handle error
|
|
222
|
+
catch (e) {
|
|
223
|
+
console.error('[ContentfulPageController/save] save failed', e);
|
|
224
|
+
// update state
|
|
225
|
+
this.state = 'error';
|
|
226
|
+
}
|
|
227
|
+
// complete
|
|
228
|
+
finally {
|
|
229
|
+
page.syncing = false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async reload() {
|
|
233
|
+
throw new funnel_core_1.NotImplementedError();
|
|
234
|
+
}
|
|
235
|
+
async unpublish() {
|
|
236
|
+
throw new funnel_core_1.NotImplementedError();
|
|
237
|
+
}
|
|
238
|
+
async processQueues() {
|
|
239
|
+
// try to save (if queued)
|
|
240
|
+
const { _queuedSave, _page } = this;
|
|
241
|
+
if (_queuedSave) {
|
|
242
|
+
// nuke if page differs (keep going afterward)
|
|
243
|
+
if (_page !== _queuedSave) {
|
|
244
|
+
console.debug('[ContentfulPageController/processQueues] ignoring queued save for old page');
|
|
245
|
+
delete this._queuedSave;
|
|
246
|
+
}
|
|
247
|
+
// otherwise, try to save
|
|
248
|
+
else {
|
|
249
|
+
console.debug('[ContentfulPageController/processQueues] restarting queued save');
|
|
250
|
+
// save
|
|
251
|
+
this.save(_page).catch(console.error);
|
|
252
|
+
// stop processing
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
// try to sync
|
|
257
|
+
const { _queuedSync, _pageSys } = this;
|
|
258
|
+
if (_queuedSync) {
|
|
259
|
+
// clear sync
|
|
260
|
+
delete this._queuedSync;
|
|
261
|
+
// reload if entity is different
|
|
262
|
+
if (_queuedSync.id !== (_pageSys === null || _pageSys === void 0 ? void 0 : _pageSys.id)) {
|
|
263
|
+
console.debug('[ContentfulPageController/processQueues] reloading on entity change');
|
|
264
|
+
this.load().catch(console.error);
|
|
265
|
+
}
|
|
266
|
+
// otherwise, try to sync
|
|
267
|
+
else {
|
|
268
|
+
console.debug('[ContentfulPageController/processQueues] retrying sync');
|
|
269
|
+
this.sync(_queuedSync).catch(console.error);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
raiseEvent(type) {
|
|
274
|
+
this._eventBus.publish(components_1.IPageController.Event.create({ type, controller: this }));
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
exports.ContentfulPageController = ContentfulPageController;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
export declare function ContentfulPageControllerContainer({ children }: PageControllerContainer.Props): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export declare namespace PageControllerContainer {
|
|
4
|
+
type Props = PropsWithChildren;
|
|
5
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContentfulPageControllerContainer = ContentfulPageControllerContainer;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_apps_toolkit_1 = require("@contentful/react-apps-toolkit");
|
|
6
|
+
const components_1 = require("@nascentdigital/funnel-editor/components");
|
|
7
|
+
const react_1 = require("react");
|
|
8
|
+
const ContentfulPageController_1 = require("./ContentfulPageController");
|
|
9
|
+
// container
|
|
10
|
+
function ContentfulPageControllerContainer({ children }) {
|
|
11
|
+
// bind context
|
|
12
|
+
const pageRepository = (0, components_1.usePageRepository)();
|
|
13
|
+
const sdk = (0, react_apps_toolkit_1.useSDK)();
|
|
14
|
+
const context = (0, react_1.useMemo)(() => ({
|
|
15
|
+
controller: new ContentfulPageController_1.ContentfulPageController({ pageRepository })
|
|
16
|
+
}), [pageRepository]);
|
|
17
|
+
// listen to page changes
|
|
18
|
+
(0, react_1.useEffect)(() => {
|
|
19
|
+
// get controller
|
|
20
|
+
const { controller } = context;
|
|
21
|
+
// sync on change (return unsubscribe)
|
|
22
|
+
return sdk.entry.onSysChanged(sys => {
|
|
23
|
+
controller.sync(sys).catch(console.error);
|
|
24
|
+
});
|
|
25
|
+
}, [sdk, context]);
|
|
26
|
+
// render
|
|
27
|
+
return ((0, jsx_runtime_1.jsx)(components_1.PageControllerContext.Provider, { value: context, children: children }));
|
|
28
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
1
|
+
export * from './ContentfulPageController';
|
|
2
|
+
export * from './ContentfulPageControllerContainer';
|
|
3
|
+
export * from './useContentfulPageController';
|
|
@@ -14,6 +14,6 @@ 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("./
|
|
18
|
-
__exportStar(require("./
|
|
19
|
-
__exportStar(require("./
|
|
17
|
+
__exportStar(require("./ContentfulPageController"), exports);
|
|
18
|
+
__exportStar(require("./ContentfulPageControllerContainer"), exports);
|
|
19
|
+
__exportStar(require("./useContentfulPageController"), exports);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useContentfulPageController = useContentfulPageController;
|
|
4
|
+
const components_1 = require("@nascentdigital/funnel-editor/components");
|
|
5
|
+
// hook
|
|
6
|
+
function useContentfulPageController() {
|
|
7
|
+
return (0, components_1.usePageController)();
|
|
8
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { AssetClient } from '@nascentdigital/funnel-cms';
|
|
1
|
+
import { AssetClient, PageClient } from '@nascentdigital/funnel-cms';
|
|
2
|
+
import { ContentfulData, ContentfulPageData } from '@nascentdigital/funnel-cms/contentful';
|
|
2
3
|
import { EventBus, FieldModel, Language, Schema } from '@nascentdigital/funnel-core';
|
|
3
4
|
import { Asset, Block, IPage, PageSettings, Section, SectionBlock } from '@nascentdigital/funnel-editor/components';
|
|
4
5
|
import { Observable } from 'rxjs';
|
|
@@ -35,6 +36,7 @@ export declare class Page implements IPage {
|
|
|
35
36
|
private _syncing;
|
|
36
37
|
private readonly _subscription;
|
|
37
38
|
private _savingOn?;
|
|
39
|
+
readonly references: ReadonlyArray<ContentfulData.Link.Entry | ContentfulData.Link.Asset>;
|
|
38
40
|
constructor(args: Page.ConstructorArgs);
|
|
39
41
|
get events$(): Observable<IPage.Events>;
|
|
40
42
|
get stable$(): Observable<boolean>;
|
|
@@ -71,10 +73,11 @@ export declare class Page implements IPage {
|
|
|
71
73
|
get blocks(): (Block<Schema.Block<string, any, any>> | SectionBlock<Schema.Block<string, any, any>>)[];
|
|
72
74
|
get deleteBlocks(): ReadonlyArray<Block>;
|
|
73
75
|
get firstBlock(): Block<Schema.Block<string, any, any>> | SectionBlock<Schema.Block<string, any, any>> | undefined;
|
|
74
|
-
get firstItem(): Block<Schema.Block<string, any, any
|
|
76
|
+
get firstItem(): Section | Block<Schema.Block<string, any, any>>;
|
|
75
77
|
get items(): Array<Block | Section>;
|
|
76
78
|
get assets(): Asset[];
|
|
77
79
|
get collections(): ReadonlyArray<Schema.Collection.Data.AsLink>;
|
|
80
|
+
get pages(): ReadonlyArray<Schema.Page.Data.AsRef>;
|
|
78
81
|
get initialTags(): ReadonlySet<Schema.Tag<string, string>>;
|
|
79
82
|
get tagGroups(): ReadonlyArray<Schema.TagGroup>;
|
|
80
83
|
get tags(): ReadonlySet<Schema.Tag>;
|
|
@@ -101,6 +104,17 @@ export declare class Page implements IPage {
|
|
|
101
104
|
private raiseEvent;
|
|
102
105
|
}
|
|
103
106
|
export declare namespace Page {
|
|
107
|
+
type Blocks = Block[];
|
|
108
|
+
type Content = Array<Block | Section>;
|
|
109
|
+
type Errors = {
|
|
110
|
+
page: Page;
|
|
111
|
+
items: Array<Block | Section>;
|
|
112
|
+
};
|
|
113
|
+
type Changes = {
|
|
114
|
+
page: Page;
|
|
115
|
+
items: Array<Block | Section>;
|
|
116
|
+
};
|
|
117
|
+
type Target = Block | SectionBlock | Section | FieldModel;
|
|
104
118
|
type ConstructorArgs = {
|
|
105
119
|
template: Schema.Page;
|
|
106
120
|
eventBus: EventBus;
|
|
@@ -124,16 +138,13 @@ export declare namespace Page {
|
|
|
124
138
|
updatedOn: number;
|
|
125
139
|
publishedOn?: number;
|
|
126
140
|
publication?: number;
|
|
141
|
+
references: ContentfulData.References;
|
|
127
142
|
};
|
|
128
|
-
type
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
items: Array<Block | Section>;
|
|
143
|
+
type FromSchemaData = {
|
|
144
|
+
data: ContentfulPageData.ForSchema;
|
|
145
|
+
references: Schema.Page.References;
|
|
146
|
+
eventBus?: EventBus;
|
|
133
147
|
};
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
items: Array<Block | Section>;
|
|
137
|
-
};
|
|
138
|
-
type Target = Block | SectionBlock | Section | FieldModel;
|
|
148
|
+
function fromSchemaData({ data, references, eventBus }: FromSchemaData): Page;
|
|
149
|
+
function toUpdates(page: Page, savables: IPage.Savable[]): PageClient.Update.Args;
|
|
139
150
|
}
|
|
@@ -1,6 +1,18 @@
|
|
|
1
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
|
+
};
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
14
|
exports.Page = void 0;
|
|
15
|
+
const contentful_1 = require("@nascentdigital/funnel-cms/contentful");
|
|
4
16
|
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
17
|
const components_1 = require("@nascentdigital/funnel-editor/components");
|
|
6
18
|
const rxjs_1 = require("rxjs");
|
|
@@ -33,6 +45,7 @@ class Page {
|
|
|
33
45
|
this._collections = (_c = args.collections) !== null && _c !== void 0 ? _c : [];
|
|
34
46
|
this._initialTags = new Set(args.tags);
|
|
35
47
|
this._tags = new Set(args.tags);
|
|
48
|
+
this.references = args.references;
|
|
36
49
|
this._deletedBlocks = [];
|
|
37
50
|
this._syncing = false;
|
|
38
51
|
// bind content
|
|
@@ -253,6 +266,9 @@ class Page {
|
|
|
253
266
|
get collections() {
|
|
254
267
|
return this._collections;
|
|
255
268
|
}
|
|
269
|
+
get pages() {
|
|
270
|
+
return this._pages;
|
|
271
|
+
}
|
|
256
272
|
get initialTags() {
|
|
257
273
|
return this._initialTags;
|
|
258
274
|
}
|
|
@@ -491,3 +507,126 @@ class Page {
|
|
|
491
507
|
}
|
|
492
508
|
}
|
|
493
509
|
exports.Page = Page;
|
|
510
|
+
// extension
|
|
511
|
+
(function (Page) {
|
|
512
|
+
function fromSchemaData({ data, references, eventBus }) {
|
|
513
|
+
// setup
|
|
514
|
+
const { snapshot, discover, content, tags } = data, pageArgs = __rest(data, ["snapshot", "discover", "content", "tags"]);
|
|
515
|
+
const { files = {}, collections = {}, pages = {} } = references !== null && references !== void 0 ? references : {};
|
|
516
|
+
const { discover: discoverSnapshot = {}, content: contentSnapshot = {} } = snapshot !== null && snapshot !== void 0 ? snapshot : {};
|
|
517
|
+
const template = funnel_core_1.Schema.Site.getPage(data.type, data.region);
|
|
518
|
+
eventBus = eventBus !== null && eventBus !== void 0 ? eventBus : new funnel_core_1.EventBus();
|
|
519
|
+
// create page
|
|
520
|
+
return new Page(Object.assign(Object.assign({}, pageArgs), { eventBus,
|
|
521
|
+
template, tags: components_1.TagSerializer.deserializeTags({
|
|
522
|
+
groups: template.tags,
|
|
523
|
+
tagsData: tags !== null && tags !== void 0 ? tags : []
|
|
524
|
+
}), discover: [
|
|
525
|
+
components_1.PageSerializer.deserializeBlock({
|
|
526
|
+
schema: funnel_core_1.Schema.Seo,
|
|
527
|
+
eventBus,
|
|
528
|
+
key: 'seo',
|
|
529
|
+
content: discover['seo'],
|
|
530
|
+
snapshot: discoverSnapshot['seo']
|
|
531
|
+
})
|
|
532
|
+
], content: Object.entries(template.content).map(([key, schema]) => components_1.PageSerializer.deserializeContent({
|
|
533
|
+
key,
|
|
534
|
+
schema: schema.unwrap(),
|
|
535
|
+
eventBus,
|
|
536
|
+
content: content[key],
|
|
537
|
+
snapshot: contentSnapshot[key],
|
|
538
|
+
})), files: Object.values(files), collections: Object.values(collections), pages: Object.values(pages).map(components_1.IPage.Ref.fromData), references: contentful_1.ContentfulData.findReferences([discover, content]) }));
|
|
539
|
+
}
|
|
540
|
+
Page.fromSchemaData = fromSchemaData;
|
|
541
|
+
function toUpdates(page, savables) {
|
|
542
|
+
var _a, _b;
|
|
543
|
+
// root page updates
|
|
544
|
+
const { id, discover, content } = page;
|
|
545
|
+
const rootPageUpdates = [];
|
|
546
|
+
// name
|
|
547
|
+
if (page.initialName !== page.name) {
|
|
548
|
+
rootPageUpdates.push({
|
|
549
|
+
type: 'page',
|
|
550
|
+
property: 'name',
|
|
551
|
+
value: page.name
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
// tags
|
|
555
|
+
if (page.initialTags.symmetricDifference(page.tags).size > 0) {
|
|
556
|
+
rootPageUpdates.push({
|
|
557
|
+
type: 'page',
|
|
558
|
+
property: 'tags',
|
|
559
|
+
value: Array.from(page.tags).map(tag => tag.data)
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
// slug + url
|
|
563
|
+
if (page.initialSlug !== page.slug) {
|
|
564
|
+
rootPageUpdates.push({
|
|
565
|
+
type: 'page',
|
|
566
|
+
property: 'slug',
|
|
567
|
+
value: (_a = page.slug) !== null && _a !== void 0 ? _a : null
|
|
568
|
+
});
|
|
569
|
+
rootPageUpdates.push({
|
|
570
|
+
type: 'page',
|
|
571
|
+
property: 'url',
|
|
572
|
+
value: page.url
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
// preview
|
|
576
|
+
const previewBlock = page.getPreviewBlock();
|
|
577
|
+
if (previewBlock && previewBlock.modified) {
|
|
578
|
+
rootPageUpdates.push({
|
|
579
|
+
type: 'page',
|
|
580
|
+
property: 'preview',
|
|
581
|
+
value: previewBlock.value
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
// errors
|
|
585
|
+
if (page.initialErrors !== !page.valid) {
|
|
586
|
+
rootPageUpdates.push({
|
|
587
|
+
type: 'page',
|
|
588
|
+
property: 'errors',
|
|
589
|
+
value: !page.valid
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
// publication
|
|
593
|
+
if (page.initialPublication !== page.publication) {
|
|
594
|
+
rootPageUpdates.push({
|
|
595
|
+
type: 'page',
|
|
596
|
+
property: 'publication',
|
|
597
|
+
value: (_b = page.publication) !== null && _b !== void 0 ? _b : null
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
// aggregate other updates
|
|
601
|
+
return {
|
|
602
|
+
id,
|
|
603
|
+
updatedOn: page.updatedOn,
|
|
604
|
+
updates: [
|
|
605
|
+
...rootPageUpdates,
|
|
606
|
+
...discover.reduce((updates, block) => {
|
|
607
|
+
// try to update block
|
|
608
|
+
components_1.SerializePageUpdate.serializeBlockUpdate(updates, block, 'discover', savables);
|
|
609
|
+
// keep reducing
|
|
610
|
+
return updates;
|
|
611
|
+
}, []),
|
|
612
|
+
...content.reduce((updates, item) => {
|
|
613
|
+
// handle block
|
|
614
|
+
if (item instanceof components_1.Block) {
|
|
615
|
+
components_1.SerializePageUpdate.serializeBlockUpdate(updates, item, 'content', savables);
|
|
616
|
+
}
|
|
617
|
+
// or section
|
|
618
|
+
else {
|
|
619
|
+
components_1.SerializePageUpdate.serializeSectionUpdate(updates, item, 'content', savables);
|
|
620
|
+
}
|
|
621
|
+
// keep reducing
|
|
622
|
+
return updates;
|
|
623
|
+
}, []),
|
|
624
|
+
...page.deleteBlocks.map(block => ({
|
|
625
|
+
type: 'block.delete',
|
|
626
|
+
path: [block.area, block.key]
|
|
627
|
+
}))
|
|
628
|
+
]
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
Page.toUpdates = toUpdates;
|
|
632
|
+
})(Page || (exports.Page = Page = {}));
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Page';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./Page"), exports);
|
package/dist/page/index.d.ts
CHANGED
package/dist/page/index.js
CHANGED
|
@@ -14,5 +14,8 @@ 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("./bridge"), exports);
|
|
18
|
+
__exportStar(require("./domain"), exports);
|
|
19
|
+
__exportStar(require("./repository"), exports);
|
|
17
20
|
__exportStar(require("./screens"), exports);
|
|
18
21
|
__exportStar(require("./controller"), exports);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { EditorAppSDK, EntrySys, PageAppSDK } 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 | PageAppSDK;
|
|
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 | PageAppSDK;
|
|
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
|
+
}
|