summaryrefslogtreecommitdiffstatshomepage
path: root/frontend/src/lib/Form.ts
diff options
context:
space:
mode:
authorWolfgang Müller2025-02-13 17:52:16 +0100
committerWolfgang Müller2025-02-13 17:52:16 +0100
commitdc4db405d2991d3ec6a114f3b08d3fccd057d3ee (patch)
tree2c620c9af2062ba09fa591f8b3ed961664adab58 /frontend/src/lib/Form.ts
parent4df870d793123be95c8af031a340a39b5b8402ac (diff)
downloadhircine-dc4db405d2991d3ec6a114f3b08d3fccd057d3ee.tar.gz
frontend: Migrate to Svelte 5
Diffstat (limited to 'frontend/src/lib/Form.ts')
-rw-r--r--frontend/src/lib/Form.ts76
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)
+ );
+}