From 9010be260b5226c2280940e252e331361b6f367a Mon Sep 17 00:00:00 2001
From: Konrad Mohrfeldt <konrad.mohrfeldt@farbdev.org>
Date: Thu, 6 Apr 2023 13:06:40 +0200
Subject: [PATCH] feat: add pinia API store for images

closes #138
---
 src/stores/auth.ts   | 11 +++++++++
 src/stores/images.ts | 57 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)
 create mode 100644 src/stores/images.ts

diff --git a/src/stores/auth.ts b/src/stores/auth.ts
index a3eddac1..9711815f 100644
--- a/src/stores/auth.ts
+++ b/src/stores/auth.ts
@@ -145,3 +145,14 @@ axios.interceptors.request.use((config) => {
 
   return config
 })
+
+export const steeringAuthInit: { getRequestDefaults: () => RequestInit } = {
+  getRequestDefaults() {
+    const authStore = useAuthStore()
+    return {
+      headers: {
+        Authorization: `Bearer ${authStore.currentUser?.oidcAccessToken}`,
+      },
+    }
+  },
+}
diff --git a/src/stores/images.ts b/src/stores/images.ts
new file mode 100644
index 00000000..5b18ae32
--- /dev/null
+++ b/src/stores/images.ts
@@ -0,0 +1,57 @@
+import { defineStore } from 'pinia'
+import { computed, ComputedRef, watchEffect } from 'vue'
+import type { Ref } from 'vue'
+import { steeringAuthInit } from '@/stores/auth'
+
+import {
+  APICreate,
+  APIListPaginated,
+  APIRemove,
+  APIRetrieve,
+  APIUpdate,
+  createExtendableAPI,
+  createSteeringURL,
+} from '@/api'
+
+export type Image = {
+  id: number
+  alt_text: string
+  credits: string
+  image: string
+  file?: File
+  ppoi: string
+  width: number | null
+  height: number | null
+  thumbnails: readonly string[]
+}
+export type NewImage = Omit<Image, 'id'> & { file: File }
+type ReadonlyAttrs = 'id' | 'width' | 'height' | 'thumbnails' | 'file' | 'image'
+type ImageCreateData = Omit<Image, ReadonlyAttrs> & { image: File }
+type ImageUpdateData = Partial<Omit<Image, ReadonlyAttrs>>
+
+export const useImageStore = defineStore('images', () => {
+  const endpoint = createSteeringURL.prefix('images')
+  const { base, ...api } = createExtendableAPI<Image>(endpoint, steeringAuthInit)
+  return {
+    ...base,
+    ...APIListPaginated(api),
+    ...APIRetrieve(api),
+    ...APICreate<Image, ImageCreateData>(api),
+    ...APIUpdate<Image, ImageUpdateData>(api),
+    ...APIRemove(api),
+  }
+})
+
+export function useImage(id: Ref<number | null>): ComputedRef<Image | null> {
+  const imageStore = useImageStore()
+  const image = computed(() => {
+    return id.value !== null ? imageStore.itemMap.get(id.value) ?? null : null
+  })
+  watchEffect(async () => {
+    if (id.value) {
+      // Force an API request in case the image is not yet in the store.
+      await imageStore.retrieve(id.value, undefined, { useCached: true })
+    }
+  })
+  return image
+}
-- 
GitLab