mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-31 21:48:32 +01:00
Format Server/Network Overview values in the frontend
This commit is contained in:
parent
f9d2b0767f
commit
8e94d26ff3
@ -16,7 +16,6 @@
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.rendering.json;
|
||||
|
||||
import com.djrapitops.plan.delivery.domain.DateHolder;
|
||||
import com.djrapitops.plan.delivery.domain.DateObj;
|
||||
import com.djrapitops.plan.delivery.domain.mutators.TPSMutator;
|
||||
import com.djrapitops.plan.delivery.formatting.Formatter;
|
||||
@ -55,17 +54,14 @@ import java.util.concurrent.TimeUnit;
|
||||
@Singleton
|
||||
public class ServerOverviewJSONCreator implements ServerTabJSONCreator<Map<String, Object>> {
|
||||
|
||||
private final Formatter<Long> day;
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final ServerInfo serverInfo;
|
||||
private final ServerSensor<?> serverSensor;
|
||||
|
||||
private final Formatter<Long> timeAmount;
|
||||
private final Formatter<Double> decimals;
|
||||
private final Formatter<Double> percentage;
|
||||
private final ServerUptimeCalculator serverUptimeCalculator;
|
||||
private final Formatter<DateHolder> year;
|
||||
|
||||
@Inject
|
||||
public ServerOverviewJSONCreator(
|
||||
@ -82,9 +78,6 @@ public class ServerOverviewJSONCreator implements ServerTabJSONCreator<Map<Strin
|
||||
this.serverSensor = serverSensor;
|
||||
this.serverUptimeCalculator = serverUptimeCalculator;
|
||||
|
||||
year = formatters.year();
|
||||
day = formatters.dayLong();
|
||||
timeAmount = formatters.timeAmount();
|
||||
decimals = formatters.decimals();
|
||||
percentage = formatters.percentage();
|
||||
}
|
||||
@ -118,7 +111,7 @@ public class ServerOverviewJSONCreator implements ServerTabJSONCreator<Map<Strin
|
||||
double averageTPS = tpsMutator.averageTPS();
|
||||
sevenDays.put("average_tps", averageTPS != -1 ? decimals.apply(averageTPS) : GenericLang.UNAVAILABLE.getKey());
|
||||
sevenDays.put("low_tps_spikes", tpsMutator.lowTpsSpikeCount(config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED)));
|
||||
sevenDays.put("downtime", timeAmount.apply(tpsMutator.serverDownTime()));
|
||||
sevenDays.put("downtime", tpsMutator.serverDownTime());
|
||||
|
||||
return sevenDays;
|
||||
}
|
||||
@ -137,18 +130,19 @@ public class ServerOverviewJSONCreator implements ServerTabJSONCreator<Map<Strin
|
||||
numbers.put("online_players", getOnlinePlayers(serverUUID, db));
|
||||
Optional<DateObj<Integer>> lastPeak = db.query(TPSQueries.fetchPeakPlayerCount(serverUUID, twoDaysAgo));
|
||||
Optional<DateObj<Integer>> allTimePeak = db.query(TPSQueries.fetchAllTimePeakPlayerCount(serverUUID));
|
||||
numbers.put("last_peak_date", lastPeak.map(year).orElse("-"));
|
||||
numbers.put("last_peak_date", lastPeak.map(DateObj::getDate).map(Object.class::cast).orElse("-"));
|
||||
numbers.put("last_peak_players", lastPeak.map(dateObj -> dateObj.getValue().toString()).orElse("-"));
|
||||
numbers.put("best_peak_date", allTimePeak.map(year).orElse("-"));
|
||||
numbers.put("best_peak_date", allTimePeak.map(DateObj::getDate).map(Object.class::cast).orElse("-"));
|
||||
numbers.put("best_peak_players", allTimePeak.map(dateObj -> dateObj.getValue().toString()).orElse("-"));
|
||||
Long totalPlaytime = db.query(SessionQueries.playtime(0L, now, serverUUID));
|
||||
numbers.put("playtime", timeAmount.apply(totalPlaytime));
|
||||
numbers.put("player_playtime", userCount != 0 ? timeAmount.apply(totalPlaytime / userCount) : "-");
|
||||
numbers.put("playtime", totalPlaytime);
|
||||
numbers.put("player_playtime", userCount != 0 ? totalPlaytime / userCount : "-");
|
||||
numbers.put("sessions", db.query(SessionQueries.sessionCount(0L, now, serverUUID)));
|
||||
numbers.put("player_kills", db.query(KillQueries.playerKillCount(0L, now, serverUUID)));
|
||||
numbers.put("mob_kills", db.query(KillQueries.mobKillCount(0L, now, serverUUID)));
|
||||
numbers.put("deaths", db.query(KillQueries.deathCount(0L, now, serverUUID)));
|
||||
numbers.put("current_uptime", serverUptimeCalculator.getServerUptimeMillis(serverUUID).map(timeAmount)
|
||||
numbers.put("current_uptime", serverUptimeCalculator.getServerUptimeMillis(serverUUID)
|
||||
.map(Object.class::cast)
|
||||
.orElse(GenericLang.UNAVAILABLE.getKey()));
|
||||
|
||||
return numbers;
|
||||
@ -171,9 +165,9 @@ public class ServerOverviewJSONCreator implements ServerTabJSONCreator<Map<Strin
|
||||
|
||||
Map<String, Object> weeks = new HashMap<>();
|
||||
|
||||
weeks.put("start", day.apply(twoWeeksAgo));
|
||||
weeks.put("midpoint", day.apply(oneWeekAgo));
|
||||
weeks.put("end", day.apply(now));
|
||||
weeks.put("start", twoWeeksAgo);
|
||||
weeks.put("midpoint", oneWeekAgo);
|
||||
weeks.put("end", now);
|
||||
|
||||
Integer uniqueBefore = db.query(PlayerCountQueries.uniquePlayerCount(twoWeeksAgo, oneWeekAgo, serverUUID));
|
||||
Integer uniqueAfter = db.query(PlayerCountQueries.uniquePlayerCount(oneWeekAgo, now, serverUUID));
|
||||
@ -199,9 +193,9 @@ public class ServerOverviewJSONCreator implements ServerTabJSONCreator<Map<Strin
|
||||
Long playtimeAfter = db.query(SessionQueries.playtime(oneWeekAgo, now, serverUUID));
|
||||
long avgPlaytimeBefore = uniqueBefore != 0 ? playtimeBefore / uniqueBefore : 0L;
|
||||
long avgPlaytimeAfter = uniqueAfter != 0 ? playtimeAfter / uniqueAfter : 0L;
|
||||
Trend avgPlaytimeTrend = new Trend(avgPlaytimeBefore, avgPlaytimeAfter, false, timeAmount);
|
||||
weeks.put("average_playtime_before", timeAmount.apply(avgPlaytimeBefore));
|
||||
weeks.put("average_playtime_after", timeAmount.apply(avgPlaytimeAfter));
|
||||
Trend avgPlaytimeTrend = new Trend(avgPlaytimeBefore, avgPlaytimeAfter, false);
|
||||
weeks.put("average_playtime_before", avgPlaytimeBefore);
|
||||
weeks.put("average_playtime_after", avgPlaytimeAfter);
|
||||
weeks.put("average_playtime_trend", avgPlaytimeTrend);
|
||||
|
||||
Long sessionsBefore = db.query(SessionQueries.sessionCount(twoWeeksAgo, oneWeekAgo, serverUUID));
|
||||
|
@ -16,9 +16,7 @@
|
||||
*/
|
||||
package com.djrapitops.plan.delivery.rendering.json.network;
|
||||
|
||||
import com.djrapitops.plan.delivery.domain.DateHolder;
|
||||
import com.djrapitops.plan.delivery.domain.DateObj;
|
||||
import com.djrapitops.plan.delivery.formatting.Formatter;
|
||||
import com.djrapitops.plan.delivery.formatting.Formatters;
|
||||
import com.djrapitops.plan.delivery.rendering.json.Trend;
|
||||
import com.djrapitops.plan.gathering.ServerSensor;
|
||||
@ -50,14 +48,11 @@ import java.util.concurrent.TimeUnit;
|
||||
@Singleton
|
||||
public class NetworkOverviewJSONCreator implements NetworkTabJSONCreator<Map<String, Object>> {
|
||||
|
||||
private final Formatter<Long> day;
|
||||
private final PlanConfig config;
|
||||
private final DBSystem dbSystem;
|
||||
private final ServerInfo serverInfo;
|
||||
private final ServerSensor<?> serverSensor;
|
||||
private final Formatter<Long> timeAmount;
|
||||
private final ServerUptimeCalculator serverUptimeCalculator;
|
||||
private final Formatter<DateHolder> year;
|
||||
|
||||
@Inject
|
||||
public NetworkOverviewJSONCreator(
|
||||
@ -73,10 +68,6 @@ public class NetworkOverviewJSONCreator implements NetworkTabJSONCreator<Map<Str
|
||||
this.serverInfo = serverInfo;
|
||||
this.serverSensor = serverSensor;
|
||||
this.serverUptimeCalculator = serverUptimeCalculator;
|
||||
|
||||
year = formatters.year();
|
||||
day = formatters.dayLong();
|
||||
timeAmount = formatters.timeAmount();
|
||||
}
|
||||
|
||||
public Map<String, Object> createJSONAsMap() {
|
||||
@ -122,17 +113,18 @@ public class NetworkOverviewJSONCreator implements NetworkTabJSONCreator<Map<Str
|
||||
ServerUUID serverUUID = serverInfo.getServerUUID();
|
||||
Optional<DateObj<Integer>> lastPeak = db.query(TPSQueries.fetchPeakPlayerCount(serverUUID, twoDaysAgo));
|
||||
Optional<DateObj<Integer>> allTimePeak = db.query(TPSQueries.fetchAllTimePeakPlayerCount(serverUUID));
|
||||
numbers.put("last_peak_date", lastPeak.map(year).orElse("-"));
|
||||
numbers.put("last_peak_date", lastPeak.map(DateObj::getDate).map(Object.class::cast).orElse("-"));
|
||||
numbers.put("last_peak_players", lastPeak.map(dateObj -> dateObj.getValue().toString()).orElse("-"));
|
||||
numbers.put("best_peak_date", allTimePeak.map(year).orElse("-"));
|
||||
numbers.put("best_peak_date", allTimePeak.map(DateObj::getDate).map(Object.class::cast).orElse("-"));
|
||||
numbers.put("best_peak_players", allTimePeak.map(dateObj -> dateObj.getValue().toString()).orElse("-"));
|
||||
Long totalPlaytime = db.query(SessionQueries.playtime(0L, now));
|
||||
numbers.put("playtime", timeAmount.apply(totalPlaytime));
|
||||
numbers.put("player_playtime", userCount != 0 ? timeAmount.apply(totalPlaytime / userCount) : "-");
|
||||
numbers.put("playtime", totalPlaytime);
|
||||
numbers.put("player_playtime", userCount != 0 ? totalPlaytime / userCount : "-");
|
||||
Long sessionCount = db.query(SessionQueries.sessionCount(0L, now));
|
||||
numbers.put("sessions", sessionCount);
|
||||
numbers.put("session_length_avg", sessionCount != 0 ? timeAmount.apply(totalPlaytime / sessionCount) : "-");
|
||||
numbers.put("current_uptime", serverUptimeCalculator.getServerUptimeMillis(serverUUID).map(timeAmount)
|
||||
numbers.put("session_length_avg", sessionCount != 0 ? totalPlaytime / sessionCount : "-");
|
||||
numbers.put("current_uptime", serverUptimeCalculator.getServerUptimeMillis(serverUUID)
|
||||
.map(Object.class::cast)
|
||||
.orElse(GenericLang.UNAVAILABLE.getKey()));
|
||||
|
||||
return numbers;
|
||||
@ -147,9 +139,9 @@ public class NetworkOverviewJSONCreator implements NetworkTabJSONCreator<Map<Str
|
||||
|
||||
Map<String, Object> weeks = new HashMap<>();
|
||||
|
||||
weeks.put("start", day.apply(twoWeeksAgo));
|
||||
weeks.put("midpoint", day.apply(oneWeekAgo));
|
||||
weeks.put("end", day.apply(now));
|
||||
weeks.put("start", twoWeeksAgo);
|
||||
weeks.put("midpoint", oneWeekAgo);
|
||||
weeks.put("end", now);
|
||||
|
||||
Integer uniqueBefore = db.query(PlayerCountQueries.uniquePlayerCount(twoWeeksAgo, oneWeekAgo));
|
||||
Integer uniqueAfter = db.query(PlayerCountQueries.uniquePlayerCount(oneWeekAgo, now));
|
||||
@ -175,9 +167,9 @@ public class NetworkOverviewJSONCreator implements NetworkTabJSONCreator<Map<Str
|
||||
Long playtimeAfter = db.query(SessionQueries.playtime(oneWeekAgo, now));
|
||||
long avgPlaytimeBefore = uniqueBefore != 0 ? playtimeBefore / uniqueBefore : 0L;
|
||||
long avgPlaytimeAfter = uniqueAfter != 0 ? playtimeAfter / uniqueAfter : 0L;
|
||||
Trend avgPlaytimeTrend = new Trend(avgPlaytimeBefore, avgPlaytimeAfter, false, timeAmount);
|
||||
weeks.put("average_playtime_before", timeAmount.apply(avgPlaytimeBefore));
|
||||
weeks.put("average_playtime_after", timeAmount.apply(avgPlaytimeAfter));
|
||||
Trend avgPlaytimeTrend = new Trend(avgPlaytimeBefore, avgPlaytimeAfter, false);
|
||||
weeks.put("average_playtime_before", avgPlaytimeBefore);
|
||||
weeks.put("average_playtime_after", avgPlaytimeAfter);
|
||||
weeks.put("average_playtime_trend", avgPlaytimeTrend);
|
||||
|
||||
Long sessionsBefore = db.query(SessionQueries.sessionCount(twoWeeksAgo, oneWeekAgo));
|
||||
@ -189,9 +181,9 @@ public class NetworkOverviewJSONCreator implements NetworkTabJSONCreator<Map<Str
|
||||
|
||||
long avgSessionLengthBefore = sessionsBefore != 0 ? playtimeBefore / sessionsBefore : 0;
|
||||
long avgSessionLengthAfter = sessionsAfter != 0 ? playtimeAfter / sessionsAfter : 0;
|
||||
Trend avgSessionLengthTrend = new Trend(avgSessionLengthBefore, avgSessionLengthAfter, false, timeAmount);
|
||||
weeks.put("session_length_average_before", timeAmount.apply(avgSessionLengthBefore));
|
||||
weeks.put("session_length_average_after", timeAmount.apply(avgSessionLengthAfter));
|
||||
Trend avgSessionLengthTrend = new Trend(avgSessionLengthBefore, avgSessionLengthAfter, false);
|
||||
weeks.put("session_length_average_before", avgSessionLengthBefore);
|
||||
weeks.put("session_length_average_after", avgSessionLengthAfter);
|
||||
weeks.put("session_length_average_trend", avgSessionLengthTrend);
|
||||
|
||||
return weeks;
|
||||
|
@ -8,6 +8,8 @@ import {faCalendarCheck, faClock} from "@fortawesome/free-regular-svg-icons";
|
||||
import React from "react";
|
||||
import {TableRow} from "../../../table/TableRow";
|
||||
import {CardLoader} from "../../../navigation/Loader";
|
||||
import FormattedDay from "../../../text/FormattedDay.jsx";
|
||||
import FormattedTime, {formatTimeFunction} from "../../../text/FormattedTime.jsx";
|
||||
|
||||
const ServerWeekComparisonCard = ({data}) => {
|
||||
const {t} = useTranslation();
|
||||
@ -20,11 +22,18 @@ const ServerWeekComparisonCard = ({data}) => {
|
||||
</h6>
|
||||
</Card.Header>
|
||||
<ComparisonTable comparisonHeader={t('html.label.comparing7days')}
|
||||
headers={[data.start + ' - ' + data.midpoint, data.midpoint + ' - ' + data.end, t('html.label.trend')]}>
|
||||
<TableRow icon={faUsers} color="blue" text={t('html.label.uniquePlayers')}
|
||||
values={[data.unique_before, data.unique_after,
|
||||
headers={[
|
||||
<><FormattedDay date={data.start}/> - <FormattedDay date={data.midpoint}/></>,
|
||||
<><FormattedDay date={data.midpoint}/> - <FormattedDay date={data.end}/></>,
|
||||
t('html.label.trend')]}>
|
||||
<TableRow icon={faUsers} color="blue"
|
||||
text={t('html.label.uniquePlayers')}
|
||||
values={[
|
||||
data.unique_before,
|
||||
data.unique_after,
|
||||
<BigTrend key={JSON.stringify(data.unique_trend)}
|
||||
trend={data.unique_trend}/>]}/>
|
||||
trend={data.unique_trend}/>
|
||||
]}/>
|
||||
<TableRow icon={faUsers} color="light-green" text={t('html.label.newPlayers')}
|
||||
values={[data.new_before, data.new_after,
|
||||
<BigTrend key={JSON.stringify(data.new_trend)}
|
||||
@ -35,14 +44,20 @@ const ServerWeekComparisonCard = ({data}) => {
|
||||
trend={data.regular_trend}/>]}/>
|
||||
<TableRow icon={faClock} color="green"
|
||||
text={t('html.label.averagePlaytime') + ' ' + t('html.label.perPlayer')}
|
||||
values={[data.average_playtime_before, data.average_playtime_after,
|
||||
values={[
|
||||
<FormattedTime key={"before-ms"} timeMs={data.average_playtime_before}/>,
|
||||
<FormattedTime key={"after-ms"} timeMs={data.average_playtime_after}/>,
|
||||
<BigTrend key={JSON.stringify(data.average_playtime_trend)}
|
||||
trend={data.average_playtime_trend}/>]}/>
|
||||
<TableRow icon={faClock} color="teal"
|
||||
text={t('html.label.averageSessionLength')}
|
||||
values={[data.session_length_average_before, data.session_length_average_after,
|
||||
<BigTrend key={JSON.stringify(data.session_length_average_trend)}
|
||||
trend={data.session_length_average_trend}/>]}/>
|
||||
trend={data.average_playtime_trend}
|
||||
format={formatTimeFunction}/>]}/>
|
||||
{data.session_length_average_before !== undefined && <TableRow
|
||||
icon={faClock} color="teal"
|
||||
text={t('html.label.averageSessionLength')}
|
||||
values={[<FormattedTime key={"before-ms"} timeMs={data.session_length_average_before}/>,
|
||||
<FormattedTime key={"after-ms"} timeMs={data.session_length_average_after}/>,
|
||||
<BigTrend key={JSON.stringify(data.session_length_average_trend)}
|
||||
trend={data.session_length_average_trend}
|
||||
format={formatTimeFunction}/>]}/>}
|
||||
<TableRow icon={faCalendarCheck} color="teal" text={t('html.label.sessions')}
|
||||
values={[data.sessions_before, data.sessions_after,
|
||||
<BigTrend key={JSON.stringify(data.sessions_trend)}
|
||||
|
@ -9,6 +9,8 @@ import {CardLoader} from "../../../navigation/Loader";
|
||||
import ExtendableCardBody from "../../../layout/extension/ExtendableCardBody";
|
||||
import {useMetadata} from "../../../../hooks/metadataHook";
|
||||
import CurrentUptime from "../../../datapoint/CurrentUptime";
|
||||
import FormattedTime from "../../../text/FormattedTime.jsx";
|
||||
import FormattedDate from "../../../text/FormattedDate.jsx";
|
||||
|
||||
const ServerAsNumbersCard = ({data}) => {
|
||||
const {t} = useTranslation();
|
||||
@ -40,23 +42,23 @@ const ServerAsNumbersCard = ({data}) => {
|
||||
value={data.online_players} bold/>
|
||||
{showPeaks && <>
|
||||
<hr/>
|
||||
<Datapoint name={t('html.label.lastPeak') + ' (' + data.last_peak_date + ')'}
|
||||
<Datapoint name={<>{t('html.label.lastPeak')} (<FormattedDate date={data.last_peak_date}/>)</>}
|
||||
color={'blue'} icon={faChartLine}
|
||||
value={data.last_peak_players} valueLabel={t('html.unit.players')} bold/>
|
||||
<Datapoint name={t('html.label.bestPeak') + ' (' + data.best_peak_date + ')'}
|
||||
<Datapoint name={<>{t('html.label.bestPeak')} (<FormattedDate date={data.best_peak_date}/>)</>}
|
||||
color={'light-green'} icon={faChartLine}
|
||||
value={data.best_peak_players} valueLabel={t('html.unit.players')} bold/>
|
||||
</>}
|
||||
<hr/>
|
||||
<Datapoint name={t('html.label.totalPlaytime')}
|
||||
color={'green'} icon={faClock}
|
||||
value={data.playtime}/>
|
||||
value={<FormattedTime timeMs={data.playtime}/>}/>
|
||||
<Datapoint name={t('html.label.averagePlaytime') + ' ' + t('html.label.perPlayer')}
|
||||
color={'green'} icon={faClock}
|
||||
value={data.player_playtime}/>
|
||||
value={<FormattedTime timeMs={data.player_playtime}/>}/>
|
||||
<Datapoint name={t('html.label.averageSessionLength')}
|
||||
color={'teal'} icon={faClock}
|
||||
value={data.session_length_avg}/>
|
||||
value={<FormattedTime timeMs={data.session_length_avg}/>}/>
|
||||
<Datapoint name={t('html.label.sessions')}
|
||||
color={'teal'} icon={faCalendarCheck}
|
||||
value={data.sessions} bold/>
|
||||
|
@ -4,6 +4,8 @@ import {faPowerOff} from "@fortawesome/free-solid-svg-icons";
|
||||
import {faQuestionCircle} from "@fortawesome/free-regular-svg-icons";
|
||||
import Datapoint from "../Datapoint";
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
import FormattedTime from "../text/FormattedTime.jsx";
|
||||
import {isNumber} from "../../util/isNumber.js";
|
||||
|
||||
const CurrentUptime = ({uptime}) => {
|
||||
const {t} = useTranslation();
|
||||
@ -15,7 +17,7 @@ const CurrentUptime = ({uptime}) => {
|
||||
return (
|
||||
<Datapoint icon={faPowerOff} color={'light-green'}
|
||||
name={t('html.label.currentUptime')}
|
||||
value={uptime} valueLabel={infoBubble}/>
|
||||
value={isNumber(uptime) && <FormattedTime timeMs={uptime}/> || uptime} valueLabel={infoBubble}/>
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -3,13 +3,16 @@ import {usePreferences} from "../../hooks/preferencesHook";
|
||||
import {SimpleDateFormat} from "../../util/format/SimpleDateFormat";
|
||||
import {useMetadata} from "../../hooks/metadataHook";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {isNumber} from "../../util/isNumber.js";
|
||||
|
||||
const FormattedDate = ({date}) => {
|
||||
console.log(date);
|
||||
const {t} = useTranslation();
|
||||
const {timeZoneOffsetHours} = useMetadata();
|
||||
const {preferencesLoaded, dateFormatNoSeconds, recentDaysInDateFormat} = usePreferences();
|
||||
|
||||
if (!preferencesLoaded || date === undefined || date === null) return <></>
|
||||
if (!preferencesLoaded || date === undefined || date === null) return <></>;
|
||||
if (!isNumber(date)) return date;
|
||||
|
||||
const pattern = dateFormatNoSeconds;
|
||||
const recentDays = recentDaysInDateFormat;
|
||||
|
24
Plan/react/dashboard/src/components/text/FormattedDay.jsx
Normal file
24
Plan/react/dashboard/src/components/text/FormattedDay.jsx
Normal file
@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import {SimpleDateFormat} from "../../util/format/SimpleDateFormat";
|
||||
import {useMetadata} from "../../hooks/metadataHook";
|
||||
import {isNumber} from "../../util/isNumber.js";
|
||||
|
||||
const FormattedDay = ({date}) => {
|
||||
const {timeZoneOffsetHours} = useMetadata();
|
||||
|
||||
if (date === undefined || date === null) return <></>;
|
||||
if (!isNumber(date)) return date;
|
||||
|
||||
const pattern = "MMMMM d";
|
||||
|
||||
const offset = timeZoneOffsetHours * 60 * 60 * 1000;
|
||||
const timestamp = date - offset;
|
||||
|
||||
const formatted = date !== 0 ? new SimpleDateFormat(pattern).format(timestamp) : '-';
|
||||
|
||||
return (
|
||||
<>{formatted}</>
|
||||
)
|
||||
};
|
||||
|
||||
export default FormattedDay
|
@ -1,11 +1,13 @@
|
||||
import React from 'react';
|
||||
import {usePreferences} from "../../hooks/preferencesHook";
|
||||
import {formatTimeAmount} from "../../util/format/TimeAmountFormat";
|
||||
import {isNumber} from "../../util/isNumber.js";
|
||||
|
||||
const FormattedTime = ({timeMs}) => {
|
||||
const {preferencesLoaded, timeFormat} = usePreferences();
|
||||
|
||||
if (!preferencesLoaded) return <></>
|
||||
if (!preferencesLoaded) return <></>;
|
||||
if (!isNumber(timeMs)) return timeMs;
|
||||
|
||||
const options = {
|
||||
YEAR: timeFormat.year,
|
||||
@ -26,4 +28,10 @@ const FormattedTime = ({timeMs}) => {
|
||||
)
|
||||
};
|
||||
|
||||
export const formatTimeFunction = time => {
|
||||
return (
|
||||
<FormattedTime timeMs={time}/>
|
||||
);
|
||||
}
|
||||
|
||||
export default FormattedTime
|
@ -9,17 +9,20 @@ const TrendDownGood = ({value}) => <span className="badge bg-success"><Fa icon={
|
||||
const TrendSame = ({value}) => <span className="badge bg-warning"><Fa icon={faCaretRight}/>{value}</span>;
|
||||
|
||||
|
||||
const BigTrend = ({trend}) => {
|
||||
const BigTrend = ({trend, format}) => {
|
||||
if (!trend) {
|
||||
return <TrendSame value={'?'}/>;
|
||||
}
|
||||
|
||||
const value = format ? format(trend.text) : trend.text;
|
||||
|
||||
switch (trend.direction) {
|
||||
case '+':
|
||||
return (trend.reversed ? <TrendUpBad value={trend.text}/> : <TrendUpGood value={trend.text}/>);
|
||||
return (trend.reversed ? <TrendUpBad value={trend.text}/> : <TrendUpGood value={value}/>);
|
||||
case '-':
|
||||
return (trend.reversed ? <TrendDownGood value={trend.text}/> : <TrendDownBad value={trend.text}/>);
|
||||
return (trend.reversed ? <TrendDownGood value={trend.text}/> : <TrendDownBad value={value}/>);
|
||||
default:
|
||||
return <TrendSame value={trend.text}/>;
|
||||
return <TrendSame value={value}/>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1505,4 +1505,14 @@ ul.filters {
|
||||
|
||||
.nav-item.disabled {
|
||||
opacity: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
.link {
|
||||
color: var(--bs-link-color);
|
||||
opacity: var(--bs-link-opacity);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
color: var(--bs-link-hover-color)
|
||||
}
|
||||
|
4
Plan/react/dashboard/src/util/isNumber.js
Normal file
4
Plan/react/dashboard/src/util/isNumber.js
Normal file
@ -0,0 +1,4 @@
|
||||
// https://stackoverflow.com/a/1421988/20825073
|
||||
export function isNumber(n) {
|
||||
return !isNaN(parseFloat(n)) && !isNaN(n - 0)
|
||||
}
|
@ -23,6 +23,7 @@ import {CardLoader} from "../../components/navigation/Loader";
|
||||
import ExtendableRow from "../../components/layout/extension/ExtendableRow";
|
||||
import {useAuth} from "../../hooks/authenticationHook";
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
import FormattedTime from "../../components/text/FormattedTime.jsx";
|
||||
|
||||
const Last7DaysCard = ({data}) => {
|
||||
const {t} = useTranslation();
|
||||
@ -64,7 +65,7 @@ const Last7DaysCard = ({data}) => {
|
||||
value={data.low_tps_spikes} bold/>
|
||||
<Datapoint name={t('html.label.downtime')}
|
||||
color={'red'} icon={faPowerOff}
|
||||
value={data.downtime}/>
|
||||
value={<FormattedTime timeMs={data.downtime}/>}/>
|
||||
</Card.Body>
|
||||
</Card>
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user