Merge branch 'master' into breathe-effect-framerate
This commit is contained in:
@@ -8,6 +8,10 @@ indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.ts]
|
||||
quote_type = single
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
|
||||
2
frontend/.prettierignore
Normal file
2
frontend/.prettierignore
Normal file
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
package-lock.json
|
||||
6
frontend/.prettierrc
Normal file
6
frontend/.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"endOfLine": "lf",
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
171
frontend/cypress/e2e/mainnet/mining.spec.ts
Normal file
171
frontend/cypress/e2e/mainnet/mining.spec.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
const baseModule = Cypress.env("BASE_MODULE");
|
||||
|
||||
describe('Mainnet - Mining Features', () => {
|
||||
beforeEach(() => {
|
||||
//https://github.com/cypress-io/cypress/issues/14459
|
||||
if (Cypress.browser.family === 'chromium') {
|
||||
Cypress.automation('remote:debugger:protocol', {
|
||||
command: 'Network.enable',
|
||||
params: {}
|
||||
});
|
||||
Cypress.automation('remote:debugger:protocol', {
|
||||
command: 'Network.setCacheDisabled',
|
||||
params: { cacheDisabled: true }
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (baseModule === 'mempool') {
|
||||
|
||||
describe('Miner page', () => {
|
||||
beforeEach(() => {
|
||||
cy.intercept('/api/v1/mining/pool/**').as('pool');
|
||||
cy.intercept('/api/v1/mining/hashrate/pools/**').as('hashrate');
|
||||
cy.intercept('/api/tx/**').as('tx');
|
||||
cy.intercept('/api/v1/outpends/**').as('outspends');
|
||||
});
|
||||
it('loads the mining pool page from the dashboard', () => {
|
||||
cy.visit('/mining');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.get('[data-cy="bitcoin-block-0-pool"]').click().then(() => {
|
||||
cy.waitForSkeletonGone();
|
||||
cy.wait('@pool');
|
||||
cy.url().should('match', /\/mining\/pool\/(\w+)/);
|
||||
});
|
||||
});
|
||||
|
||||
it('loads the mining pool page from the blocks page', () => {
|
||||
cy.visit('/mining');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.get('[data-cy="bitcoin-block-0-height"]').click().then(() => {
|
||||
cy.waitForSkeletonGone();
|
||||
cy.get('[data-cy="block-details-miner-badge"]').click().then(() => {
|
||||
cy.waitForSkeletonGone();
|
||||
cy.wait('@pool');
|
||||
cy.url().should('match', /\/mining\/pool\/(\w+)/);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Mining Dashboard Landing page widgets', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.visit('/mining');
|
||||
cy.waitForSkeletonGone();
|
||||
});
|
||||
|
||||
it('shows the mempool blocks', () => {
|
||||
cy.get('[data-cy="mempool-block-0-fees"]').invoke('text').should('match', /~(.*) sat\/vB/);
|
||||
cy.get('[data-cy="mempool-block-0-fee-span"]').invoke('text').should('match', /(.*) - (.*) sat\/vB/);
|
||||
cy.get('[data-cy="mempool-block-0-total-fees"]').invoke('text').should('match', /(.*) BTC/);
|
||||
cy.get('[data-cy="mempool-block-0-transaction-count"]').invoke('text').should('match', /(.*) transactions/);
|
||||
cy.get('[data-cy="mempool-block-0-time"]').invoke('text').should('match', /In ~(.*) minutes/);
|
||||
});
|
||||
|
||||
it('shows the mined blocks', () => {
|
||||
cy.get('[data-cy="bitcoin-block-0-height"]').invoke('text').should('match', /(\d)/);
|
||||
cy.get('[data-cy="bitcoin-block-0-fees"]').invoke('text').should('match', /~(.*) sat\/vB/);
|
||||
cy.get('[data-cy="bitcoin-block-0-fee-span"]').invoke('text').should('match', /(.*) - (.*) sat\/vB/);
|
||||
cy.get('[data-cy="bitcoin-block-0-total-fees"]').invoke('text').should('match', /(.*) BTC/);
|
||||
cy.get('[data-cy="bitcoin-block-0-transactions"]').invoke('text').should('match', /(.*) transactions/);
|
||||
cy.get('[data-cy="bitcoin-block-0-time"]').invoke('text').should('match', /((.*) ago|Just now)/);
|
||||
cy.get('[data-cy="bitcoin-block-0-pool"]').invoke('text').should('match', /(\w)/);
|
||||
});
|
||||
|
||||
it('shows the reward stats for the last 144 blocks', () => {
|
||||
cy.get('[data-cy="reward-stats"]');
|
||||
});
|
||||
|
||||
it('shows the difficulty adjustment stats', () => {
|
||||
cy.get('[data-cy="difficulty-adjustment"]');
|
||||
});
|
||||
|
||||
it('shows the latest blocks', () => {
|
||||
cy.get('[data-cy="latest-blocks"]');
|
||||
});
|
||||
|
||||
it('shows the pools pie chart', () => {
|
||||
cy.get('[data-cy="pool-distribution"]');
|
||||
});
|
||||
|
||||
it('shows the hashrate graph', () => {
|
||||
cy.get('[data-cy="hashrate-graph"]');
|
||||
});
|
||||
it('shows the latest blocks', () => {
|
||||
cy.get('[data-cy="latest-blocks"]');
|
||||
});
|
||||
|
||||
it('shows the latest adjustments', () => {
|
||||
cy.get('[data-cy="difficulty-adjustments-table"]');
|
||||
});
|
||||
});
|
||||
|
||||
describe.only('mining graphs', () => {
|
||||
describe('pools ranking', () => {
|
||||
it('loads the graph', () => {
|
||||
cy.visit('/graphs/mining/pools');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.waitForPageIdle();
|
||||
cy.get('.spinner-border').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('pools dominance', () => {
|
||||
it('loads the graph', () => {
|
||||
cy.visit('/graphs/mining/pools-dominance');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.waitForPageIdle();
|
||||
cy.get('.spinner-border').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('hashrate & difficulty', () => {
|
||||
it('loads the graph', () => {
|
||||
cy.visit('/graphs/mining/hashrate-difficulty');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.waitForPageIdle();
|
||||
cy.get('.spinner-border').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('block fee rates', () => {
|
||||
it('loads the graph', () => {
|
||||
cy.visit('/graphs/mining/block-fee-rates');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.waitForPageIdle();
|
||||
cy.get('.spinner-border').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('block fees', () => {
|
||||
it('loads the graph', () => {
|
||||
cy.visit('/graphs/mining/block-fees');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.waitForPageIdle();
|
||||
cy.get('.spinner-border').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('block rewards', () => {
|
||||
it('loads the graph', () => {
|
||||
cy.visit('/graphs/mining/block-rewards');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.waitForPageIdle();
|
||||
cy.get('.spinner-border').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
describe('block sizes and weights', () => {
|
||||
it('loads the graph', () => {
|
||||
cy.visit('/graphs/mining/block-sizes-weights');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.waitForPageIdle();
|
||||
cy.get('.spinner-border').should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
it.skip(`Tests cannot be run on the selected BASE_MODULE ${baseModule}`);
|
||||
}
|
||||
});
|
||||
88
frontend/package-lock.json
generated
88
frontend/package-lock.json
generated
@@ -56,14 +56,15 @@
|
||||
"@typescript-eslint/parser": "^5.30.5",
|
||||
"eslint": "^8.19.0",
|
||||
"http-proxy-middleware": "~2.0.6",
|
||||
"prettier": "^2.7.1",
|
||||
"ts-node": "~10.8.1",
|
||||
"typescript": "~4.6.4"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@cypress/schematic": "~2.0.0",
|
||||
"cypress": "^10.0.2",
|
||||
"cypress-fail-on-console-error": "~2.1.4",
|
||||
"cypress-wait-until": "^1.7.1",
|
||||
"cypress": "^10.3.0",
|
||||
"cypress-fail-on-console-error": "~3.0.0",
|
||||
"cypress-wait-until": "^1.7.2",
|
||||
"mock-socket": "~9.1.4",
|
||||
"start-server-and-test": "~1.14.0"
|
||||
}
|
||||
@@ -1366,9 +1367,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-plugin-utils": {
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz",
|
||||
"integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==",
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.6.tgz",
|
||||
"integrity": "sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg==",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@@ -7293,9 +7294,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/cypress": {
|
||||
"version": "10.0.2",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-10.0.2.tgz",
|
||||
"integrity": "sha512-7+C4KHYBcfZrawss+Gt5PlS35rfc6ySc59JcHDVsIMm1E/J35dqE41UEXpdtwIq3549umCerNWnFADzqib4kcA==",
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-10.3.0.tgz",
|
||||
"integrity": "sha512-txkQWKzvBVnWdCuKs5Xc08gjpO89W2Dom2wpZgT9zWZT5jXxqPIxqP/NC1YArtkpmp3fN5HW8aDjYBizHLUFvg==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -7350,9 +7351,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cypress-fail-on-console-error": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-2.1.4.tgz",
|
||||
"integrity": "sha512-arjx2xfQN1FDM3s4HoKK0ZXszPgIZLAI61sbwaZfdo8HEIVJPdOwY+oBKM1XY9yso80rgtwlSY75KJOQTNOkdg==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-3.0.0.tgz",
|
||||
"integrity": "sha512-DBu5DI3gMzwFkzuOTbJ/A1xbGtYKukFoe7o07unEJlqe0f50xwB5OnAm6Pxe7J9eNtg40ZUJB8fcATqDr0qwgw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"chai": "^4.3.4",
|
||||
@@ -7361,9 +7362,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cypress-wait-until": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-1.7.1.tgz",
|
||||
"integrity": "sha512-8DL5IsBTbAxBjfYgCzdbohPq/bY+IKc63fxtso1C8RWhLnQkZbVESyaclNr76jyxfId6uyzX8+Xnt0ZwaXNtkA==",
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-1.7.2.tgz",
|
||||
"integrity": "sha512-uZ+M8/MqRcpf+FII/UZrU7g1qYZ4aVlHcgyVopnladyoBrpoaMJ4PKZDrdOJ05H5RHbr7s9Tid635X3E+ZLU/Q==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/cypress/node_modules/@types/node": {
|
||||
@@ -10994,9 +10995,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jest-worker": {
|
||||
"version": "27.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.0.tgz",
|
||||
"integrity": "sha512-laB0ZVIBz+voh/QQy9dmUuuDsadixeerrKqyVpgPz+CCWiOYjOBabUXHIXZhsdvkWbLqSHbgkAHWl5cg24Q6RA==",
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
|
||||
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"merge-stream": "^2.0.0",
|
||||
@@ -14340,6 +14341,21 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-bytes": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
|
||||
@@ -18695,9 +18711,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/helper-plugin-utils": {
|
||||
"version": "7.16.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz",
|
||||
"integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA=="
|
||||
"version": "7.18.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.6.tgz",
|
||||
"integrity": "sha512-gvZnm1YAAxh13eJdkb9EWHBnF3eAub3XTLCZEehHT2kWxiKVRL64+ae5Y6Ivne0mVHmMYKT+xWgZO+gQhuLUBg=="
|
||||
},
|
||||
"@babel/helper-remap-async-to-generator": {
|
||||
"version": "7.16.8",
|
||||
@@ -23197,9 +23213,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"cypress": {
|
||||
"version": "10.0.2",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-10.0.2.tgz",
|
||||
"integrity": "sha512-7+C4KHYBcfZrawss+Gt5PlS35rfc6ySc59JcHDVsIMm1E/J35dqE41UEXpdtwIq3549umCerNWnFADzqib4kcA==",
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-10.3.0.tgz",
|
||||
"integrity": "sha512-txkQWKzvBVnWdCuKs5Xc08gjpO89W2Dom2wpZgT9zWZT5jXxqPIxqP/NC1YArtkpmp3fN5HW8aDjYBizHLUFvg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"@cypress/request": "^2.88.10",
|
||||
@@ -23374,9 +23390,9 @@
|
||||
}
|
||||
},
|
||||
"cypress-fail-on-console-error": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-2.1.4.tgz",
|
||||
"integrity": "sha512-arjx2xfQN1FDM3s4HoKK0ZXszPgIZLAI61sbwaZfdo8HEIVJPdOwY+oBKM1XY9yso80rgtwlSY75KJOQTNOkdg==",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-3.0.0.tgz",
|
||||
"integrity": "sha512-DBu5DI3gMzwFkzuOTbJ/A1xbGtYKukFoe7o07unEJlqe0f50xwB5OnAm6Pxe7J9eNtg40ZUJB8fcATqDr0qwgw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chai": "^4.3.4",
|
||||
@@ -23385,9 +23401,9 @@
|
||||
}
|
||||
},
|
||||
"cypress-wait-until": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-1.7.1.tgz",
|
||||
"integrity": "sha512-8DL5IsBTbAxBjfYgCzdbohPq/bY+IKc63fxtso1C8RWhLnQkZbVESyaclNr76jyxfId6uyzX8+Xnt0ZwaXNtkA==",
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-1.7.2.tgz",
|
||||
"integrity": "sha512-uZ+M8/MqRcpf+FII/UZrU7g1qYZ4aVlHcgyVopnladyoBrpoaMJ4PKZDrdOJ05H5RHbr7s9Tid635X3E+ZLU/Q==",
|
||||
"optional": true
|
||||
},
|
||||
"d": {
|
||||
@@ -26030,9 +26046,9 @@
|
||||
}
|
||||
},
|
||||
"jest-worker": {
|
||||
"version": "27.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.2.0.tgz",
|
||||
"integrity": "sha512-laB0ZVIBz+voh/QQy9dmUuuDsadixeerrKqyVpgPz+CCWiOYjOBabUXHIXZhsdvkWbLqSHbgkAHWl5cg24Q6RA==",
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
|
||||
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"merge-stream": "^2.0.0",
|
||||
@@ -28514,6 +28530,12 @@
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
|
||||
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
|
||||
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
|
||||
"dev": true
|
||||
},
|
||||
"pretty-bytes": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
"test": "npm run ng -- test",
|
||||
"lint": "./node_modules/.bin/eslint . --ext .ts",
|
||||
"lint:fix": "./node_modules/.bin/eslint . --ext .ts --fix",
|
||||
"prettier": "prettier --write \"src/app/**/*.{js,json,css,scss,less,md,ts,html,component.html}\"",
|
||||
"e2e": "npm run generate-config && npm run ng -- e2e",
|
||||
"e2e:ci": "npm run cypress:run:ci",
|
||||
"config:defaults:mempool": "node update-config.js TESTNET_ENABLED=true SIGNET_ENABLED=true LIQUID_ENABLED=true LIQUID_TESTNET_ENABLED=true BISQ_ENABLED=true ITEMS_PER_PAGE=25 BASE_MODULE=mempool BLOCK_WEIGHT_UNITS=4000000 && npm run generate-config",
|
||||
@@ -109,14 +110,15 @@
|
||||
"@typescript-eslint/parser": "^5.30.5",
|
||||
"eslint": "^8.19.0",
|
||||
"http-proxy-middleware": "~2.0.6",
|
||||
"prettier": "^2.7.1",
|
||||
"ts-node": "~10.8.1",
|
||||
"typescript": "~4.6.4"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@cypress/schematic": "~2.0.0",
|
||||
"cypress": "^10.0.2",
|
||||
"cypress-fail-on-console-error": "~2.1.4",
|
||||
"cypress-wait-until": "^1.7.1",
|
||||
"cypress": "^10.3.0",
|
||||
"cypress-fail-on-console-error": "~3.0.0",
|
||||
"cypress-wait-until": "^1.7.2",
|
||||
"mock-socket": "~9.1.4",
|
||||
"start-server-and-test": "~1.14.0"
|
||||
},
|
||||
|
||||
@@ -2,41 +2,41 @@
|
||||
|
||||
<div class="full-container">
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-prediction-accuracy">Block Predictions Accuracy</span>
|
||||
<span i18n="mining.block-prediction-accuracy">Block Prediction Accuracy</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 144">
|
||||
<input ngbButton type="radio" [value]="'24h'" fragment="24h" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> 24h
|
||||
<input ngbButton type="radio" [value]="'24h'" fragment="24h" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> 24h
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 432">
|
||||
<input ngbButton type="radio" [value]="'3d'" fragment="3d" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> 3D
|
||||
<input ngbButton type="radio" [value]="'3d'" fragment="3d" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> 3D
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 1008">
|
||||
<input ngbButton type="radio" [value]="'1w'" fragment="1w" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> 1W
|
||||
<input ngbButton type="radio" [value]="'1w'" fragment="1w" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> 1W
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 4320">
|
||||
<input ngbButton type="radio" [value]="'1m'" fragment="1m" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> 1M
|
||||
<input ngbButton type="radio" [value]="'1m'" fragment="1m" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> 1M
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 12960">
|
||||
<input ngbButton type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> 3M
|
||||
<input ngbButton type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> 3M
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 25920">
|
||||
<input ngbButton type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> 6M
|
||||
<input ngbButton type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> 6M
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 52560">
|
||||
<input ngbButton type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> 1Y
|
||||
<input ngbButton type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> 1Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 105120">
|
||||
<input ngbButton type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> 2Y
|
||||
<input ngbButton type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> 2Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 157680">
|
||||
<input ngbButton type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> 3Y
|
||||
<input ngbButton type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> 3Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount > 157680">
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/block-predictions' | relativeUrl]"> ALL
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/block-prediction' | relativeUrl]"> ALL
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
@@ -13,9 +13,9 @@ import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-block-predictions-graph',
|
||||
templateUrl: './block-predictions-graph.component.html',
|
||||
styleUrls: ['./block-predictions-graph.component.scss'],
|
||||
selector: 'app-block-prediction-graph',
|
||||
templateUrl: './block-prediction-graph.component.html',
|
||||
styleUrls: ['./block-prediction-graph.component.scss'],
|
||||
styles: [`
|
||||
.loadingGraphs {
|
||||
position: absolute;
|
||||
@@ -26,7 +26,7 @@ import { StateService } from 'src/app/services/state.service';
|
||||
`],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BlockPredictionsGraphComponent implements OnInit {
|
||||
export class BlockPredictionGraphComponent implements OnInit {
|
||||
@Input() right: number | string = 45;
|
||||
@Input() left: number | string = 75;
|
||||
|
||||
@@ -60,7 +60,7 @@ export class BlockPredictionsGraphComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.seoService.setTitle($localize`Block predictions accuracy`);
|
||||
this.seoService.setTitle($localize`:@@d7d5fcf50179ad70c938491c517efb82de2c8146:Block Prediction Accuracy`);
|
||||
this.miningWindowPreference = '24h';//this.miningService.getDefaultTimespan('24h');
|
||||
this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference });
|
||||
this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference);
|
||||
@@ -113,13 +113,13 @@
|
||||
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet'">
|
||||
<td i18n="block.miner">Miner</td>
|
||||
<td *ngIf="stateService.env.MINING_DASHBOARD">
|
||||
<a placement="bottom" [routerLink]="['/mining/pool' | relativeUrl, block.extras.pool.slug]" class="badge"
|
||||
<a [attr.data-cy]="'block-details-miner-badge'" placement="bottom" [routerLink]="['/mining/pool' | relativeUrl, block.extras.pool.slug]" class="badge"
|
||||
[class]="block.extras.pool.name === 'Unknown' ? 'badge-secondary' : 'badge-primary'">
|
||||
{{ block.extras.pool.name }}
|
||||
</a>
|
||||
</td>
|
||||
<td *ngIf="!stateService.env.MINING_DASHBOARD && stateService.env.BASE_MODULE === 'mempool'">
|
||||
<span placement="bottom" class="badge"
|
||||
<span [attr.data-cy]="'block-details-miner-badge'" placement="bottom" class="badge"
|
||||
[class]="block.extras.pool.name === 'Unknown' ? 'badge-secondary' : 'badge-primary'">
|
||||
{{ block.extras.pool.name }}
|
||||
</span>
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
<div class="blocks-container blockchain-blocks-container" *ngIf="(loadingBlocks$ | async) === false; else loadingBlocksTemplate">
|
||||
<div *ngFor="let block of blocks; let i = index; trackBy: trackByBlocksFn" >
|
||||
<div class="text-center bitcoin-block mined-block blockchain-blocks-{{ i }}" id="bitcoin-block-{{ block.height }}" [ngStyle]="blockStyles[i]" [class.blink-bg]="(specialBlocks[block.height] !== undefined)">
|
||||
<a draggable="false" [routerLink]="['/block/' | relativeUrl, block.id]" [state]="{ data: { block: block } }"
|
||||
<div [attr.data-cy]="'bitcoin-block-' + i" class="text-center bitcoin-block mined-block blockchain-blocks-{{ i }}" id="bitcoin-block-{{ block.height }}" [ngStyle]="blockStyles[i]" [class.blink-bg]="(specialBlocks[block.height] !== undefined)">
|
||||
<a draggable="false" [routerLink]="['/block/' | relativeUrl, block.id]" [state]="{ data: { block: block } }"
|
||||
class="blockLink" [ngClass]="{'disabled': (this.stateService.blockScrolling$ | async)}"> </a>
|
||||
<div class="block-height">
|
||||
<div [attr.data-cy]="'bitcoin-block-' + i + '-height'" class="block-height">
|
||||
<a [routerLink]="['/block/' | relativeUrl, block.id]" [state]="{ data: { block: block } }">{{ block.height }}</a>
|
||||
</div>
|
||||
<div class="block-body">
|
||||
<div class="fees">
|
||||
<div [attr.data-cy]="'bitcoin-block-' + i + '-fees'" class="fees">
|
||||
~{{ block?.extras?.medianFee | number:feeRounding }} <ng-container i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
||||
</div>
|
||||
<div class="fee-span">
|
||||
<div [attr.data-cy]="'bitcoin-block-' + i + '-fee-span'" class="fee-span">
|
||||
{{ block?.extras?.feeRange[1] | number:feeRounding }} - {{ block?.extras?.feeRange[block?.extras?.feeRange.length - 1] | number:feeRounding }} <ng-container i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
||||
</div>
|
||||
<div *ngIf="showMiningInfo" class="block-size">
|
||||
<div [attr.data-cy]="'bitcoin-block-' + i + '-total-fees'" *ngIf="showMiningInfo" class="block-size">
|
||||
<app-amount [satoshis]="block.extras?.totalFees ?? 0" digitsInfo="1.2-3" [noFiat]="true"></app-amount>
|
||||
</div>
|
||||
<div *ngIf="!showMiningInfo" class="block-size" [innerHTML]="'‎' + (block.size | bytes: 2)"></div>
|
||||
<div class="transaction-count">
|
||||
<div [attr.data-cy]="'bitcoin-block-' + i + 'block-size'" *ngIf="!showMiningInfo" class="block-size" [innerHTML]="'‎' + (block.size | bytes: 2)"></div>
|
||||
<div [attr.data-cy]="'bitcoin-block-' + i + '-transactions'" class="transaction-count">
|
||||
<ng-container *ngTemplateOutlet="block.tx_count === 1 ? transactionsSingular : transactionsPlural; context: {$implicit: block.tx_count | number}"></ng-container>
|
||||
<ng-template #transactionsSingular let-i i18n="shared.transaction-count.singular">{{ i }} transaction</ng-template>
|
||||
<ng-template #transactionsPlural let-i i18n="shared.transaction-count.plural">{{ i }} transactions</ng-template>
|
||||
</div>
|
||||
<div class="time-difference"><app-time-since [time]="block.timestamp" [fastRender]="true"></app-time-since></div>
|
||||
<div [attr.data-cy]="'bitcoin-block-' + i + '-time'" class="time-difference"><app-time-since [time]="block.timestamp" [fastRender]="true"></app-time-since></div>
|
||||
</div>
|
||||
<div class="animated" [class]="showMiningInfo ? 'show' : 'hide'" *ngIf="block.extras?.pool != undefined">
|
||||
<a class="badge badge-primary" [routerLink]="[('/mining/pool/' + block.extras.pool.slug) | relativeUrl]">
|
||||
<a [attr.data-cy]="'bitcoin-block-' + i + '-pool'" class="badge badge-primary" [routerLink]="[('/mining/pool/' + block.extras.pool.slug) | relativeUrl]">
|
||||
{{ block.extras.pool.name}}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<a class="dropdown-item" routerLinkActive="active"
|
||||
[routerLink]="['/graphs/mining/block-sizes-weights' | relativeUrl]" i18n="mining.block-sizes-weights">Block Sizes and Weights</a>
|
||||
<a class="dropdown-item" routerLinkActive="active"
|
||||
[routerLink]="['/graphs/mining/block-predictions' | relativeUrl]" i18n="mining.block-prediction-accuracy">Blocks Predictions Accuracy</a>
|
||||
[routerLink]="['/graphs/mining/block-prediction' | relativeUrl]" i18n="mining.block-prediction-accuracy">Block Prediction Accuracy</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -28,22 +28,22 @@
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 12960">
|
||||
<input ngbButton type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]"> 3M
|
||||
<input ngbButton type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" [attr.data-cy]="'3m'"> 3M
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 25920">
|
||||
<input ngbButton type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]"> 6M
|
||||
<input ngbButton type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" [attr.data-cy]="'6m'"> 6M
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 52560">
|
||||
<input ngbButton type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]"> 1Y
|
||||
<input ngbButton type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" [attr.data-cy]="'1y'"> 1Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 105120">
|
||||
<input ngbButton type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]"> 2Y
|
||||
<input ngbButton type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" [attr.data-cy]="'2y'"> 2Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 157680">
|
||||
<input ngbButton type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]"> 3Y
|
||||
<input ngbButton type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" [attr.data-cy]="'3y'"> 3Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm">
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]"> ALL
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" [attr.data-cy]="'all'"> ALL
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -10,19 +10,19 @@
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 25920">
|
||||
<input ngbButton type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]"> 6M
|
||||
<input ngbButton type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]" [attr.data-cy]="'6m'"> 6M
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 52560">
|
||||
<input ngbButton type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]"> 1Y
|
||||
<input ngbButton type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]" [attr.data-cy]="'1y'"> 1Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 105120">
|
||||
<input ngbButton type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]"> 2Y
|
||||
<input ngbButton type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]" [attr.data-cy]="'2y'"> 2Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 157680">
|
||||
<input ngbButton type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]"> 3Y
|
||||
<input ngbButton type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]" [attr.data-cy]="'3y'"> 3Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm">
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]"> ALL
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]" [attr.data-cy]="'all'"> ALL
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -2,26 +2,26 @@
|
||||
<div class="mempool-blocks-container" *ngIf="(difficultyAdjustments$ | async) as da;">
|
||||
<div class="flashing">
|
||||
<ng-template ngFor let-projectedBlock [ngForOf]="mempoolBlocks$ | async" let-i="index" [ngForTrackBy]="trackByFn">
|
||||
<div class="bitcoin-block text-center mempool-block" id="mempool-block-{{ i }}" [ngStyle]="mempoolBlockStyles[i]" [class.blink-bg]="projectedBlock.blink">
|
||||
<div [attr.data-cy]="'mempool-block-' + i" class="bitcoin-block text-center mempool-block" id="mempool-block-{{ i }}" [ngStyle]="mempoolBlockStyles[i]" [class.blink-bg]="projectedBlock.blink">
|
||||
<a draggable="false" [routerLink]="['/mempool-block/' | relativeUrl, i]"
|
||||
class="blockLink" [ngClass]="{'disabled': (this.stateService.blockScrolling$ | async)}"> </a>
|
||||
<div class="block-body">
|
||||
<div class="fees">
|
||||
<div [attr.data-cy]="'mempool-block-' + i + '-fees'" class="fees">
|
||||
~{{ projectedBlock.medianFee | number:feeRounding }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
</div>
|
||||
<div class="fee-span">
|
||||
<div [attr.data-cy]="'mempool-block-' + i + '-fee-span'" class="fee-span">
|
||||
{{ projectedBlock.feeRange[0] | number:feeRounding }} - {{ projectedBlock.feeRange[projectedBlock.feeRange.length - 1] | number:feeRounding }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
</div>
|
||||
<div *ngIf="showMiningInfo" class="block-size">
|
||||
<app-amount [satoshis]="projectedBlock.totalFees" digitsInfo="1.2-3" [noFiat]="true"></app-amount>
|
||||
<app-amount [attr.data-cy]="'mempool-block-' + i + '-total-fees'" [satoshis]="projectedBlock.totalFees" digitsInfo="1.2-3" [noFiat]="true"></app-amount>
|
||||
</div>
|
||||
<div *ngIf="!showMiningInfo" class="block-size" [innerHTML]="'‎' + (projectedBlock.blockSize | bytes: 2)"></div>
|
||||
<div class="transaction-count">
|
||||
<div [attr.data-cy]="'mempool-block-' + i + '-transaction-count'" class="transaction-count">
|
||||
<ng-container *ngTemplateOutlet="projectedBlock.nTx === 1 ? transactionsSingular : transactionsPlural; context: {$implicit: projectedBlock.nTx | number}"></ng-container>
|
||||
<ng-template #transactionsSingular let-i i18n="shared.transaction-count.singular">{{ i }} transaction</ng-template>
|
||||
<ng-template #transactionsPlural let-i i18n="shared.transaction-count.plural">{{ i }} transactions</ng-template>
|
||||
</div>
|
||||
<div class="time-difference" *ngIf="projectedBlock.blockVSize <= stateService.blockVSize; else mergedBlock">
|
||||
<div [attr.data-cy]="'mempool-block-' + i + '-time'" class="time-difference" *ngIf="projectedBlock.blockVSize <= stateService.blockVSize; else mergedBlock">
|
||||
<ng-template [ngIf]="network === 'liquid' || network === 'liquidtestnet'" [ngIfElse]="timeDiffMainnet">
|
||||
<app-time-until [time]="(1 * i) + now + 61000" [fastRender]="false" [fixedRender]="true"></app-time-until>
|
||||
</ng-template>
|
||||
@@ -30,7 +30,7 @@
|
||||
</ng-template>
|
||||
</div>
|
||||
<ng-template #mergedBlock>
|
||||
<div class="time-difference">
|
||||
<div [attr.data-cy]="'mempool-block-' + i + '-blocks'" class="time-difference">
|
||||
<b>(<ng-container *ngTemplateOutlet="blocksPlural; context: {$implicit: projectedBlock.blockVSize / stateService.blockVSize | ceil }"></ng-container>)</b>
|
||||
<ng-template #blocksPlural let-i i18n="shared.blocks">{{ i }} <span class="shared-block">blocks</span></ng-template>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<!-- Temporary stuff here - Will be moved to a component once we have more useful data to show -->
|
||||
<div class="col">
|
||||
<div class="main-title">
|
||||
<span i18n="mining.reward-stats">Reward stats</span>
|
||||
<span [attr.data-cy]="'reward-stats'" i18n="mining.reward-stats">Reward stats</span>
|
||||
<span style="font-size: xx-small" i18n="mining.144-blocks">(144 blocks)</span>
|
||||
</div>
|
||||
<div class="card-wrapper">
|
||||
@@ -22,15 +22,15 @@
|
||||
<!-- difficulty adjustment -->
|
||||
<div class="col">
|
||||
<div class="main-title" i18n="dashboard.difficulty-adjustment">Difficulty Adjustment</div>
|
||||
<app-difficulty [showTitle]="false" [showProgress]="false" [showHalving]="true"></app-difficulty>
|
||||
<app-difficulty [attr.data-cy]="'difficulty-adjustment'" [showTitle]="false" [showProgress]="false" [showHalving]="true"></app-difficulty>
|
||||
</div>
|
||||
|
||||
<!-- pool distribution -->
|
||||
<div class="col" style="margin-bottom: 1.47rem">
|
||||
<div class="card graph-card">
|
||||
<div class="card-body pl-2 pr-2">
|
||||
<app-pool-ranking [widget]=true></app-pool-ranking>
|
||||
<div class="mt-1"><a [routerLink]="['/graphs/mining/pools' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
<app-pool-ranking [attr.data-cy]="'pool-distribution'" [widget]=true></app-pool-ranking>
|
||||
<div class="mt-1"><a [attr.data-cy]="'pool-distribution-view-more'" [routerLink]="['/graphs/mining/pools' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,7 +39,7 @@
|
||||
<div class="col" style="margin-bottom: 1.47rem">
|
||||
<div class="card">
|
||||
<div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2">
|
||||
<app-hashrate-chart [widget]="true"></app-hashrate-chart>
|
||||
<app-hashrate-chart [attr.data-cy]="'hashrate-graph'" [widget]="true"></app-hashrate-chart>
|
||||
<div class="mt-1"><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" fragment="1y" i18n="dashboard.view-more">View more »</a></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -54,7 +54,7 @@
|
||||
<span> </span>
|
||||
<fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: 'text-top'; font-size: 13px; color: '#4a68b9'"></fa-icon>
|
||||
</a>
|
||||
<app-blocks-list [widget]=true></app-blocks-list>
|
||||
<app-blocks-list [attr.data-cy]="'latest-blocks'" [widget]=true></app-blocks-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -68,7 +68,7 @@
|
||||
<span> </span>
|
||||
<fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: 'text-top'; font-size: 13px; color: '#4a68b9'"></fa-icon>
|
||||
</a>
|
||||
<app-difficulty-adjustments-table></app-difficulty-adjustments-table>
|
||||
<app-difficulty-adjustments-table [attr.data-cy]="'difficulty-adjustments-table'"></app-difficulty-adjustments-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -40,34 +40,34 @@
|
||||
*ngIf="!widget && (miningStatsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 144">
|
||||
<input ngbButton type="radio" [value]="'24h'" fragment="24h" [routerLink]="['/graphs/mining/pools' | relativeUrl]"> 24h
|
||||
<input ngbButton type="radio" [value]="'24h'" fragment="24h" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'24h'"> 24h
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 432">
|
||||
<input ngbButton type="radio" [value]="'3d'" fragment="3d" [routerLink]="['/graphs/mining/pools' | relativeUrl]"> 3D
|
||||
<input ngbButton type="radio" [value]="'3d'" fragment="3d" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'3d'"> 3D
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 1008">
|
||||
<input ngbButton type="radio" [value]="'1w'" fragment="1w" [routerLink]="['/graphs/mining/pools' | relativeUrl]"> 1W
|
||||
<input ngbButton type="radio" [value]="'1w'" fragment="1w" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'1w'"> 1W
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 4320">
|
||||
<input ngbButton type="radio" [value]="'1m'" fragment="1m" [routerLink]="['/graphs/mining/pools' | relativeUrl]"> 1M
|
||||
<input ngbButton type="radio" [value]="'1m'" fragment="1m" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'1m'"> 1M
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 12960">
|
||||
<input ngbButton type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/pools' | relativeUrl]"> 3M
|
||||
<input ngbButton type="radio" [value]="'3m'" fragment="3m" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'3m'"> 3M
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 25920">
|
||||
<input ngbButton type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/pools' | relativeUrl]"> 6M
|
||||
<input ngbButton type="radio" [value]="'6m'" fragment="6m" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'6m'"> 6M
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 52560">
|
||||
<input ngbButton type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/pools' | relativeUrl]"> 1Y
|
||||
<input ngbButton type="radio" [value]="'1y'" fragment="1y" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'1y'"> 1Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 105120">
|
||||
<input ngbButton type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/pools' | relativeUrl]"> 2Y
|
||||
<input ngbButton type="radio" [value]="'2y'" fragment="2y" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'2y'"> 2Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount >= 157680">
|
||||
<input ngbButton type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/pools' | relativeUrl]"> 3Y
|
||||
<input ngbButton type="radio" [value]="'3y'" fragment="3y" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'3y'"> 3Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm">
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/pools' | relativeUrl]"><span i18n>All</span>
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all" [routerLink]="['/graphs/mining/pools' | relativeUrl]" [attr.data-cy]="'all'"><span i18n>All</span>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
@@ -95,7 +95,7 @@
|
||||
<th class="d-none d-md-block" i18n="mining.empty-blocks">Empty blocks</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody *ngIf="(miningStatsObservable$ | async) as miningStats">
|
||||
<tbody [attr.data-cy]="'pools-table'" *ngIf="(miningStatsObservable$ | async) as miningStats">
|
||||
<tr *ngFor="let pool of miningStats.pools">
|
||||
<td class="d-none d-md-block">{{ pool.rank }}</td>
|
||||
<td class="text-right">
|
||||
|
||||
@@ -22,7 +22,7 @@ import { DashboardComponent } from '../dashboard/dashboard.component';
|
||||
import { MiningDashboardComponent } from '../components/mining-dashboard/mining-dashboard.component';
|
||||
import { HashrateChartComponent } from '../components/hashrate-chart/hashrate-chart.component';
|
||||
import { HashrateChartPoolsComponent } from '../components/hashrates-chart-pools/hashrate-chart-pools.component';
|
||||
import { BlockPredictionsGraphComponent } from '../components/block-predictions-graph/block-predictions-graph.component';
|
||||
import { BlockPredictionGraphComponent } from '../components/block-prediction-graph/block-prediction-graph.component';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
@NgModule({
|
||||
@@ -48,7 +48,7 @@ import { CommonModule } from '@angular/common';
|
||||
LbtcPegsGraphComponent,
|
||||
HashrateChartComponent,
|
||||
HashrateChartPoolsComponent,
|
||||
BlockPredictionsGraphComponent,
|
||||
BlockPredictionGraphComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
import { BlockPredictionsGraphComponent } from '../components/block-predictions-graph/block-predictions-graph.component';
|
||||
import { BlockPredictionGraphComponent } from '../components/block-prediction-graph/block-prediction-graph.component';
|
||||
import { BlockFeeRatesGraphComponent } from '../components/block-fee-rates-graph/block-fee-rates-graph.component';
|
||||
import { BlockFeesGraphComponent } from '../components/block-fees-graph/block-fees-graph.component';
|
||||
import { BlockRewardsGraphComponent } from '../components/block-rewards-graph/block-rewards-graph.component';
|
||||
@@ -94,8 +94,8 @@ const routes: Routes = [
|
||||
redirectTo: 'mempool',
|
||||
},
|
||||
{
|
||||
path: 'mining/block-predictions',
|
||||
component: BlockPredictionsGraphComponent,
|
||||
path: 'mining/block-prediction',
|
||||
component: BlockPredictionGraphComponent,
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user