2021-02-24 19:49:26 +01:00
import { findRawTemplate } from "discourse-common/lib/raw-templates" ;
2020-09-04 13:23:11 +02:00
import I18n from "I18n" ;
2018-10-10 17:26:23 +05:30
import { ajax } from "discourse/lib/ajax" ;
2020-07-06 15:25:19 -04:00
import getURL from "discourse-common/lib/get-url" ;
2018-10-10 17:26:23 +05:30
import Badge from "discourse/models/badge" ;
2020-02-19 11:57:59 -05:00
import { default as computed } from "discourse-common/utils/decorators" ;
2015-06-30 15:12:12 -07:00
2015-07-09 12:02:47 -07:00
function randomIdShort () {
2019-07-16 12:46:32 +02:00
return "xxxxxxxx" . replace ( /[xy]/g , () => {
2015-09-14 15:34:57 -07:00
/*eslint-disable*/
2018-10-10 17:26:23 +05:30
return (( Math . random () * 16 ) | 0 ). toString ( 16 );
2015-09-14 15:34:57 -07:00
/*eslint-enable*/
2015-07-09 12:02:47 -07:00
});
}
2015-06-30 15:12:12 -07:00
2015-08-25 21:36:39 -07:00
function transformedRelTable ( table , modelClass ) {
2015-08-25 20:48:19 -07:00
const result = {};
2020-09-04 13:23:11 +02:00
table . forEach (( item ) => {
2015-08-25 21:36:39 -07:00
if ( modelClass ) {
result [ item . id ] = modelClass . create ( item );
} else {
result [ item . id ] = item ;
}
2015-08-25 20:48:19 -07:00
});
return result ;
}
2015-06-30 15:12:12 -07:00
const QueryResultComponent = Ember . Component . extend ({
2018-10-10 17:26:23 +05:30
layoutName : "explorer-query-result" ,
2015-06-30 15:12:12 -07:00
2019-01-22 17:19:01 +05:30
rows : Ember . computed . alias ( "content.rows" ),
columns : Ember . computed . alias ( "content.columns" ),
params : Ember . computed . alias ( "content.params" ),
explainText : Ember . computed . alias ( "content.explain" ),
hasExplain : Ember . computed . notEmpty ( "content.explain" ),
2021-02-18 15:06:22 +04:00
chartDatasetName : Ember . computed . reads ( "columnDispNames.1" ),
chartValues : Ember . computed . mapBy ( "content.rows" , "1" ),
showChart : false ,
2018-09-16 21:58:16 +05:30
2018-10-10 17:26:23 +05:30
@ computed ( "content.result_count" )
2019-07-16 12:46:32 +02:00
resultCount ( count ) {
2019-01-23 16:09:20 +05:30
if ( count === this . get ( "content.default_limit" )) {
2018-10-10 17:26:23 +05:30
return I18n . t ( "explorer.max_result_count" , { count });
2018-09-16 21:58:16 +05:30
} else {
2018-10-10 17:26:23 +05:30
return I18n . t ( "explorer.result_count" , { count });
2018-09-16 21:58:16 +05:30
}
},
2019-07-16 12:46:32 +02:00
colCount : Ember . computed . reads ( "content.columns.length" ),
2015-06-30 15:12:12 -07:00
2019-07-16 12:46:32 +02:00
@ computed ( "content.duration" )
duration ( contentDuration ) {
2018-10-10 17:26:23 +05:30
return I18n . t ( "explorer.run_time" , {
2020-09-04 13:23:11 +02:00
value : I18n . toNumber ( contentDuration , { precision : 1 }),
2018-10-10 17:26:23 +05:30
});
2019-07-16 12:46:32 +02:00
},
2015-06-30 15:12:12 -07:00
2019-07-16 12:46:32 +02:00
@ computed ( "params.[]" )
parameterAry ( params ) {
2015-06-30 15:12:12 -07:00
let arr = [];
2021-01-27 10:38:56 +01:00
for ( let key in params ) {
2015-06-30 15:12:12 -07:00
if ( params . hasOwnProperty ( key )) {
2019-07-16 12:46:32 +02:00
arr . push ({ key , value : params [ key ] });
2015-06-30 15:12:12 -07:00
}
}
return arr ;
2019-07-16 12:46:32 +02:00
},
2015-06-30 15:12:12 -07:00
2019-07-16 12:46:32 +02:00
@ computed ( "content" , "columns.[]" )
columnDispNames ( content , columns ) {
if ( ! columns ) {
2015-06-30 21:21:14 -07:00
return [];
2015-06-30 15:12:12 -07:00
}
2020-09-04 13:23:11 +02:00
return columns . map (( colName ) => {
2015-08-25 20:48:19 -07:00
if ( colName . endsWith ( "_id" )) {
return colName . slice ( 0 , - 3 );
2015-06-30 15:12:12 -07:00
}
2018-10-10 17:26:23 +05:30
const dIdx = colName . indexOf ( "$" );
2015-08-25 20:48:19 -07:00
if ( dIdx >= 0 ) {
return colName . substring ( dIdx + 1 );
}
return colName ;
2015-06-30 15:12:12 -07:00
});
2019-07-16 12:46:32 +02:00
},
2015-06-30 15:12:12 -07:00
2019-07-16 12:46:32 +02:00
@ computed
fallbackTemplate () {
2021-02-24 19:49:26 +01:00
return findRawTemplate ( "javascripts/explorer/text" );
2019-07-16 12:46:32 +02:00
},
2015-09-14 16:00:39 -07:00
2019-07-16 12:46:32 +02:00
@ computed ( "content" , "columns.[]" )
columnTemplates ( content , columns ) {
if ( ! columns ) {
2015-08-25 20:48:19 -07:00
return [];
}
2019-07-16 12:46:32 +02:00
return columns . map (( colName , idx ) => {
2015-08-25 20:48:19 -07:00
let viewName = "text" ;
2019-07-16 12:46:32 +02:00
if ( this . get ( "content.colrender" )[ idx ]) {
viewName = this . get ( "content.colrender" )[ idx ];
2015-08-25 20:48:19 -07:00
}
2016-12-27 11:47:50 -05:00
2021-02-24 19:49:26 +01:00
const template = findRawTemplate ( `javascripts/explorer/ ${ viewName } ` );
2016-12-27 11:47:50 -05:00
2018-10-10 17:26:23 +05:30
return { name : viewName , template };
2015-08-25 20:48:19 -07:00
});
2019-07-16 12:46:32 +02:00
},
2015-08-25 20:48:19 -07:00
2019-07-16 12:46:32 +02:00
@ computed ( "content.relations.user" )
transformedUserTable ( contentRelationsUser ) {
return transformedRelTable ( contentRelationsUser );
},
@ computed ( "content.relations.badge" )
transformedBadgeTable ( contentRelationsBadge ) {
return transformedRelTable ( contentRelationsBadge , Badge );
},
@ computed ( "content.relations.post" )
transformedPostTable ( contentRelationsPost ) {
return transformedRelTable ( contentRelationsPost );
},
@ computed ( "content.relations.topic" )
transformedTopicTable ( contentRelationsTopic ) {
return transformedRelTable ( contentRelationsTopic );
},
2015-08-25 20:48:19 -07:00
2019-07-16 12:46:32 +02:00
@ computed ( "site.groups" )
transformedGroupTable ( groups ) {
return transformedRelTable ( groups );
},
2015-09-21 14:43:23 -07:00
2021-02-18 15:06:22 +04:00
@ computed (
"rows.[]" ,
"content.colrender.[]" ,
"content.result_count" ,
"colCount"
)
canShowChart ( rows , colRender , resultCount , colCount ) {
const hasTwoColumns = colCount === 2 ;
const secondColumnContainsNumber =
resultCount > 0 && typeof rows [ 0 ][ 1 ] === "number" ;
const secondColumnContainsId = colRender [ 1 ];
return (
hasTwoColumns && secondColumnContainsNumber && ! secondColumnContainsId
);
},
@ computed ( "content.rows.[]" , "content.colrender.[]" )
chartLabels ( rows , colRender ) {
const labelSelectors = {
user : ( user ) => user . username ,
badge : ( badge ) => badge . name ,
topic : ( topic ) => topic . title ,
group : ( group ) => group . name ,
category : ( category ) => category . name ,
};
const relationName = colRender [ 0 ];
if ( relationName ) {
const lookupFunc = this [ `lookup ${ relationName . capitalize () } ` ];
const labelSelector = labelSelectors [ relationName ];
if ( lookupFunc && labelSelector ) {
return rows . map (( r ) => {
const relation = lookupFunc . call ( this , r [ 0 ]);
const label = labelSelector ( relation );
return this . _cutChartLabel ( label );
});
}
}
return rows . map (( r ) => this . _cutChartLabel ( r [ 0 ]));
},
2015-08-25 21:36:39 -07:00
lookupUser ( id ) {
2019-07-16 12:46:32 +02:00
return this . transformedUserTable [ id ];
2015-08-25 20:48:19 -07:00
},
2015-08-25 21:36:39 -07:00
lookupBadge ( id ) {
2019-07-16 12:46:32 +02:00
return this . transformedBadgeTable [ id ];
2015-08-25 21:36:39 -07:00
},
lookupPost ( id ) {
2019-07-16 12:46:32 +02:00
return this . transformedPostTable [ id ];
2015-08-25 21:36:39 -07:00
},
lookupTopic ( id ) {
2019-07-16 12:46:32 +02:00
return this . transformedTopicTable [ id ];
2015-08-25 21:36:39 -07:00
},
2015-09-21 14:43:23 -07:00
lookupGroup ( id ) {
2019-07-16 12:46:32 +02:00
return this . transformedGroupTable [ id ];
2015-09-21 14:43:23 -07:00
},
2015-08-25 21:36:39 -07:00
lookupCategory ( id ) {
2018-10-10 17:26:23 +05:30
return this . site . get ( "categoriesById" )[ id ];
2015-08-25 21:36:39 -07:00
},
2015-08-25 20:48:19 -07:00
2019-09-11 09:09:41 -05:00
download_url () {
return this . group
? `/g/ ${ this . group . name } /reports/`
: "/admin/plugins/explorer/queries/" ;
},
2015-08-03 15:07:29 -07:00
downloadResult ( format ) {
// Create a frame to submit the form in (?)
// to avoid leaving an about:blank behind
let windowName = randomIdShort ();
2018-10-10 17:26:23 +05:30
const newWindowContents =
"<style>body{font-size:36px;display:flex;justify-content:center;align-items:center;}</style><body>Click anywhere to close this window once the download finishes.<script>window.onclick=function(){window.close()};</script>" ;
2015-08-03 15:07:29 -07:00
2018-10-10 17:26:23 +05:30
window . open ( "data:text/html;base64," + btoa ( newWindowContents ), windowName );
2015-08-03 15:07:29 -07:00
let form = document . createElement ( "form" );
2018-10-10 17:26:23 +05:30
form . setAttribute ( "id" , "query-download-result" );
form . setAttribute ( "method" , "post" );
form . setAttribute (
"action" ,
2020-07-06 15:25:19 -04:00
getURL (
2019-09-11 09:09:41 -05:00
this . download_url () +
2018-10-10 17:26:23 +05:30
this . get ( "query.id" ) +
"/run." +
format +
"?download=1"
)
);
form . setAttribute ( "target" , windowName );
form . setAttribute ( "style" , "display:none;" );
2015-08-03 15:07:29 -07:00
2015-09-14 15:34:57 -07:00
function addInput ( name , value ) {
2015-08-03 15:07:29 -07:00
let field ;
2018-10-10 17:26:23 +05:30
field = document . createElement ( "input" );
field . setAttribute ( "name" , name );
field . setAttribute ( "value" , value );
2015-08-03 15:07:29 -07:00
form . appendChild ( field );
}
2019-07-16 12:46:32 +02:00
addInput ( "params" , JSON . stringify ( this . params ));
addInput ( "explain" , this . hasExplain );
2018-10-10 17:26:23 +05:30
addInput ( "limit" , "1000000" );
2015-08-03 15:07:29 -07:00
2020-09-04 13:23:11 +02:00
ajax ( "/session/csrf.json" ). then (( csrf ) => {
2018-10-10 17:26:23 +05:30
addInput ( "authenticity_token" , csrf . csrf );
2015-08-03 15:07:29 -07:00
document . body . appendChild ( form );
form . submit ();
2019-07-16 12:46:32 +02:00
Ember . run . schedule ( "afterRender" , () => document . body . removeChild ( form ));
2015-08-03 15:07:29 -07:00
});
},
2021-02-18 15:06:22 +04:00
_cutChartLabel ( label ) {
const labelString = label . toString ();
if ( labelString . length > 25 ) {
return ` ${ labelString . substring ( 0 , 25 ) } ...` ;
} else {
return labelString ;
}
},
2015-07-09 12:02:47 -07:00
actions : {
2015-08-03 15:07:29 -07:00
downloadResultJson () {
2018-10-10 17:26:23 +05:30
this . downloadResult ( "json" );
2015-08-03 15:07:29 -07:00
},
downloadResultCsv () {
2018-10-10 17:26:23 +05:30
this . downloadResult ( "csv" );
2020-09-04 13:23:11 +02:00
},
2021-02-18 15:06:22 +04:00
showChart () {
this . set ( "showChart" , true );
},
showTable () {
this . set ( "showChart" , false );
},
2020-09-04 13:23:11 +02:00
},
2015-06-30 15:12:12 -07:00
});
export default QueryResultComponent ;