From a12f93672b8499b79bff669cab30ecc24c3671ba Mon Sep 17 00:00:00 2001 From: ihorml Date: Thu, 8 Dec 2022 16:24:33 +0200 Subject: [PATCH] Add feature dashboard filtering * #23 Add filter by asset and operation type for dashboard operations * #23 Add operation text for Credit Offer Deal Expired * #23 Fix credit offers fetch bug * #23 Add operations-table directive/service * #23 Replace operations on dashboard by operations-table * #23 Move filter style to css * #23 Replace operations view list by operations-table * #23 Replace credit offers operations by operations-table * #23 Replace account operations by operations-table * #23 Replace pool operations by operations-table * #23 Add pagination for operations * #23 Add the load more button to fetch all possible data * #23 Fix dates format * #23 Fix load more data for filtered duplicates * #23 Move filter parameters to groupBy * #23 Remove all no longer used routes that were replaced by new universal history route * fix: group_by -> filter_by * #23 Add filters for responsive-table and use operations-table like an example * #23 Remove table filters for operations-table Co-authored-by: Stefan --- app/branding.js | 5 +- app/core/app.utilities.js | 21 ++ app/core/service.account.js | 41 --- app/core/service.market.js | 82 ------ app/core/service.network.js | 21 +- app/i18n/en.json | 6 +- app/images/filter-on.svg | 3 + app/images/filter.svg | 1 + app/sections/accounts/account.html | 39 +-- app/sections/accounts/accounts.controller.js | 63 ----- app/sections/credit_offers/credit_offer.html | 40 +-- .../credit_offers/credit_offers.controller.js | 50 +--- .../dashboard/dashboard.controller.js | 58 ----- app/sections/dashboard/dashboard.html | 34 +-- .../operations/operations-table.directive.js | 240 ++++++++++++++++++ app/sections/operations/operations-table.html | 80 ++++++ .../operations/operations.controller.js | 54 +--- app/sections/operations/operations.html | 47 +--- app/sections/operations/operations.service.js | 113 +++++++++ app/sections/pools/pool.html | 40 +-- app/sections/pools/pools.controller.js | 42 --- app/styles/custom.css | 30 +++ app/ui/responsive-table.directive.js | 9 + app/ui/responsive-table.html | 54 ++++ entry.js | 2 + html.js | 1 + package.json | 1 + 27 files changed, 633 insertions(+), 544 deletions(-) create mode 100644 app/images/filter-on.svg create mode 100644 app/images/filter.svg create mode 100644 app/sections/operations/operations-table.directive.js create mode 100644 app/sections/operations/operations-table.html create mode 100644 app/sections/operations/operations.service.js diff --git a/app/branding.js b/app/branding.js index 148210b..20de541 100644 --- a/app/branding.js +++ b/app/branding.js @@ -9,7 +9,7 @@ export function getAvailableEndpoints() { translate: 'Mainnet', url: 'https://api.bitshares.ws/openexplorer', chainId: '4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8', - isDefault: true, + isDefault: false, }, { key: "testnet", @@ -21,7 +21,8 @@ export function getAvailableEndpoints() { key: "local", translate: 'Local', url: 'http://localhost:5000/openexplorer', - chainId: '4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8' + chainId: '4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8', + isDefault: true, } ]; } diff --git a/app/core/app.utilities.js b/app/core/app.utilities.js index af5ba1f..921438f 100644 --- a/app/core/app.utilities.js +++ b/app/core/app.utilities.js @@ -128,6 +128,10 @@ object: (objectId) => ({ text: objectId, href: `/#/objects/${objectId}` + }), + offer: (offerId) => ({ + text: offerId, + href: `/#/credit-offers/${offerId}` }) }) @@ -1559,6 +1563,23 @@ }) } + else if (operation_type === 74) { // Expired Credit Deal + console.log('debug expired', operation) + const operation_account = operation.borrower; + const unpaid = operation.unpaid_amount; + getAccount(operation_account).then((account_name) => { + getAsset(unpaid.asset_id, unpaid.amount).then((unpaidAsset) => { + operation_text = $filter('translateWithLinks')('Operation Credit Deal Expired', { + accountLink : getLink().account(account_name), + amount : unpaidAsset.amount, + offerLink : getLink().offer(operation.offer_id), + assetLink : getLink().asset(unpaidAsset.symbol), + }); + callback(operation_text) + }); + }) + } + else { operation_text = $filter('translate')('Operation Beautifier Missing Description', { diff --git a/app/core/service.account.js b/app/core/service.account.js index f6a408a..43db8a3 100644 --- a/app/core/service.account.js +++ b/app/core/service.account.js @@ -287,47 +287,6 @@ callback(results); } }, - getAccountHistory: function(account_id, limit, from, callback) { - return $http.get(appConfig.urls.elasticsearch_wrapper() + "/account_history" - + "?account_id=" + account_id - + "&offset=" + from - + "&limit=" + limit - + (from == 0 ? "&from_date=now-1y" : "&from_date=2015-10-10") - ).then(response => { - let last_ops = []; - - // only add if the op id is not already added (transfer appears in both accounts!) - const unique_data = response.data.filter((v,i,a)=>a.findIndex(t=>(t.operation_id_num === v.operation_id_num))===i); - - angular.forEach(unique_data, function (value) { - let operation = {}; - operation.block_num = value.block_data.block_num; - operation.operation_id = value.account_history.operation_id; - operation.operation_id_num = value.operation_id_num; - operation.time = value.block_data.block_time; - operation.witness = value.witness; - operation.sequence = value.account_history.sequence; - - let parsed_op = value.operation_history.op_object; - if (parsed_op == undefined) - parsed_op = JSON.parse(value.operation_history.op)[1]; - if (parsed_op.amount) - parsed_op.amount_ = parsed_op.amount; - const _with_result = {...parsed_op, result: value.operation_history.operation_result}; - if (typeof _with_result.result === "string") _with_result.result = JSON.parse(value.operation_history.operation_result); - utilities.opText(appConfig, $http, value.operation_type, _with_result, function(returnData) { - operation.operation_text = returnData; - }); - - const type_res = utilities.operationType(value.operation_type); - operation.type = type_res[0]; - operation.color = type_res[1]; - - last_ops.push(operation); - }); - callback(last_ops); - }); - }, exportAccountHistory: function(account_id, premium_code = null, document=null) { let url = appConfig.urls.elasticsearch_wrapper() + "/export/account_history" + "?account_id=" + account_id diff --git a/app/core/service.market.js b/app/core/service.market.js index 7f65cd7..bd8c70e 100644 --- a/app/core/service.market.js +++ b/app/core/service.market.js @@ -169,47 +169,6 @@ callback(response.data); }); }, - getLiquidityPoolHistory: function(pool_id, limit, from, callback) { - return $http.get(appConfig.urls.elasticsearch_wrapper() + "/pool_operation_history" - + "?pool_id=" + pool_id - + "&offset=" + from - + "&limit=" + limit - + (from == 0 ? "&from_date=now-1y" : "&from_date=2015-10-10") - ).then(response => { - let last_ops = []; - - // only add if the op id is not already added (transfer appears in both accounts!) - const unique_data = response.data.filter((v,i,a)=>a.findIndex(t=>(t.operation_id_num === v.operation_id_num))===i); - - angular.forEach(unique_data, function (value) { - let operation = {}; - operation.block_num = value.block_data.block_num; - operation.operation_id = value.account_history.operation_id; - operation.operation_id_num = value.operation_id_num; - operation.time = value.block_data.block_time; - operation.witness = value.witness; - operation.sequence = value.account_history.sequence; - - let parsed_op = value.operation_history.op_object; - if (parsed_op == undefined) - parsed_op = JSON.parse(value.operation_history.op)[1]; - if (parsed_op.amount) - parsed_op.amount_ = parsed_op.amount; - const _with_result = {...parsed_op, result: value.operation_history.operation_result}; - if (typeof _with_result.result === "string") _with_result.result = JSON.parse(value.operation_history.operation_result); - utilities.opText(appConfig, $http, value.operation_type, _with_result, function(returnData) { - operation.operation_text = returnData; - }); - - const type_res = utilities.operationType(value.operation_type); - operation.type = type_res[0]; - operation.color = type_res[1]; - - last_ops.push(operation); - }); - callback(last_ops); - }); - }, getCreditOffers: function () { return $http.get(appConfig.urls.python_backend() + "/creditoffers").then((response) => { const data = response && response.data; @@ -223,47 +182,6 @@ }) }) }, - getCreditOfferOperationsHistory: function (credit_offer_id, limit, offset, from) { - let last_ops = []; - - return $http.get(appConfig.urls.python_backend() + "/creditoffer_operation_history", { params: { - creditoffer_id: credit_offer_id, - offset: offset, - limit: limit, - from: (from == 0 ? "&from_date=now-1y" : "&from_date=2015-10-10") - }}).then((response) => { - const unique_data = response.data.filter((v,i,a)=>a.findIndex(t=>(t.operation_id_num === v.operation_id_num))===i); - - angular.forEach(unique_data, function (value) { - let operation = {}; - operation.block_num = value.block_data.block_num; - operation.operation_id = value.account_history.operation_id; - operation.operation_id_num = value.operation_id_num; - operation.time = value.block_data.block_time; - operation.witness = value.witness; - operation.sequence = value.account_history.sequence; - - let parsed_op = value.operation_history.op_object; - if (parsed_op == undefined) - parsed_op = JSON.parse(value.operation_history.op)[1]; - if (parsed_op.amount) - parsed_op.amount_ = parsed_op.amount; - const _with_result = {...parsed_op, result: value.operation_history.operation_result}; - if (typeof _with_result.result === "string") _with_result.result = JSON.parse(value.operation_history.operation_result); - utilities.opText(appConfig, $http, value.operation_type, _with_result, function(returnData) { - operation.operation_text = returnData; - }); - - const type_res = utilities.operationType(value.operation_type); - operation.type = type_res[0]; - operation.color = type_res[1]; - - last_ops.push(operation); - }); - - return last_ops - }) - } }; } diff --git a/app/core/service.network.js b/app/core/service.network.js index 852beb4..e228354 100644 --- a/app/core/service.network.js +++ b/app/core/service.network.js @@ -63,13 +63,20 @@ }); }, - getLastOperations: function(limit, from, date_to = (new Date().toISOString()), callback) { - return $http.get(appConfig.urls.elasticsearch_wrapper() + "/account_history" - + "?limit=" + limit - + "&offset=" + from - + (from < 1000000 ? "&from_date=now-1M" : "&from_date=2015-10-10") - + "&to_date=" + date_to - ).then(response => { + getLastOperations: function({ limit = 10, from = 0, assetId = undefined, operationType = undefined, date_to = (new Date().toISOString()) }, callback) { + return $http.get(appConfig.urls.elasticsearch_wrapper() + "/account_history", { + params: { + "limit": limit, + "offset": from, + "from_date": (from < 1000000 ? "now-1M" : "2015-10-10"), + "asset_id": assetId, + "operation_type": operationType, + "to_date": date_to, + } + }).then(response => { + if(response && response.data && response.data.asset_not_found) { + return callback(response.data) + } let last_ops = []; // only add if the op id is not already added (transfer appears in both accounts!) diff --git a/app/i18n/en.json b/app/i18n/en.json index 1874fb7..b64549f 100644 --- a/app/i18n/en.json +++ b/app/i18n/en.json @@ -168,7 +168,7 @@ "Operation Credit Offer Update": "{{accountLink}} update a credit offer #{{offerId}}", "Operation Credit Offer Accept": "{{accountLink}} borrows {{amount}} {{assetLink}} from credit offer #{{offerId}}", "Operation Credit Deal Repay": "{{accountLink}} repays {{amount}} {{assetLink}} to credit offer with fee {{feeAmount}} {{feeAssetLink}}", - "Operation Credit Deal Expired": "{{accountLink}} create a credit offer of {{amount}} {{assetLink}} with fee rate {{fee}}%", + "Operation Credit Deal Expired": "{{accountLink}} credit deal for offer {{offerLink}} has expired. Unpaid amount: {{amount}} {{assetLink}}", "Operation Ticket Create Description": "{{accountLink}} locked away {{amount}} {{assetLink}} in a voting ticket", "Operation Ticket Update Description": "{{accountLink}} changed the locked away amount to {{amount}} {{assetLink}} of ticket {{ticket}}", @@ -211,6 +211,10 @@ "Daily DEX Volume Chart Series Title": "{{symbol}} Volume", "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/images/filter-on.svg b/app/images/filter-on.svg new file mode 100644 index 0000000..b3a29a4 --- /dev/null +++ b/app/images/filter-on.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/images/filter.svg b/app/images/filter.svg new file mode 100644 index 0000000..6cb63fd --- /dev/null +++ b/app/images/filter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/sections/accounts/account.html b/app/sections/accounts/account.html index 847a165..e2b0d61 100644 --- a/app/sections/accounts/account.html +++ b/app/sections/accounts/account.html @@ -510,6 +510,7 @@

