Skip to content

Commit

Permalink
Content snackbar and page 3 layout update (#419)
Browse files Browse the repository at this point in the history
* Remove content ID from snackbar messages

* Add slide-in and clean disappear to snackbars on content page

* Make content edit/creation snackbar independent of URL

* Update to "Query Topics" and update logos

* Refactor dashboard page 3 layout components

* Hide AI summary box if discovery has never been run

* Button now says Run Discovery if never ran, "Rerun" if ran before. Updated to LoadingButton with magic wand logo.

---------

Co-authored-by: Mark Botterill <[email protected]>
  • Loading branch information
amiraliemami and markbotterill committed Aug 30, 2024
1 parent e76dbf3 commit 827ec3c
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 91 deletions.
31 changes: 22 additions & 9 deletions admin_app/src/app/content/edit/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ const ContentBox = ({
const [highlightedOption, setHighlightedOption] = React.useState<Tag | null>();
const [isSaving, setIsSaving] = React.useState(false);

const setMainPageSnackMessage = (message: string): void => {
localStorage.setItem("editPageSnackMessage", message);
};

const router = useRouter();
React.useEffect(() => {
const fetchTags = async () => {
Expand All @@ -181,6 +185,7 @@ const ContentBox = ({

fetchTags();
}, [refreshKey]);

const saveContent = async (content: Content): Promise<number | null> => {
setIsSaving(true);

Expand Down Expand Up @@ -215,6 +220,19 @@ const ContentBox = ({
setIsSaving(false);
}
};

const handleSaveContent = async (content: Content) => {
const content_id = await saveContent(content);
if (content_id) {
{
content.content_id
? setMainPageSnackMessage("Content edited successfully")
: setMainPageSnackMessage("Content created successfully");
}
router.push(`/content`);
}
};

function createEmptyContent(contentTags: Tag[]): Content {
return {
content_id: null,
Expand All @@ -228,6 +246,7 @@ const ContentBox = ({
content_metadata: {},
};
}

const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
key: keyof Content,
Expand All @@ -242,6 +261,7 @@ const ContentBox = ({
: setContent({ ...emptyContent, [key]: e.target.value });
setIsSaved(false);
};

const handleTagsChange = (updatedTags: Tag[]) => {
setContentTags(updatedTags);
setIsSaved(false);
Expand Down Expand Up @@ -272,6 +292,7 @@ const ContentBox = ({
setSnackMessage(`Tag "${tag}" already exists`);
}
};

const openDeleteConfirmModal = (tag: Tag) => {
setTagToDelete(tag);
setOpenDeleteModal(true);
Expand All @@ -289,6 +310,7 @@ const ContentBox = ({
});
}
};

return (
<Layout.FlexBox>
<Dialog
Expand Down Expand Up @@ -500,15 +522,6 @@ const ContentBox = ({
} else if (content.content_text === "") {
setIsContentEmpty(true);
} else {
const handleSaveContent = async (content: Content) => {
const content_id = await saveContent(content);
if (content_id) {
const actionType = content.content_id ? "edit" : "add";
router.push(
`/content/?content_id=${content_id}&action=${actionType}`,
);
}
};
handleSaveContent(content);
}
}}
Expand Down
49 changes: 21 additions & 28 deletions admin_app/src/app/content/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
Menu,
MenuItem,
Paper,
Slide,
SlideProps,
Snackbar,
TextField,
Tooltip,
Expand All @@ -30,7 +32,7 @@ import type { Content } from "@/app/content/edit/page";
import ContentCard from "./components/ContentCard";
import { DownloadModal } from "./components/DownloadModal";
import { Layout } from "@/components/Layout";
import { appStyles, appColors, LANGUAGE_OPTIONS, sizes } from "@/utils";
import { appColors, LANGUAGE_OPTIONS, sizes } from "@/utils";
import { apiCalls } from "@/utils/api";
import { useAuth } from "@/utils/auth";
import { ImportModal } from "./components/ImportModal";
Expand Down Expand Up @@ -101,6 +103,10 @@ const CardsPage = () => {
}
}, [accessLevel, token]);

const SnackbarSlideTransition = (props: SlideProps) => {
return <Slide {...props} direction="up" />;
};

return (
<>
<Grid container>
Expand Down Expand Up @@ -205,10 +211,11 @@ const CardsPage = () => {
</Grid>
<Snackbar
open={snackMessage.message !== null}
autoHideDuration={6000}
autoHideDuration={4000}
onClose={() => {
setSnackMessage({ message: null, color: snackMessage.color });
}}
TransitionComponent={SnackbarSlideTransition}
>
<Alert
onClose={() => {
Expand Down Expand Up @@ -414,8 +421,6 @@ const CardsGrid = ({
const [isLoading, setIsLoading] = React.useState<boolean>(true);

const searchParams = useSearchParams();
const action = searchParams.get("action") || null;
const content_id = Number(searchParams.get("content_id")) || null;

const calculateMaxCardsPerPage = () => {
// set rows as per height of each card and height of grid (approximated from window height)
Expand Down Expand Up @@ -445,41 +450,20 @@ const CardsGrid = ({
return () => window.removeEventListener("resize", calculateMaxCardsPerPage);
}, []);

const getSnackMessage = React.useCallback(
(action: string | null, content_id: number | null): string | null => {
if (action === "edit") {
return `Content #${content_id} updated`;
} else if (action === "add") {
return `Content #${content_id} created`;
}
return null;
},
[],
);

React.useEffect(() => {
if (action) {
setSnackMessage({
message: getSnackMessage(action, content_id),
color: "success",
});
}
}, [action, content_id, getSnackMessage]);

const [refreshKey, setRefreshKey] = React.useState(0);
const onSuccessfulArchive = (content_id: number) => {
setIsLoading(true);
setRefreshKey((prevKey) => prevKey + 1);
setSnackMessage({
message: `Content #${content_id} removed successfully`,
message: `Content removed successfully`,
color: "success",
});
};
const onSuccessfulDelete = (content_id: number) => {
setIsLoading(true);
setRefreshKey((prevKey) => prevKey + 1);
setSnackMessage({
message: `Content #${content_id} deleted successfully`,
message: `Content deleted successfully`,
color: "success",
});
};
Expand All @@ -504,6 +488,15 @@ const CardsGrid = ({
setCards(filteredData);
setMaxPages(Math.ceil(filteredData.length / maxCardsPerPage));
setIsLoading(false);

const message = localStorage.getItem("editPageSnackMessage");
if (message) {
setSnackMessage({
message: message,
color: "success",
});
localStorage.removeItem("editPageSnackMessage");
}
})
.catch((error) => {
console.error("Failed to fetch content:", error);
Expand Down Expand Up @@ -618,7 +611,7 @@ const CardsGrid = ({
onSuccessfulArchive={onSuccessfulArchive}
onFailedArchive={(content_id: number) => {
setSnackMessage({
message: `Failed to remove content #${content_id}`,
message: `Failed to remove content`,
color: "error",
});
}}
Expand Down
69 changes: 45 additions & 24 deletions admin_app/src/app/dashboard/components/Insights.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useState } from "react";
import { QueryData, Period, TopicModelingResponse } from "../types";
import { generateNewTopics, fetchTopicsData } from "../api";
import { useAuth } from "@/utils/auth";
import { Paper } from "@mui/material";

interface InsightProps {
timePeriod: Period;
Expand Down Expand Up @@ -76,44 +77,64 @@ const Insight: React.FC<InsightProps> = ({ timePeriod }) => {
);

return (
<Grid container sx={{ bgcolor: "grey.100", borderRadius: 2, mx: 0.5 }}>
<Grid
container
md={12}
columnSpacing={{ xs: 2 }}
sx={{ bgcolor: "white", borderRadius: 2, mx: 0.5, mt: 2, height: 400 }}
<Box
sx={{
display: "flex",
flexDirection: "column",
}}
>
<Paper
elevation={0}
sx={{
display: "flex",
flexDirection: "row",
height: 600,
width: "100%",
border: 0.5,
borderColor: "lightgrey",
}}
>
<Grid
md={3}
sx={{ p: 2, borderRight: 1, borderColor: "grey.300", borderWidth: 2 }}
<Box
sx={{
width: "25%",
padding: 2,
borderRight: 1,
borderColor: "grey.300",
borderWidth: 2,
}}
>
<Topics
data={topics}
selectedTopicId={selectedTopicId}
onClick={setSelectedTopicId}
topicsPerPage={4}
topicsPerPage={8}
/>
</Grid>
<Grid md={9} sx={{ p: 2 }}>
</Box>
<Box
sx={{
padding: 2,
width: "75%",
}}
>
<Queries
data={topicQueries}
onRefreshClick={runRefresh}
aiSummary={aiSummary}
lastRefreshed={dataFromBackend.refreshTimeStamp}
refreshing={refreshing}
/>
</Grid>
</Grid>
<Grid
md={12}
height={400}
</Box>
</Paper>
<Paper
elevation={0}
sx={{
bgcolor: "white",
borderRadius: 2,
mx: 0.5,
mt: 2,
width: "100%",
height: "400px",
marginTop: 2,
justifyItems: "center",
justifySelf: "stretch",
border: 0.5,
borderColor: "lightgrey",
}}
>
<Box
Expand All @@ -125,10 +146,10 @@ const Insight: React.FC<InsightProps> = ({ timePeriod }) => {
justifyContent: "center",
}}
>
-- Chart - Coming Soon! --
Chart coming soon!
</Box>
</Grid>
</Grid>
</Paper>
</Box>
);
};

Expand Down
10 changes: 5 additions & 5 deletions admin_app/src/app/dashboard/components/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from "react";

import {
BarChart,
Category,
ChevronLeft,
ChevronRight,
Dashboard,
Insights,
QueryStats,
} from "@mui/icons-material";
import {
Box,
Expand All @@ -27,16 +27,16 @@ interface SideBarProps {
selectedDashboardPage: PageName;
}

type PageName = "Overview" | "Content Performance" | "Content Gaps";
type PageName = "Overview" | "Content Performance" | "Query Topics";

interface MenuItem {
name: PageName;
icon: React.ReactNode;
}
const menuItems: MenuItem[] = [
{ name: "Overview", icon: <Dashboard /> },
{ name: "Content Performance", icon: <BarChart /> },
{ name: "Content Gaps", icon: <Insights /> },
{ name: "Content Performance", icon: <QueryStats /> },
{ name: "Query Topics", icon: <Category /> },
];
const openedMixin = (theme: Theme): CSSObject => ({
width: drawerWidth,
Expand Down
Loading

0 comments on commit 827ec3c

Please sign in to comment.