mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-04-24 05:47:22 -04:00
New: Summary Stats
This commit is contained in:
parent
3dd3c80b54
commit
d7df946c2b
6 changed files with 120 additions and 3 deletions
|
@ -0,0 +1,20 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
|
||||
import RelativeDateCell from './RelativeDateCell';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createUISettingsSelector(),
|
||||
(uiSettings) => {
|
||||
return {
|
||||
showRelativeDates: uiSettings.showRelativeDates,
|
||||
shortDateFormat: uiSettings.shortDateFormat,
|
||||
longDateFormat: uiSettings.longDateFormat,
|
||||
timeFormat: uiSettings.timeFormat
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export default connect(createMapStateToProps, null)(RelativeDateCell);
|
|
@ -8,6 +8,11 @@
|
|||
width: 50%;
|
||||
}
|
||||
|
||||
.quarterWidthChart {
|
||||
display: inline-block;
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.chartContainer {
|
||||
margin: 5px;
|
||||
padding: 15px 25px;
|
||||
|
@ -16,12 +21,32 @@
|
|||
background-color: var(--chartBackgroundColor);
|
||||
}
|
||||
|
||||
.statContainer {
|
||||
margin: 5px;
|
||||
padding: 15px 25px;
|
||||
height: 150px;
|
||||
border-radius: 10px;
|
||||
background-color: var(--chartBackgroundColor);
|
||||
}
|
||||
|
||||
.statTitle {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.stat {
|
||||
font-weight: bold;
|
||||
font-size: 60px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $breakpointSmall) {
|
||||
.halfWidthChart {
|
||||
display: inline-block;
|
||||
margin: 5px;
|
||||
padding: 15px 25px;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.quarterWidthChart {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,10 @@ interface CssExports {
|
|||
'chartContainer': string;
|
||||
'fullWidthChart': string;
|
||||
'halfWidthChart': string;
|
||||
'quarterWidthChart': string;
|
||||
'stat': string;
|
||||
'statContainer': string;
|
||||
'statTitle': string;
|
||||
}
|
||||
export const cssExports: CssExports;
|
||||
export default cssExports;
|
||||
|
|
|
@ -24,6 +24,7 @@ import {
|
|||
IndexerStatsIndexer,
|
||||
IndexerStatsUserAgent,
|
||||
} from 'typings/IndexerStats';
|
||||
import abbreviateNumber from 'Utilities/Number/abbreviateNumber';
|
||||
import getErrorMessage from 'Utilities/Object/getErrorMessage';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import IndexerStatsFilterModal from './IndexerStatsFilterModal';
|
||||
|
@ -201,6 +202,16 @@ function IndexerStats() {
|
|||
);
|
||||
|
||||
const isLoaded = !error && isPopulated;
|
||||
const indexerCount = item.indexers?.length ?? 0;
|
||||
const userAgentCount = item.userAgents?.length ?? 0;
|
||||
const queryCount =
|
||||
item.indexers?.reduce((total, indexer) => {
|
||||
return total + indexer.numberOfQueries;
|
||||
}, 0) ?? 0;
|
||||
const grabCount =
|
||||
item.indexers?.reduce((total, indexer) => {
|
||||
return total + indexer.numberOfGrabs;
|
||||
}, 0) ?? 0;
|
||||
|
||||
return (
|
||||
<PageContent>
|
||||
|
@ -228,6 +239,40 @@ function IndexerStats() {
|
|||
|
||||
{isLoaded && (
|
||||
<div>
|
||||
<div className={styles.quarterWidthChart}>
|
||||
<div className={styles.statContainer}>
|
||||
<div className={styles.statTitle}>
|
||||
{translate('ActiveIndexers')}
|
||||
</div>
|
||||
<div className={styles.stat}>{indexerCount}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.quarterWidthChart}>
|
||||
<div className={styles.statContainer}>
|
||||
<div className={styles.statTitle}>
|
||||
{translate('TotalQueries')}
|
||||
</div>
|
||||
<div className={styles.stat}>
|
||||
{abbreviateNumber(queryCount)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.quarterWidthChart}>
|
||||
<div className={styles.statContainer}>
|
||||
<div className={styles.statTitle}>
|
||||
{translate('TotalGrabs')}
|
||||
</div>
|
||||
<div className={styles.stat}>{abbreviateNumber(grabCount)}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.quarterWidthChart}>
|
||||
<div className={styles.statContainer}>
|
||||
<div className={styles.statTitle}>
|
||||
{translate('ActiveApps')}
|
||||
</div>
|
||||
<div className={styles.stat}>{userAgentCount}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.fullWidthChart}>
|
||||
<div className={styles.chartContainer}>
|
||||
<BarChart
|
||||
|
|
19
frontend/src/Utilities/Number/abbreviateNumber.js
Normal file
19
frontend/src/Utilities/Number/abbreviateNumber.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
export default function abbreviateNumber(num, decimalPlaces) {
|
||||
if (num === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (num === 0) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
decimalPlaces = (!decimalPlaces || decimalPlaces < 0) ? 0 : decimalPlaces;
|
||||
|
||||
const b = (num).toPrecision(2).split('e');
|
||||
const k = b.length === 1 ? 0 : Math.floor(Math.min(b[1].slice(1), 14) / 3);
|
||||
const c = k < 1 ? num.toFixed(0 + decimalPlaces) : (num / Math.pow(10, k * 3) ).toFixed(1 + decimalPlaces);
|
||||
const d = c < 0 ? c : Math.abs(c);
|
||||
const e = d + ['', 'K', 'M', 'B', 'T'][k];
|
||||
|
||||
return e;
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
"About": "About",
|
||||
"AcceptConfirmationModal": "Accept Confirmation Modal",
|
||||
"Actions": "Actions",
|
||||
"ActiveIndexers": "Active Indexers",
|
||||
"ActiveApps": "Active Apps",
|
||||
"Add": "Add",
|
||||
"AddApplication": "Add Application",
|
||||
"AddApplicationImplementation": "Add Application - {implementationName}",
|
||||
|
@ -527,10 +529,12 @@
|
|||
"Torrent": "Torrent",
|
||||
"Torrents": "Torrents",
|
||||
"TorznabUrl": "Torznab Url",
|
||||
"TotalGrabs": "Total Grabs",
|
||||
"TotalHostGrabs": "Total Host Grabs",
|
||||
"TotalHostQueries": "Total Host Queries",
|
||||
"TotalIndexerQueries": "Total Indexer Queries",
|
||||
"TotalIndexerSuccessfulGrabs": "Total Indexer Successful Grabs",
|
||||
"TotalQueries": "Total Queries",
|
||||
"TotalUserAgentGrabs": "Total User Agent Grabs",
|
||||
"TotalUserAgentQueries": "Total User Agent Queries",
|
||||
"Track": "Track",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue