mirror of
https://github.com/ankitects/anki.git
synced 2025-11-13 08:07:11 -05:00
Rework ChangeNotetype screen
This commit is contained in:
parent
c0027005c1
commit
9d1e131e7f
7 changed files with 194 additions and 89 deletions
|
|
@ -4,31 +4,44 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
-->
|
||||
<script lang="ts">
|
||||
import * as tr from "../lib/ftl";
|
||||
import NotetypeSelector from "./NotetypeSelector.svelte";
|
||||
import Mapper from "./Mapper.svelte";
|
||||
import { ChangeNotetypeState, MapContext } from "./lib";
|
||||
import marked from "marked";
|
||||
import { ChangeNotetypeState, MapContext } from "./lib";
|
||||
import Container from "../components/Container.svelte";
|
||||
import Row from "../components/Row.svelte";
|
||||
import Col from "../components/Col.svelte";
|
||||
import NotetypeSelector from "./NotetypeSelector.svelte";
|
||||
import ScrollArea from "./ScrollArea.svelte";
|
||||
import StickyNav from "./StickyNav.svelte";
|
||||
import Mapper from "./Mapper.svelte";
|
||||
import Spacer from "../components/Spacer.svelte";
|
||||
|
||||
export let state: ChangeNotetypeState;
|
||||
let info = state.info;
|
||||
$: info = state.info;
|
||||
let offset: number;
|
||||
</script>
|
||||
|
||||
<NotetypeSelector {state} />
|
||||
<div bind:clientHeight={offset}>
|
||||
<NotetypeSelector {state} />
|
||||
<Spacer --height="1em" />
|
||||
</div>
|
||||
|
||||
<h5>{tr.changeNotetypeFields()}</h5>
|
||||
|
||||
<Mapper {state} ctx={MapContext.Field} />
|
||||
|
||||
<h5>{tr.changeNotetypeTemplates()}</h5>
|
||||
|
||||
{#if $info.templates}
|
||||
<Mapper {state} ctx={MapContext.Template} />
|
||||
{:else}
|
||||
<div>{@html marked(tr.changeNotetypeToFromCloze())}</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
h5 {
|
||||
margin-top: 1em;
|
||||
}
|
||||
</style>
|
||||
<ScrollArea --gutter-inline="0.5rem" {offset}>
|
||||
<Row --cols={2}>
|
||||
<Col --col-size={1} breakpoint="md">
|
||||
<Container>
|
||||
<StickyNav {state} ctx={MapContext.Field} />
|
||||
<Mapper {state} ctx={MapContext.Field} />
|
||||
</Container>
|
||||
</Col>
|
||||
<Col --col-size={1} breakpoint="md">
|
||||
<Container>
|
||||
<StickyNav {state} ctx={MapContext.Template} />
|
||||
{#if $info.templates}
|
||||
<Mapper {state} ctx={MapContext.Template} />
|
||||
{:else}
|
||||
<div>{@html marked(tr.changeNotetypeToFromCloze())}</div>
|
||||
{/if}
|
||||
</Container>
|
||||
</Col>
|
||||
</Row>
|
||||
</ScrollArea>
|
||||
|
|
|
|||
|
|
@ -4,78 +4,17 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
-->
|
||||
<script lang="ts">
|
||||
import Container from "../components/Container.svelte";
|
||||
import Row from "../components/Row.svelte";
|
||||
import Col from "../components/Col.svelte";
|
||||
import Badge from "../components/Badge.svelte";
|
||||
import MapperRow from "./MapperRow.svelte";
|
||||
import * as tr from "../lib/ftl";
|
||||
import { ChangeNotetypeState, MapContext } from "./lib";
|
||||
import { plusIcon, minusIcon } from "./icons";
|
||||
import { slide } from "svelte/transition";
|
||||
import type { ChangeNotetypeState, MapContext } from "./lib";
|
||||
|
||||
export let state: ChangeNotetypeState;
|
||||
export let ctx: MapContext;
|
||||
|
||||
let info = state.info;
|
||||
|
||||
$: unused = $info.unusedItems(ctx);
|
||||
$: unusedMsg =
|
||||
ctx === MapContext.Field
|
||||
? tr.changeNotetypeWillDiscardContent()
|
||||
: tr.changeNotetypeWillDiscardCards();
|
||||
|
||||
let maxItems: number = 4;
|
||||
let collapsed: boolean = true;
|
||||
$: collapseMsg = collapsed
|
||||
? tr.changeNotetypeExpand()
|
||||
: tr.changeNotetypeCollapse();
|
||||
$: icon = collapsed ? plusIcon : minusIcon;
|
||||
</script>
|
||||
|
||||
{#if unused.length > 0}
|
||||
<div class="alert alert-warning" in:slide out:slide>
|
||||
{#if unused.length > maxItems}
|
||||
<div class="clickable" on:click={() => collapsed = !collapsed}>
|
||||
<Badge iconSize={80}>
|
||||
{@html icon}
|
||||
</Badge>
|
||||
{collapseMsg}
|
||||
</div>
|
||||
{/if}
|
||||
{unusedMsg}
|
||||
<ul>
|
||||
{#if collapsed}
|
||||
{#each unused.slice(0, maxItems) as entry}
|
||||
<li>{entry}</li>
|
||||
{/each}
|
||||
{#if unused.length > maxItems}
|
||||
<div class="clickable" on:click={() => collapsed = !collapsed}>
|
||||
+{unused.length - maxItems}
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
{#each unused as entry}
|
||||
<li>{entry}</li>
|
||||
{/each}
|
||||
{/if}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<Container --gutter-inline="0.5rem" --gutter-block="0.1rem">
|
||||
<Row --cols={2}>
|
||||
<Col --col-size={1}><b>{tr.changeNotetypeCurrent()}</b></Col>
|
||||
<Col --col-size={1}><b>{tr.changeNotetypeNew()}</b></Col>
|
||||
</Row>
|
||||
|
||||
<Container --gutter-inline="0.5rem" --gutter-block="0.15rem">
|
||||
{#each $info.mapForContext(ctx) as _, newIndex}
|
||||
<MapperRow {state} {ctx} {newIndex} />
|
||||
{/each}
|
||||
</Container>
|
||||
|
||||
<style lang="scss">
|
||||
.clickable {
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ 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 tr from "../lib/ftl";
|
||||
import Row from "../components/Row.svelte";
|
||||
import Col from "../components/Col.svelte";
|
||||
import type { ChangeNotetypeState, MapContext } from "./lib";
|
||||
|
|
@ -11,12 +12,25 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
export let ctx: MapContext;
|
||||
export let newIndex: number;
|
||||
|
||||
let info = state.info;
|
||||
$: info = state.info;
|
||||
|
||||
let oldNames: string[];
|
||||
let current: string;
|
||||
$: {
|
||||
oldNames = $info.getOldNamesIncludingNothing(ctx);
|
||||
current = oldNames[newIndex] || tr.changeNotetypeNothing();
|
||||
}
|
||||
|
||||
function onChange(evt: Event) {
|
||||
const oldIdx = parseInt((evt.target as HTMLSelectElement).value, 10);
|
||||
state.setOldIndex(ctx, newIndex, oldIdx);
|
||||
}
|
||||
|
||||
// optimization for big notetypes
|
||||
let active: boolean = false;
|
||||
function activate(evt: Event) {
|
||||
active = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Row --cols={2}>
|
||||
|
|
|
|||
|
|
@ -11,12 +11,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import ButtonGroup from "../components/ButtonGroup.svelte";
|
||||
import ButtonGroupItem from "../components/ButtonGroupItem.svelte";
|
||||
|
||||
import LabelButton from "../components/LabelButton.svelte";
|
||||
import Badge from "../components/Badge.svelte";
|
||||
import { arrowRightIcon } from "./icons";
|
||||
import SelectButton from "../components/SelectButton.svelte";
|
||||
import SelectOption from "../components/SelectOption.svelte";
|
||||
import SaveButton from "./SaveButton.svelte";
|
||||
|
||||
export let state: ChangeNotetypeState;
|
||||
let notetypes = state.notetypes;
|
||||
let info = state.info;
|
||||
|
||||
async function blur(event: Event): Promise<void> {
|
||||
await state.setTargetNotetypeIndex(
|
||||
|
|
@ -25,8 +29,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
</script>
|
||||
|
||||
<StickyContainer --gutter-block="0.1rem" --sticky-borders="0 0 1px">
|
||||
<StickyContainer --gutter-block="0.1rem">
|
||||
<ButtonToolbar class="justify-content-between" size={2.3} wrap={false}>
|
||||
<Item>
|
||||
<ButtonGroupItem>
|
||||
<LabelButton disabled={true}>
|
||||
{$info.oldNotetypeName}
|
||||
</LabelButton>
|
||||
</ButtonGroupItem>
|
||||
</Item>
|
||||
<Item>
|
||||
<Badge iconSize={70}>
|
||||
{@html arrowRightIcon}
|
||||
</Badge>
|
||||
</Item>
|
||||
<Item>
|
||||
<ButtonGroup class="flex-grow-1">
|
||||
<ButtonGroupItem>
|
||||
|
|
|
|||
23
ts/change-notetype/ScrollArea.svelte
Normal file
23
ts/change-notetype/ScrollArea.svelte
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<!--
|
||||
Copyright: Ankitects Pty Ltd and contributors
|
||||
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
-->
|
||||
<script lang="ts">
|
||||
export let offset: number;
|
||||
</script>
|
||||
|
||||
<div style="--offset: {offset}px">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
padding: 0, 0.5rem;
|
||||
overflow: hidden auto;
|
||||
background: var(--frame-bg);
|
||||
height: calc(100% - var(--offset));
|
||||
border: 1px solid var(--medium-border);
|
||||
box-shadow: 0 0 0 1px var(--faint-border);
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
</style>
|
||||
100
ts/change-notetype/StickyNav.svelte
Normal file
100
ts/change-notetype/StickyNav.svelte
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<!--
|
||||
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 tr from "../lib/ftl";
|
||||
import Badge from "../components/Badge.svelte";
|
||||
import Container from "../components/Container.svelte";
|
||||
import Row from "../components/Row.svelte";
|
||||
import Col from "../components/Col.svelte";
|
||||
import { exclamationIcon } from "./icons";
|
||||
import { ChangeNotetypeState, MapContext } from "./lib";
|
||||
import StickyContainer from "../components/StickyContainer.svelte";
|
||||
import { plusIcon, minusIcon } from "./icons";
|
||||
import { slide } from "svelte/transition";
|
||||
|
||||
export let state: ChangeNotetypeState;
|
||||
export let ctx: MapContext;
|
||||
|
||||
$: info = state.info;
|
||||
|
||||
let heading: string =
|
||||
ctx === MapContext.Field
|
||||
? tr.changeNotetypeFields()
|
||||
: tr.changeNotetypeTemplates();
|
||||
|
||||
$: unused = $info.unusedItems(ctx);
|
||||
$: unusedMsg =
|
||||
ctx === MapContext.Field
|
||||
? tr.changeNotetypeWillDiscardContent()
|
||||
: tr.changeNotetypeWillDiscardCards();
|
||||
|
||||
let maxItems: number = 3;
|
||||
let collapsed: boolean = true;
|
||||
$: collapseMsg = collapsed
|
||||
? tr.changeNotetypeExpand()
|
||||
: tr.changeNotetypeCollapse();
|
||||
$: icon = collapsed ? plusIcon : minusIcon;
|
||||
</script>
|
||||
|
||||
<StickyContainer
|
||||
--sticky-bg={"var(--frame-bg)"}
|
||||
--sticky-border="var(--window-bg)"
|
||||
--sticky-borders="0 0 1px"
|
||||
>
|
||||
<h1>
|
||||
{heading}
|
||||
{#if unused.length > 0}
|
||||
<Badge iconSize={80}>
|
||||
{@html exclamationIcon}
|
||||
</Badge>
|
||||
{/if}
|
||||
</h1>
|
||||
|
||||
{#if unused.length > 0}
|
||||
<div class="alert alert-warning" in:slide out:slide>
|
||||
{#if unused.length > maxItems}
|
||||
<div class="clickable" on:click={() => (collapsed = !collapsed)}>
|
||||
<Badge iconSize={80}>
|
||||
{@html icon}
|
||||
</Badge>
|
||||
{collapseMsg}
|
||||
</div>
|
||||
{/if}
|
||||
{unusedMsg}
|
||||
{#if collapsed}
|
||||
<div>
|
||||
{unused.slice(0, maxItems).join(", ")}
|
||||
{#if unused.length > maxItems}
|
||||
... (+{unused.length - maxItems})
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<ul>
|
||||
{#each unused as entry}
|
||||
<li>{entry}</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{#if $info.templates}
|
||||
<Container --gutter-inline="0.5rem" --gutter-block="0.2rem">
|
||||
<Row --cols={2}>
|
||||
<Col --col-size={1}><b>{tr.changeNotetypeCurrent()}</b></Col>
|
||||
<Col --col-size={1}><b>{tr.changeNotetypeNew()}</b></Col>
|
||||
</Row>
|
||||
</Container>
|
||||
{/if}
|
||||
</StickyContainer>
|
||||
|
||||
<style lang="scss">
|
||||
h1 {
|
||||
padding-top: 0.5em;
|
||||
}
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
}
|
||||
|
||||
body {
|
||||
width: min(100vw, 35em);
|
||||
width: min(100vw, 70em);
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ html {
|
|||
|
||||
#main {
|
||||
padding: 0 1em 1em 1em;
|
||||
height: calc(100vh - 1em);
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
// override the default down arrow colour in <select> elements
|
||||
|
|
|
|||
Loading…
Reference in a new issue