From d9fc44a189e8fcee53baf23762314eb4814e2079 Mon Sep 17 00:00:00 2001 From: James Dabbs Date: Sun, 10 Dec 2023 11:24:17 -0800 Subject: [PATCH 1/6] fix trait#show page reactivity (#94) per report [here](https://github.com/orgs/pi-base/discussions/464#discussioncomment-7560692) --- .github/workflows/e2e.yaml | 2 +- .../viewer/src/components/Traits/Show.svelte | 60 ------------------- .../viewer/src/components/Traits/index.ts | 2 +- .../[id]/properties/[propertyId]/+page.svelte | 29 ++++++++- .../[id]/properties/[propertyId]/+page.ts | 26 ++++++++ 5 files changed, 54 insertions(+), 65 deletions(-) delete mode 100644 packages/viewer/src/components/Traits/Show.svelte create mode 100644 packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.ts diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 67063d69..ce2a82ea 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -66,7 +66,7 @@ jobs: cp cypress/fixtures/main.min.json dist/refs/heads/main.json - name: Cypress run - uses: cypress-io/github-action@v5 + uses: cypress-io/github-action@v6 with: browser: chrome build: echo "Start runs build" diff --git a/packages/viewer/src/components/Traits/Show.svelte b/packages/viewer/src/components/Traits/Show.svelte deleted file mode 100644 index ad82d57a..00000000 --- a/packages/viewer/src/components/Traits/Show.svelte +++ /dev/null @@ -1,60 +0,0 @@ - - -{#await loading} - -{:then { property, space, trait, proof, meta }} - - - <h1> - {#if proof} - <Robot /> - {/if} - <Link.Space {space} /> - is - {trait.value ? '' : 'not'} - <Link.Property {property} /> - </h1> - - {#if proof} - <Proof {space} {...proof} /> - {:else if meta} - <section class="description"> - <Typeset body={meta.description} /> - </section> - <h3>References</h3> - <References references={meta.refs} /> - {/if} -{:catch} - <NotFound>Could not find space {spaceId} / property {propertyId}</NotFound> -{/await} diff --git a/packages/viewer/src/components/Traits/index.ts b/packages/viewer/src/components/Traits/index.ts index 309d0b75..698b91ac 100644 --- a/packages/viewer/src/components/Traits/index.ts +++ b/packages/viewer/src/components/Traits/index.ts @@ -1,4 +1,4 @@ +export { default as Proof } from './Proof.svelte' export { default as Related } from './Related.svelte' -export { default as Show } from './Show.svelte' export { default as Table } from './Table.svelte' export { default as Value } from './Value.svelte' diff --git a/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.svelte b/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.svelte index 5a6f6cea..2bb6f2ab 100644 --- a/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.svelte +++ b/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.svelte @@ -1,6 +1,29 @@ <script lang="ts"> - import { page } from '$app/stores' - import { Show } from '@/components/Traits' + import { Icons, Link, References, Title, Typeset } from '@/components/Shared' + import { Proof } from '@/components/Traits' + + import type { PageData } from './$types' + export let data: PageData </script> -<Show spaceId={$page.params.id} propertyId={$page.params.propertyId} /> +<Title title={`${data.space.name}: ${data.property.name}`} /> + +<h1> + {#if data.proof} + <Icons.Robot /> + {/if} + <Link.Space space={data.space} /> + is + {data.trait.value ? '' : 'not'} + <Link.Property property={data.property} /> +</h1> + +{#if data.proof} + <Proof space={data.space} {...data.proof} /> +{:else if data.meta} + <section class="description"> + <Typeset body={data.meta.description} /> + </section> + <h3>References</h3> + <References references={data.meta.refs} /> +{/if} diff --git a/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.ts b/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.ts new file mode 100644 index 00000000..15ecb4ba --- /dev/null +++ b/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.ts @@ -0,0 +1,26 @@ +import { get } from 'svelte/store' +import { error } from '@sveltejs/kit' + +import type { PageLoad } from './$types' + +export const load: PageLoad = async function ({ + params: { id: spaceId, propertyId }, + parent, +}) { + const { load, spaces, properties, theorems, traits, checked } = await parent() + + return load( + traits, + ts => + ts.lookup({ + spaceId, + propertyId, + spaces: get(spaces), + properties: get(properties), + theorems: get(theorems), + }), + checked(spaceId), + ).catch(() => { + throw error(404, `Trait not found ${spaceId} / ${propertyId}`) + }) +} From 12b5fd5b624b9bd02b28658b30bef339e053f9c4 Mon Sep 17 00:00:00 2001 From: James Dabbs <james.dabbs@gmail.com> Date: Sun, 10 Dec 2023 14:12:55 -0800 Subject: [PATCH 2/6] truncate previews at first line break (#96) --- packages/core/src/Parser.ts | 4 +-- packages/core/src/Parser/truncate.ts | 4 +++ packages/core/src/Parser/unnest.ts | 6 +++- packages/core/test/Parser.test.ts | 35 ++++++++++++++++++- .../test/__snapshots__/Parser.test.ts.snap | 2 ++ packages/core/vite.config.ts | 8 ++--- 6 files changed, 51 insertions(+), 8 deletions(-) diff --git a/packages/core/src/Parser.ts b/packages/core/src/Parser.ts index 55b2f536..0e4c0f68 100644 --- a/packages/core/src/Parser.ts +++ b/packages/core/src/Parser.ts @@ -53,14 +53,14 @@ export function parser({ .use(remarkRehype) // Convert math nodes to hast .use(rehypeKatex) - // Automatically remove outermost paragraph wrapper - .use(unnest) // Optionally trim mdast to a minimal preview .use(truncator, { maxChars: 100, disable: !truncate, ignoreTags: ['math', 'inline-math'], }) + // Automatically remove outermost paragraph wrapper + .use(unnest) // Render hast to HTML string .use(rehypeStringify) ) diff --git a/packages/core/src/Parser/truncate.ts b/packages/core/src/Parser/truncate.ts index d3043c60..6bc92595 100644 --- a/packages/core/src/Parser/truncate.ts +++ b/packages/core/src/Parser/truncate.ts @@ -28,12 +28,16 @@ export function truncate({ if (node.type === 'text') { foundText += node.value.length + if (foundText >= maxChars) { node.value = `${node.value.slice( 0, node.value.length - (foundText - maxChars), )}${ellipses}` return maxChars + } else if (node.value === '\n') { + node.value = '' + return maxChars } } diff --git a/packages/core/src/Parser/unnest.ts b/packages/core/src/Parser/unnest.ts index 673e5a3a..b55c5b76 100644 --- a/packages/core/src/Parser/unnest.ts +++ b/packages/core/src/Parser/unnest.ts @@ -8,7 +8,11 @@ import { Transformer } from 'unified' */ export const unnest = () => { const transformer: Transformer<Root> = tree => { - if (tree && tree.children?.length === 1 && 'tagName' in tree.children[0]) { + if (tree.children) { + tree.children = tree.children.filter(n => n.type !== 'text' || n.value) + } + + if (tree?.children.length === 1 && 'tagName' in tree.children[0]) { tree.children = tree.children[0].children if ('tagName' in tree.children[0] && tree.children[0].tagName === 'p') { diff --git a/packages/core/test/Parser.test.ts b/packages/core/test/Parser.test.ts index 4adc3f9c..93799f8a 100644 --- a/packages/core/test/Parser.test.ts +++ b/packages/core/test/Parser.test.ts @@ -8,12 +8,13 @@ function link([kind, id]: [unknown, unknown]) { } } -async function parse(input: string) { +async function parse(input: string, { truncate = false } = {}) { const file = await parser({ link: { internal: link, external: link, }, + truncate, }).process(input) return String(file) } @@ -90,6 +91,38 @@ it.todo('expands math in linked titles', async () => { ) }) +describe('truncate', () => { + it('breaks on newlines', () => { + const input = `a first sentence.\n\nand some extra stuff` + expect(parse(input)).resolves.toEqual( + '<p>a first sentence.</p>\n<p>and some extra stuff</p>', + ) + expect(parse(input, { truncate: true })).resolves.toEqual( + 'a first sentence.', + ) + }) + + it('adds ellipses', () => { + expect( + parse( + 'this is a fairly long sentence and it needs to be summarized because it is too long because it just goes on and on and on', + { truncate: true }, + ), + ).resolves.toEqual( + 'this is a fairly long sentence and it needs to be summarized because it is too long because it just …', + ) + }) + + it('preserves math', () => { + expect( + parse( + 'this is a fairly long sentence and it needs to be summarized because it is too long because it $T_{3\\frac{1}{2}}$ just goes on and on and on', + { truncate: true }, + ), + ).resolves.toMatchSnapshot() + }) +}) + describe('unwrapping', () => { it('unwraps math', () => { expect(parse('$\\sigma$')).resolves.toEqual( diff --git a/packages/core/test/__snapshots__/Parser.test.ts.snap b/packages/core/test/__snapshots__/Parser.test.ts.snap index f3fd3e82..e29ebde7 100644 --- a/packages/core/test/__snapshots__/Parser.test.ts.snap +++ b/packages/core/test/__snapshots__/Parser.test.ts.snap @@ -14,3 +14,5 @@ exports[`parses a complex example 1`] = ` <li><a href=\\"mo://123\\" title=\\"123\\" class=\\"external-link\\">123</a></li> </ul>" `; + +exports[`truncate > preserves math 1`] = `"this is a fairly long sentence and it needs to be summarized because it is too long because it <span class=\\"math math-inline\\"><span class=\\"katex\\"><span class=\\"katex-mathml\\"><math xmlns=\\"http://www.w3.org/1998/Math/MathML\\"><semantics><mrow><msub><mi>T</mi><mrow><mn>3</mn><mfrac><mn>1</mn><mn>2</mn></mfrac></mrow></msub></mrow><annotation encoding=\\"application/x-tex\\">T_{3\\\\frac{1}{2}}</annotation></semantics></math></span><span class=\\"katex-html\\" aria-hidden=\\"true\\"><span class=\\"base\\"><span class=\\"strut\\" style=\\"height:1.1704em;vertical-align:-0.487em;\\"></span><span class=\\"mord\\"><span class=\\"mord mathnormal\\" style=\\"margin-right:0.13889em;\\">T</span><span class=\\"msupsub\\"><span class=\\"vlist-t vlist-t2\\"><span class=\\"vlist-r\\"><span class=\\"vlist\\" style=\\"height:0.3448em;\\"><span style=\\"top:-2.7538em;margin-left:-0.1389em;margin-right:0.05em;\\"><span class=\\"pstrut\\" style=\\"height:3em;\\"></span><span class=\\"sizing reset-size6 size3 mtight\\"><span class=\\"mord mtight\\"><span class=\\"mord mtight\\">3</span><span class=\\"mord mtight\\"><span class=\\"mopen nulldelimiter sizing reset-size3 size6\\"></span><span class=\\"mfrac\\"><span class=\\"vlist-t vlist-t2\\"><span class=\\"vlist-r\\"><span class=\\"vlist\\" style=\\"height:0.8443em;\\"><span style=\\"top:-2.656em;\\"><span class=\\"pstrut\\" style=\\"height:3em;\\"></span><span class=\\"sizing reset-size3 size1 mtight\\"><span class=\\"mord mtight\\"><span class=\\"mord mtight\\">2</span></span></span></span><span style=\\"top:-3.2255em;\\"><span class=\\"pstrut\\" style=\\"height:3em;\\"></span><span class=\\"frac-line mtight\\" style=\\"border-bottom-width:0.049em;\\"></span></span><span style=\\"top:-3.384em;\\"><span class=\\"pstrut\\" style=\\"height:3em;\\"></span><span class=\\"sizing reset-size3 size1 mtight\\"><span class=\\"mord mtight\\"><span class=\\"mord mtight\\">1</span></span></span></span></span><span class=\\"vlist-s\\">​…</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span>"`; diff --git a/packages/core/vite.config.ts b/packages/core/vite.config.ts index ec2c34f9..d4fa5a77 100644 --- a/packages/core/vite.config.ts +++ b/packages/core/vite.config.ts @@ -17,10 +17,10 @@ export default defineConfig({ }, test: { coverage: { - lines: 91.04, - branches: 93.68, - statements: 91.04, - functions: 83.55, + lines: 93.04, + branches: 94.35, + statements: 93.04, + functions: 84.21, skipFull: true, thresholdAutoUpdate: true, exclude: ['src/Formula/Grammar.ts', 'test'], From 195a60672877bb471fe08a5878c8fa8c87e6b081 Mon Sep 17 00:00:00 2001 From: James Dabbs <james.dabbs@gmail.com> Date: Sun, 10 Dec 2023 16:53:25 -0800 Subject: [PATCH 3/6] fix filter reactivity (#97) fixes #77 --- .../src/components/Properties/List.svelte | 27 ++++++------------- .../src/components/Search/Search.svelte | 4 +-- .../src/components/Shared/Filter.svelte | 4 +++ .../Shared/Formula/Input/Formula.svelte | 1 + .../viewer/src/components/Spaces/List.svelte | 27 ++++++------------- .../src/components/Theorems/List.svelte | 22 +++++---------- .../src/routes/(app)/properties/+page.ts | 17 ++++++++++++ .../src/routes/(app)/spaces/all/+page.ts | 17 ++++++++++++ .../viewer/src/routes/(app)/theorems/+page.ts | 17 ++++++++++++ packages/viewer/src/stores/list.ts | 7 +---- packages/viewer/src/stores/urlSearchParam.ts | 26 +++++++++--------- 11 files changed, 93 insertions(+), 76 deletions(-) create mode 100644 packages/viewer/src/routes/(app)/properties/+page.ts create mode 100644 packages/viewer/src/routes/(app)/spaces/all/+page.ts create mode 100644 packages/viewer/src/routes/(app)/theorems/+page.ts diff --git a/packages/viewer/src/components/Properties/List.svelte b/packages/viewer/src/components/Properties/List.svelte index b41c4ef8..79d6e6ff 100644 --- a/packages/viewer/src/components/Properties/List.svelte +++ b/packages/viewer/src/components/Properties/List.svelte @@ -1,35 +1,24 @@ <script lang="ts"> - import { derived, type Readable } from 'svelte/store' + import { Filter, Link, Title, Typeset } from '@/components/Shared' + import type { Property } from '@/models' + import type { Store } from '@/stores/list' - import { list } from '@/stores' - - import { Filter, Link, Title, Typeset } from '../Shared' - import type { Collection, Property } from 'src/models' - - export let properties: Readable<Collection<Property>> - - const index = list( - derived(properties, ps => ps.all), - { - weights: { name: 0.7, aliases: 0.7, description: 0.3 }, - queryParam: 'filter', - }, - ) + export let properties: Store<Property> </script> <Title title="Properties" /> -<Filter filter={index.filter} /> +<Filter filter={properties.filter} /> <table class="table"> <thead> <tr> - <th on:click={index.sort('id')}>Id</th> - <th on:click={index.sort('name')}>Name</th> + <th on:click={properties.sort('id')}>Id</th> + <th on:click={properties.sort('name')}>Name</th> <th>Description</th> </tr> </thead> - {#each $index as property (property.id)} + {#each $properties as property (property.id)} <tr> <td> <Link.Property {property}>{property.id}</Link.Property> diff --git a/packages/viewer/src/components/Search/Search.svelte b/packages/viewer/src/components/Search/Search.svelte index 61ade3fb..f94fe1b6 100644 --- a/packages/viewer/src/components/Search/Search.svelte +++ b/packages/viewer/src/components/Search/Search.svelte @@ -20,7 +20,7 @@ // // It really feels like we don't have the right architecture for this formula // state. - const suggest = writable(true) + const suggest = writable(false) rawFormula.subscribe(_ => ($suggest = true)) function selectExample(example: string) { $rawFormula = example @@ -28,7 +28,7 @@ } urlSearchParam('text', text) - urlSearchParam('q', rawFormula) + urlSearchParam('q', rawFormula, () => ($suggest = false)) let title: string $: if ($rawFormula.length > 0) { diff --git a/packages/viewer/src/components/Shared/Filter.svelte b/packages/viewer/src/components/Shared/Filter.svelte index 4f2806e1..df95ea57 100644 --- a/packages/viewer/src/components/Shared/Filter.svelte +++ b/packages/viewer/src/components/Shared/Filter.svelte @@ -1,8 +1,12 @@ <script lang="ts"> import type { Writable } from 'svelte/store' + import urlSearchParam from '@/stores/urlSearchParam' + import { Search } from './Icons' export let filter: Writable<string> + + urlSearchParam('filter', filter) </script> <div class="input-group"> diff --git a/packages/viewer/src/components/Shared/Formula/Input/Formula.svelte b/packages/viewer/src/components/Shared/Formula/Input/Formula.svelte index 791191d2..de3b686c 100644 --- a/packages/viewer/src/components/Shared/Formula/Input/Formula.svelte +++ b/packages/viewer/src/components/Shared/Formula/Input/Formula.svelte @@ -35,6 +35,7 @@ <input class="form-control" + autocomplete="off" {name} {placeholder} bind:value={$raw} diff --git a/packages/viewer/src/components/Spaces/List.svelte b/packages/viewer/src/components/Spaces/List.svelte index 4483938e..e5c0ce3b 100644 --- a/packages/viewer/src/components/Spaces/List.svelte +++ b/packages/viewer/src/components/Spaces/List.svelte @@ -1,35 +1,24 @@ <script lang="ts"> - import { derived, type Readable } from 'svelte/store' + import { Filter, Link, Title, Typeset } from '@/components/Shared' + import type { Space } from '@/models' + import type { Store } from '@/stores/list' - import { list } from '@/stores' - - import { Filter, Link, Title, Typeset } from '../Shared' - import type { Collection, Space } from 'src/models' - - export let spaces: Readable<Collection<Space>> - - const index = list( - derived(spaces, ss => ss.all), - { - weights: { name: 0.7, aliases: 0.7, description: 0.3 }, - queryParam: 'filter', - }, - ) + export let spaces: Store<Space> </script> <Title title="Spaces" /> -<Filter filter={index.filter} /> +<Filter filter={spaces.filter} /> <table class="table"> <thead> <tr> - <th on:click={index.sort('id')}>Id</th> - <th on:click={index.sort('name')}>Name</th> + <th on:click={spaces.sort('id')}>Id</th> + <th on:click={spaces.sort('name')}>Name</th> <th>Description</th> </tr> </thead> - {#each $index as space (space.id)} + {#each $spaces as space (space.id)} <tr> <td> <Link.Space {space}>{space.id}</Link.Space> diff --git a/packages/viewer/src/components/Theorems/List.svelte b/packages/viewer/src/components/Theorems/List.svelte index c9a71fa3..f7a9b242 100644 --- a/packages/viewer/src/components/Theorems/List.svelte +++ b/packages/viewer/src/components/Theorems/List.svelte @@ -1,35 +1,25 @@ <script lang="ts"> - import { derived, type Readable } from 'svelte/store' - import { list } from '@/stores' - import { Filter, Formula, Link, Title, Typeset } from '../Shared' - import type { Theorems } from 'src/models' - - export let theorems: Readable<Theorems> + import type { Theorem } from '@/models' + import type { Store } from '@/stores/list' - const index = list( - derived(theorems, ts => ts.all), - { - weights: { name: 0.7, description: 0.3 }, - queryParam: 'filter', - }, - ) + export let theorems: Store<Theorem> </script> <Title title="Theorems" /> -<Filter filter={index.filter} /> +<Filter filter={theorems.filter} /> <table class="table"> <thead> <tr> - <th on:click={index.sort('id')}>Id</th> + <th on:click={theorems.sort('id')}>Id</th> <th>If</th> <th>Then</th> <th>Description</th> </tr> </thead> - {#each $index as theorem (theorem.id)} + {#each $theorems as theorem (theorem.id)} <tr> <td> <Link.Theorem {theorem} /> diff --git a/packages/viewer/src/routes/(app)/properties/+page.ts b/packages/viewer/src/routes/(app)/properties/+page.ts new file mode 100644 index 00000000..c2089273 --- /dev/null +++ b/packages/viewer/src/routes/(app)/properties/+page.ts @@ -0,0 +1,17 @@ +import { derived } from 'svelte/store' + +import { list } from '@/stores' +import type { PageLoad } from './$types' + +export const load: PageLoad = async function ({ parent, url }) { + const { properties } = await parent() + + return { + properties: list( + derived(properties, ps => ps.all), + { + weights: { name: 0.7, aliases: 0.7, description: 0.3 }, + }, + ), + } +} diff --git a/packages/viewer/src/routes/(app)/spaces/all/+page.ts b/packages/viewer/src/routes/(app)/spaces/all/+page.ts new file mode 100644 index 00000000..1194ad36 --- /dev/null +++ b/packages/viewer/src/routes/(app)/spaces/all/+page.ts @@ -0,0 +1,17 @@ +import { derived } from 'svelte/store' + +import { list } from '@/stores' +import type { PageLoad } from './$types' + +export const load: PageLoad = async function ({ parent, url }) { + const { spaces } = await parent() + + return { + spaces: list( + derived(spaces, ss => ss.all), + { + weights: { name: 0.7, aliases: 0.7, description: 0.3 }, + }, + ), + } +} diff --git a/packages/viewer/src/routes/(app)/theorems/+page.ts b/packages/viewer/src/routes/(app)/theorems/+page.ts new file mode 100644 index 00000000..084358a3 --- /dev/null +++ b/packages/viewer/src/routes/(app)/theorems/+page.ts @@ -0,0 +1,17 @@ +import { derived } from 'svelte/store' + +import { list } from '@/stores' +import type { PageLoad } from './$types' + +export const load: PageLoad = async function ({ parent, url }) { + const { theorems } = await parent() + + return { + theorems: list( + derived(theorems, ts => ts.all), + { + weights: { name: 0.7, description: 0.3 }, + }, + ), + } +} diff --git a/packages/viewer/src/stores/list.ts b/packages/viewer/src/stores/list.ts index 31b7f2dc..ab79c420 100644 --- a/packages/viewer/src/stores/list.ts +++ b/packages/viewer/src/stores/list.ts @@ -2,11 +2,9 @@ import Fuse from 'fuse.js' import { type Readable, type Writable, derived, writable } from 'svelte/store' import * as sort from './sort' -import urlSearchParam from './urlSearchParam' type Options<T> = { weights: Weighted<T> - queryParam?: string } type Weighted<T> = { @@ -20,7 +18,7 @@ export type Store<T> = Readable<T[]> & { export default function list<T>( collection: Readable<T[]>, - { weights, queryParam }: Options<T>, + { weights }: Options<T>, ): Store<T> { const keys = Object.entries(weights).map(([name, weight]) => ({ name, @@ -35,9 +33,6 @@ export default function list<T>( const filter = writable('') filter.subscribe(sorter.reset) - if (queryParam) { - urlSearchParam(queryParam, filter) - } const { subscribe } = derived( [collection, index, sorter, filter], diff --git a/packages/viewer/src/stores/urlSearchParam.ts b/packages/viewer/src/stores/urlSearchParam.ts index 7d67ca66..b3ab944c 100644 --- a/packages/viewer/src/stores/urlSearchParam.ts +++ b/packages/viewer/src/stores/urlSearchParam.ts @@ -1,46 +1,44 @@ import { browser } from '$app/environment' +import { goto } from '$app/navigation' +import { page } from '$app/stores' import { onMount } from 'svelte' -import type { Writable } from 'svelte/store' +import { get, type Writable } from 'svelte/store' // Wraps an existing writable store, writing updates to the named URL query // param, and initializing the store value from that param at mount. export default function urlSearchParam( name: string, { subscribe, set }: Writable<string>, + mountCallback?: () => any, ) { if (!browser) { return } function parse() { - return new URL(location.href).searchParams + return new URL(get(page).url) } onMount(() => { - set(parse().get(name) || '') + set(parse().searchParams.get(name) || '') + mountCallback && mountCallback() }) let initialized = false subscribe(value => { - const search = parse() + const url = parse() - if (!search) { + if (!url.searchParams) { return } if (value) { - search.set(name, value) + url.searchParams.set(name, value) } else if (initialized) { - search.delete(name) + url.searchParams.delete(name) } initialized = true - window.history.replaceState( - null, - '', - search.toString() - ? `${window.location.pathname}?${search}` - : window.location.pathname, - ) + goto(url, { replaceState: true, keepFocus: true }) }) } From 6016eb98cf0811ec8cc8405749b2fed78f549252 Mon Sep 17 00:00:00 2001 From: James Dabbs <james.dabbs@gmail.com> Date: Sun, 10 Dec 2023 19:38:47 -0800 Subject: [PATCH 4/6] add related trait filter url param --- packages/viewer/src/components/Traits/Related.svelte | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/viewer/src/components/Traits/Related.svelte b/packages/viewer/src/components/Traits/Related.svelte index 58af9fd5..a48aa091 100644 --- a/packages/viewer/src/components/Traits/Related.svelte +++ b/packages/viewer/src/components/Traits/Related.svelte @@ -5,13 +5,17 @@ import context from '@/context' import type { Property, Space, Trait, Traits } from '@/models' import { capitalize } from '@/util' + import { writable } from 'svelte/store' + import urlSearchParam from '@/stores/urlSearchParam' export let related: (traits: Traits) => [Space, Property, Trait][] export let mode: 'spaces' | 'properties' const { traits } = context() - let filter = '' + const filter = writable('') + urlSearchParam('filter', filter) + let showDeduced = true function toggleDeduced() { @@ -23,7 +27,7 @@ // we need to index names in different positions depending on which kind we // are displaying $: index = new Fuse(all, { keys: [`${mode === 'spaces' ? 0 : 1}.name`] }) - $: searched = filter ? index.search(filter).map(r => r.item) : all + $: searched = $filter ? index.search($filter).map(r => r.item) : all $: filtered = searched.filter( ([_space, _property, t]) => showDeduced || t.asserted, ) @@ -35,7 +39,7 @@ <Icons.Search /> </span> </div> - <input placeholder="Filter" class="form-control" bind:value={filter} /> + <input placeholder="Filter" class="form-control" bind:value={$filter} /> <div class="input-group-append"> <button class="btn btn-outline-secondary {!showDeduced ? 'active' : ''}" From 753c936f2e1a4eb3bb06ac44f53e840d2539a970 Mon Sep 17 00:00:00 2001 From: James Dabbs <james.dabbs@gmail.com> Date: Sun, 10 Dec 2023 20:22:42 -0800 Subject: [PATCH 5/6] typeset internal links (#99) --- packages/viewer/cypress/e2e/typesetting.spec.ts | 4 +++- packages/viewer/src/components/Shared/Typeset.svelte | 4 ++++ packages/viewer/vite.config.js | 8 ++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/viewer/cypress/e2e/typesetting.spec.ts b/packages/viewer/cypress/e2e/typesetting.spec.ts index cd0d5129..8904e804 100644 --- a/packages/viewer/cypress/e2e/typesetting.spec.ts +++ b/packages/viewer/cypress/e2e/typesetting.spec.ts @@ -12,6 +12,8 @@ it('renders internal links', () => { ) cy.get('[data-testid=output]').contains( - 'Discrete topology on a two-point set is $T_0$ as noted in Discrete topology on a two-point set is $T_0$', + // The T0T_0T0 rendering here is the text representation of the inner html of katex rendered math. + // We're effectively asserting that it _isn't_ still rendered as $T_0$ + 'Discrete topology on a two-point set is T0T_0T0​ as noted in Discrete topology on a two-point set is T0T_0T0​', ) }) diff --git a/packages/viewer/src/components/Shared/Typeset.svelte b/packages/viewer/src/components/Shared/Typeset.svelte index 2006a9b3..f72c0556 100644 --- a/packages/viewer/src/components/Shared/Typeset.svelte +++ b/packages/viewer/src/components/Shared/Typeset.svelte @@ -43,6 +43,10 @@ continue } + $typeset(link.innerHTML, false).then(value => { + link.innerHTML = value + }) + link.setAttribute('_wired', 'true') link.addEventListener('click', e => { e.preventDefault() diff --git a/packages/viewer/vite.config.js b/packages/viewer/vite.config.js index 6488ef4c..f9fb644e 100644 --- a/packages/viewer/vite.config.js +++ b/packages/viewer/vite.config.js @@ -7,10 +7,10 @@ export default defineConfig({ test: { include: ['src/**/*.{test,spec}.{js,ts}'], coverage: { - lines: 80.3, - branches: 86.91, - statements: 80.3, - functions: 81, + lines: 83.09, + branches: 87.36, + statements: 83.09, + functions: 81.81, skipFull: true, thresholdAutoUpdate: true, }, From 4448fb95c0dffdf2cc64b36dfa2b49d3778a1e3a Mon Sep 17 00:00:00 2001 From: James Dabbs <james.dabbs@gmail.com> Date: Sun, 10 Dec 2023 20:59:23 -0800 Subject: [PATCH 6/6] misc. minor style tweaks (#100) - adjust icon styling - fix spacing around ,s in alias lists - correct table header style --- .../viewer/src/components/Shared/Aliases.svelte | 6 ++++-- .../src/components/Shared/Icons/Check.svelte | 17 +++++++++-------- .../viewer/src/components/Shared/Icons/X.svelte | 17 +++++++++-------- .../viewer/src/components/Traits/Table.svelte | 4 ++-- .../viewer/src/components/Traits/Value.svelte | 12 ++++++------ 5 files changed, 30 insertions(+), 26 deletions(-) diff --git a/packages/viewer/src/components/Shared/Aliases.svelte b/packages/viewer/src/components/Shared/Aliases.svelte index 177eaa6e..b89c9768 100644 --- a/packages/viewer/src/components/Shared/Aliases.svelte +++ b/packages/viewer/src/components/Shared/Aliases.svelte @@ -8,8 +8,10 @@ <small> <span class="text-muted">or</span> {#each aliases as alias, i (i)} - <Typeset body={alias} /> - {#if i !== aliases.length - 1}<span class="text-muted comma">,</span>{/if} + <Typeset body={alias} />{#if i !== aliases.length - 1}<span + class="text-muted comma" + >, + </span>{/if} {/each} </small> {/if} diff --git a/packages/viewer/src/components/Shared/Icons/Check.svelte b/packages/viewer/src/components/Shared/Icons/Check.svelte index 11fb5b23..d2f96275 100644 --- a/packages/viewer/src/components/Shared/Icons/Check.svelte +++ b/packages/viewer/src/components/Shared/Icons/Check.svelte @@ -1,13 +1,14 @@ <svg - width="2em" - height="2em" - viewBox="0 0 16 16" class="bi bi-check" + stroke="currentColor" fill="currentColor" + stroke-width="0" + viewBox="0 0 512 512" + style="margin-right: 0.4em;" + height="1em" + width="1em" xmlns="http://www.w3.org/2000/svg" + ><path + d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" + /></svg > - <path - fill-rule="evenodd" - d="M10.97 4.97a.75.75 0 0 1 1.071 1.05l-3.992 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.236.236 0 0 1 .02-.022z" - /> -</svg> diff --git a/packages/viewer/src/components/Shared/Icons/X.svelte b/packages/viewer/src/components/Shared/Icons/X.svelte index 7acc7bc6..e1c94249 100644 --- a/packages/viewer/src/components/Shared/Icons/X.svelte +++ b/packages/viewer/src/components/Shared/Icons/X.svelte @@ -1,13 +1,14 @@ <svg - width="2em" - height="2em" - viewBox="0 0 16 16" class="bi bi-x" + stroke="currentColor" fill="currentColor" + stroke-width="0" + viewBox="0 0 352 512" + style="margin-right: 0.4em;" + height="1em" + width="1em" xmlns="http://www.w3.org/2000/svg" + ><path + d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z" + /></svg > - <path - fill-rule="evenodd" - d="M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z" - /> -</svg> diff --git a/packages/viewer/src/components/Traits/Table.svelte b/packages/viewer/src/components/Traits/Table.svelte index 775a4f72..5522ef62 100644 --- a/packages/viewer/src/components/Traits/Table.svelte +++ b/packages/viewer/src/components/Traits/Table.svelte @@ -17,9 +17,9 @@ <th>Id</th> <th>Name</th> {#each properties as property (property.id)} - <td> + <th> <Link.Property {property} /> - </td> + </th> {/each} </tr> </thead> diff --git a/packages/viewer/src/components/Traits/Value.svelte b/packages/viewer/src/components/Traits/Value.svelte index 0901142c..adbaedf2 100644 --- a/packages/viewer/src/components/Traits/Value.svelte +++ b/packages/viewer/src/components/Traits/Value.svelte @@ -2,21 +2,21 @@ export let value: boolean | undefined export let icon: 'check' | 'user' = 'check' - import { Check, Question, X, Robot, User } from '../Shared/Icons' + import { Icons } from '../Shared' </script> {#if value} {#if icon === 'user'} - <User /> + <Icons.User /> {:else} - <Check /> + <Icons.Check /> {/if} {:else if value === false} {#if icon === 'user'} - <Robot /> + <Icons.Robot /> {:else} - <X /> + <Icons.X /> {/if} {:else}<!-- value === undefined --> - <Question /> + <Icons.Question /> {/if}