diff --git a/examples/components/App.tsx b/examples/components/App.tsx
index 8136f54d9..d7d468875 100644
--- a/examples/components/App.tsx
+++ b/examples/components/App.tsx
@@ -14,7 +14,7 @@ import {
} from 'amis';
import {eachTree} from 'amis-core';
import 'amis-ui/lib/locale/en-US';
-import {withRouter} from 'react-router';
+import {withRouter} from 'react-router-dom';
// @ts-ignore
import DocSearch from './DocSearch';
import Doc from './Doc';
@@ -142,6 +142,8 @@ class BackTop extends React.PureComponent {
}
}
+// @ts-ignore
+@withRouter
export class App extends React.PureComponent<{
location: Location;
}> {
diff --git a/examples/components/SchemaRender.jsx b/examples/components/SchemaRender.jsx
index 88a10a1cb..0a66fd121 100644
--- a/examples/components/SchemaRender.jsx
+++ b/examples/components/SchemaRender.jsx
@@ -3,7 +3,7 @@ import {render, toast, makeTranslator, LazyComponent, Drawer} from 'amis';
import axios from 'axios';
import Portal from 'react-overlays/Portal';
import {normalizeLink} from 'amis-core';
-import {withRouter} from 'react-router';
+import {withRouter} from 'react-router-dom';
import copy from 'copy-to-clipboard';
import {qsparse, parseQuery, attachmentAdpator} from 'amis-core';
import isPlainObject from 'lodash/isPlainObject';
@@ -31,391 +31,395 @@ export default function (schema, schemaProps, showCode, envOverrides) {
};
}
- return class extends React.Component {
- static displayName = 'SchemaRenderer';
- iframeRef;
- state = {open: false, schema: {}};
- originalTitle = document.title;
- toggleCode = () =>
- this.setState({
- open: !this.state.open
- });
- copyCode = () => {
- copy(JSON.stringify(schema, null, 2));
- toast.success('页面配置JSON已复制到粘贴板');
- };
- close = () =>
- this.setState({
- open: false
- });
- constructor(props) {
- super(props);
+ return withRouter(
+ class extends React.Component {
+ static displayName = 'SchemaRenderer';
+ iframeRef;
+ state = {open: false, schema: {}};
+ originalTitle = document.title;
+ toggleCode = () =>
+ this.setState({
+ open: !this.state.open
+ });
+ copyCode = () => {
+ copy(JSON.stringify(schema, null, 2));
+ toast.success('页面配置JSON已复制到粘贴板');
+ };
+ close = () =>
+ this.setState({
+ open: false
+ });
+ constructor(props) {
+ super(props);
- const __ = makeTranslator(props.locale);
- const {history} = props;
- this.env = {
- updateLocation: (location, replace) => {
- history[replace ? 'replace' : 'push'](normalizeLink(location));
- },
- jumpTo: (to, action) => {
- if (to === 'goBack') {
- return history.location.goBack();
- }
- to = normalizeLink(to);
- if (action && action.actionType === 'url') {
- action.blank === false
- ? (window.location.href = to)
- : window.open(to);
- return;
- }
- if (action && to && action.target) {
- window.open(to, action.target);
- return;
- }
- if (/^https?:\/\//.test(to)) {
- window.location.replace(to);
- } else {
- history.push(to);
- }
- },
- isCurrentUrl: to => {
- const history = this.props.history;
- const link = normalizeLink(to);
- const location = history.location;
- let pathname = link;
- let search = '';
- const idx = link.indexOf('?');
- if (~idx) {
- pathname = link.substring(0, idx);
- search = link.substring(idx);
- }
-
- if (search) {
- if (pathname !== location.pathname || !location.search) {
- return false;
+ const __ = makeTranslator(props.locale);
+ const {history} = props;
+ this.env = {
+ updateLocation: (location, replace) => {
+ history[replace ? 'replace' : 'push'](normalizeLink(location));
+ },
+ jumpTo: (to, action) => {
+ if (to === 'goBack') {
+ return history.location.goBack();
}
- const currentQuery = parseQuery(location);
- const query = qsparse(search.substring(1));
-
- return Object.keys(query).every(
- key => query[key] === currentQuery[key]
- );
- } else if (pathname === location.pathname) {
- return true;
- }
-
- return false;
- },
- fetcher: async api => {
- let {url, method, data, responseType, config, headers} = api;
- config = config || {};
- config.url = url;
- responseType && (config.responseType = responseType);
-
- if (config.cancelExecutor) {
- config.cancelToken = new axios.CancelToken(config.cancelExecutor);
- }
-
- config.headers = headers || {};
- config.method = method;
- config.data = data;
-
- if (method === 'get' && data) {
- config.params = data;
- } else if (data && data instanceof FormData) {
- // 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';
- }
-
- // 支持返回各种报错信息
- config.validateStatus = function () {
- return true;
- };
-
- let response = await axios(config);
- response = await attachmentAdpator(response, __, api);
-
- if (response.status >= 400) {
- if (response.data) {
- // 主要用于 raw: 模式下,后端自己校验登录,
- if (
- response.status === 401 &&
- response.data.location &&
- response.data.location.startsWith('http')
- ) {
- location.href = response.data.location.replace(
- '{{redirect}}',
- encodeURIComponent(location.href)
- );
- return new Promise(() => {});
- } else if (response.data.msg) {
- throw new Error(response.data.msg);
- } else {
- throw new Error(JSON.stringify(response.data, null, 2));
- }
+ to = normalizeLink(to);
+ if (action && action.actionType === 'url') {
+ action.blank === false
+ ? (window.location.href = to)
+ : window.open(to);
+ return;
+ }
+ if (action && to && action.target) {
+ window.open(to, action.target);
+ return;
+ }
+ if (/^https?:\/\//.test(to)) {
+ window.location.replace(to);
} else {
- throw new Error(`${response.status}`);
+ history.push(to);
+ }
+ },
+ isCurrentUrl: to => {
+ const history = this.props.history;
+ const link = normalizeLink(to);
+ const location = history.location;
+ let pathname = link;
+ let search = '';
+ const idx = link.indexOf('?');
+ if (~idx) {
+ pathname = link.substring(0, idx);
+ search = link.substring(idx);
}
- }
- return response;
- },
- isCancel: value => axios.isCancel(value),
- copy: (content, options) => {
- copy(content, options);
- toast.success('内容已复制到粘贴板');
- },
- blockRouting: fn => {
- return history.block(fn);
- },
- tracker(eventTrack) {
- console.debug('eventTrack', eventTrack);
- },
- loadTinymcePlugin: async tinymce => {
- // 参考:https://www.tiny.cloud/docs/advanced/creating-a-plugin/
- /*
+ if (search) {
+ if (pathname !== location.pathname || !location.search) {
+ return false;
+ }
+ const currentQuery = parseQuery(location);
+ const query = qsparse(search.substring(1));
+
+ return Object.keys(query).every(
+ key => query[key] === currentQuery[key]
+ );
+ } else if (pathname === location.pathname) {
+ return true;
+ }
+
+ return false;
+ },
+ fetcher: async api => {
+ let {url, method, data, responseType, config, headers} = api;
+ config = config || {};
+ config.url = url;
+ responseType && (config.responseType = responseType);
+
+ if (config.cancelExecutor) {
+ config.cancelToken = new axios.CancelToken(config.cancelExecutor);
+ }
+
+ config.headers = headers || {};
+ config.method = method;
+ config.data = data;
+
+ if (method === 'get' && data) {
+ config.params = data;
+ } else if (data && data instanceof FormData) {
+ // 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';
+ }
+
+ // 支持返回各种报错信息
+ config.validateStatus = function () {
+ return true;
+ };
+
+ let response = await axios(config);
+ response = await attachmentAdpator(response, __, api);
+
+ if (response.status >= 400) {
+ if (response.data) {
+ // 主要用于 raw: 模式下,后端自己校验登录,
+ if (
+ response.status === 401 &&
+ response.data.location &&
+ response.data.location.startsWith('http')
+ ) {
+ location.href = response.data.location.replace(
+ '{{redirect}}',
+ encodeURIComponent(location.href)
+ );
+ return new Promise(() => {});
+ } else if (response.data.msg) {
+ throw new Error(response.data.msg);
+ } else {
+ throw new Error(JSON.stringify(response.data, null, 2));
+ }
+ } else {
+ throw new Error(`${response.status}`);
+ }
+ }
+
+ return response;
+ },
+ isCancel: value => axios.isCancel(value),
+ copy: (content, options) => {
+ copy(content, options);
+ toast.success('内容已复制到粘贴板');
+ },
+ blockRouting: fn => {
+ return history.block(fn);
+ },
+ tracker(eventTrack) {
+ console.debug('eventTrack', eventTrack);
+ },
+ loadTinymcePlugin: async tinymce => {
+ // 参考:https://www.tiny.cloud/docs/advanced/creating-a-plugin/
+ /*
Note: We have included the plugin in the same JavaScript file as the TinyMCE
instance for display purposes only. Tiny recommends not maintaining the plugin
with the TinyMCE instance and using the `external_plugins` option.
*/
- tinymce.PluginManager.add('example', function (editor, url) {
- var openDialog = function () {
- return editor.windowManager.open({
- title: 'Example plugin',
- body: {
- type: 'panel',
- items: [
- {
- type: 'input',
- name: 'title',
- label: 'Title'
- }
- ]
- },
- buttons: [
- {
- type: 'cancel',
- text: 'Close'
+ tinymce.PluginManager.add('example', function (editor, url) {
+ var openDialog = function () {
+ return editor.windowManager.open({
+ title: 'Example plugin',
+ body: {
+ type: 'panel',
+ items: [
+ {
+ type: 'input',
+ name: 'title',
+ label: 'Title'
+ }
+ ]
},
- {
- type: 'submit',
- text: 'Save',
- primary: true
+ buttons: [
+ {
+ type: 'cancel',
+ text: 'Close'
+ },
+ {
+ type: 'submit',
+ text: 'Save',
+ primary: true
+ }
+ ],
+ onSubmit: function (api) {
+ var data = api.getData();
+ /* Insert content when the window form is submitted */
+ editor.insertContent('Title: ' + data.title);
+ api.close();
}
- ],
- onSubmit: function (api) {
- var data = api.getData();
- /* Insert content when the window form is submitted */
- editor.insertContent('Title: ' + data.title);
- api.close();
+ });
+ };
+ /* Add a button that opens a window */
+ editor.ui.registry.addButton('example', {
+ text: 'My button',
+ onAction: function () {
+ /* Open window */
+ openDialog();
}
});
- };
- /* Add a button that opens a window */
- editor.ui.registry.addButton('example', {
- text: 'My button',
- onAction: function () {
- /* Open window */
- openDialog();
- }
+ /* Adds a menu item, which can then be included in any menu via the menu/menubar configuration */
+ editor.ui.registry.addMenuItem('example', {
+ text: 'Example plugin',
+ onAction: function () {
+ /* Open window */
+ openDialog();
+ }
+ });
+ /* Return the metadata for the help plugin */
+ return {
+ getMetadata: function () {
+ return {
+ name: 'Example plugin',
+ url: 'http://exampleplugindocsurl.com'
+ };
+ }
+ };
});
- /* Adds a menu item, which can then be included in any menu via the menu/menubar configuration */
- editor.ui.registry.addMenuItem('example', {
- text: 'Example plugin',
- onAction: function () {
- /* Open window */
- openDialog();
- }
- });
- /* Return the metadata for the help plugin */
- return {
- getMetadata: function () {
- return {
- name: 'Example plugin',
- url: 'http://exampleplugindocsurl.com'
- };
- }
- };
- });
- },
- // 是否开启测试 testid
- // enableTestid: true,
- ...envOverrides
- };
-
- this.handleEditorMount = this.handleEditorMount.bind(this);
-
- this.iframeRef = React.createRef();
- this.watchIframeReady = this.watchIframeReady.bind(this);
- window.addEventListener('message', this.watchIframeReady, false);
- }
-
- handleEditorMount(editor, monaco) {
- let host = `${window.location.protocol}//${window.location.host}`;
-
- // 如果在 gh-pages 里面
- if (/^\/amis/.test(window.location.pathname)) {
- host += '/amis';
- }
-
- const schemaUrl = `${host}/schema.json`;
-
- monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
- schemas: [
- {
- uri: schemaUrl,
- fileMatch: ['*']
- }
- ],
- validate: true,
- enableSchemaRequest: true,
- allowComments: true
- });
- }
-
- renderCode() {
- return (
-