The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/src/app/panels/table/module.html

124 lines
8.1 KiB

<div ng-controller='table' ng-init='init()'>
<style>
.table-doc-table {
margin-left: 0px !important;
overflow-y: auto;
overflow-x: scroll;
}
</style>
<div class="row-fluid">
<div bindonce ng-class="{'span3':panel.field_list}" ng-if="panel.field_list">
<div class="sidebar-nav">
<strong>Fields <i class=" icon-chevron-sign-left pointer " ng-click="panel.field_list = !panel.field_list" bs-tooltip="'Hide field list'"></i></strong><p>
<div class="small">
<span class="link small" ng-click="panel.all_fields = true;" ng-if="fields.list.length" ng-class="{strong:panel.all_fields}">
All ({{fields.list.length}})</span> /
<span class="link small" ng-click="panel.all_fields = false;" ng-class="{strong:!panel.all_fields}">
Current ({{current_fields.length || 0}})</span>
</div>
<div><input type="text" class="input-medium" placeholder="Type to filter..." ng-model="fieldFilter"></div>
<ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;" ng-if="panel.all_fields">
<li ng-style="panel.style" ng-repeat="field in fields.list|filter:fieldFilter|orderBy:identity">
<i class="pointer" ng-class="{'icon-check': columns[field],'icon-check-empty': _.isUndefined(columns[field])}" ng-click="toggle_field(field)"></i>
<a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: columns[field]}" bo-text="field"></a>
</li>
</ul>
<ul class="unstyled" style="{{panel.overflow}}:{{panel.height || row.height}};overflow-y:auto;overflow-x:hidden;" ng-if="!panel.all_fields">
<li ng-style="panel.style" ng-repeat="field in current_fields|filter:fieldFilter|orderBy:identity">
<i class="pointer" ng-class="{'icon-check': columns[field],'icon-check-empty': _.isUndefined(columns[field])}" ng-click="toggle_field(field)"></i>
<a class="pointer" data-unique="1" bs-popover="'app/panels/table/micropanel.html'" data-placement="rightTop" ng-click="toggle_micropanel(field,true)" ng-class="{label: columns[field]}" bo-text="field"></a>
</li>
</ul>
</div>
</div>
<div style="{{panel.overflow}}:{{panel.height || row.height}};" ng-class="{'span9':panel.field_list,'span12':!panel.field_list}" class="table-doc-table">
<i class="pull-left icon-chevron-sign-right pointer" ng-click="panel.field_list = !panel.field_list" bs-tooltip="'Show field list'" ng-show="!panel.field_list"></i>
<div class="row-fluid" ng-show="panel.paging">
<div class="span1 offset1" style="text-align:right">
<i ng-click="panel.offset = 0" ng-show="panel.offset > 0" class='icon-circle-arrow-left pointer'></i>
<i ng-click="panel.offset = (panel.offset - panel.size)" ng-show="panel.offset > 0" class='icon-arrow-left pointer'></i>
</div>
<div class="span8" style="text-align:center">
<strong>{{panel.offset}}</strong> to <strong>{{panel.offset + data.slice(panel.offset,panel.offset+panel.size).length}}</strong>
<small> of {{data.length}} available for paging</small>
</div>
<div class="span1" style="text-align:left">
<i ng-click="panel.offset = (panel.offset + panel.size)" ng-show="data.length > panel.offset+panel.size" class='icon-arrow-right pointer'></i>
</div>
</div>
<table class="table-hover table table-condensed" ng-style="panel.style">
<thead ng-show="panel.header">
<th ng-show="panel.fields.length<1">_source (select columns from the list to the left)</th>
<th style="white-space:nowrap" ng-repeat="field in panel.fields">
<i ng-show="!$first" class="pointer link icon-caret-left" ng-click="_.move(panel.fields,$index,$index-1)"></i>
<span class="pointer" ng-click="set_sort(field)" ng-show='panel.sortable'>
{{field}}
<i ng-show='field == panel.sort[0]' class="pointer link" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i>
</span>
<span ng-show='!panel.sortable'>{{field}}</span>
<i ng-show="!$last" class="pointer link icon-caret-right" ng-click="_.move(panel.fields,$index,$index+1)"></i>
</th>
</thead>
<tbody bindonce ng-repeat="event in data| slice:panel.offset:panel.offset+panel.size" ng-class-odd="'odd'">
<tr ng-click="toggle_details(event)" class="pointer">
<td ng-if="panel.fields.length<1" bo-text="event._source|stringify|tableTruncate:panel.trimFactor:1"></td>
<td ng-show="panel.fields.length>0" ng-repeat="field in panel.fields">
<span ng-if="!panel.localTime || panel.timeField != field" bo-html="(event.kibana.highlight[field]||event.kibana._source[field]) |tableHighlight | tableTruncate:panel.trimFactor:panel.fields.length"></span>
<span ng-if="panel.localTime && panel.timeField == field" bo-html="event.sort[1]|tableLocalTime:event"></span>
</td>
</tr>
<tr ng-if="event.kibana.details">
<td colspan={{panel.fields.length}} ng-switch="event.kibana.view">
<span>
View:
<a class="link" ng-class="{'strong':event.kibana.view == 'table'}" ng-click="event.kibana.view = 'table'">Table</a> /
<a class="link" ng-class="{'strong':event.kibana.view == 'json'}" ng-click="event.kibana.view = 'json'">JSON</a> /
<a class="link" ng-class="{'strong':event.kibana.view == 'raw'}" ng-click="event.kibana.view = 'raw'">Raw</a>
<i class="link pull-right icon-chevron-up" ng-click="toggle_details(event)"></i>
</span>
<table class='table table-bordered table-condensed' ng-switch-when="table">
<thead>
<th>Field</th>
<th>Action</th>
<th>Value</th>
</thead>
<tr ng-repeat="(key,value) in event.kibana._source track by $index" ng-class-odd="'odd'">
<td bo-text="key"></td>
<td style="white-space:nowrap">
<i class='icon-search pointer' ng-click="build_search(key,value)" bs-tooltip="'Add filter to match this value'"></i>
<i class='icon-ban-circle pointer' ng-click="build_search(key,value,true)" bs-tooltip="'Add filter to NOT match this value'"></i>
<i class="pointer icon-th" ng-click="toggle_field(key)" bs-tooltip="'Toggle table column'"></i>
</td>
<!-- At some point we need to create a more efficient way of applying the filter pipeline -->
<td style="white-space:pre-wrap" bo-html="value|noXml|urlLink|stringify"></td>
</tr>
</table>
<pre style="white-space:pre-wrap" bo-html="without_kibana(event)|tableJson:2" ng-switch-when="json"></pre>
<pre bo-html="without_kibana(event)|tableJson:1" ng-switch-when="raw"></pre>
</td>
</tr>
</tbody>
</table>
<div class="row-fluid" ng-show="panel.paging">
<div class="span1 offset3" style="text-align:right">
<i ng-click="panel.offset = 0" ng-show="panel.offset > 0" class='icon-circle-arrow-left pointer'></i>
<i ng-click="panel.offset = (panel.offset - panel.size)" ng-show="panel.offset > 0" class='icon-arrow-left pointer'></i>
</div>
<div class="span4" style="text-align:center">
<strong>{{panel.offset}}</strong> to <strong>{{panel.offset + data.slice(panel.offset,panel.offset+panel.size).length}}</strong>
<small> of {{data.length}} available for paging</small>
</div>
<div class="span1" style="text-align:left">
<i ng-click="panel.offset = (panel.offset + panel.size)" ng-show="data.length > panel.offset+panel.size" class='icon-arrow-right pointer'></i>
</div>
</div>
</div>
</div>
</div>