-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add projects list and new project form
- Loading branch information
Showing
30 changed files
with
708 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './newProjectForm'; |
1 change: 1 addition & 0 deletions
1
apps/app/src/components/dashboard/forms/newProjectForm/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './newProjectForm.component'; |
78 changes: 78 additions & 0 deletions
78
apps/app/src/components/dashboard/forms/newProjectForm/newProjectForm.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import { useMutation } from '@apollo/client'; | ||
import { PlusIcon } from '@heroicons/react/24/solid'; | ||
import { useForm } from 'react-hook-form'; | ||
|
||
import { ValidationError } from '@vm/api-client/__generated/gql/graphql'; | ||
|
||
import { newProjectMutation } from '@app/graphql/projects.graphql'; | ||
|
||
type NewProjectFormData = { | ||
name: string; | ||
}; | ||
|
||
export const NewProjectForm = () => { | ||
const { | ||
register, | ||
handleSubmit, | ||
formState: { errors }, | ||
reset, | ||
} = useForm<NewProjectFormData>(); | ||
|
||
const [createProject, { loading, error }] = useMutation(newProjectMutation); | ||
|
||
const onSubmit = async (formData: NewProjectFormData) => { | ||
try { | ||
const response = await createProject({ | ||
variables: { | ||
name: formData.name, | ||
}, | ||
}); | ||
|
||
const responseData = response.data?.createProject; | ||
|
||
if (response.data) { | ||
console.log(response.data); | ||
// handle success | ||
reset(); | ||
} else { | ||
const { message, fieldErrors } = responseData as ValidationError; | ||
// handle validation error | ||
console.error(message, fieldErrors); | ||
} | ||
} catch (error) { | ||
// handle other errors | ||
console.error(error); | ||
} | ||
}; | ||
|
||
return ( | ||
<form onSubmit={handleSubmit(onSubmit)} className="flex items-center mb-4"> | ||
<input | ||
type="text" | ||
{...register('name', { required: true })} | ||
className="flex-grow p-2 mr-2 border border-gray-400 rounded-md bg-white text-gray-800 dark:bg-gray-800 dark:text-white" | ||
placeholder="Enter project name" | ||
/> | ||
<button | ||
type="submit" | ||
className={`flex items-center px-4 py-2 rounded-md ${ | ||
loading ? 'bg-gray-400 cursor-wait' : 'bg-blue-500 hover:bg-blue-600' | ||
}`} | ||
disabled={loading} | ||
> | ||
<PlusIcon className="w-5 h-5 mr-2" /> | ||
Add Project | ||
</button> | ||
{errors.name && ( | ||
<p className="ml-2 text-red-500"> | ||
{errors.name.type === 'required' ? 'Project name is required' : errors.name.message} | ||
</p> | ||
)} | ||
{error && ( | ||
<p className="ml-2 text-red-500"> | ||
{error.message.includes('validation') ? error.message : 'Something went wrong'} | ||
</p> | ||
)} | ||
</form> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { Navigation } from './navigation.component'; |
21 changes: 21 additions & 0 deletions
21
apps/app/src/components/dashboard/navigation/navigation.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import Link from 'next/link'; | ||
|
||
export const Navigation = () => { | ||
return ( | ||
<div className="flex flex-col flex-auto"> | ||
<div className="grow p-4 px-2"> | ||
<div className="grid gap-y-1"> | ||
<Link href="/dashboard" className="p-2 rounded-lg hover:bg-indigo-900"> | ||
Dashboard | ||
</Link> | ||
<Link href="/projects" className="p-2 rounded-lg hover:bg-indigo-900"> | ||
Projects | ||
</Link> | ||
</div> | ||
</div> | ||
<div className="flex-none justify-self-end p-4"> | ||
<a href="#">Logout</a> | ||
</div> | ||
</div> | ||
); | ||
}; |
35 changes: 35 additions & 0 deletions
35
apps/app/src/components/dashboard/projectsList/projectsList.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { useQuery } from '@apollo/client'; | ||
import { PlusIcon } from '@heroicons/react/24/solid'; | ||
import Link from 'next/link'; | ||
import React from 'react'; | ||
|
||
import { ProjectsListItem } from '@app/components/dashboard/projectsList/projectsListItem.component'; | ||
import { projectsQuery } from '@app/graphql'; | ||
|
||
export const ProjectsList = () => { | ||
const { loading, data } = useQuery(projectsQuery); | ||
|
||
if (loading || !data) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<div className="p-4"> | ||
<div className="flex items-center justify-between mb-4"> | ||
<h1 className="text-2xl font-bold">Projects</h1> | ||
<Link | ||
href="/projects/new" | ||
className="flex items-center px-4 py-2 text-white bg-blue-500 rounded-md hover:bg-blue-600" | ||
> | ||
<PlusIcon className="w-5 h-5 mr-2" /> | ||
New Project | ||
</Link> | ||
</div> | ||
<ul className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3"> | ||
{data?.projects.map((project) => ( | ||
<ProjectsListItem project={project} key={project.id} /> | ||
))} | ||
</ul> | ||
</div> | ||
); | ||
}; |
62 changes: 62 additions & 0 deletions
62
apps/app/src/components/dashboard/projectsList/projectsListItem.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { Menu, Transition } from '@headlessui/react'; | ||
import { PencilIcon, TrashIcon } from '@heroicons/react/24/solid'; | ||
import Link from 'next/link'; | ||
import React from 'react'; | ||
|
||
import { FragmentType, getFragmentData } from '@vm/api-client/__generated/gql'; | ||
|
||
import { projectFragment } from '@app/graphql'; | ||
|
||
interface ProjectsListItemProps { | ||
project: FragmentType<typeof projectFragment>; | ||
} | ||
|
||
export const ProjectsListItem = ({ project }: ProjectsListItemProps) => { | ||
const data = getFragmentData(projectFragment, project); | ||
return ( | ||
<li className="flex flex-col p-4 bg-white dark:bg-slate-900 rounded-md shadow-md"> | ||
<h2 className="mb-2 text-xl font-bold">{data.name}</h2> | ||
<div className="flex mb-2 space-x-2"> | ||
<Link | ||
href={`/projects/${data.id}/edit`} | ||
className="flex items-center px-2 py-1 text-white bg-green-500 rounded-md hover:bg-green-600" | ||
> | ||
<PencilIcon className="w-5 h-5 mr-2" /> | ||
Edit | ||
</Link> | ||
<Menu as="div" className="relative inline-block text-left"> | ||
<div> | ||
<Menu.Button className="flex items-center px-2 py-1 text-white bg-red-500 rounded-md hover:bg-red-600"> | ||
<TrashIcon className="w-5 h-5 mr-2" /> | ||
Delete | ||
</Menu.Button> | ||
</div> | ||
<Transition | ||
enter="transition ease-out duration-100" | ||
enterFrom="transform opacity-0 scale-95" | ||
enterTo="transform opacity-100 scale-100" | ||
leave="transition ease-in duration-75" | ||
leaveFrom="transform opacity-100 scale-100" | ||
leaveTo="transform opacity-0 scale-95" | ||
> | ||
<Menu.Items className="absolute right-0 z-10 w-48 mt-2 origin-top-right bg-white rounded-md shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"> | ||
<Menu.Item> | ||
{({ active }) => ( | ||
<button | ||
className={`${active ? 'bg-gray-100' : ''} block w-full text-left px-4 py-2 text-sm`} | ||
onClick={() => { | ||
// Handle delete | ||
}} | ||
> | ||
Delete | ||
</button> | ||
)} | ||
</Menu.Item> | ||
</Menu.Items> | ||
</Transition> | ||
</Menu> | ||
</div> | ||
<p className="text-sm text-gray-600 dark:text-slate-400">{data.environments.edges.length} environments</p> | ||
</li> | ||
); | ||
}; |
24 changes: 24 additions & 0 deletions
24
apps/app/src/components/layouts/dashboard/dashboardLayout.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { Inter } from 'next/font/google'; | ||
import { PropsWithChildren, ReactNode } from 'react'; | ||
|
||
import { Navigation } from '@app/components/dashboard/navigation'; | ||
|
||
const inter = Inter({ subsets: ['latin'] }); | ||
|
||
export const DashboardLayout = ({ children }: PropsWithChildren) => { | ||
return ( | ||
<div className={`flex flex-row min-h-screen ${inter.className}`}> | ||
<div className="basis-60 bg-indigo-800 flex"> | ||
<Navigation /> | ||
</div> | ||
<div className="grow flex flex-col bg-white dark:bg-slate-900"> | ||
<header className="bg-white shadow dark:bg-gray-900"> | ||
<div className="mx-auto max-w-7xl px-4 py-6 sm:px-6 lg:px-8"></div> | ||
</header> | ||
<div className="grow overflow-auto bg-white dark:bg-gray-700">{children}</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export const getDashboardLayout = (page: ReactNode) => <DashboardLayout>{page}</DashboardLayout>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './dashboardLayout.component'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './dashboard'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { ProjectVersionsView } from './projectVersionsView.component'; |
75 changes: 75 additions & 0 deletions
75
apps/app/src/components/projectVersionsView/projectVersionsView.component.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { useQuery } from '@apollo/client'; | ||
import React from 'react'; | ||
|
||
import { projectsQuery } from './projectVersionsView.graphql'; | ||
|
||
interface ProjectVersionsViewProps { | ||
projectId: string; | ||
} | ||
|
||
export const ProjectVersionsView = ({ projectId }: ProjectVersionsViewProps) => { | ||
const { loading, data } = useQuery(projectsQuery, { variables: { id: projectId } }); | ||
|
||
if (loading || !data) { | ||
return null; | ||
} | ||
|
||
const project = data.project; | ||
return ( | ||
<> | ||
<div className="text-xl p-2">{project.name}</div> | ||
<div className="grid grid-flow-col justify-stretch"> | ||
{project.environments.edges.map((environmentNode, key) => { | ||
const env = environmentNode?.node; | ||
return ( | ||
<div | ||
className="bg-white dark:bg-slate-800 rounded-lg overflow-hidden m-2 ring-1 ring-slate-900/5 shadow-xl" | ||
key={key} | ||
> | ||
<div className="p-2"> | ||
<div className="text-slate-500 dark:text-slate-400">Environment name</div> | ||
<div className="text-xl font-medium text-slate-950 dark:text-white">{env?.name}</div> | ||
<a href="#" className="text-blue-600"> | ||
Open environment | ||
</a> | ||
</div> | ||
<div className="p-2"> | ||
<div className="text-slate-500 dark:text-slate-400">Version</div> | ||
<div className="text-xl font-medium text-green-800 dark:text-green-500">1.0.{key - 1}</div> | ||
<div className="text-slate-400 text-sx">Updated: 6.05.23 16:41:11</div> | ||
</div> | ||
<div className="bg-gray-100 dark:bg-slate-700 p-2"> | ||
<a href="#" className="text-gray-500 dark:text-slate-400 font-medium"> | ||
Show environment history | ||
</a> | ||
</div> | ||
</div> | ||
); | ||
})} | ||
</div> | ||
|
||
<div className="grid grid-flow-col justify-stretch"> | ||
{project.environments.edges.map((environmentNode, key) => { | ||
const env = environmentNode?.node; | ||
return ( | ||
<div className="bg-white dark:bg-slate-800 rounded-lg overflow-hidden m-2" key={key}> | ||
<div className="p-2"> | ||
<div className="text-slate-500 dark:text-slate-400 font-medium">Environment services</div> | ||
</div> | ||
{project.services.edges.map((serviceNode, key) => { | ||
const service = serviceNode?.node; | ||
return ( | ||
<div className="p-2" key={key}> | ||
<div className="text-slate-500 dark:text-slate-400 font-medium">{service?.name}</div> | ||
<div className="text-xl font-medium text-green-800 dark:text-green-500"></div> | ||
<div className="text-slate-400 text-sx">Updated: 6.05.23 16:41:11</div> | ||
</div> | ||
); | ||
})} | ||
</div> | ||
); | ||
})} | ||
</div> | ||
</> | ||
); | ||
}; |
30 changes: 30 additions & 0 deletions
30
apps/app/src/components/projectVersionsView/projectVersionsView.graphql.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { gql } from '@vm/api-client/__generated/gql'; | ||
|
||
export const projectsQuery = gql(/* GraphQL */ ` | ||
query projectQuery($id: ID!) { | ||
project(id: $id) { | ||
id | ||
name | ||
environments { | ||
edges { | ||
node { | ||
id | ||
name | ||
currentVersion { | ||
name | ||
id | ||
createdAt | ||
} | ||
} | ||
} | ||
} | ||
services { | ||
edges { | ||
node { | ||
name | ||
} | ||
} | ||
} | ||
} | ||
} | ||
`); |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './projects.graphql'; |
Oops, something went wrong.