From 9760d1b70a592249c0608350e94076fac57d780e Mon Sep 17 00:00:00 2001 From: shankar ambady Date: Mon, 30 Sep 2024 13:34:52 -0400 Subject: [PATCH 1/9] adding initial button --- .../src/pages/DashboardPage/SettingsPage.tsx | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx index 2a135a5178..34f52955e4 100644 --- a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx +++ b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx @@ -1,5 +1,5 @@ import React from "react" -import { PlainList, Typography, Link, styled } from "ol-components" +import { PlainList, Typography, Link, styled, Button } from "ol-components" import { useUserMe } from "api/hooks/user" import { useSearchSubscriptionDelete, @@ -37,6 +37,29 @@ const SubTitleText = styled(Typography)(({ theme }) => ({ ...theme.typography.body2, })) +const SettingsHeader = styled.div(({ theme }) => ({ + display: "flex", + alignItems: "center", + alignSelf: "stretch", + [theme.breakpoints.down("md")]: { + paddingBottom: "8px", + }, +})) + +const SettingsHeaderLeft = styled.div({ + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + flex: "1 0 0", +}) + +const SettingsHeaderRight = styled.div(({ theme }) => ({ + display: "flex", + [theme.breakpoints.down("md")]: { + display: "none", + }, +})) + const ListItem = styled.li(({ theme }) => [ { padding: "16px 32px", @@ -95,10 +118,17 @@ const SettingsPage: React.FC = () => { return ( <> - Following - - All topics, academic departments, and MIT units you are following. - + + + Following + + All topics, academic departments, and MIT units you are following. + + + + + + {subscriptionList?.data?.map((subscriptionItem) => ( From 3577c460e3c2142a0e7ba5e02b1a6e0c8fe9b391 Mon Sep 17 00:00:00 2001 From: shankar ambady Date: Mon, 30 Sep 2024 14:47:05 -0400 Subject: [PATCH 2/9] adding working dialog --- .../src/pages/DashboardPage/SettingsPage.tsx | 78 ++++++++++++++++--- 1 file changed, 69 insertions(+), 9 deletions(-) diff --git a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx index 34f52955e4..d7be643488 100644 --- a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx +++ b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx @@ -1,11 +1,18 @@ import React from "react" -import { PlainList, Typography, Link, styled, Button } from "ol-components" +import { + PlainList, + Typography, + Link, + styled, + Button, + Dialog, +} from "ol-components" import { useUserMe } from "api/hooks/user" import { useSearchSubscriptionDelete, useSearchSubscriptionList, } from "api/hooks/searchSubscription" - +import * as NiceModal from "@ebay/nice-modal-react" const SOURCE_LABEL_DISPLAY = { topic: "Topic", unit: "MIT Unit", @@ -106,16 +113,55 @@ const ListItemBody: React.FC = ({ ) } +interface UnfollowDialogProps { + subscriptionIds?: number[] + subscriptionName?: string +} +const UnfollowDialog = NiceModal.create( + ({ subscriptionIds, subscriptionName }: UnfollowDialogProps) => { + const modal = NiceModal.useModal() + const subscriptionDelete = useSearchSubscriptionDelete() + const unsubscribe = subscriptionDelete.mutate + return ( + + subscriptionIds.map((subscriptionId) => unsubscribe(subscriptionId)) + } + title="Unfollow" + confirmText={ + subscriptionIds.length === 1 ? "Yes, Unfollow" : "Yes, Unfollow All" + } + > + {subscriptionIds.length === 1 ? ( + <> + Are you sure you want to unfollow {subscriptionName}? + + ) : ( + <> + Are you sure you want to Unfollow All? You will stop getting + emails for all topics, academic departments, and MIT units you are + following.{" "} + + )} + + ) + }, +) + const SettingsPage: React.FC = () => { const { data: user } = useUserMe() - const subscriptionDelete = useSearchSubscriptionDelete() + const subscriptionList = useSearchSubscriptionList({ enabled: !!user?.is_authenticated, }) - const unsubscribe = subscriptionDelete.mutate if (!user || subscriptionList.isLoading) return null + const showDialog = (subscriptionIds, subscriptionName) => { + return NiceModal.show(UnfollowDialog, { subscriptionIds, subscriptionName }) + } + return ( <> @@ -126,7 +172,19 @@ const SettingsPage: React.FC = () => { - + @@ -141,10 +199,12 @@ const SettingsPage: React.FC = () => { } /> { - event.preventDefault() - unsubscribe(subscriptionItem.id) - }} + onClick={() => + showDialog( + [subscriptionItem.id], + subscriptionItem.source_description, + ) + } > Unfollow From 1ffb1c59f64b5c2635911ae7f7e5284fa5f2ae6c Mon Sep 17 00:00:00 2001 From: shankar ambady Date: Mon, 30 Sep 2024 16:18:34 -0400 Subject: [PATCH 3/9] fixing typecheck lint --- .../src/pages/DashboardPage/SettingsPage.tsx | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx index d7be643488..7584945a18 100644 --- a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx +++ b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx @@ -113,7 +113,7 @@ const ListItemBody: React.FC = ({ ) } -interface UnfollowDialogProps { +type UnfollowDialogProps = { subscriptionIds?: number[] subscriptionName?: string } @@ -125,15 +125,15 @@ const UnfollowDialog = NiceModal.create( return ( - subscriptionIds.map((subscriptionId) => unsubscribe(subscriptionId)) - } + onConfirm={async () => { + subscriptionIds?.map((subscriptionId) => unsubscribe(subscriptionId)) + }} title="Unfollow" confirmText={ - subscriptionIds.length === 1 ? "Yes, Unfollow" : "Yes, Unfollow All" + subscriptionIds?.length === 1 ? "Yes, Unfollow" : "Yes, Unfollow All" } > - {subscriptionIds.length === 1 ? ( + {subscriptionIds?.length === 1 ? ( <> Are you sure you want to unfollow {subscriptionName}? @@ -158,10 +158,6 @@ const SettingsPage: React.FC = () => { if (!user || subscriptionList.isLoading) return null - const showDialog = (subscriptionIds, subscriptionName) => { - return NiceModal.show(UnfollowDialog, { subscriptionIds, subscriptionName }) - } - return ( <> @@ -175,12 +171,13 @@ const SettingsPage: React.FC = () => { + + + } > {subscriptionIds?.length === 1 ? ( @@ -141,7 +163,7 @@ const UnfollowDialog = NiceModal.create( <> Are you sure you want to Unfollow All? You will stop getting emails for all topics, academic departments, and MIT units you are - following.{" "} + following.? )} @@ -167,22 +189,26 @@ const SettingsPage: React.FC = () => { All topics, academic departments, and MIT units you are following. - - - + {subscriptionList?.data.length > 1 ? ( + + + + ) : ( + <> + )} {subscriptionList?.data?.map((subscriptionItem) => ( From 587b5f57ea8c760fb95c11d585dd7aeddaac6358 Mon Sep 17 00:00:00 2001 From: shankar ambady Date: Tue, 1 Oct 2024 10:25:38 -0400 Subject: [PATCH 5/9] adding tests --- .../pages/DashboardPage/SettingsPage.test.tsx | 38 +++++++++++++++---- .../src/pages/DashboardPage/SettingsPage.tsx | 2 + 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.test.tsx b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.test.tsx index 38812527f3..1100cc1ea3 100644 --- a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.test.tsx +++ b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.test.tsx @@ -25,10 +25,15 @@ const setupApis = ({ `${urls.userSubscription.check(subscriptionRequest)}`, subscribeResponse, ) - const unsubscribeUrl = urls.userSubscription.delete(subscribeResponse[0]?.id) - setMockResponse.delete(unsubscribeUrl, subscribeResponse[0]) + const unsubscribeUrls = [] + for (const sub of subscribeResponse) { + const unsubscribeUrl = urls.userSubscription.delete(sub?.id) + unsubscribeUrls.push(unsubscribeUrl) + setMockResponse.delete(unsubscribeUrl, sub) + } + return { - unsubscribeUrl, + unsubscribeUrls, } } @@ -46,7 +51,7 @@ describe("SettingsPage", () => { }) test("Clicking 'Unfollow' removes the subscription", async () => { - const { unsubscribeUrl } = setupApis({ + const { unsubscribeUrls } = setupApis({ isAuthenticated: true, isSubscribed: true, subscriptionRequest: {}, @@ -54,13 +59,32 @@ describe("SettingsPage", () => { renderWithProviders() const followList = await screen.findByTestId("follow-list") - const unsubscribeButton = within(followList).getAllByText("Unfollow")[0] - await user.click(unsubscribeButton) + const unsubscribeLink = within(followList).getAllByText("Unfollow")[0] + await user.click(unsubscribeLink) + const unsubscribeButton = await screen.findByTestId("dialog-unfollow") + await user.click(unsubscribeButton) expect(makeRequest).toHaveBeenCalledWith( "delete", - unsubscribeUrl, + unsubscribeUrls[0], undefined, ) }) + + test("Clicking 'Unfollow All' removes all subscriptions", async () => { + const { unsubscribeUrls } = setupApis({ + isAuthenticated: true, + isSubscribed: true, + subscriptionRequest: {}, + }) + renderWithProviders() + const unsubscribeLink = await screen.findByTestId("unfollow-all") + await user.click(unsubscribeLink) + + const unsubscribeButton = await screen.findByTestId("dialog-unfollow") + await user.click(unsubscribeButton) + for (const unsubUrl of unsubscribeUrls) { + expect(makeRequest).toHaveBeenCalledWith("delete", unsubUrl, undefined) + } + }) }) diff --git a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx index bc56c69e16..9ec1b20a77 100644 --- a/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx +++ b/frontends/mit-learn/src/pages/DashboardPage/SettingsPage.tsx @@ -138,6 +138,7 @@ const UnfollowDialog = NiceModal.create(