Update frontend after library deletion

This commit is contained in:
grimsi
2025-05-11 15:42:01 +02:00
parent 8adfd4b444
commit 0bf1d68d9f
3 changed files with 82 additions and 42 deletions
@@ -3,7 +3,7 @@ import ConfigFormField from "Frontend/components/administration/ConfigFormField"
import withConfigPage from "Frontend/components/administration/withConfigPage"; import withConfigPage from "Frontend/components/administration/withConfigPage";
import Section from "Frontend/components/general/Section"; import Section from "Frontend/components/general/Section";
import * as Yup from 'yup'; import * as Yup from 'yup';
import {Button, Divider, Tooltip, useDisclosure} from "@heroui/react"; import {addToast, Button, Divider, Tooltip, useDisclosure} from "@heroui/react";
import {Plus} from "@phosphor-icons/react"; import {Plus} from "@phosphor-icons/react";
import {LibraryEndpoint} from "Frontend/generated/endpoints"; import {LibraryEndpoint} from "Frontend/generated/endpoints";
import {LibraryOverviewCard} from "Frontend/components/general/cards/LibraryOverviewCard"; import {LibraryOverviewCard} from "Frontend/components/general/cards/LibraryOverviewCard";
@@ -41,6 +41,24 @@ function LibraryManagementLayout({getConfig, formik}: any) {
} }
return [...prevLibraries, updatedLibrary]; return [...prevLibraries, updatedLibrary];
}); });
addToast({
title: "Library updated",
description: `Library ${library.name} has been updated.`,
color: "success"
})
}
async function removeLibrary(library: LibraryDto) {
await LibraryEndpoint.removeLibrary(library.id);
setLibraries((prevLibraries) => {
return prevLibraries.filter((l) => l.id !== library.id);
});
addToast({
title: "Library removed",
description: `Library ${library.name} has been removed.`,
color: "success"
})
} }
return ( return (
@@ -72,7 +90,8 @@ function LibraryManagementLayout({getConfig, formik}: any) {
// Aspect ratio of cover = 12/17 -> 5 covers = 60/17 -> 353px * 100px // Aspect ratio of cover = 12/17 -> 5 covers = 60/17 -> 353px * 100px
<div id="library-cards" className="grid gap-4 grid-cols-[repeat(auto-fill,minmax(353px,1fr))]"> <div id="library-cards" className="grid gap-4 grid-cols-[repeat(auto-fill,minmax(353px,1fr))]">
{libraries.map((library) => {libraries.map((library) =>
<LibraryOverviewCard library={library} updateLibrary={updateLibrary} key={library.name}/> <LibraryOverviewCard library={library} updateLibrary={updateLibrary}
removeLibrary={removeLibrary} key={library.name}/>
)} )}
</div> : </div> :
"No libraries configured. Add your first library!" "No libraries configured. Add your first library!"
@@ -25,9 +25,10 @@ import LibraryUpdateDto from "Frontend/generated/de/grimsi/gameyfin/libraries/dt
import ScanType from "Frontend/generated/de/grimsi/gameyfin/libraries/enums/ScanType"; import ScanType from "Frontend/generated/de/grimsi/gameyfin/libraries/enums/ScanType";
import {randomGamesFromLibrary} from "Frontend/util/utils"; import {randomGamesFromLibrary} from "Frontend/util/utils";
export function LibraryOverviewCard({library, updateLibrary}: { export function LibraryOverviewCard({library, updateLibrary, removeLibrary}: {
library: LibraryDto, library: LibraryDto,
updateLibrary: (library: LibraryUpdateDto) => void updateLibrary: (library: LibraryUpdateDto) => Promise<void>,
removeLibrary: (library: LibraryDto) => Promise<void>
}) { }) {
const MAX_COVER_COUNT = 5; const MAX_COVER_COUNT = 5;
@@ -103,6 +104,7 @@ export function LibraryOverviewCard({library, updateLibrary}: {
isOpen={libraryDetailsModal.isOpen} isOpen={libraryDetailsModal.isOpen}
onOpenChange={libraryDetailsModal.onOpenChange} onOpenChange={libraryDetailsModal.onOpenChange}
updateLibrary={updateLibrary} updateLibrary={updateLibrary}
removeLibrary={removeLibrary}
/> />
</> </>
); );
@@ -2,56 +2,75 @@ import React from "react";
import {Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react"; import {Button, Modal, ModalBody, ModalContent, ModalFooter, ModalHeader} from "@heroui/react";
import {Form, Formik} from "formik"; import {Form, Formik} from "formik";
import Input from "Frontend/components/general/input/Input"; import Input from "Frontend/components/general/input/Input";
import {LibraryEndpoint} from "Frontend/generated/endpoints";
import LibraryUpdateDto from "Frontend/generated/de/grimsi/gameyfin/libraries/dto/LibraryUpdateDto"; import LibraryUpdateDto from "Frontend/generated/de/grimsi/gameyfin/libraries/dto/LibraryUpdateDto";
import LibraryDto from "Frontend/generated/de/grimsi/gameyfin/libraries/dto/LibraryDto"; import LibraryDto from "Frontend/generated/de/grimsi/gameyfin/libraries/dto/LibraryDto";
import Section from "Frontend/components/general/Section";
interface LibraryDetailsModalProps { interface LibraryDetailsModalProps {
library: LibraryDto; library: LibraryDto;
isOpen: boolean; isOpen: boolean;
onOpenChange: () => void; onOpenChange: () => void;
updateLibrary: (library: LibraryUpdateDto) => void; updateLibrary: (library: LibraryUpdateDto) => Promise<void>;
removeLibrary: (library: LibraryDto) => Promise<void>;
} }
export default function LibraryDetailsModal({library, isOpen, onOpenChange, updateLibrary}: LibraryDetailsModalProps) { export default function LibraryDetailsModal({
library,
isOpen,
onOpenChange,
updateLibrary,
removeLibrary
}: LibraryDetailsModalProps) {
return ( return (
<Modal isOpen={isOpen} onOpenChange={onOpenChange} backdrop="opaque" size="lg"> <Modal isOpen={isOpen} onOpenChange={onOpenChange} backdrop="opaque" size="lg">
<ModalContent> <ModalContent>
{(onClose) => ( {(onClose) => {
<Formik initialValues={library} async function update(values: LibraryUpdateDto) {
enableReinitialize={true} await updateLibrary(values);
onSubmit={async (values: LibraryUpdateDto) => { onClose();
updateLibrary(values); }
onClose();
}} async function remove(library: LibraryDto) {
> await removeLibrary(library);
{(formik: { isSubmitting: any; }) => ( onClose();
<Form> }
<ModalHeader className="flex flex-col gap-1">
Edit library return (
</ModalHeader> <Formik initialValues={library}
<ModalBody> enableReinitialize={true}
<Input key="name" name="name" label="Name"/> onSubmit={(values) => update(values)}
<Button onPress={() => LibraryEndpoint.removeLibrary(library.id)} >
color="danger">Delete</Button> {(formik: { isSubmitting: any; }) => (
</ModalBody> <Form>
<ModalFooter> <ModalHeader className="flex flex-col gap-1">
<Button variant="light" onPress={onClose}> Edit library
Cancel </ModalHeader>
</Button> <ModalBody>
<Button <Input key="name" name="name" label="Name"/>
color="primary"
isLoading={formik.isSubmitting} <Section title="Danger zone"/>
disabled={formik.isSubmitting} <Button onPress={() => remove(library)} color="danger">
type="submit" Delete this library
> </Button>
{formik.isSubmitting ? "" : "Save"} </ModalBody>
</Button> <ModalFooter>
</ModalFooter> <Button variant="light" onPress={onClose}>
</Form> Cancel
)} </Button>
</Formik> <Button
)} color="primary"
isLoading={formik.isSubmitting}
disabled={formik.isSubmitting}
type="submit"
>
{formik.isSubmitting ? "" : "Save"}
</Button>
</ModalFooter>
</Form>
)}
</Formik>
)
}}
</ModalContent> </ModalContent>
</Modal> </Modal>
); );