Skip to content

Commit

Permalink
feat(BooksManager): introduce option to Unpublish book but not delete…
Browse files Browse the repository at this point in the history
… project
  • Loading branch information
ethanaturner committed Aug 29, 2024
1 parent 21af9a7 commit ad84a2f
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ import { Button, Checkbox, Icon, Modal, ModalProps } from "semantic-ui-react";
import useGlobalError from "../../error/ErrorHooks";
import { useNotifications } from "../../../context/NotificationContext";

interface DeleteBookModalProps extends ModalProps {
interface UnpublishOrDeleteBookModalProps extends ModalProps {
bookID: string;
bookTitle: string;
deleteMode: boolean;
onClose: () => void;
open: boolean;
}

export const DeleteBookModal: React.FC<DeleteBookModalProps> = ({
export const UnpublishOrDeleteBookModal: React.FC<UnpublishOrDeleteBookModalProps> = ({
bookID,
bookTitle,
deleteMode,
onClose,
open,
}) => {
Expand All @@ -35,14 +37,18 @@ export const DeleteBookModal: React.FC<DeleteBookModalProps> = ({
if (!confirmCoverPage) return;
try {
setIsLoading(true);
const delRes = await axios.delete(`/commons/book/${bookID}`);
const delRes = await axios.delete(`/commons/book/${bookID}`, {
params: {
...(deleteMode && { deleteProject: deleteMode }),
},
});
setIsLoading(false);
if (delRes.data.error) {
handleGlobalError(delRes.data.errMsg);
return;
}
addNotification({
message: `"${bookTitle}" was successfully deleted.`,
message: deleteMode ? `"${bookTitle}" and associated Conductor project was successfully deleted.` : `"${bookTitle}" was successfully unpublished.`,
type: 'success',
});
handleClose();
Expand All @@ -58,9 +64,9 @@ export const DeleteBookModal: React.FC<DeleteBookModalProps> = ({
open={open}
size="large"
>
<Modal.Header>Delete Book</Modal.Header>
<Modal.Header>{deleteMode ? 'Delete Book and Project' : 'Unpublish Book'}</Modal.Header>
<Modal.Content>
<p>Are you sure you want to delete the record for "{bookTitle}"? <strong>By clicking Delete, you confirm you understand the following:</strong></p>
<p>Are you sure you want to {deleteMode ? 'delete the record for' : 'unpublish'} "{bookTitle}"? <strong>By clicking {deleteMode ? 'Delete' : 'Unpublish'}, you confirm you understand the following:</strong></p>
<ul className="my-4 list-disc list-inside leading-7">
<li>
<span>The entry will be removed from Commons.</span>
Expand All @@ -69,8 +75,11 @@ export const DeleteBookModal: React.FC<DeleteBookModalProps> = ({
<li>Any submitted Adoption Reports for this Commons entry will be deleted.</li>
</ul>
</li>
<li>The entry will be removed from any collections it is a part of.</li>
<li>The entry will be removed from the central downloads listings and vendor export lists.</li>
<li>The connected project (if applicable) and any related resources will be deleted.</li>
{deleteMode && (
<li>The corresponding Conductor project (if applicable) and any related resources will be deleted.</li>
)}
</ul>
<p className="mb-2"><strong>In order to continue, confirm the following:</strong></p>
<Checkbox
Expand All @@ -84,12 +93,12 @@ export const DeleteBookModal: React.FC<DeleteBookModalProps> = ({
Cancel
</Button>
<Button
color="red"
color={deleteMode ? 'red' : 'orange'}
disabled={!confirmCoverPage}
loading={isLoading}
onClick={submitDeleteBook}
>
<Icon name="trash" /> Delete
<Icon name={deleteMode ? 'trash' : 'eraser'} /> {deleteMode ? 'Delete' : 'Unpublish'}
</Button>
</Modal.Actions>
</Modal>
Expand Down
34 changes: 22 additions & 12 deletions client/src/screens/conductor/controlpanel/BooksManager/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
Segment,
Table,
} from 'semantic-ui-react';
import { DeleteBookModal } from "../../../../components/controlpanel/BooksManager/DeleteBookModal";
import { UnpublishOrDeleteBookModal } from "../../../../components/controlpanel/BooksManager/UnpublishOrDeleteBookModal";
import useGlobalError from '../../../../components/error/ErrorHooks';
import { useModals } from "../../../../context/ModalContext";
import { itemsPerPageOptions } from '../../../../components/util/PaginationOptions';
Expand Down Expand Up @@ -225,19 +225,20 @@ const BooksManager = () => {
setEOCWorking(false);
}

function closeDeleteModal() {
function closeUnpublishOrDeleteModal() {
closeAllModals();
getBooks();
}

function openDeleteModal(bookID, bookTitle) {
function openUnpublishOrDeleteModal(bookID, bookTitle, deleteMode) {
if (!bookID) return;

openModal(
<DeleteBookModal
<UnpublishOrDeleteBookModal
bookID={bookID}
bookTitle={bookTitle}
onClose={closeDeleteModal}
deleteMode={deleteMode}
onClose={closeUnpublishOrDeleteModal}
open={true}
/>
);
Expand Down Expand Up @@ -369,13 +370,22 @@ const BooksManager = () => {
</Button>
)}
{isSuperAdmin && (
<Button
color="red"
onClick={() => openDeleteModal(book.bookID, book.title)}
>
<Icon name="trash" />
Delete Book
</Button>
<>
<Button
color="orange"
onClick={() => openUnpublishOrDeleteModal(book.bookID, book.title)}
>
<Icon name="eraser" />
Unpublish Book
</Button>
<Button
color="red"
onClick={() => openUnpublishOrDeleteModal(book.bookID, book.title, true)}
>
<Icon name="trash" />
Delete Book and Project
</Button>
</>
)}
</Button.Group>
</Table.Cell>
Expand Down
2 changes: 1 addition & 1 deletion server/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ router.route('/commons/book/:bookID')
booksAPI.getBookDetail,
)
.delete(
middleware.validateZod(BookValidators.getWithBookIDParamSchema),
middleware.validateZod(BookValidators.deleteBookSchema),
authAPI.verifyRequest,
authAPI.getUserAttributes,
authAPI.checkHasRoleMiddleware('libretexts', 'superadmin'),
Expand Down
15 changes: 10 additions & 5 deletions server/api/books.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const defaultImagesURL = "https://cdn.libretexts.net/DefaultImages";
import { PipelineStage } from "mongoose";
import {
createBookSchema,
deleteBookSchema,
getCommonsCatalogSchema,
getMasterCatalogSchema,
getWithBookIDParamSchema,
Expand Down Expand Up @@ -1445,10 +1446,11 @@ async function createBook(
* @param {express.Response} res - Outgoing response.
*/
async function deleteBook(
req: ZodReqWithUser<z.infer<typeof getWithBookIDParamSchema>>,
req: ZodReqWithUser<z.infer<typeof deleteBookSchema>>,
res: Response,
) {
try {
const deleteProject = !!req.query?.deleteProject;
const bookID = req.params.bookID;
const [lib, coverID] = getLibraryAndPageFromBookID(req.params.bookID);
if (!lib || !coverID) {
Expand All @@ -1467,11 +1469,14 @@ async function deleteBook(
});
if (attachedProject) {
const projectID = attachedProject.projectID;
const projDelRes = await projectsAPI.deleteProjectInternal(projectID);
if (!projDelRes) {
return conductor500Err(res);
}
await PeerReview.deleteMany({ projectID });
if (deleteProject) {
debug(`[Delete Book]: Deleting project ${projectID}`);
const projDelRes = await projectsAPI.deleteProjectInternal(projectID);
if (!projDelRes) {
return conductor500Err(res);
}
}
}
// </find and delete project and associated resources>

Expand Down
9 changes: 9 additions & 0 deletions server/api/validators/book.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,12 @@ export const downloadBookFileSchema = z.object({
fileID: z.string().uuid(),
}),
});

export const deleteBookSchema = z.intersection(
z.object({
query: z.object({
deleteProject: z.coerce.boolean().optional(),
}),
}),
getWithBookIDParamSchema,
);

0 comments on commit ad84a2f

Please sign in to comment.