mirror of
https://github.com/makeplane/plane.git
synced 2026-01-30 10:23:26 -06:00
refactor: recents widget for scalability (#6453)
Co-authored-by: pushya22 <130810100+pushya22@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
ee22dbba1b
commit
c429ca7b36
4
packages/types/src/home.d.ts
vendored
4
packages/types/src/home.d.ts
vendored
@@ -1,7 +1,7 @@
|
||||
import { TLogoProps } from "./common";
|
||||
import { TIssuePriorities } from "./issues";
|
||||
|
||||
export type TRecentActivityFilterKeys = "all item" | "issue" | "page" | "project";
|
||||
export type TRecentActivityFilterKeys = "all item" | "issue" | "page" | "project" | "workspace_page";
|
||||
export type THomeWidgetKeys = "quick_links" | "recents" | "my_stickies" | "quick_tutorial" | "new_at_plane";
|
||||
|
||||
export type THomeWidgetProps = {
|
||||
@@ -39,7 +39,7 @@ export type TIssueEntityData = {
|
||||
|
||||
export type TActivityEntityData = {
|
||||
id: string;
|
||||
entity_name: "page" | "project" | "issue";
|
||||
entity_name: "page" | "project" | "issue" | "workspace_page";
|
||||
entity_identifier: string;
|
||||
visited_at: string;
|
||||
entity_data: TPageEntityData | TProjectEntityData | TIssueEntityData;
|
||||
|
||||
@@ -22,15 +22,21 @@ const WIDGET_KEY = EWidgetKeys.RECENT_ACTIVITY;
|
||||
const workspaceService = new WorkspaceService();
|
||||
const filters: { name: TRecentActivityFilterKeys; icon?: React.ReactNode }[] = [
|
||||
{ name: "all item" },
|
||||
{ name: "issue", icon: <LayersIcon className="w-4 h-4" /> },
|
||||
{ name: "page", icon: <FileText size={16} /> },
|
||||
{ name: "project", icon: <Briefcase size={16} /> },
|
||||
{ name: "issue", icon: <LayersIcon className="flex-shrink-0 size-4" /> },
|
||||
{ name: "page", icon: <FileText className="flex-shrink-0 size-4" /> },
|
||||
{ name: "workspace_page", icon: <FileText className="flex-shrink-0 size-4" /> },
|
||||
{ name: "project", icon: <Briefcase className="flex-shrink-0 size-4" /> },
|
||||
];
|
||||
|
||||
export const RecentActivityWidget: React.FC<THomeWidgetProps> = observer((props) => {
|
||||
const { workspaceSlug } = props;
|
||||
type TRecentWidgetProps = THomeWidgetProps & {
|
||||
presetFilter?: TRecentActivityFilterKeys;
|
||||
showFilterSelect?: boolean;
|
||||
};
|
||||
|
||||
export const RecentActivityWidget: React.FC<TRecentWidgetProps> = observer((props) => {
|
||||
const { presetFilter, showFilterSelect = true, workspaceSlug } = props;
|
||||
// state
|
||||
const [filter, setFilter] = useState<TRecentActivityFilterKeys>(filters[0].name);
|
||||
const [filter, setFilter] = useState<TRecentActivityFilterKeys>(presetFilter ?? filters[0].name);
|
||||
// ref
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
// store hooks
|
||||
@@ -55,6 +61,7 @@ export const RecentActivityWidget: React.FC<THomeWidgetProps> = observer((props)
|
||||
const resolveRecent = (activity: TActivityEntityData) => {
|
||||
switch (activity.entity_name) {
|
||||
case "page":
|
||||
case "workspace_page":
|
||||
return <RecentPage activity={activity} ref={ref} workspaceSlug={workspaceSlug} />;
|
||||
case "project":
|
||||
return <RecentProject activity={activity} ref={ref} workspaceSlug={workspaceSlug} />;
|
||||
@@ -72,7 +79,7 @@ export const RecentActivityWidget: React.FC<THomeWidgetProps> = observer((props)
|
||||
<div ref={ref} className="max-h-[500px] overflow-y-scroll">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="text-base font-semibold text-custom-text-350">Recents</div>
|
||||
<FiltersDropdown filters={filters} activeFilter={filter} setActiveFilter={setFilter} />
|
||||
{showFilterSelect && <FiltersDropdown filters={filters} activeFilter={filter} setActiveFilter={setFilter} />}
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<RecentsEmptyState type={filter} />
|
||||
@@ -89,8 +96,7 @@ export const RecentActivityWidget: React.FC<THomeWidgetProps> = observer((props)
|
||||
>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="text-base font-semibold text-custom-text-350">Recents</div>
|
||||
|
||||
<FiltersDropdown filters={filters} activeFilter={filter} setActiveFilter={setFilter} />
|
||||
{showFilterSelect && <FiltersDropdown filters={filters} activeFilter={filter} setActiveFilter={setFilter} />}
|
||||
</div>
|
||||
<div className="min-h-[250px] flex flex-col">
|
||||
{isLoading && <WidgetLoader widgetKey={WIDGET_KEY} />}
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { useRouter } from "next/navigation";
|
||||
import { FileText } from "lucide-react";
|
||||
// plane types
|
||||
import { TActivityEntityData, TPageEntityData } from "@plane/types";
|
||||
// plane ui
|
||||
import { Avatar, Logo } from "@plane/ui";
|
||||
// plane utils
|
||||
import { getFileURL } from "@plane/utils";
|
||||
// components
|
||||
import { ListItem } from "@/components/core/list";
|
||||
// helpers
|
||||
import { calculateTimeAgo } from "@/helpers/date-time.helper";
|
||||
// hooks
|
||||
import { useMember } from "@/hooks/store";
|
||||
|
||||
type BlockProps = {
|
||||
@@ -12,15 +18,20 @@ type BlockProps = {
|
||||
ref: React.RefObject<HTMLDivElement>;
|
||||
workspaceSlug: string;
|
||||
};
|
||||
|
||||
export const RecentPage = (props: BlockProps) => {
|
||||
const { activity, ref, workspaceSlug } = props;
|
||||
// router
|
||||
const router = useRouter();
|
||||
// hooks
|
||||
// store hooks
|
||||
const { getUserDetails } = useMember();
|
||||
// derived values
|
||||
const pageDetails: TPageEntityData = activity.entity_data as TPageEntityData;
|
||||
const pageDetails = activity.entity_data as TPageEntityData;
|
||||
const ownerDetails = getUserDetails(pageDetails?.owned_by);
|
||||
const pageLink = pageDetails.project_id
|
||||
? `/${workspaceSlug}/projects/${pageDetails.project_id}/pages/${pageDetails.id}`
|
||||
: `/${workspaceSlug}/pages/${pageDetails.id}`;
|
||||
|
||||
return (
|
||||
<ListItem
|
||||
key={activity.id}
|
||||
@@ -58,7 +69,7 @@ export const RecentPage = (props: BlockProps) => {
|
||||
onItemClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
router.push(`/${workspaceSlug}/projects/${pageDetails?.project_id}/pages/${pageDetails.id}`);
|
||||
router.push(pageLink);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user