2019-06-11 17:00:02 +08:00
|
|
|
import React from 'react';
|
2019-04-30 11:11:25 +08:00
|
|
|
import {render} from '../../src/index';
|
2019-06-11 17:00:02 +08:00
|
|
|
import axios from 'axios';
|
2019-04-30 11:11:25 +08:00
|
|
|
import {toast} from '../../src/components/Toast';
|
2020-11-18 17:26:20 +08:00
|
|
|
import {normalizeLink} from '../../src/utils/normalizeLink';
|
2019-11-07 10:41:14 +08:00
|
|
|
import Button from '../../src/components/Button';
|
|
|
|
import LazyComponent from '../../src/components/LazyComponent';
|
|
|
|
import {default as DrawerContainer} from '../../src/components/Drawer';
|
|
|
|
import {Portal} from 'react-overlays';
|
2019-06-05 09:48:22 +08:00
|
|
|
import {withRouter} from 'react-router';
|
2020-07-28 18:23:02 +08:00
|
|
|
import copy from 'copy-to-clipboard';
|
2021-01-04 16:46:41 +08:00
|
|
|
|
2019-04-30 11:11:25 +08:00
|
|
|
function loadEditor() {
|
2019-11-07 10:41:14 +08:00
|
|
|
return new Promise(resolve =>
|
|
|
|
require(['../../src/components/Editor'], component =>
|
|
|
|
resolve(component.default))
|
|
|
|
);
|
2019-04-30 11:11:25 +08:00
|
|
|
}
|
2020-11-19 13:47:56 +08:00
|
|
|
|
|
|
|
const viewMode = localStorage.getItem('viewMode') || 'pc';
|
|
|
|
|
2021-03-05 10:53:10 +08:00
|
|
|
export default function (schema, showCode, envOverrides) {
|
2019-11-07 10:41:14 +08:00
|
|
|
if (!schema['$schema']) {
|
|
|
|
schema = {
|
|
|
|
...schema
|
|
|
|
};
|
|
|
|
}
|
2019-04-30 11:11:25 +08:00
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
return withRouter(
|
|
|
|
class extends React.Component {
|
|
|
|
static displayName = 'SchemaRenderer';
|
2020-11-19 13:47:56 +08:00
|
|
|
iframeRef;
|
|
|
|
state = {open: false, schema: {}};
|
2019-11-07 10:41:14 +08:00
|
|
|
toggleCode = () =>
|
|
|
|
this.setState({
|
|
|
|
open: !this.state.open
|
2019-04-30 11:11:25 +08:00
|
|
|
});
|
2020-07-28 18:23:02 +08:00
|
|
|
copyCode = () => {
|
2020-11-03 11:34:23 +08:00
|
|
|
copy(JSON.stringify(schema, null, 2));
|
2020-07-28 18:23:02 +08:00
|
|
|
toast.success('页面配置JSON已复制到粘贴板');
|
|
|
|
};
|
2019-11-07 10:41:14 +08:00
|
|
|
close = () =>
|
|
|
|
this.setState({
|
|
|
|
open: false
|
2019-04-30 11:11:25 +08:00
|
|
|
});
|
2019-11-07 10:41:14 +08:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2020-11-19 13:47:56 +08:00
|
|
|
|
2021-01-04 16:46:41 +08:00
|
|
|
const {router, route} = props;
|
2019-11-07 10:41:14 +08:00
|
|
|
this.env = {
|
|
|
|
updateLocation: (location, replace) => {
|
|
|
|
router[replace ? 'replace' : 'push'](normalizeLink(location));
|
|
|
|
},
|
2020-12-01 15:24:44 +08:00
|
|
|
jumpTo: (to, action) => {
|
|
|
|
if (to === 'goBack') {
|
|
|
|
return router.location.goBack();
|
|
|
|
}
|
|
|
|
to = normalizeLink(to);
|
|
|
|
if (action && action.actionType === 'url') {
|
|
|
|
action.blank === false
|
|
|
|
? (window.location.href = to)
|
|
|
|
: window.open(to);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (/^https?:\/\//.test(to)) {
|
|
|
|
window.location.replace(to);
|
|
|
|
} else {
|
|
|
|
router.push(to);
|
|
|
|
}
|
|
|
|
},
|
2019-11-07 10:41:14 +08:00
|
|
|
isCurrentUrl: to => {
|
2021-01-10 11:40:26 +08:00
|
|
|
if (!to) {
|
|
|
|
return false;
|
|
|
|
}
|
2019-11-07 10:41:14 +08:00
|
|
|
const link = normalizeLink(to);
|
|
|
|
return router.isActive(link);
|
|
|
|
},
|
2019-11-07 19:03:58 +08:00
|
|
|
fetcher: ({url, method, data, config, headers}) => {
|
|
|
|
config = config || {};
|
|
|
|
config.headers = headers || {};
|
|
|
|
|
2020-05-14 11:23:44 +08:00
|
|
|
if (config.cancelExecutor) {
|
|
|
|
config.cancelToken = new axios.CancelToken(config.cancelExecutor);
|
|
|
|
}
|
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
if (data && data instanceof FormData) {
|
|
|
|
// config.headers = config.headers || {};
|
|
|
|
// config.headers['Content-Type'] = 'multipart/form-data';
|
|
|
|
} else if (
|
|
|
|
data &&
|
|
|
|
typeof data !== 'string' &&
|
|
|
|
!(data instanceof Blob) &&
|
|
|
|
!(data instanceof ArrayBuffer)
|
|
|
|
) {
|
|
|
|
data = JSON.stringify(data);
|
|
|
|
config.headers['Content-Type'] = 'application/json';
|
|
|
|
}
|
2019-04-30 11:11:25 +08:00
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
if (method !== 'post' && method !== 'put' && method !== 'patch') {
|
|
|
|
if (data) {
|
|
|
|
if (method === 'delete') {
|
|
|
|
config.data = data;
|
|
|
|
} else {
|
|
|
|
config.params = data;
|
|
|
|
}
|
|
|
|
}
|
2019-04-30 11:11:25 +08:00
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
return axios[method](url, config);
|
|
|
|
}
|
2019-04-30 11:11:25 +08:00
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
return axios[method](url, data, config);
|
|
|
|
},
|
|
|
|
isCancel: value => axios.isCancel(value),
|
2020-08-05 14:59:27 +08:00
|
|
|
copy: content => {
|
|
|
|
copy(content);
|
|
|
|
toast.success('内容已复制到粘贴板');
|
2021-01-04 16:46:41 +08:00
|
|
|
},
|
|
|
|
blockRouting: fn => {
|
|
|
|
return router.setRouteLeaveHook(route, nextLocation => {
|
|
|
|
return fn(nextLocation);
|
|
|
|
});
|
2021-01-10 11:40:26 +08:00
|
|
|
},
|
|
|
|
...envOverrides
|
2019-11-07 10:41:14 +08:00
|
|
|
};
|
2019-04-30 11:11:25 +08:00
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
this.handleEditorMount = this.handleEditorMount.bind(this);
|
2020-11-19 13:47:56 +08:00
|
|
|
|
|
|
|
this.iframeRef = React.createRef();
|
|
|
|
this.watchIframeReady = this.watchIframeReady.bind(this);
|
|
|
|
window.addEventListener('message', this.watchIframeReady, false);
|
2019-11-07 10:41:14 +08:00
|
|
|
}
|
2019-04-30 11:11:25 +08:00
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
handleEditorMount(editor, monaco) {
|
2020-09-30 13:47:25 +08:00
|
|
|
let host = `${window.location.protocol}//${window.location.host}`;
|
|
|
|
|
|
|
|
// 如果在 gh-pages 里面
|
|
|
|
if (/^\/amis/.test(window.location.pathname)) {
|
|
|
|
host += '/amis';
|
|
|
|
}
|
|
|
|
|
|
|
|
const schemaUrl = `${host}/schema.json`;
|
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
2020-09-30 13:47:25 +08:00
|
|
|
schemas: [
|
|
|
|
{
|
|
|
|
uri: schemaUrl,
|
|
|
|
fileMatch: ['*']
|
|
|
|
}
|
|
|
|
],
|
|
|
|
validate: true,
|
2019-11-07 10:41:14 +08:00
|
|
|
enableSchemaRequest: true,
|
2020-09-30 13:47:25 +08:00
|
|
|
allowComments: true
|
2019-11-07 10:41:14 +08:00
|
|
|
});
|
|
|
|
}
|
2019-04-30 11:11:25 +08:00
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
renderCode() {
|
|
|
|
return (
|
|
|
|
<LazyComponent
|
|
|
|
getComponent={loadEditor}
|
|
|
|
editorDidMount={this.handleEditorMount}
|
|
|
|
language="json"
|
|
|
|
value={schema}
|
|
|
|
placeholder="加载中,请稍后。。。"
|
|
|
|
disabled
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
2019-04-30 11:11:25 +08:00
|
|
|
|
2020-11-19 13:47:56 +08:00
|
|
|
watchIframeReady(event) {
|
|
|
|
// iframe 里面的 amis 初始化了就可以发数据
|
|
|
|
if (event.data && event.data === 'amisReady') {
|
|
|
|
this.updateIframe();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
updateIframe() {
|
|
|
|
if (this.iframeRef && this.iframeRef.current) {
|
|
|
|
this.iframeRef.current.contentWindow.postMessage(
|
|
|
|
{
|
|
|
|
schema: schema,
|
|
|
|
props: {
|
|
|
|
location: this.props.location,
|
|
|
|
theme: this.props.theme,
|
|
|
|
locale: this.props.locale
|
|
|
|
}
|
|
|
|
},
|
|
|
|
'*'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
|
|
|
this.props.setAsideFolded && this.props.setAsideFolded(false);
|
|
|
|
window.removeEventListener('message', this.watchIframeReady, false);
|
|
|
|
}
|
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
renderSchema() {
|
2020-06-02 20:41:51 +08:00
|
|
|
const {router, location, theme, locale} = this.props;
|
2019-11-07 10:41:14 +08:00
|
|
|
|
2020-11-19 13:47:56 +08:00
|
|
|
if (viewMode === 'mobile') {
|
|
|
|
return (
|
|
|
|
<iframe
|
|
|
|
width="375"
|
|
|
|
height="100%"
|
|
|
|
frameBorder={0}
|
|
|
|
className="mobile-frame"
|
|
|
|
ref={this.iframeRef}
|
|
|
|
// @ts-ignore
|
2020-11-19 19:22:56 +08:00
|
|
|
src={__uri('../mobile.html')}
|
2020-11-19 13:47:56 +08:00
|
|
|
></iframe>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-11-07 10:41:14 +08:00
|
|
|
return render(
|
|
|
|
schema,
|
|
|
|
{
|
|
|
|
location,
|
2020-06-02 20:41:51 +08:00
|
|
|
theme,
|
|
|
|
locale
|
2019-11-07 10:41:14 +08:00
|
|
|
},
|
|
|
|
this.env
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const ns = this.props.classPrefix;
|
2021-01-10 11:40:26 +08:00
|
|
|
const finalShowCode = this.props.showCode ?? showCode;
|
2019-11-07 10:41:14 +08:00
|
|
|
return (
|
2020-07-28 18:23:02 +08:00
|
|
|
<>
|
|
|
|
<div className="schema-wrapper">
|
2021-01-10 11:40:26 +08:00
|
|
|
{finalShowCode !== false ? (
|
2020-07-28 18:23:02 +08:00
|
|
|
<DrawerContainer
|
|
|
|
classPrefix={ns}
|
|
|
|
size="lg"
|
|
|
|
onHide={this.close}
|
|
|
|
show={this.state.open}
|
2020-07-29 15:33:25 +08:00
|
|
|
// overlay={false}
|
2020-07-28 18:23:02 +08:00
|
|
|
closeOnOutside={true}
|
|
|
|
position="right"
|
|
|
|
>
|
|
|
|
{this.state.open ? this.renderCode() : null}
|
|
|
|
</DrawerContainer>
|
|
|
|
) : null}
|
|
|
|
{this.renderSchema()}
|
|
|
|
</div>
|
2021-01-10 11:40:26 +08:00
|
|
|
{finalShowCode !== false ? (
|
2020-07-28 18:23:02 +08:00
|
|
|
// <div className="schema-toolbar-wrapper">
|
|
|
|
// <div onClick={this.toggleCode}>
|
|
|
|
// 查看页面配置 <i className="fa fa-code p-l-xs"></i>
|
|
|
|
// </div>
|
|
|
|
// <div onClick={this.copyCode}>
|
|
|
|
// 复制页面配置 <i className="fa fa-copy p-l-xs"></i>
|
|
|
|
// </div>
|
|
|
|
// </div>
|
2020-12-24 20:08:51 +08:00
|
|
|
<Portal
|
|
|
|
container={() => document.getElementById('Header-toolbar')}
|
|
|
|
>
|
|
|
|
<div className="hidden-xs hidden-sm ml-3">
|
|
|
|
<div>
|
|
|
|
<div className="Doc-headingList">
|
|
|
|
<div className="Doc-headingList-item">
|
|
|
|
<a onClick={this.toggleCode}>
|
|
|
|
查看配置 <i className="fa fa-code p-l-xs"></i>
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
<div className="Doc-headingList-item">
|
|
|
|
<a onClick={this.copyCode}>
|
|
|
|
复制配置 <i className="fa fa-copy p-l-xs"></i>
|
|
|
|
</a>
|
|
|
|
</div>
|
2020-07-29 15:33:25 +08:00
|
|
|
</div>
|
2020-07-28 18:23:02 +08:00
|
|
|
</div>
|
|
|
|
</div>
|
2020-12-24 20:08:51 +08:00
|
|
|
</Portal>
|
2019-11-07 10:41:14 +08:00
|
|
|
) : null}
|
2020-07-28 18:23:02 +08:00
|
|
|
</>
|
2019-11-07 10:41:14 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
2019-04-30 11:11:25 +08:00
|
|
|
}
|