mirror of
https://github.com/getredash/redash.git
synced 2026-03-23 04:00:09 -04:00
269 lines
14 KiB
HTML
269 lines
14 KiB
HTML
|
|
<div class="container">
|
|
|
|
<p class="alert alert-warning" ng-if="query.is_archived">This query is archived and can't be used in dashboards, and won't appear in search results.</p>
|
|
<alert-unsaved-changes ng-if="canEdit" is-dirty="isDirty"></alert-unsaved-changes>
|
|
|
|
<div class="row">
|
|
<div class="col-lg-12">
|
|
<div class="row">
|
|
<div class="col-lg-10">
|
|
<h2>
|
|
<edit-in-place editable="isQueryOwner" done="saveName" ignore-blanks='true' value="query.name"></edit-in-place>
|
|
</h2>
|
|
<p>
|
|
<em>
|
|
<edit-in-place editable="isQueryOwner"
|
|
done="saveDescription"
|
|
editor="textarea"
|
|
placeholder="No description"
|
|
ignore-blanks='false'
|
|
value="query.description"
|
|
markdown="true">
|
|
</edit-in-place>
|
|
</em>
|
|
</p>
|
|
</div>
|
|
|
|
<div class="col-lg-2">
|
|
<div class="pull-right">
|
|
<query-source-link></query-source-link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="visible-xs">
|
|
<p>
|
|
<span class="text-muted">Last update </span>
|
|
<strong>
|
|
<rd-time-ago value="queryResult.query_result.retrieved_at"></rd-time-ago>
|
|
</strong>
|
|
|
|
<span class="text-muted">Created By </span>
|
|
<strong ng-hide="isQueryOwner">{{query.user.name}}</strong>
|
|
<strong ng-show="isQueryOwner">You</strong>
|
|
|
|
<span class="text-muted">Runtime </span>
|
|
<strong ng-show="!queryExecuting">{{queryResult.getRuntime() | durationHumanize}}</strong>
|
|
<span ng-show="queryExecuting">Running…</span>
|
|
|
|
<span class="text-muted">Rows </span>
|
|
<strong>{{queryResult.getData().length}}</strong>
|
|
</p>
|
|
<p>
|
|
<query-source-link></query-source-link>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<hr>
|
|
|
|
<div class="row" ng-if="sourceMode">
|
|
<div ng-class="editorSize">
|
|
<div>
|
|
<p>
|
|
<button type="button" class="btn btn-primary btn-xs" ng-disabled="queryExecuting" ng-click="executeQuery()" ng-if="canExecuteQuery">
|
|
<span class="glyphicon glyphicon-play"></span> Execute
|
|
</button>
|
|
<query-formatter></query-formatter>
|
|
<span class="pull-right">
|
|
<button class="btn btn-xs btn-default" ng-click="duplicateQuery()">
|
|
<span class="glyphicon glyphicon-share-alt"></span> Fork
|
|
</button>
|
|
|
|
<button class="btn btn-success btn-xs" ng-show="canEdit" ng-click="saveQuery()">
|
|
<span class="glyphicon glyphicon-floppy-disk"> </span> Save<span ng-show="isDirty">*</span>
|
|
</button>
|
|
</span>
|
|
</p>
|
|
|
|
<p>
|
|
<query-editor query="query" schema="schema" syntax="dataSource.syntax" lock="queryFormatting"></query-editor>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-3 schema-container" ng-show="hasSchema">
|
|
<div ng-show="schema.length < 200">
|
|
<input type="text" placeholder="Search schema..." class="form-control" ng-model="schemaFilter">
|
|
</div>
|
|
<div class="schema-browser">
|
|
<div ng-repeat="table in schema | filter:schemaFilter track by table.name">
|
|
<div class="table-name" ng-click="table.collapsed = !table.collapsed">
|
|
<i class="fa fa-table"></i> <strong><span title="{{table.name}}">{{table.name}}</span><span ng-if="table.size !== undefined"> ({{table.size}})</span></strong>
|
|
</div>
|
|
<div collapse="table.collapsed && !schemaFilter">
|
|
<div ng-repeat="column in table.columns track by column" style="padding-left:16px;">{{column}}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
<hr ng-if="sourceMode">
|
|
<div class="row">
|
|
<div class="col-lg-3">
|
|
<p>
|
|
<span class="glyphicon glyphicon-user"></span>
|
|
<span class="text-muted">Created By </span>
|
|
<strong>{{query.user.name}}</strong>
|
|
</p>
|
|
<p ng-if="query.last_modified_by && query.user.id != query.last_modified_by.id">
|
|
<span class="glyphicon glyphicon-user"></span>
|
|
<span class="text-muted">Last Modified By </span>
|
|
<strong>{{query.last_modified_by.name}}</strong>
|
|
</p>
|
|
<p>
|
|
<span class="glyphicon glyphicon-time"></span>
|
|
<span class="text-muted">Last update </span>
|
|
<strong>
|
|
<rd-time-ago value="queryResult.query_result.retrieved_at"></rd-time-ago>
|
|
</strong>
|
|
</p>
|
|
<p>
|
|
<span class="glyphicon glyphicon-play"></span>
|
|
<span class="text-muted">Runtime </span>
|
|
<strong ng-show="!queryExecuting">{{queryResult.getRuntime() | durationHumanize}}</strong>
|
|
<span ng-show="queryExecuting">Running…</span>
|
|
</p>
|
|
<p>
|
|
<span class="glyphicon glyphicon-align-justify"></span>
|
|
<span class="text-muted">Rows </span><strong>{{queryResult.getData().length}}</strong>
|
|
</p>
|
|
<p>
|
|
<span class="glyphicon glyphicon-refresh"></span>
|
|
<span class="text-muted">Refresh Schedule</span>
|
|
<a href="" ng-click="openScheduleForm()">{{query.schedule | scheduleHumanize}}</a>
|
|
</p>
|
|
|
|
<p>
|
|
<i class="fa fa-database"></i>
|
|
<span class="text-muted">Data Source</span>
|
|
<select ng-disabled="!isQueryOwner" ng-model="query.data_source_id" ng-change="updateDataSource()" ng-options="ds.id as ds.name for ds in dataSources"></select>
|
|
</p>
|
|
|
|
<hr>
|
|
|
|
<p>
|
|
<a class="btn btn-primary btn-sm" ng-disabled="queryExecuting || !queryResult.getData()" query-result-link target="_self">
|
|
<span class="glyphicon glyphicon-cloud-download"></span>
|
|
<span>Download Dataset</span>
|
|
</a>
|
|
|
|
<a class="btn btn-warning btn-sm" ng-disabled="queryExecuting" data-toggle="modal" data-target="#archive-confirmation-modal"
|
|
ng-show="!query.is_archived && query.id != undefined && (isQueryOwner || currentUser.hasPermission('admin'))">
|
|
<i class="fa fa-archive" title="Archive Query"></i>
|
|
</a>
|
|
|
|
<button class="btn btn-default btn-sm" ng-show="query.id != undefined" ng-click="showApiKey()">
|
|
<i class="fa fa-key" title="Show API Key"></i>
|
|
</button>
|
|
|
|
<div class="modal fade" id="archive-confirmation-modal" tabindex="-1" role="dialog" aria-labelledby="archiveConfirmationModal" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4 class="modal-title">Query Archive</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
Are you sure you want to archive this query? <br/>
|
|
All dashboard widgets created with its visualizations will be deleted.
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">No</button>
|
|
<button type="button" class="btn btn-primary" ng-click="archiveQuery()">Yes, archive.</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</p>
|
|
</div>
|
|
|
|
<div class="col-lg-9">
|
|
<!-- alerts -->
|
|
<div class="alert alert-info" ng-show="queryResult.getStatus() == 'processing'">
|
|
Executing query… <rd-timer timestamp="queryResult.getUpdatedAt()"></rd-timer>
|
|
<button type="button" class="btn btn-warning btn-xs pull-right" ng-disabled="cancelling" ng-click="cancelExecution()">Cancel</button>
|
|
</div>
|
|
<div class="alert alert-info" ng-show="queryResult.getStatus() == 'waiting'">
|
|
Query in queue… <rd-timer timestamp="queryResult.getUpdatedAt()"></rd-timer>
|
|
<button type="button" class="btn btn-warning btn-xs pull-right" ng-disabled="cancelling" ng-click="cancelExecution()">Cancel</button>
|
|
</div>
|
|
<div class="alert alert-danger" ng-show="queryResult.getError()">Error running query: <strong>{{queryResult.getError()}}</strong></div>
|
|
|
|
<div class="row log-container" ng-show="showLog">
|
|
<span ng-show="showLog">Log Information:</span>
|
|
<table>
|
|
<tbody>
|
|
<tr ng-repeat="l in queryResult.getLog()">
|
|
<td>{{l}}</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<!-- tabs and data -->
|
|
<div ng-show="showDataset">
|
|
<div class="row">
|
|
<div class="col-lg-12">
|
|
<ul class="nav nav-tabs">
|
|
<rd-tab tab-id="table" name="Table"></rd-tab>
|
|
<rd-tab tab-id="pivot" name="Pivot Table"></rd-tab>
|
|
<rd-tab tab-id="{{vis.id}}" name="{{vis.name}}" ng-if="vis.type!='TABLE'" ng-repeat="vis in query.visualizations">
|
|
<span class="remove" ng-click="deleteVisualization($event, vis)" ng-show="canEdit"> ×</span>
|
|
</rd-tab>
|
|
<rd-tab tab-id="add" name="+ New Visualization" removeable="true" ng-show="canEdit"></rd-tab>
|
|
<li ng-if="!sourceMode && canExecuteQuery" class="rd-tab-btn"><button class="btn btn-sm btn-default" ng-click="executeQuery()" ng-disabled="queryExecuting" title="Refresh Dataset"><span class="glyphicon glyphicon-refresh"></span></button></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-lg-12">
|
|
<div ng-show="selectedTab == 'table'" >
|
|
<filters></filters>
|
|
<grid-renderer query-result="queryResult" items-per-page="50"></grid-renderer>
|
|
|
|
<div class="row" ng-if="vis.type=='TABLE'" ng-repeat="vis in query.visualizations">
|
|
<div class="col-lg-8 embed-code">
|
|
<i class="fa fa-code" ng-click="show_code = show_code==true ? false : true;"></i>
|
|
<div ng-show="show_code">
|
|
<span class="text-muted">Embed code for this table: <small>(height should be adjusted)</small></span>
|
|
<code><iframe src="{{ base_url }}/embed/query/{{query.id}}/visualization/{{ vis.id }}?api_key={{query.api_key}}"<br/>
|
|
|
|
width="720" height="1650"></iframe></code>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<pivot-table-renderer ng-show="selectedTab == 'pivot'" query-result="queryResult"></pivot-table-renderer>
|
|
|
|
<div ng-show="selectedTab == vis.id" ng-repeat="vis in query.visualizations">
|
|
<visualization-renderer visualization="vis" query-result="queryResult"></visualization-renderer>
|
|
|
|
<div class="row">
|
|
<div class="col-lg-8 embed-code">
|
|
<i class="fa fa-code" ng-click="show_code = show_code==true ? false : true;"></i>
|
|
<div ng-show="show_code">
|
|
<span class="text-muted">Embed code for this chart: <small>(height should be adjusted)</small></span>
|
|
<code><iframe src="{{ base_url }}/embed/query/{{query.id}}/visualization/{{ vis.id }}?api_key={{query.api_key}}"<br/>
|
|
|
|
width="720" height="391"></iframe></code>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<edit-visulatization-form visualization="vis" query="query" query-result="queryResult" ng-show="canEdit"></edit-visulatization-form>
|
|
</div>
|
|
|
|
<div ng-if="canEdit" ng-show="selectedTab == 'add'">
|
|
<visualization-renderer visualization="newVisualization" query-result="queryResult"></visualization-renderer>
|
|
<edit-visulatization-form visualization="newVisualization" query="query" query-result="queryResult" ng-show="canEdit" open-editor="true" on-new-success="setVisualizationTab"></edit-visulatization-form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|