mirror of
https://gitee.com/baidu/amis.git
synced 2024-12-05 13:38:56 +08:00
213 lines
8.1 KiB
JavaScript
213 lines
8.1 KiB
JavaScript
import React from 'react';
|
|
import {render} from '../../src/index';
|
|
import axios from 'axios';
|
|
import {toast} from '../../src/components/Toast';
|
|
import {alert, confirm} from '../../src/components/Alert';
|
|
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';
|
|
import {withRouter} from 'react-router';
|
|
function loadEditor() {
|
|
return new Promise((resolve) => require(['../../src/components/Editor'], (component) => resolve(component.default)));
|
|
}
|
|
export default function(schema) {
|
|
if (!schema['$schema']) {
|
|
schema = {
|
|
'$schema': 'https://houtai.baidu.com/v2/schemas/page.json',
|
|
...schema
|
|
};
|
|
}
|
|
|
|
|
|
return withRouter(class extends React.Component {
|
|
static displayName = 'SchemaRenderer';
|
|
state = {open: false};
|
|
toggleCode = () => this.setState({
|
|
open: !this.state.open
|
|
});
|
|
close = () => this.setState({
|
|
open: false
|
|
});
|
|
constructor(props) {
|
|
super(props);
|
|
const {router} = props;
|
|
const normalizeLink = (to) => {
|
|
to = to || '';
|
|
const location = router.getCurrentLocation();
|
|
|
|
if (to && to[0] === '#') {
|
|
to = location.pathname + location.search + to;
|
|
} else if (to && to[0] === '?') {
|
|
to = location.pathname + to;
|
|
}
|
|
|
|
const idx = to.indexOf('?');
|
|
const idx2 = to.indexOf('#');
|
|
let pathname = ~idx ? to.substring(0, idx) : ~idx2 ? to.substring(0, idx2) : to;
|
|
let search = ~idx ? to.substring(idx, ~idx2 ? idx2 : undefined) : '';
|
|
let hash = ~idx2 ? to.substring(idx2) : '';
|
|
|
|
if (!pathname) {
|
|
pathname = location.pathname;
|
|
} else if (pathname[0] != '/' && !/^https?:\/\//.test(pathname)) {
|
|
let relativeBase = location.pathname;
|
|
const paths = relativeBase.split('/');
|
|
paths.pop();
|
|
let m;
|
|
while ((m = /^\.\.?\//.exec(pathname))) {
|
|
if (m[0] === '../') {
|
|
paths.pop();
|
|
}
|
|
pathname = pathname.substring(m[0].length);
|
|
}
|
|
pathname = paths.concat(pathname).join('/');
|
|
}
|
|
|
|
return pathname + search + hash;
|
|
}
|
|
this.env = {
|
|
updateLocation: (location, replace) => {
|
|
router[replace ? 'replace' : 'push'](normalizeLink(location));
|
|
},
|
|
isCurrentUrl: (to) => {
|
|
const link = normalizeLink(to);
|
|
return router.isActive(link);
|
|
},
|
|
jumpTo: (to) => {
|
|
to = normalizeLink(to);
|
|
|
|
if (/^https?:\/\//.test(to)) {
|
|
window.location.replace(to);
|
|
} else {
|
|
router.push(to);
|
|
}
|
|
},
|
|
fetcher: ({
|
|
url,
|
|
method,
|
|
data,
|
|
config
|
|
}) => {
|
|
let hasFile = function(data) {
|
|
return Object.keys(data).some(key => {
|
|
let value = data[key];
|
|
|
|
return value instanceof File || Array.isArray(value) && value.length && value[0] instanceof File;
|
|
});
|
|
}
|
|
|
|
if (data && data instanceof FormData) {
|
|
// config.headers = config.headers || {};
|
|
// config.headers['Content-Type'] = 'multipart/form-data';
|
|
} else if (hasFile(data)) {
|
|
const fd = new FormData();
|
|
Object.keys(data).forEach(key => {
|
|
const value = data[key];
|
|
|
|
if (value instanceof File) {
|
|
fd.append(key, value, value.name);
|
|
} else if (Array.isArray(value) && value.length && value[0] instanceof File) {
|
|
value.forEach(value => fd.append(`${key}[]`, value, value.name));
|
|
} else {
|
|
// todo 复杂对象还需要特殊处理。
|
|
fd.append(key, value);
|
|
}
|
|
});
|
|
data = fd;
|
|
} else if (data
|
|
&& typeof data !== 'string'
|
|
&& !(data instanceof Blob)
|
|
&& !(data instanceof ArrayBuffer)
|
|
) {
|
|
data = JSON.stringify(data);
|
|
config = config || {};
|
|
config.headers = config.headers || {};
|
|
config.headers['Content-Type'] = 'application/json';
|
|
}
|
|
|
|
if (method !== 'post' && method !== 'put' && method !== 'patch') {
|
|
if (data) {
|
|
if (method === 'delete') {
|
|
config.data = data;
|
|
} else {
|
|
config.params = data;
|
|
}
|
|
}
|
|
|
|
return axios[method](url, config);
|
|
}
|
|
|
|
return axios[method](url, data, config);
|
|
},
|
|
isCancel: value => axios.isCancel(value),
|
|
notify: (type, msg) => toast[type] ? toast[type](msg, type === 'error' ? '系统错误' : '系统消息') : console.warn('[Notify]', type, msg),
|
|
alert,
|
|
confirm,
|
|
copy: (content) => console.log('Copy', content)
|
|
};
|
|
|
|
this.handleEditorMount = this.handleEditorMount.bind(this);
|
|
}
|
|
|
|
handleEditorMount(editor, monaco) {
|
|
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
|
enableSchemaRequest: true,
|
|
validate: true
|
|
});
|
|
}
|
|
|
|
renderCode() {
|
|
return (
|
|
<LazyComponent
|
|
getComponent={loadEditor}
|
|
editorDidMount={this.handleEditorMount}
|
|
language="json"
|
|
value={schema}
|
|
placeholder="加载中,请稍后。。。"
|
|
disabled
|
|
/>
|
|
);
|
|
}
|
|
|
|
renderSchema() {
|
|
const {
|
|
router,
|
|
location,
|
|
theme
|
|
} = this.props;
|
|
|
|
return render(schema, {
|
|
location,
|
|
theme
|
|
}, this.env);
|
|
}
|
|
|
|
render() {
|
|
const ns = this.props.classPrefix;
|
|
const showCode = this.props.showCode;
|
|
return (
|
|
<div className="schema-wrapper">
|
|
{showCode !== false ? (
|
|
<DrawerContainer
|
|
classPrefix={ns}
|
|
size="lg"
|
|
onHide={this.close}
|
|
show={this.state.open}
|
|
position="left"
|
|
>
|
|
{this.state.open ? this.renderCode() : null}
|
|
</DrawerContainer>
|
|
) : null }
|
|
{this.renderSchema()}
|
|
{showCode !== false ? (
|
|
<Portal container={() => document.querySelector('.navbar-nav')}>
|
|
<Button classPrefix={ns} onClick={this.toggleCode} active={this.state.open} iconOnly tooltip="查看源码" level="link" placement="bottom" className="view-code"><i className="fa fa-code" /></Button>
|
|
</Portal>
|
|
) : null}
|
|
</div>
|
|
);
|
|
}
|
|
});
|
|
}
|