@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
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
14
|
exports.AssetUploader = void 0;
|
|
4
15
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
16
|
const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
6
17
|
const react_1 = require("motion/react");
|
|
7
18
|
const react_2 = require("react");
|
|
8
|
-
const client_1 = require("../../../client");
|
|
9
19
|
const hooks_1 = require("../../../hooks");
|
|
10
20
|
const feedback_1 = require("../../feedback");
|
|
11
21
|
const interaction_1 = require("../../interaction");
|
|
@@ -21,22 +31,24 @@ exports.AssetUploader = (0, react_2.forwardRef)(function AssetUploader(_, ref) {
|
|
|
21
31
|
// bind props + hooks
|
|
22
32
|
const [deferral, setDeferral] = (0, react_2.useState)(undefined);
|
|
23
33
|
const [result, setResult] = (0, react_2.useState)();
|
|
34
|
+
const [uploading, setUploading] = (0, react_2.useState)(false);
|
|
24
35
|
const [schema, setSchema] = (0, react_2.useState)();
|
|
25
|
-
const [
|
|
36
|
+
const [popupProps, setPopupProps] = (0, react_2.useState)();
|
|
26
37
|
const [errorLevel, setErrorLevel] = (0, react_2.useState)('none');
|
|
27
38
|
const [error, setError] = (0, react_2.useState)();
|
|
28
39
|
const [assetInfo, setAssetInfo] = (0, react_2.useState)();
|
|
29
|
-
const { nameField,
|
|
40
|
+
const { nameField, descriptionField } = (0, useAssetFields_1.useAssetFields)();
|
|
30
41
|
const [shared, setShared] = (0, react_2.useState)(false);
|
|
31
|
-
const
|
|
42
|
+
const assetRepo = (0, hooks_1.useAssetRepository)();
|
|
32
43
|
const assetStore = (0, hooks_1.useAssetStore)();
|
|
33
44
|
const assetOptions = (0, react_2.useMemo)(() => getAssetOptions(schema), [schema]);
|
|
34
45
|
// export service
|
|
35
46
|
(0, react_2.useImperativeHandle)(ref, () => ({
|
|
36
|
-
upload: async (
|
|
47
|
+
upload: async (_a) => {
|
|
48
|
+
var { schema } = _a, popupProps = __rest(_a, ["schema"]);
|
|
37
49
|
// reset state
|
|
38
50
|
setSchema(schema);
|
|
39
|
-
|
|
51
|
+
setPopupProps(popupProps);
|
|
40
52
|
setErrorLevel('none');
|
|
41
53
|
setError(undefined);
|
|
42
54
|
setShared(false);
|
|
@@ -56,9 +68,7 @@ exports.AssetUploader = (0, react_2.forwardRef)(function AssetUploader(_, ref) {
|
|
|
56
68
|
// update fields if there's a file
|
|
57
69
|
if (assetInfo) {
|
|
58
70
|
nameField.reset(funnel_core_1.Schema.TextField.Value.toData(assetInfo.fileName));
|
|
59
|
-
anchorField.reset(funnel_core_1.Schema.EnumField.Value.toData('center'));
|
|
60
71
|
descriptionField.reset(null);
|
|
61
|
-
accessibleField.reset(funnel_core_1.Schema.EnumField.Value.toData('system'));
|
|
62
72
|
}
|
|
63
73
|
};
|
|
64
74
|
const onValidate = () => {
|
|
@@ -69,8 +79,7 @@ exports.AssetUploader = (0, react_2.forwardRef)(function AssetUploader(_, ref) {
|
|
|
69
79
|
// check if level
|
|
70
80
|
let valid = nameField.valid;
|
|
71
81
|
if (valid && assetInfo.isVisual) {
|
|
72
|
-
valid =
|
|
73
|
-
(!descriptionField.exists || descriptionField.valid);
|
|
82
|
+
valid = !descriptionField.exists || descriptionField.valid;
|
|
74
83
|
}
|
|
75
84
|
// update error level
|
|
76
85
|
setErrorLevel('all');
|
|
@@ -86,11 +95,13 @@ exports.AssetUploader = (0, react_2.forwardRef)(function AssetUploader(_, ref) {
|
|
|
86
95
|
}
|
|
87
96
|
// handle upload
|
|
88
97
|
try {
|
|
98
|
+
// start upload
|
|
99
|
+
setUploading(true);
|
|
89
100
|
// create meta
|
|
90
|
-
const metadata = await getAssetMetadata({ assetInfo
|
|
101
|
+
const metadata = await getAssetMetadata({ assetInfo });
|
|
91
102
|
console.debug('[AssetUploader/onUpload] uploading asset', { assetInfo, metadata });
|
|
92
103
|
// upload new file
|
|
93
|
-
const uploadedFile = await
|
|
104
|
+
const uploadedFile = await assetRepo.uploadFile({
|
|
94
105
|
file: assetInfo.file,
|
|
95
106
|
type: assetInfo.mimeType,
|
|
96
107
|
size: assetInfo.size,
|
|
@@ -115,6 +126,10 @@ exports.AssetUploader = (0, react_2.forwardRef)(function AssetUploader(_, ref) {
|
|
|
115
126
|
console.error('[AssetUploader/upload] file upload failure', e);
|
|
116
127
|
setError(feedback_1.ErrorMessage.getGenericError((e instanceof Error) ? e : new funnel_core_1.ServerError()));
|
|
117
128
|
}
|
|
129
|
+
// clear uploading flag
|
|
130
|
+
finally {
|
|
131
|
+
setUploading(false);
|
|
132
|
+
}
|
|
118
133
|
};
|
|
119
134
|
const onCancel = () => {
|
|
120
135
|
// set result (triggers uploader to close)
|
|
@@ -129,12 +144,12 @@ exports.AssetUploader = (0, react_2.forwardRef)(function AssetUploader(_, ref) {
|
|
|
129
144
|
deferral.resolve(result !== null && result !== void 0 ? result : undefined);
|
|
130
145
|
};
|
|
131
146
|
// skip if we don't have any params
|
|
132
|
-
if (!deferral || !schema || !
|
|
147
|
+
if (!deferral || !schema || !popupProps) {
|
|
133
148
|
return null;
|
|
134
149
|
}
|
|
135
150
|
// render
|
|
136
|
-
return ((0, jsx_runtime_1.jsxs)(interaction_1.MiniEditor, { className: "flex flex-col gap-l8", title: "Upload Asset", open: result === undefined,
|
|
137
|
-
(0, jsx_runtime_1.jsx)(feedback_1.Note, { variant: "tip", children: schema.description }), (0, jsx_runtime_1.jsx)(AssetSelectorPane_1.AssetSelectorPane, { options: assetOptions, onAssetChanged: onAssetChanged }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { children: (0, jsx_runtime_1.jsx)(FieldErrorController_1.FieldErrorController, { errorLevel: errorLevel, children: renderAssetInfo({ assetInfo, nameField,
|
|
151
|
+
return ((0, jsx_runtime_1.jsxs)(interaction_1.MiniEditor, Object.assign({ className: "flex flex-col gap-l8", title: "Upload Asset", open: result === undefined, canSave: onValidate, disableSave: !(assetInfo === null || assetInfo === void 0 ? void 0 : assetInfo.isValid), renderSaveLabel: () => 'Upload', customActions: (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", iconLeft: "ImageDown", disabled: uploading, onClick: () => setResult('pick'), children: "Open Library" }), onSave: onUpload, onClose: onCancel, onClosed: onPickerClosed }, popupProps, { children: [schema.description &&
|
|
152
|
+
(0, jsx_runtime_1.jsx)(feedback_1.Note, { variant: "tip", children: schema.description }), (0, jsx_runtime_1.jsx)(AssetSelectorPane_1.AssetSelectorPane, { options: assetOptions, onAssetChanged: onAssetChanged }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { children: (0, jsx_runtime_1.jsx)(FieldErrorController_1.FieldErrorController, { errorLevel: errorLevel, children: renderAssetInfo({ assetInfo, nameField, descriptionField, shared, setShared, uploading }) }) })] })));
|
|
138
153
|
});
|
|
139
154
|
function getAssetOptions(schema) {
|
|
140
155
|
// return empty options if there's no schema
|
|
@@ -158,52 +173,41 @@ function getAssetOptions(schema) {
|
|
|
158
173
|
// normalize options
|
|
159
174
|
return AssetInfo_1.AssetInfo.Options.normalize(options);
|
|
160
175
|
}
|
|
161
|
-
function renderAssetInfo({ assetInfo, nameField,
|
|
176
|
+
function renderAssetInfo({ assetInfo, nameField, descriptionField, shared, setShared, uploading }) {
|
|
162
177
|
// skip if there's no asset info
|
|
163
178
|
if (!assetInfo || !assetInfo.isValid) {
|
|
164
179
|
return null;
|
|
165
180
|
}
|
|
166
181
|
// build fields
|
|
167
182
|
const fields = [
|
|
168
|
-
(0, jsx_runtime_1.jsx)(FieldEditor_1.FieldEditor, { field: nameField }, "name")
|
|
183
|
+
(0, jsx_runtime_1.jsx)(FieldEditor_1.FieldEditor, { field: nameField, disabled: uploading }, "name")
|
|
169
184
|
];
|
|
170
185
|
// add fields related to visuals
|
|
171
186
|
if (assetInfo.isVisual) {
|
|
172
|
-
// add anchor
|
|
173
|
-
fields.push((0, jsx_runtime_1.jsx)(FieldEditor_1.FieldEditor, { field: anchorField }, "anchor"));
|
|
174
|
-
// add accessible flag (for videos)
|
|
175
|
-
if (assetInfo.isVideo) {
|
|
176
|
-
fields.push((0, jsx_runtime_1.jsx)(FieldEditor_1.FieldEditor, { field: accessibleField }, "accessible"));
|
|
177
|
-
}
|
|
178
|
-
// get description
|
|
179
187
|
fields.push(descriptionField.exists
|
|
180
|
-
? (0, jsx_runtime_1.jsx)(FieldEditor_1.FieldEditor, { field: descriptionField }, "desc")
|
|
181
|
-
: (0, jsx_runtime_1.jsx)(OptInField_1.OptInField, { field: descriptionField }, "desc.option"));
|
|
188
|
+
? (0, jsx_runtime_1.jsx)(FieldEditor_1.FieldEditor, { field: descriptionField, disabled: uploading }, "desc")
|
|
189
|
+
: (0, jsx_runtime_1.jsx)(OptInField_1.OptInField, { field: descriptionField, disabled: uploading }, "desc.option"));
|
|
182
190
|
}
|
|
183
191
|
// render editing fields
|
|
184
|
-
return ((0, jsx_runtime_1.jsxs)(transitions_1.FadeIn, { className: "flex flex-col gap-l8", children: [fields, (0, jsx_runtime_1.jsx)(interaction_1.Checkbox, { checked: shared, onChange: setShared, children: "Store in global media library" })] }, "fields"));
|
|
192
|
+
return ((0, jsx_runtime_1.jsxs)(transitions_1.FadeIn, { className: "flex flex-col gap-l8", children: [fields, (0, jsx_runtime_1.jsx)(interaction_1.Checkbox, { checked: shared, onChange: setShared, disabled: uploading, children: "Store in global media library" })] }, "fields"));
|
|
185
193
|
}
|
|
186
|
-
async function getAssetMetadata({ assetInfo
|
|
187
|
-
var _a;
|
|
194
|
+
async function getAssetMetadata({ assetInfo }) {
|
|
188
195
|
const { fileType, dimensions, blurHash } = assetInfo;
|
|
189
196
|
switch (fileType) {
|
|
190
197
|
case 'image':
|
|
191
198
|
return {
|
|
192
|
-
crop:
|
|
199
|
+
crop: 'center',
|
|
193
200
|
dimensions,
|
|
194
201
|
blurHash
|
|
195
202
|
};
|
|
196
203
|
case 'icon':
|
|
197
204
|
return { dimensions };
|
|
198
205
|
case 'video': {
|
|
199
|
-
const accessible = (_a = funnel_core_1.Schema.EnumField.Value.fromData(accessibleField.value)) !== null && _a !== void 0 ? _a : 'system';
|
|
200
206
|
return {
|
|
201
|
-
crop:
|
|
207
|
+
crop: 'center',
|
|
202
208
|
dimensions,
|
|
203
209
|
blurHash,
|
|
204
|
-
accessible:
|
|
205
|
-
? 'system'
|
|
206
|
-
: accessible === 'true'
|
|
210
|
+
accessible: 'system'
|
|
207
211
|
};
|
|
208
212
|
}
|
|
209
213
|
default:
|
|
@@ -11,11 +11,13 @@ const classnames_1 = __importDefault(require("classnames"));
|
|
|
11
11
|
const react_1 = require("react");
|
|
12
12
|
// component
|
|
13
13
|
function VideoPreview({ className, asset, active }) {
|
|
14
|
+
var _a;
|
|
14
15
|
// bind state + refs
|
|
15
16
|
const { url, metadata } = asset;
|
|
16
17
|
const { blurHash } = metadata;
|
|
17
18
|
const [videoRef, video] = (0, client_1.useRefElement)();
|
|
18
19
|
const videoProxy = (0, client_1.useVideoProxy)(video);
|
|
20
|
+
const videoState = (_a = videoProxy === null || videoProxy === void 0 ? void 0 : videoProxy.state) !== null && _a !== void 0 ? _a : 'uninitialized';
|
|
19
21
|
const blurCanvasRef = (0, react_1.useRef)(null);
|
|
20
22
|
// decode blurhash (if any)
|
|
21
23
|
(0, react_1.useEffect)(() => {
|
|
@@ -44,7 +46,10 @@ function VideoPreview({ className, asset, active }) {
|
|
|
44
46
|
});
|
|
45
47
|
// cancel on unmount
|
|
46
48
|
return () => {
|
|
49
|
+
// mark cancelled
|
|
47
50
|
cancelled = true;
|
|
51
|
+
// stop video (if required)
|
|
52
|
+
videoProxy.pause().catch(console.error);
|
|
48
53
|
};
|
|
49
54
|
}, [videoProxy]);
|
|
50
55
|
// start/stop video when active
|
|
@@ -53,22 +58,22 @@ function VideoPreview({ className, asset, active }) {
|
|
|
53
58
|
if (!videoProxy) {
|
|
54
59
|
return;
|
|
55
60
|
}
|
|
56
|
-
//
|
|
57
|
-
if (
|
|
61
|
+
// or ignore if it's not ready (playing or paused)
|
|
62
|
+
else if (videoState !== 'ready' && videoState !== 'playing') {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// start video if not playing
|
|
66
|
+
const playbackRate = active ? 1 : 0.33;
|
|
67
|
+
if (videoProxy.state !== 'playing') {
|
|
58
68
|
videoProxy
|
|
59
|
-
.play({ playbackRate
|
|
69
|
+
.play({ playbackRate, loop: true })
|
|
60
70
|
.catch(console.error);
|
|
61
71
|
}
|
|
72
|
+
// or adjust speed
|
|
62
73
|
else {
|
|
63
|
-
videoProxy
|
|
64
|
-
.pause()
|
|
65
|
-
.catch(console.error);
|
|
74
|
+
videoProxy.video.playbackRate = playbackRate;
|
|
66
75
|
}
|
|
67
|
-
|
|
68
|
-
return () => {
|
|
69
|
-
videoProxy.pause().catch(console.error);
|
|
70
|
-
};
|
|
71
|
-
}, [videoProxy, active]);
|
|
76
|
+
}, [videoProxy, videoState, active]);
|
|
72
77
|
// render
|
|
73
78
|
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)(className, 'relative w-full h-full'), children: [blurHash &&
|
|
74
79
|
(0, jsx_runtime_1.jsx)("canvas", { ref: blurCanvasRef, className: "absolute inset-0 w-full h-full", width: 32, height: 32, draggable: false }), (0, jsx_runtime_1.jsx)("video", { ref: videoRef, className: (0, classnames_1.default)('absolute inset-0 w-full h-full object-cover cursor-pointer interpolate', {
|
|
@@ -1,20 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function useAssetFields(): import("
|
|
1
|
+
import { Schema } from '@nascentdigital/funnel-core';
|
|
2
|
+
export declare function useAssetFields(): import("@nascentdigital/funnel-core").SchemaToFields<{
|
|
3
3
|
nameField: Schema.TextField;
|
|
4
|
-
anchorField: Schema.EnumField<Schema.EnumField.Options<Position>>;
|
|
5
|
-
accessibleField: Schema.EnumField<{
|
|
6
|
-
system: {
|
|
7
|
-
name: string;
|
|
8
|
-
hint: string;
|
|
9
|
-
};
|
|
10
|
-
true: {
|
|
11
|
-
name: string;
|
|
12
|
-
hint: string;
|
|
13
|
-
};
|
|
14
|
-
false: {
|
|
15
|
-
name: string;
|
|
16
|
-
hint: string;
|
|
17
|
-
};
|
|
18
|
-
}>;
|
|
19
4
|
descriptionField: Schema.TextField;
|
|
20
5
|
}>;
|
|
@@ -9,27 +9,6 @@ function useAssetFields() {
|
|
|
9
9
|
nameField: funnel_core_1.Schema.TextField.slug({
|
|
10
10
|
name: 'Name'
|
|
11
11
|
}),
|
|
12
|
-
anchorField: funnel_core_1.Schema.Field.enumeration({
|
|
13
|
-
name: 'Cropping',
|
|
14
|
-
options: funnel_core_1.Position.values.reduce((options, position) => {
|
|
15
|
-
// bind position
|
|
16
|
-
options[position] = {
|
|
17
|
-
name: funnel_core_1.Position.getName(position)
|
|
18
|
-
};
|
|
19
|
-
// keep reducing
|
|
20
|
-
return options;
|
|
21
|
-
}, {}),
|
|
22
|
-
defaultOption: 'center',
|
|
23
|
-
required: true
|
|
24
|
-
}),
|
|
25
|
-
accessibleField: funnel_core_1.Schema.Field.enumeration({
|
|
26
|
-
name: 'Pause Button',
|
|
27
|
-
options: {
|
|
28
|
-
system: { name: 'Site Default', hint: `Use the default for the site (${funnel_core_1.AppConfig.get().accessible ? 'enabled' : 'disabled'})` },
|
|
29
|
-
true: { name: 'Enable', hint: 'A pause button will be included' },
|
|
30
|
-
false: { name: 'Disable', hint: 'There will be no way to pause the video' }
|
|
31
|
-
}
|
|
32
|
-
}),
|
|
33
12
|
descriptionField: funnel_core_1.Schema.TextField.text({
|
|
34
13
|
name: 'Alt Text',
|
|
35
14
|
hint: 'What\'s happening in this visual?',
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Language, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { Popup } from '../../interaction';
|
|
2
3
|
export declare const CollectionEditor: import("react").ForwardRefExoticComponent<CollectionEditor.Props & import("react").RefAttributes<CollectionEditor.Ref>>;
|
|
3
4
|
export declare namespace CollectionEditor {
|
|
4
5
|
type Props = {
|
|
@@ -7,7 +8,7 @@ export declare namespace CollectionEditor {
|
|
|
7
8
|
interface Ref {
|
|
8
9
|
edit(options: Options): Promise<Schema.Field.Data<Schema.CollectionField> | undefined>;
|
|
9
10
|
}
|
|
10
|
-
type Options = {
|
|
11
|
+
type Options = Popup.Props.Delegated & {
|
|
11
12
|
schema: Schema.CollectionField;
|
|
12
13
|
collectionSchema: Schema.Collection;
|
|
13
14
|
value?: Schema.CollectionField.Value;
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
14
|
exports.CollectionEditor = void 0;
|
|
4
15
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
@@ -21,6 +32,7 @@ exports.CollectionEditor = (0, react_1.forwardRef)(function CollectionEditor({ l
|
|
|
21
32
|
const [schema, setSchema] = (0, react_1.useState)();
|
|
22
33
|
const [collectionSchema, setCollectionSchema] = (0, react_1.useState)();
|
|
23
34
|
const [initialValue, setInitialValue] = (0, react_1.useState)();
|
|
35
|
+
const [popupProps, setPopupProps] = (0, react_1.useState)();
|
|
24
36
|
const [field, setField] = (0, react_1.useState)();
|
|
25
37
|
const [shared, setShared] = (0, react_1.useState)(false);
|
|
26
38
|
const page = (0, hooks_1.usePossiblePage)();
|
|
@@ -32,11 +44,13 @@ exports.CollectionEditor = (0, react_1.forwardRef)(function CollectionEditor({ l
|
|
|
32
44
|
(0, hooks_1.useCollectionFieldProxy)(field);
|
|
33
45
|
// export service
|
|
34
46
|
(0, react_1.useImperativeHandle)(ref, () => ({
|
|
35
|
-
edit: async (
|
|
47
|
+
edit: async (_a) => {
|
|
48
|
+
var { schema, collectionSchema, value } = _a, popupProps = __rest(_a, ["schema", "collectionSchema", "value"]);
|
|
36
49
|
// reset state
|
|
37
50
|
setSchema(schema);
|
|
38
51
|
setCollectionSchema(collectionSchema);
|
|
39
52
|
setInitialValue(value);
|
|
53
|
+
setPopupProps(popupProps);
|
|
40
54
|
setField(undefined);
|
|
41
55
|
setShared(false);
|
|
42
56
|
// create deferral
|
|
@@ -69,8 +83,8 @@ exports.CollectionEditor = (0, react_1.forwardRef)(function CollectionEditor({ l
|
|
|
69
83
|
setShared(!field.isNew && field.isRef);
|
|
70
84
|
});
|
|
71
85
|
}, [language, collectionRepository, collectionStore, schema, collectionSchema, initialValue]);
|
|
72
|
-
// skip if
|
|
73
|
-
if (!schema || !collectionSchema) {
|
|
86
|
+
// skip if not ready
|
|
87
|
+
if (!schema || !collectionSchema || !popupProps) {
|
|
74
88
|
return null;
|
|
75
89
|
}
|
|
76
90
|
// helpers
|
|
@@ -147,7 +161,7 @@ exports.CollectionEditor = (0, react_1.forwardRef)(function CollectionEditor({ l
|
|
|
147
161
|
? () => setShared(!shared)
|
|
148
162
|
: undefined, children: shared ? 'Shared' : 'Unshared' }), (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "primary", size: "sm", disabled: !field || !field.nameField.valid || !field.modified, onClick: onSave, children: !initialValue ? 'Create' : 'Update' })] }), (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { mode: "wait", initial: false, children: field
|
|
149
163
|
?
|
|
150
|
-
(0, jsx_runtime_1.jsxs)(transitions_1.FadeIn, { className: "flex flex-col gap-
|
|
164
|
+
(0, jsx_runtime_1.jsxs)(transitions_1.FadeIn, { className: "flex-1 flex flex-col gap-l10 px-l6 py-l10 overflow-y-scroll scrollbar-thin bg-background", children: [(0, jsx_runtime_1.jsx)(FieldsPanel_1.FieldsPanel, { className: "flex-1", fields: field.allFields, autoFocus: true }), field.tagGroups.length > 0 &&
|
|
151
165
|
(0, jsx_runtime_1.jsx)("div", { className: "px-l7", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-l8 p-l8 bg-surface1 rounded-md", children: [(0, jsx_runtime_1.jsx)("h2", { className: "display-xxs flex-1", children: "Tags" }), (0, jsx_runtime_1.jsx)(TagEditor_1.TagEditor, { className: "bg-surface2 p-l6 rounded-sm", tagged: field })] }) })] }, "fields")
|
|
152
166
|
:
|
|
153
167
|
(0, jsx_runtime_1.jsx)(transitions_1.FadeIn, { className: "w-full h-full flex flex-col justify-center items-center", children: (0, jsx_runtime_1.jsx)(interaction_1.Loader, { size: "lg" }) }, "loader") })] }) }) }));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Language, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
-
import {
|
|
2
|
+
import { ICollection } from '../../../domain';
|
|
3
3
|
export declare const CollectionPicker: import("react").ForwardRefExoticComponent<CollectionPicker.Props & import("react").RefAttributes<CollectionPicker.Ref>>;
|
|
4
4
|
export declare namespace CollectionPicker {
|
|
5
5
|
type Props = {
|
|
@@ -11,5 +11,5 @@ export declare namespace CollectionPicker {
|
|
|
11
11
|
type Options = {
|
|
12
12
|
schema: Schema.CollectionField;
|
|
13
13
|
};
|
|
14
|
-
type Result =
|
|
14
|
+
type Result = ICollection.Ref | undefined;
|
|
15
15
|
}
|
|
@@ -9,7 +9,6 @@ const funnel_core_1 = require("@nascentdigital/funnel-core");
|
|
|
9
9
|
const classnames_1 = __importDefault(require("classnames"));
|
|
10
10
|
const framer_motion_1 = require("framer-motion");
|
|
11
11
|
const react_1 = require("react");
|
|
12
|
-
const client_1 = require("../../../client");
|
|
13
12
|
const hooks_1 = require("../../../hooks");
|
|
14
13
|
const feedback_1 = require("../../feedback");
|
|
15
14
|
const interaction_1 = require("../../interaction");
|
|
@@ -28,7 +27,7 @@ exports.CollectionPicker = (0, react_1.forwardRef)(function CollectionPicker({ l
|
|
|
28
27
|
const [tagTooltip, setTagTooltip] = (0, react_1.useState)();
|
|
29
28
|
const [fetching, setFetching] = (0, react_1.useState)(false);
|
|
30
29
|
const [error, setError] = (0, react_1.useState)();
|
|
31
|
-
const
|
|
30
|
+
const collectionRepo = (0, hooks_1.useCollectionRepository)();
|
|
32
31
|
const siteCollections = (0, hooks_1.useCollections)();
|
|
33
32
|
const collectionStore = (0, hooks_1.useCollectionStore)();
|
|
34
33
|
// export service
|
|
@@ -144,7 +143,7 @@ exports.CollectionPicker = (0, react_1.forwardRef)(function CollectionPicker({ l
|
|
|
144
143
|
setTagTooltip(undefined);
|
|
145
144
|
// fetch ref (or fail)
|
|
146
145
|
const { template, id, name } = collectionRef;
|
|
147
|
-
const collection = await
|
|
146
|
+
const collection = await collectionRepo.get({ id, version: 'draft' });
|
|
148
147
|
if (!collection) {
|
|
149
148
|
setFetching(false);
|
|
150
149
|
setError({
|
|
@@ -173,7 +172,7 @@ exports.CollectionPicker = (0, react_1.forwardRef)(function CollectionPicker({ l
|
|
|
173
172
|
deferral.resolve(result !== null && result !== void 0 ? result : undefined);
|
|
174
173
|
};
|
|
175
174
|
// render
|
|
176
|
-
return ((0, jsx_runtime_1.jsxs)(interaction_1.Picker, { className: "flex", open: deferral && result === undefined, disableDismiss: fetching, onClose: onCancel, onClosed: onPickerClosed, children: [(0, jsx_runtime_1.jsxs)("section", { className: "shrink-0 w-[206px] flex flex-col gap-l8 p-l8 bg-modal-background", children: [(0, jsx_runtime_1.jsx)("h1", { className: "heading-md text-content-primary", children: "Select Collection" }), (0, jsx_runtime_1.jsx)(interaction_1.ChipFilters, { title: "Site Collections", options: collectionGroups, selectedOptions: collectionGroup && [collectionGroup], onToggle: (collectionGroup, selected) => selected && setCollectionGroup(collectionGroup), renderLabel: collectionGroup => collectionGroup.template.name, disabled: fetching })] }), (0, jsx_runtime_1.jsxs)("section", { className: "flex-1 flex flex-col", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l8 overflow-y-scroll", children: (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { mode: "wait", initial: false, children: renderPicker({ language, error, collectionGroups, collectionGroup, collections, tagOptions, tagFilters, onPick, setTagTooltip, fetching }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex justify-end items-center p-l8 border-t border-solid border-border-l1", children: (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", onClick: onCancel, disabled: fetching, children: "Cancel" }) }), (0, jsx_runtime_1.jsx)(interaction_1.Popup, { className: (0, classnames_1.default)('max-w-[200px] bg-surface2 rounded-md p-l5', 'border border-solid border-border-l1 shadow-tooltip', 'flex flex-wrap items-center gap-l4'), open: !!tagTooltip, anchor: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.anchor, anchorOffset: 4, placement: "top", disableOverlay: true, onClose: () => setTagTooltip(undefined), children: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.tags.map(tag => (0, jsx_runtime_1.jsx)(feedback_1.Badge, { variant: "outlinedTiny", status: "draft", label: tag.name }, tag.data)) })] })] }));
|
|
175
|
+
return ((0, jsx_runtime_1.jsxs)(interaction_1.Picker, { className: "flex", open: deferral && result === undefined, disableDismiss: fetching, onClose: onCancel, onClosed: onPickerClosed, children: [(0, jsx_runtime_1.jsxs)("section", { className: "shrink-0 w-[206px] flex flex-col gap-l8 p-l8 bg-modal-background", children: [(0, jsx_runtime_1.jsx)("h1", { className: "heading-md text-content-primary", children: "Select Collection" }), (0, jsx_runtime_1.jsx)(interaction_1.ChipFilters, { title: "Site Collections", options: collectionGroups, selectedOptions: collectionGroup && [collectionGroup], onToggle: (collectionGroup, selected) => selected && setCollectionGroup(collectionGroup), renderLabel: collectionGroup => collectionGroup.template.name, disabled: fetching })] }), (0, jsx_runtime_1.jsxs)("section", { className: "flex-1 flex flex-col", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l8 overflow-y-scroll", tabIndex: -1, children: (0, jsx_runtime_1.jsx)(framer_motion_1.AnimatePresence, { mode: "wait", initial: false, children: renderPicker({ language, error, collectionGroups, collectionGroup, collections, tagOptions, tagFilters, onPick, setTagTooltip, fetching }) }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex justify-end items-center p-l8 border-t border-solid border-border-l1", children: (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", onClick: onCancel, disabled: fetching, children: "Cancel" }) }), (0, jsx_runtime_1.jsx)(interaction_1.Popup, { className: (0, classnames_1.default)('max-w-[200px] bg-surface2 rounded-md p-l5', 'border border-solid border-border-l1 shadow-tooltip', 'flex flex-wrap items-center gap-l4'), open: !!tagTooltip, anchor: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.anchor, anchorOffset: 4, placement: "top", disableOverlay: true, onClose: () => setTagTooltip(undefined), children: tagTooltip === null || tagTooltip === void 0 ? void 0 : tagTooltip.tags.map(tag => (0, jsx_runtime_1.jsx)(feedback_1.Badge, { variant: "outlinedTiny", status: "draft", label: tag.name }, tag.data)) })] })] }));
|
|
177
176
|
});
|
|
178
177
|
function renderPicker({ language, schema, error, collectionGroups, collectionGroup, collections, tagOptions, tagFilters, onPick, setTagTooltip, fetching }) {
|
|
179
178
|
// show error if we have one
|
|
@@ -50,7 +50,7 @@ exports.PagePriorityDialog = (0, react_1.forwardRef)(function CreatePageDialog({
|
|
|
50
50
|
return;
|
|
51
51
|
}
|
|
52
52
|
// render
|
|
53
|
-
return ((0, jsx_runtime_1.jsxs)(interaction_1.Picker, { open: !!deferral, onClose: onClose, className: "flex", children: [(0, jsx_runtime_1.jsxs)("section", { className: "shrink-0 w-[206px] flex flex-col gap-l8 p-l8 bg-modal-background", children: [(0, jsx_runtime_1.jsx)("h1", { className: "heading-md text-content-primary", children: "Priority Settings" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-l6", children: [(0, jsx_runtime_1.jsx)("h2", { className: "label-sm label-strong text-content-tertiary", children: "Site Pages" }), (0, jsx_runtime_1.jsx)(feedback_1.Badge, { label: currentPage.name })] })] }), (0, jsx_runtime_1.jsxs)("section", { className: "flex-1 flex flex-col", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l8 overflow-y-scroll", children: currentPage.tags.map(group => (0, jsx_runtime_1.jsx)(TagGroup, { page: currentPage, group: group, state: pageTagState }, group.id)) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-end gap-l4 items-center p-l8 border-t border-solid border-border-l1", children: [(0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", onClick: onClose, children: "Cancel" }), (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", onClick: onReset, children: "Reset" }), (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "primary", size: "sm", onClick: onSave, children: "Save" })] })] })] }));
|
|
53
|
+
return ((0, jsx_runtime_1.jsxs)(interaction_1.Picker, { open: !!deferral, onClose: onClose, className: "flex", children: [(0, jsx_runtime_1.jsxs)("section", { className: "shrink-0 w-[206px] flex flex-col gap-l8 p-l8 bg-modal-background", children: [(0, jsx_runtime_1.jsx)("h1", { className: "heading-md text-content-primary", children: "Priority Settings" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col gap-l6", children: [(0, jsx_runtime_1.jsx)("h2", { className: "label-sm label-strong text-content-tertiary", children: "Site Pages" }), (0, jsx_runtime_1.jsx)(feedback_1.Badge, { label: currentPage.name })] })] }), (0, jsx_runtime_1.jsxs)("section", { className: "flex-1 flex flex-col", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex-1 p-l8 overflow-y-scroll", tabIndex: -1, children: currentPage.tags.map(group => (0, jsx_runtime_1.jsx)(TagGroup, { page: currentPage, group: group, state: pageTagState }, group.id)) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-end gap-l4 items-center p-l8 border-t border-solid border-border-l1", children: [(0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", onClick: onClose, children: "Cancel" }), (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "secondary", size: "sm", onClick: onReset, children: "Reset" }), (0, jsx_runtime_1.jsx)(interaction_1.Button, { variant: "primary", size: "sm", onClick: onSave, children: "Save" })] })] })] }));
|
|
54
54
|
});
|
|
55
55
|
var PageTagState;
|
|
56
56
|
(function (PageTagState) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Language, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
+
import { Popup } from '../../interaction';
|
|
2
3
|
export declare const EmbeddedVideoEditor: import("react").ForwardRefExoticComponent<EmbeddedVideoEditor.Props & import("react").RefAttributes<EmbeddedVideoEditor.Ref>>;
|
|
3
4
|
export declare namespace EmbeddedVideoEditor {
|
|
4
5
|
type Props = {
|
|
@@ -7,9 +8,8 @@ export declare namespace EmbeddedVideoEditor {
|
|
|
7
8
|
interface Ref {
|
|
8
9
|
edit(options: Options): Promise<Schema.Field.Data<Schema.EmbeddedVideoField> | undefined>;
|
|
9
10
|
}
|
|
10
|
-
type Options = {
|
|
11
|
+
type Options = Popup.Props.Delegated & {
|
|
11
12
|
schema: Schema.EmbeddedVideoField;
|
|
12
13
|
initialValue?: Schema.Field.Data<Schema.EmbeddedVideoField>;
|
|
13
|
-
anchor: string;
|
|
14
14
|
};
|
|
15
15
|
}
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
15
|
};
|
|
@@ -14,7 +25,6 @@ const hooks_1 = require("../../../hooks");
|
|
|
14
25
|
const feedback_1 = require("../../feedback");
|
|
15
26
|
const interaction_1 = require("../../interaction");
|
|
16
27
|
const visuals_1 = require("../../visuals");
|
|
17
|
-
const FieldEditor_1 = require("../FieldEditor");
|
|
18
28
|
const FieldErrorController_1 = require("../FieldErrorController");
|
|
19
29
|
const TextField_1 = require("../TextField");
|
|
20
30
|
// component
|
|
@@ -23,22 +33,15 @@ exports.EmbeddedVideoEditor = (0, react_1.forwardRef)(function EmbeddedVideoEdit
|
|
|
23
33
|
const [deferral, setDeferral] = (0, react_1.useState)(undefined);
|
|
24
34
|
const [schema, setSchema] = (0, react_1.useState)();
|
|
25
35
|
const [initialValue, setInitialValue] = (0, react_1.useState)();
|
|
26
|
-
const [
|
|
36
|
+
const [popupProps, setPopupProps] = (0, react_1.useState)();
|
|
27
37
|
const [state, setState] = (0, react_1.useState)('initializing');
|
|
28
38
|
const touch = (0, client_1.useTouch)();
|
|
29
|
-
const { uriField
|
|
39
|
+
const { uriField } = (0, hooks_1.useTempFields)({
|
|
30
40
|
uriField: funnel_core_1.Schema.Field.uri({
|
|
31
41
|
name: 'YouTube or Vimeo URL',
|
|
32
42
|
hint: 'Enter video link',
|
|
33
43
|
required: true
|
|
34
44
|
}),
|
|
35
|
-
mutedField: funnel_core_1.Schema.Field.boolean({
|
|
36
|
-
name: 'Muted',
|
|
37
|
-
hint: 'Video starts off on mute',
|
|
38
|
-
semantics: 'toggle',
|
|
39
|
-
required: true,
|
|
40
|
-
defaultValue: true
|
|
41
|
-
})
|
|
42
45
|
});
|
|
43
46
|
const uri = uriField.valid
|
|
44
47
|
? funnel_core_1.Schema.TextField.Value.fromData(uriField.value)
|
|
@@ -48,12 +51,12 @@ exports.EmbeddedVideoEditor = (0, react_1.forwardRef)(function EmbeddedVideoEdit
|
|
|
48
51
|
const video = video$.value;
|
|
49
52
|
// export service
|
|
50
53
|
(0, react_1.useImperativeHandle)(ref, () => ({
|
|
51
|
-
edit: async (
|
|
52
|
-
var _a;
|
|
54
|
+
edit: async (_a) => {
|
|
55
|
+
var { schema, initialValue } = _a, popupProps = __rest(_a, ["schema", "initialValue"]);
|
|
53
56
|
// reset state
|
|
54
57
|
setSchema(schema);
|
|
55
58
|
setInitialValue(initialValue);
|
|
56
|
-
|
|
59
|
+
setPopupProps(popupProps);
|
|
57
60
|
setState('initializing');
|
|
58
61
|
// setup inputs
|
|
59
62
|
const video = initialValue === null || initialValue === void 0 ? void 0 : initialValue.value;
|
|
@@ -61,14 +64,13 @@ exports.EmbeddedVideoEditor = (0, react_1.forwardRef)(function EmbeddedVideoEdit
|
|
|
61
64
|
uriField.reset(video
|
|
62
65
|
? funnel_core_1.Schema.TextField.Value.toData(funnel_core_1.Schema.EmbeddedVideoField.Value.toUrl(video).href)
|
|
63
66
|
: null);
|
|
64
|
-
mutedField.reset(funnel_core_1.Schema.BooleanField.Value.toData(schema.allowMuting ? (_a = video === null || video === void 0 ? void 0 : video.muted) !== null && _a !== void 0 ? _a : true : true));
|
|
65
67
|
// create deferral
|
|
66
68
|
const deferral = new funnel_core_1.Deferral();
|
|
67
69
|
setDeferral(deferral);
|
|
68
70
|
// wait until deferral is resolved
|
|
69
71
|
return deferral.promise;
|
|
70
72
|
}
|
|
71
|
-
}), [uriField,
|
|
73
|
+
}), [uriField, video$]);
|
|
72
74
|
// sync uri on change
|
|
73
75
|
(0, react_1.useEffect)(() => {
|
|
74
76
|
var _a;
|
|
@@ -100,7 +102,7 @@ exports.EmbeddedVideoEditor = (0, react_1.forwardRef)(function EmbeddedVideoEdit
|
|
|
100
102
|
return;
|
|
101
103
|
}
|
|
102
104
|
// or if there's already a thumb
|
|
103
|
-
else if (video.thumbUrl) {
|
|
105
|
+
else if (video.thumbUrl && video.dimensions.width && video.dimensions.height) {
|
|
104
106
|
setState('valid');
|
|
105
107
|
return;
|
|
106
108
|
}
|
|
@@ -113,18 +115,28 @@ exports.EmbeddedVideoEditor = (0, react_1.forwardRef)(function EmbeddedVideoEdit
|
|
|
113
115
|
return;
|
|
114
116
|
}
|
|
115
117
|
// or fail if we couldn't get a thumbnail (means no video)
|
|
116
|
-
if (!thumbUrl) {
|
|
118
|
+
else if (!thumbUrl) {
|
|
117
119
|
setState('error');
|
|
120
|
+
return;
|
|
118
121
|
}
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
// touch (just in case we were already valid)
|
|
126
|
-
touch();
|
|
122
|
+
// get video dimensions
|
|
123
|
+
const dimensions = await getVideoThumbnailSize(thumbUrl.href);
|
|
124
|
+
console.debug('[EmbeddedVideoEditor] got video size as ', dimensions);
|
|
125
|
+
// skip if video has changed (debounced)
|
|
126
|
+
if (video$.value !== video) {
|
|
127
|
+
return;
|
|
127
128
|
}
|
|
129
|
+
// or fail if we couldn't get dimensions (means no thumbnail)
|
|
130
|
+
else if (!dimensions || !dimensions.width || !dimensions.height) {
|
|
131
|
+
setState('error');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
// update video
|
|
135
|
+
video$.next(Object.assign(Object.assign({}, video), { dimensions, thumbUrl: thumbUrl.href }));
|
|
136
|
+
// update state
|
|
137
|
+
setState('valid');
|
|
138
|
+
// touch (just in case we were already valid)
|
|
139
|
+
touch();
|
|
128
140
|
});
|
|
129
141
|
// unsubscribe on unmount
|
|
130
142
|
return () => subscription.unsubscribe();
|
|
@@ -134,14 +146,12 @@ exports.EmbeddedVideoEditor = (0, react_1.forwardRef)(function EmbeddedVideoEdit
|
|
|
134
146
|
return state === 'valid';
|
|
135
147
|
};
|
|
136
148
|
const onSave = async () => {
|
|
137
|
-
var _a;
|
|
138
149
|
// blow up if missing uri (should never happen)
|
|
139
150
|
if (!video || state !== 'valid') {
|
|
140
151
|
throw new funnel_core_1.IllegalStateError('Missing URI');
|
|
141
152
|
}
|
|
142
153
|
// resolve embed (we're done)
|
|
143
|
-
|
|
144
|
-
deferral === null || deferral === void 0 ? void 0 : deferral.resolve(funnel_core_1.Schema.EmbeddedVideoField.Value.toData(Object.assign(Object.assign({}, video), { muted })));
|
|
154
|
+
deferral === null || deferral === void 0 ? void 0 : deferral.resolve(funnel_core_1.Schema.EmbeddedVideoField.Value.toData(Object.assign({}, video)));
|
|
145
155
|
// refresh
|
|
146
156
|
touch();
|
|
147
157
|
};
|
|
@@ -156,9 +166,8 @@ exports.EmbeddedVideoEditor = (0, react_1.forwardRef)(function EmbeddedVideoEdit
|
|
|
156
166
|
touch();
|
|
157
167
|
};
|
|
158
168
|
// render
|
|
159
|
-
return ((0, jsx_runtime_1.jsxs)(interaction_1.MiniEditor, { title: `${initialValue ? 'Edit' : 'Add'} ${name}`, open: !!deferral && !deferral.isComplete,
|
|
160
|
-
(0, jsx_runtime_1.jsx)(feedback_1.Note, { variant: "tip", children: description }), renderPreview({ state, video }), (0, jsx_runtime_1.
|
|
161
|
-
(0, jsx_runtime_1.jsx)(FieldEditor_1.FieldEditor, { field: mutedField })] })] }));
|
|
169
|
+
return ((0, jsx_runtime_1.jsxs)(interaction_1.MiniEditor, Object.assign({ title: `${initialValue ? 'Edit' : 'Add'} ${name}`, open: !!deferral && !deferral.isComplete, canSave: canSave, onSave: onSave, onClose: onCancel, disabled: state === 'validating' }, popupProps, { children: [description &&
|
|
170
|
+
(0, jsx_runtime_1.jsx)(feedback_1.Note, { variant: "tip", children: description }), renderPreview({ state, video }), (0, jsx_runtime_1.jsx)(FieldErrorController_1.FieldErrorController, { errorLevel: "none", children: (0, jsx_runtime_1.jsx)(TextField_1.TextField, { field: uriField }) })] })));
|
|
162
171
|
});
|
|
163
172
|
async function getVideoThumbnailUrl(video) {
|
|
164
173
|
// skip if there's no video
|
|
@@ -207,6 +216,16 @@ async function getVideoThumbnailUrl(video) {
|
|
|
207
216
|
return null;
|
|
208
217
|
}
|
|
209
218
|
}
|
|
219
|
+
async function getVideoThumbnailSize(url) {
|
|
220
|
+
// get blob
|
|
221
|
+
const response = await fetch(url);
|
|
222
|
+
const blob = await response.blob();
|
|
223
|
+
// get image
|
|
224
|
+
const imageProxy = new funnel_core_1.BlobImageProxy(blob);
|
|
225
|
+
await imageProxy.waitUntilReady();
|
|
226
|
+
// return dimensions
|
|
227
|
+
return imageProxy.intrinsicSize;
|
|
228
|
+
}
|
|
210
229
|
function renderPreview({ state, video }) {
|
|
211
230
|
// show loader if checking
|
|
212
231
|
let content;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Callback, Schema } from '@nascentdigital/funnel-core';
|
|
2
|
-
|
|
2
|
+
import { Popup } from '../../interaction';
|
|
3
|
+
export declare function AssetFactory({ schema, assetId, onCommit, onCancel: onCancelRaw, ...popupProps }: AssetFactory.Props): import("react/jsx-runtime").JSX.Element;
|
|
3
4
|
export declare namespace AssetFactory {
|
|
4
|
-
type Props = {
|
|
5
|
+
type Props = Popup.Props.Delegated & {
|
|
5
6
|
schema: Schema.AssetField;
|
|
6
7
|
assetId?: Schema.Asset.Id;
|
|
7
|
-
anchor: string;
|
|
8
8
|
onCommit: Callback<Schema.Field.Data<Schema.AssetField>>;
|
|
9
9
|
onCancel: Callback.Void;
|
|
10
10
|
};
|