UNPKG

@ovine/editor

Version:
166 lines (165 loc) 7.18 kB
import { toast, confirm } from 'amis'; import cls from 'classnames'; import copy from 'copy-to-clipboard'; import _ from 'lodash'; import { observer, inject } from 'mobx-react'; import React, { useEffect, useRef } from 'react'; import { app } from "../../../../core/lib/app"; import { saveToFile } from "../../../../core/lib/utils/file"; import { editorStore } from "../../stores/editor"; import { StyledHeader } from "./styled"; // TODO: 优化 getSchemaString export default inject('store')(observer((props) => { const { isPreview, option, isDirty, isMobile, togglePreview, toggleViewMode, setLastSavedSchema, editorInstance, } = props.store; const { breadcrumb, onExit, onSave, saveApi, saveInterval } = option; const timerRef = useRef(0); const hasPrevStep = editorInstance.canUndo(); const hasNextStep = editorInstance.canRedo(); const getBreadcrumbItems = () => { return typeof breadcrumb === 'string' ? [breadcrumb] : breadcrumb; }; const getSchemaString = (errTip) => { let value = ''; try { value = JSON.stringify(editorStore.schema); } catch (__) { toast.error(errTip, 'JSON解析错误'); return false; } return value; }; const onExitEditor = () => { if (isPreview) { togglePreview(); return; } const exit = () => { let exitRes = true; if (onExit) { exitRes = onExit(); } if (exitRes !== false) { if (app.routerHistory.length) { app.routerHistory.goBack(); } else { app.routerHistory.replace('/'); } } }; if (isDirty) { confirm('当前存在未保存的改动,退出将视为放弃更改!', '确定退出编辑器?').then((choose) => { if (choose) { exit(); } }); return; } exit(); }; const onCopyClick = () => { const value = getSchemaString('复制操作执行失败!'); if (value) { copy(value); toast.success('复制成功'); } }; const onDownloadClick = () => { const value = getSchemaString('下载操作执行失败!'); if (value) { saveToFile(value, 'text/plain', `${_.last(getBreadcrumbItems())}.json`); toast.success('文件下载成功'); } }; const renderBreadcrumb = () => { if (!breadcrumb) { return React.createElement("span", null, "\u672A\u77E5\u9875\u9762"); } return (React.createElement("nav", { "aria-label": "breadcrumb" }, React.createElement("ol", { className: "breadcrumb " }, getBreadcrumbItems().map((text, index) => { return (React.createElement("li", { key: index, className: "breadcrumb-item text-ellipsis" }, text)); })))); }; const saveSchemaApi = (mounted = false) => { const value = editorStore.schema; saveApi.data = Object.assign(Object.assign({}, saveApi.data), { schema: value }); return app .request(saveApi) .then((source) => { const { status, msg } = source.data; if (!mounted) { if (status === 0) { toast.success(msg || '保存成功', '系统提示'); } else { toast.error(msg || '保存失败', '系统提示'); } } if (onSave) { onSave(value); } setLastSavedSchema(value); return source; }) .catch((source) => { toast.error((source === null || source === void 0 ? void 0 : source.msg) || '保存失败', '系统提示'); }); }; const onSaveClick = () => { const value = editorStore.schema; if (saveApi) { saveSchemaApi(); return; } if (onSave) { onSave(value); } setLastSavedSchema(value); toast.success('当前编辑数据已经保存', '系统提示'); }; useEffect(() => { if (saveApi && saveInterval > 2 * 1000) { if (timerRef.current) { clearInterval(timerRef.current); } timerRef.current = setInterval(() => { saveSchemaApi(true); }, saveInterval); } return () => { if (timerRef.current) { clearInterval(timerRef.current); } }; }, []); return (React.createElement(StyledHeader, null, React.createElement("div", { className: "toolbar-left" }, React.createElement("i", { className: "fa fa-chevron-left back-icon", "data-tooltip": "\u9000\u51FA", "data-position": "bottom", onClick: onExitEditor }), renderBreadcrumb()), React.createElement("div", { className: "toolbar-main" }, React.createElement("div", { className: cls('toolbar-item', { active: isPreview }), onClick: togglePreview }, React.createElement("i", { className: `fa ${isPreview ? 'fa-eye-slash' : 'fa-eye'}` }), React.createElement("span", null, "\u9884\u89C8")), React.createElement("div", { className: cls('toolbar-item view-mode', { active: !isPreview && isMobile, }), onClick: toggleViewMode }, React.createElement("i", { className: `fa ${isMobile ? 'fa-mobile' : 'fa-desktop'}` }), React.createElement("span", null, isMobile ? '移动端' : 'PC端')), React.createElement("div", { className: cls('toolbar-item', { disabled: isPreview || !hasPrevStep }), onClick: () => editorInstance.undo() }, React.createElement("i", { className: "fa fa-reply" }), React.createElement("span", null, "\u64A4\u9500")), React.createElement("div", { className: cls('toolbar-item', { disabled: isPreview || !hasNextStep }), onClick: () => editorInstance.redo() }, React.createElement("i", { className: "fa fa-share" }), React.createElement("span", null, "\u56DE\u9000")), React.createElement("div", { className: cls('toolbar-item'), onClick: onCopyClick }, React.createElement("i", { className: "fa fa-copy" }), React.createElement("span", null, "\u590D\u5236")), React.createElement("div", { className: cls('toolbar-item'), onClick: onDownloadClick }, React.createElement("i", { className: "fa fa-save" }), React.createElement("span", null, "\u5BFC\u51FA")), React.createElement("div", { className: cls('toolbar-item'), onClick: onSaveClick }, React.createElement("i", { className: "fa fa-cloud-upload " }), React.createElement("span", null, "\u4FDD\u5B58"))), React.createElement("div", { className: "toolbar-right" }))); }));