diff --git a/packages/viewer/src/components/Dev/Explore.svelte b/packages/viewer/src/components/Dev/Explore.svelte index ba6487a8..4d774614 100644 --- a/packages/viewer/src/components/Dev/Explore.svelte +++ b/packages/viewer/src/components/Dev/Explore.svelte @@ -1,15 +1,10 @@

Entities

@@ -47,10 +42,22 @@ + + + + + + diff --git a/packages/viewer/src/components/Properties/Show.svelte b/packages/viewer/src/components/Properties/Show.svelte index cc4eb43b..a0b05445 100644 --- a/packages/viewer/src/components/Properties/Show.svelte +++ b/packages/viewer/src/components/Properties/Show.svelte @@ -1,6 +1,14 @@ -

Property

+

+ Property + +

diff --git a/packages/viewer/src/components/Shared/Icons/Lean.svelte b/packages/viewer/src/components/Shared/Icons/Lean.svelte new file mode 100644 index 00000000..bc39924d --- /dev/null +++ b/packages/viewer/src/components/Shared/Icons/Lean.svelte @@ -0,0 +1,14 @@ + diff --git a/packages/viewer/src/components/Shared/Icons/index.ts b/packages/viewer/src/components/Shared/Icons/index.ts index 15267334..a56627a0 100644 --- a/packages/viewer/src/components/Shared/Icons/index.ts +++ b/packages/viewer/src/components/Shared/Icons/index.ts @@ -1,6 +1,7 @@ export { default as Branch } from './Branch.svelte' export { default as Check } from './Check.svelte' export { default as Dice } from './Dice.svelte' +export { default as Lean } from './Lean.svelte' export { default as Question } from './Question.svelte' export { default as Repeat } from './Repeat.svelte' export { default as Search } from './Search.svelte' diff --git a/packages/viewer/src/components/Shared/LeanLink.svelte b/packages/viewer/src/components/Shared/LeanLink.svelte new file mode 100644 index 00000000..8a26d953 --- /dev/null +++ b/packages/viewer/src/components/Shared/LeanLink.svelte @@ -0,0 +1,80 @@ + + + + +{#if $showLeanLinks && loaded} + {#if available} +
+ + + +
+ {/if} +{/if} + + diff --git a/packages/viewer/src/components/Shared/index.ts b/packages/viewer/src/components/Shared/index.ts index f7d893de..80d4cd27 100644 --- a/packages/viewer/src/components/Shared/index.ts +++ b/packages/viewer/src/components/Shared/index.ts @@ -5,6 +5,7 @@ export { default as Aliases } from './Aliases.svelte' export { default as Filter } from './Filter.svelte' export { default as Formula } from './Formula.svelte' export { default as Id } from './Id.svelte' +export { default as LeanLink } from './LeanLink.svelte' export { default as Link } from './Link' export { default as Loading } from './Loading.svelte' export { default as NotFound } from './NotFound.svelte' diff --git a/packages/viewer/src/components/Theorems/Show.svelte b/packages/viewer/src/components/Theorems/Show.svelte index 8f469ca8..9ddf4692 100644 --- a/packages/viewer/src/components/Theorems/Show.svelte +++ b/packages/viewer/src/components/Theorems/Show.svelte @@ -1,6 +1,6 @@ -

Theorem

+

+ Theorem + +

diff --git a/packages/viewer/src/components/Traits/Related.svelte b/packages/viewer/src/components/Traits/Related.svelte index 8e1c4d2c..d3685f7d 100644 --- a/packages/viewer/src/components/Traits/Related.svelte +++ b/packages/viewer/src/components/Traits/Related.svelte @@ -5,8 +5,8 @@ import context from '@/context' import type { Property, Space, Trait, Traits } from '@/models' import FilterButtons from './FilterButtons.svelte' - import { defaultStorage } from '@/repositories' import { writable } from 'svelte/store' + import { showRedundancy } from '@/stores/settings' import urlSearchParam from '@/stores/urlSearchParam' import { checkIfRedundant } from '@/stores/deduction' @@ -21,8 +21,6 @@ let filterMode: 'all' | 'known' | 'asserted' | 'true' | 'false' | 'missing' filterMode = 'known' - let showRedundancy = defaultStorage.getItem('showRedundancy') != null - $: all = related($traits) // all has type [Space, Property, Trait][] // we need to index names in different positions depending on which kind we @@ -109,10 +107,9 @@ diff --git a/packages/viewer/src/stores/settings.test.ts b/packages/viewer/src/stores/settings.test.ts new file mode 100644 index 00000000..b86db960 --- /dev/null +++ b/packages/viewer/src/stores/settings.test.ts @@ -0,0 +1,85 @@ +import { beforeEach, describe, expect, it } from 'vitest' +import { get } from 'svelte/store' +import { persistedBoolean, showLeanLinks, showRedundancy } from './settings' + +function mockStorage() { + const data: Record = {} + return { + data, + getItem: (key: string) => data[key] ?? null, + setItem: (key: string, value: string) => { + data[key] = value + }, + removeItem: (key: string) => { + delete data[key] + }, + } +} + +describe('persistedBoolean', () => { + it('defaults to the given default value when storage is empty', () => { + const storage = mockStorage() + const store = persistedBoolean('flag', false, storage) + expect(get(store)).toBe(false) + }) + + it('initializes to true when the key already exists in storage', () => { + const storage = mockStorage() + storage.data['flag'] = 'show' + const store = persistedBoolean('flag', false, storage) + expect(get(store)).toBe(true) + }) + + it('writes to storage when set to true', () => { + const storage = mockStorage() + const store = persistedBoolean('flag', false, storage) + store.set(true) + expect(storage.data['flag']).toBe('show') + }) + + it('removes from storage when set to false', () => { + const storage = mockStorage() + storage.data['flag'] = 'show' + const store = persistedBoolean('flag', true, storage) + store.set(false) + expect(storage.data['flag']).toBeUndefined() + }) + + it('reflects updates via subscribe', () => { + const storage = mockStorage() + const store = persistedBoolean('flag', false, storage) + const values: boolean[] = [] + store.subscribe(v => values.push(v)) + + store.set(true) + store.set(false) + + expect(values).toEqual([false, true, false]) + }) +}) + +describe('showLeanLinks', () => { + it('defaults to false', () => { + expect(get(showLeanLinks)).toBe(false) + }) + + it('can be toggled', () => { + showLeanLinks.set(true) + expect(get(showLeanLinks)).toBe(true) + showLeanLinks.set(false) + expect(get(showLeanLinks)).toBe(false) + }) +}) + +describe('showRedundancy', () => { + it('defaults to false', () => { + expect(get(showRedundancy)).toBe(false) + }) + + it('can be toggled', () => { + showRedundancy.set(true) + expect(get(showRedundancy)).toBe(true) + showRedundancy.set(false) + expect(get(showRedundancy)).toBe(false) + }) +}) diff --git a/packages/viewer/src/stores/settings.ts b/packages/viewer/src/stores/settings.ts new file mode 100644 index 00000000..f0a51117 --- /dev/null +++ b/packages/viewer/src/stores/settings.ts @@ -0,0 +1,25 @@ +import { writable } from 'svelte/store' +import { defaultStorage } from '@/repositories' + +export function persistedBoolean( + key: string, + defaultValue: boolean, + storage: Pick = defaultStorage, +) { + const store = writable( + storage.getItem(key) !== null ? true : defaultValue, + ) + + store.subscribe(v => { + if (v) { + storage.setItem(key, 'show') + } else { + storage.removeItem(key) + } + }) + + return store +} + +export const showLeanLinks = persistedBoolean('showLeanLinks', false) +export const showRedundancy = persistedBoolean('showRedundancy', false)