@nascentdigital/funnel-editor 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/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 +15 -3
- package/dist/components.js +18 -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 +43 -3
- 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.d.ts +1 -2
- package/dist/core/components/fields/asset/AssetEditor.js +29 -49
- package/dist/core/components/fields/asset/AssetPicker.js +6 -6
- package/dist/core/components/fields/asset/AssetUploader.d.ts +1 -2
- package/dist/core/components/fields/asset/AssetUploader.js +39 -35
- 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.d.ts +2 -1
- package/dist/core/components/fields/collection/CollectionEditor.js +18 -4
- 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.d.ts +2 -2
- package/dist/core/components/fields/embed/EmbeddedVideoEditor.js +50 -31
- package/dist/core/components/fields/factories/AssetFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/AssetFactory.js +18 -13
- package/dist/core/components/fields/factories/CollectionFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/CollectionFactory.js +20 -13
- package/dist/core/components/fields/factories/EmbeddedVideoFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/EmbeddedVideoFactory.js +17 -8
- package/dist/core/components/fields/factories/FieldValueFactory.d.ts +7 -5
- package/dist/core/components/fields/factories/FieldValueFactory.js +57 -13
- package/dist/core/components/fields/factories/LinkFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/LinkFactory.js +17 -8
- package/dist/core/components/fields/factories/MediaFactory.d.ts +13 -0
- package/dist/core/components/fields/factories/MediaFactory.js +212 -0
- package/dist/core/components/fields/factories/ObjectFactory.d.ts +3 -2
- package/dist/core/components/fields/factories/ObjectFactory.js +16 -2
- package/dist/core/components/fields/factories/TextFactory.d.ts +3 -3
- package/dist/core/components/fields/factories/TextFactory.js +16 -10
- package/dist/core/components/fields/link/LinkEditor.d.ts +2 -2
- package/dist/core/components/fields/link/LinkEditor.js +18 -6
- 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 +36 -0
- package/dist/core/components/fields/media/MediaEditor.js +264 -0
- package/dist/core/components/fields/media/index.d.ts +2 -0
- package/dist/core/components/fields/media/index.js +18 -0
- package/dist/core/components/fields/object/ObjectEditor.d.ts +2 -1
- package/dist/core/components/fields/object/ObjectEditor.js +16 -2
- 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/Popup.d.ts +11 -7
- package/dist/core/components/interaction/Popup.js +8 -6
- package/dist/core/components/interaction/QuickEditor.js +1 -1
- package/dist/core/components/interaction/QuickInput.d.ts +2 -4
- package/dist/core/components/interaction/QuickInput.js +6 -2
- 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/interaction/menu/Menu.d.ts +8 -19
- package/dist/core/components/interaction/menu/Menu.js +26 -60
- package/dist/core/components/interaction/menu/useMenuController.d.ts +4 -2
- package/dist/core/components/interaction/menu/useMenuController.js +4 -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 +15 -9
- 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 -6
- package/dist/core/domain/ICollection.d.ts +72 -0
- package/dist/core/domain/ICollection.js +20 -0
- package/dist/core/domain/IPage.d.ts +16 -1
- 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 -5
- 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/useCollections.js +4 -0
- package/dist/core/hooks/usePageRepository.d.ts +3 -2
- package/dist/core/hooks/usePageRepository.js +4 -4
- package/dist/core/hooks/useSite.js +4 -0
- 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 +22 -21
- 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 +61 -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 +10 -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/core/splash/SplashContainer.d.ts +4 -2
- package/dist/core/splash/SplashContainer.js +3 -3
- 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,292 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SerializePageUpdate = void 0;
|
|
4
|
+
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
5
|
+
// namespace
|
|
6
|
+
var SerializePageUpdate;
|
|
7
|
+
(function (SerializePageUpdate) {
|
|
8
|
+
// helpers
|
|
9
|
+
function serializeSectionUpdate(updates, section, parentPath, savables) {
|
|
10
|
+
// track insert/update
|
|
11
|
+
let sectionChanged = false;
|
|
12
|
+
const path = [parentPath, section.key];
|
|
13
|
+
const { blocks, initialBlocks = [] } = section;
|
|
14
|
+
const blockIds = [];
|
|
15
|
+
blocks.forEach((sectionBlock, index) => {
|
|
16
|
+
// track id
|
|
17
|
+
const { id, block } = sectionBlock;
|
|
18
|
+
blockIds.push(id);
|
|
19
|
+
// track insert
|
|
20
|
+
const originalIndex = initialBlocks.findIndex(item => item.id === id);
|
|
21
|
+
if (originalIndex < 0) {
|
|
22
|
+
// add as insertion
|
|
23
|
+
updates.push({
|
|
24
|
+
type: 'section.insert',
|
|
25
|
+
path,
|
|
26
|
+
index,
|
|
27
|
+
section: {
|
|
28
|
+
type: 'section',
|
|
29
|
+
version: section.schema.version
|
|
30
|
+
},
|
|
31
|
+
block: sectionBlock.value
|
|
32
|
+
});
|
|
33
|
+
// mark changed
|
|
34
|
+
sectionChanged = true;
|
|
35
|
+
// track nested savables for section-block insertion
|
|
36
|
+
const fields = [...block.config, ...block.fields];
|
|
37
|
+
fields.forEach(field => {
|
|
38
|
+
if (field.modified) {
|
|
39
|
+
savables.push(field);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// recurse update if it's set
|
|
44
|
+
else if (block.modified) {
|
|
45
|
+
// track name field
|
|
46
|
+
if (block.nameField.modified) {
|
|
47
|
+
// send update
|
|
48
|
+
updates.push({
|
|
49
|
+
type: 'section.blockName',
|
|
50
|
+
path,
|
|
51
|
+
id,
|
|
52
|
+
value: funnel_core_1.Schema.TextField.Value.fromData(block.nameField.value) || null
|
|
53
|
+
});
|
|
54
|
+
// track change
|
|
55
|
+
savables.push(block.nameField);
|
|
56
|
+
}
|
|
57
|
+
// serialize config fields
|
|
58
|
+
serializeFieldsUpdate(updates, block.config, [...path, id, 'config'], savables);
|
|
59
|
+
// serialize content fields
|
|
60
|
+
serializeFieldsUpdate(updates, block.fields, [...path, id, 'fields'], savables);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
// track delete/reorder
|
|
64
|
+
let reordered = false;
|
|
65
|
+
initialBlocks.forEach(({ id }, index) => {
|
|
66
|
+
// add to deleted list if the original doesn't exist anymore
|
|
67
|
+
const blockIndex = blockIds.findIndex(blockId => blockId === id);
|
|
68
|
+
if (blockIndex < 0) {
|
|
69
|
+
// delete
|
|
70
|
+
updates.push({
|
|
71
|
+
type: 'section.delete',
|
|
72
|
+
path,
|
|
73
|
+
id
|
|
74
|
+
});
|
|
75
|
+
// track reorder
|
|
76
|
+
sectionChanged = true;
|
|
77
|
+
}
|
|
78
|
+
// or mark reorder if index isn't the same
|
|
79
|
+
else if (blockIndex !== index) {
|
|
80
|
+
reordered = true;
|
|
81
|
+
sectionChanged = true;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
// track reorder
|
|
85
|
+
if (reordered) {
|
|
86
|
+
updates.push({
|
|
87
|
+
type: 'section.reorder',
|
|
88
|
+
path,
|
|
89
|
+
ids: blockIds
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// track section change (if any)
|
|
93
|
+
if (sectionChanged) {
|
|
94
|
+
savables.push(section);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
SerializePageUpdate.serializeSectionUpdate = serializeSectionUpdate;
|
|
98
|
+
function serializeBlockUpdate(updates, block, parentPath, savables) {
|
|
99
|
+
// ignore if block isn't activated
|
|
100
|
+
if (!block.activated) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// create a new block if it's new
|
|
104
|
+
else if (block.isNew) {
|
|
105
|
+
// create update
|
|
106
|
+
updates.push({
|
|
107
|
+
type: 'block.create',
|
|
108
|
+
path: [parentPath, block.key],
|
|
109
|
+
block: block.value
|
|
110
|
+
});
|
|
111
|
+
// track block
|
|
112
|
+
savables.push(block);
|
|
113
|
+
// track nested savables for block insertion
|
|
114
|
+
const fields = [...block.config, ...block.fields];
|
|
115
|
+
fields.forEach(field => {
|
|
116
|
+
if (field.modified) {
|
|
117
|
+
savables.push(field);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
// or just track updated fields
|
|
122
|
+
else {
|
|
123
|
+
// serialize config fields
|
|
124
|
+
serializeFieldsUpdate(updates, block.config, [parentPath, block.key, 'config'], savables);
|
|
125
|
+
// serialize content fields
|
|
126
|
+
serializeFieldsUpdate(updates, block.fields, [parentPath, block.key, 'fields'], savables);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
SerializePageUpdate.serializeBlockUpdate = serializeBlockUpdate;
|
|
130
|
+
function serializeFieldsUpdate(updates, fields, parentPath, savables) {
|
|
131
|
+
// handle fields in block
|
|
132
|
+
fields.forEach(field => {
|
|
133
|
+
if (field instanceof funnel_core_1.Field) {
|
|
134
|
+
serializeFieldUpdate(updates, field, parentPath, savables);
|
|
135
|
+
}
|
|
136
|
+
else if (field instanceof funnel_core_1.ObjectField) {
|
|
137
|
+
serializeObjectFieldUpdate(updates, field, parentPath, savables);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
serializeListUpdate(updates, field, parentPath, savables);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
// return changes (for chaining)
|
|
144
|
+
return updates;
|
|
145
|
+
}
|
|
146
|
+
SerializePageUpdate.serializeFieldsUpdate = serializeFieldsUpdate;
|
|
147
|
+
function serializeObjectFieldUpdate(updates, field, parentPath, savables) {
|
|
148
|
+
var _a;
|
|
149
|
+
// create object if it's new
|
|
150
|
+
if (field.isNew) {
|
|
151
|
+
// add insert
|
|
152
|
+
updates.push({
|
|
153
|
+
type: 'object.insert',
|
|
154
|
+
path: [...parentPath, field.id],
|
|
155
|
+
value: (_a = field.value) !== null && _a !== void 0 ? _a : null
|
|
156
|
+
});
|
|
157
|
+
// track save
|
|
158
|
+
savables.push(field);
|
|
159
|
+
}
|
|
160
|
+
// or process subfields
|
|
161
|
+
else if (field.exists) {
|
|
162
|
+
// save fields
|
|
163
|
+
serializeFieldsUpdate(updates, field.fields, [...parentPath, field.id], savables);
|
|
164
|
+
// track save
|
|
165
|
+
savables.push(field);
|
|
166
|
+
}
|
|
167
|
+
// or process opted out field
|
|
168
|
+
else if (field.optedOut) {
|
|
169
|
+
// remove field
|
|
170
|
+
updates.push({
|
|
171
|
+
type: 'value',
|
|
172
|
+
path: [...parentPath, field.id],
|
|
173
|
+
value: null
|
|
174
|
+
});
|
|
175
|
+
// track save
|
|
176
|
+
savables.push(field);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
SerializePageUpdate.serializeObjectFieldUpdate = serializeObjectFieldUpdate;
|
|
180
|
+
function serializeFieldUpdate(updates, field, parentPath, savables) {
|
|
181
|
+
var _a;
|
|
182
|
+
// track change if modified (ignore if field is sandboxed)
|
|
183
|
+
if (field.modified && !field.sandboxed) {
|
|
184
|
+
// set field
|
|
185
|
+
updates.push({
|
|
186
|
+
type: 'value',
|
|
187
|
+
path: [...parentPath, field.id],
|
|
188
|
+
value: ((_a = field.value) !== null && _a !== void 0 ? _a : null)
|
|
189
|
+
});
|
|
190
|
+
// track save
|
|
191
|
+
savables.push(field);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
SerializePageUpdate.serializeFieldUpdate = serializeFieldUpdate;
|
|
195
|
+
function serializeListUpdate(updates, list, parentPath, savables) {
|
|
196
|
+
var _a, _b;
|
|
197
|
+
// create list if it's new
|
|
198
|
+
if (list.isNew) {
|
|
199
|
+
// add new list
|
|
200
|
+
updates.push({
|
|
201
|
+
type: 'value',
|
|
202
|
+
path: [...parentPath, list.id],
|
|
203
|
+
value: funnel_core_1.Schema.Field.Data.newValue('list')
|
|
204
|
+
});
|
|
205
|
+
// track save
|
|
206
|
+
savables.push(list);
|
|
207
|
+
}
|
|
208
|
+
// or drop list on opt-out
|
|
209
|
+
else if (list.optedOut) {
|
|
210
|
+
// drop list
|
|
211
|
+
updates.push({
|
|
212
|
+
type: 'value',
|
|
213
|
+
path: [...parentPath, list.id],
|
|
214
|
+
value: null
|
|
215
|
+
});
|
|
216
|
+
// track save
|
|
217
|
+
savables.push(list);
|
|
218
|
+
}
|
|
219
|
+
// or if it is modified (otherwise ignore)
|
|
220
|
+
else if (list.modified) {
|
|
221
|
+
// add new list if there's nothing and it's new
|
|
222
|
+
const path = [...parentPath, list.id];
|
|
223
|
+
const { value: currentValue, items: fields, initialValue } = list;
|
|
224
|
+
const currentItems = (_a = currentValue === null || currentValue === void 0 ? void 0 : currentValue.value) !== null && _a !== void 0 ? _a : [];
|
|
225
|
+
const initialItems = (_b = initialValue === null || initialValue === void 0 ? void 0 : initialValue.value) !== null && _b !== void 0 ? _b : [];
|
|
226
|
+
const fieldIds = [];
|
|
227
|
+
// track inserts/updates of elements
|
|
228
|
+
currentItems.forEach((item, index) => {
|
|
229
|
+
// track id
|
|
230
|
+
const { id, field } = fields[index];
|
|
231
|
+
fieldIds.push(item.id);
|
|
232
|
+
// track insert
|
|
233
|
+
const originalIndex = initialItems.findIndex(initialItem => initialItem.id === id);
|
|
234
|
+
if (originalIndex < 0) {
|
|
235
|
+
updates.push({
|
|
236
|
+
type: 'array.insert',
|
|
237
|
+
path,
|
|
238
|
+
index,
|
|
239
|
+
id,
|
|
240
|
+
value: item
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
// track update
|
|
244
|
+
else if (field.modified) {
|
|
245
|
+
// object field updates should be recursed and indexed
|
|
246
|
+
if (field instanceof funnel_core_1.ObjectField) {
|
|
247
|
+
serializeFieldsUpdate(updates, field.fields, [...path, id], savables);
|
|
248
|
+
}
|
|
249
|
+
// basic field updates can be done inline
|
|
250
|
+
else {
|
|
251
|
+
updates.push({
|
|
252
|
+
type: 'value',
|
|
253
|
+
path: [...path, id],
|
|
254
|
+
value: item
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
// track delete/reorder
|
|
260
|
+
let reordered = false;
|
|
261
|
+
let deleted = 0;
|
|
262
|
+
initialItems.forEach(({ id }, index) => {
|
|
263
|
+
// add to deleted list if the original doesn't exist anymore
|
|
264
|
+
const fieldIndex = fieldIds.findIndex(fieldId => fieldId === id) + deleted;
|
|
265
|
+
if (fieldIndex < 0) {
|
|
266
|
+
updates.push({
|
|
267
|
+
type: 'array.delete',
|
|
268
|
+
path,
|
|
269
|
+
id
|
|
270
|
+
});
|
|
271
|
+
// track deletion
|
|
272
|
+
++deleted;
|
|
273
|
+
}
|
|
274
|
+
// or mark reorder if index isn't the same
|
|
275
|
+
else if (fieldIndex !== index) {
|
|
276
|
+
reordered = true;
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
// track reorder
|
|
280
|
+
if (reordered) {
|
|
281
|
+
updates.push({
|
|
282
|
+
type: 'array.reorder',
|
|
283
|
+
path,
|
|
284
|
+
ids: fieldIds
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
// track save
|
|
288
|
+
savables.push(list);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
SerializePageUpdate.serializeListUpdate = serializeListUpdate;
|
|
292
|
+
})(SerializePageUpdate || (exports.SerializePageUpdate = SerializePageUpdate = {}));
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
export * from './AssetRepository';
|
|
1
2
|
export * from './CollectionRepository';
|
|
2
3
|
export * from './CollectionSerializer';
|
|
3
4
|
export * from './CollectionTarget';
|
|
4
5
|
export * from './FieldSerializer';
|
|
6
|
+
export * from './IAssetRepository';
|
|
7
|
+
export * from './ICollectionRepository';
|
|
8
|
+
export * from './IPageRepository';
|
|
5
9
|
export * from './PageRepository';
|
|
6
10
|
export * from './PageSerializer';
|
|
7
11
|
export * from './PageTarget';
|
|
@@ -14,10 +14,14 @@ 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("./AssetRepository"), exports);
|
|
17
18
|
__exportStar(require("./CollectionRepository"), exports);
|
|
18
19
|
__exportStar(require("./CollectionSerializer"), exports);
|
|
19
20
|
__exportStar(require("./CollectionTarget"), exports);
|
|
20
21
|
__exportStar(require("./FieldSerializer"), exports);
|
|
22
|
+
__exportStar(require("./IAssetRepository"), exports);
|
|
23
|
+
__exportStar(require("./ICollectionRepository"), exports);
|
|
24
|
+
__exportStar(require("./IPageRepository"), exports);
|
|
21
25
|
__exportStar(require("./PageRepository"), exports);
|
|
22
26
|
__exportStar(require("./PageSerializer"), exports);
|
|
23
27
|
__exportStar(require("./PageTarget"), exports);
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
|
-
export declare function SplashContainer({ children }: SplashContainer.Props): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function SplashContainer({ message, children }: SplashContainer.Props): import("react/jsx-runtime").JSX.Element;
|
|
3
3
|
export declare namespace SplashContainer {
|
|
4
|
-
type Props = PropsWithChildren
|
|
4
|
+
type Props = PropsWithChildren & {
|
|
5
|
+
message?: string;
|
|
6
|
+
};
|
|
5
7
|
}
|
|
@@ -8,16 +8,16 @@ const Splash_1 = require("./Splash");
|
|
|
8
8
|
const SplashContext_1 = require("./SplashContext");
|
|
9
9
|
const SplashService_1 = require("./SplashService");
|
|
10
10
|
// component
|
|
11
|
-
function SplashContainer({ children }) {
|
|
11
|
+
function SplashContainer({ message = 'Signing you in', children }) {
|
|
12
12
|
// bind hooks + memo
|
|
13
13
|
const service = (0, react_2.useMemo)(() => {
|
|
14
14
|
// create service
|
|
15
15
|
const service = new SplashService_1.SplashService();
|
|
16
16
|
// start in a loading state
|
|
17
|
-
service.showLoading(
|
|
17
|
+
service.showLoading(message);
|
|
18
18
|
// return service
|
|
19
19
|
return service;
|
|
20
|
-
}, []);
|
|
20
|
+
}, [message]);
|
|
21
21
|
const [context, setContext] = (0, react_2.useState)(() => ({ service }));
|
|
22
22
|
// update context on event changes
|
|
23
23
|
(0, react_2.useEffect)(() => {
|
|
@@ -23,7 +23,7 @@ function Dashboard() {
|
|
|
23
23
|
splash.dismiss();
|
|
24
24
|
}, [splash]);
|
|
25
25
|
// render
|
|
26
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col bg-surface1", children: [(0, jsx_runtime_1.jsx)(core_1.Header, { breadcrumbs: [brand.name, 'Dashboard'], back: "none" }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1", children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('w-full sm:w-4/5 md:w-3/5 max-h-full overflow-y-scroll p-l6', 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 grid-auto-rows auto-cols-fr auto-rows-fr gap-l6'), children: [(0, jsx_runtime_1.jsx)(components_1.NavCard, { title: "My Site's Pages", caption: "Your main website.", action: "Explore pages", onClick: () => router.navigateToTemplates({ region: brand.regionalization.fallback }) }), collections.length > 0 &&
|
|
26
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col bg-surface1", children: [(0, jsx_runtime_1.jsx)(core_1.Header, { breadcrumbs: [brand.name, 'Dashboard'], back: "none" }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1", children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('w-full sm:w-4/5 md:w-3/5 max-h-full overflow-y-scroll p-l6', 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 grid-auto-rows auto-cols-fr auto-rows-fr gap-l6'), tabIndex: -1, children: [(0, jsx_runtime_1.jsx)(components_1.NavCard, { title: "My Site's Pages", caption: "Your main website.", action: "Explore pages", onClick: () => router.navigateToTemplates({ region: brand.regionalization.fallback }) }), collections.length > 0 &&
|
|
27
27
|
(0, jsx_runtime_1.jsx)(components_1.NavCard, { title: "Collections", caption: "Shared data used by site pages.", action: "Manage collections", onClick: () => router.navigateToCollections() }), (0, jsx_runtime_1.jsx)(components_1.NavCard, { title: "Publishing", caption: "View and manage groups of changes.", action: "Manage changes", onClick: () => router.navigateToChangeSets() }), (0, jsx_runtime_1.jsx)(components_1.NavCard, { title: "Media", caption: "Images, videos and other files.", action: "Manage media", disabled: true }), user.hasAny('user.create', 'user.update', 'user.delete') &&
|
|
28
28
|
(0, jsx_runtime_1.jsx)(components_1.NavCard, { title: "Users", caption: "Control who has access to content.", action: "Manage Users", onClick: () => router.navigateToUsers() }), user.role.id === 'owner' &&
|
|
29
29
|
(0, jsx_runtime_1.jsx)(components_1.NavCard, { variant: "destructive", title: "Developer", caption: "Access tools tomaintain the site.", action: "Developer Tools", onClick: () => router.navigateToDevtools() })] }) })] }));
|
|
@@ -66,5 +66,5 @@ function Devtools() {
|
|
|
66
66
|
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col bg-surface1", children: [(0, jsx_runtime_1.jsx)(core_1.Header, { breadcrumbs: [brand.name, 'Developer Tools'], back: "back", onBack: () => router.navigateToDashboard() }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 flex items-center justify-center", children: (0, jsx_runtime_1.jsx)(core_1.EmptyState, { variant: "missing", size: "md", children: (0, jsx_runtime_1.jsx)("h1", { className: "heading text-content-primary", children: "You're not authorized to see this page!" }) }) })] }));
|
|
67
67
|
}
|
|
68
68
|
// render
|
|
69
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col bg-surface1", children: [(0, jsx_runtime_1.jsx)(core_1.Header, { breadcrumbs: [brand.name, 'Developer Tools'], back: "back", onBack: () => router.navigateToDashboard() }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1", children: (0, jsx_runtime_1.jsxs)("div", { className: "absolute inset-0 flex", children: [(0, jsx_runtime_1.jsx)("section", { className: "flex-1 h-full max-h-full overflow-y-scroll flex flex-wrap justify-start items-start gap-l6 p-l6", children: (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { mode: "wait", initial: true, children: (0, jsx_runtime_1.jsx)(core_1.Button, { variant: isEditorLocked ? 'destructive' : 'primary', iconLeft: isEditorLocked ? 'Lock' : 'LockOpen', onClick: onToggleEditorLockdown, disabled: !ready, children: isEditorLocked ? 'Unlock Editor' : 'Lock Editor' }) }) }), (0, jsx_runtime_1.jsx)("section", { className: "hidden md:block md:w-[280px] lg:w-[320px] xl:w-[350px] border-l border-solid border-border-l1 overflow-y-scroll shrink-0" })] }) })] }));
|
|
69
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col bg-surface1", children: [(0, jsx_runtime_1.jsx)(core_1.Header, { breadcrumbs: [brand.name, 'Developer Tools'], back: "back", onBack: () => router.navigateToDashboard() }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1", children: (0, jsx_runtime_1.jsxs)("div", { className: "absolute inset-0 flex", children: [(0, jsx_runtime_1.jsx)("section", { className: "flex-1 h-full max-h-full overflow-y-scroll flex flex-wrap justify-start items-start gap-l6 p-l6", tabIndex: -1, children: (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { mode: "wait", initial: true, children: (0, jsx_runtime_1.jsx)(core_1.Button, { variant: isEditorLocked ? 'destructive' : 'primary', iconLeft: isEditorLocked ? 'Lock' : 'LockOpen', onClick: onToggleEditorLockdown, disabled: !ready, children: isEditorLocked ? 'Unlock Editor' : 'Lock Editor' }) }) }), (0, jsx_runtime_1.jsx)("section", { className: "hidden md:block md:w-[280px] lg:w-[320px] xl:w-[350px] border-l border-solid border-border-l1 overflow-y-scroll shrink-0" })] }) })] }));
|
|
70
70
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Schema } from '@nascentdigital/funnel-core';
|
|
2
|
-
import {
|
|
2
|
+
import { IPage, Pages, Popup, Site } from '../../core';
|
|
3
3
|
export declare const CreatePageDialog: import("react").ForwardRefExoticComponent<import("react").RefAttributes<CreatePageDialog.Ref>>;
|
|
4
4
|
export declare namespace CreatePageDialog {
|
|
5
5
|
type Props = {};
|
|
6
6
|
interface Ref {
|
|
7
|
-
createPage(options: Options): Promise<
|
|
7
|
+
createPage(options: Options): Promise<IPage | undefined>;
|
|
8
8
|
}
|
|
9
9
|
type Options = {
|
|
10
10
|
site: Site;
|
|
@@ -46,7 +46,7 @@ function CollectionExplorer({ type }) {
|
|
|
46
46
|
await router.navigateToCollection({ type, language, groupId });
|
|
47
47
|
};
|
|
48
48
|
// render
|
|
49
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col", children: [(0, jsx_runtime_1.jsx)(core_1.Header, { breadcrumbs: ['Dashboard', 'Collection explorer'], back: "back", onBack: () => router.navigateToCollections() }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1 overflow-y-scroll shrink-0", children: (0, jsx_runtime_1.jsx)("div", { className: "container-sm container-p", children: (0, jsx_runtime_1.jsx)(core_1.LoadingUntilReady, { className: "flex flex-col gap-l10 py-l14", ready: !!template && !!groupedCollections, children: renderCollections({ template, groupedCollections, onOpenLink, onCreateCollection }) }) }) }), (0, jsx_runtime_1.jsx)(components_1.CreateCollectionDialog, { ref: createDialogRef })] }));
|
|
49
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col", children: [(0, jsx_runtime_1.jsx)(core_1.Header, { breadcrumbs: ['Dashboard', 'Collection explorer'], back: "back", onBack: () => router.navigateToCollections() }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1 overflow-y-scroll shrink-0", tabIndex: -1, children: (0, jsx_runtime_1.jsx)("div", { className: "container-sm container-p", children: (0, jsx_runtime_1.jsx)(core_1.LoadingUntilReady, { className: "flex flex-col gap-l10 py-l14", ready: !!template && !!groupedCollections, children: renderCollections({ template, groupedCollections, onOpenLink, onCreateCollection }) }) }) }), (0, jsx_runtime_1.jsx)(components_1.CreateCollectionDialog, { ref: createDialogRef })] }));
|
|
50
50
|
}
|
|
51
51
|
function renderCollections({ template, groupedCollections, onOpenLink, onCreateCollection }) {
|
|
52
52
|
// show loader if browser isn't ready
|
|
@@ -21,7 +21,7 @@ function CollectionsExplorer(_) {
|
|
|
21
21
|
}
|
|
22
22
|
}, [splash, ready]);
|
|
23
23
|
// render
|
|
24
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col bg-surface1", children: [(0, jsx_runtime_1.jsx)(core_1.Header, { back: "back", breadcrumbs: [brand.name, 'Collections'], onBack: () => router.navigateToDashboard() }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1", children: (0, jsx_runtime_1.jsxs)("div", { className: "absolute inset-0 flex", children: [(0, jsx_runtime_1.jsx)("section", { className: "w-[200px] md:w-[220px] lg:w-[300px] border-r border-solid border-border-l1 overflow-y-scroll shrink-0" }), (0, jsx_runtime_1.jsx)("section", { className: "flex-1 h-full max-h-full overflow-y-scroll flex flex-wrap justify-start items-start gap-l6 p-l8", children: (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { children: renderContent({ collections, router }) }) }), (0, jsx_runtime_1.jsx)("section", { className: "hidden md:block md:w-[280px] lg:w-[320px] xl:w-[350px] border-l border-solid border-border-l1 overflow-y-scroll shrink-0" })] }) })] }));
|
|
24
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col bg-surface1", children: [(0, jsx_runtime_1.jsx)(core_1.Header, { back: "back", breadcrumbs: [brand.name, 'Collections'], onBack: () => router.navigateToDashboard() }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1", children: (0, jsx_runtime_1.jsxs)("div", { className: "absolute inset-0 flex", children: [(0, jsx_runtime_1.jsx)("section", { className: "w-[200px] md:w-[220px] lg:w-[300px] border-r border-solid border-border-l1 overflow-y-scroll shrink-0", tabIndex: -1 }), (0, jsx_runtime_1.jsx)("section", { className: "flex-1 h-full max-h-full overflow-y-scroll flex flex-wrap justify-start items-start gap-l6 p-l8", tabIndex: -1, children: (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { children: renderContent({ collections, router }) }) }), (0, jsx_runtime_1.jsx)("section", { className: "hidden md:block md:w-[280px] lg:w-[320px] xl:w-[350px] border-l border-solid border-border-l1 overflow-y-scroll shrink-0", tabIndex: -1 })] }) })] }));
|
|
25
25
|
}
|
|
26
26
|
function renderContent({ collections, router }) {
|
|
27
27
|
// show loader if browser isn't ready
|
|
@@ -48,7 +48,7 @@ function PageExplorer({ region, page: pageType }) {
|
|
|
48
48
|
await router.navigateToPage({ page: template.type, region, language, slug });
|
|
49
49
|
};
|
|
50
50
|
// render
|
|
51
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col", children: [(0, jsx_runtime_1.jsx)(components_1.ExploreHeader, { breadcrumbs: ['Dashboard', 'Site explorer'], region: region, onBack: () => router.navigateToTemplates({ region }), onRegionChange: region => router.navigateToPages({ region: region.id, page: pageType }) }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1 overflow-y-scroll shrink-0", children: (0, jsx_runtime_1.jsx)("div", { className: "container-sm container-p", children: (0, jsx_runtime_1.jsx)(core_1.LoadingUntilReady, { className: "flex flex-col gap-l10 py-l14", ready: ready, children: renderPages({ template, groupedPages, onCreatePage, onOpenPage }) }) }) }), (0, jsx_runtime_1.jsx)(components_1.CreatePageDialog, { ref: createDialogRef })] }));
|
|
51
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col", children: [(0, jsx_runtime_1.jsx)(components_1.ExploreHeader, { breadcrumbs: ['Dashboard', 'Site explorer'], region: region, onBack: () => router.navigateToTemplates({ region }), onRegionChange: region => router.navigateToPages({ region: region.id, page: pageType }) }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1 overflow-y-scroll shrink-0", tabIndex: -1, children: (0, jsx_runtime_1.jsx)("div", { className: "container-sm container-p", children: (0, jsx_runtime_1.jsx)(core_1.LoadingUntilReady, { className: "flex flex-col gap-l10 py-l14", ready: ready, children: renderPages({ template, groupedPages, onCreatePage, onOpenPage }) }) }) }), (0, jsx_runtime_1.jsx)(components_1.CreatePageDialog, { ref: createDialogRef })] }));
|
|
52
52
|
}
|
|
53
53
|
function renderPages({ template, groupedPages, onCreatePage, onOpenPage }) {
|
|
54
54
|
// show loader if not ready
|
|
@@ -29,7 +29,7 @@ function SiteExplorer({ region }) {
|
|
|
29
29
|
}
|
|
30
30
|
};
|
|
31
31
|
// render
|
|
32
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col", children: [(0, jsx_runtime_1.jsx)(components_1.ExploreHeader, { breadcrumbs: ['Dashboard'], region: region, onBack: () => router.navigateToDashboard(), onRegionChange: region => router.navigateToTemplates({ region: region.id }) }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1 overflow-y-scroll shrink-0", children: (0, jsx_runtime_1.jsx)("div", { className: "container-sm container-p", children: (0, jsx_runtime_1.jsxs)(core_1.LoadingUntilReady, { className: "flex flex-col gap-l10 py-l14", ready: ready, children: [(0, jsx_runtime_1.jsx)("h2", { className: "heading-lg text-content-primary", children: "Site explorer" }), (0, jsx_runtime_1.jsx)(core_1.Table, { className: "flex-1", children: site.overviews.map(overview => overview instanceof core_1.DynamicPageOverview
|
|
32
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col", children: [(0, jsx_runtime_1.jsx)(components_1.ExploreHeader, { breadcrumbs: ['Dashboard'], region: region, onBack: () => router.navigateToDashboard(), onRegionChange: region => router.navigateToTemplates({ region: region.id }) }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1 overflow-y-scroll shrink-0", tabIndex: -1, children: (0, jsx_runtime_1.jsx)("div", { className: "container-sm container-p", children: (0, jsx_runtime_1.jsxs)(core_1.LoadingUntilReady, { className: "flex flex-col gap-l10 py-l14", ready: ready, children: [(0, jsx_runtime_1.jsx)("h2", { className: "heading-lg text-content-primary", children: "Site explorer" }), (0, jsx_runtime_1.jsx)(core_1.Table, { className: "flex-1", children: site.overviews.map(overview => overview instanceof core_1.DynamicPageOverview
|
|
33
33
|
?
|
|
34
34
|
(0, jsx_runtime_1.jsx)(core_1.Table, { nested: true, children: (0, jsx_runtime_1.jsx)(core_1.TableItem, { nested: true, iconLeft: "CornerDownRight", iconRight: "ChevronRight", details: (0, jsx_runtime_1.jsx)(core_1.CountBadge, { count: overview.count }), onClick: () => onPageClicked(overview), children: overview.template.name }) }, overview.type)
|
|
35
35
|
:
|
|
@@ -59,7 +59,7 @@ function BlockEditor({ className, block, onSelectItem }) {
|
|
|
59
59
|
// render editor
|
|
60
60
|
const { messageFields, visualFields, listsFields, extendedFields } = block;
|
|
61
61
|
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(className, 'max-h-full h-full flex flex-col'), children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center px-l6 pt-l10 pb-l4", children: [(0, jsx_runtime_1.jsx)("h2", { className: "heading-lg flex-1", children: block.name }), (0, jsx_runtime_1.jsx)("div", { className: "shrink-0 flex items-center gap-l5", children: block.canDelete &&
|
|
62
|
-
(0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.IconButton, { anchorId: anchorId, className: "DeleteAction text-content-primary hover:text-destructive shrink-0", variant: "util", icon: "EllipsisVertical", onClick: e => menu.open(anchorId) }), (0, jsx_runtime_1.jsx)(core_1.Menu, { controller: menu, onItemClick: onMenuClick })] }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 flex flex-col gap-l8 px-l6 pb-l10 overflow-y-scroll scrollbar-thin scroller-fade-top bg-background", children: [messageFields.length > 0 &&
|
|
62
|
+
(0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(core_1.IconButton, { anchorId: anchorId, className: "DeleteAction text-content-primary hover:text-destructive shrink-0", variant: "util", icon: "EllipsisVertical", onClick: e => menu.open(anchorId) }), (0, jsx_runtime_1.jsx)(core_1.Menu, { controller: menu, onItemClick: onMenuClick })] }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 flex flex-col gap-l8 px-l6 pb-l10 overflow-y-scroll scrollbar-thin scroller-fade-top bg-background", tabIndex: -1, children: [messageFields.length > 0 &&
|
|
63
63
|
(0, jsx_runtime_1.jsx)(core_1.FieldsPanel, { title: "Messaging", actions: (0, jsx_runtime_1.jsx)(config_1.BlockConfigButton, { target: "message" }), fields: messageFields }), visualFields.length > 0 &&
|
|
64
64
|
(0, jsx_runtime_1.jsx)(core_1.FieldsPanel, { title: "Visual", actions: (0, jsx_runtime_1.jsx)(config_1.BlockConfigButton, { target: "visual" }), fields: visualFields }), listsFields.length > 0 &&
|
|
65
65
|
(0, jsx_runtime_1.jsx)(core_1.FieldsPanel, { title: "List", actions: (0, jsx_runtime_1.jsx)(config_1.BlockConfigButton, { target: "list" }), fields: listsFields }), extendedFields.length > 0 &&
|
|
@@ -9,15 +9,11 @@ const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
|
9
9
|
const classnames_1 = __importDefault(require("classnames"));
|
|
10
10
|
const react_1 = require("react");
|
|
11
11
|
const core_1 = require("../../core");
|
|
12
|
-
const hooks_1 = require("../hooks");
|
|
13
12
|
// component
|
|
14
13
|
function SettingsEditor({ className }) {
|
|
15
14
|
// bind state + hooks
|
|
16
15
|
const { timezone } = funnel_core_1.AppConfig.get();
|
|
17
|
-
const controller = (0, hooks_1.usePageController)();
|
|
18
16
|
const page = (0, core_1.usePage)();
|
|
19
|
-
const editorApi = (0, core_1.useEditorApi)();
|
|
20
|
-
const router = (0, core_1.useEditorRouter)();
|
|
21
17
|
const { publicationField, slugField } = (0, core_1.useTempFields)({
|
|
22
18
|
publicationField: funnel_core_1.Schema.Field.timestamp({
|
|
23
19
|
name: 'Published Date',
|
|
@@ -27,11 +23,8 @@ function SettingsEditor({ className }) {
|
|
|
27
23
|
}).optional(),
|
|
28
24
|
slugField: funnel_core_1.Schema.Field.slug({ name: 'Slug', minLength: 2, required: true })
|
|
29
25
|
});
|
|
30
|
-
const dialog = (0, core_1.useDialog)();
|
|
31
26
|
const publicationModified = !publicationField.sandboxed && publicationField.modified;
|
|
32
27
|
const slugModified = !slugField.sandboxed && slugField.modified;
|
|
33
|
-
const tagOptions = page.template.tags;
|
|
34
|
-
const { tags } = page;
|
|
35
28
|
const canUnpublish = page.published;
|
|
36
29
|
const canDelete = page.hasSlug && !page.published;
|
|
37
30
|
const showDangerOptions = canUnpublish || canDelete;
|
|
@@ -35,6 +35,8 @@ function BlockConfigButton({ target, anchorId: anchorOverrideId, children = 'Con
|
|
|
35
35
|
const listLayoutPickerRef = (0, react_2.useRef)(null);
|
|
36
36
|
const configuration = (0, core_1.useBlockConfiguration)();
|
|
37
37
|
const pageController = (0, hooks_1.usePageController)();
|
|
38
|
+
const collectionStore = (0, core_1.useCollectionStore)();
|
|
39
|
+
const assetStore = (0, core_1.useAssetStore)();
|
|
38
40
|
// skip if there's no config
|
|
39
41
|
if (!configuration) {
|
|
40
42
|
return null;
|
|
@@ -145,20 +147,36 @@ function BlockConfigButton({ target, anchorId: anchorOverrideId, children = 'Con
|
|
|
145
147
|
title = 'Visual Configuration';
|
|
146
148
|
tip = 'Cropping changes how the image appears on your site, not your original file.';
|
|
147
149
|
// get fields
|
|
148
|
-
const { aspect: aspectField, anchor: anchorField, width: widthField, horizontalAlign: horizontalAlignField } = configuration.visualFields;
|
|
150
|
+
const { aspect: aspectField, anchor: anchorField, width: widthField, horizontalAlign: horizontalAlignField, controls: controlsField, autoPlay: autoPlayField, loop: loopField, mute: muteField, } = configuration.visualFields;
|
|
149
151
|
const { value } = (_a = configuration.getFieldData('visual')) !== null && _a !== void 0 ? _a : {};
|
|
150
|
-
const
|
|
152
|
+
const media = funnel_core_1.Schema.CollectionField.Value.ForInline.filter(value)
|
|
151
153
|
? value
|
|
152
|
-
:
|
|
154
|
+
: funnel_core_1.Schema.CollectionField.Value.ForRef.filter(value)
|
|
155
|
+
? collectionStore.getCollection(value.id)
|
|
156
|
+
: undefined;
|
|
157
|
+
// helpers
|
|
158
|
+
const renderOptionButton = (field) => {
|
|
159
|
+
var _a;
|
|
160
|
+
// skip if there's no field
|
|
161
|
+
if (!field) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
// render
|
|
165
|
+
const enabled = ((_a = field.value) === null || _a === void 0 ? void 0 : _a.value) === true;
|
|
166
|
+
return ((0, jsx_runtime_1.jsx)(core_1.Button, { variant: enabled ? 'primary' : 'secondary', size: "xs", onClick: () => field.value = funnel_core_1.Schema.BooleanField.Value.toData(!enabled), children: field.schema.name }));
|
|
167
|
+
};
|
|
168
|
+
// content
|
|
153
169
|
content = ((0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-l9", children: [(0, jsx_runtime_1.jsxs)("section", { className: "flex flex-col gap-l4", children: [aspectField &&
|
|
154
170
|
(0, jsx_runtime_1.jsx)(core_1.FieldEditor, { field: aspectField, size: "xs" }), anchorField
|
|
155
171
|
? (0, jsx_runtime_1.jsx)(core_1.FieldEditor, { field: anchorField, size: "xs" })
|
|
156
172
|
:
|
|
157
173
|
(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(core_1.FieldHeader, { label: "Anchor", size: "xs" }), (0, jsx_runtime_1.jsx)("p", { className: "label-xs text-content-secondary text-pretty", children: "Your current image size and aspect ratio don't require and anchor (there's no cropping)." })] }), widthField &&
|
|
158
174
|
(0, jsx_runtime_1.jsx)(core_1.FieldEditor, { field: widthField, size: "xs" }, widthField.id), horizontalAlignField &&
|
|
159
|
-
(0, jsx_runtime_1.jsx)(core_1.FieldEditor, { field: horizontalAlignField, size: "xs" }, horizontalAlignField.id)
|
|
175
|
+
(0, jsx_runtime_1.jsx)(core_1.FieldEditor, { field: horizontalAlignField, size: "xs" }, horizontalAlignField.id), (controlsField || autoPlayField || loopField || muteField) &&
|
|
176
|
+
(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-l2", children: [(0, jsx_runtime_1.jsx)(core_1.FieldHeader, { label: "Video Options", size: "xs" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap gap-l4 items-center", children: [renderOptionButton(controlsField), renderOptionButton(autoPlayField)] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap gap-l4 items-center", children: [renderOptionButton(loopField), renderOptionButton(muteField)] })] })] }), funnel_ui_1.Media.Value.filter(media) && renderVisual({
|
|
177
|
+
assetStore,
|
|
160
178
|
configuration,
|
|
161
|
-
visual,
|
|
179
|
+
visual: media,
|
|
162
180
|
aspectField: aspectField,
|
|
163
181
|
anchorField: anchorField
|
|
164
182
|
})] }));
|
|
@@ -280,14 +298,46 @@ function renderListLayoutItem(item) {
|
|
|
280
298
|
// render item in frame
|
|
281
299
|
return ((0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('w-full h-full flex justify-center items-center'), children: content }));
|
|
282
300
|
}
|
|
283
|
-
function renderVisual({ configuration, visual, aspectField, anchorField }) {
|
|
284
|
-
var _a, _b, _c;
|
|
301
|
+
function renderVisual({ assetStore, configuration, visual, aspectField, anchorField }) {
|
|
302
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
303
|
+
// get dimensions
|
|
304
|
+
let width = undefined;
|
|
305
|
+
let height = undefined;
|
|
306
|
+
let image = undefined;
|
|
307
|
+
let video = undefined;
|
|
308
|
+
let embeddedVideo = undefined;
|
|
309
|
+
if (funnel_ui_1.Media.Value.isImage(visual) && ((_c = (_b = (_a = visual.fields) === null || _a === void 0 ? void 0 : _a.image) === null || _b === void 0 ? void 0 : _b.value) === null || _c === void 0 ? void 0 : _c.id)) {
|
|
310
|
+
const asset = assetStore.getAsset(visual.fields.image.value.id);
|
|
311
|
+
image = asset === null || asset === void 0 ? void 0 : asset.value;
|
|
312
|
+
const { dimensions } = (_d = image === null || image === void 0 ? void 0 : image.metadata) !== null && _d !== void 0 ? _d : {};
|
|
313
|
+
width = (_e = dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) !== null && _e !== void 0 ? _e : undefined;
|
|
314
|
+
height = (_f = dimensions === null || dimensions === void 0 ? void 0 : dimensions.height) !== null && _f !== void 0 ? _f : undefined;
|
|
315
|
+
}
|
|
316
|
+
else if (funnel_ui_1.Media.Value.isVideo(visual) && ((_h = (_g = visual.fields) === null || _g === void 0 ? void 0 : _g.video) === null || _h === void 0 ? void 0 : _h.value)) {
|
|
317
|
+
// link local video
|
|
318
|
+
const { video: { value: { local, remote } }, cover: coverRaw } = visual.fields;
|
|
319
|
+
if ((_j = local === null || local === void 0 ? void 0 : local.value) === null || _j === void 0 ? void 0 : _j.id) {
|
|
320
|
+
const asset = assetStore.getAsset(local.value.id);
|
|
321
|
+
video = asset === null || asset === void 0 ? void 0 : asset.value;
|
|
322
|
+
const { dimensions } = (_k = video === null || video === void 0 ? void 0 : video.metadata) !== null && _k !== void 0 ? _k : {};
|
|
323
|
+
width = (_l = dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) !== null && _l !== void 0 ? _l : undefined;
|
|
324
|
+
height = (_m = dimensions === null || dimensions === void 0 ? void 0 : dimensions.height) !== null && _m !== void 0 ? _m : undefined;
|
|
325
|
+
}
|
|
326
|
+
// or remote
|
|
327
|
+
else if (remote === null || remote === void 0 ? void 0 : remote.value) {
|
|
328
|
+
embeddedVideo = remote.value;
|
|
329
|
+
width = embeddedVideo.dimensions.width;
|
|
330
|
+
height = embeddedVideo.dimensions.height;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// slop if there's no asset
|
|
334
|
+
if (!width || !height) {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
285
337
|
// determine layout info
|
|
286
|
-
const { metadata, name, description } = visual;
|
|
287
|
-
const { dimensions: { width, height } } = metadata;
|
|
288
338
|
const isPortrait = width < height;
|
|
289
|
-
const aspect = (
|
|
290
|
-
const anchor = (
|
|
339
|
+
const aspect = (_p = (_o = aspectField === null || aspectField === void 0 ? void 0 : aspectField.value) === null || _o === void 0 ? void 0 : _o.value) !== null && _p !== void 0 ? _p : 'auto';
|
|
340
|
+
const anchor = (_q = anchorField === null || anchorField === void 0 ? void 0 : anchorField.value) === null || _q === void 0 ? void 0 : _q.value;
|
|
291
341
|
const anchorDirection = anchorField
|
|
292
342
|
? anchorField.schema.isValidOption('left')
|
|
293
343
|
? 'x'
|
|
@@ -297,9 +347,13 @@ function renderVisual({ configuration, visual, aspectField, anchorField }) {
|
|
|
297
347
|
return ((0, jsx_runtime_1.jsx)("section", { className: (0, classnames_1.default)('w-full h-[210px]', 'flex flex-col justify-center items-center', 'bg-background rounded-xs'), children: (0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)('relative bg-destructive', {
|
|
298
348
|
'h-full max-h-full w-auto': isPortrait,
|
|
299
349
|
'w-full': !isPortrait
|
|
300
|
-
}), children: [
|
|
301
|
-
? renderImage({ configuration, visual })
|
|
302
|
-
:
|
|
350
|
+
}), children: [image
|
|
351
|
+
? renderImage({ assetStore, configuration, visual: image })
|
|
352
|
+
: video
|
|
353
|
+
? renderVideo({ assetStore, configuration, visual: video })
|
|
354
|
+
: embeddedVideo
|
|
355
|
+
? renderStreamingVideo({ assetStore, configuration, visual: embeddedVideo })
|
|
356
|
+
: null, aspect !== 'auto' && anchor && anchorDirection &&
|
|
303
357
|
(0, jsx_runtime_1.jsx)("div", { className: (0, classnames_1.default)('absolute inset-0 z-supersurface flex', {
|
|
304
358
|
'flex-col': anchorDirection === 'y'
|
|
305
359
|
}), children: (0, jsx_runtime_1.jsxs)(react_1.AnimatePresence, { mode: "popLayout", children: [anchor !== 'left' && anchor !== 'top' &&
|
|
@@ -321,3 +375,6 @@ function renderImage({ visual }) {
|
|
|
321
375
|
function renderVideo({ visual }) {
|
|
322
376
|
return ((0, jsx_runtime_1.jsx)("video", { className: "max-w-full max-h-full", src: visual.url, autoPlay: true, muted: true, loop: true, playsInline: true }));
|
|
323
377
|
}
|
|
378
|
+
function renderStreamingVideo({ visual }) {
|
|
379
|
+
return ((0, jsx_runtime_1.jsx)("img", { className: "max-w-full max-h-full", src: visual.thumbUrl, alt: "Video preview" }));
|
|
380
|
+
}
|
|
@@ -76,7 +76,7 @@ function PageEditor({ templateId, region, language, slug }) {
|
|
|
76
76
|
};
|
|
77
77
|
const onSelectItem = (item) => setItemId(item.identifier);
|
|
78
78
|
// render
|
|
79
|
-
return ((0, jsx_runtime_1.jsx)(hooks_1.PageControllerContext.Provider, { value: controllerContext, children: (0, jsx_runtime_1.jsx)(core_1.PageContext.Provider, { value: pageContext, children: (0, jsx_runtime_1.jsx)(core_1.AssetStoreContext.Provider, { value: page, children: (0, jsx_runtime_1.jsx)(core_1.CollectionStoreContext.Provider, { value: page, children: (0, jsx_runtime_1.jsx)(core_1.PageRefStoreContext.Provider, { value: pageRefStoreProxy, children: (0, jsx_runtime_1.jsx)(config_1.BlockConfigurationProvider, { item: selectedItem, children: (0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col bg-background", children: [(0, jsx_runtime_1.jsx)(components_1.PageHeader, { target: target, selectedItem: selectedItem, onBack: onHeaderBack }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1", children: (0, jsx_runtime_1.jsxs)("div", { className: "absolute inset-0 flex", children: [(0, jsx_runtime_1.jsx)("section", { className: "w-[220px] lg:w-[240px] xl:w-[280px] shrink-0 overflow-y-scroll scrollbar-thin", children: (0, jsx_runtime_1.jsx)(components_1.PageNav, { selectedItem: selectedItem, onSelectItem: onSelectItem }) }), (0, jsx_runtime_1.jsx)("section", { className: "flex-1 h-full max-h-full max-w-[1000px] mx-auto", children: (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { mode: "wait", initial: false, children: renderContent({ target, controller, page, selectedItem, onSelectItem }) }) }), (0, jsx_runtime_1.jsxs)(react_1.motion.section, { className: (0, classnames_1.default)('hidden lg:flex lg:w-[320px] shrink-0 overflow-y-scroll scrollbar-thin', 'flex-col gap-l8 pt-l9 px-l8 pb-l8'), layout: true, children: [(0, jsx_runtime_1.jsx)("h2", { className: "label-sm text-content-tertiary uppercase", children: "Inspector" }), (0, jsx_runtime_1.jsxs)(react_1.AnimatePresence, { mode: "popLayout", children: [page && selectedItem && (selectedItem instanceof core_1.Block || selectedItem instanceof core_1.SectionBlock) &&
|
|
79
|
+
return ((0, jsx_runtime_1.jsx)(hooks_1.PageControllerContext.Provider, { value: controllerContext, children: (0, jsx_runtime_1.jsx)(core_1.PageContext.Provider, { value: pageContext, children: (0, jsx_runtime_1.jsx)(core_1.AssetStoreContext.Provider, { value: page, children: (0, jsx_runtime_1.jsx)(core_1.CollectionStoreContext.Provider, { value: page, children: (0, jsx_runtime_1.jsx)(core_1.PageRefStoreContext.Provider, { value: pageRefStoreProxy, children: (0, jsx_runtime_1.jsx)(config_1.BlockConfigurationProvider, { item: selectedItem, children: (0, jsx_runtime_1.jsxs)("div", { className: "w-dvw h-dvh flex flex-col bg-background", children: [(0, jsx_runtime_1.jsx)(components_1.PageHeader, { target: target, selectedItem: selectedItem, onBack: onHeaderBack }), (0, jsx_runtime_1.jsx)("div", { className: "relative flex-1", children: (0, jsx_runtime_1.jsxs)("div", { className: "absolute inset-0 flex z-default", children: [(0, jsx_runtime_1.jsx)("section", { className: "w-[220px] lg:w-[240px] xl:w-[280px] shrink-0 overflow-y-scroll scrollbar-thin", tabIndex: -1, children: (0, jsx_runtime_1.jsx)(components_1.PageNav, { selectedItem: selectedItem, onSelectItem: onSelectItem }) }), (0, jsx_runtime_1.jsx)("section", { className: "flex-1 h-full max-h-full max-w-[1000px] mx-auto", tabIndex: -1, children: (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { mode: "wait", initial: false, children: renderContent({ target, controller, page, selectedItem, onSelectItem }) }) }), (0, jsx_runtime_1.jsxs)(react_1.motion.section, { className: (0, classnames_1.default)('hidden lg:flex lg:w-[320px] shrink-0 overflow-y-scroll scrollbar-thin', 'flex-col gap-l8 pt-l9 px-l8 pb-l8'), layout: true, tabIndex: -1, children: [(0, jsx_runtime_1.jsx)("h2", { className: "label-sm text-content-tertiary uppercase", children: "Inspector" }), (0, jsx_runtime_1.jsxs)(react_1.AnimatePresence, { mode: "popLayout", children: [page && selectedItem && (selectedItem instanceof core_1.Block || selectedItem instanceof core_1.SectionBlock) &&
|
|
80
80
|
(0, jsx_runtime_1.jsx)(components_1.BlockConfigPanel, {}, "block.config"), page && selectedItem &&
|
|
81
81
|
(0, jsx_runtime_1.jsx)(components_1.PageStatus, { page: page, selectedItem: selectedItem, onSelectItem: onSelectItem }, "status")] })] })] }) })] }) }) }) }) }) }) }));
|
|
82
82
|
}
|