From 39a332eff1b466aa01c151c417c7da27588e85ba Mon Sep 17 00:00:00 2001 From: Hemachandar <132386067+hmacr@users.noreply.github.com> Date: Wed, 11 Oct 2023 15:54:24 +0530 Subject: [PATCH] feat: add filter for active jobs in the dashboard (#601) * feat: add filter for active jobs in the dashboard * use cursor-pointer when hovering Switch label * remove unused import * remove unnecessary span * add flex-gap --- .../app/components/primitives/Switch.tsx | 2 +- apps/webapp/app/hooks/useFilterJobs.ts | 24 ++++++++++++++++--- apps/webapp/app/hooks/useToggleFilter.ts | 21 ++++++++++++++++ .../route.tsx | 20 ++++++++++++---- .../route.tsx | 2 +- 5 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 apps/webapp/app/hooks/useToggleFilter.ts diff --git a/apps/webapp/app/components/primitives/Switch.tsx b/apps/webapp/app/components/primitives/Switch.tsx index fe4d69c46..cf592f8b8 100644 --- a/apps/webapp/app/components/primitives/Switch.tsx +++ b/apps/webapp/app/components/primitives/Switch.tsx @@ -15,7 +15,7 @@ const variations = { container: "flex items-center gap-x-1.5 rounded hover:bg-slate-850 pr-1 py-[0.1rem] pl-1.5", root: "h-3 w-6", thumb: "h-2.5 w-2.5 data-[state=checked]:translate-x-2.5 data-[state=unchecked]:translate-x-0", - text: "text-xs text-slate-400 group-hover:text-slate-200 mt-0.5", + text: "text-xs text-slate-400 group-hover:text-slate-200 hover:cursor-pointer", }, }; diff --git a/apps/webapp/app/hooks/useFilterJobs.ts b/apps/webapp/app/hooks/useFilterJobs.ts index 5cad14da3..950e19a43 100644 --- a/apps/webapp/app/hooks/useFilterJobs.ts +++ b/apps/webapp/app/hooks/useFilterJobs.ts @@ -1,9 +1,21 @@ import { ProjectJob } from "./useJobs"; import { useTextFilter } from "./useTextFilter"; +import { useToggleFilter } from "./useToggleFilter"; -export function useFilterJobs(jobs: ProjectJob[]) { - const { filterText, setFilterText, filteredItems } = useTextFilter({ +export function useFilterJobs(jobs: ProjectJob[], onlyActiveJobs = false) { + const toggleFilterRes = useToggleFilter({ items: jobs, + filter: (job, onlyActiveJobs) => { + if (onlyActiveJobs && job.status !== "ACTIVE") { + return false; + } + return true; + }, + defaultValue: onlyActiveJobs, + }); + + const textFilterRes = useTextFilter({ + items: toggleFilterRes.filteredItems, filter: (job, text) => { if (job.slug.toLowerCase().includes(text.toLowerCase())) return true; if (job.title.toLowerCase().includes(text.toLowerCase())) return true; @@ -24,5 +36,11 @@ export function useFilterJobs(jobs: ProjectJob[]) { }, }); - return { filterText, setFilterText, filteredItems }; + return { + filteredItems: textFilterRes.filteredItems, + filterText: textFilterRes.filterText, + setFilterText: textFilterRes.setFilterText, + onlyActiveJobs: toggleFilterRes.isToggleActive, + setOnlyActiveJobs: toggleFilterRes.setToggleActive, + }; } diff --git a/apps/webapp/app/hooks/useToggleFilter.ts b/apps/webapp/app/hooks/useToggleFilter.ts new file mode 100644 index 000000000..2e099a9f9 --- /dev/null +++ b/apps/webapp/app/hooks/useToggleFilter.ts @@ -0,0 +1,21 @@ +import { useMemo, useState } from "react"; + +type ToggleFilterProps = { + items: T[]; + filter: (item: T, isToggleActive: boolean) => boolean; + defaultValue?: boolean; +}; + +export function useToggleFilter({ items, filter, defaultValue = false }: ToggleFilterProps) { + const [isToggleActive, setToggleActive] = useState(defaultValue); + + const filteredItems = useMemo(() => { + return items.filter((item) => filter(item, isToggleActive)); + }, [items, isToggleActive]); + + return { + isToggleActive, + setToggleActive, + filteredItems, + }; +} diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam._index/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam._index/route.tsx index 0144db63b..88ce334c3 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam._index/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam._index/route.tsx @@ -19,6 +19,7 @@ import { PageTitleRow, } from "~/components/primitives/PageHeader"; import { Paragraph } from "~/components/primitives/Paragraph"; +import { Switch } from "~/components/primitives/Switch"; import { TextLink } from "~/components/primitives/TextLink"; import { useFilterJobs } from "~/hooks/useFilterJobs"; import { useOrganization } from "~/hooks/useOrganizations"; @@ -62,8 +63,11 @@ export default function Page() { const organization = useOrganization(); const project = useProject(); const { jobs } = useTypedLoaderData(); - const { filterText, setFilterText, filteredItems } = useFilterJobs(jobs); - const hasJobs = jobs.length > 0; + const { filterText, setFilterText, filteredItems, onlyActiveJobs, setOnlyActiveJobs } = + useFilterJobs(jobs); + const totalJobs = jobs.length; + const hasJobs = totalJobs > 0; + const activeJobCount = jobs.filter((j) => j.status === "ACTIVE").length; return ( @@ -74,7 +78,8 @@ export default function Page() { - + + @@ -96,7 +101,7 @@ export default function Page() { )}
-
+
setFilterText(e.target.value)} autoFocus /> +
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.integrations/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.integrations/route.tsx index 8a2535a2b..f450aef11 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.integrations/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.integrations/route.tsx @@ -152,7 +152,7 @@ function PossibleIntegrationsList({ onCheckedChange={setOnlyShowIntegrations} variant="small" label={ - + Trigger.dev Integrations }