mirror of
https://github.com/ankitects/anki.git
synced 2025-11-13 16:17:13 -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">
|
<script lang="ts">
|
||||||
import * as tr from "../lib/ftl";
|
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 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;
|
export let state: ChangeNotetypeState;
|
||||||
let info = state.info;
|
$: info = state.info;
|
||||||
|
let offset: number;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<NotetypeSelector {state} />
|
<div bind:clientHeight={offset}>
|
||||||
|
<NotetypeSelector {state} />
|
||||||
|
<Spacer --height="1em" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<h5>{tr.changeNotetypeFields()}</h5>
|
<ScrollArea --gutter-inline="0.5rem" {offset}>
|
||||||
|
<Row --cols={2}>
|
||||||
<Mapper {state} ctx={MapContext.Field} />
|
<Col --col-size={1} breakpoint="md">
|
||||||
|
<Container>
|
||||||
<h5>{tr.changeNotetypeTemplates()}</h5>
|
<StickyNav {state} ctx={MapContext.Field} />
|
||||||
|
<Mapper {state} ctx={MapContext.Field} />
|
||||||
{#if $info.templates}
|
</Container>
|
||||||
<Mapper {state} ctx={MapContext.Template} />
|
</Col>
|
||||||
{:else}
|
<Col --col-size={1} breakpoint="md">
|
||||||
<div>{@html marked(tr.changeNotetypeToFromCloze())}</div>
|
<Container>
|
||||||
{/if}
|
<StickyNav {state} ctx={MapContext.Template} />
|
||||||
|
{#if $info.templates}
|
||||||
<style>
|
<Mapper {state} ctx={MapContext.Template} />
|
||||||
h5 {
|
{:else}
|
||||||
margin-top: 1em;
|
<div>{@html marked(tr.changeNotetypeToFromCloze())}</div>
|
||||||
}
|
{/if}
|
||||||
</style>
|
</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">
|
<script lang="ts">
|
||||||
import Container from "../components/Container.svelte";
|
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 MapperRow from "./MapperRow.svelte";
|
||||||
import * as tr from "../lib/ftl";
|
import type { ChangeNotetypeState, MapContext } from "./lib";
|
||||||
import { ChangeNotetypeState, MapContext } from "./lib";
|
|
||||||
import { plusIcon, minusIcon } from "./icons";
|
|
||||||
import { slide } from "svelte/transition";
|
|
||||||
|
|
||||||
export let state: ChangeNotetypeState;
|
export let state: ChangeNotetypeState;
|
||||||
export let ctx: MapContext;
|
export let ctx: MapContext;
|
||||||
|
|
||||||
let info = state.info;
|
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>
|
</script>
|
||||||
|
|
||||||
{#if unused.length > 0}
|
<Container --gutter-inline="0.5rem" --gutter-block="0.15rem">
|
||||||
<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>
|
|
||||||
|
|
||||||
{#each $info.mapForContext(ctx) as _, newIndex}
|
{#each $info.mapForContext(ctx) as _, newIndex}
|
||||||
<MapperRow {state} {ctx} {newIndex} />
|
<MapperRow {state} {ctx} {newIndex} />
|
||||||
{/each}
|
{/each}
|
||||||
</Container>
|
</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
|
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
-->
|
-->
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import * as tr from "../lib/ftl";
|
||||||
import Row from "../components/Row.svelte";
|
import Row from "../components/Row.svelte";
|
||||||
import Col from "../components/Col.svelte";
|
import Col from "../components/Col.svelte";
|
||||||
import type { ChangeNotetypeState, MapContext } from "./lib";
|
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 ctx: MapContext;
|
||||||
export let newIndex: number;
|
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) {
|
function onChange(evt: Event) {
|
||||||
const oldIdx = parseInt((evt.target as HTMLSelectElement).value, 10);
|
const oldIdx = parseInt((evt.target as HTMLSelectElement).value, 10);
|
||||||
state.setOldIndex(ctx, newIndex, oldIdx);
|
state.setOldIndex(ctx, newIndex, oldIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// optimization for big notetypes
|
||||||
|
let active: boolean = false;
|
||||||
|
function activate(evt: Event) {
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Row --cols={2}>
|
<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 ButtonGroup from "../components/ButtonGroup.svelte";
|
||||||
import ButtonGroupItem from "../components/ButtonGroupItem.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 SelectButton from "../components/SelectButton.svelte";
|
||||||
import SelectOption from "../components/SelectOption.svelte";
|
import SelectOption from "../components/SelectOption.svelte";
|
||||||
import SaveButton from "./SaveButton.svelte";
|
import SaveButton from "./SaveButton.svelte";
|
||||||
|
|
||||||
export let state: ChangeNotetypeState;
|
export let state: ChangeNotetypeState;
|
||||||
let notetypes = state.notetypes;
|
let notetypes = state.notetypes;
|
||||||
|
let info = state.info;
|
||||||
|
|
||||||
async function blur(event: Event): Promise<void> {
|
async function blur(event: Event): Promise<void> {
|
||||||
await state.setTargetNotetypeIndex(
|
await state.setTargetNotetypeIndex(
|
||||||
|
|
@ -25,8 +29,20 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||||
}
|
}
|
||||||
</script>
|
</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}>
|
<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>
|
<Item>
|
||||||
<ButtonGroup class="flex-grow-1">
|
<ButtonGroup class="flex-grow-1">
|
||||||
<ButtonGroupItem>
|
<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 {
|
body {
|
||||||
width: min(100vw, 35em);
|
width: min(100vw, 70em);
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ html {
|
||||||
|
|
||||||
#main {
|
#main {
|
||||||
padding: 0 1em 1em 1em;
|
padding: 0 1em 1em 1em;
|
||||||
height: calc(100vh - 1em);
|
height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
// override the default down arrow colour in <select> elements
|
// override the default down arrow colour in <select> elements
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue