Feat[DropdownButtonComponent]: Create Dropdown Button component

This commit is contained in:
igorrCarvalho 2023-08-29 18:34:55 -03:00
commit d6f9124405
8 changed files with 310 additions and 251 deletions

View file

@ -43,7 +43,9 @@ def add_user(
db.refresh(new_user) db.refresh(new_user)
except IntegrityError as e: except IntegrityError as e:
db.rollback() db.rollback()
raise HTTPException(status_code=400, detail="This username is unavailable.") from e raise HTTPException(
status_code=400, detail="This username is unavailable."
) from e
return new_user return new_user

View file

@ -0,0 +1,49 @@
import { useState } from "react";
import IconComponent from "../genericIconComponent";
import { Button } from "../ui/button";
export default function DropdownButton({
firstButtonName,
onFirstBtnClick,
options,
}): JSX.Element {
const [showOptions, setShowOptions] = useState(false);
return (
<div className="align-center relative flex">
<div>
<Button
variant="primary"
className="mr-4 w-full"
onClick={onFirstBtnClick}
>
{firstButtonName}
</Button>
</div>
<div>
<button
className="absolute inset-y-0 right-0 items-center text-muted-foreground"
onClick={(event) => {
event.stopPropagation();
setShowOptions(!showOptions);
}}
>
{!showOptions ? (
<IconComponent name="ChevronDown" className="" aria-hidden="true" />
) : (
<IconComponent name="ChevronUp" />
)}
</button>
</div>
{showOptions && (
<div className="absolute top-10 w-full">
{options.map((optionName) => (
<Button className="w-full" variant="primary">
{optionName}
</Button>
))}
</div>
)}
</div>
);
}

View file

@ -37,7 +37,7 @@ export default function Header(): JSX.Element {
logout(); logout();
navigate("/login"); navigate("/login");
}} }}
className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer mx-5" className="mx-5 cursor-pointer text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
> >
Sign out Sign out
</a> </a>
@ -48,7 +48,7 @@ export default function Header(): JSX.Element {
onClick={() => { onClick={() => {
navigate("/"); navigate("/");
}} }}
className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer" className="cursor-pointer text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
> >
Home Home
</a> </a>
@ -59,7 +59,7 @@ export default function Header(): JSX.Element {
location.pathname !== "/admin" && location.pathname !== "/admin" &&
location.pathname !== `/flow/${tabId}` && ( location.pathname !== `/flow/${tabId}` && (
<a <a
className="text-sm font-medium text-muted-foreground transition-colors hover:text-primary cursor-pointer" className="cursor-pointer text-sm font-medium text-muted-foreground transition-colors hover:text-primary"
onClick={() => navigate("/admin")} onClick={() => navigate("/admin")}
> >
Admin page Admin page

View file

@ -4,6 +4,7 @@ import { useContext, useEffect, useRef, useState } from "react";
import PaginatorComponent from "../../components/PaginatorComponent"; import PaginatorComponent from "../../components/PaginatorComponent";
import ShadTooltip from "../../components/ShadTooltipComponent"; import ShadTooltip from "../../components/ShadTooltipComponent";
import IconComponent from "../../components/genericIconComponent"; import IconComponent from "../../components/genericIconComponent";
import Header from "../../components/headerComponent";
import { Button } from "../../components/ui/button"; import { Button } from "../../components/ui/button";
import { Checkbox } from "../../components/ui/checkbox"; import { Checkbox } from "../../components/ui/checkbox";
import { Input } from "../../components/ui/input"; import { Input } from "../../components/ui/input";
@ -25,9 +26,8 @@ import {
} from "../../controllers/API"; } from "../../controllers/API";
import ConfirmationModal from "../../modals/ConfirmationModal"; import ConfirmationModal from "../../modals/ConfirmationModal";
import UserManagementModal from "../../modals/UserManagementModal"; import UserManagementModal from "../../modals/UserManagementModal";
import { UserInputType } from "../../types/components";
import Header from "../../components/headerComponent";
import { Users } from "../../types/api"; import { Users } from "../../types/api";
import { UserInputType } from "../../types/components";
export default function AdminPage() { export default function AdminPage() {
const [inputValue, setInputValue] = useState(""); const [inputValue, setInputValue] = useState("");
@ -89,7 +89,7 @@ export default function AdminPage() {
if (input === "") { if (input === "") {
setFilterUserList(userList.current); setFilterUserList(userList.current);
} else { } else {
const filteredList = userList.current.filter((user:Users) => const filteredList = userList.current.filter((user: Users) =>
user.username.toLowerCase().includes(input.toLowerCase()) user.username.toLowerCase().includes(input.toLowerCase())
); );
setFilterUserList(filteredList); setFilterUserList(filteredList);
@ -280,7 +280,8 @@ export default function AdminPage() {
</TableHeader> </TableHeader>
{!loadingUsers && ( {!loadingUsers && (
<TableBody> <TableBody>
{filterUserList.map((user:UserInputType, index) => ( {filterUserList.map(
(user: UserInputType, index) => (
<TableRow key={index}> <TableRow key={index}>
<TableCell className="truncate py-2 font-medium"> <TableCell className="truncate py-2 font-medium">
<ShadTooltip content={user.id}> <ShadTooltip content={user.id}>
@ -396,7 +397,10 @@ export default function AdminPage() {
handleDeleteUser(user); handleDeleteUser(user);
}} }}
> >
<ShadTooltip content="Delete" side="top"> <ShadTooltip
content="Delete"
side="top"
>
<IconComponent <IconComponent
name="Trash2" name="Trash2"
className="ml-2 h-4 w-4 cursor-pointer" className="ml-2 h-4 w-4 cursor-pointer"
@ -406,7 +410,8 @@ export default function AdminPage() {
</div> </div>
</TableCell> </TableCell>
</TableRow> </TableRow>
))} )
)}
</TableBody> </TableBody>
)} )}
</Table> </Table>

View file

@ -421,7 +421,7 @@ export default function Page({
zoomOnScroll={!view} zoomOnScroll={!view}
zoomOnPinch={!view} zoomOnPinch={!view}
panOnDrag={!view} panOnDrag={!view}
proOptions={{hideAttribution: true}} proOptions={{ hideAttribution: true }}
> >
<Background className="" /> <Background className="" />
{!view && ( {!view && (

View file

@ -19,7 +19,8 @@ export default function LoginPage(): JSX.Element {
useState<loginInputStateType>(CONTROL_LOGIN_STATE); useState<loginInputStateType>(CONTROL_LOGIN_STATE);
const { password, username } = inputState; const { password, username } = inputState;
const { login, getAuthentication, setUserData, setIsAdmin } = useContext(AuthContext); const { login, getAuthentication, setUserData, setIsAdmin } =
useContext(AuthContext);
const navigate = useNavigate(); const navigate = useNavigate();
const { setErrorData } = useContext(alertContext); const { setErrorData } = useContext(alertContext);

View file

@ -268,7 +268,7 @@ export type UserInputType = {
is_superuser?: boolean; is_superuser?: boolean;
id?: string; id?: string;
create_at?: string; create_at?: string;
updated_at?:string; updated_at?: string;
}; };
export type ApiKeyType = { export type ApiKeyType = {

View file

@ -5,6 +5,7 @@ import {
ChevronDown, ChevronDown,
ChevronLeft, ChevronLeft,
ChevronRight, ChevronRight,
ChevronUp,
ChevronsLeft, ChevronsLeft,
ChevronsRight, ChevronsRight,
ChevronsUpDown, ChevronsUpDown,
@ -300,4 +301,5 @@ export const nodeIconsLucide: iconsType = {
UserCog2, UserCog2,
Key, Key,
Unplug, Unplug,
ChevronUp,
}; };