From 50bcd00361f545f0841cc83c377dff93f18b3a74 Mon Sep 17 00:00:00 2001 From: zurdi Date: Wed, 3 Jul 2024 01:29:01 +0200 Subject: [PATCH] added remove rom from collection dialog --- backend/endpoints/collections.py | 12 +- backend/endpoints/responses/collection.py | 1 + .../__generated__/models/CollectionSchema.ts | 2 + .../src/components/Gallery/FabOverlay.vue | 39 ++-- .../common/Collection/Dialog/AddRoms.vue | 197 ++++++++++++++++++ .../Collection/Dialog/CreateCollection.vue | 7 +- .../Collection/Dialog/EditCollection.vue | 16 +- .../common/Collection/Dialog/RemoveRoms.vue | 175 ++++++++++++++++ .../components/common/Collection/ListItem.vue | 7 +- .../components/common/Collection/RAvatar.vue | 13 +- .../src/components/common/Game/AdminMenu.vue | 16 +- .../common/Game/Dialog/AddToCollection.vue | 10 +- .../common/Game/Dialog/DeleteRom.vue | 10 +- .../src/components/common/Game/RAvatar.vue | 16 +- frontend/src/components/common/Game/Table.vue | 10 +- frontend/src/types/emitter.d.ts | 2 + frontend/src/views/Gallery/Collection.vue | 10 +- frontend/src/views/Home.vue | 4 + frontend/src/views/Play/Base.vue | 10 +- frontend/src/views/Scan.vue | 10 +- 20 files changed, 478 insertions(+), 89 deletions(-) create mode 100644 frontend/src/components/common/Collection/Dialog/AddRoms.vue create mode 100644 frontend/src/components/common/Collection/Dialog/RemoveRoms.vue diff --git a/backend/endpoints/collections.py b/backend/endpoints/collections.py index 16da33bda..7511014f2 100644 --- a/backend/endpoints/collections.py +++ b/backend/endpoints/collections.py @@ -97,18 +97,18 @@ async def update_collection(request: Request, id: int) -> MessageResponse: if not collection: raise CollectionNotFoundInDatabaseException(id) - roms = collection.roms # Default to the roms list from the database - - if "roms" in data: + try: try: - roms = json.loads(data.get("roms")) + roms = json.loads(data["roms"]) except json.JSONDecodeError: - raise ValueError("Invalid JSON for roms field") + raise ValueError("Invalid list for roms field in update collection") + except KeyError: + roms = collection.roms cleaned_data = { "name": data.get("name", collection.name), "description": data.get("description", collection.description), - "roms": roms, + "roms": list(set(roms)), "is_public": data.get("is_public", collection.is_public), "user_id": request.user.id, } diff --git a/backend/endpoints/responses/collection.py b/backend/endpoints/responses/collection.py index 484c96be5..a78defb4e 100644 --- a/backend/endpoints/responses/collection.py +++ b/backend/endpoints/responses/collection.py @@ -9,6 +9,7 @@ class CollectionSchema(BaseModel): description: str path_cover_l: str | None path_cover_s: str | None + has_cover: bool url_cover: str roms: set[int] rom_count: int diff --git a/frontend/src/__generated__/models/CollectionSchema.ts b/frontend/src/__generated__/models/CollectionSchema.ts index 481255ea9..762969e9b 100644 --- a/frontend/src/__generated__/models/CollectionSchema.ts +++ b/frontend/src/__generated__/models/CollectionSchema.ts @@ -9,6 +9,8 @@ export type CollectionSchema = { description: string; path_cover_l: string | null; path_cover_s: string | null; + has_cover: boolean; + url_cover: string; roms: Array; rom_count: number; user_id: number; diff --git a/frontend/src/components/Gallery/FabOverlay.vue b/frontend/src/components/Gallery/FabOverlay.vue index cbb90b08e..b099de106 100644 --- a/frontend/src/components/Gallery/FabOverlay.vue +++ b/frontend/src/components/Gallery/FabOverlay.vue @@ -118,35 +118,50 @@ function onDownload() { - mdi-download - + @click="onScan" + /> - mdi-magnify-scan - + @click="onDownload" + /> + +import RAvatarCollection from "@/components/common/Collection/RAvatar.vue"; +import RAvatarRom from "@/components/common/Game/RAvatar.vue"; +import RDialog from "@/components/common/RDialog.vue"; +import type { UpdateCollection } from "@/services/api/collection"; +import collectionApi from "@/services/api/collection"; +import storeCollections from "@/stores/collections"; +import { type SimpleRom } from "@/stores/roms"; +import type { Events } from "@/types/emitter"; +import type { Emitter } from "mitt"; +import { inject, ref, watch } from "vue"; +import { useDisplay, useTheme } from "vuetify"; + +// Props +const theme = useTheme(); +const { mdAndUp } = useDisplay(); +const show = ref(false); +const collectionsStore = storeCollections(); +const selectedCollection = ref(); +const roms = ref([]); +const emitter = inject>("emitter"); +emitter?.on("showAddToCollectionDialog", (romsToAdd) => { + roms.value = romsToAdd; + updateDataTablePages(); + show.value = true; +}); +const HEADERS = [ + { + title: "Name", + align: "start", + sortable: true, + key: "name", + }, +] as const; +const page = ref(1); +const itemsPerPage = ref(10); +const pageCount = ref(0); +const PER_PAGE_OPTIONS = [10, 25, 50, 100]; + +// Functions +async function addRomsToCollection() { + if (!selectedCollection.value) return; + selectedCollection.value.roms.push(...roms.value.map((r) => r.id)); + await collectionApi + .updateCollection({ collection: selectedCollection.value }) + .then(({ data }) => { + emitter?.emit("snackbarShow", { + msg: `Roms added to ${selectedCollection.value?.name} successfully!`, + icon: "mdi-check-bold", + color: "green", + timeout: 2000, + }); + }) + .catch((error) => { + console.log(error); + emitter?.emit("snackbarShow", { + msg: error.response.data.detail, + icon: "mdi-close-circle", + color: "red", + }); + return; + }) + .finally(() => { + emitter?.emit("showLoadingDialog", { loading: false, scrim: false }); + closeDialog(); + }); +} + +function updateDataTablePages() { + pageCount.value = Math.ceil(roms.value.length / itemsPerPage.value); +} + +watch(itemsPerPage, async () => { + updateDataTablePages(); +}); + +function closeDialog() { + roms.value = []; + show.value = false; + selectedCollection.value = undefined; +} + + + diff --git a/frontend/src/components/common/Collection/Dialog/CreateCollection.vue b/frontend/src/components/common/Collection/Dialog/CreateCollection.vue index cd268abfc..416e2e141 100644 --- a/frontend/src/components/common/Collection/Dialog/CreateCollection.vue +++ b/frontend/src/components/common/Collection/Dialog/CreateCollection.vue @@ -177,7 +177,12 @@ function closeDialog() { Cancel - + Create diff --git a/frontend/src/components/common/Collection/Dialog/EditCollection.vue b/frontend/src/components/common/Collection/Dialog/EditCollection.vue index aa84256be..1c27c17a8 100644 --- a/frontend/src/components/common/Collection/Dialog/EditCollection.vue +++ b/frontend/src/components/common/Collection/Dialog/EditCollection.vue @@ -1,10 +1,9 @@ + + diff --git a/frontend/src/components/common/Collection/ListItem.vue b/frontend/src/components/common/Collection/ListItem.vue index d49139253..5e0f52f3f 100644 --- a/frontend/src/components/common/Collection/ListItem.vue +++ b/frontend/src/components/common/Collection/ListItem.vue @@ -13,12 +13,7 @@ defineProps<{ collection: Collection }>(); :value="collection.name" > +import type { Collection } from "@/stores/collections"; import { useTheme } from "vuetify"; -withDefaults(defineProps<{ src?: string | null; size?: number }>(), { size: 45 }); +withDefaults(defineProps<{ collection: Collection; size?: number }>(), { + size: 45, +}); const theme = useTheme(); @@ -9,12 +12,16 @@ const theme = useTheme(); diff --git a/frontend/src/components/common/Game/AdminMenu.vue b/frontend/src/components/common/Game/AdminMenu.vue index 2d4646beb..5acac2a3f 100644 --- a/frontend/src/components/common/Game/AdminMenu.vue +++ b/frontend/src/components/common/Game/AdminMenu.vue @@ -39,12 +39,12 @@ const heartbeat = storeHeartbeat(); {{ - !heartbeat.value.STEAMGRIDDB_ENABLED ? "SteamgridDB is not enabled" : "" + !heartbeat.value.STEAMGRIDDB_ENABLED + ? "SteamgridDB is not enabled" + : "" }} - - + + + Add to + collection + + + {{ item.name }} {{ item.name }} -withDefaults(defineProps<{ src: string; size?: number }>(), { size: 45 }); +import type { SimpleRom } from "@/stores/roms"; +import { useTheme } from "vuetify"; + +withDefaults(defineProps<{ rom: SimpleRom; size?: number }>(), { size: 45 }); +const theme = useTheme(); diff --git a/frontend/src/components/common/Game/Table.vue b/frontend/src/components/common/Game/Table.vue index e89805a53..bcb98c33f 100644 --- a/frontend/src/components/common/Game/Table.vue +++ b/frontend/src/components/common/Game/Table.vue @@ -120,15 +120,7 @@ onMounted(() => { {{ item.name }} { const routeCollectionId = Number(route.params.collection); - const routeCollection = collections.get(routeCollectionId); + const routeCollection = collectionsStore.get(routeCollectionId); if (!routeCollection) { await collectionApi .getCollection(routeCollectionId) .then((data) => { - collections.add(data.data); + collectionsStore.add(data.data); romsStore.setCurrentCollection(data.data); }) .catch((error) => { @@ -232,10 +232,10 @@ onBeforeRouteUpdate(async (to, from) => { resetGallery(); const routeCollectionId = Number(to.params.collection); - const routeCollection = collections.get(routeCollectionId); + const routeCollection = collectionsStore.get(routeCollectionId); if (!routeCollection) { const { data } = await collectionApi.getCollection(routeCollectionId); - collections.add(data); + collectionsStore.add(data); } else { romsStore.setCurrentCollection(routeCollection); } diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue index 579c1be9b..fb0188f09 100644 --- a/frontend/src/views/Home.vue +++ b/frontend/src/views/Home.vue @@ -9,6 +9,8 @@ import DeletePlatformBindingDialog from "@/components/Management/Dialog/DeletePl import DeletePlatformVersionDialog from "@/components/Management/Dialog/DeletePlatformVersion.vue"; import CreateCollectionDialog from "@/components/common/Collection/Dialog/CreateCollection.vue"; import EditCollectionDialog from "@/components/common/Collection/Dialog/EditCollection.vue"; +import AddRomsToCollectionDialog from "@/components/common/Collection/Dialog/AddRoms.vue"; +import RemoveRomsFromCollectionDialog from "@/components/common/Collection/Dialog/RemoveRoms.vue"; import DeleteCollectionDialog from "@/components/common/Collection/Dialog/DeleteCollection.vue"; import DeleteAssetDialog from "@/components/common/Game/Dialog/Asset/DeleteAssets.vue"; import CopyRomDownloadLinkDialog from "@/components/common/Game/Dialog/CopyDownloadLink.vue"; @@ -99,6 +101,8 @@ onMounted(async () => { + + diff --git a/frontend/src/views/Play/Base.vue b/frontend/src/views/Play/Base.vue index 2bcb1358d..f6b1cba81 100644 --- a/frontend/src/views/Play/Base.vue +++ b/frontend/src/views/Play/Base.vue @@ -91,15 +91,7 @@ onMounted(async () => { {{ rom.name }}