mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 09:26:47 +00:00
Merge pull request #4432 from Infisical/project-view-select-improvements
improvement(frontend): Revise Project View Select UI on Project Overview Page
This commit is contained in:
@@ -11,7 +11,7 @@ import { usePopUp } from "@app/hooks/usePopUp";
|
|||||||
|
|
||||||
import { AllProjectView } from "./components/AllProjectView";
|
import { AllProjectView } from "./components/AllProjectView";
|
||||||
import { MyProjectView } from "./components/MyProjectView";
|
import { MyProjectView } from "./components/MyProjectView";
|
||||||
import { ProjectListToggle, ProjectListView } from "./components/ProjectListToggle";
|
import { ProjectListView } from "./components/ProjectListToggle";
|
||||||
|
|
||||||
// const formatDescription = (type: ProjectType) => {
|
// const formatDescription = (type: ProjectType) => {
|
||||||
// if (type === ProjectType.SecretManager)
|
// if (type === ProjectType.SecretManager)
|
||||||
@@ -28,7 +28,23 @@ import { ProjectListToggle, ProjectListView } from "./components/ProjectListTogg
|
|||||||
export const ProjectsPage = () => {
|
export const ProjectsPage = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [projectListView, setProjectListView] = useState(ProjectListView.MyProjects);
|
const [projectListView, setProjectListView] = useState<ProjectListView>(() => {
|
||||||
|
const storedView = localStorage.getItem("projectListView");
|
||||||
|
|
||||||
|
if (
|
||||||
|
storedView &&
|
||||||
|
(storedView === ProjectListView.AllProjects || storedView === ProjectListView.MyProjects)
|
||||||
|
) {
|
||||||
|
return storedView;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProjectListView.MyProjects;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSetProjectListView = (value: ProjectListView) => {
|
||||||
|
localStorage.setItem("projectListView", value);
|
||||||
|
setProjectListView(value);
|
||||||
|
};
|
||||||
|
|
||||||
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([
|
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp([
|
||||||
"addNewWs",
|
"addNewWs",
|
||||||
@@ -49,11 +65,7 @@ export const ProjectsPage = () => {
|
|||||||
</Helmet>
|
</Helmet>
|
||||||
<div className="mb-4 flex flex-col items-start justify-start">
|
<div className="mb-4 flex flex-col items-start justify-start">
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title={
|
title="Projects"
|
||||||
<div className="flex items-center gap-4">
|
|
||||||
<ProjectListToggle value={projectListView} onChange={setProjectListView} />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
description="Your team's complete security toolkit - organized and ready when you need them."
|
description="Your team's complete security toolkit - organized and ready when you need them."
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -62,12 +74,16 @@ export const ProjectsPage = () => {
|
|||||||
onAddNewProject={() => handlePopUpOpen("addNewWs")}
|
onAddNewProject={() => handlePopUpOpen("addNewWs")}
|
||||||
onUpgradePlan={() => handlePopUpOpen("upgradePlan")}
|
onUpgradePlan={() => handlePopUpOpen("upgradePlan")}
|
||||||
isAddingProjectsAllowed={isAddingProjectsAllowed}
|
isAddingProjectsAllowed={isAddingProjectsAllowed}
|
||||||
|
projectListView={projectListView}
|
||||||
|
onProjectListViewChange={handleSetProjectListView}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<AllProjectView
|
<AllProjectView
|
||||||
onAddNewProject={() => handlePopUpOpen("addNewWs")}
|
onAddNewProject={() => handlePopUpOpen("addNewWs")}
|
||||||
onUpgradePlan={() => handlePopUpOpen("upgradePlan")}
|
onUpgradePlan={() => handlePopUpOpen("upgradePlan")}
|
||||||
isAddingProjectsAllowed={isAddingProjectsAllowed}
|
isAddingProjectsAllowed={isAddingProjectsAllowed}
|
||||||
|
projectListView={projectListView}
|
||||||
|
onProjectListViewChange={handleSetProjectListView}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<NewProjectModal
|
<NewProjectModal
|
||||||
|
|||||||
@@ -49,11 +49,17 @@ import {
|
|||||||
useSearchProjects
|
useSearchProjects
|
||||||
} from "@app/hooks/api";
|
} from "@app/hooks/api";
|
||||||
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
|
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
|
||||||
|
import {
|
||||||
|
ProjectListToggle,
|
||||||
|
ProjectListView
|
||||||
|
} from "@app/pages/organization/ProjectsPage/components/ProjectListToggle";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onAddNewProject: () => void;
|
onAddNewProject: () => void;
|
||||||
onUpgradePlan: () => void;
|
onUpgradePlan: () => void;
|
||||||
isAddingProjectsAllowed: boolean;
|
isAddingProjectsAllowed: boolean;
|
||||||
|
projectListView: ProjectListView;
|
||||||
|
onProjectListViewChange: (value: ProjectListView) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
type RequestAccessModalProps = {
|
type RequestAccessModalProps = {
|
||||||
@@ -106,7 +112,9 @@ const RequestAccessModal = ({ projectId, onPopUpToggle }: RequestAccessModalProp
|
|||||||
export const AllProjectView = ({
|
export const AllProjectView = ({
|
||||||
onAddNewProject,
|
onAddNewProject,
|
||||||
onUpgradePlan,
|
onUpgradePlan,
|
||||||
isAddingProjectsAllowed
|
isAddingProjectsAllowed,
|
||||||
|
projectListView,
|
||||||
|
onProjectListViewChange
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [searchFilter, setSearchFilter] = useState("");
|
const [searchFilter, setSearchFilter] = useState("");
|
||||||
@@ -176,10 +184,10 @@ export const AllProjectView = ({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex w-full flex-row">
|
<div className="flex w-full flex-row">
|
||||||
<div className="flex-grow" />
|
<ProjectListToggle value={projectListView} onChange={onProjectListViewChange} />
|
||||||
<Input
|
<Input
|
||||||
className="h-[2.3rem] bg-mineshaft-800 text-sm placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80"
|
className="h-[2.3rem] bg-mineshaft-800 text-sm placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80"
|
||||||
containerClassName="w-full"
|
containerClassName="w-full ml-2"
|
||||||
placeholder="Search by project name..."
|
placeholder="Search by project name..."
|
||||||
value={searchFilter}
|
value={searchFilter}
|
||||||
onChange={(e) => setSearchFilter(e.target.value)}
|
onChange={(e) => setSearchFilter(e.target.value)}
|
||||||
@@ -242,7 +250,7 @@ export const AllProjectView = ({
|
|||||||
))}
|
))}
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<div className="ml-2 flex rounded-md border border-mineshaft-600 bg-mineshaft-800 p-1">
|
<div className="ml-2 flex gap-x-0.5 rounded-md border border-mineshaft-600 bg-mineshaft-800 p-1">
|
||||||
<Tooltip content="Disabled across All Project view.">
|
<Tooltip content="Disabled across All Project view.">
|
||||||
<div className="flex cursor-not-allowed items-center justify-center">
|
<div className="flex cursor-not-allowed items-center justify-center">
|
||||||
<IconButton
|
<IconButton
|
||||||
|
|||||||
@@ -44,11 +44,17 @@ import { OrderByDirection } from "@app/hooks/api/generic/types";
|
|||||||
import { useUpdateUserProjectFavorites } from "@app/hooks/api/users/mutation";
|
import { useUpdateUserProjectFavorites } from "@app/hooks/api/users/mutation";
|
||||||
import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries";
|
import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries";
|
||||||
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
|
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
|
||||||
|
import {
|
||||||
|
ProjectListToggle,
|
||||||
|
ProjectListView
|
||||||
|
} from "@app/pages/organization/ProjectsPage/components/ProjectListToggle";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onAddNewProject: () => void;
|
onAddNewProject: () => void;
|
||||||
onUpgradePlan: () => void;
|
onUpgradePlan: () => void;
|
||||||
isAddingProjectsAllowed: boolean;
|
isAddingProjectsAllowed: boolean;
|
||||||
|
projectListView: ProjectListView;
|
||||||
|
onProjectListViewChange: (value: ProjectListView) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ProjectOrderBy {
|
enum ProjectOrderBy {
|
||||||
@@ -63,7 +69,9 @@ enum ProjectsViewMode {
|
|||||||
export const MyProjectView = ({
|
export const MyProjectView = ({
|
||||||
onAddNewProject,
|
onAddNewProject,
|
||||||
onUpgradePlan,
|
onUpgradePlan,
|
||||||
isAddingProjectsAllowed
|
isAddingProjectsAllowed,
|
||||||
|
projectListView,
|
||||||
|
onProjectListViewChange
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { currentOrg } = useOrganization();
|
const { currentOrg } = useOrganization();
|
||||||
@@ -371,10 +379,10 @@ export const MyProjectView = ({
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className="flex w-full flex-row">
|
<div className="flex w-full flex-row">
|
||||||
<div className="flex-grow" />
|
<ProjectListToggle value={projectListView} onChange={onProjectListViewChange} />
|
||||||
<Input
|
<Input
|
||||||
className="h-[2.3rem] bg-mineshaft-800 text-sm placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80"
|
className="h-[2.3rem] bg-mineshaft-800 text-sm placeholder-mineshaft-50 duration-200 focus:bg-mineshaft-700/80"
|
||||||
containerClassName="w-full"
|
containerClassName="w-full ml-2"
|
||||||
placeholder="Search by project name..."
|
placeholder="Search by project name..."
|
||||||
value={searchFilter}
|
value={searchFilter}
|
||||||
onChange={(e) => setSearchFilter(e.target.value)}
|
onChange={(e) => setSearchFilter(e.target.value)}
|
||||||
@@ -441,7 +449,7 @@ export const MyProjectView = ({
|
|||||||
))}
|
))}
|
||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<div className="ml-2 flex rounded-md border border-mineshaft-600 bg-mineshaft-800 p-1">
|
<div className="ml-2 flex gap-x-0.5 rounded-md border border-mineshaft-600 bg-mineshaft-800 p-1">
|
||||||
<IconButton
|
<IconButton
|
||||||
variant="outline_bg"
|
variant="outline_bg"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
import { faChevronDown } from "@fortawesome/free-solid-svg-icons";
|
import { Button } from "@app/components/v2";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
||||||
|
|
||||||
import { Select, SelectItem } from "@app/components/v2";
|
|
||||||
|
|
||||||
export enum ProjectListView {
|
export enum ProjectListView {
|
||||||
MyProjects = "my-projects",
|
MyProjects = "my-projects",
|
||||||
@@ -14,28 +11,32 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const ProjectListToggle = ({ value, onChange }: Props) => {
|
export const ProjectListToggle = ({ value, onChange }: Props) => {
|
||||||
const getDisplayText = (listView: ProjectListView) => {
|
|
||||||
return listView === ProjectListView.MyProjects ? "My Projects" : "All Projects";
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="group relative flex cursor-pointer items-center gap-2">
|
<div className="flex gap-x-0.5 rounded-md border border-mineshaft-600 bg-mineshaft-800 p-1">
|
||||||
<h1 className="text-3xl font-semibold transition-colors group-hover:text-gray-500">
|
<Button
|
||||||
{getDisplayText(value)}
|
variant="outline_bg"
|
||||||
</h1>
|
onClick={() => {
|
||||||
<Select
|
onChange(ProjectListView.MyProjects);
|
||||||
value={value}
|
}}
|
||||||
onValueChange={onChange}
|
size="xs"
|
||||||
className="absolute left-0 top-0 h-full w-full cursor-pointer opacity-0"
|
className={`${
|
||||||
position="popper"
|
value === ProjectListView.MyProjects ? "bg-mineshaft-500" : "bg-transparent"
|
||||||
|
} min-w-[2.4rem] rounded border-none hover:bg-mineshaft-600`}
|
||||||
>
|
>
|
||||||
<SelectItem value={ProjectListView.MyProjects}>My Projects</SelectItem>
|
My Projects
|
||||||
<SelectItem value={ProjectListView.AllProjects}>All Projects</SelectItem>
|
</Button>
|
||||||
</Select>
|
<Button
|
||||||
<FontAwesomeIcon
|
variant="outline_bg"
|
||||||
icon={faChevronDown}
|
onClick={() => {
|
||||||
className="text-lg transition-colors group-hover:text-gray-500"
|
onChange(ProjectListView.AllProjects);
|
||||||
/>
|
}}
|
||||||
|
size="xs"
|
||||||
|
className={`${
|
||||||
|
value === ProjectListView.AllProjects ? "bg-mineshaft-500" : "bg-transparent"
|
||||||
|
} min-w-[2.4rem] rounded border-none hover:bg-mineshaft-600`}
|
||||||
|
>
|
||||||
|
All Projects
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user