@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.
Files changed (185) hide show
  1. package/dist/EditorApp.js +1 -1
  2. package/dist/EditorRoutes.js +7 -5
  3. package/dist/changesets/screens/ChangeSetViewer.js +1 -1
  4. package/dist/changesets/screens/ChangeSetsExplorer.js +1 -2
  5. package/dist/collection/hooks/CollectionController.d.ts +5 -16
  6. package/dist/collection/hooks/CollectionController.js +18 -37
  7. package/dist/collection/hooks/ICollectionController.d.ts +24 -0
  8. package/dist/collection/hooks/ICollectionController.js +20 -0
  9. package/dist/collection/hooks/index.d.ts +1 -0
  10. package/dist/collection/hooks/index.js +1 -0
  11. package/dist/collection/hooks/useCollectionController.d.ts +3 -3
  12. package/dist/collection/screens/CollectionEditor.js +2 -2
  13. package/dist/components.d.ts +15 -3
  14. package/dist/components.js +18 -3
  15. package/dist/core/components/feedback/dialog/MinimalDialogLayout.js +1 -1
  16. package/dist/core/components/fields/BooleanField.d.ts +2 -1
  17. package/dist/core/components/fields/BooleanField.js +2 -2
  18. package/dist/core/components/fields/DateField.d.ts +2 -1
  19. package/dist/core/components/fields/DateField.js +2 -2
  20. package/dist/core/components/fields/DynamicPagesEditor.d.ts +2 -1
  21. package/dist/core/components/fields/DynamicPagesEditor.js +1 -1
  22. package/dist/core/components/fields/EnumField.d.ts +2 -1
  23. package/dist/core/components/fields/EnumField.js +2 -2
  24. package/dist/core/components/fields/FieldCard.d.ts +1 -0
  25. package/dist/core/components/fields/FieldCard.js +8 -1
  26. package/dist/core/components/fields/FieldEditor.d.ts +2 -1
  27. package/dist/core/components/fields/FieldEditor.js +11 -11
  28. package/dist/core/components/fields/FieldLayout.d.ts +2 -1
  29. package/dist/core/components/fields/FieldLayout.js +3 -3
  30. package/dist/core/components/fields/ListEditor.d.ts +2 -1
  31. package/dist/core/components/fields/ListEditor.js +5 -6
  32. package/dist/core/components/fields/OptInField.d.ts +2 -1
  33. package/dist/core/components/fields/OptInField.js +43 -3
  34. package/dist/core/components/fields/RichTextEditor.js +1 -1
  35. package/dist/core/components/fields/RichTextField.d.ts +2 -1
  36. package/dist/core/components/fields/RichTextField.js +3 -5
  37. package/dist/core/components/fields/TextField.d.ts +2 -0
  38. package/dist/core/components/fields/TextField.js +2 -2
  39. package/dist/core/components/fields/TimestampField.d.ts +2 -1
  40. package/dist/core/components/fields/TimestampField.js +3 -3
  41. package/dist/core/components/fields/asset/AssetEditor.d.ts +1 -2
  42. package/dist/core/components/fields/asset/AssetEditor.js +29 -49
  43. package/dist/core/components/fields/asset/AssetPicker.js +6 -6
  44. package/dist/core/components/fields/asset/AssetUploader.d.ts +1 -2
  45. package/dist/core/components/fields/asset/AssetUploader.js +39 -35
  46. package/dist/core/components/fields/asset/preview/VideoPreview.js +16 -11
  47. package/dist/core/components/fields/asset/useAssetFields.d.ts +2 -17
  48. package/dist/core/components/fields/asset/useAssetFields.js +0 -21
  49. package/dist/core/components/fields/collection/CollectionEditor.d.ts +2 -1
  50. package/dist/core/components/fields/collection/CollectionEditor.js +18 -4
  51. package/dist/core/components/fields/collection/CollectionPicker.d.ts +2 -2
  52. package/dist/core/components/fields/collection/CollectionPicker.js +3 -4
  53. package/dist/core/components/fields/dynamicPages/PagePriorityDialog.js +1 -1
  54. package/dist/core/components/fields/embed/EmbeddedVideoEditor.d.ts +2 -2
  55. package/dist/core/components/fields/embed/EmbeddedVideoEditor.js +50 -31
  56. package/dist/core/components/fields/factories/AssetFactory.d.ts +3 -3
  57. package/dist/core/components/fields/factories/AssetFactory.js +18 -13
  58. package/dist/core/components/fields/factories/CollectionFactory.d.ts +3 -3
  59. package/dist/core/components/fields/factories/CollectionFactory.js +20 -13
  60. package/dist/core/components/fields/factories/EmbeddedVideoFactory.d.ts +3 -3
  61. package/dist/core/components/fields/factories/EmbeddedVideoFactory.js +17 -8
  62. package/dist/core/components/fields/factories/FieldValueFactory.d.ts +7 -5
  63. package/dist/core/components/fields/factories/FieldValueFactory.js +57 -13
  64. package/dist/core/components/fields/factories/LinkFactory.d.ts +3 -3
  65. package/dist/core/components/fields/factories/LinkFactory.js +17 -8
  66. package/dist/core/components/fields/factories/MediaFactory.d.ts +13 -0
  67. package/dist/core/components/fields/factories/MediaFactory.js +212 -0
  68. package/dist/core/components/fields/factories/ObjectFactory.d.ts +3 -2
  69. package/dist/core/components/fields/factories/ObjectFactory.js +16 -2
  70. package/dist/core/components/fields/factories/TextFactory.d.ts +3 -3
  71. package/dist/core/components/fields/factories/TextFactory.js +16 -10
  72. package/dist/core/components/fields/link/LinkEditor.d.ts +2 -2
  73. package/dist/core/components/fields/link/LinkEditor.js +18 -6
  74. package/dist/core/components/fields/list/CreateFieldButton.js +1 -1
  75. package/dist/core/components/fields/media/MediaCard.d.ts +7 -0
  76. package/dist/core/components/fields/media/MediaCard.js +92 -0
  77. package/dist/core/components/fields/media/MediaEditor.d.ts +36 -0
  78. package/dist/core/components/fields/media/MediaEditor.js +264 -0
  79. package/dist/core/components/fields/media/index.d.ts +2 -0
  80. package/dist/core/components/fields/media/index.js +18 -0
  81. package/dist/core/components/fields/object/ObjectEditor.d.ts +2 -1
  82. package/dist/core/components/fields/object/ObjectEditor.js +16 -2
  83. package/dist/core/components/fields/page/PagePicker.js +1 -1
  84. package/dist/core/components/interaction/Combobox.js +1 -1
  85. package/dist/core/components/interaction/MultiSelectControls.js +2 -5
  86. package/dist/core/components/interaction/Popup.d.ts +11 -7
  87. package/dist/core/components/interaction/Popup.js +8 -6
  88. package/dist/core/components/interaction/QuickEditor.js +1 -1
  89. package/dist/core/components/interaction/QuickInput.d.ts +2 -4
  90. package/dist/core/components/interaction/QuickInput.js +6 -2
  91. package/dist/core/components/interaction/QuickPicker.js +1 -1
  92. package/dist/core/components/interaction/SideSheet.js +1 -1
  93. package/dist/core/components/interaction/centersheet/CenterSheet.js +7 -1
  94. package/dist/core/components/interaction/centersheet/CenterSheetContainer.js +3 -1
  95. package/dist/core/components/interaction/menu/Menu.d.ts +8 -19
  96. package/dist/core/components/interaction/menu/Menu.js +26 -60
  97. package/dist/core/components/interaction/menu/useMenuController.d.ts +4 -2
  98. package/dist/core/components/interaction/menu/useMenuController.js +4 -1
  99. package/dist/core/components/transitions/FadeIn.js +1 -1
  100. package/dist/core/components/visuals/Icon.d.ts +1 -1
  101. package/dist/core/components/visuals/Icon.js +3 -0
  102. package/dist/core/containers/AssetRepositoryContainer.d.ts +2 -0
  103. package/dist/core/containers/AssetRepositoryContainer.js +18 -0
  104. package/dist/core/containers/CollectionRepositoryContainer.d.ts +2 -0
  105. package/dist/core/containers/CollectionRepositoryContainer.js +18 -0
  106. package/dist/core/containers/PageRepositoryContainer.d.ts +2 -0
  107. package/dist/core/containers/PageRepositoryContainer.js +18 -0
  108. package/dist/core/containers/index.d.ts +3 -0
  109. package/dist/core/containers/index.js +19 -0
  110. package/dist/core/domain/Block.js +2 -1
  111. package/dist/core/domain/BlockConfiguration.d.ts +4 -1
  112. package/dist/core/domain/BlockConfiguration.js +59 -3
  113. package/dist/core/domain/Collection.d.ts +7 -25
  114. package/dist/core/domain/Collection.js +2 -16
  115. package/dist/core/domain/CollectionBrowser.d.ts +3 -2
  116. package/dist/core/domain/CollectionBrowser.js +3 -3
  117. package/dist/core/domain/CollectionFieldProxy.d.ts +12 -8
  118. package/dist/core/domain/CollectionFieldProxy.js +15 -9
  119. package/dist/core/domain/CollectionGroup.d.ts +0 -5
  120. package/dist/core/domain/CollectionGroup.js +0 -7
  121. package/dist/core/domain/CollectionSummary.d.ts +2 -2
  122. package/dist/core/domain/Collections.d.ts +3 -3
  123. package/dist/core/domain/Collections.js +4 -6
  124. package/dist/core/domain/ICollection.d.ts +72 -0
  125. package/dist/core/domain/ICollection.js +20 -0
  126. package/dist/core/domain/IPage.d.ts +16 -1
  127. package/dist/core/domain/Page.js +2 -2
  128. package/dist/core/domain/Pages.js +4 -6
  129. package/dist/core/domain/SectionBlock.js +2 -1
  130. package/dist/core/domain/Site.d.ts +4 -4
  131. package/dist/core/domain/Site.js +3 -5
  132. package/dist/core/domain/index.d.ts +1 -1
  133. package/dist/core/domain/index.js +1 -1
  134. package/dist/core/hooks/index.d.ts +4 -3
  135. package/dist/core/hooks/index.js +4 -3
  136. package/dist/core/hooks/useAssetRepository.d.ts +3 -0
  137. package/dist/core/hooks/useAssetRepository.js +11 -0
  138. package/dist/core/hooks/useCollection.d.ts +4 -4
  139. package/dist/core/hooks/useCollectionRepository.d.ts +3 -2
  140. package/dist/core/hooks/useCollectionRepository.js +4 -4
  141. package/dist/core/hooks/useCollections.js +4 -0
  142. package/dist/core/hooks/usePageRepository.d.ts +3 -2
  143. package/dist/core/hooks/usePageRepository.js +4 -4
  144. package/dist/core/hooks/useSite.js +4 -0
  145. package/dist/core/hooks/useTempFields.d.ts +2 -3
  146. package/dist/core/index.d.ts +1 -0
  147. package/dist/core/index.js +1 -0
  148. package/dist/core/repository/AssetRepository.d.ts +10 -0
  149. package/dist/core/repository/AssetRepository.js +22 -0
  150. package/dist/core/repository/CollectionRepository.d.ts +22 -21
  151. package/dist/core/repository/CollectionRepository.js +23 -161
  152. package/dist/core/repository/CollectionSerializer.d.ts +4 -1
  153. package/dist/core/repository/CollectionSerializer.js +3 -3
  154. package/dist/core/repository/IAssetRepository.d.ts +25 -0
  155. package/dist/core/repository/ICollectionRepository.d.ts +61 -0
  156. package/dist/core/repository/ICollectionRepository.js +2 -0
  157. package/dist/core/repository/IPageRepository.d.ts +40 -0
  158. package/dist/core/repository/IPageRepository.js +2 -0
  159. package/dist/core/repository/PageRepository.d.ts +5 -8
  160. package/dist/core/repository/PageRepository.js +7 -280
  161. package/dist/core/repository/SerializeCollectionUpdate.d.ts +8 -0
  162. package/dist/core/repository/SerializeCollectionUpdate.js +168 -0
  163. package/dist/core/repository/SerializePageUpdate.d.ts +10 -0
  164. package/dist/core/repository/SerializePageUpdate.js +292 -0
  165. package/dist/core/repository/index.d.ts +4 -0
  166. package/dist/core/repository/index.js +4 -0
  167. package/dist/core/splash/SplashContainer.d.ts +4 -2
  168. package/dist/core/splash/SplashContainer.js +3 -3
  169. package/dist/dashboard/screens/Dashboard.js +1 -1
  170. package/dist/devtools/screens/Devtools.js +1 -1
  171. package/dist/explore/components/CreatePageDialog.d.ts +2 -2
  172. package/dist/explore/screens/CollectionExplorer.js +1 -1
  173. package/dist/explore/screens/CollectionsExplorer.js +1 -1
  174. package/dist/explore/screens/PageExplorer.js +1 -1
  175. package/dist/explore/screens/SiteExplorer.js +1 -1
  176. package/dist/page/components/BlockEditor.js +1 -1
  177. package/dist/page/components/SettingsEditor.js +0 -7
  178. package/dist/page/components/config/BlockConfigButton.js +71 -14
  179. package/dist/page/screens/PageEditor.js +1 -1
  180. package/dist/styles/index.css +24 -20
  181. package/dist/styles/tailwind.js +1 -0
  182. package/dist/users/screens/UserExplorer.js +1 -1
  183. package/package.json +2 -2
  184. package/dist/core/domain/TranslateSchema.d.ts +0 -7
  185. /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(`Signing you in`);
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 { Page, Pages, Popup, Site } from '../../core';
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<Page | undefined>;
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 visual = funnel_core_1.Schema.AssetField.LinkedValue.Visual.filter(value)
152
+ const media = funnel_core_1.Schema.CollectionField.Value.ForInline.filter(value)
151
153
  ? value
152
- : undefined;
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)] }), visual && renderVisual({
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 = (_b = (_a = aspectField === null || aspectField === void 0 ? void 0 : aspectField.value) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 'auto';
290
- const anchor = (_c = anchorField === null || anchorField === void 0 ? void 0 : anchorField.value) === null || _c === void 0 ? void 0 : _c.value;
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: [funnel_core_1.Schema.AssetField.LinkedValue.Image.filter(visual)
301
- ? renderImage({ configuration, visual })
302
- : renderVideo({ configuration, visual }), aspect !== 'auto' && anchor && anchorDirection &&
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
  }