Display searched project from different organization (#52)

* Refactor to remove use of organization project

* Remove organization project from member tab panel

* Handle review changes

---------

Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
Nabarun Gogoi 2024-01-30 17:24:40 +05:30 committed by Ashwin Phatak
parent 8bbe2583cb
commit 8ead083ab3
6 changed files with 32 additions and 118 deletions

View File

@ -1,28 +1,20 @@
import React, { useMemo } from 'react';
import React from 'react';
import { Project } from 'gql-client';
import { Typography, Button, Chip } from '@material-tailwind/react';
import ActivityCard from './ActivityCard';
import activityDetails from '../../../assets/activities.json';
import { ProjectDetails } from '../../../types/project';
import { relativeTimeMs } from '../../../utils/time';
interface OverviewProps {
project: Project;
organizationProject: ProjectDetails;
}
const OverviewTabPanel = ({ project, organizationProject }: OverviewProps) => {
// TODO: Fetch current deployment
const currentDeploymentTitle = useMemo(() => {
const deployment = organizationProject?.deployments.find((deployment) => {
return deployment.isCurrent === true;
});
return deployment?.title;
}, [organizationProject]);
// TODO: Check any live domain is set for production branch
const IS_DOMAIN_SETUP = true;
const OverviewTabPanel = ({ project }: OverviewProps) => {
return (
<div className="grid grid-cols-5">
<div className="col-span-3 p-2">
@ -39,17 +31,24 @@ const OverviewTabPanel = ({ project, organizationProject }: OverviewProps) => {
<div className="flex justify-between p-2 text-sm items-center">
<div>
^ Domain
{!organizationProject.domain && (
{!IS_DOMAIN_SETUP && (
<Chip
className="normal-case ml-6 bg-[#FED7AA] text-[#EA580C] inline font-normal"
className="normal-case ml-6 inline font-normal"
size="sm"
value="Not connected"
icon="^"
color="orange"
/>
)}
</div>
{organizationProject.domain ? (
<p>{organizationProject.domain}</p>
{IS_DOMAIN_SETUP ? (
<Chip
className="normal-case ml-6 inline font-normal"
size="sm"
value="Connected"
icon="^"
color="green"
/>
) : (
<Button className="normal-case rounded-full" color="blue" size="sm">
Setup
@ -58,11 +57,13 @@ const OverviewTabPanel = ({ project, organizationProject }: OverviewProps) => {
</div>
<div className="flex justify-between p-2 text-sm">
<p>^ Source</p>
<p>{organizationProject.source}</p>
<p>{project.deployments[0]?.branch}</p>
</div>
<div className="flex justify-between p-2 text-sm">
<p>^ Deployment</p>
<p className="text-blue-600">{currentDeploymentTitle}</p>
<p className="text-blue-600">
{project.deployments[0]?.domain?.name}
</p>
</div>
<div className="flex justify-between p-2 text-sm">
<p>^ Created</p>

View File

@ -4,12 +4,10 @@ import { Project } from 'gql-client';
import OverviewTabPanel from './OverviewTabPanel';
import DeploymentsTabPanel from './DeploymentsTabPanel';
import { ProjectDetails } from '../../../types/project';
import SettingsTabPanel from './SettingsTabPanel';
interface ProjectTabsProps {
project: Project;
organizationProject: ProjectDetails;
onUpdate: () => Promise<void>;
}
@ -31,11 +29,7 @@ const Integrations = () => (
</div>
);
const ProjectTabs = ({
project,
onUpdate,
organizationProject,
}: ProjectTabsProps) => {
const ProjectTabs = ({ project, onUpdate }: ProjectTabsProps) => {
return (
<Tabs
selectedTabClassName={
@ -50,10 +44,7 @@ const ProjectTabs = ({
<Tab className={'p-2 cursor-pointer'}>Settings</Tab>
</TabList>
<TabPanel>
<OverviewTabPanel
project={project}
organizationProject={organizationProject}
/>
<OverviewTabPanel project={project} />
</TabPanel>
<TabPanel>
<DeploymentsTabPanel projectId={project.id} />

View File

@ -1,33 +1,21 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useOutletContext, useParams } from 'react-router-dom';
import React, { useCallback, useEffect, useState } from 'react';
import toast, { Toaster } from 'react-hot-toast';
import { Project } from 'gql-client';
import { Chip, Button, Typography } from '@material-tailwind/react';
import MemberCard from './MemberCard';
import {
ProjectMember,
ProjectSearchOutletContext,
} from '../../../../types/project';
import { ProjectMember } from '../../../../types/project';
import AddMemberDialog from './AddMemberDialog';
import { useGQLClient } from '../../../../context/GQLClientContext';
const FIRST_MEMBER_CARD = 0;
const MembersTabPanel = ({ project }: { project: Project }) => {
const { id } = useParams();
const client = useGQLClient();
const [addmemberDialogOpen, setAddMemberDialogOpen] = useState(false);
const { projects } = useOutletContext<ProjectSearchOutletContext>();
const currentProject = useMemo(() => {
return projects.find((project) => project.id === id);
}, [id]);
const [projectMembers, setProjectMembers] = useState<ProjectMember[]>([]);
const addMemberHandler = useCallback((projectMember: ProjectMember) => {
@ -36,14 +24,10 @@ const MembersTabPanel = ({ project }: { project: Project }) => {
}, []);
const fetchProjectMembers = useCallback(async () => {
if (currentProject) {
const { projectMembers } = await client.getProjectMembers(
currentProject.id,
);
const { projectMembers } = await client.getProjectMembers(project.id);
setProjectMembers(projectMembers);
}
}, [currentProject]);
}, [project.id]);
const removeMemberHandler = async (projectMemberId: string) => {
const { removeMember: isMemberRemoved } =
@ -59,7 +43,7 @@ const MembersTabPanel = ({ project }: { project: Project }) => {
useEffect(() => {
fetchProjectMembers();
}, []);
}, [project.id]);
return (
<div className="p-2 mb-20">
@ -98,7 +82,7 @@ const MembersTabPanel = ({ project }: { project: Project }) => {
member={projectMember.member}
key={projectMember.id}
isFirstCard={index === FIRST_MEMBER_CARD}
isOwner={projectMember.member.id === currentProject?.owner.id}
isOwner={projectMember.member.id === project.owner.id}
isPending={projectMember.member.name === ''}
permissions={projectMember.permissions}
handleDeletePendingMember={(id: string) => {

View File

@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useNavigate, useOutletContext, useParams } from 'react-router-dom';
import React, { useCallback, useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { Project as ProjectType } from 'gql-client';
import { Button, Typography } from '@material-tailwind/react';
@ -7,7 +7,6 @@ import { Button, Typography } from '@material-tailwind/react';
import HorizontalLine from '../../components/HorizontalLine';
import ProjectTabs from '../../components/projects/project/ProjectTabs';
import { useGQLClient } from '../../context/GQLClientContext';
import { ProjectSearchOutletContext } from '../../types/project';
const Project = () => {
const { id } = useParams();
@ -31,19 +30,9 @@ const Project = () => {
await fetchProject(id);
};
// TODO: Remove organization projects
const { projects: organizationProjects } =
useOutletContext<ProjectSearchOutletContext>();
const organizationProject = useMemo(() => {
return organizationProjects.find((project) => {
return project.id === id;
});
}, [id, organizationProjects]);
return (
<div className="h-full">
{project && organizationProject ? (
{project ? (
<>
<div className="flex p-4 gap-4 items-center">
<Button
@ -65,11 +54,7 @@ const Project = () => {
</div>
<HorizontalLine />
<div className="p-4">
<ProjectTabs
project={project}
organizationProject={organizationProject}
onUpdate={onUpdate}
/>
<ProjectTabs project={project} onUpdate={onUpdate} />
</div>
</>
) : (

View File

@ -1,43 +0,0 @@
import React from 'react';
import { Link, useOutletContext } from 'react-router-dom';
import { Button, Typography, Chip } from '@material-tailwind/react';
import ProjectCard from '../../components/projects/ProjectCard';
import { ProjectSearchOutletContext } from '../../types/project';
const Projects = () => {
const { projects } = useOutletContext<ProjectSearchOutletContext>();
return (
<div>
<div className="flex p-5">
<div className="grow">
<div className="flex gap-2 items-center">
<Typography variant="h4">Projects</Typography>
<Chip
className="bg-gray-300 rounded-full static"
value={projects.length}
size="sm"
/>
</div>
</div>
<div>
<Link to="/projects/create">
<Button className="rounded-full" color="blue">
Create project
</Button>
</Link>
</div>
</div>
<div className="grid grid-cols-3 gap-5 p-5">
{projects.length !== 0 &&
projects.map((project: any, key: number) => {
return <ProjectCard project={project} key={key} />;
})}
</div>
</div>
);
};
export default Projects;

View File

@ -1,10 +1,6 @@
import { Project, Deployment } from 'gql-client';
export interface ProjectDetails extends Project {
// TODO: isDomain flag
domain?: string | null;
// TODO: Use deployment branch
source?: string;
latestCommit: Commit;
// TODO: Move out of project