diff --git a/app/i18n/en.json b/app/i18n/en.json index c30f6a6..b64549f 100644 --- a/app/i18n/en.json +++ b/app/i18n/en.json @@ -212,7 +212,9 @@ "Block number symbol": "Block #", "Operations Count": "Operations Count", "Asset not found": "Asset {{asset}} not found", + "Account not found": "Account {{account}} not found", "Please check the asset name": "Please check the asset name or use the id", + "Please check the account name": "Please check the account name or use the id", "Committee members": "Committee members", "Current active committee members": "Current active committee members", diff --git a/app/sections/operations/operations-table.directive.js b/app/sections/operations/operations-table.directive.js new file mode 100644 index 0000000..ba0f2d6 --- /dev/null +++ b/app/sections/operations/operations-table.directive.js @@ -0,0 +1,184 @@ +/* +Use this directive like this: + + +* * * * * * * * * * * * * * * +* * * * * Options * * * * * * +* * * * * * * * * * * * * * * + +_ _ _ _ _ _ _ _ +| Grouping | +- - - - - - - - +This is a way to display all operations of specific blockchain object (account/creditoffer/pool) + +(Examples) + - use if you want to display operations of specific account + - use if you want to display operations of specific credit offer + - use if you want to display operations of specific pool + +_ _ _ _ _ _ _ _ _ _ _ _ _ +| Enable User Filters | +- - - - - - - - - - - - - +This show/hide filtering fields for the user to filter all operations by account/asset/operation + +// By default all true + +(Examples) + - use if you want to display operations of specific account + - use if you want to display operations of specific credit offer + - use if you want to display operations of specific pool + + _ _ _ _ _ _ _ _ +| Date From | + - - - - - - - - +Use this field to optimize ES search by date limits + +// By default: now-1M + +(Example) + + + _ _ _ _ _ _ _ _ _ +| Show filters | + - - - - - - - - - +Use this field show / hide user filters + +// By default: undefined + +(Example) + + +*/ +(function () { + + angular.module('app.operations') + .directive('operationsTable', [operationsTable]); + + function operationsTable() { + return { + restrict: 'E', + replace: true, + scope: { + showFilters: '=', + groupByAccountId: '=', + groupByCreditOfferId: '=', + groupByPoolId: '=', + dateFrom: "@", + filterByAccountIdEnabled: '=', + filterByAssetIdEnabled: '=', + filterByOperationTypeEnabled: '=', + }, + templateUrl: 'html/operations-table.html', + controller: ['$scope', '$filter', 'Notify', 'OperationsService', 'utilities', operationsTableController] + }; + + function operationsTableController($scope, $filter, Notify, OperationsService, utilities) { + + // list of values for filter by operation type + +
+ +
+
+ +
+ + + + + + diff --git a/app/sections/operations/operations.service.js b/app/sections/operations/operations.service.js new file mode 100644 index 0000000..b1d67b7 --- /dev/null +++ b/app/sections/operations/operations.service.js @@ -0,0 +1,110 @@ +(function () { + 'use strict'; + + angular.module('app.ui') + .service('OperationsService', ['utilities', 'appConfig', '$filter', '$http', OperationsService]); + + function OperationsService(utilities, appConfig, $filter, $http) { + + function getOperationsHistory({ poolId = undefined, creditOfferId = undefined, limit = 20, offset = 0, date_from = undefined, date_to = undefined, assetId = undefined, operationType = undefined, accountId = undefined }) { + + function filterOperationDuplicates(v, i, a) { + return a.findIndex(t=>(t.operation_id_num === v.operation_id_num))===i + } + + function operationMapperToAppFormat(op) { + let operation = {}; + + operation.block_num = op.block_data.block_num; + operation.operation_id = op.account_history.operation_id; + operation.operation_id_num = op.operation_id_num; + operation.time = op.block_data.block_time; + operation.witness = op.witness; + operation.sequence = op.account_history.sequence; + + let parsed_op = op.operation_history.op_object; + + if (parsed_op === undefined) { + parsed_op = JSON.parse(op.operation_history.op)[1]; + } + + if (parsed_op.amount) { + parsed_op.amount_ = parsed_op.amount; + } + + const _with_result = {...parsed_op, result: op.operation_history.operation_result}; + + if (typeof _with_result.result === "string") { + _with_result.result = JSON.parse(op.operation_history.operation_result); + } + + utilities.opText(appConfig, $http, op.operation_type, _with_result, function(returnData) { + operation.operation_text = returnData; + }); + + const type_res = utilities.operationType(op.operation_type); + operation.type = type_res[0]; + operation.color = type_res[1]; + + return operation; + } + + const MAGIC_NUMBER = 1000000; + + return $http.get(appConfig.urls.elasticsearch_wrapper() + "/history", { + params: { + "limit": limit, + "offset": offset, + "from_date": date_from ? date_from : (offset < MAGIC_NUMBER ? "now-1M" : "2015-10-10"), + "to_date": date_to, + "asset_id": assetId ? assetId : undefined, + "operation_type": Number(operationType) === -1 ? undefined : operationType, + "account_id": accountId ? accountId : undefined, + "creditoffer_id": creditOfferId ? creditOfferId : undefined, + "pool_id": poolId ? poolId : undefined + } + }).then(response => { + if(response && response.data && (response.data.asset_not_found || response.data.account_not_found)) { + return response.data + } + + const operations = response.data.filter(filterOperationDuplicates).map(operationMapperToAppFormat); + + return operations; + }); + } + + const COLUMNS = { + OPERATION_TEXT: { + title: $filter('translate')('Operation'), + index: 'operation_text', + }, + OPERATION_ID: { + title: $filter('translate')('ID'), + index: 'operation_id', + }, + DATETIME: { + title: $filter('translate')('Date and time'), + index: 'time', + hidden: ['xs'] + }, + BLOCK: { + title: $filter('translate')('Block'), + index: 'block_num', + hidden: ['xs', 'sm'] + }, + TYPE: { + title: $filter('translate')('Type'), + index: 'type', + hidden: ['xs', 'sm', 'md'] + } + } + + return { + columns: COLUMNS, + getOperationsHistory + } + } + + +})(); diff --git a/app/styles/custom.css b/app/styles/custom.css index 073c0ca..988b1b5 100644 --- a/app/styles/custom.css +++ b/app/styles/custom.css @@ -353,6 +353,15 @@ ul.scrollable-tabs-shadow-right:after { z-index: 1000; } +.operations-table-filters > div { + margin-right: 12px; +} + +.operations-table-filters { + display: flex; + margin-bottom: 16px; +} + .dashboard-operations-filters > div { margin-right: 12px; } diff --git a/entry.js b/entry.js index 4a4a6e0..34f4654 100644 --- a/entry.js +++ b/entry.js @@ -78,6 +78,8 @@ require("./app/sections/voting/voting.controller.js"); require("./app/sections/witnesses/witnesses.controller.js"); require("./app/sections/workers/workers.controller.js"); require("./app/sections/operations/operations.controller.js"); +require("./app/sections/operations/operations-table.directive.js"); +require("./app/sections/operations/operations.service.js"); require("./app/sections/blocks/blocks.controller.js"); require("./app/sections/pools/pools.controller.js"); require("./app/sections/credit_offers/credit_offers.controller.js"); diff --git a/html.js b/html.js index d83d4cb..f9d9c9a 100644 --- a/html.js +++ b/html.js @@ -18,6 +18,7 @@ const HTML = [ "sections/objects/object.html", "sections/operations/operation.html", "sections/operations/operations.html", + "sections/operations/operations-table.html", "sections/proxies/proxies.html", "sections/search/search.html", "sections/txs/tx.html",