+

@@ -526,34 +527,14 @@

-
- - - -
-
-
-
-
-
    -
    -
    -
    -
    + + + diff --git a/app/sections/accounts/accounts.controller.js b/app/sections/accounts/accounts.controller.js index f86dd53..a2c3ba1 100644 --- a/app/sections/accounts/accounts.controller.js +++ b/app/sections/accounts/accounts.controller.js @@ -77,69 +77,6 @@ import {sha256} from "js-sha256"; $scope.account = new_account; } - $scope.operationsColumns = [ - { - title: $filter('translate')('Operation'), - index: 'operation_text', - }, - { - title: $filter('translate')('ID'), - index: 'operation_id', - }, - { - title: $filter('translate')('Date and time'), - index: 'time', - hidden: ['xs'] - }, - { - title: $filter('translate')('Block'), - index: 'block_num', - hidden: ['xs', 'sm'] - }, - { - title: $filter('translate')('Type'), - index: 'type', - hidden: ['xs', 'sm', 'md'] - } - ]; - $scope.select = function(page_operations) { - const page = page_operations - 1; - const limit = 20; - const from = page * limit; - - $scope.operationsLoading = true; - $scope.operationsLoadingError = false; - accountService.getAccountHistory(fullAccount.account.id, limit, from, function (returnData) { - $scope.operationsLoading = false; - $scope.operations = returnData; - $scope.currentPage = page_operations; - if (page_operations == 1) { - let new_account = { - total_ops: 0 - }; - if (returnData.length > 0) { - new_account.total_ops = returnData[0].sequence; - } - if ($scope.account) { - $scope.account = Object.assign(new_account, $scope.account); - } else { - $scope.account = new_account; - } - } - }).catch(err => { - $scope.operationsLoadingError = true; - let new_account = { - total_ops: -1, - }; - if ($scope.account) { - $scope.account = Object.assign(new_account, $scope.account); - } else { - $scope.account = new_account; - } - throw err; - }); - } - $scope.select(1); // initial sort of fullAccount.balances by balance fullAccount.balances = $filter("orderBy")(fullAccount.balances, 'float_balance', true); diff --git a/app/sections/credit_offers/credit_offer.html b/app/sections/credit_offers/credit_offer.html index 0f4421a..2ce881f 100644 --- a/app/sections/credit_offers/credit_offer.html +++ b/app/sections/credit_offers/credit_offer.html @@ -30,34 +30,18 @@
    -

    -
    - - -
    -
    -
    -
    -
    -
      -
      -
      -
      +
      +
      + +
      + +
      diff --git a/app/sections/credit_offers/credit_offers.controller.js b/app/sections/credit_offers/credit_offers.controller.js index 6eebbd5..c23dcd5 100644 --- a/app/sections/credit_offers/credit_offers.controller.js +++ b/app/sections/credit_offers/credit_offers.controller.js @@ -2,8 +2,7 @@ 'use strict'; angular.module('app.credit_offers') - .controller('creditOffersCtrl', ['$scope', '$route', '$routeParams', '$location', '$filter', 'utilities', 'marketService', - 'chartService', 'appConfig', creditOffersCtrl]) + .controller('creditOffersCtrl', ['$scope', '$route', '$routeParams', '$filter', 'marketService', creditOffersCtrl]) .filter('to_trusted', ['$sce', function($sce){ return function(text) { return $sce.trustAsHtml(text); @@ -49,56 +48,13 @@ } } - function creditOffersCtrl($scope, $route, $routeParams, $location, $filter, utilities, marketService, chartService, appConfig) { + function creditOffersCtrl($scope, $route, $routeParams, $filter, marketService) { $scope.credit_offer_id = $routeParams.name; $scope.showOnlyActive = true; if($scope.credit_offer_id) { - - $scope.operationsColumns = [ - { - title: $filter('translate')('Operation'), - index: 'operation_text', - }, - { - title: $filter('translate')('ID'), - index: 'operation_id' - }, - { - title: $filter('translate')('Date and time'), - index: 'time', - hidden: ['xs'] - }, - { - title: $filter('translate')('Block'), - index: 'block_num', - hidden: ['xs', 'sm'] - }, - { - title: $filter('translate')('Type'), - index: 'type', - hidden: ['xs', 'sm', 'md'] - } - ]; - $scope.select = function(page_operations) { - const page = page_operations - 1; - const limit = 20; - const from = page * limit; - - $scope.operationsLoading = true; - $scope.operationsLoadingError = false; - marketService.getCreditOfferOperationsHistory($scope.credit_offer_id, limit, from).then((returnData) => { - console.log('test?'); - $scope.operationsLoading = false; - $scope.operations = returnData; - $scope.currentPage = page_operations; - }).catch(err => { - $scope.operationsLoadingError = true; - throw err; - }); - } - $scope.select(1); + } else { $scope.columns = [{ title: 'ID', diff --git a/app/sections/dashboard/dashboard.controller.js b/app/sections/dashboard/dashboard.controller.js index bbd4867..9f39f2f 100644 --- a/app/sections/dashboard/dashboard.controller.js +++ b/app/sections/dashboard/dashboard.controller.js @@ -19,65 +19,7 @@ }); $scope.branding = appConfig.branding; - - $scope.operationsColumns = [ - { - title: $filter('translate')('Operation'), - index: 'operation_text', - }, - { - title: $filter('translate')('ID'), - index: 'operation_id', - }, - { - title: $filter('translate')('Date and time'), - index: 'time', - hidden: ['xs'] - }, - { - title: $filter('translate')('Block'), - index: 'block_num', - hidden: ['xs', 'sm'] - }, - { - title: $filter('translate')('Type'), - index: 'type', - hidden: ['xs', 'sm', 'md'] - } - ]; - $scope.userOpenedFirstPageTime = null; - - $scope.select = function(page_operations) { - const page = page_operations -1; - const limit = 20; - const from = page * limit; - - if(page_operations === 1 || !$scope.userOpenedFirstPageTime) { // if user switches back from page Y (Y>1) to page 1 we need to fetch new transactions and update time range - $scope.userOpenedFirstPageTime = new Date(); - } - - const date_to = $scope.userOpenedFirstPageTime.toISOString(); - - $scope.operationsLoading = true; - $scope.operationsLoadingError = false; - networkService.getLastOperations(limit, from, date_to, function (returnData) { - $scope.operationsLoading = false; - $scope.operations = returnData; - $scope.currentPage = page_operations; - if (page_operations == 1) { - if (returnData.length > 0) { - $scope.total_ops = returnData[0].operation_id_num; - } else { - $scope.total_ops = 0; - } - } - }).catch(err => { - $scope.operationsLoadingError = true; - }); - }; - $scope.select(1); - $scope.chartsData = { operations_chart: chartService.loadingChart(), proxies_chart: chartService.loadingChart(), diff --git a/app/sections/dashboard/dashboard.html b/app/sections/dashboard/dashboard.html index f94f323..c03d7fc 100644 --- a/app/sections/dashboard/dashboard.html +++ b/app/sections/dashboard/dashboard.html @@ -137,34 +137,16 @@
      -
      +
      + + +
      - - - -
      -
      -
      -
      -
      -
        -
        -
        -
        + -
        diff --git a/app/sections/operations/operations-table.directive.js b/app/sections/operations/operations-table.directive.js new file mode 100644 index 0000000..d8e82f0 --- /dev/null +++ b/app/sections/operations/operations-table.directive.js @@ -0,0 +1,240 @@ +import moment from 'moment' + +/* +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 fields to optimize ES search by date limits + +// By default: now-1M + +(Example) + this is a date-from which applies when no filters + this is a date-from which applies when any filter defined by the user + + _ _ _ _ _ _ _ _ _ +| 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: '=', + defaultDateFrom: "@", + filtersDateFrom: "@", + filterByAccountIdEnabled: '=', + filterByAssetIdEnabled: '=', + filterByOperationTypeEnabled: '=', + }, + templateUrl: 'html/operations-table.html', + controller: ['$scope', '$filter', 'Notify', 'OperationsService', 'utilities', operationsTableController] + }; + + function operationsTableController($scope, $filter, Notify, OperationsService, utilities) { + + function filtersDefined() { + return $scope.filters.operationType !== '-1' || $scope.filters.accountIdOrName || $scope.filters.assetIdOrName; + } + + // list of values for filter by operation type + +
        + +
        +
        + +
        + + + + +
        +
        + There might be more data +
        +
        + Data from {{ extendedDateFrom.format("YYYY-DD-MM") }} to {{ userOpenedFirstPageTime.format("YYYY-DD-MM") }} +
        + +
        + +
        +
        +
        +
        +
        + +
          + +
          +
          +
          + diff --git a/app/sections/operations/operations.controller.js b/app/sections/operations/operations.controller.js index 0496972..eff95f2 100644 --- a/app/sections/operations/operations.controller.js +++ b/app/sections/operations/operations.controller.js @@ -2,9 +2,9 @@ 'use strict'; angular.module('app.operations') - .controller('operationsCtrl', ['$scope', 'Notify', '$filter', '$routeParams', '$location', 'networkService', operationsCtrl]); + .controller('operationsCtrl', ['$scope', '$routeParams', '$location', 'networkService', operationsCtrl]); - function operationsCtrl($scope, Notify, $filter, $routeParams, $location, networkService) { + function operationsCtrl($scope, $routeParams, $location, networkService) { const path = $location.path(); const name = $routeParams.name; @@ -19,56 +19,6 @@ else { if (path === "/operations") { - $scope.operationsColumns = [ - { - title: $filter('translate')('Operation'), - index: 'operation_text', - }, - { - title: $filter('translate')('ID'), - index: 'operation_id', - }, - { - title: $filter('translate')('Date and time'), - index: 'time', - hidden: ['xs'] - }, - { - title: $filter('translate')('Block'), - index: 'block_num', - hidden: ['xs', 'sm'] - }, - { - title: $filter('translate')('Type'), - index: 'type', - hidden: ['xs', 'sm', 'md'] - } - ]; - - $scope.userOpenedFirstPageTime = null; - - $scope.select = function (page_operations) { - const page = page_operations - 1; - const limit = 50; - const from = page * limit; - - if(page_operations === 1 || !$scope.userOpenedFirstPageTime) { // if user switches back from page Y (Y>1) to page 1 we need to fetch new transactions and update time range - $scope.userOpenedFirstPageTime = new Date(); - } - - const date_to = $scope.userOpenedFirstPageTime.toISOString(); - - $scope.operationsLoading = true; - networkService.getLastOperations(limit, from, date_to, function (returnData) { - $scope.operationsLoading = false; - $scope.operations = returnData; - $scope.currentPage = page_operations; - $scope.total_ops = 10000; - }).catch(err => { - $scope.operationsLoadingError = true; - }); - }; - $scope.select(1); } } } diff --git a/app/sections/operations/operations.html b/app/sections/operations/operations.html index fedaabe..079e133 100644 --- a/app/sections/operations/operations.html +++ b/app/sections/operations/operations.html @@ -31,45 +31,14 @@
          -
          -
          -
          -
          -
          -
          -
          -
          - -
          -
          -
          - - - - - -
          -
          -
          -
          -
          -
            -
            -
            -
            +
            + +
            + +
            diff --git a/app/sections/operations/operations.service.js b/app/sections/operations/operations.service.js new file mode 100644 index 0000000..6b58fbf --- /dev/null +++ b/app/sections/operations/operations.service.js @@ -0,0 +1,113 @@ +(function () { + 'use strict'; + + angular.module('app.ui') + .service('OperationsService', ['utilities', 'appConfig', '$filter', '$http', OperationsService]) + + function OperationsService(utilities, appConfig, $filter, $http) { + + function filterOperationDuplicates(v, i, a) { + return a.findIndex(t=>(t.operation_id_num === v.operation_id_num))===i + } + + function getOperationsHistory({ poolId = undefined, creditOfferId = undefined, limit = 20, offset = 0, date_from = undefined, date_to = undefined, assetId = undefined, operationType = undefined, accountId = undefined }) { + + 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 + 1, // fetch a one more item to define is there a next page + "offset": offset, + "from_date": date_from ? date_from : (offset < MAGIC_NUMBER ? "now-1M" : "2015-10-10"), + "to_date": date_to, + "filter_by": { + "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.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, + filterOperationDuplicates + } + } + + +})(); diff --git a/app/sections/pools/pool.html b/app/sections/pools/pool.html index eb8c0f5..0397bb2 100644 --- a/app/sections/pools/pool.html +++ b/app/sections/pools/pool.html @@ -153,34 +153,20 @@ -

            -
            - +
            +
            + + +
            -
            -
            -
            -
            -
            -
              -
              -
              -
              + +
              diff --git a/app/sections/pools/pools.controller.js b/app/sections/pools/pools.controller.js index 3125b3d..771997c 100644 --- a/app/sections/pools/pools.controller.js +++ b/app/sections/pools/pools.controller.js @@ -108,48 +108,6 @@ } }; - $scope.operationsColumns = [ - { - title: $filter('translate')('Operation'), - index: 'operation_text', - }, - { - title: $filter('translate')('ID'), - index: 'operation_id' - }, - { - title: $filter('translate')('Date and time'), - index: 'time', - hidden: ['xs'] - }, - { - title: $filter('translate')('Block'), - index: 'block_num', - hidden: ['xs', 'sm'] - }, - { - title: $filter('translate')('Type'), - index: 'type', - hidden: ['xs', 'sm', 'md'] - } - ]; - $scope.select = function(page_operations) { - const page = page_operations - 1; - const limit = 20; - const from = page * limit; - - $scope.operationsLoading = true; - $scope.operationsLoadingError = false; - marketService.getLiquidityPoolHistory(name, limit, from, function (returnData) { - $scope.operationsLoading = false; - $scope.operations = returnData; - $scope.currentPage = page_operations; - }).catch(err => { - $scope.operationsLoadingError = true; - throw err; - }); - } - $scope.select(1); } } else { diff --git a/app/styles/custom.css b/app/styles/custom.css index 5d78404..324693e 100644 --- a/app/styles/custom.css +++ b/app/styles/custom.css @@ -353,6 +353,36 @@ ul.scrollable-tabs-shadow-right:after { z-index: 1000; } +.operations-table-filters > div { + margin-right: 12px; +} + +.operations-table--load-more > div{ + margin-bottom: 8px; +} +.operations-table--load-more { + text-align: center; +} + +.operations-filter { + width: 18px; + cursor: pointer; +} + +.operations-table-filters { + display: flex; + margin-bottom: 16px; +} + +.dashboard-operations-filters > div { + margin-right: 12px; +} + +.dashboard-operations-filters { + display: flex; + margin-bottom: 16px; +} + .market--tv_chart_container { height: 43vh; } diff --git a/app/ui/responsive-table.directive.js b/app/ui/responsive-table.directive.js index 50900bd..4ae91d8 100644 --- a/app/ui/responsive-table.directive.js +++ b/app/ui/responsive-table.directive.js @@ -38,6 +38,15 @@ * * columns[].sortReverse {boolean} - Reverse the sorting when user sort the column * columns[].sortByDefault {boolean} - Turns on the sorting for the column when page loads + * + * columns[].filter[] - use an array to apply one or more filters to specific column + * columns[].filter[].width - The width of input/select + * columns[].filter[].placeholder - The placeholder of input/select + * columns[].filter[].defaultValue - Default value, please use '-1' for select + * columns[].filter[].onChange(value) - Handler for filter changes + * columns[].filter[].onFilterCancel - Handler when filter canceled (for e.g. to fetch non filtered data) + * columns[].filter[].modelOptions - ng-model-options + * columns[].filter[].options - use this for + + + +
              + +
              + @@ -53,6 +80,33 @@ {{column.title}}: + + + + +
              + +
              +
              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", diff --git a/package.json b/package.json index 892d0c7..76f5189 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "extract-zip": "^2.0.0", "highcharts": "^8.1.2", "md5-file": "^5.0.0", + "moment": "^2.29.4", "ngstorage": "^0.3.11" } }