Changed notification center popup to ShadCN Popover and deleted popupContext permanently.
This commit is contained in:
parent
dda8676d34
commit
39a696117e
8 changed files with 154 additions and 132 deletions
50
src/frontend/package-lock.json
generated
50
src/frontend/package-lock.json
generated
|
|
@ -20,6 +20,7 @@
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-menubar": "^1.0.3",
|
"@radix-ui/react-menubar": "^1.0.3",
|
||||||
|
"@radix-ui/react-popover": "^1.0.6",
|
||||||
"@radix-ui/react-progress": "^1.0.3",
|
"@radix-ui/react-progress": "^1.0.3",
|
||||||
"@radix-ui/react-separator": "^1.0.3",
|
"@radix-ui/react-separator": "^1.0.3",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
|
|
@ -143,10 +144,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/compat-data": {
|
"node_modules/@babel/compat-data": {
|
||||||
"version": "7.22.6",
|
"version": "7.22.9",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz",
|
||||||
"integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==",
|
"integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==",
|
||||||
"version": "7.22.9",
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
|
|
@ -1464,6 +1464,43 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@radix-ui/react-popover": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-cZ4defGpkZ0qTRtlIBzJLSzL6ht7ofhhW4i1+pkemjV1IKXm0wgCRnee154qlV6r9Ttunmh2TNZhMfV2bavUyA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": "^7.13.10",
|
||||||
|
"@radix-ui/primitive": "1.0.1",
|
||||||
|
"@radix-ui/react-compose-refs": "1.0.1",
|
||||||
|
"@radix-ui/react-context": "1.0.1",
|
||||||
|
"@radix-ui/react-dismissable-layer": "1.0.4",
|
||||||
|
"@radix-ui/react-focus-guards": "1.0.1",
|
||||||
|
"@radix-ui/react-focus-scope": "1.0.3",
|
||||||
|
"@radix-ui/react-id": "1.0.1",
|
||||||
|
"@radix-ui/react-popper": "1.1.2",
|
||||||
|
"@radix-ui/react-portal": "1.0.3",
|
||||||
|
"@radix-ui/react-presence": "1.0.1",
|
||||||
|
"@radix-ui/react-primitive": "1.0.3",
|
||||||
|
"@radix-ui/react-slot": "1.0.2",
|
||||||
|
"@radix-ui/react-use-controllable-state": "1.0.1",
|
||||||
|
"aria-hidden": "^1.1.1",
|
||||||
|
"react-remove-scroll": "2.5.5"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "*",
|
||||||
|
"@types/react-dom": "*",
|
||||||
|
"react": "^16.8 || ^17.0 || ^18.0",
|
||||||
|
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@types/react-dom": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@radix-ui/react-popper": {
|
"node_modules/@radix-ui/react-popper": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
@ -2614,6 +2651,15 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/axios": {
|
||||||
|
"version": "0.14.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/axios/-/axios-0.14.0.tgz",
|
||||||
|
"integrity": "sha512-KqQnQbdYE54D7oa/UmYVMZKq7CO4l8DEENzOKc4aBRwxCXSlJXGz83flFx5L7AWrOQnmuN3kVsRdt+GZPPjiVQ==",
|
||||||
|
"deprecated": "This is a stub types definition for axios (https://github.com/mzabriskie/axios). axios provides its own type definitions, so you don't need @types/axios installed!",
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/cacheable-request": {
|
"node_modules/@types/cacheable-request": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
"@radix-ui/react-icons": "^1.3.0",
|
"@radix-ui/react-icons": "^1.3.0",
|
||||||
"@radix-ui/react-label": "^2.0.2",
|
"@radix-ui/react-label": "^2.0.2",
|
||||||
"@radix-ui/react-menubar": "^1.0.3",
|
"@radix-ui/react-menubar": "^1.0.3",
|
||||||
|
"@radix-ui/react-popover": "^1.0.6",
|
||||||
"@radix-ui/react-progress": "^1.0.3",
|
"@radix-ui/react-progress": "^1.0.3",
|
||||||
"@radix-ui/react-separator": "^1.0.3",
|
"@radix-ui/react-separator": "^1.0.3",
|
||||||
"@radix-ui/react-slot": "^1.0.2",
|
"@radix-ui/react-slot": "^1.0.2",
|
||||||
|
|
|
||||||
|
|
@ -1,66 +1,72 @@
|
||||||
import { useContext, useRef } from "react";
|
import { useContext, useState } from "react";
|
||||||
import IconComponent from "../../components/genericIconComponent";
|
import IconComponent from "../../components/genericIconComponent";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "../../components/ui/popover";
|
||||||
import { alertContext } from "../../contexts/alertContext";
|
import { alertContext } from "../../contexts/alertContext";
|
||||||
import { PopUpContext } from "../../contexts/popUpContext";
|
|
||||||
import { AlertDropdownType } from "../../types/alerts";
|
import { AlertDropdownType } from "../../types/alerts";
|
||||||
import { useOnClickOutside } from "../hooks/useOnClickOutside";
|
|
||||||
import SingleAlert from "./components/singleAlertComponent";
|
import SingleAlert from "./components/singleAlertComponent";
|
||||||
|
|
||||||
export default function AlertDropdown({}: AlertDropdownType) {
|
export default function AlertDropdown({ children }: AlertDropdownType) {
|
||||||
const { closePopUp } = useContext(PopUpContext);
|
|
||||||
const componentRef = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
// Use the custom hook
|
|
||||||
useOnClickOutside(componentRef, () => {
|
|
||||||
closePopUp();
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
notificationList,
|
notificationList,
|
||||||
clearNotificationList,
|
clearNotificationList,
|
||||||
removeFromNotificationList,
|
removeFromNotificationList,
|
||||||
|
setNotificationCenter,
|
||||||
} = useContext(alertContext);
|
} = useContext(alertContext);
|
||||||
|
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<Popover
|
||||||
ref={componentRef}
|
open={open}
|
||||||
className="z-10 flex h-[500px] w-[400px] flex-col overflow-hidden rounded-md bg-muted px-2 py-3 pb-4 shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
|
onOpenChange={(k) => {
|
||||||
|
setOpen(k);
|
||||||
|
if (k) setNotificationCenter(false);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<div className="text-md flex flex-row justify-between pl-3 font-medium text-foreground">
|
<PopoverTrigger>{children}</PopoverTrigger>
|
||||||
Notifications
|
<PopoverContent className="flex h-[500px] w-[500px] flex-col">
|
||||||
<div className="flex gap-3 pr-3 ">
|
<div className="text-md flex flex-row justify-between pl-3 font-medium text-foreground">
|
||||||
<button
|
Notifications
|
||||||
className="text-foreground hover:text-status-red"
|
<div className="flex gap-3 pr-3 ">
|
||||||
onClick={() => {
|
<button
|
||||||
closePopUp();
|
className="text-foreground hover:text-status-red"
|
||||||
setTimeout(clearNotificationList, 100);
|
onClick={() => {
|
||||||
}}
|
setOpen(false);
|
||||||
>
|
setTimeout(clearNotificationList, 100);
|
||||||
<IconComponent name="Trash2" className="h-[1.1rem] w-[1.1rem]" />
|
}}
|
||||||
</button>
|
>
|
||||||
<button
|
<IconComponent name="Trash2" className="h-[1.1rem] w-[1.1rem]" />
|
||||||
className="text-foreground hover:text-status-red"
|
</button>
|
||||||
onClick={closePopUp}
|
<button
|
||||||
>
|
className="text-foreground hover:text-status-red"
|
||||||
<IconComponent name="X" className="h-5 w-5" />
|
onClick={() => {
|
||||||
</button>
|
setOpen(false);
|
||||||
</div>
|
}}
|
||||||
</div>
|
>
|
||||||
<div className="text-high-foreground mt-3 flex h-full w-full flex-col overflow-y-scroll scrollbar-hide">
|
<IconComponent name="X" className="h-5 w-5" />
|
||||||
{notificationList.length !== 0 ? (
|
</button>
|
||||||
notificationList.map((alertItem, index) => (
|
|
||||||
<SingleAlert
|
|
||||||
key={alertItem.id}
|
|
||||||
dropItem={alertItem}
|
|
||||||
removeAlert={removeFromNotificationList}
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<div className="flex h-full w-full items-center justify-center pb-16 text-ring">
|
|
||||||
No new notifications
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
</div>
|
||||||
</div>
|
<div className="text-high-foreground mt-3 flex h-full w-full flex-col overflow-y-scroll scrollbar-hide">
|
||||||
</div>
|
{notificationList.length !== 0 ? (
|
||||||
|
notificationList.map((alertItem, index) => (
|
||||||
|
<SingleAlert
|
||||||
|
key={alertItem.id}
|
||||||
|
dropItem={alertItem}
|
||||||
|
removeAlert={removeFromNotificationList}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<div className="flex h-full w-full items-center justify-center pb-16 text-ring">
|
||||||
|
No new notifications
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import { useContext, useEffect, useState } from "react";
|
import { useContext, useEffect, useState } from "react";
|
||||||
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
|
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
|
||||||
import { Link, useLocation, useParams } from "react-router-dom";
|
import { Link, useLocation } from "react-router-dom";
|
||||||
import AlertDropdown from "../../alerts/alertDropDown";
|
import AlertDropdown from "../../alerts/alertDropDown";
|
||||||
import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
import { USER_PROJECTS_HEADER } from "../../constants/constants";
|
||||||
import { alertContext } from "../../contexts/alertContext";
|
import { alertContext } from "../../contexts/alertContext";
|
||||||
import { darkContext } from "../../contexts/darkContext";
|
import { darkContext } from "../../contexts/darkContext";
|
||||||
import { PopUpContext } from "../../contexts/popUpContext";
|
|
||||||
import { TabsContext } from "../../contexts/tabsContext";
|
import { TabsContext } from "../../contexts/tabsContext";
|
||||||
import { typesContext } from "../../contexts/typesContext";
|
|
||||||
import { getRepoStars } from "../../controllers/API";
|
import { getRepoStars } from "../../controllers/API";
|
||||||
import IconComponent from "../genericIconComponent";
|
import IconComponent from "../genericIconComponent";
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
|
|
@ -15,14 +13,9 @@ import { Separator } from "../ui/separator";
|
||||||
import MenuBar from "./components/menuBar";
|
import MenuBar from "./components/menuBar";
|
||||||
|
|
||||||
export default function Header() {
|
export default function Header() {
|
||||||
const { flows, addFlow, tabId } = useContext(TabsContext);
|
const { flows, tabId } = useContext(TabsContext);
|
||||||
const { openPopUp } = useContext(PopUpContext);
|
|
||||||
const { templates } = useContext(typesContext);
|
|
||||||
const { id } = useParams();
|
|
||||||
const AlertWidth = 384;
|
|
||||||
const { dark, setDark } = useContext(darkContext);
|
const { dark, setDark } = useContext(darkContext);
|
||||||
const { notificationCenter, setNotificationCenter, setErrorData } =
|
const { notificationCenter } = useContext(alertContext);
|
||||||
useContext(alertContext);
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
const [stars, setStars] = useState(null);
|
const [stars, setStars] = useState(null);
|
||||||
|
|
@ -111,33 +104,18 @@ export default function Header() {
|
||||||
<IconComponent name="MoonIcon" className="side-bar-button-size" />
|
<IconComponent name="MoonIcon" className="side-bar-button-size" />
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<AlertDropdown>
|
||||||
className="extra-side-bar-save-disable relative"
|
<div className="extra-side-bar-save-disable relative">
|
||||||
onClick={(event: React.MouseEvent<HTMLElement>) => {
|
{notificationCenter && (
|
||||||
setNotificationCenter(false);
|
<div className="header-notifications"></div>
|
||||||
const { top, left } = (
|
)}
|
||||||
event.target as Element
|
<IconComponent
|
||||||
).getBoundingClientRect();
|
name="Bell"
|
||||||
openPopUp(
|
className="side-bar-button-size"
|
||||||
<>
|
aria-hidden="true"
|
||||||
<div
|
/>
|
||||||
className="absolute z-10"
|
</div>
|
||||||
style={{ top: top + 40, left: left - AlertWidth }}
|
</AlertDropdown>
|
||||||
>
|
|
||||||
<AlertDropdown />
|
|
||||||
</div>
|
|
||||||
<div className="header-notifications-box"></div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{notificationCenter && <div className="header-notifications"></div>}
|
|
||||||
<IconComponent
|
|
||||||
name="Bell"
|
|
||||||
className="side-bar-button-size"
|
|
||||||
aria-hidden="true"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
30
src/frontend/src/components/ui/popover.tsx
Normal file
30
src/frontend/src/components/ui/popover.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import * as PopoverPrimitive from "@radix-ui/react-popover";
|
||||||
|
import * as React from "react";
|
||||||
|
import { cn } from "../../utils/utils";
|
||||||
|
|
||||||
|
const Popover = PopoverPrimitive.Root;
|
||||||
|
|
||||||
|
const PopoverTrigger = PopoverPrimitive.Trigger;
|
||||||
|
|
||||||
|
const PopoverContent = React.forwardRef<
|
||||||
|
React.ElementRef<typeof PopoverPrimitive.Content>,
|
||||||
|
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
|
||||||
|
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
|
||||||
|
<PopoverPrimitive.Portal>
|
||||||
|
<PopoverPrimitive.Content
|
||||||
|
ref={ref}
|
||||||
|
align={align}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</PopoverPrimitive.Portal>
|
||||||
|
));
|
||||||
|
PopoverContent.displayName = PopoverPrimitive.Content.displayName;
|
||||||
|
|
||||||
|
export { Popover, PopoverTrigger, PopoverContent };
|
||||||
|
|
@ -5,7 +5,6 @@ import { SSEProvider } from "./SSEContext";
|
||||||
import { AlertProvider } from "./alertContext";
|
import { AlertProvider } from "./alertContext";
|
||||||
import { DarkProvider } from "./darkContext";
|
import { DarkProvider } from "./darkContext";
|
||||||
import { LocationProvider } from "./locationContext";
|
import { LocationProvider } from "./locationContext";
|
||||||
import PopUpProvider from "./popUpContext";
|
|
||||||
import { TabsProvider } from "./tabsContext";
|
import { TabsProvider } from "./tabsContext";
|
||||||
import { TypesProvider } from "./typesContext";
|
import { TypesProvider } from "./typesContext";
|
||||||
import { UndoRedoProvider } from "./undoRedoContext";
|
import { UndoRedoProvider } from "./undoRedoContext";
|
||||||
|
|
@ -22,9 +21,7 @@ export default function ContextWrapper({ children }: { children: ReactNode }) {
|
||||||
<AlertProvider>
|
<AlertProvider>
|
||||||
<SSEProvider>
|
<SSEProvider>
|
||||||
<TabsProvider>
|
<TabsProvider>
|
||||||
<UndoRedoProvider>
|
<UndoRedoProvider>{children}</UndoRedoProvider>
|
||||||
<PopUpProvider>{children}</PopUpProvider>
|
|
||||||
</UndoRedoProvider>
|
|
||||||
</TabsProvider>
|
</TabsProvider>
|
||||||
</SSEProvider>
|
</SSEProvider>
|
||||||
</AlertProvider>
|
</AlertProvider>
|
||||||
|
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
import React, { createContext, useState } from "react";
|
|
||||||
|
|
||||||
// context to set JSX element on the DOM
|
|
||||||
export const PopUpContext = createContext({
|
|
||||||
openPopUp: (popUpElement: JSX.Element) => {},
|
|
||||||
closePopUp: () => {},
|
|
||||||
setCloseEdit: (value: string) => {},
|
|
||||||
closeEdit: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
interface PopUpProviderProps {
|
|
||||||
children: React.ReactNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PopUpProvider = ({ children }: PopUpProviderProps) => {
|
|
||||||
const [popUpElements, setPopUpElements] = useState<JSX.Element[]>([]);
|
|
||||||
|
|
||||||
const openPopUp = (element: JSX.Element) => {
|
|
||||||
setPopUpElements((prevPopUps) => [element, ...prevPopUps]);
|
|
||||||
};
|
|
||||||
|
|
||||||
const closePopUp = () => {
|
|
||||||
setPopUpElements((prevPopUps) => prevPopUps.slice(1));
|
|
||||||
};
|
|
||||||
|
|
||||||
const [closeEdit, setCloseEdit] = useState("");
|
|
||||||
|
|
||||||
return (
|
|
||||||
<PopUpContext.Provider
|
|
||||||
value={{ openPopUp, closePopUp, closeEdit, setCloseEdit }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
{popUpElements[0]}
|
|
||||||
</PopUpContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default PopUpProvider;
|
|
||||||
|
|
@ -19,7 +19,9 @@ export type SingleAlertComponentType = {
|
||||||
dropItem: AlertItemType;
|
dropItem: AlertItemType;
|
||||||
removeAlert: (index: string) => void;
|
removeAlert: (index: string) => void;
|
||||||
};
|
};
|
||||||
export type AlertDropdownType = {};
|
export type AlertDropdownType = {
|
||||||
|
children: JSX.Element;
|
||||||
|
};
|
||||||
export type AlertItemType = {
|
export type AlertItemType = {
|
||||||
type: "notice" | "error" | "success";
|
type: "notice" | "error" | "success";
|
||||||
title: string;
|
title: string;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue