mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
092e65b43d
* [WEB-1424] chore: page and view logo implementation, and emoji/icon picker improvement (#4583) * chore: added logo_props * chore: logo props in cycles, views and modules * chore: emoji icon picker types updated * chore: info icon added to plane ui package * chore: icon color adjust helper function added * style: icon picker ui improvement and default color options updated * chore: update page logo action added in store * chore: emoji code to unicode helper function added * chore: common logo renderer component added * chore: app header project logo updated * chore: project logo updated across platform * chore: page logo picker added * chore: control link component improvement * chore: list item improvement * chore: emoji picker component updated * chore: space app and package logo prop type updated * chore: migration * chore: logo added to project view * chore: page logo picker added in create modal and breadcrumbs * chore: view logo picker added in create modal and updated breadcrumbs * fix: build error * chore: AIO docker images for preview deployments (#4605) * fix: adding single docker base file * action added * fix action * dockerfile.base modified * action fix * dockerfile * fix: base aio dockerfile * fix: dockerfile.base * fix: dockerfile base * fix: modified folder structure * fix: action * fix: dockerfile * fix: dockerfile.base * fix: supervisor file name changed * fix: base dockerfile updated * fix dockerfile base * fix: base dockerfile * fix: docker files * fix: base dockerfile * update base image * modified docker aio base * aio base modified to debian-12-slim * fixes * finalize the dockerfiles with volume exposure * modified the aio build and dockerfile * fix: codacy suggestions implemented * fix: codacy fix * update aio build action --------- Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com> * fix: merge conflict * chore: lucide react added to planu ui package * chore: new emoji picker component added with lucid icon and code refactor * chore: logo component updated * chore: emoji picker updated for pages and views --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> Co-authored-by: Manish Gupta <59428681+mguptahub@users.noreply.github.com> Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com> * fix: build error --------- Co-authored-by: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com> Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> Co-authored-by: Manish Gupta <59428681+mguptahub@users.noreply.github.com> Co-authored-by: Anmol Singh Bhatia <anmolsinghbhatia@plane.so>
117 lines
4.3 KiB
TypeScript
117 lines
4.3 KiB
TypeScript
import { useEffect } from "react";
|
|
import { observer } from "mobx-react";
|
|
import Link from "next/link";
|
|
import { Plus } from "lucide-react";
|
|
// types
|
|
import { TRecentProjectsWidgetResponse } from "@plane/types";
|
|
// ui
|
|
import { Avatar, AvatarGroup } from "@plane/ui";
|
|
// components
|
|
import { Logo } from "@/components/common";
|
|
import { WidgetLoader, WidgetProps } from "@/components/dashboard/widgets";
|
|
// constants
|
|
import { PROJECT_BACKGROUND_COLORS } from "@/constants/dashboard";
|
|
import { EUserWorkspaceRoles } from "@/constants/workspace";
|
|
// hooks
|
|
import { useEventTracker, useDashboard, useProject, useUser, useCommandPalette } from "@/hooks/store";
|
|
|
|
const WIDGET_KEY = "recent_projects";
|
|
|
|
type ProjectListItemProps = {
|
|
projectId: string;
|
|
workspaceSlug: string;
|
|
};
|
|
|
|
const ProjectListItem: React.FC<ProjectListItemProps> = observer((props) => {
|
|
const { projectId, workspaceSlug } = props;
|
|
// store hooks
|
|
const { getProjectById } = useProject();
|
|
const projectDetails = getProjectById(projectId);
|
|
|
|
const randomBgColor = PROJECT_BACKGROUND_COLORS[Math.floor(Math.random() * PROJECT_BACKGROUND_COLORS.length)];
|
|
|
|
if (!projectDetails) return null;
|
|
|
|
return (
|
|
<Link href={`/${workspaceSlug}/projects/${projectId}/issues`} className="group flex items-center gap-8">
|
|
<div
|
|
className={`grid h-[3.375rem] w-[3.375rem] flex-shrink-0 place-items-center rounded border border-transparent ${randomBgColor}`}
|
|
>
|
|
<div className="grid h-7 w-7 place-items-center">
|
|
<Logo logo={projectDetails.logo_props} size={20} />
|
|
</div>
|
|
</div>
|
|
<div className="flex-grow truncate">
|
|
<h6 className="truncate text-sm font-medium text-custom-text-300 group-hover:text-custom-text-100 group-hover:underline">
|
|
{projectDetails.name}
|
|
</h6>
|
|
<div className="mt-2">
|
|
<AvatarGroup>
|
|
{projectDetails.members?.map((member) => (
|
|
<Avatar key={member.member_id} src={member.member__avatar} name={member.member__display_name} />
|
|
))}
|
|
</AvatarGroup>
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
);
|
|
});
|
|
|
|
export const RecentProjectsWidget: React.FC<WidgetProps> = observer((props) => {
|
|
const { dashboardId, workspaceSlug } = props;
|
|
// store hooks
|
|
const { toggleCreateProjectModal } = useCommandPalette();
|
|
const { setTrackElement } = useEventTracker();
|
|
const {
|
|
membership: { currentWorkspaceRole },
|
|
} = useUser();
|
|
const { fetchWidgetStats, getWidgetStats } = useDashboard();
|
|
// derived values
|
|
const widgetStats = getWidgetStats<TRecentProjectsWidgetResponse>(workspaceSlug, dashboardId, WIDGET_KEY);
|
|
const canCreateProject = currentWorkspaceRole && currentWorkspaceRole >= EUserWorkspaceRoles.MEMBER;
|
|
|
|
useEffect(() => {
|
|
fetchWidgetStats(workspaceSlug, dashboardId, {
|
|
widget_key: WIDGET_KEY,
|
|
});
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, []);
|
|
|
|
if (!widgetStats) return <WidgetLoader widgetKey={WIDGET_KEY} />;
|
|
|
|
return (
|
|
<div className="min-h-96 w-full rounded-xl border-[0.5px] border-custom-border-200 bg-custom-background-100 py-6 duration-300 hover:shadow-custom-shadow-4xl">
|
|
<Link
|
|
href={`/${workspaceSlug}/projects`}
|
|
className="mx-7 text-lg font-semibold text-custom-text-300 hover:underline"
|
|
>
|
|
Recent projects
|
|
</Link>
|
|
<div className="mx-7 mt-4 space-y-8">
|
|
{canCreateProject && (
|
|
<button
|
|
type="button"
|
|
className="group flex items-center gap-8"
|
|
onClick={(e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
setTrackElement("Sidebar");
|
|
toggleCreateProjectModal(true);
|
|
}}
|
|
>
|
|
<div className="grid h-[3.375rem] w-[3.375rem] flex-shrink-0 place-items-center rounded border border-dashed border-custom-primary-60 bg-custom-primary-100/20 text-custom-primary-100">
|
|
<Plus className="h-6 w-6" />
|
|
</div>
|
|
<p className="text-sm font-medium text-custom-text-300 group-hover:text-custom-text-100 group-hover:underline">
|
|
Create new project
|
|
</p>
|
|
</button>
|
|
)}
|
|
{widgetStats.map((projectId) => (
|
|
<ProjectListItem key={projectId} projectId={projectId} workspaceSlug={workspaceSlug} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
});
|