diff options
Diffstat (limited to 'frontend/src/lib/Form.ts')
-rw-r--r-- | frontend/src/lib/Form.ts | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/frontend/src/lib/Form.ts b/frontend/src/lib/Form.ts new file mode 100644 index 0000000..ab0f4f7 --- /dev/null +++ b/frontend/src/lib/Form.ts @@ -0,0 +1,76 @@ +import type { FullComicFragment, FullTag, Namespace } from '$gql/graphql'; +import type { OmitIdentifiers } from '$gql/Utils'; +import equal from 'fast-deep-equal'; +import type { Snippet } from 'svelte'; + +export interface FormProps<I, P> { + initial: OmitIdentifiers<I>; + submit: (input: P) => void; + children?: Snippet; +} + +interface Item { + id: number | string; + name: string; +} + +function stringPending(a?: string | null, b?: string | null) { + if (a?.length === 0) { + a = null; + } + + if (b?.length === 0) { + b = null; + } + + return a !== b; +} + +function associationPending(as: Item[], bs: Item[]) { + return !equal( + as.map((a) => a.id), + bs.map((b) => b.id) + ); +} + +export function itemPending(initial: OmitIdentifiers<Item>, current: OmitIdentifiers<Item>) { + return stringPending(initial.name, current.name); +} + +export function namespacePending( + initial: OmitIdentifiers<Namespace>, + current: OmitIdentifiers<Namespace> +) { + return itemPending(initial, current) || stringPending(initial.sortName, current.sortName); +} + +export function tagPending(a: OmitIdentifiers<FullTag>, b: OmitIdentifiers<FullTag>) { + return ( + itemPending(a, b) || + stringPending(a.description, b.description) || + associationPending(a.namespaces, b.namespaces) + ); +} + +export function comicPending(a?: FullComicFragment, b?: OmitIdentifiers<FullComicFragment>) { + if (a === undefined) return b === undefined; + if (b === undefined) return a === undefined; + + return ( + stringPending(a.title, b.title) || + stringPending(a.originalTitle, b.originalTitle) || + stringPending(a.url, b.url) || + stringPending(a.date, b.date) || + a.category !== b.category || + a.rating !== b.rating || + a.censorship !== b.censorship || + a.language !== b.language || + a.direction !== b.direction || + a.layout !== b.layout || + associationPending(a.artists, b.artists) || + associationPending(a.circles, b.circles) || + associationPending(a.characters, b.characters) || + associationPending(a.tags, b.tags) || + associationPending(a.worlds, b.worlds) + ); +} |