16
16
* limitations under the License.
17
17
*/
18
18
19
- import { AnchorButton , Button , Intent , Menu , MenuItem , Popover , Position } from '@blueprintjs/core' ;
19
+ import {
20
+ AnchorButton ,
21
+ Button ,
22
+ ControlGroup ,
23
+ InputGroup ,
24
+ Intent ,
25
+ Label ,
26
+ Menu ,
27
+ MenuItem ,
28
+ Popover ,
29
+ Position ,
30
+ } from '@blueprintjs/core' ;
20
31
import { IconNames } from '@blueprintjs/icons' ;
21
32
import React , { useState } from 'react' ;
22
33
import ReactTable from 'react-table' ;
@@ -47,7 +58,7 @@ function resultFormatToExtension(resultFormat: ResultFormat): string {
47
58
}
48
59
}
49
60
50
- const RESULT_FORMAT_LABEL : Record < ResultFormat , string > = {
61
+ const RESULT_FORMAT_DESCRIPTION : Record < ResultFormat , string > = {
51
62
object : 'Array of objects' ,
52
63
array : 'Array of arrays' ,
53
64
objectLines : 'JSON Lines' ,
@@ -63,34 +74,34 @@ export const DestinationPagesPane = React.memo(function DestinationPagesPane(
63
74
props : DestinationPagesPaneProps ,
64
75
) {
65
76
const { execution } = props ;
77
+ const [ prefix , setPrefix ] = useState ( execution . id ) ;
66
78
const [ desiredResultFormat , setDesiredResultFormat ] = useState < ResultFormat > ( 'objectLines' ) ;
67
79
const desiredExtension = resultFormatToExtension ( desiredResultFormat ) ;
68
80
69
81
const destination = execution . destination ;
70
82
const pages = execution . destinationPages ;
71
83
if ( ! pages ) return null ;
72
84
const numPages = pages . length ;
73
- const id = Api . encodePath ( execution . id ) ;
74
85
75
86
const numTotalRows = destination ?. numTotalRows ;
76
87
77
88
function getResultUrl ( pageIndex : number ) {
78
89
return UrlBaser . base (
79
- `/druid/v2/sql/statements/${ id } /results?${
90
+ `/druid/v2/sql/statements/${ Api . encodePath ( execution . id ) } /results?${
80
91
pageIndex < 0 ? '' : `page=${ pageIndex } &`
81
92
} resultFormat=${ desiredResultFormat } &filename=${ getPageFilename ( pageIndex ) } `,
82
93
) ;
83
94
}
84
95
85
96
function getFilenamePageInfo ( pageIndex : number ) {
86
- if ( pageIndex < 0 ) return 'all_data ' ;
97
+ if ( pageIndex < 0 ) return '' ;
87
98
const numPagesString = String ( numPages ) ;
88
99
const pageNumberString = String ( pageIndex + 1 ) . padStart ( numPagesString . length , '0' ) ;
89
- return `page_${ pageNumberString } _of_${ numPagesString } ` ;
100
+ return `. page_${ pageNumberString } _of_${ numPagesString } ` ;
90
101
}
91
102
92
103
function getPageFilename ( pageIndex : number ) {
93
- return `${ id } _ ${ getFilenamePageInfo ( pageIndex ) } .${ desiredExtension } ` ;
104
+ return `${ prefix } ${ getFilenamePageInfo ( pageIndex ) } .${ desiredExtension } ` ;
94
105
}
95
106
96
107
return (
@@ -101,29 +112,38 @@ export const DestinationPagesPane = React.memo(function DestinationPagesPane(
101
112
} have been written to ${ pluralIfNeeded ( numPages , 'page' ) } . `}
102
113
</ p >
103
114
< p >
104
- Format when downloading:{ ' ' }
105
- < Popover
106
- minimal
107
- position = { Position . BOTTOM_LEFT }
108
- content = {
109
- < Menu >
110
- { RESULT_FORMATS . map ( ( resultFormat , i ) => (
111
- < MenuItem
112
- key = { i }
113
- icon = { tickIcon ( desiredResultFormat === resultFormat ) }
114
- text = { RESULT_FORMAT_LABEL [ resultFormat ] }
115
- label = { resultFormat }
116
- onClick = { ( ) => setDesiredResultFormat ( resultFormat ) }
117
- />
118
- ) ) }
119
- </ Menu >
120
- }
121
- >
122
- < Button
123
- text = { RESULT_FORMAT_LABEL [ desiredResultFormat ] }
124
- rightIcon = { IconNames . CARET_DOWN }
115
+ < Label > Download as</ Label >
116
+ < ControlGroup className = "download-as-controls" >
117
+ < InputGroup
118
+ value = { prefix }
119
+ onChange = { ( e : any ) => setPrefix ( e . target . value . slice ( 0 , 200 ) ) }
120
+ placeholder = "file_prefix"
121
+ rightElement = { < Button disabled text = { `.${ desiredExtension } ` } /> }
122
+ fill
125
123
/>
126
- </ Popover > { ' ' }
124
+ < Popover
125
+ minimal
126
+ position = { Position . BOTTOM_LEFT }
127
+ content = {
128
+ < Menu >
129
+ { RESULT_FORMATS . map ( ( resultFormat , i ) => (
130
+ < MenuItem
131
+ key = { i }
132
+ icon = { tickIcon ( desiredResultFormat === resultFormat ) }
133
+ text = { RESULT_FORMAT_DESCRIPTION [ resultFormat ] }
134
+ label = { resultFormat }
135
+ onClick = { ( ) => setDesiredResultFormat ( resultFormat ) }
136
+ />
137
+ ) ) }
138
+ </ Menu >
139
+ }
140
+ >
141
+ < Button
142
+ text = { RESULT_FORMAT_DESCRIPTION [ desiredResultFormat ] }
143
+ rightIcon = { IconNames . CARET_DOWN }
144
+ />
145
+ </ Popover >
146
+ </ ControlGroup >
127
147
< AnchorButton
128
148
intent = { Intent . PRIMARY }
129
149
icon = { IconNames . DOWNLOAD }
0 commit comments