thingsboard-aplcache

Details

diff --git a/ui/src/app/widget/lib/timeseries-table-widget.js b/ui/src/app/widget/lib/timeseries-table-widget.js
index 58a626c..28ac811 100644
--- a/ui/src/app/widget/lib/timeseries-table-widget.js
+++ b/ui/src/app/widget/lib/timeseries-table-widget.js
@@ -47,11 +47,37 @@ function TimeseriesTableWidget() {
 /*@ngInject*/
 function TimeseriesTableWidgetController($element, $scope, $filter) {
     var vm = this;
+    let dateFormatFilter = 'yyyy-MM-dd HH:mm:ss';
 
     vm.sources = [];
     vm.sourceIndex = 0;
     vm.defaultPageSize = 10;
     vm.defaultSortOrder = '-0';
+    vm.query = {
+        "search": null
+    };
+
+    vm.enterFilterMode = enterFilterMode;
+    vm.exitFilterMode = exitFilterMode;
+
+    function enterFilterMode () {
+        vm.query.search = '';
+        vm.ctx.hideTitlePanel = true;
+    }
+
+    function exitFilterMode () {
+        vm.query.search = null;
+        vm.ctx.hideTitlePanel = false;
+    }
+
+    vm.searchAction = {
+        name: 'action.search',
+        show: true,
+        onAction: function() {
+            vm.enterFilterMode();
+        },
+        icon: 'search'
+    };
 
     $scope.$watch('vm.ctx', function() {
        if (vm.ctx) {
@@ -64,6 +90,7 @@ function TimeseriesTableWidgetController($element, $scope, $filter) {
     });
 
     function initialize() {
+        vm.ctx.widgetActions = [ vm.searchAction ];
         vm.showTimestamp = vm.settings.showTimestamp !== false;
         var origColor = vm.widgetConfig.color || 'rgba(0, 0, 0, 0.87)';
         var defaultColor = tinycolor(origColor);
@@ -167,7 +194,7 @@ function TimeseriesTableWidgetController($element, $scope, $filter) {
 
     vm.cellContent = function(source, index, row, value) {
         if (index === 0) {
-            return $filter('date')(value, 'yyyy-MM-dd HH:mm:ss');
+            return $filter('date')(value, dateFormatFilter);
         } else {
             var strContent = '';
             if (angular.isDefined(value)) {
@@ -291,7 +318,30 @@ function TimeseriesTableWidgetController($element, $scope, $filter) {
     }
 
     function reorder(source) {
+        let searchRegExp = new RegExp(vm.query.search);
+
         source.data = $filter('orderBy')(source.data, source.query.order);
+        if (vm.query.search !== null) {
+            source.data = source.data.filter(function(item){
+                for (let i = 0; i < item.length; i++) {
+                    if (vm.showTimestamp) {
+                        if (i === 0) {
+                            if (searchRegExp.test($filter('date')(item[i], dateFormatFilter))) {
+                                return true;
+                            }
+                        } else {
+                            if (searchRegExp.test(item[i])) {
+                                return true;
+                            }
+                        }
+                    } else {
+                        if (searchRegExp.test(item[i])) {
+                            return true;
+                        }
+                    }
+                }
+            });
+        }
     }
 
     function convertData(data) {
diff --git a/ui/src/app/widget/lib/timeseries-table-widget.scss b/ui/src/app/widget/lib/timeseries-table-widget.scss
index 99a0653..da3ee81 100644
--- a/ui/src/app/widget/lib/timeseries-table-widget.scss
+++ b/ui/src/app/widget/lib/timeseries-table-widget.scss
@@ -26,4 +26,8 @@ tb-timeseries-table-widget {
     .md-table-pagination>* {
         height: 46px;
     }
+
+    .tb-data-table md-toolbar {
+        z-index: 10;
+    }
 }
diff --git a/ui/src/app/widget/lib/timeseries-table-widget.tpl.html b/ui/src/app/widget/lib/timeseries-table-widget.tpl.html
index 32fb8e4..2e7286c 100644
--- a/ui/src/app/widget/lib/timeseries-table-widget.tpl.html
+++ b/ui/src/app/widget/lib/timeseries-table-widget.tpl.html
@@ -15,33 +15,71 @@
     limitations under the License.
 
 -->
+<div class="tb-absolute-fill tb-entities-table tb-data-table timeseriesWidget" layout="column">
+    <div flex class="tb-absolute-fill" layout="column">
+        <md-toolbar class="md-table-toolbar md-default" ng-show="vm.query.search !== null">
+            <div class="md-toolbar-tools">
+                <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}">
+                    <md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon>
+                    <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
+                        {{'entity.search' | translate}}
+                    </md-tooltip>
+                </md-button>
+                <md-input-container flex>
+                    <label>&nbsp;</label>
+                    <input ng-model="vm.query.search" placeholder="{{'widget.search-data' | translate}}" md-autofocus/>
+                </md-input-container>
+                <md-button class="md-icon-button" aria-label="Close" ng-click="vm.exitFilterMode()">
+                    <md-icon aria-label="Close" class="material-icons">close</md-icon>
+                    <md-tooltip md-direction="{{vm.ctx.dashboard.isWidgetExpanded ? 'bottom' : 'top'}}">
+                        {{ 'action.close' | translate }}
+                    </md-tooltip>
+                </md-button>
+            </div>
+        </md-toolbar>
 
-<md-tabs md-selected="vm.sourceIndex" ng-class="{'tb-headless': vm.sources.length === 1}"
-         id="tabs" md-border-bottom flex class="tb-absolute-fill">
-    <md-tab ng-repeat="source in vm.sources" label="{{ source.datasource.name }}">
-        <md-table-container>
-            <table md-table>
-                <thead md-head md-order="source.query.order" md-on-reorder="vm.onReorder(source)">
-                <tr md-row>
-                    <th ng-show="vm.showTimestamp" md-column md-order-by="0"><span>Timestamp</span></th>
-                    <th md-column md-order-by="{{ h.index }}" ng-repeat="h in source.ts.header"><span>{{ h.dataKey.label }}</span></th>
-                </tr>
-                </thead>
-                <tbody md-body>
-                <tr md-row ng-repeat="row in source.ts.data track by $index">
-                    <td ng-show="$index > 0 || ($index === 0 && vm.showTimestamp)" md-cell ng-repeat="d in row track by $index" ng-style="vm.cellStyle(source, $index, d)" ng-bind-html="vm.cellContent(source, $index, row, d)">
-                    </td>
-                </tr>
-                </tbody>
-            </table>
-        </md-table-container>
-        <md-table-pagination ng-if="vm.displayPagination"
-                             md-limit="source.query.limit"
-                             md-limit-options="vm.limitOptions"
-                             md-page="source.query.page"
-                             md-total="{{source.ts.count}}"
-                             md-on-paginate="vm.onPaginate(source)"
-                             md-page-select>
-        </md-table-pagination>
-    </md-tab>
-</md-tabs>
\ No newline at end of file
+        <md-tabs flex md-selected="vm.sourceIndex" ng-class="{'tb-headless': vm.sources.length === 1}"
+                 id="tabs" md-border-bottom flex>
+            <md-tab ng-repeat="source in vm.sources" label="{{ source.datasource.name }}">
+                <md-table-container>
+                    <table md-table>
+                        <thead md-head md-order="source.query.order" md-on-reorder="vm.onReorder(source)">
+                            <tr md-row>
+                                <th ng-show="vm.showTimestamp"
+                                    md-column md-order-by="0"
+                                >
+                                    <span>Timestamp</span>
+                                </th>
+                                <th md-column
+                                    md-order-by="{{ h.index }}"
+                                    ng-repeat="h in source.ts.header"
+                                >
+                                    <span>{{ h.dataKey.label }}</span>
+                                </th>
+                            </tr>
+                        </thead>
+
+                        <tbody md-body>
+                            <tr md-row ng-repeat="row in source.ts.data track by $index">
+                                <td ng-show="$index > 0 || ($index === 0 && vm.showTimestamp)"
+                                    md-cell
+                                    ng-repeat="d in row track by $index"
+                                    ng-style="vm.cellStyle(source, $index, d)"
+                                    ng-bind-html="vm.cellContent(source, $index, row, d)"
+                                ></td>
+                            </tr>
+                        </tbody>
+                    </table>
+                </md-table-container>
+                <md-table-pagination ng-if="vm.displayPagination"
+                                     md-limit="source.query.limit"
+                                     md-limit-options="vm.limitOptions"
+                                     md-page="source.query.page"
+                                     md-total="{{source.data.length}}"
+                                     md-on-paginate="vm.onPaginate(source)"
+                                     md-page-select>
+                </md-table-pagination>
+            </md-tab>
+        </md-tabs>
+    </div>
+</div>
\ No newline at end of file