diff --git a/src/management/api/logs/_logs.scss b/src/management/api/logs/_logs.scss index 2b06f587c1..919928ad7b 100644 --- a/src/management/api/logs/_logs.scss +++ b/src/management/api/logs/_logs.scss @@ -1,5 +1,3 @@ - - tr.log-error { background-color: #f9f2f4; color: #c7254e; @@ -27,3 +25,9 @@ tr.log-error { font-size:12px; } } + +.logs-filters-container { + md-input-container.md-block { + margin-top: 0px; + } +} diff --git a/src/management/api/logs/components/logs-filters.component.ts b/src/management/api/logs/components/logs-filters.component.ts new file mode 100644 index 0000000000..8e9e4f5961 --- /dev/null +++ b/src/management/api/logs/components/logs-filters.component.ts @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015 The Gravitee team (http://gravitee.io) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const LogsFiltersComponent: ng.IComponentOptions = { + template: require('./logs-filters.html'), + controller: 'LogsFiltersController', + bindings: { + onFiltersChange: '&', + metadata: '<' + } +}; + +export default LogsFiltersComponent; + diff --git a/src/management/api/logs/components/logs-filters.controller.ts b/src/management/api/logs/components/logs-filters.controller.ts new file mode 100644 index 0000000000..1799fd1d00 --- /dev/null +++ b/src/management/api/logs/components/logs-filters.controller.ts @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2015 The Gravitee team (http://gravitee.io) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import * as _ from 'lodash'; + +class LogsFiltersController { + public filters: any = {}; + public methods = { + 1: 'CONNECT', + 2: 'DELETE', + 3: 'GET', + 4: 'HEAD', + 5: 'OPTIONS', + 6: 'PATCH', + 7: 'POST', + 8: 'PUT', + 9: 'TRACE' + }; + public responseTimes = { + '[0 TO 100]': '0 to 100ms', + '[100 TO 200]': '100 to 200ms', + '[200 TO 300]': '200 to 300ms', + '[300 TO 400]': '300 to 400ms', + '[400 TO 500]': '400 to 500ms', + '[500 TO *]': '> 500ms' + }; + public httpStatus = { + 100: 'CONTINUE 100', + 101: 'SWITCHING PROTOCOLS 101', + 102: 'PROCESSING 102', + 200: 'OK 200', + 201: 'CREATED 201', + 202: 'ACCEPTED 202', + 203: 'NON AUTHORITATIVE INFORMATION 203', + 204: 'NO CONTENT 204', + 205: 'RESET CONTENT 205', + 206: 'PARTIAL CONTENT 206', + 207: 'MULTI STATUS 207', + 300: 'MULTIPLE CHOICES 300', + 301: 'MOVED PERMANENTLY 301', + 302: 'FOUND 302', + 303: 'SEE OTHER 303', + 304: 'NOT MODIFIED 304', + 305: 'USE PROXY 305', + 307: 'TEMPORARY REDIRECT 307', + 400: 'BAD REQUEST 400', + 401: 'UNAUTHORIZED 401', + 402: 'PAYMENT REQUIRED 402', + 403: 'FORBIDDEN 403', + 404: 'NOT FOUND 404', + 405: 'METHOD NOT ALLOWED 405', + 406: 'NOT ACCEPTABLE 406', + 407: 'PROXY AUTHENTICATION REQUIRED 407', + 408: 'REQUEST TIMEOUT 408', + 409: 'CONFLICT 409', + 410: 'GONE 410', + 411: 'LENGTH REQUIRED 411', + 412: 'PRECONDITION FAILED 412', + 413: 'REQUEST ENTITY TOO LARGE 413', + 414: 'REQUEST URI TOO LONG 414', + 415: 'UNSUPPORTED MEDIA TYPE 415', + 416: 'REQUESTED RANGE NOT SATISFIABLE 416', + 417: 'EXPECTATION FAILED 417', + 422: 'UNPROCESSABLE ENTITY 422', + 423: 'LOCKED 423', + 424: 'FAILED DEPENDENCY 424', + 429: 'TOO MANY REQUESTS 429', + 500: 'INTERNAL SERVER ERROR 500', + 501: 'NOT IMPLEMENTED 501', + 502: 'BAD GATEWAY 502', + 503: 'SERVICE UNAVAILABLE 503', + 504: 'GATEWAY TIMEOUT 504', + 505: 'HTTP VERSION NOT SUPPORTED 505', + 507: 'INSUFFICIENT STORAGE 507' + }; + private fields = { + 'responseTime': 'response-time' + }; + private onFiltersChange: any; + private reordererdMedata: any; + private $scope; + + constructor($scope) { + 'ngInject'; + this.$scope = $scope; + } + + $onChanges(changesObj) { + if (changesObj.metadata) { + let metadata = changesObj.metadata.currentValue; + if (metadata) { + this.reordererdMedata = this.swap(metadata); + } + } + }; + + search() { + let query = this.buildQuery(this.filters); + this.onFiltersChange({filters : query}); + } + + clearFilters() { + this.$scope.logsFiltersForm.$setPristine(); + this.filters = {}; + this.search(); + } + + hasFilters() { + return !_.isEmpty(this.filters) && !this.isEmpty(this.filters); + } + + private isEmpty(map) { + for(let key in map) { + let val = map[key]; + return !(val !== undefined && val.length > 0); + } + return true; + } + + private buildQuery(filters): string { + let query = ''; + let keys = Object.keys(filters); + let index = 0; + let that = this; + _.forEach(keys, function (key) { + let val = filters[key]; + if (key === 'application' || key === 'plan') { + val = that.map(val, that.reordererdMedata); + } + if (val !== undefined && val.length > 0) { + let params = (val.constructor === Array && val.length > 1) ? that.convert(val) : val; + query += that.map(key, that.fields) + ':' + params; + if (index + 1 < keys.length) { + query += ' AND '; + } + } + index++; + }); + return query; + } + + private convert(params) { + return '(' + params.join(' OR ') + ')'; + } + + private map(_val, list) { + let val = list[_val]; + return (val) ? val : _val; + } + + private swap(metadata) { + let ret = {}; + for(let key in metadata){ + ret[metadata[key].name] = key; + } + return ret; + } +} + +export default LogsFiltersController; diff --git a/src/management/api/logs/components/logs-filters.html b/src/management/api/logs/components/logs-filters.html new file mode 100644 index 0000000000..1d6104ef6b --- /dev/null +++ b/src/management/api/logs/components/logs-filters.html @@ -0,0 +1,74 @@ + + +
+ + + Filters + + + +
+
+ + + + + + + + {{ value }} + + + + + + + + + + {{ value }} + + + + + + {{ value }} + + + + + + + + + + +
+ + Clear filters + + + Search + +
+
+
+
+
+
diff --git a/src/management/api/logs/logs.controller.ts b/src/management/api/logs/logs.controller.ts index fdc590b89f..05ee3426a9 100644 --- a/src/management/api/logs/logs.controller.ts +++ b/src/management/api/logs/logs.controller.ts @@ -58,7 +58,6 @@ class ApiLogsController { } selectLog(log) { - console.log(log); } refresh() { @@ -70,6 +69,12 @@ class ApiLogsController { getMetadata(id) { return this.logs.metadata[id]; } + + filtersChange(filters) { + this.query.page = 1; + this.query.query = filters; + this.refresh(); + } } export default ApiLogsController; diff --git a/src/management/api/logs/logs.html b/src/management/api/logs/logs.html index cc95a86228..ff08f3ce87 100644 --- a/src/management/api/logs/logs.html +++ b/src/management/api/logs/logs.html @@ -18,11 +18,14 @@ + + + @@ -39,6 +42,7 @@ md-auto-select md-select="log" md-select-id="key" md-on-select="logsCtrl.selectLog" ng-class="{'log-error': log.status >= 400}"> +
Request IdTransaction Id Method Path Status{{log.id}}{{log.transactionId}} {{log.method | uppercase}} diff --git a/src/management/management.module.ts b/src/management/management.module.ts index a159f96be0..118a87afd9 100644 --- a/src/management/management.module.ts +++ b/src/management/management.module.ts @@ -222,6 +222,8 @@ import ApiLogsController from '../management/api/logs/logs.controller'; import LogsTimeframeComponent from '../management/api/logs/components/logs-timeframe.component'; import LogsTimeframeController from '../management/api/logs/components/logs-timeframe.controller'; import LogComponent from '../management/api/logs/log.component'; +import LogsFiltersComponent from '../management/api/logs/components/logs-filters.component'; +import LogsFiltersController from '../management/api/logs/components/logs-filters.controller'; // Others import ImageDirective from '../components/image/image.directive'; @@ -548,6 +550,8 @@ angular.module('gravitee-management', [uiRouter, permission, uiPermission, 'ngMa .component('gvLogsTimeframe', LogsTimeframeComponent) .controller('LogsTimeframeController', LogsTimeframeController) .component('log', LogComponent) + .component('gvLogsFilters', LogsFiltersComponent) + .controller('LogsFiltersController', LogsFiltersController) .component("gvAudit", AuditComponent) .component('gvContextualDoc', ContextualDocComponent)