Commit fa4e61cb authored by wenmo's avatar wenmo

优化状态与SQL编辑器性能

parent 21325641
......@@ -6,7 +6,7 @@ import {connect,Dispatch} from "umi";
import {DocumentStateType} from "@/pages/Document/model";
import {DocumentTableListItem} from "@/pages/Document/data";
import {parseSqlMetaData} from "@/components/Studio/StudioEvent/Utils";
import {Column, MetaData} from "@/components/Studio/StudioEvent/data";
import {Column, MetaData, SqlMetaData} from "@/components/Studio/StudioEvent/data";
import StudioExplain from "@/components/Studio/StudioConsole/StudioExplain";
import {format} from "sql-formatter";
......@@ -23,45 +23,35 @@ interface ISuggestions {
const FlinkSqlEditor = (props:any) => {
const {
tabsKey,
tabsKey,
height = '100%',
width = '100%',
language = 'sql',
onChange=(val: string, event: { changes: { text: any }[] })=>{},
onChange=(val: string, event: any)=>{},
options = {
selectOnLineNumbers: true,
renderSideBySide: false,
},
tabs,
sql,
monaco,
// sqlMetaData,
fillDocuments,
} = props;
const editorInstance:any = useRef<any>();
const editorInstance: any = useRef<any>();
const monacoInstance: any = useRef();
const [modalVisible, handleModalVisible] = useState<boolean>(false);
const getTabIndex = ():number=>{
for(let i=0;i<tabs.panes.length;i++){
if(tabs.panes[i].key==tabsKey){
return i;
}
}
return 0;
};
const tabIndex = getTabIndex();
const code: any = useRef(tabs.panes[tabIndex].value ? tabs.panes[tabIndex].value : '');
const cache: any = useRef(code.current);
const [metaData, setMetaData] = useState<SqlMetaData>({});
const [code, setCode] = useState<string>(sql);
useEffect(
() => () => {
provider.dispose();
},
[]
);
reloadCompletion();
}, [code]);
useImperativeHandle(editorInstance, () => ({
handleSetEditorVal,
getEditorData: () => cache.current,
getEditorData: () => code,
}));
const handleSetEditorVal = (value: string): void => {
......@@ -82,23 +72,34 @@ const FlinkSqlEditor = (props:any) => {
}
};
const onChangeHandle = (val: string, event: { changes: { text: any }[] }) => {
let sqlMetaData = parseSqlMetaData(val);
props.saveMetaData(sqlMetaData,tabs,tabIndex);
const onChangeHandle = (val: string, event: any) => {
setCode(val);
onChange(val,event);
/*const curWord = event.changes[0].text;
if (curWord === ';') {
cache.current = val +'\r\n';
setRefresh(!refresh); // 刷新页面
return;
}
cache.current = val;*/
/*let newSqlMetaData = parseSqlMetaData(val);
setMetaData(newSqlMetaData);
props.saveSqlMetaData(newSqlMetaData,tabsKey);*/
props.saveSql(val);
};
const reloadCompletion = () =>{
let newSqlMetaData = parseSqlMetaData(code);
setMetaData({...newSqlMetaData});
provider.dispose();// 清空提示项
provider = monacoInstance.current.languages.registerCompletionItemProvider('sql', {
provideCompletionItems() {
return {
suggestions:buildSuggestions(),
};
},
// quickSuggestions: false,
// triggerCharacters: ['$', '.', '='],
});
};
const buildSuggestions = () => {
let suggestions: ISuggestions[] = [];
tabs.panes[tabIndex].sqlMetaData?.metaData?.forEach((item:MetaData) => {
console.log(metaData);
metaData.metaData?.forEach((item: MetaData) => {
suggestions.push({
label: item.table,
kind: _monaco.languages.CompletionItemKind.Constant,
......@@ -141,9 +142,6 @@ const FlinkSqlEditor = (props:any) => {
const editorDidMountHandle = (editor: any, monaco: any) => {
monacoInstance.current = monaco;
editorInstance.current = editor;
editor.addCommand(monaco.KeyMod.Alt|monaco.KeyCode.KEY_1,function (){
props.saveText(tabs,tabIndex);
})
editor.addCommand(monaco.KeyMod.Alt|monaco.KeyCode.KEY_2,function (){
handleModalVisible(true);
......@@ -151,17 +149,9 @@ const FlinkSqlEditor = (props:any) => {
editor.addCommand(monaco.KeyMod.Alt|monaco.KeyCode.KEY_3,function (){
editor.getAction(['editor.action.formatDocument'])._run();
})
provider.dispose();// 清空提示项
// 提示项设值
provider = monaco.languages.registerCompletionItemProvider('sql', {
provideCompletionItems() {
return {
suggestions:buildSuggestions(),
};
},
// quickSuggestions: false,
// triggerCharacters: ['$', '.', '='],
});
reloadCompletion();
monaco.languages.registerDocumentRangeFormattingEditProvider('sql', {
provideDocumentRangeFormattingEdits(model, range, options) {
var formatted = format(model.getValueInRange(range), {
......@@ -181,11 +171,11 @@ const FlinkSqlEditor = (props:any) => {
return (
<React.Fragment>
<MonacoEditor
ref={tabs.panes[tabIndex].monaco}
ref={monaco}
width={width}
height={height}
language={language}
value={tabs.panes[tabIndex].value}
value={code}
options={options}
onChange={onChangeHandle}
theme="vs-dark"
......@@ -201,28 +191,23 @@ const FlinkSqlEditor = (props:any) => {
}
const mapDispatchToProps = (dispatch:Dispatch)=>({
saveText:(tabs:any,tabIndex:any)=>dispatch({
/*saveText:(tabs:any,tabIndex:any)=>dispatch({
type: "Studio/saveTask",
payload: tabs.panes[tabIndex].task,
}),
saveSql:(val:any)=>dispatch({
}),*/
saveSql:(val: any)=>dispatch({
type: "Studio/saveSql",
payload: val,
}),saveSqlMetaData:(sqlMetaData: any,key: number)=>dispatch({
type: "Studio/saveSqlMetaData",
payload: {
activeKey:key,
sqlMetaData,
isModified: true,
}
}),
saveMetaData:(sqlMetaData:any,tabs:any,tabIndex:any)=>dispatch({
type: "Studio/saveSqlMetaData",
payload: {
activeKey:tabs.panes[tabIndex].key,
sqlMetaData,
isModified: true,
}
})
})
export default connect(({ Studio,Document }: { Studio: StateType,Document: DocumentStateType }) => ({
current: Studio.current,
sql: Studio.sql,
tabs: Studio.tabs,
monaco: Studio.monaco,
export default connect(({ Document }: { Document: DocumentStateType }) => ({
fillDocuments: Document.fillDocuments,
}),mapDispatchToProps)(FlinkSqlEditor);
export type SqlMetaData = {
statement: string,
metaData: MetaData[],
statement?: string,
metaData?: MetaData[],
};
export type MetaData = {
table: string,
......
......@@ -35,11 +35,11 @@ const menu = (
const StudioMenu = (props: any) => {
const {tabs, current, currentPath, form,width,height, refs, dispatch, currentSession} = props;
const {isFullScreen, tabs, current, currentPath, form,width,height, refs, dispatch, currentSession} = props;
const [modalVisible, handleModalVisible] = useState<boolean>(false);
const [exportModalVisible, handleExportModalVisible] = useState<boolean>(false);
const [graphModalVisible, handleGraphModalVisible] = useState<boolean>(false);
const [editModalVisible, handleEditModalVisible] = useState<boolean>(false);
// const [editModalVisible, handleEditModalVisible] = useState<boolean>(false);
const [graphData, setGraphData] = useState();
const onKeyDown = useCallback((e) => {
......@@ -52,7 +52,8 @@ const StudioMenu = (props: any) => {
if(e.keyCode === 113){
e.preventDefault();
if(current) {
handleEditModalVisible(true);
// handleEditModalVisible(true);
props.changeFullScreen(true);
}
}
}, [current]);
......@@ -463,16 +464,18 @@ const StudioMenu = (props: any) => {
>
<SqlExport id={current.task.id} />
</ModalForm>:undefined}
{current?<Modal
{current && isFullScreen?<Modal
width={width}
bodyStyle={{padding: 0}}
style={{top:0,padding:0,margin:0,maxWidth:'100vw'}}
destroyOnClose
maskClosable={false}
closable={false}
visible={editModalVisible}
visible={isFullScreen}
footer={null}
onCancel={() => handleEditModalVisible(false)}>
onCancel={() => {
props.changeFullScreen(false);
}}>
<StudioTabs width={width} height={height}/>
</Modal>:undefined}
</Row>
......@@ -487,10 +490,14 @@ const mapDispatchToProps = (dispatch: Dispatch)=>({
}),saveTabs:(tabs: any)=>dispatch({
type: "Studio/saveTabs",
payload: tabs,
}),changeFullScreen:(isFull: boolean)=>dispatch({
type: "Studio/changeFullScreen",
payload: isFull,
}),
});
export default connect(({Studio}: { Studio: StateType }) => ({
isFullScreen: Studio.isFullScreen,
current: Studio.current,
currentPath: Studio.currentPath,
tabs: Studio.tabs,
......
......@@ -6,33 +6,23 @@ import styles from './index.less';
import StudioEdit from '../StudioEdit';
import {DIALECT} from '../conf';
import StudioHome from "@/components/Studio/StudioHome";
import {Dispatch} from "@@/plugin-dva/connect";
const {TabPane} = Tabs;
const EditorTabs = (props: any) => {
const {tabs, dispatch, current, toolHeight, width,height} = props;
const {tabs, current, toolHeight, width,height} = props;
const onChange = (activeKey: any) => {
dispatch &&
dispatch({
type: 'Studio/saveToolHeight',
payload: toolHeight - 0.0001,
});
dispatch({
type: 'Studio/changeActiveKey',
payload: activeKey,
});
props.saveToolHeight(toolHeight);
props.changeActiveKey(activeKey);
};
const onEdit = (targetKey: any, action: any) => {
if (action === 'add') {
add();
} else if (action === 'remove') {
dispatch &&
dispatch({
type: 'Studio/saveToolHeight',
payload: toolHeight - 0.0001,
});
props.saveToolHeight(toolHeight-0.0001);
// if (current.isModified) {
// saveTask(current, dispatch);
// }
......@@ -61,23 +51,11 @@ const EditorTabs = (props: any) => {
newActiveKey = newPanes[0].key;
}
}
dispatch({
type: 'Studio/saveTabs',
payload: {
activeKey: newActiveKey,
panes: newPanes,
},
});
props.saveTabs(newPanes,newActiveKey);
};
const handleClickMenu = (e: any, current) => {
dispatch({
type: 'Studio/closeTabs',
payload: {
deleteType: e.key,
current
},
});
props.closeTabs(current,e.key);
};
const menu = (pane) => (
......@@ -118,10 +96,13 @@ const EditorTabs = (props: any) => {
className={styles['edit-tabs']}
style={{height: height?height:toolHeight}}
>
{tabs.panes.map((pane) => (
{tabs.panes.map((pane,i) => (
<TabPane tab={Tab(pane)} key={pane.key} closable={pane.closable}>
<StudioEdit
tabsKey={pane.key}
sql={pane.value}
monaco={pane.monaco}
// sqlMetaData={pane.sqlMetaData}
height={height?height:(toolHeight - 32)}
width={width}
language={current.task.dialect === DIALECT.JAVA ? 'java' : 'sql'}
......@@ -133,9 +114,31 @@ const EditorTabs = (props: any) => {
);
};
const mapDispatchToProps = (dispatch: Dispatch)=>({
closeTabs:(current: any,key: string)=>dispatch({
type: 'Studio/closeTabs',
payload: {
deleteType: key,
current
},
}),saveTabs:(newPanes: any,newActiveKey: number)=>dispatch({
type: 'Studio/saveTabs',
payload: {
activeKey: newActiveKey,
panes: newPanes,
},
}),saveToolHeight:(toolHeight: number)=>dispatch({
type: 'Studio/saveToolHeight',
payload: toolHeight - 0.0001,
}),changeActiveKey:(activeKey: number)=>dispatch({
type: 'Studio/changeActiveKey',
payload: activeKey,
}),
})
export default connect(({Studio}: { Studio: StateType }) => ({
current: Studio.current,
sql: Studio.sql,
tabs: Studio.tabs,
toolHeight: Studio.toolHeight,
}))(EditorTabs);
}),mapDispatchToProps)(EditorTabs);
......@@ -20,7 +20,7 @@ import DraggleVerticalLayout from "@/components/DraggleLayout/DraggleVerticalLay
const Studio = (props: any) => {
const {rightClickMenu, toolHeight, toolLeftWidth,toolRightWidth,dispatch} = props;
const {isFullScreen,rightClickMenu, toolHeight, toolLeftWidth,toolRightWidth,dispatch} = props;
const [form] = Form.useForm();
const VIEW = {
leftToolWidth: 300,
......@@ -134,7 +134,7 @@ const Studio = (props: any) => {
}}/>
</Col>
<Col>
<StudioTabs width={size.width - toolRightWidth - toolLeftWidth}/>
{!isFullScreen?<StudioTabs width={size.width - toolRightWidth - toolLeftWidth}/>:undefined}
</Col>
</DraggleLayout>
<Col id='StudioRightTool' className={styles["vertical-tabs"]}>
......@@ -155,6 +155,7 @@ const Studio = (props: any) => {
};
export default connect(({Studio}: { Studio: StateType }) => ({
isFullScreen: Studio.isFullScreen,
rightClickMenu: Studio.rightClickMenu,
toolHeight: Studio.toolHeight,
toolLeftWidth: Studio.toolLeftWidth,
......
......@@ -136,6 +136,7 @@ export type SessionType = {
}
export type StateType = {
isFullScreen: boolean;
toolHeight?: number;
toolRightWidth?: number;
toolLeftWidth?: number;
......@@ -147,7 +148,7 @@ export type StateType = {
currentSession?: SessionType;
current?: TabsItemType;
sql?: string;
monaco?: any;
// monaco?: any;
currentPath?: string[];
tabs?: TabsType;
session?: SessionType[];
......@@ -165,12 +166,13 @@ export type ModelType = {
saveTask: Effect;
};
reducers: {
changeFullScreen: Reducer<StateType>;
saveToolHeight: Reducer<StateType>;
saveToolRightWidth: Reducer<StateType>;
saveToolLeftWidth: Reducer<StateType>;
saveSql: Reducer<StateType>;
saveCurrentPath: Reducer<StateType>;
saveMonaco: Reducer<StateType>;
// saveMonaco: Reducer<StateType>;
saveSqlMetaData: Reducer<StateType>;
saveTabs: Reducer<StateType>;
closeTabs: Reducer<StateType>;
......@@ -193,6 +195,7 @@ export type ModelType = {
const Model: ModelType = {
namespace: 'Studio',
state: {
isFullScreen: false,
toolHeight: 400,
toolRightWidth: 300,
toolLeftWidth: 300,
......@@ -206,7 +209,7 @@ const Model: ModelType = {
},
current: undefined,
sql: '',
monaco: {},
// monaco: {},
currentPath: ['引导页'],
tabs: {
activeKey: 0,
......@@ -233,6 +236,12 @@ const Model: ModelType = {
},
reducers: {
changeFullScreen(state, {payload}) {
return {
...state,
isFullScreen: payload,
};
},
saveToolHeight(state, {payload}) {
return {
...state,
......@@ -250,19 +259,19 @@ const Model: ModelType = {
};
},
saveSql(state, {payload}) {
const {tabs} = state;
const newTabs = state.tabs;
const newCurrent = state.current;
newCurrent.value = payload;
for (let i = 0; i < tabs.panes.length; i++) {
if (tabs.panes[i].key == tabs.activeKey) {
tabs.panes[i].value = payload;
tabs.panes[i].task && (tabs.panes[i].task.statement = payload);
for (let i = 0; i < newTabs.panes.length; i++) {
if (newTabs.panes[i].key == newTabs.activeKey) {
newTabs.panes[i].value = payload;
newTabs.panes[i].task && (newTabs.panes[i].task.statement = payload);
}
}
return {
...state,
current: newCurrent,
tabs,
current: {...newCurrent},
tabs:{...newTabs},
};
},
saveCurrentPath(state, {payload}) {
......@@ -271,32 +280,30 @@ const Model: ModelType = {
currentPath: payload,
};
},
saveMonaco(state, {payload}) {
/*saveMonaco(state, {payload}) {
return {
...state,
monaco: {
...payload
},
monaco:payload,
};
},
},*/
saveSqlMetaData(state, {payload}) {
const newCurrent = state.current;
const newTabs = state.tabs;
if(newCurrent.key == payload.activeKey){
newCurrent.sqlMetaData = payload.sqlMetaData;
newCurrent.sqlMetaData = {...payload.sqlMetaData};
newCurrent.isModified = payload.isModified;
}
for (let i = 0; i < newTabs.panes.length; i++) {
if (newTabs.panes[i].key == payload.activeKey) {
newTabs.panes[i].sqlMetaData = payload.sqlMetaData;
newTabs.panes[i].sqlMetaData = {...payload.sqlMetaData};
newTabs.panes[i].isModified = payload.isModified;
break;
}
}
return {
...state,
current: newCurrent,
tabs: newTabs,
current: {...newCurrent},
tabs: {...newTabs},
};
},
saveTabs(state, {payload}) {
......@@ -320,7 +327,7 @@ const Model: ModelType = {
...newCurrent,
isModified:false,
},
tabs: payload,
tabs: {...payload},
currentPath: newCurrent.path,
};
},
......@@ -341,8 +348,8 @@ const Model: ModelType = {
}
return {
...state,
current: newCurrent,
tabs: newTabs,
current: {...newCurrent},
tabs: {...newTabs},
};
},
closeTabs(state, {payload}) {
......@@ -362,23 +369,23 @@ const Model: ModelType = {
return {
...state,
current: newCurrent,
tabs: newTabs
current: {...newCurrent},
tabs: {...newTabs}
};
},
changeActiveKey(state, {payload}) {
const newTabs = state.tabs;
let newCurrent = state.current;
newTabs.activeKey = payload;
const newTabs = state?.tabs;
let newCurrent = state?.current;
for (let i = 0; i < newTabs.panes.length; i++) {
if (newTabs.panes[i].key == payload) {
newTabs.activeKey = payload;
newCurrent = newTabs.panes[i];
}
}
return {
...state,
current: newCurrent,
tabs: newTabs,
current: {...newCurrent},
tabs: {...newTabs},
currentPath: newCurrent.path,
};
},
......@@ -396,14 +403,14 @@ const Model: ModelType = {
}
return {
...state,
current: newCurrent,
tabs: newTabs,
current: {...newCurrent},
tabs: {...newTabs},
};
},
saveSession(state, {payload}) {
return {
...state,
session: payload,
session: [...payload],
};
},
showRightClickMenu(state, {payload}) {
......@@ -431,44 +438,46 @@ const Model: ModelType = {
},
saveResult(state, {payload}) {
const newTabs = state?.tabs;
let newCurrent = state?.current;
const newCurrent = state?.current;
for (let i = 0; i < newTabs.panes.length; i++) {
if (newTabs.panes[i].key == newTabs.activeKey) {
newTabs.panes[i].console.result.result = payload;
newCurrent = newTabs.panes[i];
if (newTabs.panes[i].key == payload.key) {
newTabs.panes[i].console.result.result = payload.datas;
if(newCurrent.key == payload.key){
newCurrent.console = newTabs.panes[i].console;
}
break;
}
}
return {
...state,
current: newCurrent,
tabs: newTabs,
current: {...newCurrent},
tabs: {...newTabs},
};
},
saveCluster(state, {payload}) {
return {
...state,
cluster: payload,
cluster: [...payload],
};
},saveSessionCluster(state, {payload}) {
return {
...state,
sessionCluster: payload,
sessionCluster: [...payload],
};
},saveClusterConfiguration(state, {payload}) {
return {
...state,
clusterConfiguration: payload,
clusterConfiguration: [...payload],
};
},saveDataBase(state, {payload}) {
return {
...state,
database: payload,
database: [...payload],
};
},saveEnv(state, {payload}) {
return {
...state,
env: payload,
env: [...payload],
};
},saveChart(state, {payload}) {
let newTabs = state?.tabs;
......@@ -482,8 +491,8 @@ const Model: ModelType = {
}
return {
...state,
current: newCurrent,
tabs: newTabs,
current: {...newCurrent},
tabs: {...newTabs},
};
},
},
......
......@@ -589,6 +589,27 @@ export default (): React.ReactNode => {
<li>
<Link>新增 F2 全屏开发</Link>
</li>
<li>
<Link>升级 SpringBoot 至 2.6.3</Link>
</li>
<li>
<Link>优化 日志依赖</Link>
</li>
<li>
<Link>修复 前端 state 赋值 bug</Link>
</li>
<li>
<Link>修复 异常预览内容溢出 bug</Link>
</li>
<li>
<Link>修复 数据预览特殊条件下无法获取数据的 bug</Link>
</li>
<li>
<Link>优化 SQL编辑器性能</Link>
</li>
<li>
<Link>修复 全屏开发退出后 sql 不同步</Link>
</li>
</ul>
</Paragraph>
</Timeline.Item>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment