burdy
Version:
Open Source Headless Platform
272 lines (271 loc) • 13.8 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const loading_bar_1 = __importDefault(require("../../../components/loading-bar"));
const react_1 = require("@fluentui/react");
const react_2 = __importStar(require("react"));
const dynamic_form_1 = require("../../../config-fields/dynamic-form");
const empty_1 = __importDefault(require("../../../components/empty"));
const posts_context_1 = require("../../posts/context/posts.context");
const classnames_1 = __importDefault(require("classnames"));
const use_debounce_1 = require("use-debounce");
const post_details_1 = __importDefault(require("../../posts/components/post-details"));
const dynamic_group_1 = __importDefault(require("../../../config-fields/dynamic-group"));
const react_hook_form_1 = require("react-hook-form");
const react_router_1 = require("react-router");
const query_string_1 = __importDefault(require("query-string"));
const theme = (0, react_1.getTheme)();
const Tabs = ({ items, onSelected, loading }) => {
const [selectedKey, setSelectedKey] = (0, react_2.useState)(null);
(0, react_2.useEffect)(() => {
var _a;
if (!selectedKey && (items === null || items === void 0 ? void 0 : items.length) > 0) {
setSelectedKey((_a = items === null || items === void 0 ? void 0 : items[0]) === null || _a === void 0 ? void 0 : _a.key);
}
}, [items]);
(0, react_2.useEffect)(() => {
onSelected(selectedKey);
}, [selectedKey]);
return (react_2.default.createElement("div", null,
loading && (react_2.default.createElement(react_1.Stack, { horizontal: true, style: { height: '100%' }, verticalAlign: "center", tokens: { childrenGap: 10 } },
react_2.default.createElement(react_1.Shimmer, { width: 50, shimmerElements: [{ type: react_1.ShimmerElementType.line, height: 8 }], style: {} }),
react_2.default.createElement(react_1.Shimmer, { width: 50, shimmerElements: [{ type: react_1.ShimmerElementType.line, height: 8 }], style: {} }))),
!loading && (react_2.default.createElement(react_1.Pivot, { selectedKey: selectedKey, headersOnly: true, "aria-label": "Basic Pivot", onLinkClick: (item) => {
var _a;
setSelectedKey((_a = item === null || item === void 0 ? void 0 : item.props) === null || _a === void 0 ? void 0 : _a.itemKey);
} }, items.map((item) => {
var _a;
return (react_2.default.createElement(react_1.PivotItem, { itemKey: item.key, headerText: ((_a = item === null || item === void 0 ? void 0 : item.name) === null || _a === void 0 ? void 0 : _a.length) > 0 ? item === null || item === void 0 ? void 0 : item.name : item === null || item === void 0 ? void 0 : item.key, style: { paddingTop: 20 } }));
})))));
};
const styles = (0, react_1.mergeStyleSets)({
card: {
margin: 24,
},
mainWrapper: {
display: 'flex',
flexFlow: 'row nowrap',
alignItems: 'flex-start',
width: '100%',
height: '100%',
boxSizing: 'border-box',
},
content: {
flexGrow: 1,
height: '100%',
overflowY: 'auto',
position: 'relative',
padding: 24,
boxSizing: 'border-box',
},
side: {
maxWidth: 380,
minWidth: 380,
flexGrow: 1,
height: '100%',
overflowY: 'auto',
position: 'relative',
boxShadow: theme.effects.elevation16,
},
cardHeading: {
padding: '0 14px',
boxShadow: theme.effects.elevation4,
display: 'flex',
position: 'relative',
height: 44,
alignItems: 'center',
},
editor: {
boxShadow: theme.effects.elevation16,
maxWidth: 1920,
position: 'relative',
minHeight: 100,
marginLeft: 'auto',
marginRight: 'auto',
height: '100%',
display: 'flex',
flexDirection: 'column',
},
browserMobile: {
maxWidth: '375px',
},
browserTablet: {
maxWidth: '768px',
},
iframeWrapper: {
flex: 1,
overflowY: 'auto',
},
urlBar: {
backgroundColor: theme.palette.neutralLight,
display: 'flex',
alignItems: 'center',
height: 40,
padding: '0 10px',
},
urlBarSearch: {
backgroundColor: theme.palette.white,
borderRadius: 4,
padding: '0 10px',
flex: 1,
display: 'flex',
alignItems: 'center',
height: 34,
fontWeight: 600,
overflowX: 'auto',
whiteSpace: 'nowrap'
},
iframe: {
display: 'block',
boxSizing: 'content-box',
height: '100%',
width: '100%',
border: '0px none',
overflow: 'auto',
},
messages: {
marginLeft: 'auto',
marginRight: 'auto',
marginBottom: 12,
maxWidth: 960,
width: '100%',
},
hide: {
display: 'none !important',
},
});
const PreviewEditor = ({ methods, device = 'desktop', menuOpened = true, message, loading }) => {
var _a, _b, _c, _d;
const { post, compilePost, getPreviewData } = (0, posts_context_1.usePosts)();
const iframeRef = (0, react_2.useRef)(null);
const [selectedTab, setSelectedTab] = (0, react_2.useState)(null);
const [iframeSrc, setIframeSrc] = (0, react_2.useState)();
const history = (0, react_router_1.useHistory)();
const debounced = (0, use_debounce_1.useDebouncedCallback)((val) => __awaiter(void 0, void 0, void 0, function* () {
try {
const compiled = yield compilePost.execute(Object.assign(Object.assign({}, post), { meta: Object.assign(Object.assign({}, ((post === null || post === void 0 ? void 0 : post.meta) || {})), { content: val }) }));
if (iframeRef === null || iframeRef === void 0 ? void 0 : iframeRef.current) {
iframeRef.current.contentWindow.postMessage({
source: 'burdy-post-edit',
payload: compiled,
}, '*');
}
}
catch (err) {
//
}
}), 500);
(0, react_2.useEffect)(() => {
methods.watch((val) => {
debounced(val);
});
}, []);
(0, react_2.useEffect)(() => {
const handler = (event) => {
var _a, _b;
const id = (_b = (_a = event.data) === null || _a === void 0 ? void 0 : _a.post) === null || _b === void 0 ? void 0 : _b.id;
if (!id || id === (post === null || post === void 0 ? void 0 : post.id))
return;
history.push({
pathname: `/sites/editor/${id}`,
search: query_string_1.default.stringify({
editor: 'preview'
})
});
};
window.addEventListener('message', handler);
return () => window.removeEventListener('message', handler);
}, [post === null || post === void 0 ? void 0 : post.id]);
const fetchPreviewData = (post) => __awaiter(void 0, void 0, void 0, function* () {
try {
const response = yield getPreviewData.execute(post === null || post === void 0 ? void 0 : post.id, post === null || post === void 0 ? void 0 : post.versionId);
if (response) {
setIframeSrc(response === null || response === void 0 ? void 0 : response.src);
}
}
catch (err) {
//
}
});
(0, react_2.useEffect)(() => {
if (post) {
fetchPreviewData(post);
}
}, [post === null || post === void 0 ? void 0 : post.id]);
const tabs = (0, react_2.useMemo)(() => {
const tmpTabs = [
{
name: 'editor',
label: 'Editor',
},
{
name: 'details',
label: 'Details',
},
];
return tmpTabs;
}, [post]);
return (react_2.default.createElement("div", { className: styles.mainWrapper },
react_2.default.createElement("div", { className: styles.content },
react_2.default.createElement("div", { className: `${styles.editor} ${(0, classnames_1.default)({
[styles.browserTablet]: device === 'tablet',
[styles.browserMobile]: device === 'mobile',
})}` },
react_2.default.createElement(loading_bar_1.default, { loading: loading },
react_2.default.createElement("div", { className: styles.urlBar },
react_2.default.createElement("div", { className: styles.urlBarSearch }, iframeSrc),
react_2.default.createElement("div", null,
react_2.default.createElement(react_1.IconButton, { iconProps: { iconName: 'OpenInNewTab' }, onClick: () => window.open(iframeSrc, '_blank') }))),
react_2.default.createElement("div", { className: styles.iframeWrapper }, iframeSrc && (react_2.default.createElement("iframe", { title: "burdy-editor", id: "burdy-editor", className: styles.iframe, ref: iframeRef, src: iframeSrc, style: { width: '1px', minWidth: '100%' } })))))),
react_2.default.createElement("div", { className: (0, classnames_1.default)([styles.side, !menuOpened && styles.hide]) },
react_2.default.createElement("div", { className: styles.cardHeading }, !post ? (react_2.default.createElement(react_1.Shimmer, { width: 50, shimmerElements: [{ type: react_1.ShimmerElementType.line, height: 8 }], style: {} })) : (react_2.default.createElement(Tabs, { items: tabs.map((tab) => ({
key: tab.name,
name: tab.label,
})), onSelected: (e) => setSelectedTab(e) }))),
react_2.default.createElement("div", { className: styles.card },
(post === null || post === void 0 ? void 0 : post.versionId) && (react_2.default.createElement("div", { className: styles.messages },
react_2.default.createElement(react_1.MessageBar, { messageBarType: react_1.MessageBarType.info }, "You are previewing historical version"))),
message === 'version_deleted' && (react_2.default.createElement("div", { className: styles.messages },
react_2.default.createElement(react_1.MessageBar, { messageBarType: react_1.MessageBarType.success }, "Version deleted"))),
message === 'version_restored' && (react_2.default.createElement("div", { className: styles.messages },
react_2.default.createElement(react_1.MessageBar, { messageBarType: react_1.MessageBarType.success }, "Version restored"))),
react_2.default.createElement("div", { className: `${selectedTab === 'editor' ? '' : styles.hide}` },
react_2.default.createElement(loading_bar_1.default, { loading: loading },
((_b = (_a = post === null || post === void 0 ? void 0 : post.contentType) === null || _a === void 0 ? void 0 : _a.fields) === null || _b === void 0 ? void 0 : _b.length) > 0 && (react_2.default.createElement(react_hook_form_1.FormProvider, Object.assign({}, methods),
react_2.default.createElement(dynamic_form_1.FormHelperContextProvider, { disabled: !!(post === null || post === void 0 ? void 0 : post.versionId), narrow: true },
react_2.default.createElement(dynamic_group_1.default, { field: post === null || post === void 0 ? void 0 : post.contentType })))),
!(((_d = (_c = post === null || post === void 0 ? void 0 : post.contentType) === null || _c === void 0 ? void 0 : _c.fields) === null || _d === void 0 ? void 0 : _d.length) > 0) && (react_2.default.createElement(empty_1.default, { compact: true, title: "No fields defined" })))),
react_2.default.createElement("div", { className: `${selectedTab === 'details' ? '' : styles.hide}` },
react_2.default.createElement(post_details_1.default, { loading: loading, post: post }))))));
};
exports.default = PreviewEditor;