Skip to content

Commit aacf8ec

Browse files
Add help modal to TR table (#3874)
* Update TrueRetention.svelte adding description * Update statistics.ftl to add additional info * Swap TR with DR * Change string to 'Is expected to' * Add help modal to TR table * Add tooltip slot to Graph.svelte (thanks @Luc-Mcgrady) * Fix lint warning and failing test * Remove unused code * removedd on:mount to make eslint happy * ADD back on:mount * ADD back code needed for on:mount * REMOVE openHelpModal() as I couldn't figure out how to make the title clickable * attempt to ADD clickable title (BROKEN\!) * Update ts/lib/components/TitledContainer.svelte Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com> * Update ts/routes/graphs/Graph.svelte Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com> * Update ts/routes/graphs/TrueRetention.svelte Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com> * ADD exported onTitleClick as @Luc-Mcgrady suggested * REMOVE vite.config.ts file --------- Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com>
1 parent 79b19a1 commit aacf8ec

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed

ftl/core/statistics.ftl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ statistics-counts-separate-suspended-buried-cards = Separate suspended/buried ca
114114

115115
statistics-true-retention-title = True Retention
116116
statistics-true-retention-subtitle = Pass rate of cards with an interval ≥ 1 day.
117+
statistics-true-retention-tooltip = If you are using FSRS, your true retention is expected to be close to your desired retention. Please keep in mind that data for a single day is noisy, so it's better to look at monthly data.
117118
statistics-true-retention-range = Range
118119
statistics-true-retention-pass = Pass
119120
statistics-true-retention-fail = Fail

ts/lib/components/TitledContainer.svelte

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
1212
export { className as class };
1313
1414
export let title: string;
15+
export let onTitleClick: ((_e: MouseEvent | KeyboardEvent) => void) | null = null;
1516
</script>
1617

1718
<div
@@ -24,7 +25,22 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
2425
style:--container-margin="0"
2526
>
2627
<div class="position-relative">
27-
<h1>{title}</h1>
28+
{#if onTitleClick}
29+
<span
30+
on:click={onTitleClick}
31+
on:keydown={onTitleClick}
32+
role="button"
33+
tabindex="0"
34+
>
35+
<h1>
36+
{title}
37+
</h1>
38+
</span>
39+
{:else}
40+
<h1>
41+
{title}
42+
</h1>
43+
{/if}
2844
<div class="help-badge position-absolute" class:rtl>
2945
<slot name="tooltip" />
3046
</div>

ts/routes/graphs/Graph.svelte

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
88
// When title is null (default), the graph is inlined, not having TitledContainer wrapper.
99
export let title: string | null = null;
1010
export let subtitle: string | null = null;
11+
export let onTitleClick: ((_e: MouseEvent | KeyboardEvent) => void) | null = null;
1112
</script>
1213

1314
{#if title == null}
@@ -18,7 +19,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
1819
<slot />
1920
</div>
2021
{:else}
21-
<TitledContainer class="d-flex flex-column" {title}>
22+
<TitledContainer class="d-flex flex-column" {title} {onTitleClick}>
23+
<slot slot="tooltip" name="tooltip"></slot>
2224
<div class="graph d-flex flex-grow-1 flex-column justify-content-center">
2325
{#if subtitle}
2426
<div class="subtitle">{subtitle}</div>

ts/routes/graphs/TrueRetention.svelte

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
55
<script lang="ts">
66
import type { GraphsResponse } from "@generated/anki/stats_pb";
77
import * as tr from "@generated/ftl";
8+
import { HelpPage } from "@tslib/help-page";
9+
import HelpModal from "$lib/components/HelpModal.svelte";
10+
import type Carousel from "bootstrap/js/dist/carousel";
11+
import type Modal from "bootstrap/js/dist/modal";
12+
import type { HelpItem } from "$lib/components/types";
813
914
import { type RevlogRange } from "./graph-helpers";
1015
import { DisplayMode, type PeriodTrueRetentionData, Scope } from "./true-retention";
@@ -31,13 +36,43 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
3136
}
3237
});
3338
39+
const retentionHelp = {
40+
trueRetention: {
41+
title: tr.statisticsTrueRetentionTitle(),
42+
help: tr.statisticsTrueRetentionTooltip(),
43+
},
44+
};
45+
46+
const helpSections: HelpItem[] = Object.values(retentionHelp);
47+
48+
let modal: Modal;
49+
let carousel: Carousel;
50+
51+
function openHelpModal(index: number): void {
52+
modal.show();
53+
carousel.to(index);
54+
}
55+
3456
let mode: DisplayMode = $state(DisplayMode.Summary);
3557
3658
const title = tr.statisticsTrueRetentionTitle();
3759
const subtitle = tr.statisticsTrueRetentionSubtitle();
60+
const onTitleClick = () => {
61+
openHelpModal(Object.keys(retentionHelp).indexOf("trueRetention"));
62+
};
3863
</script>
3964

40-
<Graph {title} {subtitle}>
65+
<Graph {title} {subtitle} {onTitleClick}>
66+
<HelpModal
67+
title={tr.statisticsTrueRetentionTitle()}
68+
url={HelpPage.DeckOptions.fsrs}
69+
slot="tooltip"
70+
{helpSections}
71+
on:mount={(e) => {
72+
modal = e.detail.modal;
73+
carousel = e.detail.carousel;
74+
}}
75+
/>
4176
<InputBox>
4277
<label>
4378
<input type="radio" bind:group={mode} value={DisplayMode.Young} />

0 commit comments

Comments
 (0)