@@ -149,14 +149,6 @@ const StyledButtonWrapper = styled.span`
149149 ` }
150150` ;
151151
152- const sqlTooltipOptions = {
153- placement : 'topRight' ,
154- title : t (
155- 'If changes are made to your SQL query, ' +
156- 'columns in your dataset will be synced when saving the dataset.' ,
157- ) ,
158- } ;
159-
160152const checkboxGenerator = ( d , onChange ) => (
161153 < CheckboxControl value = { d } onChange = { onChange } />
162154) ;
@@ -723,6 +715,22 @@ class DatasourceEditor extends PureComponent {
723715 } ) ;
724716 }
725717
718+ getSQLLabUrl ( ) {
719+ const queryParams = new URLSearchParams ( {
720+ dbid : this . state . datasource . database . id ,
721+ sql : this . state . datasource . sql ,
722+ name : this . state . datasource . datasource_name ,
723+ schema : this . state . datasource . schema ,
724+ autorun : true ,
725+ isDataset : true ,
726+ } ) ;
727+ return `/sqllab/?${ queryParams . toString ( ) } ` ;
728+ }
729+
730+ openOnSqlLab ( ) {
731+ window . open ( this . getSQLLabUrl ( ) , '_blank' , 'noopener,noreferrer' ) ;
732+ }
733+
726734 tableChangeAndSyncMetadata ( ) {
727735 this . validate ( ( ) => {
728736 this . syncMetadata ( ) ;
@@ -996,8 +1004,81 @@ class DatasourceEditor extends PureComponent {
9961004 ) ;
9971005 }
9981006
1007+ renderSqlEditorOverlay = ( ) => (
1008+ < div
1009+ css = { theme => css `
1010+ position : absolute;
1011+ background : ${ theme . colors . secondary . light5 } ;
1012+ align-items : center;
1013+ display : flex;
1014+ height : 100% ;
1015+ width : 100% ;
1016+ justify-content : center;
1017+ ` }
1018+ >
1019+ < div >
1020+ < Loading position = "inline-centered" />
1021+ < span
1022+ css = { theme => css `
1023+ display : block;
1024+ margin : ${ theme . gridUnit * 4 } px auto;
1025+ width : fit-content;
1026+ color : ${ theme . colors . grayscale . base } ;
1027+ ` }
1028+ >
1029+ { t ( 'We are working on your query' ) }
1030+ </ span >
1031+ </ div >
1032+ </ div >
1033+ ) ;
1034+
1035+ renderOpenInSqlLabLink ( isError = false ) {
1036+ return (
1037+ < a
1038+ href = { this . getSQLLabUrl ( ) }
1039+ target = "_blank"
1040+ rel = "noopener noreferrer"
1041+ css = { theme => css `
1042+ color : ${ isError
1043+ ? theme . colors . error . base
1044+ : theme . colors . grayscale . base } ;
1045+ font-size : ${ theme . typography . sizes . s } px;
1046+ text-decoration : underline;
1047+ ` }
1048+ >
1049+ { t ( 'Open in SQL lab' ) }
1050+ </ a >
1051+ ) ;
1052+ }
1053+
1054+ renderSqlErrorMessage = ( ) => (
1055+ < >
1056+ < span
1057+ css = { theme => css `
1058+ font-size : ${ theme . typography . sizes . s } px;
1059+ ` }
1060+ >
1061+ { this . props . database ?. error && t ( 'Error executing query. ' ) }
1062+ </ span >
1063+ { this . renderOpenInSqlLabLink ( true ) }
1064+ < span
1065+ css = { theme => css `
1066+ font-size : ${ theme . typography . sizes . s } px;
1067+ ` }
1068+ >
1069+ { t ( ' to check for details.' ) }
1070+ </ span >
1071+ </ >
1072+ ) ;
1073+
9991074 renderSourceFieldset ( ) {
10001075 const { datasource } = this . state ;
1076+ const floatingButtonCss = css `
1077+ align-self : flex-end;
1078+ height : 24px ;
1079+ padding-left : 6px ;
1080+ padding-right : 6px ;
1081+ ` ;
10011082 return (
10021083 < div >
10031084 < EditLockContainer >
@@ -1097,18 +1178,33 @@ class DatasourceEditor extends PureComponent {
10971178 description = { t (
10981179 'When specifying SQL, the datasource acts as a view. ' +
10991180 'Superset will use this statement as a subquery while grouping and filtering ' +
1100- 'on the generated parent queries.' ,
1181+ 'on the generated parent queries.' +
1182+ 'If changes are made to your SQL query, ' +
1183+ 'columns in your dataset will be synced when saving the dataset.' ,
11011184 ) }
11021185 control = {
1103- < TextAreaControl
1104- language = "sql"
1105- offerEditInModal = { false }
1106- minLines = { 10 }
1107- maxLines = { Infinity }
1108- readOnly = { ! this . state . isEditMode }
1109- resize = "both"
1110- tooltipOptions = { sqlTooltipOptions }
1111- />
1186+ this . props . database ?. isLoading ? (
1187+ < >
1188+ { this . renderSqlEditorOverlay ( ) }
1189+ < TextAreaControl
1190+ language = "sql"
1191+ offerEditInModal = { false }
1192+ minLines = { 10 }
1193+ maxLines = { Infinity }
1194+ readOnly = { ! this . state . isEditMode }
1195+ resize = "both"
1196+ />
1197+ </ >
1198+ ) : (
1199+ < TextAreaControl
1200+ language = "sql"
1201+ offerEditInModal = { false }
1202+ minLines = { 10 }
1203+ maxLines = { Infinity }
1204+ readOnly = { ! this . state . isEditMode }
1205+ resize = "both"
1206+ />
1207+ )
11121208 }
11131209 additionalControl = {
11141210 < div
@@ -1120,12 +1216,25 @@ class DatasourceEditor extends PureComponent {
11201216 ` }
11211217 >
11221218 < Button
1123- css = { css `
1124- align-self : flex-end;
1125- height : 24px ;
1126- padding-left : 6px ;
1127- padding-right : 6px ;
1128- ` }
1219+ disabled = { this . props . database ?. isLoading }
1220+ tooltip = { t ( 'Open SQL Lab in a new tab' ) }
1221+ css = { floatingButtonCss }
1222+ size = "small"
1223+ >
1224+ < Icons . ExportOutlined
1225+ iconSize = "s"
1226+ css = { theme => ( {
1227+ color : theme . colors . primary . dark1 ,
1228+ } ) }
1229+ onClick = { ( ) => {
1230+ this . openOnSqlLab ( ) ;
1231+ } }
1232+ />
1233+ </ Button >
1234+ < Button
1235+ disabled = { this . props . database ?. isLoading }
1236+ tooltip = { t ( 'Run query' ) }
1237+ css = { floatingButtonCss }
11291238 size = "small"
11301239 buttonStyle = "primary"
11311240 onClick = { ( ) => {
@@ -1142,22 +1251,49 @@ class DatasourceEditor extends PureComponent {
11421251 </ div >
11431252 }
11441253 errorMessage = {
1145- this . props . database ?. error && t ( 'Error executing query.' )
1254+ this . props . database ?. error && this . renderSqlErrorMessage ( )
11461255 }
11471256 />
11481257 { this . props . database ?. queryResult && (
1149- < ResultTable
1150- data = { this . props . database . queryResult . data }
1151- queryId = { this . props . database . queryResult . query . id }
1152- orderedColumnKeys = { this . props . database . queryResult . columns . map (
1153- col => col . column_name ,
1154- ) }
1155- height = { 100 }
1156- expandedColumns = {
1157- this . props . database . queryResult . expandedColumns
1158- }
1159- allowHTML
1160- />
1258+ < >
1259+ < div
1260+ css = { theme => css `
1261+ margin-bottom : ${ theme . gridUnit * 4 } px;
1262+ ` }
1263+ >
1264+ < span
1265+ css = { theme => css `
1266+ color : ${ theme . colors . grayscale . base } ;
1267+ font-size : ${ theme . typography . sizes . s } px;
1268+ ` }
1269+ >
1270+ { t (
1271+ 'In this view you can preview the first 25 rows. ' ,
1272+ ) }
1273+ </ span >
1274+ { this . renderOpenInSqlLabLink ( ) }
1275+ < span
1276+ css = { theme => css `
1277+ color : ${ theme . colors . grayscale . base } ;
1278+ font-size : ${ theme . typography . sizes . s } px;
1279+ ` }
1280+ >
1281+ { t ( ' to see details.' ) }
1282+ </ span >
1283+ </ div >
1284+ < ResultTable
1285+ data = { this . props . database ?. queryResult . data }
1286+ queryId = { this . props . database ?. queryResult . query . id }
1287+ orderedColumnKeys = { this . props . database ?. queryResult . columns . map (
1288+ col => col . column_name ,
1289+ ) }
1290+ height = { 100 }
1291+ expandedColumns = {
1292+ this . props . database ?. queryResult . expandedColumns
1293+ }
1294+ allowHTML
1295+ />
1296+ </ >
11611297 ) }
11621298 </ >
11631299 ) }
@@ -1555,8 +1691,7 @@ const mapDispatchToProps = dispatch => ({
15551691 resetQuery : ( ) => dispatch ( resetDatabaseState ( ) ) ,
15561692} ) ;
15571693const mapStateToProps = state => ( {
1558- test : state . queryApi ,
1559- database : state . database ,
1694+ database : state ?. database ,
15601695} ) ;
15611696export default withToasts (
15621697 connect ( mapStateToProps , mapDispatchToProps ) ( DataSourceComponent ) ,
0 commit comments