Skip to content

feat: container delete confirmation modal #2145

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions src/course-libraries/data/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
const getApiBaseUrl = () => getConfig().STUDIO_BASE_URL;

export const getEntityLinksByDownstreamContextUrl = () => `${getApiBaseUrl()}/api/contentstore/v2/downstreams/`;
export const getContainerEntityLinksByDownstreamContextUrl = () => `${getApiBaseUrl()}/api/contentstore/v2/downstream-containers/`;

export const getEntityLinksSummaryByDownstreamContextUrl = (downstreamContextKey: string) => `${getApiBaseUrl()}/api/contentstore/v2/downstreams/${downstreamContextKey}/summary`;

Expand All @@ -18,9 +19,8 @@
results: T,
}

export interface PublishableEntityLink {
export interface BasePublishableEntityLink {
id: number;
upstreamUsageKey: string;
upstreamContextKey: string;
upstreamContextTitle: string;
upstreamVersion: number;
Expand All @@ -33,6 +33,14 @@
readyToSync: boolean;
}

export interface PublishableEntityLink extends BasePublishableEntityLink {
upstreamUsageKey: string;
}

export interface ContainerPublishableEntityLink extends BasePublishableEntityLink {
upstreamContainerKey: string;
}

export interface PublishableEntityLinkSummary {
upstreamContextKey: string;
upstreamContextTitle: string;
Expand All @@ -58,6 +66,23 @@
return camelCaseObject(data);
};

export const getContainerEntityLinks = async (
downstreamContextKey?: string,
readyToSync?: boolean,
upstreamContainerKey?: string,
): Promise<ContainerPublishableEntityLink[]> => {
const { data } = await getAuthenticatedHttpClient()
.get(getContainerEntityLinksByDownstreamContextUrl(), {
params: {
course_id: downstreamContextKey,
ready_to_sync: readyToSync,
upstream_container_key: upstreamContainerKey,
no_page: true,
},
});
return camelCaseObject(data);

Check warning on line 83 in src/course-libraries/data/api.ts

View check run for this annotation

Codecov / codecov/patch

src/course-libraries/data/api.ts#L83

Added line #L83 was not covered by tests
};

export const getEntityLinksSummaryByDownstreamContext = async (
downstreamContextKey: string,
): Promise<PublishableEntityLinkSummary[]> => {
Expand Down
36 changes: 34 additions & 2 deletions src/course-libraries/data/apiHooks.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import {
useQuery,
} from '@tanstack/react-query';
import { getEntityLinks, getEntityLinksSummaryByDownstreamContext } from './api';
import { getContainerEntityLinks, getEntityLinks, getEntityLinksSummaryByDownstreamContext } from './api';

export const courseLibrariesQueryKeys = {
all: ['courseLibraries'],
courseLibraries: (courseId?: string) => [...courseLibrariesQueryKeys.all, courseId],
courseReadyToSyncLibraries: ({ courseId, readyToSync, upstreamUsageKey }: {
courseReadyToSyncLibraries: ({
courseId, readyToSync, upstreamUsageKey, upstreamContainerKey,
}: {
courseId?: string,
readyToSync?: boolean,
upstreamUsageKey?: string,
upstreamContainerKey?: string,
pageSize?: number,
}) => {
const key: Array<string | boolean | number> = [...courseLibrariesQueryKeys.all];
Expand All @@ -22,6 +25,9 @@ export const courseLibrariesQueryKeys = {
if (upstreamUsageKey !== undefined) {
key.push(upstreamUsageKey);
}
if (upstreamContainerKey !== undefined) {
key.push(upstreamContainerKey);
}
return key;
},
courseLibrariesSummary: (courseId?: string) => [...courseLibrariesQueryKeys.courseLibraries(courseId), 'summary'],
Expand Down Expand Up @@ -63,3 +69,29 @@ export const useEntityLinksSummaryByDownstreamContext = (courseId?: string) => (
enabled: courseId !== undefined,
})
);

/**
* Hook to fetch list of publishable entity links for containers by course key.
* (That is, get a list of the library containers used in the given course.)
*/
export const useContainerEntityLinks = ({
courseId, readyToSync, upstreamContainerKey,
}: {
courseId?: string,
readyToSync?: boolean,
upstreamContainerKey?: string,
}) => (
useQuery({
queryKey: courseLibrariesQueryKeys.courseReadyToSyncLibraries({
courseId,
readyToSync,
upstreamContainerKey,
}),
queryFn: () => getContainerEntityLinks(
courseId,
readyToSync,
upstreamContainerKey,
),
enabled: courseId !== undefined || upstreamContainerKey !== undefined || readyToSync !== undefined,
})
);
2 changes: 1 addition & 1 deletion src/generic/delete-modal/DeleteModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const DeleteModal = ({
</ActionRow>
)}
>
<p>{modalDescription}</p>
<div>{modalDescription}</div>
</AlertModal>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/library-authoring/LibraryContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { useLibraryContext } from './common/context/LibraryContext';
import { useSidebarContext } from './common/context/SidebarContext';
import CollectionCard from './components/CollectionCard';
import ComponentCard from './components/ComponentCard';
import ContainerCard from './components/ContainerCard';
import { ContentType } from './routes';
import { useLoadOnScroll } from '../hooks';
import messages from './collections/messages';
import ContainerCard from './containers/ContainerCard';

/**
* Library Content to show content grid
Expand Down
9 changes: 5 additions & 4 deletions src/library-authoring/components/ComponentMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import { canEditComponent } from './ComponentEditorModal';
import ComponentDeleter from './ComponentDeleter';
import messages from './messages';
import containerMessages from '../containers/messages';
import { useLibraryRoutes } from '../routes';
import { useRunOnNextRender } from '../../utils';

Expand Down Expand Up @@ -58,9 +59,9 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
// Close sidebar if current component is open
closeLibrarySidebar();
}
showToast(intl.formatMessage(messages.removeComponentFromCollectionSuccess));
showToast(intl.formatMessage(containerMessages.removeComponentFromCollectionSuccess));
}).catch(() => {
showToast(intl.formatMessage(messages.removeComponentFromCollectionFailure));
showToast(intl.formatMessage(containerMessages.removeComponentFromCollectionFailure));
});
};

Expand Down Expand Up @@ -139,11 +140,11 @@ export const ComponentMenu = ({ usageKey }: { usageKey: string }) => {
</Dropdown.Item>
{insideCollection && (
<Dropdown.Item onClick={removeFromCollection}>
<FormattedMessage {...messages.menuRemoveFromCollection} />
<FormattedMessage {...containerMessages.menuRemoveFromCollection} />
</Dropdown.Item>
)}
<Dropdown.Item onClick={showManageCollections}>
<FormattedMessage {...messages.menuAddToCollection} />
<FormattedMessage {...containerMessages.menuAddToCollection} />
</Dropdown.Item>
</Dropdown.Menu>
{isConfirmingDelete && (
Expand Down
96 changes: 0 additions & 96 deletions src/library-authoring/components/ContainerDeleter.tsx

This file was deleted.

1 change: 0 additions & 1 deletion src/library-authoring/components/index.scss
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
@import "./BaseCard.scss";
@import "./ContainerCard.scss";
85 changes: 0 additions & 85 deletions src/library-authoring/components/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ const messages = defineMessages({
defaultMessage: 'Collection actions menu',
description: 'Alt/title text for the collection card menu button.',
},
containerCardMenuAlt: {
id: 'course-authoring.library-authoring.container.menu',
defaultMessage: 'Container actions menu',
description: 'Alt/title text for the container card menu button.',
},
menuOpen: {
id: 'course-authoring.library-authoring.menu.open',
defaultMessage: 'Open',
Expand All @@ -36,26 +31,6 @@ const messages = defineMessages({
defaultMessage: 'Delete',
description: 'Menu item for deleting a component.',
},
menuAddToCollection: {
id: 'course-authoring.library-authoring.component.menu.add',
defaultMessage: 'Add to collection',
description: 'Menu item for add a component to collection.',
},
menuRemoveFromCollection: {
id: 'course-authoring.library-authoring.component.menu.remove',
defaultMessage: 'Remove from collection',
description: 'Menu item for remove an item from collection.',
},
removeComponentFromCollectionSuccess: {
id: 'course-authoring.library-authoring.component.remove-from-collection-success',
defaultMessage: 'Item successfully removed',
description: 'Message for successful removal of an item from collection.',
},
removeComponentFromCollectionFailure: {
id: 'course-authoring.library-authoring.component.remove-from-collection-failure',
defaultMessage: 'Failed to remove item',
description: 'Message for failure of removal of an item from collection.',
},
deleteComponentWarningTitle: {
id: 'course-authoring.library-authoring.component.delete-confirmation-title',
defaultMessage: 'Delete Component',
Expand Down Expand Up @@ -191,61 +166,6 @@ const messages = defineMessages({
defaultMessage: 'This component can be synced in courses after publish.',
description: 'Alert text of the modal to confirm publish a component in a library.',
},
menuDeleteContainer: {
id: 'course-authoring.library-authoring.container.delete-menu-text',
defaultMessage: 'Delete',
description: 'Menu item to delete a container.',
},
deleteUnitWarningTitle: {
id: 'course-authoring.library-authoring.unit.delete-confirmation-title',
defaultMessage: 'Delete Unit',
description: 'Title text for the warning displayed before deleting a Unit',
},
deleteUnitConfirm: {
id: 'course-authoring.library-authoring.unit.delete-confirmation-text',
defaultMessage: 'Delete {unitName}? {message}',
description: 'Confirmation text to display before deleting a unit',
},
deleteUnitConfirmMsg1: {
id: 'course-authoring.library-authoring.unit.delete-confirmation-msg-1',
defaultMessage: 'Any course instances will stop receiving updates.',
description: 'First part of confirmation message to display before deleting a unit',
},
deleteUnitConfirmMsg2: {
id: 'course-authoring.library-authoring.unit.delete-confirmation-msg-2',
defaultMessage: 'Any components will remain in the library.',
description: 'Second part of confirmation message to display before deleting a unit',
},
deleteUnitSuccess: {
id: 'course-authoring.library-authoring.unit.delete.success',
defaultMessage: 'Unit deleted',
description: 'Message to display on delete unit success',
},
deleteUnitFailed: {
id: 'course-authoring.library-authoring.unit.delete-failed-error',
defaultMessage: 'Failed to delete unit',
description: 'Message to display on failure to delete a unit',
},
undoDeleteContainerToastAction: {
id: 'course-authoring.library-authoring.container.undo-delete-container-toast-button',
defaultMessage: 'Undo',
description: 'Toast message to undo deletion of container',
},
undoDeleteContainerToastMessage: {
id: 'course-authoring.library-authoring.container.undo-delete-container-toast-text',
defaultMessage: 'Undo successful',
description: 'Message to display on undo delete container success',
},
undoDeleteUnitToastFailed: {
id: 'course-authoring.library-authoring.unit.undo-delete-unit-failed',
defaultMessage: 'Failed to undo delete Unit operation',
description: 'Message to display on failure to undo delete unit',
},
containerPreviewMoreBlocks: {
id: 'course-authoring.library-authoring.component.container-card-preview.more-blocks',
defaultMessage: '+{count}',
description: 'Count shown when a container has more blocks than will fit on the card preview.',
},
removeComponentFromUnitMenu: {
id: 'course-authoring.library-authoring.unit.component.remove.button',
defaultMessage: 'Remove from unit',
Expand Down Expand Up @@ -276,10 +196,5 @@ const messages = defineMessages({
defaultMessage: 'Failed to undo remove component operation',
description: 'Message to display on failure to undo delete component',
},
containerPreviewText: {
id: 'course-authoring.library-authoring.container.preview.text',
defaultMessage: 'Contains {children}.',
description: 'Preview message for section/subsections with the names of children separated by commas',
},
});
export default messages;
Loading