diff --git a/webui/graphql.schema.json b/webui/graphql.schema.json index 08742a9..06436c1 100644 --- a/webui/graphql.schema.json +++ b/webui/graphql.schema.json @@ -958,6 +958,71 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "updateProject", + "description": null, + "args": [ + { + "name": "description", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "id", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "ID", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "name", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "tags", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "Project", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -1344,6 +1409,30 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "description", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "displayName", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "id", "description": null, @@ -1459,6 +1548,26 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "tags", + "description": null, + "args": [], + "type": { + "kind": "LIST", + "name": null, + "ofType": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + } + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, diff --git a/webui/src/Components/Header/Header.tsx b/webui/src/Components/Header/Header.tsx index c355c0f..b8a11ff 100644 --- a/webui/src/Components/Header/Header.tsx +++ b/webui/src/Components/Header/Header.tsx @@ -1,10 +1,18 @@ import { FC } from "react"; +import { Github } from "@styled-icons/bootstrap"; import { EllipsisVertical } from "@styled-icons/fa-solid"; import { StatefulPopover } from "baseui/popover"; import { StatefulMenu } from "baseui/menu"; import { Breadcrumbs } from "baseui/breadcrumbs"; -import styles, { Link, Container, RunButton, PopoverButton } from "./styles"; +import styles, { + Link, + Container, + RunButton, + PopoverButton, + GithubLink, +} from "./styles"; import { Spinner } from "baseui/spinner"; +import { Project, Repository } from "../../Hooks/GraphQL"; export type HeaderProps = { id: string; @@ -13,40 +21,82 @@ export type HeaderProps = { breadcrumbs?: { title: string; link?: string }[]; showRunButton?: boolean; loading?: boolean; + linkedRepository?: Repository | null; + project?: Project | null; }; const Header: FC = (props) => { - const { id, breadcrumbs, onRun, menu, showRunButton } = props; + const { id, breadcrumbs, onRun, menu, showRunButton, linkedRepository } = + props; return ( - ({ - fontFamily: $theme.primaryFontFamily, - }), - }, +
+ +
+
- {breadcrumbs?.map(({ title, link }, index) => { - if (link) { - return ( - - {title} - - ); - } - return {title}; - })} - + ({ + fontFamily: $theme.primaryFontFamily, + }), + }, + }} + > + {breadcrumbs?.map(({ title, link }, index) => { + if (link) { + return ( + + {title} + + ); + } + return {title}; + })} + +

+ {props.project?.description} +

+
+ {linkedRepository && ( +
+ + + +
+ )} {!!menu?.length && ( = () => { const navigate = useNavigate(); const { pathname } = useLocation(); const { id } = useParams(); - const [project, setProject] = useState(null); + const [{ project }, setProjectState] = useRecoilState(ProjectState); // eslint-disable-next-line @typescript-eslint/no-explicit-any const [actions, setActions] = useState([]); const [run, setRun] = useState(null); @@ -45,7 +46,7 @@ const HeaderWithData: FC = () => { const [getActions] = useGetActionsLazyQuery(); const { data } = useGetActionsQuery({ variables: { - projectId: project?.id || "", + projectId: id!, }, fetchPolicy: "cache-and-network", }); @@ -55,6 +56,9 @@ const HeaderWithData: FC = () => { const [getLinkedRepository] = useGetLinkedRepositoryLazyQuery(); const [loading, setLoading] = useState(false); + const setProject = (value?: Project | null) => + setProjectState({ project: value }); + useEffect(() => { if (pathname.startsWith("/run")) { getRun().then(({ data }) => { @@ -86,16 +90,16 @@ const HeaderWithData: FC = () => { }, [pathname]); useEffect(() => { - if (!me || !project) { + if (!me || !id) { return; } getLinkedRepository({ variables: { - projectId: project.id, + projectId: pathname.startsWith("/run") ? project!.id : id, }, - fetchPolicy: "cache-and-network", + fetchPolicy: "network-only", }).then((res) => setLinkedRepository(res.data?.linkedRepository)); - }, [me, getLinkedRepository, project]); + }, [me, getLinkedRepository, id, project, pathname]); useEffect(() => { if (!data) { @@ -124,7 +128,7 @@ const HeaderWithData: FC = () => { link: "/", }, { - title: project?.name || "", + title: project?.displayName || project?.name || "", link: run && project?.id ? `/project/${project.id}` : undefined, }, ]; @@ -142,7 +146,7 @@ const HeaderWithData: FC = () => { setTimeout(() => { getActions({ variables: { - projectId: project.id, + projectId: pathname.startsWith("/run") ? project!.id : id!, }, fetchPolicy: "cache-and-network", }).then(({ data }) => { @@ -161,11 +165,14 @@ const HeaderWithData: FC = () => { showRunButton={ !!project && !pathname.startsWith("/link-project") && - (!!actions?.filter((x) => x.enabled).length || + ((project?.path !== "empty" && + !!actions?.filter((x) => x.enabled).length) || (project?.path !== "empty" && !linkedRepository) || (!!linkedRepository && !!actions?.filter((x) => x.enabled).length)) } loading={loading} + linkedRepository={linkedRepository} + project={project} /> ); }; diff --git a/webui/src/Components/Header/__snapshots__/Header.test.tsx.snap b/webui/src/Components/Header/__snapshots__/Header.test.tsx.snap index 66a9aba..a83a27b 100644 --- a/webui/src/Components/Header/__snapshots__/Header.test.tsx.snap +++ b/webui/src/Components/Header/__snapshots__/Header.test.tsx.snap @@ -3,60 +3,74 @@ exports[`Header > should render the component 1`] = `
-
+
+
+ +
  • - frosty-hamilton - -
  • - - + + frosty-hamilton + + + + +

    +

    `; diff --git a/webui/src/Components/Header/styles.tsx b/webui/src/Components/Header/styles.tsx index d58e219..0e79c07 100644 --- a/webui/src/Components/Header/styles.tsx +++ b/webui/src/Components/Header/styles.tsx @@ -19,8 +19,8 @@ export const Container = styled.div` display: flex; flex-direction: row; justify-content: space-between; - margin-bottom: 20px; height: 40px; + margin-bottom: 20px; `; export const RunButton = styled.button` @@ -50,6 +50,13 @@ export const PopoverButton = styled.button` margin-right: 10px; `; +export const GithubLink = styled.a` + color: #fff; + &:hover { + color: #24ffb5; + } +`; + export default { Tab: { Tab: { diff --git a/webui/src/Containers/Home/MainContent/MainContent.tsx b/webui/src/Containers/Home/MainContent/MainContent.tsx index 7960b9b..9ea976a 100644 --- a/webui/src/Containers/Home/MainContent/MainContent.tsx +++ b/webui/src/Containers/Home/MainContent/MainContent.tsx @@ -32,15 +32,35 @@ const MainContent: FC = (props) => {
    -
    {item.name}
    - {item.path !== "empty" ? item.path : ""} +
    {item.displayName || item.name}
    + {item.path !== "empty" && !!item.path && ( + {item.path} + )} +
    + {item.tags?.map((tag) => ( + + {tag} + + ))} +
    {_.get(item, "recentRuns.0.status") && ( should render the component 1`] = `
    should render the component 1`] = ` stoic-leavitt
    /home/tsirysndr/Documents/github/base-pipeline/example
    +
    should render the component 1`] = `
    should render the component 1`] = ` agitated-williams
    /home/tsirysndr/Documents/github/bun-pipeline/example
    +
    should render the component 1`] = `
    should render the component 1`] = ` flamboyant-visvesvaraya
    /home/tsirysndr/Documents/github/go-pipeline/example
    +
    should render the component 1`] = `
    should render the component 1`] = ` admiring-meninsky
    /home/tsirysndr/Documents/github/gleam-pipeline/example
    +
    void; @@ -48,6 +50,17 @@ const MainContent: FC = ({ onTabChange }) => { > + + + Settings + + } + overrides={styles.Tab} + > + + ); diff --git a/webui/src/Containers/Project/MainContent/Settings/Settings.tsx b/webui/src/Containers/Project/MainContent/Settings/Settings.tsx new file mode 100644 index 0000000..5421543 --- /dev/null +++ b/webui/src/Containers/Project/MainContent/Settings/Settings.tsx @@ -0,0 +1,105 @@ +import { BaseSyntheticEvent, FC } from "react"; +import styles, { + Title, + Text, + Label, + Section, + Cluster, + ClusterStart, + SaveButton, +} from "./styles"; +import { Input } from "baseui/input"; +import { Controller, useFormContext } from "react-hook-form"; +import { Account } from "../../../../Hooks/GraphQL"; +import { Spinner } from "baseui/spinner"; + +export type SettingsProps = { + loading: boolean; + me?: Account | null; + handleSubmit: (e: BaseSyntheticEvent) => void; +}; + +const Settings: FC = ({ handleSubmit, me, loading }) => { + const { control, watch } = useFormContext(); + const name = watch("name"); + return ( + <> +
    + General + + Here you can change the name and description of your project + (pipeline), or even decide to share it with the rest of the world. + +
    + {!!me && ( +
    + + + FL-10 +
    + 6 vCPU · 16GB memory +
    +
    +
    + )} +
    + + ( + + )} + /> +
    +
    + + } + /> +
    +
    + + } + /> + + Short words to categorize this pipeline. Separate multiple tags with a + comma + +
    + {!loading && Save} + {loading && ( + + + + )} + + ); +}; + +export default Settings; diff --git a/webui/src/Containers/Project/MainContent/Settings/SettingsWithData.tsx b/webui/src/Containers/Project/MainContent/Settings/SettingsWithData.tsx new file mode 100644 index 0000000..b02da1f --- /dev/null +++ b/webui/src/Containers/Project/MainContent/Settings/SettingsWithData.tsx @@ -0,0 +1,56 @@ +import { FC, useState } from "react"; +import { FormProvider, useForm } from "react-hook-form"; +import Settings from "./Settings"; +import { schema } from "./schema"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useRecoilState, useRecoilValue } from "recoil"; +import { ProjectState } from "../../ProjectState"; +import { AuthState } from "../../../Auth/AuthState"; +import { useUpdateProjectMutation } from "../../../../Hooks/GraphQL"; +import _ from "lodash"; + +const SettingsWithData: FC = () => { + const [updateProject] = useUpdateProjectMutation(); + const [loading, setLoading] = useState(false); + const me = useRecoilValue(AuthState); + const [{ project }, setProject] = useRecoilState(ProjectState); + const methods = useForm({ + mode: "onChange", + resolver: zodResolver(schema), + defaultValues: { + name: project?.displayName || project?.name, + description: project?.description, + tags: _.get(project, "tags", [])?.join(", "), + }, + }); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const onSubmit = (data: any) => { + setLoading(true); + updateProject({ + variables: { + id: project!.id, + name: data.name, + description: data.description, + tags: data.tags, + }, + }) + .then(({ data }) => { + setProject({ project: data?.updateProject }); + setLoading(false); + }) + .catch(() => setLoading(false)); + }; + + return ( + + + + ); +}; + +export default SettingsWithData; diff --git a/webui/src/Containers/Project/MainContent/Settings/index.tsx b/webui/src/Containers/Project/MainContent/Settings/index.tsx new file mode 100644 index 0000000..5819556 --- /dev/null +++ b/webui/src/Containers/Project/MainContent/Settings/index.tsx @@ -0,0 +1,3 @@ +import Settings from "./SettingsWithData"; + +export default Settings; diff --git a/webui/src/Containers/Project/MainContent/Settings/schema.tsx b/webui/src/Containers/Project/MainContent/Settings/schema.tsx new file mode 100644 index 0000000..0e13f98 --- /dev/null +++ b/webui/src/Containers/Project/MainContent/Settings/schema.tsx @@ -0,0 +1,7 @@ +import { z } from "zod"; + +export const schema = z.object({ + name: z.string().min(1, { message: "Please enter a name" }), + description: z.string().optional().nullable(), + tags: z.string().optional().nullable(), +}); diff --git a/webui/src/Containers/Project/MainContent/Settings/styles.tsx b/webui/src/Containers/Project/MainContent/Settings/styles.tsx new file mode 100644 index 0000000..0dbc2e0 --- /dev/null +++ b/webui/src/Containers/Project/MainContent/Settings/styles.tsx @@ -0,0 +1,68 @@ +import styled from "@emotion/styled"; + +export const Title = styled.div` + font-size: 18px; + margin-bottom: 4px; +`; + +export const Text = styled.p` + font-size: 14px; + margin: 0px; + color: #ffffffb2; +`; + +export const Label = styled.div` + font-size: 14px; + font-weight: 600; + margin-bottom: 8px; +`; + +export const Section = styled.div` + margin-bottom: 32px; +`; + +export const ClusterStart = styled.div` + color: #f701ad; + border-right: 1px solid #f701ad; + padding: 6px; + background-color: #f701ad28; +`; + +export const Cluster = styled.div` + font-size: 13px; + border: 1px solid #f701ad; + width: 230px; + border-radius: 6px; + display: flex; + align-items: center; +`; + +export const SaveButton = styled.button` + display: flex; + justify-content: center; + align-items: center; + height: 40px; + background-color: #24ffb5; + color: #000; + border: none; + font-weight: 600; + width: 150px; + cursor: pointer; + font-family: Lexend; + &:hover { + opacity: 0.8; + } +`; + +export default { + Input: { + Root: { + style: { border: "1px solid #ffffff28" }, + }, + Input: { + style: { + fontFamily: "Lexend", + }, + }, + }, +}; diff --git a/webui/src/Containers/Project/ProjectState.tsx b/webui/src/Containers/Project/ProjectState.tsx new file mode 100644 index 0000000..512d68a --- /dev/null +++ b/webui/src/Containers/Project/ProjectState.tsx @@ -0,0 +1,11 @@ +import { atom } from "recoil"; +import { Project } from "../../Hooks/GraphQL"; + +export const ProjectState = atom<{ + project?: Project | null; +}>({ + key: "project-state", + default: { + project: null, + }, +}); diff --git a/webui/src/GraphQL/Fragment.tsx b/webui/src/GraphQL/Fragment.tsx index d2fdaed..6c20bce 100644 --- a/webui/src/GraphQL/Fragment.tsx +++ b/webui/src/GraphQL/Fragment.tsx @@ -28,6 +28,9 @@ export const ProjectFragment = gql` fragment ProjectFragment on Project { id name + displayName + description + tags path createdAt picture diff --git a/webui/src/GraphQL/Project/Mutation.tsx b/webui/src/GraphQL/Project/Mutation.tsx index ad1df79..bc197d4 100644 --- a/webui/src/GraphQL/Project/Mutation.tsx +++ b/webui/src/GraphQL/Project/Mutation.tsx @@ -9,3 +9,22 @@ export const CREATE_PROJECT = gql` } ${ProjectFragment} `; + +export const UPDATE_PROJECT = gql` + mutation UpdateProject( + $id: ID! + $name: String + $description: String + $tags: String + ) { + updateProject( + id: $id + name: $name + description: $description + tags: $tags + ) { + ...ProjectFragment + } + } + ${ProjectFragment} +`; diff --git a/webui/src/Hooks/GraphQL.tsx b/webui/src/Hooks/GraphQL.tsx index bdebf71..c70d9df 100644 --- a/webui/src/Hooks/GraphQL.tsx +++ b/webui/src/Hooks/GraphQL.tsx @@ -86,6 +86,7 @@ export type Mutation = { runPipeline?: Maybe; saveActions?: Maybe>; unlinkRepository?: Maybe; + updateProject?: Maybe; }; @@ -132,6 +133,14 @@ export type MutationUnlinkRepositoryArgs = { repoName: Scalars['String']; }; + +export type MutationUpdateProjectArgs = { + description?: InputMaybe; + id: Scalars['ID']; + name?: InputMaybe; + tags?: InputMaybe; +}; + export type Organization = { __typename?: 'Organization'; createdAt: Scalars['String']; @@ -168,6 +177,8 @@ export type Project = { buildsPerWeek?: Maybe; createdAt: Scalars['String']; cursor?: Maybe; + description?: Maybe; + displayName?: Maybe; id: Scalars['ID']; logs?: Maybe; name: Scalars['String']; @@ -176,6 +187,7 @@ export type Project = { recentRuns?: Maybe>; reliability?: Maybe; speed?: Maybe; + tags?: Maybe>; }; export type Query = { @@ -385,7 +397,7 @@ export type ExportActionsQuery = { __typename?: 'Query', exportActions: string } export type RunFragmentFragment = { __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }; -export type ProjectFragmentFragment = { __typename?: 'Project', id: string, name: string, path?: string | null, createdAt: string, picture: string, speed?: number | null, reliability?: number | null, buildsPerWeek?: number | null, recentRuns?: Array<{ __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }> | null }; +export type ProjectFragmentFragment = { __typename?: 'Project', id: string, name: string, displayName?: string | null, description?: string | null, tags?: Array | null, path?: string | null, createdAt: string, picture: string, speed?: number | null, reliability?: number | null, buildsPerWeek?: number | null, recentRuns?: Array<{ __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }> | null }; export type LogFragmentFragment = { __typename?: 'Log', id: string, message: string, createdAt: string }; @@ -444,7 +456,17 @@ export type GetOrganizationsQuery = { __typename?: 'Query', organizations: Array export type CreateProjectMutationVariables = Exact<{ [key: string]: never; }>; -export type CreateProjectMutation = { __typename?: 'Mutation', createProject: { __typename?: 'Project', id: string, name: string, path?: string | null, createdAt: string, picture: string, speed?: number | null, reliability?: number | null, buildsPerWeek?: number | null, recentRuns?: Array<{ __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }> | null } }; +export type CreateProjectMutation = { __typename?: 'Mutation', createProject: { __typename?: 'Project', id: string, name: string, displayName?: string | null, description?: string | null, tags?: Array | null, path?: string | null, createdAt: string, picture: string, speed?: number | null, reliability?: number | null, buildsPerWeek?: number | null, recentRuns?: Array<{ __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }> | null } }; + +export type UpdateProjectMutationVariables = Exact<{ + id: Scalars['ID']; + name?: InputMaybe; + description?: InputMaybe; + tags?: InputMaybe; +}>; + + +export type UpdateProjectMutation = { __typename?: 'Mutation', updateProject?: { __typename?: 'Project', id: string, name: string, displayName?: string | null, description?: string | null, tags?: Array | null, path?: string | null, createdAt: string, picture: string, speed?: number | null, reliability?: number | null, buildsPerWeek?: number | null, recentRuns?: Array<{ __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }> | null } | null }; export type GetProjectsQueryVariables = Exact<{ cursor?: InputMaybe; @@ -454,14 +476,14 @@ export type GetProjectsQueryVariables = Exact<{ }>; -export type GetProjectsQuery = { __typename?: 'Query', projects: Array<{ __typename?: 'Project', id: string, name: string, path?: string | null, createdAt: string, picture: string, speed?: number | null, reliability?: number | null, buildsPerWeek?: number | null, recentRuns?: Array<{ __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }> | null }> }; +export type GetProjectsQuery = { __typename?: 'Query', projects: Array<{ __typename?: 'Project', id: string, name: string, displayName?: string | null, description?: string | null, tags?: Array | null, path?: string | null, createdAt: string, picture: string, speed?: number | null, reliability?: number | null, buildsPerWeek?: number | null, recentRuns?: Array<{ __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }> | null }> }; export type GetProjectQueryVariables = Exact<{ id: Scalars['ID']; }>; -export type GetProjectQuery = { __typename?: 'Query', project?: { __typename?: 'Project', id: string, name: string, path?: string | null, createdAt: string, picture: string, speed?: number | null, reliability?: number | null, buildsPerWeek?: number | null, recentRuns?: Array<{ __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }> | null } | null }; +export type GetProjectQuery = { __typename?: 'Query', project?: { __typename?: 'Project', id: string, name: string, displayName?: string | null, description?: string | null, tags?: Array | null, path?: string | null, createdAt: string, picture: string, speed?: number | null, reliability?: number | null, buildsPerWeek?: number | null, recentRuns?: Array<{ __typename?: 'Run', id: string, branch?: string | null, commit?: string | null, date: string, project: string, projectId: string, duration?: number | null, message?: string | null, name: string, title: string, cursor?: string | null, status?: string | null, jobs: Array<{ __typename?: 'Job', id: string, name: string, createdAt: string, status: string, duration?: number | null }> }> | null } | null }; export type CountProjectsQueryVariables = Exact<{ [key: string]: never; }>; @@ -556,6 +578,9 @@ export const ProjectFragmentFragmentDoc = gql` fragment ProjectFragment on Project { id name + displayName + description + tags path createdAt picture @@ -1113,6 +1138,42 @@ export function useCreateProjectMutation(baseOptions?: Apollo.MutationHookOption export type CreateProjectMutationHookResult = ReturnType; export type CreateProjectMutationResult = Apollo.MutationResult; export type CreateProjectMutationOptions = Apollo.BaseMutationOptions; +export const UpdateProjectDocument = gql` + mutation UpdateProject($id: ID!, $name: String, $description: String, $tags: String) { + updateProject(id: $id, name: $name, description: $description, tags: $tags) { + ...ProjectFragment + } +} + ${ProjectFragmentFragmentDoc}`; +export type UpdateProjectMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateProjectMutation__ + * + * To run a mutation, you first call `useUpdateProjectMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateProjectMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateProjectMutation, { data, loading, error }] = useUpdateProjectMutation({ + * variables: { + * id: // value for 'id' + * name: // value for 'name' + * description: // value for 'description' + * tags: // value for 'tags' + * }, + * }); + */ +export function useUpdateProjectMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateProjectDocument, options); + } +export type UpdateProjectMutationHookResult = ReturnType; +export type UpdateProjectMutationResult = Apollo.MutationResult; +export type UpdateProjectMutationOptions = Apollo.BaseMutationOptions; export const GetProjectsDocument = gql` query GetProjects($cursor: String, $limit: Int, $skip: Int, $reverse: Boolean) { projects(cursor: $cursor, limit: $limit, skip: $skip, reverse: $reverse) {