redash/client/app/components/dashboards/widget.html
Sami Jaktholm 9c8d06578a feat: add support for expanding dashboard visualizations (#2824)
* feat: add support for expanding dashboard visualizations

These changes implement support for expanding a dashboard visualization
into a larger modal dialog.

This is useful if you have a dashboard with lots of small widgets and
want to inspect one of the widgets more closely. In the past, this
would've required you to navigate to the query page to see a larger
version of the visualization. With these changes, visualizations can
be expanded right from the dashboard.

The implementation is simple as it just renders the visualization into
a modal dialog. Other parts of the widget (e.g. parameters) are not
included in this dialog.

* chore(widget-dialog): use query-link widget to render title

This reduces code duplication a bit. The link is made read-only
as navigation doesn't close the modal dialog.

* fix: make ui-select dropdown z-index > modal dialog z-index in dashboard page

Otherwise the dropdown renders behind the modal dialog if filter value
is changed from the modal view of a widget.
2018-10-14 10:42:31 +03:00

98 lines
5.7 KiB
HTML

<div class="widget-wrapper">
<div class="tile body-container widget-visualization" ng-if="$ctrl.type=='visualization'" ng-class="$ctrl.type"
ng-switch="$ctrl.widget.getQueryResult().getStatus()">
<div class="body-row">
<div class="t-header widget clearfix">
<div class="dropdown pull-right widget-menu-remove" ng-if="!$ctrl.public && $ctrl.dashboard.canEdit()">
<div class="actions">
<a ng-click="$ctrl.deleteWidget()" title="Remove From Dashboard"><i class="zmdi zmdi-close"></i></a>
</div>
</div>
<div class="dropdown pull-right widget-menu-regular" ng-if="!$ctrl.public" uib-dropdown>
<div class="actions">
<a data-toggle="dropdown" uib-dropdown-toggle><i class="zmdi zmdi-more-vert"></i></a>
</div>
<ul class="dropdown-menu pull-right" uib-dropdown-menu style="z-index:1000000">
<li ng-class="{'disabled': $ctrl.widget.getQueryResult().isEmpty()}"><a ng-href="{{$ctrl.widget.getQueryResult().getLink($ctrl.widget.getQuery().id, 'csv')}}" download="{{$ctrl.widget.getQueryResult().getName($ctrl.widget.getQuery().name, 'csv')}}" target="_self">Download as CSV File</a></li>
<li ng-class="{'disabled': $ctrl.widget.getQueryResult().isEmpty()}"><a ng-href="{{$ctrl.widget.getQueryResult().getLink($ctrl.widget.getQuery().id, 'xlsx')}}" download="{{$ctrl.widget.getQueryResult().getName($ctrl.widget.getQuery().name, 'xlsx')}}" target="_self">Download as Excel File</a></li>
<li><a ng-href="{{$ctrl.widget.getQuery().getUrl(true, $ctrl.widget.visualization.id)}}" ng-show="$ctrl.canViewQuery">View Query</a></li>
<li><a ng-show="$ctrl.dashboard.canEdit()" ng-click="$ctrl.deleteWidget()">Remove From Dashboard</a></li>
</ul>
</div>
<div class="th-title">
<p>
<query-link query="$ctrl.widget.getQuery()" visualization="$ctrl.widget.visualization"
readonly="!$ctrl.canViewQuery"></query-link>
</p>
<div class="text-muted query--description" ng-bind-html="$ctrl.widget.getQuery().description | markdown"></div>
</div>
</div>
<div class="m-b-10" ng-if="$ctrl.localParametersDefs().length > 0">
<parameters parameters="$ctrl.localParametersDefs()"></parameters>
</div>
</div>
<div ng-switch-when="failed" class="body-row-auto scrollbox">
<div class="alert alert-danger m-5" ng-show="$ctrl.widget.getQueryResult().getError()">Error running query: <strong>{{$ctrl.widget.getQueryResult().getError()}}</strong></div>
</div>
<div ng-switch-when="done" class="body-row-auto scrollbox">
<visualization-renderer visualization="$ctrl.widget.visualization" query-result="$ctrl.widget.getQueryResult()" class="t-body"></visualization-renderer>
</div>
<div ng-switch-default class="body-row-auto spinner-container">
<div class="spinner">
<i class="zmdi zmdi-refresh zmdi-hc-spin zmdi-hc-5x"></i>
</div>
</div>
<div class="body-row clearfix tile__bottom-control">
<a class="small hidden-print" ng-click="$ctrl.refresh()" ng-if="!$ctrl.public">
<i ng-class='{"zmdi-hc-spin": $ctrl.widget.loading}' class="zmdi zmdi-refresh"></i>
<span am-time-ago="$ctrl.widget.getQueryResult().getUpdatedAt()" ng-if="!$ctrl.widget.loading"></span>
<rd-timer timestamp="$ctrl.widget.refreshStartedAt" ng-if="$ctrl.widget.loading"></rd-timer>
</a>
<span class="small hidden-print" ng-if="$ctrl.public">
<i class="zmdi zmdi-time-restore"></i> <span am-time-ago="$ctrl.widget.getQueryResult().getUpdatedAt()"></span>
</span>
<span class="visible-print">
<i class="zmdi zmdi-time-restore"></i> {{$ctrl.widget.getQueryResult().getUpdatedAt() | dateTime}}
</span>
<button class="btn btn-sm btn-default pull-right hidden-print btn-transparent btn__refresh" ng-click="$ctrl.refresh()" ng-if="!$ctrl.public"><i class="zmdi zmdi-refresh"></i></button>
<button class="btn btn-sm btn-default pull-right hidden-print btn-transparent btn__refresh" ng-click="$ctrl.expandVisualization()"><i class="zmdi zmdi-fullscreen"></i></button>
</div>
</div>
<div class="tile body-container widget-restricted" ng-if="$ctrl.type=='restricted'" ng-class="$ctrl.type">
<div class="t-body body-row-auto scrollbox">
<div class="text-center">
<h1><span class="zmdi zmdi-lock"></span></h1>
<p class="text-muted">
This widget requires access to a data source you don't have access to.
</p>
</div>
</div>
</div>
<div class="tile body-container widget-text" ng-hide="$ctrl.widget.width === 0" ng-if="$ctrl.type=='textbox'" ng-class="$ctrl.type">
<div class="body-row clearfix t-body">
<div class="dropdown pull-right widget-menu-remove" ng-if="!$ctrl.public && $ctrl.dashboard.canEdit()">
<div class="dropdown-header">
<a class="actions" ng-click="$ctrl.deleteWidget()" title="Remove From Dashboard"><i class="zmdi zmdi-close"></i></a>
</div>
</div>
<div class="dropdown pull-right widget-menu-regular" ng-if="!$ctrl.public && $ctrl.dashboard.canEdit()" uib-dropdown>
<div class="dropdown-header">
<a data-toggle="dropdown" uib-dropdown-toggle class="actions"><i class="zmdi zmdi-more"></i></a>
</div>
<ul class="dropdown-menu pull-right" uib-dropdown-menu style="z-index:1000000">
<li><a ng-show="$ctrl.dashboard.canEdit()" ng-click="$ctrl.editTextBox()">Edit</a></li>
<li><a ng-show="$ctrl.dashboard.canEdit()" ng-click="$ctrl.deleteWidget()">Remove From Dashboard</a></li>
</ul>
</div>
</div>
<div class="body-row-auto scrollbox tiled t-body p-15" ng-bind-html="$ctrl.widget.text | markdown"></div>
</div>
</div>