diff --git a/next-ui/src/colada/queries/actuator-info.test.ts b/next-ui/src/colada/actuator-info.test.ts
similarity index 95%
rename from next-ui/src/colada/queries/actuator-info.test.ts
rename to next-ui/src/colada/actuator-info.test.ts
index 8b022fd1..7abbfa07 100644
--- a/next-ui/src/colada/queries/actuator-info.test.ts
+++ b/next-ui/src/colada/actuator-info.test.ts
@@ -1,6 +1,6 @@
import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest'
import { server } from '@/mocks/api/node'
-import { useActuatorInfo } from '@/colada/queries/actuator-info'
+import { useActuatorInfo } from '@/colada/actuator-info'
import { createMockColada } from '@/mocks/pinia-colada'
import { enableAutoUnmount } from '@vue/test-utils'
import type { ErrorCause } from '@/api/komga-client'
diff --git a/next-ui/src/colada/queries/actuator-info.ts b/next-ui/src/colada/actuator-info.ts
similarity index 100%
rename from next-ui/src/colada/queries/actuator-info.ts
rename to next-ui/src/colada/actuator-info.ts
diff --git a/next-ui/src/colada/queries/announcements.test.ts b/next-ui/src/colada/announcements.test.ts
similarity index 90%
rename from next-ui/src/colada/queries/announcements.test.ts
rename to next-ui/src/colada/announcements.test.ts
index 2afec7b6..60452bf8 100644
--- a/next-ui/src/colada/queries/announcements.test.ts
+++ b/next-ui/src/colada/announcements.test.ts
@@ -1,7 +1,7 @@
import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest'
import { server } from '@/mocks/api/node'
import { createMockColada } from '@/mocks/pinia-colada'
-import { useAnnouncements } from '@/colada/queries/announcements'
+import { useAnnouncements } from '@/colada/announcements'
import { enableAutoUnmount } from '@vue/test-utils'
beforeAll(() => server.listen())
diff --git a/next-ui/src/colada/announcements.ts b/next-ui/src/colada/announcements.ts
new file mode 100644
index 00000000..830389ce
--- /dev/null
+++ b/next-ui/src/colada/announcements.ts
@@ -0,0 +1,36 @@
+import { defineMutation, defineQuery, useMutation, useQuery, useQueryCache } from '@pinia/colada'
+import { komgaClient } from '@/api/komga-client'
+
+export const QUERY_KEYS_ANNOUNCEMENTS = {
+ root: ['announcements'] as const,
+}
+
+export const useAnnouncements = defineQuery(() => {
+ const { data, ...rest } = useQuery({
+ key: () => QUERY_KEYS_ANNOUNCEMENTS.root,
+ query: () =>
+ komgaClient
+ .GET('/api/v1/announcements')
+ // unwrap the openapi-fetch structure on success
+ .then((res) => res.data),
+ // 1 hour
+ staleTime: 60 * 60 * 1000,
+ gcTime: false,
+ })
+
+ const unreadCount = computed(
+ () => data.value?.items?.filter((x) => false == x._komga?.read)?.length || 0,
+ )
+
+ return { ...rest, data, unreadCount }
+})
+export const useMarkAnnouncementsRead = defineMutation(() => {
+ const queryCache = useQueryCache()
+ return useMutation({
+ mutation: (announcementIds: string[]) =>
+ komgaClient.PUT('/api/v1/announcements', { body: announcementIds }),
+ onSuccess: () => {
+ void queryCache.invalidateQueries({ key: QUERY_KEYS_ANNOUNCEMENTS.root })
+ },
+ })
+})
diff --git a/next-ui/src/colada/queries/app-releases.test.ts b/next-ui/src/colada/app-releases.test.ts
similarity index 92%
rename from next-ui/src/colada/queries/app-releases.test.ts
rename to next-ui/src/colada/app-releases.test.ts
index d85bfc09..e4857474 100644
--- a/next-ui/src/colada/queries/app-releases.test.ts
+++ b/next-ui/src/colada/app-releases.test.ts
@@ -1,7 +1,7 @@
import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest'
import { server } from '@/mocks/api/node'
import { createMockColada } from '@/mocks/pinia-colada'
-import { useAppReleases } from '@/colada/queries/app-releases'
+import { useAppReleases } from '@/colada/app-releases'
import { enableAutoUnmount } from '@vue/test-utils'
beforeAll(() => server.listen())
diff --git a/next-ui/src/colada/queries/app-releases.ts b/next-ui/src/colada/app-releases.ts
similarity index 93%
rename from next-ui/src/colada/queries/app-releases.ts
rename to next-ui/src/colada/app-releases.ts
index e0aa9ccc..71c2192c 100644
--- a/next-ui/src/colada/queries/app-releases.ts
+++ b/next-ui/src/colada/app-releases.ts
@@ -1,6 +1,6 @@
import { defineQuery, useQuery } from '@pinia/colada'
import { komgaClient } from '@/api/komga-client'
-import { useActuatorInfo } from '@/colada/queries/actuator-info'
+import { useActuatorInfo } from '@/colada/actuator-info'
export const useAppReleases = defineQuery(() => {
const { data, ...rest } = useQuery({
diff --git a/next-ui/src/colada/queries/libraries.ts b/next-ui/src/colada/libraries.ts
similarity index 100%
rename from next-ui/src/colada/queries/libraries.ts
rename to next-ui/src/colada/libraries.ts
diff --git a/next-ui/src/colada/mutations/logout.ts b/next-ui/src/colada/mutations/logout.ts
deleted file mode 100644
index 4da07bc6..00000000
--- a/next-ui/src/colada/mutations/logout.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { defineMutation, useMutation, useQueryCache } from '@pinia/colada'
-import { komgaClient } from '@/api/komga-client'
-
-export const useLogout = defineMutation(() => {
- const queryCache = useQueryCache()
- return useMutation({
- mutation: () => komgaClient.POST('/api/logout'),
- onSuccess: () => {
- void queryCache.invalidateQueries({ key: ['current-user'] })
- },
- onError: (error) => {
- console.log('logout error', error)
- },
- })
-})
diff --git a/next-ui/src/colada/mutations/mark-announcements-read.ts b/next-ui/src/colada/mutations/mark-announcements-read.ts
deleted file mode 100644
index e1b7bb78..00000000
--- a/next-ui/src/colada/mutations/mark-announcements-read.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { defineMutation, useMutation, useQueryCache } from '@pinia/colada'
-import { komgaClient } from '@/api/komga-client'
-
-export const useMarkAnnouncementsRead = defineMutation(() => {
- const queryCache = useQueryCache()
- return useMutation({
- mutation: (announcementIds: string[]) =>
- komgaClient.PUT('/api/v1/announcements', { body: announcementIds }),
- onSuccess: () => {
- void queryCache.invalidateQueries({ key: ['announcements'] })
- },
- onError: (error) => {
- console.log('announcements mark read error', error)
- },
- })
-})
diff --git a/next-ui/src/colada/mutations/update-user.ts b/next-ui/src/colada/mutations/update-user.ts
deleted file mode 100644
index a6d32489..00000000
--- a/next-ui/src/colada/mutations/update-user.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { defineMutation, useMutation, useQueryCache } from '@pinia/colada'
-import { komgaClient } from '@/api/komga-client'
-import type { components } from '@/generated/openapi/komga'
-
-export const useCreateUser = defineMutation(() => {
- const queryCache = useQueryCache()
- return useMutation({
- mutation: (user: components['schemas']['UserCreationDto']) =>
- komgaClient.POST('/api/v2/users', {
- body: user,
- }),
- onSuccess: () => {
- void queryCache.invalidateQueries({ key: ['users'] })
- },
- })
-})
-export const useUpdateUser = defineMutation(() => {
- const queryCache = useQueryCache()
- return useMutation({
- mutation: (user: components['schemas']['UserDto']) =>
- komgaClient.PATCH('/api/v2/users/{id}', {
- params: { path: { id: user.id } },
- body: user,
- }),
- onSuccess: () => {
- void queryCache.invalidateQueries({ key: ['users'] })
- },
- })
-})
-
-export const useUpdateUserPassword = defineMutation(() => {
- return useMutation({
- mutation: ({ userId, newPassword }: { userId: string; newPassword: string }) =>
- komgaClient.PATCH('/api/v2/users/{id}/password', {
- params: { path: { id: userId } },
- body: {
- password: newPassword,
- },
- }),
- })
-})
-
-export const useDeleteUser = defineMutation(() => {
- const queryCache = useQueryCache()
- return useMutation({
- mutation: (userId: string) =>
- komgaClient.DELETE('/api/v2/users/{id}', {
- params: { path: { id: userId } },
- }),
- onSuccess: () => {
- void queryCache.invalidateQueries({ key: ['users'] })
- },
- })
-})
diff --git a/next-ui/src/colada/queries/announcements.ts b/next-ui/src/colada/queries/announcements.ts
deleted file mode 100644
index 782048af..00000000
--- a/next-ui/src/colada/queries/announcements.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { defineQuery, useQuery } from '@pinia/colada'
-import { komgaClient } from '@/api/komga-client'
-
-export const useAnnouncements = defineQuery(() => {
- const { data, ...rest } = useQuery({
- key: () => ['announcements'],
- query: () =>
- komgaClient
- .GET('/api/v1/announcements')
- // unwrap the openapi-fetch structure on success
- .then((res) => res.data),
- // 1 hour
- staleTime: 60 * 60 * 1000,
- gcTime: false,
- })
-
- const unreadCount = computed(
- () => data.value?.items?.filter((x) => false == x._komga?.read)?.length || 0,
- )
-
- return { ...rest, data, unreadCount }
-})
diff --git a/next-ui/src/colada/queries/current-user.ts b/next-ui/src/colada/queries/current-user.ts
deleted file mode 100644
index 59340ec6..00000000
--- a/next-ui/src/colada/queries/current-user.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { defineQuery, useQuery } from '@pinia/colada'
-import { komgaClient } from '@/api/komga-client'
-import { UserRoles } from '@/types/UserRoles'
-
-export const useCurrentUser = defineQuery(() => {
- const { data, ...rest } = useQuery({
- key: () => ['current-user'],
- query: () =>
- komgaClient
- .GET('/api/v2/users/me')
- // unwrap the openapi-fetch structure on success
- .then((res) => res.data),
- // 10 minutes
- staleTime: 10 * 60 * 1000,
- gcTime: false,
- autoRefetch: true,
- })
-
- const hasRole = (role: UserRoles) => data.value?.roles.includes(role)
- const isAdmin = computed(() => hasRole(UserRoles.ADMIN))
-
- return {
- data,
- ...rest,
- hasRole,
- isAdmin,
- }
-})
diff --git a/next-ui/src/colada/queries/users.ts b/next-ui/src/colada/queries/users.ts
deleted file mode 100644
index 281bf43a..00000000
--- a/next-ui/src/colada/queries/users.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { defineQuery, useQuery } from '@pinia/colada'
-import { komgaClient } from '@/api/komga-client'
-
-export const useUsers = defineQuery(() => {
- return useQuery({
- key: () => ['users'],
- query: () =>
- komgaClient
- .GET('/api/v2/users')
- // unwrap the openapi-fetch structure on success
- .then((res) => res.data),
- })
-})
diff --git a/next-ui/src/colada/queries/referential.ts b/next-ui/src/colada/referential.ts
similarity index 100%
rename from next-ui/src/colada/queries/referential.ts
rename to next-ui/src/colada/referential.ts
diff --git a/next-ui/src/colada/users.ts b/next-ui/src/colada/users.ts
new file mode 100644
index 00000000..eb12df94
--- /dev/null
+++ b/next-ui/src/colada/users.ts
@@ -0,0 +1,107 @@
+import { defineMutation, defineQuery, useMutation, useQuery, useQueryCache } from '@pinia/colada'
+import { komgaClient } from '@/api/komga-client'
+import { UserRoles } from '@/types/UserRoles'
+import type { components } from '@/generated/openapi/komga'
+
+export const QUERY_KEYS_USERS = {
+ root: ['users'] as const,
+ currentUser: ['current-user'] as const,
+}
+
+export const useUsers = defineQuery(() => {
+ return useQuery({
+ key: () => QUERY_KEYS_USERS.root,
+ query: () =>
+ komgaClient
+ .GET('/api/v2/users')
+ // unwrap the openapi-fetch structure on success
+ .then((res) => res.data),
+ })
+})
+
+export const useCurrentUser = defineQuery(() => {
+ const { data, ...rest } = useQuery({
+ key: () => QUERY_KEYS_USERS.currentUser,
+ query: () =>
+ komgaClient
+ .GET('/api/v2/users/me')
+ // unwrap the openapi-fetch structure on success
+ .then((res) => res.data),
+ // 10 minutes
+ staleTime: 10 * 60 * 1000,
+ gcTime: false,
+ autoRefetch: true,
+ })
+
+ const hasRole = (role: UserRoles) => data.value?.roles.includes(role)
+ const isAdmin = computed(() => hasRole(UserRoles.ADMIN))
+
+ return {
+ data,
+ ...rest,
+ hasRole,
+ isAdmin,
+ }
+})
+
+export const useLogout = defineMutation(() => {
+ const queryCache = useQueryCache()
+ return useMutation({
+ mutation: () => komgaClient.POST('/api/logout'),
+ onSuccess: () => {
+ void queryCache.invalidateQueries({ key: QUERY_KEYS_USERS.currentUser })
+ },
+ })
+})
+
+export const useCreateUser = defineMutation(() => {
+ const queryCache = useQueryCache()
+ return useMutation({
+ mutation: (user: components['schemas']['UserCreationDto']) =>
+ komgaClient.POST('/api/v2/users', {
+ body: user,
+ }),
+ onSuccess: () => {
+ void queryCache.invalidateQueries({ key: QUERY_KEYS_USERS.root })
+ },
+ })
+})
+
+export const useUpdateUser = defineMutation(() => {
+ const queryCache = useQueryCache()
+ return useMutation({
+ mutation: (user: components['schemas']['UserDto']) =>
+ komgaClient.PATCH('/api/v2/users/{id}', {
+ params: { path: { id: user.id } },
+ body: user,
+ }),
+ onSuccess: () => {
+ void queryCache.invalidateQueries({ key: QUERY_KEYS_USERS.root })
+ },
+ })
+})
+
+export const useUpdateUserPassword = defineMutation(() => {
+ return useMutation({
+ mutation: ({ userId, newPassword }: { userId: string; newPassword: string }) =>
+ komgaClient.PATCH('/api/v2/users/{id}/password', {
+ params: { path: { id: userId } },
+ body: {
+ password: newPassword,
+ },
+ }),
+ })
+})
+
+export const useDeleteUser = defineMutation(() => {
+ const queryCache = useQueryCache()
+ return useMutation({
+ mutation: (userId: string) =>
+ komgaClient.DELETE('/api/v2/users/{id}', {
+ params: { path: { id: userId } },
+ }),
+ onSuccess: () => {
+ void queryCache.invalidateQueries({ key: QUERY_KEYS_USERS.root })
+ },
+ })
+})
diff --git a/next-ui/src/fragments/fragment/BuildCommit.vue b/next-ui/src/fragments/fragment/BuildCommit.vue
index a28f0564..0fbcd94b 100644
--- a/next-ui/src/fragments/fragment/BuildCommit.vue
+++ b/next-ui/src/fragments/fragment/BuildCommit.vue
@@ -14,7 +14,7 @@
diff --git a/next-ui/src/fragments/layout/app/drawer/menu/Logout.vue b/next-ui/src/fragments/layout/app/drawer/menu/Logout.vue
index e0251ceb..4680c192 100644
--- a/next-ui/src/fragments/layout/app/drawer/menu/Logout.vue
+++ b/next-ui/src/fragments/layout/app/drawer/menu/Logout.vue
@@ -13,7 +13,7 @@
diff --git a/next-ui/src/fragments/layout/app/drawer/menu/Server.vue b/next-ui/src/fragments/layout/app/drawer/menu/Server.vue
index 93a24da6..55f99fb7 100644
--- a/next-ui/src/fragments/layout/app/drawer/menu/Server.vue
+++ b/next-ui/src/fragments/layout/app/drawer/menu/Server.vue
@@ -99,7 +99,7 @@
diff --git a/next-ui/src/pages/server/announcements.vue b/next-ui/src/pages/server/announcements.vue
index 92085e40..f62a8876 100644
--- a/next-ui/src/pages/server/announcements.vue
+++ b/next-ui/src/pages/server/announcements.vue
@@ -57,8 +57,7 @@