1- import React , { memo , useState , useEffect , useRef , useContext , useMemo } from 'react' ;
1+ import React , { useState , useEffect , useRef , useMemo } from 'react' ;
22import classnames from 'classnames' ;
33import i18n from '@/i18n' ;
44import { connect } from 'umi' ;
5- import { Input , Cascader } from 'antd' ;
5+ import { Input , Cascader , Button , Space , Dropdown , MenuProps } from 'antd' ;
66import Iconfont from '@/components/Iconfont' ;
77import LoadingContent from '@/components/Loading/LoadingContent' ;
88import { IConnectionModelType } from '@/models/connection' ;
99import { IWorkspaceModelType } from '@/models/workspace' ;
1010import Tree from '../Tree' ;
1111import { treeConfig } from '../Tree/treeConfig' ;
12- import { ITreeNode } from '@/typings' ;
13- import { TreeNodeType , CreateTabIntroType , WorkspaceTabType } from '@/constants' ;
14- import styles from './index.less' ;
12+ import { TreeNodeType , WorkspaceTabType } from '@/constants' ;
1513import { approximateTreeNode } from '@/utils' ;
1614import { useUpdateEffect } from '@/hooks/useUpdateEffect' ;
1715import { v4 as uuidV4 } from 'uuid' ;
16+ import { ITreeNode } from '@/typings' ;
17+ import styles from './index.less' ;
18+ import { DownOutlined } from '@ant-design/icons' ;
19+ import { ExportTypeEnum } from '@/typings/resultTable' ;
1820
1921interface IOption {
2022 value : TreeNodeType ;
@@ -24,13 +26,13 @@ interface IOption {
2426const optionsList : IOption [ ] = [
2527 {
2628 value : TreeNodeType . TABLES ,
27- label : i18n ( 'common.text.table' )
29+ label : i18n ( 'common.text.table' ) ,
2830 } ,
2931 { value : TreeNodeType . VIEWS , label : i18n ( 'workspace.tree.view' ) } ,
3032 { value : TreeNodeType . FUNCTIONS , label : i18n ( 'workspace.tree.function' ) } ,
3133 { value : TreeNodeType . PROCEDURES , label : i18n ( 'workspace.tree.procedure' ) } ,
3234 { value : TreeNodeType . TRIGGERS , label : i18n ( 'workspace.tree.trigger' ) } ,
33- ]
35+ ] ;
3436
3537const dvaModel = connect (
3638 ( { connection, workspace } : { connection : IConnectionModelType ; workspace : IWorkspaceModelType } ) => ( {
@@ -39,23 +41,72 @@ const dvaModel = connect(
3941 } ) ,
4042) ;
4143
42- interface Option {
43- value : string ;
44- label : string ;
45- children ?: Option [ ] ;
46- }
47-
48- const TableList = dvaModel ( function ( props : any ) {
44+ const TableList = dvaModel ( ( props : any ) => {
4945 const { workspaceModel, dispatch } = props ;
5046 const { curWorkspaceParams } = workspaceModel ;
5147 const [ searching , setSearching ] = useState < boolean > ( false ) ;
5248 const inputRef = useRef < any > ( ) ;
5349 const [ searchedTableList , setSearchedTableList ] = useState < ITreeNode [ ] | undefined > ( ) ;
54- const isReady = curWorkspaceParams ?. dataSourceId && ( ( curWorkspaceParams ?. databaseName || curWorkspaceParams ?. schemaName ) || ( curWorkspaceParams ?. databaseName === null && curWorkspaceParams ?. schemaName == null ) )
50+ const isReady =
51+ curWorkspaceParams ?. dataSourceId &&
52+ ( curWorkspaceParams ?. databaseName ||
53+ curWorkspaceParams ?. schemaName ||
54+ ( curWorkspaceParams ?. databaseName === null && curWorkspaceParams ?. schemaName == null ) ) ;
5555 const [ curType , setCurType ] = useState < IOption > ( optionsList [ 0 ] ) ;
5656 const [ curList , setCurList ] = useState < ITreeNode [ ] > ( [ ] ) ;
5757 const [ tableLoading , setTableLoading ] = useState < boolean > ( false ) ;
5858
59+ // 导出表结构
60+ const handleExport = ( exportType : ExportTypeEnum ) => {
61+ props . onExport && props . onExport ( exportType ) ;
62+ } ;
63+
64+ const items : MenuProps [ 'items' ] = useMemo (
65+ ( ) => [
66+ {
67+ label : i18n ( 'common.button.exportWord' ) ,
68+ key : '1' ,
69+ // icon: <UserOutlined />,
70+ onClick : ( ) => {
71+ handleExport ( ExportTypeEnum . WORD ) ;
72+ } ,
73+ } ,
74+ {
75+ label : i18n ( 'common.button.exportExcel' ) ,
76+ key : '2' ,
77+ // icon: <UserOutlined />,
78+ onClick : ( ) => {
79+ handleExport ( ExportTypeEnum . EXCEL ) ;
80+ } ,
81+ } ,
82+ {
83+ label : i18n ( 'common.button.exportHtml' ) ,
84+ key : '3' ,
85+ // icon: <UserOutlined />,
86+ onClick : ( ) => {
87+ handleExport ( ExportTypeEnum . HTML ) ;
88+ } ,
89+ } ,
90+ {
91+ label : i18n ( 'common.button.exportMarkdown' ) ,
92+ key : '4' ,
93+ // icon: <UserOutlined />,
94+ onClick : ( ) => {
95+ handleExport ( ExportTypeEnum . MARKDOWN ) ;
96+ } ,
97+ } ,
98+ {
99+ label : i18n ( 'common.button.exportPdf' ) ,
100+ key : '5' ,
101+ // icon: <UserOutlined />,
102+ onClick : ( ) => {
103+ handleExport ( ExportTypeEnum . PDF ) ;
104+ } ,
105+ } ,
106+ ] ,
107+ [ curWorkspaceParams ] ,
108+ ) ;
109+
59110 useUpdateEffect ( ( ) => {
60111 setCurList ( [ ] ) ;
61112 getList ( ) ;
@@ -74,26 +125,28 @@ const TableList = dvaModel(function (props: any) {
74125 cursor : 'start' ,
75126 } ) ;
76127 }
77- } , [ searching ] )
128+ } , [ searching ] ) ;
78129
79130 function getList ( refresh : boolean = false ) {
80131 setTableLoading ( true ) ;
81132 treeConfig [ curType . value ] . getChildren ! ( {
82133 refresh,
83134 ...curWorkspaceParams ,
84135 extraParams : curWorkspaceParams ,
85- } ) . then ( res => {
86- setCurList ( res ) ;
87- setTableLoading ( false ) ;
88- if ( curType . value === TreeNodeType . TABLES ) {
89- dispatch ( {
90- type : 'workspace/setCurTableList' ,
91- payload : res ,
92- } )
93- }
94- } ) . catch ( ( ) => {
95- setTableLoading ( false ) ;
96136 } )
137+ . then ( ( res ) => {
138+ setCurList ( res ) ;
139+ setTableLoading ( false ) ;
140+ if ( curType . value === TreeNodeType . TABLES ) {
141+ dispatch ( {
142+ type : 'workspace/setCurTableList' ,
143+ payload : res ,
144+ } ) ;
145+ }
146+ } )
147+ . catch ( ( ) => {
148+ setTableLoading ( false ) ;
149+ } ) ;
97150 }
98151
99152 function openSearch ( ) {
@@ -108,7 +161,7 @@ const TableList = dvaModel(function (props: any) {
108161 }
109162
110163 function onChange ( value : string ) {
111- setSearchedTableList ( approximateTreeNode ( curList , value ) )
164+ setSearchedTableList ( approximateTreeNode ( curList , value ) ) ;
112165 }
113166
114167 function refreshTableList ( ) {
@@ -122,79 +175,83 @@ const TableList = dvaModel(function (props: any) {
122175 setCurType ( selectedOptions [ 0 ] ) ;
123176 }
124177
125- const cascaderOnChange : any = ( _ : string [ ] , selectedOptions : Option [ ] ) => {
178+ const cascaderOnChange : any = ( ) => {
126179 dispatch ( {
127180 type : 'workspace/setCreateConsoleIntro' ,
128181 payload : {
129182 id : uuidV4 ( ) ,
130183 type : WorkspaceTabType . EditTable ,
131184 title : 'create-table' ,
132- uniqueData : {
133-
134- }
185+ uniqueData : { } ,
135186 } ,
136- } )
187+ } ) ;
137188 } ;
138189
139190 const options = [
140191 {
141192 value : 'createTable' ,
142193 label : i18n ( 'editTable.button.createTable' ) ,
143- }
144- ]
194+ } ,
195+ ] ;
145196
146197 return (
147198 < div className = { styles . tableModule } >
148199 < div className = { styles . leftModuleTitle } >
149- {
150- searching ?
151- < div className = { styles . leftModuleTitleSearch } >
152- < Input
153- ref = { inputRef }
154- size = "small"
155- placeholder = { i18n ( 'common.text.search' ) }
156- prefix = { < Iconfont code = "" /> }
157- onBlur = { onBlur }
158- onChange = { ( e ) => onChange ( e . target . value ) }
159- allowClear
160- />
161- </ div >
162- :
163- < div className = { styles . leftModuleTitleText } >
164- < Cascader
165- defaultValue = { [ curType . value ] }
166- popupClassName = { styles . cascaderPopup }
167- options = { optionsList }
168- onChange = { cascaderChange as any }
169- >
170- < div className = { styles . modelName } >
171- { curType . label }
172- < Iconfont code = '' />
173- </ div >
174- </ Cascader >
175- < div className = { styles . iconBox } >
176- < div className = { classnames ( styles . refreshIcon , styles . itemIcon ) } onClick = { ( ) => refreshTableList ( ) } >
177- < Iconfont code = "" />
178- </ div >
179- < div className = { classnames ( styles . searchIcon , styles . itemIcon ) } onClick = { ( ) => openSearch ( ) } >
180- < Iconfont code = "" />
181- </ div >
182- {
183- curType . value === TreeNodeType . TABLES &&
184- < Cascader options = { options } onChange = { cascaderOnChange } >
185- < div className = { classnames ( styles . moreIcon , styles . itemIcon ) } >
186- < Iconfont code = "" />
187- </ div >
188- </ Cascader >
189- }
200+ { searching ? (
201+ < div className = { styles . leftModuleTitleSearch } >
202+ < Input
203+ ref = { inputRef }
204+ size = "small"
205+ placeholder = { i18n ( 'common.text.search' ) }
206+ prefix = { < Iconfont code = "" /> }
207+ onBlur = { onBlur }
208+ onChange = { ( e ) => onChange ( e . target . value ) }
209+ allowClear
210+ />
211+ </ div >
212+ ) : (
213+ < div className = { styles . leftModuleTitleText } >
214+ < Cascader
215+ defaultValue = { [ curType . value ] }
216+ popupClassName = { styles . cascaderPopup }
217+ options = { optionsList }
218+ onChange = { cascaderChange as any }
219+ >
220+ < div className = { styles . modelName } >
221+ { curType . label }
222+ < Iconfont code = "" />
190223 </ div >
224+ </ Cascader >
225+ < div className = { styles . iconBox } >
226+ < Dropdown menu = { { items } } >
227+ < Button >
228+ < Space >
229+ { i18n ( 'common.text.export' ) }
230+ < DownOutlined />
231+ </ Space >
232+ </ Button >
233+ </ Dropdown >
234+ < div className = { classnames ( styles . refreshIcon , styles . itemIcon ) } onClick = { ( ) => refreshTableList ( ) } >
235+ < Iconfont code = "" />
236+ </ div >
237+ < div className = { classnames ( styles . searchIcon , styles . itemIcon ) } onClick = { ( ) => openSearch ( ) } >
238+ < Iconfont code = "" />
239+ </ div >
240+ { curType . value === TreeNodeType . TABLES && (
241+ < Cascader options = { options } onChange = { cascaderOnChange } >
242+ < div className = { classnames ( styles . moreIcon , styles . itemIcon ) } >
243+ < Iconfont code = "" />
244+ </ div >
245+ </ Cascader >
246+ ) }
191247 </ div >
192- }
248+ </ div >
249+ ) }
193250 </ div >
194251 < LoadingContent className = { styles . treeBox } isLoading = { tableLoading } >
195- < Tree className = { styles . tree } initialData = { searchedTableList || curList } > </ Tree >
252+ < Tree className = { styles . tree } initialData = { searchedTableList || curList } / >
196253 </ LoadingContent >
197- </ div >
254+ </ div >
198255 ) ;
199256} ) ;
200257
0 commit comments