mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Make CardStats a separate component
This commit is contained in:
parent
1d63253b4f
commit
4b5ea6c110
2 changed files with 116 additions and 102 deletions
|
@ -3,108 +3,16 @@ Copyright: Ankitects Pty Ltd and contributors
|
|||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="ts">
|
||||
import * as tr2 from "../lib/ftl";
|
||||
import { Stats, unwrapOptionalNumber } from "../lib/proto";
|
||||
import { Timestamp, timeSpan, DAY } from "../lib/time";
|
||||
import type { Stats } from "../lib/proto";
|
||||
import CardStats from "./CardStats.svelte";
|
||||
import Revlog from "./Revlog.svelte";
|
||||
|
||||
export let stats: Stats.CardStatsResponse;
|
||||
|
||||
function dateString(timestamp: number): string {
|
||||
return new Timestamp(timestamp).dateString();
|
||||
}
|
||||
|
||||
interface StatsRow {
|
||||
label: string;
|
||||
value: string | number;
|
||||
}
|
||||
|
||||
function rowsFromStats(stats: Stats.CardStatsResponse): StatsRow[] {
|
||||
const statsRows: StatsRow[] = [];
|
||||
|
||||
statsRows.push({ label: tr2.cardStatsAdded(), value: dateString(stats.added) });
|
||||
|
||||
const firstReview = unwrapOptionalNumber(stats.firstReview);
|
||||
if (firstReview !== undefined) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsFirstReview(),
|
||||
value: dateString(firstReview),
|
||||
});
|
||||
}
|
||||
const latestReview = unwrapOptionalNumber(stats.latestReview);
|
||||
if (latestReview !== undefined) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsLatestReview(),
|
||||
value: dateString(latestReview),
|
||||
});
|
||||
}
|
||||
|
||||
const dueDate = unwrapOptionalNumber(stats.dueDate);
|
||||
if (dueDate !== undefined) {
|
||||
statsRows.push({
|
||||
label: tr2.statisticsDueDate(),
|
||||
value: dateString(dueDate),
|
||||
});
|
||||
}
|
||||
const duePosition = unwrapOptionalNumber(stats.duePosition);
|
||||
if (duePosition !== undefined) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsNewCardPosition(),
|
||||
value: dateString(duePosition),
|
||||
});
|
||||
}
|
||||
|
||||
if (stats.interval) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsInterval(),
|
||||
value: timeSpan(stats.interval * DAY),
|
||||
});
|
||||
}
|
||||
if (stats.ease) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsEase(),
|
||||
value: `${stats.ease / 10}%`,
|
||||
});
|
||||
}
|
||||
|
||||
statsRows.push({ label: tr2.cardStatsReviewCount(), value: stats.reviews });
|
||||
statsRows.push({ label: tr2.cardStatsLapseCount(), value: stats.lapses });
|
||||
|
||||
if (stats.totalSecs) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsAverageTime(),
|
||||
value: timeSpan(stats.averageSecs),
|
||||
});
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsTotalTime(),
|
||||
value: timeSpan(stats.totalSecs),
|
||||
});
|
||||
}
|
||||
|
||||
statsRows.push({ label: tr2.cardStatsCardTemplate(), value: stats.cardType });
|
||||
statsRows.push({ label: tr2.cardStatsNoteType(), value: stats.notetype });
|
||||
statsRows.push({ label: tr2.cardStatsDeckName(), value: stats.deck });
|
||||
|
||||
statsRows.push({ label: tr2.cardStatsCardId(), value: stats.cardId });
|
||||
statsRows.push({ label: tr2.cardStatsNoteId(), value: stats.noteId });
|
||||
|
||||
return statsRows;
|
||||
}
|
||||
|
||||
let statsRows: StatsRow[];
|
||||
$: statsRows = rowsFromStats(stats);
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div>
|
||||
<table class="stats-table">
|
||||
{#each statsRows as row, _index}
|
||||
<tr>
|
||||
<th style="text-align:start">{row.label}</th>
|
||||
<td>{row.value}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</table>
|
||||
<CardStats {stats} />
|
||||
<Revlog {stats} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -113,11 +21,4 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
.container {
|
||||
max-width: 40em;
|
||||
}
|
||||
|
||||
.stats-table {
|
||||
width: 100%;
|
||||
border-spacing: 1em 0;
|
||||
border-collapse: collapse;
|
||||
text-align: start;
|
||||
}
|
||||
</style>
|
||||
|
|
113
ts/card-info/CardStats.svelte
Normal file
113
ts/card-info/CardStats.svelte
Normal file
|
@ -0,0 +1,113 @@
|
|||
<!--
|
||||
Copyright: Ankitects Pty Ltd and contributors
|
||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="ts">
|
||||
import * as tr2 from "../lib/ftl";
|
||||
import { Stats, unwrapOptionalNumber } from "../lib/proto";
|
||||
import { Timestamp, timeSpan, DAY } from "../lib/time";
|
||||
|
||||
export let stats: Stats.CardStatsResponse;
|
||||
|
||||
function dateString(timestamp: number): string {
|
||||
return new Timestamp(timestamp).dateString();
|
||||
}
|
||||
|
||||
interface StatsRow {
|
||||
label: string;
|
||||
value: string | number;
|
||||
}
|
||||
|
||||
function rowsFromStats(stats: Stats.CardStatsResponse): StatsRow[] {
|
||||
const statsRows: StatsRow[] = [];
|
||||
|
||||
statsRows.push({ label: tr2.cardStatsAdded(), value: dateString(stats.added) });
|
||||
|
||||
const firstReview = unwrapOptionalNumber(stats.firstReview);
|
||||
if (firstReview !== undefined) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsFirstReview(),
|
||||
value: dateString(firstReview),
|
||||
});
|
||||
}
|
||||
const latestReview = unwrapOptionalNumber(stats.latestReview);
|
||||
if (latestReview !== undefined) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsLatestReview(),
|
||||
value: dateString(latestReview),
|
||||
});
|
||||
}
|
||||
|
||||
const dueDate = unwrapOptionalNumber(stats.dueDate);
|
||||
if (dueDate !== undefined) {
|
||||
statsRows.push({
|
||||
label: tr2.statisticsDueDate(),
|
||||
value: dateString(dueDate),
|
||||
});
|
||||
}
|
||||
const duePosition = unwrapOptionalNumber(stats.duePosition);
|
||||
if (duePosition !== undefined) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsNewCardPosition(),
|
||||
value: dateString(duePosition),
|
||||
});
|
||||
}
|
||||
|
||||
if (stats.interval) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsInterval(),
|
||||
value: timeSpan(stats.interval * DAY),
|
||||
});
|
||||
}
|
||||
if (stats.ease) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsEase(),
|
||||
value: `${stats.ease / 10}%`,
|
||||
});
|
||||
}
|
||||
|
||||
statsRows.push({ label: tr2.cardStatsReviewCount(), value: stats.reviews });
|
||||
statsRows.push({ label: tr2.cardStatsLapseCount(), value: stats.lapses });
|
||||
|
||||
if (stats.totalSecs) {
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsAverageTime(),
|
||||
value: timeSpan(stats.averageSecs),
|
||||
});
|
||||
statsRows.push({
|
||||
label: tr2.cardStatsTotalTime(),
|
||||
value: timeSpan(stats.totalSecs),
|
||||
});
|
||||
}
|
||||
|
||||
statsRows.push({ label: tr2.cardStatsCardTemplate(), value: stats.cardType });
|
||||
statsRows.push({ label: tr2.cardStatsNoteType(), value: stats.notetype });
|
||||
statsRows.push({ label: tr2.cardStatsDeckName(), value: stats.deck });
|
||||
|
||||
statsRows.push({ label: tr2.cardStatsCardId(), value: stats.cardId });
|
||||
statsRows.push({ label: tr2.cardStatsNoteId(), value: stats.noteId });
|
||||
|
||||
return statsRows;
|
||||
}
|
||||
|
||||
let statsRows: StatsRow[];
|
||||
$: statsRows = rowsFromStats(stats);
|
||||
</script>
|
||||
|
||||
<table class="stats-table">
|
||||
{#each statsRows as row, _index}
|
||||
<tr>
|
||||
<th style="text-align:start">{row.label}</th>
|
||||
<td>{row.value}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</table>
|
||||
|
||||
<style>
|
||||
.stats-table {
|
||||
width: 100%;
|
||||
border-spacing: 1em 0;
|
||||
border-collapse: collapse;
|
||||
text-align: start;
|
||||
}
|
||||
</style>
|
Loading…
Reference in a new issue