Replace monaco-editor with Codemirror
This commit is contained in:
parent
78b56dd38b
commit
146899934a
|
|
@ -1,13 +1,7 @@
|
||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
module.exports = {
|
module.exports = {
|
||||||
webpack: {
|
webpack: {
|
||||||
plugins: [
|
|
||||||
new MonacoWebpackPlugin({
|
|
||||||
languages: ["json", "javascript"],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
resolve: {
|
resolve: {
|
||||||
modules: [path.resolve(__dirname, "src"), "node_modules"],
|
modules: [path.resolve(__dirname, "src"), "node_modules"],
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@
|
||||||
"@uppy/webcam": "^1.3.1",
|
"@uppy/webcam": "^1.3.1",
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"chance": "^1.1.3",
|
"chance": "^1.1.3",
|
||||||
|
"codemirror": "^5.50.0",
|
||||||
"eslint": "^6.4.0",
|
"eslint": "^6.4.0",
|
||||||
"flow-bin": "^0.91.0",
|
"flow-bin": "^0.91.0",
|
||||||
"fontfaceobserver": "^2.1.0",
|
"fontfaceobserver": "^2.1.0",
|
||||||
|
|
@ -48,8 +49,6 @@
|
||||||
"lodash": "^4.17.11",
|
"lodash": "^4.17.11",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"moment-timezone": "^0.5.27",
|
"moment-timezone": "^0.5.27",
|
||||||
"monaco-editor": "^0.19.0",
|
|
||||||
"monaco-editor-webpack-plugin": "^1.1.0",
|
|
||||||
"nanoid": "^2.0.4",
|
"nanoid": "^2.0.4",
|
||||||
"node-sass": "^4.11.0",
|
"node-sass": "^4.11.0",
|
||||||
"normalizr": "^3.3.0",
|
"normalizr": "^3.3.0",
|
||||||
|
|
@ -70,7 +69,6 @@
|
||||||
"react-router-dom": "^5.1.2",
|
"react-router-dom": "^5.1.2",
|
||||||
"react-scripts": "^3.3.0",
|
"react-scripts": "^3.3.0",
|
||||||
"react-select": "^3.0.8",
|
"react-select": "^3.0.8",
|
||||||
"react-simple-tree-menu": "^1.1.9",
|
|
||||||
"react-tabs": "^3.0.0",
|
"react-tabs": "^3.0.0",
|
||||||
"react-transition-group": "^4.3.0",
|
"react-transition-group": "^4.3.0",
|
||||||
"redux": "^4.0.1",
|
"redux": "^4.0.1",
|
||||||
|
|
@ -116,6 +114,7 @@
|
||||||
"@storybook/addons": "^5.2.6",
|
"@storybook/addons": "^5.2.6",
|
||||||
"@storybook/preset-create-react-app": "^1.3.1",
|
"@storybook/preset-create-react-app": "^1.3.1",
|
||||||
"@storybook/react": "^5.2.6",
|
"@storybook/react": "^5.2.6",
|
||||||
|
"@types/codemirror": "^0.0.82",
|
||||||
"@types/jest": "^24.0.22",
|
"@types/jest": "^24.0.22",
|
||||||
"@types/react-select": "^3.0.5",
|
"@types/react-select": "^3.0.5",
|
||||||
"@types/react-tabs": "^2.3.1",
|
"@types/react-tabs": "^2.3.1",
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,12 @@ import { BaseText } from "components/designSystems/blueprint/TextComponent";
|
||||||
import { BaseTabbedView } from "components/designSystems/appsmith/TabbedView";
|
import { BaseTabbedView } from "components/designSystems/appsmith/TabbedView";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { AppState } from "reducers";
|
import { AppState } from "reducers";
|
||||||
import CodeEditor from "./CodeEditor";
|
|
||||||
import { ActionResponse } from "api/ActionAPI";
|
import { ActionResponse } from "api/ActionAPI";
|
||||||
import { formatBytes } from "utils/helpers";
|
import { formatBytes } from "utils/helpers";
|
||||||
import { APIEditorRouteParams } from "constants/routes";
|
import { APIEditorRouteParams } from "constants/routes";
|
||||||
import { ApiPaneReduxState } from "reducers/uiReducers/apiPaneReducer";
|
import { ApiPaneReduxState } from "reducers/uiReducers/apiPaneReducer";
|
||||||
import LoadingOverlayScreen from "components/editorComponents/LoadingOverlayScreen";
|
import LoadingOverlayScreen from "components/editorComponents/LoadingOverlayScreen";
|
||||||
|
import DynamicAutocompleteInput from "components/editorComponents/DynamicAutocompleteInput";
|
||||||
|
|
||||||
const ResponseWrapper = styled.div`
|
const ResponseWrapper = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
@ -138,16 +138,12 @@ const ApiResponseView = (props: Props) => {
|
||||||
key: "body",
|
key: "body",
|
||||||
title: "Response Body",
|
title: "Response Body",
|
||||||
panelComponent: (
|
panelComponent: (
|
||||||
<CodeEditor
|
<DynamicAutocompleteInput
|
||||||
theme={"LIGHT"}
|
|
||||||
height={600}
|
|
||||||
language={"json"}
|
|
||||||
input={{
|
input={{
|
||||||
value: response.body
|
value: response.body
|
||||||
? JSON.stringify(response.body, null, 2)
|
? JSON.stringify(response.body, null, 2)
|
||||||
: "",
|
: "",
|
||||||
}}
|
}}
|
||||||
lineNumbersMinChars={2}
|
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
import React from "react";
|
import React, { ChangeEvent } from "react";
|
||||||
import MonacoEditor from "react-monaco-editor";
|
import cm from "codemirror";
|
||||||
|
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { editor } from "monaco-editor";
|
import "codemirror/lib/codemirror.css";
|
||||||
|
import "codemirror/theme/monokai.css";
|
||||||
|
require("codemirror/mode/javascript/javascript");
|
||||||
|
|
||||||
const Wrapper = styled.div<{ height: number }>`
|
const Wrapper = styled.div<{ height: number }>`
|
||||||
height: ${props => props.height}px;
|
height: ${props => props.height}px;
|
||||||
|
|
@ -12,46 +13,49 @@ const Wrapper = styled.div<{ height: number }>`
|
||||||
interface Props {
|
interface Props {
|
||||||
input: {
|
input: {
|
||||||
value: string;
|
value: string;
|
||||||
onChange?: (value: string) => void;
|
onChange?: (event: ChangeEvent<HTMLTextAreaElement>) => void;
|
||||||
};
|
};
|
||||||
language: string;
|
|
||||||
height: number;
|
height: number;
|
||||||
placeholder?: string;
|
|
||||||
lineNumbers?: "on" | "off";
|
|
||||||
glyphMargin?: boolean;
|
|
||||||
folding?: boolean;
|
|
||||||
lineDecorationsWidth?: number;
|
|
||||||
lineNumbersMinChars?: number;
|
|
||||||
theme?: "LIGHT" | "DARK";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CodeEditor = (props: Props) => {
|
class CodeEditor extends React.Component<Props> {
|
||||||
const options: editor.IEditorConstructionOptions = {
|
textArea = React.createRef<HTMLTextAreaElement>();
|
||||||
wordWrap: "on",
|
editor: any;
|
||||||
wrappingIndent: "indent",
|
constructor(props: Props) {
|
||||||
selectOnLineNumbers: true,
|
super(props);
|
||||||
minimap: { enabled: false },
|
}
|
||||||
readOnly: !props.input.onChange,
|
componentDidMount(): void {
|
||||||
lineNumbers: props.lineNumbers,
|
if (this.textArea.current) {
|
||||||
glyphMargin: props.glyphMargin,
|
this.editor = cm.fromTextArea(this.textArea.current, {
|
||||||
folding: props.folding,
|
mode: { name: "javascript", json: true },
|
||||||
contextmenu: false,
|
value: this.props.input.value,
|
||||||
scrollBeyondLastLine: false,
|
lineNumbers: true,
|
||||||
// // Undocumented see https://github.com/Microsoft/vscode/issues/30795#issuecomment-410998882
|
tabSize: 2,
|
||||||
lineDecorationsWidth: props.lineDecorationsWidth,
|
indentWithTabs: true,
|
||||||
lineNumbersMinChars: props.lineNumbersMinChars,
|
lineWrapping: true,
|
||||||
};
|
});
|
||||||
return (
|
}
|
||||||
<Wrapper height={props.height}>
|
}
|
||||||
<MonacoEditor
|
|
||||||
language={props.language}
|
componentDidUpdate(
|
||||||
theme={props.theme ? props.theme : "LIGHT"}
|
prevProps: Readonly<Props>,
|
||||||
value={props.input.value}
|
prevState: Readonly<{}>,
|
||||||
options={options}
|
snapshot?: any,
|
||||||
onChange={props.input.onChange}
|
): void {
|
||||||
/>
|
this.editor.setValue(this.props.input.value);
|
||||||
</Wrapper>
|
}
|
||||||
);
|
|
||||||
};
|
render(): React.ReactNode {
|
||||||
|
return (
|
||||||
|
<Wrapper height={this.props.height}>
|
||||||
|
<textarea
|
||||||
|
ref={this.textArea}
|
||||||
|
onChange={this.props.input.onChange}
|
||||||
|
defaultValue={this.props.input.value}
|
||||||
|
/>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default CodeEditor;
|
export default CodeEditor;
|
||||||
|
|
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import { TreeMenuItem } from "react-simple-tree-menu";
|
|
||||||
import styled from "styled-components";
|
|
||||||
import { Icon } from "@blueprintjs/core";
|
|
||||||
|
|
||||||
const NodeWrapper = styled.li<{ level: number; isActive?: boolean }>`
|
|
||||||
& {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
min-height: 32px;
|
|
||||||
padding-left: ${props => props.level * 2}em;
|
|
||||||
background-color: ${props => (props.isActive ? "#e9faf3" : "white")};
|
|
||||||
cursor: pointer;
|
|
||||||
&:hover {
|
|
||||||
background-color: #e9faf3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const CaretIcon = styled(Icon)`
|
|
||||||
color: #a3b3bf;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Label = styled.div`
|
|
||||||
color: ${props => props.theme.colors.textDefault}
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
flex: none;
|
|
||||||
max-width: 70%;
|
|
||||||
padding-right: 5px;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Type = styled.span`
|
|
||||||
color: #737e8a;
|
|
||||||
flex: 2;
|
|
||||||
`;
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
item: TreeMenuItem;
|
|
||||||
};
|
|
||||||
|
|
||||||
const DataTreeNode = ({ item }: Props) => (
|
|
||||||
<NodeWrapper
|
|
||||||
onClick={item.hasNodes && item.toggleNode ? item.toggleNode : item.onClick}
|
|
||||||
level={item.level}
|
|
||||||
isActive={item.focused}
|
|
||||||
>
|
|
||||||
<CaretIcon
|
|
||||||
icon={
|
|
||||||
item.hasNodes ? (item.isOpen ? "caret-down" : "caret-right") : "dot"
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
<Label>{item.labelRender}</Label>
|
|
||||||
<Type>//{item.type}</Type>
|
|
||||||
</NodeWrapper>
|
|
||||||
);
|
|
||||||
|
|
||||||
export default DataTreeNode;
|
|
||||||
|
|
@ -1,217 +1,100 @@
|
||||||
import React, { ChangeEvent, Component, KeyboardEvent } from "react";
|
import React, { Component } from "react";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { AppState } from "reducers";
|
import { AppState } from "reducers";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import _ from "lodash";
|
import CodeMirror, { EditorConfiguration } from "codemirror";
|
||||||
import {
|
import "codemirror/lib/codemirror.css";
|
||||||
getDynamicAutocompleteSearchTerm,
|
import "codemirror/theme/monokai.css";
|
||||||
getDynamicBindings,
|
import "codemirror/addon/hint/show-hint";
|
||||||
} from "utils/DynamicBindingUtils";
|
import "codemirror/addon/hint/show-hint.css";
|
||||||
import {
|
import "codemirror/addon/hint/javascript-hint";
|
||||||
BaseTextInput,
|
|
||||||
TextInputProps,
|
|
||||||
} from "components/designSystems/appsmith/TextInputComponent";
|
|
||||||
import {
|
import {
|
||||||
getNameBindingsWithData,
|
getNameBindingsWithData,
|
||||||
NameBindingsWithData,
|
NameBindingsWithData,
|
||||||
} from "selectors/nameBindingsWithDataSelector";
|
} from "selectors/nameBindingsWithDataSelector";
|
||||||
import TreeMenu, {
|
require("codemirror/mode/javascript/javascript");
|
||||||
MatchSearchFunction,
|
|
||||||
TreeMenuItem,
|
|
||||||
TreeNodeInArray,
|
|
||||||
} from "react-simple-tree-menu";
|
|
||||||
import { DATA_BIND_AUTOCOMPLETE } from "constants/BindingsConstants";
|
|
||||||
import DataTreeNode from "components/editorComponents/DataTreeNode";
|
|
||||||
import { transformToTreeStructure } from "utils/DynamicTreeAutoCompleteUtils";
|
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div<{ height?: number; theme?: "LIGHT" | "DARK" }>`
|
||||||
|
border: ${props => props.theme !== "DARK" && "1px solid #d0d7dd"};
|
||||||
|
border-radius: 4px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
position: relative;
|
position: relative;
|
||||||
`;
|
|
||||||
|
|
||||||
const DataTreeWrapper = styled.div`
|
|
||||||
position: absolute;
|
|
||||||
top: 33px;
|
|
||||||
z-index: 21;
|
|
||||||
padding: 10px;
|
|
||||||
max-height: 400px;
|
|
||||||
width: 450px;
|
|
||||||
overflow-y: auto;
|
|
||||||
background-color: white;
|
|
||||||
border: 1px solid #ebeff2;
|
|
||||||
box-shadow: 0px 2px 4px rgba(67, 70, 74, 0.14);
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 14px;
|
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
`;
|
min-height: 32px;
|
||||||
|
height: ${props => (props.height ? `${props.height}px` : "32px")};
|
||||||
const NoResultsMessage = styled.p`
|
|
||||||
color: ${props => props.theme.colors.textDefault};
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
interface ReduxStateProps {
|
interface ReduxStateProps {
|
||||||
dynamicData: NameBindingsWithData;
|
dynamicData: NameBindingsWithData;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = ReduxStateProps & TextInputProps;
|
type Props = ReduxStateProps & {
|
||||||
|
input: {
|
||||||
type State = {
|
value: string;
|
||||||
tree: TreeNodeInArray[];
|
onChange?: (value: string) => void;
|
||||||
showTree: boolean;
|
};
|
||||||
focusedNode: string;
|
theme?: "LIGHT" | "DARK";
|
||||||
};
|
};
|
||||||
|
|
||||||
class DynamicAutocompleteInput extends Component<Props, State> {
|
class DynamicAutocompleteInput extends Component<Props> {
|
||||||
private input: HTMLInputElement | null = null;
|
textArea = React.createRef<HTMLTextAreaElement>();
|
||||||
private search: Function | undefined;
|
editor: any;
|
||||||
constructor(props: Props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
tree: [],
|
|
||||||
showTree: true,
|
|
||||||
focusedNode: "",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
this.updateTree();
|
if (this.textArea.current) {
|
||||||
}
|
const options: EditorConfiguration = {};
|
||||||
componentDidUpdate(prevProps: Readonly<Props>): void {
|
if (this.props.theme === "DARK") options.theme = "monokai";
|
||||||
if (prevProps.dynamicData !== this.props.dynamicData) {
|
if (!this.props.input.onChange) options.readOnly = true;
|
||||||
this.updateTree();
|
this.editor = CodeMirror.fromTextArea(this.textArea.current, {
|
||||||
}
|
mode: { name: "javascript", globalVars: true },
|
||||||
this.updateTreeVisibility();
|
value: this.props.input.value,
|
||||||
}
|
tabSize: 2,
|
||||||
updateTreeVisibility = () => {
|
indentWithTabs: true,
|
||||||
const { showTree } = this.state;
|
lineWrapping: true,
|
||||||
const { input } = this.props;
|
extraKeys: { "Ctrl-Space": "autocomplete" },
|
||||||
let value;
|
showHint: true,
|
||||||
let hasIncomplete = 0;
|
...options,
|
||||||
if (input && input.value) {
|
});
|
||||||
value = input.value;
|
this.editor.on("change", this.handleChange);
|
||||||
}
|
this.editor.on("keyup", this.handleAutocompleteVisibility);
|
||||||
if (value && typeof value === "string") {
|
this.editor.setOption("hintOptions", {
|
||||||
const { bindings, paths } = getDynamicBindings(value);
|
completeSingle: false,
|
||||||
bindings.forEach((binding, i) => {
|
globalScope: this.props.dynamicData,
|
||||||
if (binding.indexOf("{{") > -1 && paths[i] === "") {
|
|
||||||
hasIncomplete++;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (showTree) {
|
componentDidUpdate(): void {
|
||||||
if (hasIncomplete === 0) {
|
if (this.editor) {
|
||||||
this.setState({ showTree: false });
|
const editorValue = this.editor.getValue();
|
||||||
}
|
const inputValue = this.props.input.value;
|
||||||
} else {
|
if (inputValue && inputValue !== editorValue) {
|
||||||
if (hasIncomplete > 0) {
|
this.editor.setValue(inputValue);
|
||||||
this.setState({ showTree: true });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
handleNodeSearch: MatchSearchFunction = ({ path, searchTerm }) => {
|
|
||||||
const lowerCasePath = path.toLowerCase();
|
handleChange = () => {
|
||||||
const lowerCaseSearchTerm = searchTerm.toLowerCase();
|
const value = this.editor.getValue();
|
||||||
const matchPath = lowerCasePath.substr(0, searchTerm.length);
|
if (this.props.input.onChange) {
|
||||||
return matchPath === lowerCaseSearchTerm;
|
this.props.input.onChange(value);
|
||||||
};
|
|
||||||
updateTree = () => {
|
|
||||||
const { dynamicData } = this.props;
|
|
||||||
const filters = Object.keys(dynamicData).map(name => ({ name }));
|
|
||||||
const tree = transformToTreeStructure(
|
|
||||||
dynamicData,
|
|
||||||
filters.map(f => f.name),
|
|
||||||
);
|
|
||||||
this.setState({ tree });
|
|
||||||
};
|
|
||||||
handleNodeSelected = (node: any) => {
|
|
||||||
if (this.props.input && this.props.input.value) {
|
|
||||||
const currentValue = String(this.props.input.value);
|
|
||||||
const path = node.path;
|
|
||||||
const { bindings, paths } = getDynamicBindings(currentValue);
|
|
||||||
const autoComplete = bindings.map((binding, i) => {
|
|
||||||
if (binding.indexOf("{{") > -1 && paths[i] === "") {
|
|
||||||
return binding.replace(DATA_BIND_AUTOCOMPLETE, `{{${path}}}`);
|
|
||||||
}
|
|
||||||
return binding;
|
|
||||||
});
|
|
||||||
this.props.input.onChange &&
|
|
||||||
this.props.input.onChange(autoComplete.join(""));
|
|
||||||
this.input && this.input.focus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
setInputRef = (ref: HTMLInputElement | null) => {
|
|
||||||
if (ref) {
|
|
||||||
this.input = ref;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
handleInputChange = (e: ChangeEvent<{ value: string }>) => {
|
|
||||||
if (this.props.input && this.props.input.onChange) {
|
|
||||||
this.props.input.onChange(e);
|
|
||||||
}
|
|
||||||
const value = e.target.value;
|
|
||||||
if (this.search) {
|
|
||||||
const { bindings, paths } = getDynamicBindings(value);
|
|
||||||
bindings.forEach((binding, i) => {
|
|
||||||
if (binding.indexOf("{{") > -1 && paths[i] === "") {
|
|
||||||
const query = getDynamicAutocompleteSearchTerm(binding);
|
|
||||||
this.search && this.search(query);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
|
handleAutocompleteVisibility = (cm: any, event: any) => {
|
||||||
if (event.key === "ArrowDown") {
|
if (!cm.state.completionActive && event.keyCode !== 13) {
|
||||||
if (
|
cm.showHint(cm);
|
||||||
document.activeElement &&
|
|
||||||
document.activeElement.tagName === "INPUT"
|
|
||||||
) {
|
|
||||||
const tree = document.getElementById("tree");
|
|
||||||
const container =
|
|
||||||
tree && tree.closest<HTMLDivElement>("[tabindex='0']");
|
|
||||||
if (container) {
|
|
||||||
container.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { input, ...rest } = this.props;
|
const { input, theme } = this.props;
|
||||||
|
const height = this.editor ? this.editor.doc.height + 20 : null;
|
||||||
return (
|
return (
|
||||||
<Wrapper onKeyDown={this.handleKeyDown}>
|
<Wrapper height={height} theme={theme}>
|
||||||
<BaseTextInput
|
<textarea ref={this.textArea} defaultValue={input.value} />
|
||||||
refHandler={this.setInputRef}
|
|
||||||
input={{
|
|
||||||
...input,
|
|
||||||
onChange: this.handleInputChange,
|
|
||||||
}}
|
|
||||||
{..._.omit(rest, ["dynamicData", "dispatch"])}
|
|
||||||
/>
|
|
||||||
{this.state.showTree && this.state.tree.length && (
|
|
||||||
<TreeMenu
|
|
||||||
data={this.state.tree}
|
|
||||||
matchSearch={this.handleNodeSearch}
|
|
||||||
onClickItem={this.handleNodeSelected}
|
|
||||||
initialFocusKey={this.state.tree[0].key}
|
|
||||||
disableKeyboard={false}
|
|
||||||
>
|
|
||||||
{({ search, items }) => (
|
|
||||||
<DataTreeWrapper id="tree">
|
|
||||||
{items.length === 0 ? (
|
|
||||||
<NoResultsMessage>No results found</NoResultsMessage>
|
|
||||||
) : (
|
|
||||||
items.map((item: TreeMenuItem) => {
|
|
||||||
this.search = search;
|
|
||||||
return <DataTreeNode key={item.key} item={item} />;
|
|
||||||
})
|
|
||||||
)}
|
|
||||||
</DataTreeWrapper>
|
|
||||||
)}
|
|
||||||
</TreeMenu>
|
|
||||||
)}
|
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,9 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Field } from "redux-form";
|
import { Field } from "redux-form";
|
||||||
import CodeEditor from "components/editorComponents/CodeEditor";
|
import DynamicAutocompleteInput from "components/editorComponents/DynamicAutocompleteInput";
|
||||||
|
|
||||||
const JSONEditorField = (props: { name: string }) => {
|
const JSONEditorField = (props: { name: string }) => {
|
||||||
return (
|
return <Field name={props.name} component={DynamicAutocompleteInput} />;
|
||||||
<Field
|
|
||||||
name={props.name}
|
|
||||||
component={CodeEditor}
|
|
||||||
height={500}
|
|
||||||
language={"json"}
|
|
||||||
placeholder="Input post body here"
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default JSONEditorField;
|
export default JSONEditorField;
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,15 @@ import React from "react";
|
||||||
import BaseControl, { ControlProps } from "./BaseControl";
|
import BaseControl, { ControlProps } from "./BaseControl";
|
||||||
import { ControlType } from "constants/PropertyControlConstants";
|
import { ControlType } from "constants/PropertyControlConstants";
|
||||||
import { ControlWrapper } from "./StyledControls";
|
import { ControlWrapper } from "./StyledControls";
|
||||||
import CodeEditor from "components/editorComponents/CodeEditor";
|
import DynamicAutocompleteInput from "components/editorComponents/DynamicAutocompleteInput";
|
||||||
class CodeEditorControl extends BaseControl<ControlProps> {
|
class CodeEditorControl extends BaseControl<ControlProps> {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<ControlWrapper>
|
<ControlWrapper>
|
||||||
<label>{this.props.label}</label>
|
<label>{this.props.label}</label>
|
||||||
<CodeEditor
|
<DynamicAutocompleteInput
|
||||||
language={"json"}
|
|
||||||
height={200}
|
|
||||||
input={{ value: this.props.propertyValue, onChange: this.onChange }}
|
|
||||||
lineNumbers={"off"}
|
|
||||||
glyphMargin={false}
|
|
||||||
folding={false}
|
|
||||||
lineDecorationsWidth={0}
|
|
||||||
lineNumbersMinChars={0}
|
|
||||||
theme={"DARK"}
|
theme={"DARK"}
|
||||||
|
input={{ value: this.props.propertyValue, onChange: this.onChange }}
|
||||||
/>
|
/>
|
||||||
</ControlWrapper>
|
</ControlWrapper>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,29 +3,27 @@ import BaseControl, { ControlProps } from "./BaseControl";
|
||||||
import { ControlWrapper, StyledDynamicInput } from "./StyledControls";
|
import { ControlWrapper, StyledDynamicInput } from "./StyledControls";
|
||||||
import { InputType } from "widgets/InputWidget";
|
import { InputType } from "widgets/InputWidget";
|
||||||
import { ControlType } from "constants/PropertyControlConstants";
|
import { ControlType } from "constants/PropertyControlConstants";
|
||||||
import { Intent } from "@blueprintjs/core";
|
// import { Intent } from "@blueprintjs/core";
|
||||||
import DynamicAutocompleteInput from "components/editorComponents/DynamicAutocompleteInput";
|
import DynamicAutocompleteInput from "components/editorComponents/DynamicAutocompleteInput";
|
||||||
|
|
||||||
class InputTextControl extends BaseControl<InputControlProps> {
|
class InputTextControl extends BaseControl<InputControlProps> {
|
||||||
render() {
|
render() {
|
||||||
const { validationMessage, propertyValue, isValid, label } = this.props;
|
const {
|
||||||
|
// validationMessage,
|
||||||
|
propertyValue,
|
||||||
|
// isValid,
|
||||||
|
label,
|
||||||
|
} = this.props;
|
||||||
return (
|
return (
|
||||||
<ControlWrapper>
|
<ControlWrapper>
|
||||||
<label>{label}</label>
|
<label>{label}</label>
|
||||||
<StyledDynamicInput>
|
<StyledDynamicInput>
|
||||||
<DynamicAutocompleteInput
|
<DynamicAutocompleteInput
|
||||||
intent={isValid ? Intent.NONE : Intent.DANGER}
|
|
||||||
type={this.isNumberType() ? "number" : "text"}
|
|
||||||
input={{
|
input={{
|
||||||
value: propertyValue,
|
value: propertyValue,
|
||||||
onChange: this.onTextChange,
|
onChange: this.onTextChange,
|
||||||
}}
|
}}
|
||||||
placeholder={this.props.placeholderText}
|
theme={"DARK"}
|
||||||
meta={{
|
|
||||||
touched: true,
|
|
||||||
error: validationMessage,
|
|
||||||
}}
|
|
||||||
showError
|
|
||||||
/>
|
/>
|
||||||
</StyledDynamicInput>
|
</StyledDynamicInput>
|
||||||
</ControlWrapper>
|
</ControlWrapper>
|
||||||
|
|
@ -45,7 +43,7 @@ class InputTextControl extends BaseControl<InputControlProps> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTextChange = (event: React.ChangeEvent<HTMLInputElement> | string) => {
|
onTextChange = (event: React.ChangeEvent<HTMLTextAreaElement> | string) => {
|
||||||
let value = event;
|
let value = event;
|
||||||
if (typeof event !== "string") {
|
if (typeof event !== "string") {
|
||||||
value = event.target.value;
|
value = event.target.value;
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ import "./index.css";
|
||||||
import * as serviceWorker from "./serviceWorker";
|
import * as serviceWorker from "./serviceWorker";
|
||||||
import { Router, Route, Switch } from "react-router-dom";
|
import { Router, Route, Switch } from "react-router-dom";
|
||||||
import history from "./utils/history";
|
import history from "./utils/history";
|
||||||
import { ThemeProvider, theme } from "./constants/DefaultTheme";
|
import { ThemeProvider, theme } from "constants/DefaultTheme";
|
||||||
import { DndProvider } from "react-dnd";
|
import { DndProvider } from "react-dnd";
|
||||||
import HTML5Backend from "react-dnd-html5-backend";
|
import HTML5Backend from "react-dnd-html5-backend";
|
||||||
import { appInitializer } from "./utils/AppsmithUtils";
|
import { appInitializer } from "utils/AppsmithUtils";
|
||||||
import ProtectedRoute from "./pages/common/ProtectedRoute";
|
import ProtectedRoute from "./pages/common/ProtectedRoute";
|
||||||
import store from "./store";
|
import store from "./store";
|
||||||
import {
|
import {
|
||||||
|
|
@ -19,7 +19,7 @@ import {
|
||||||
APPLICATIONS_URL,
|
APPLICATIONS_URL,
|
||||||
ORG_URL,
|
ORG_URL,
|
||||||
USER_AUTH_URL,
|
USER_AUTH_URL,
|
||||||
} from "./constants/routes";
|
} from "constants/routes";
|
||||||
|
|
||||||
const loadingIndicator = <Loader />;
|
const loadingIndicator = <Loader />;
|
||||||
const App = lazy(() => import("./App"));
|
const App = lazy(() => import("./App"));
|
||||||
|
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
import { TreeNodeInArray } from "react-simple-tree-menu";
|
|
||||||
import React from "react";
|
|
||||||
import styled from "styled-components";
|
|
||||||
|
|
||||||
const Key = styled.span`
|
|
||||||
color: #768896;
|
|
||||||
padding-right: 5px;
|
|
||||||
`;
|
|
||||||
const Value = styled.span<{ type: string }>`
|
|
||||||
color: ${props => {
|
|
||||||
switch (props.type) {
|
|
||||||
case "string":
|
|
||||||
return "#2E3D49";
|
|
||||||
case "number":
|
|
||||||
return props.theme.colors.error;
|
|
||||||
case "boolean":
|
|
||||||
return props.theme.colors.primary;
|
|
||||||
default:
|
|
||||||
return "#2E3D49";
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const transformToTreeStructure = (
|
|
||||||
dataTree: Record<string, any>,
|
|
||||||
names: string[],
|
|
||||||
parentPath?: string,
|
|
||||||
): TreeNodeInArray[] => {
|
|
||||||
return names.map(name => {
|
|
||||||
const currentPath = parentPath ? `${parentPath}.${name}` : name;
|
|
||||||
let nodes: TreeNodeInArray["nodes"] = [];
|
|
||||||
const child = dataTree[name];
|
|
||||||
let childType: string = typeof child;
|
|
||||||
let labelRender: React.ReactNode = name;
|
|
||||||
if (childType === "object") {
|
|
||||||
if (!Array.isArray(child)) {
|
|
||||||
nodes = transformToTreeStructure(
|
|
||||||
child,
|
|
||||||
Object.keys(child),
|
|
||||||
currentPath,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
nodes = child.map((c, i) => ({
|
|
||||||
key: `[${i}]`,
|
|
||||||
path: `${currentPath}[${i}]`,
|
|
||||||
label: "",
|
|
||||||
labelRender: i.toString(),
|
|
||||||
nodes: transformToTreeStructure(
|
|
||||||
c,
|
|
||||||
Object.keys(c),
|
|
||||||
`${currentPath}[${i}]`,
|
|
||||||
),
|
|
||||||
}));
|
|
||||||
childType = "Array";
|
|
||||||
labelRender = `${name} {${child.length}}`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
labelRender = (
|
|
||||||
<div>
|
|
||||||
<Key>{name}: </Key>
|
|
||||||
<Value type={childType}>
|
|
||||||
{childType === "string"
|
|
||||||
? `"${dataTree[name]}"`
|
|
||||||
: String(dataTree[name])}
|
|
||||||
</Value>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
key: name,
|
|
||||||
path: currentPath,
|
|
||||||
label: "",
|
|
||||||
labelRender,
|
|
||||||
nodes,
|
|
||||||
type: childType,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
@ -2092,6 +2092,13 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/chance/-/chance-1.0.7.tgz#c680a3891a505d8c626ec3a46bb1c0496419dfb6"
|
resolved "https://registry.yarnpkg.com/@types/chance/-/chance-1.0.7.tgz#c680a3891a505d8c626ec3a46bb1c0496419dfb6"
|
||||||
integrity sha512-LBOkJ7899SSLm08KicLYX3DqWUhfDspMLWNGuV1UPpL3iUENSvI0THGlf05n9yNHTR7zDlV/mCGZ7ZJ0ws8v3Q==
|
integrity sha512-LBOkJ7899SSLm08KicLYX3DqWUhfDspMLWNGuV1UPpL3iUENSvI0THGlf05n9yNHTR7zDlV/mCGZ7ZJ0ws8v3Q==
|
||||||
|
|
||||||
|
"@types/codemirror@^0.0.82":
|
||||||
|
version "0.0.82"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-0.0.82.tgz#6d0c50036a023980318a6ed9f85ff5cc6b24172a"
|
||||||
|
integrity sha512-EVlPrt1rB256CRTlhNCXXLYaN24n3qZNStM6dRWaV6sUYyJA1SC5hvDSCHEHDg1SB93X8TwAGWRjEVdmUWPHmQ==
|
||||||
|
dependencies:
|
||||||
|
"@types/tern" "*"
|
||||||
|
|
||||||
"@types/color-name@^1.1.1":
|
"@types/color-name@^1.1.1":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||||
|
|
@ -2107,6 +2114,11 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d"
|
||||||
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
|
integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==
|
||||||
|
|
||||||
|
"@types/estree@*":
|
||||||
|
version "0.0.41"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.41.tgz#fd90754150b57432b72bf560530500597ff04421"
|
||||||
|
integrity sha512-rIAmXyJlqw4KEBO7+u9gxZZSQHaCNnIzYrnNmYVpgfJhxTqO0brCX0SYpqUTkVI5mwwUwzmtspLBGBKroMeynA==
|
||||||
|
|
||||||
"@types/events@*":
|
"@types/events@*":
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
|
resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7"
|
||||||
|
|
@ -2387,6 +2399,13 @@
|
||||||
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370"
|
resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370"
|
||||||
integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ==
|
integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ==
|
||||||
|
|
||||||
|
"@types/tern@*":
|
||||||
|
version "0.23.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/tern/-/tern-0.23.3.tgz#4b54538f04a88c9ff79de1f6f94f575a7f339460"
|
||||||
|
integrity sha512-imDtS4TAoTcXk0g7u4kkWqedB3E4qpjXzCpD2LU5M5NAXHzCDsypyvXSaG7mM8DKYkCRa7tFp4tS/lp/Wo7Q3w==
|
||||||
|
dependencies:
|
||||||
|
"@types/estree" "*"
|
||||||
|
|
||||||
"@types/tinycolor2@^1.4.2":
|
"@types/tinycolor2@^1.4.2":
|
||||||
version "1.4.2"
|
version "1.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf"
|
resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf"
|
||||||
|
|
@ -4517,6 +4536,11 @@ code-point-at@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||||
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
||||||
|
|
||||||
|
codemirror@^5.50.0:
|
||||||
|
version "5.50.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.50.0.tgz#aeacd18f225735b17cbab98908edace87fedcdab"
|
||||||
|
integrity sha512-32LAmGcBNhKtJP4WGgkcaCVQDyChAyaWA6jasg778ziZzo3PWBuhpAQIJMO8//Id45RoaLyXjuhcRUBoS8Vg+Q==
|
||||||
|
|
||||||
collapse-white-space@^1.0.0, collapse-white-space@^1.0.2:
|
collapse-white-space@^1.0.0, collapse-white-space@^1.0.2:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.5.tgz#c2495b699ab1ed380d29a1091e01063e75dbbe3a"
|
resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.5.tgz#c2495b699ab1ed380d29a1091e01063e75dbbe3a"
|
||||||
|
|
@ -8027,11 +8051,6 @@ is-directory@^0.3.1:
|
||||||
resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
|
resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
|
||||||
integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
|
integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
|
||||||
|
|
||||||
is-empty@^1.2.0:
|
|
||||||
version "1.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/is-empty/-/is-empty-1.2.0.tgz#de9bb5b278738a05a0b09a57e1fb4d4a341a9f6b"
|
|
||||||
integrity sha1-3pu1snhzigWgsJpX4ftNSjQan2s=
|
|
||||||
|
|
||||||
is-extendable@^0.1.0, is-extendable@^0.1.1:
|
is-extendable@^0.1.0, is-extendable@^0.1.1:
|
||||||
version "0.1.1"
|
version "0.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
|
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
|
||||||
|
|
@ -9920,18 +9939,6 @@ moment@2.24.0, "moment@>= 2.9.0", moment@>=2.14.0, moment@^2.24.0:
|
||||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
|
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
|
||||||
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
|
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
|
||||||
|
|
||||||
monaco-editor-webpack-plugin@^1.1.0:
|
|
||||||
version "1.8.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.8.1.tgz#5701bfce16c14c51503a607726d97fd92784af26"
|
|
||||||
integrity sha512-kf97Oyyz7E9BTujAvf7eary40aEB2rrHpaiSdD9p6SOwItk64mU9mGx6+S8Ku9B4RikL9aj/sK/7DinlBYj3AQ==
|
|
||||||
dependencies:
|
|
||||||
loader-utils "^1.2.3"
|
|
||||||
|
|
||||||
monaco-editor@^0.19.0:
|
|
||||||
version "0.19.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.19.0.tgz#c6e774210f3b292ff739e96f45a1cc78bf5ac2e7"
|
|
||||||
integrity sha512-ida++HI/s9V8ma8yYS9CAS0UJEFwW1gbt9G6oviEdv/aHhFd/kV3sXrINqC63TVdKzOZdKjPRRCOPJJ80zvLbw==
|
|
||||||
|
|
||||||
move-concurrently@^1.0.1:
|
move-concurrently@^1.0.1:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
|
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"
|
||||||
|
|
@ -12405,16 +12412,6 @@ react-side-effect@^1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
shallowequal "^1.0.1"
|
shallowequal "^1.0.1"
|
||||||
|
|
||||||
react-simple-tree-menu@^1.1.9:
|
|
||||||
version "1.1.12"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-simple-tree-menu/-/react-simple-tree-menu-1.1.12.tgz#ea6f0f95071f5065bc8894b02a19e2745f589844"
|
|
||||||
integrity sha512-uvT/kLdzW4xWsQMic3CJ8YI6Ir3N/rUAF/2hR5evgGTd8HkdPdQqQAKI/AnVlY9u/dx9uPA7FTNDFbUYUuSWBg==
|
|
||||||
dependencies:
|
|
||||||
classnames "^2.2.6"
|
|
||||||
fast-memoize "^2.5.1"
|
|
||||||
is-empty "^1.2.0"
|
|
||||||
tiny-debounce "^0.1.1"
|
|
||||||
|
|
||||||
react-sizeme@^2.6.7:
|
react-sizeme@^2.6.7:
|
||||||
version "2.6.10"
|
version "2.6.10"
|
||||||
resolved "https://registry.yarnpkg.com/react-sizeme/-/react-sizeme-2.6.10.tgz#9993dcb5e67fab94a8e5d078a0d3820609010f17"
|
resolved "https://registry.yarnpkg.com/react-sizeme/-/react-sizeme-2.6.10.tgz#9993dcb5e67fab94a8e5d078a0d3820609010f17"
|
||||||
|
|
@ -14362,11 +14359,6 @@ timsort@^0.3.0:
|
||||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||||
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
||||||
|
|
||||||
tiny-debounce@^0.1.1:
|
|
||||||
version "0.1.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/tiny-debounce/-/tiny-debounce-0.1.1.tgz#e7759447ca1d48830d3b302ce94666a0ca537b1d"
|
|
||||||
integrity sha1-53WUR8odSIMNOzAs6UZmoMpTex0=
|
|
||||||
|
|
||||||
tiny-emitter@^2.0.0:
|
tiny-emitter@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user