summaryrefslogtreecommitdiffstatshomepage
path: root/frontend/src/lib/Update.ts
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/lib/Update.ts')
-rw-r--r--frontend/src/lib/Update.ts97
1 files changed, 97 insertions, 0 deletions
diff --git a/frontend/src/lib/Update.ts b/frontend/src/lib/Update.ts
new file mode 100644
index 0000000..507dd52
--- /dev/null
+++ b/frontend/src/lib/Update.ts
@@ -0,0 +1,97 @@
+import {
+ UpdateMode,
+ type UpdateComicInput,
+ type UpdateOptions,
+ type UpdateTagInput
+} from '$gql/graphql';
+
+type Key = string | number | symbol;
+
+interface AssociationUpdate {
+ ids?: number[] | string[] | null;
+ options?: UpdateOptions | null;
+}
+
+type Input<T, K extends Key> = {
+ [Property in K]?: T | null;
+};
+
+abstract class Entry<K extends Key> {
+ key: K;
+
+ constructor(key: K) {
+ this.key = key;
+ }
+
+ abstract integrate(input: Input<unknown, K>): void;
+ abstract hasInput(): boolean;
+}
+
+class Association<K extends Key> extends Entry<K> {
+ ids = [];
+ options = {
+ mode: UpdateMode.Add
+ };
+
+ constructor(key: K) {
+ super(key);
+ }
+
+ integrate(input: Input<AssociationUpdate, K>) {
+ if (this.hasInput()) {
+ input[this.key] = { ids: this.ids, options: this.options };
+ }
+ }
+
+ hasInput() {
+ return this.ids.length > 0;
+ }
+}
+
+class Enum<K extends Key> extends Entry<K> {
+ value?: string = undefined;
+
+ constructor(key: K) {
+ super(key);
+ }
+
+ integrate(input: Input<string, K>): void {
+ if (this.hasInput()) {
+ input[this.key] = this.value;
+ }
+ }
+
+ hasInput() {
+ return this.value !== undefined && this.value !== null;
+ }
+}
+
+abstract class Controls<I> {
+ toInput() {
+ const input = {} as I;
+ Object.values(this).forEach((v: Entry<keyof I>) => v.integrate(input));
+ return input;
+ }
+
+ hasInput() {
+ return Object.values(this).some((i: Entry<keyof I>) => i.hasInput());
+ }
+}
+
+export class UpdateTagsControls extends Controls<UpdateTagInput> {
+ namespaces = new Association('namespaces');
+}
+
+export class UpdateComicsControls extends Controls<UpdateComicInput> {
+ artists = new Association('artists');
+ category = new Enum('category');
+ censorship = new Enum('censorship');
+ direction = new Enum('direction');
+ layout = new Enum('layout');
+ characters = new Association('characters');
+ circles = new Association('circles');
+ language = new Enum('language');
+ rating = new Enum('rating');
+ tags = new Association('tags');
+ worlds = new Association('worlds');
+}