diff --git a/package-lock.json b/package-lock.json index 2757784..8e5b394 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1313,6 +1313,35 @@ } } }, + "@fortawesome/fontawesome-common-types": { + "version": "0.2.34", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.34.tgz", + "integrity": "sha512-XcIn3iYbTEzGIxD0/dY5+4f019jIcEIWBiHc3KrmK/ROahwxmZ/s+tdj97p/5K0klz4zZUiMfUlYP0ajhSJjmA==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.34", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.34.tgz", + "integrity": "sha512-0KNN0nc5eIzaJxlv43QcDmTkDY1CqeN6J7OCGSs+fwGPdtv0yOQqRjieopBCmw+yd7uD3N2HeNL3Zm5isDleLg==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.34" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.2.tgz", + "integrity": "sha512-ZfCU+QjaFsdNZmOGmfqEWhzI3JOe37x5dF4kz9GeXvKn/sTxhqMtZ7mh3lBf76SvcYY5/GKFuyG7p1r4iWMQqw==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.34" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.14.tgz", + "integrity": "sha512-4wqNb0gRLVaBm/h+lGe8UfPPivcbuJ6ecI4hIgW0LjI7kzpYB9FkN0L9apbVzg+lsBdcTf0AlBtODjcSX5mmKA==", + "requires": { + "prop-types": "^15.7.2" + } + }, "@fullhuman/postcss-purgecss": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-3.1.3.tgz", diff --git a/package.json b/package.json index b5e0f9c..44e01cd 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,9 @@ ], "dependencies": { "@apollo/client": "^3.3.7", + "@fortawesome/fontawesome-svg-core": "^1.2.34", + "@fortawesome/free-solid-svg-icons": "^5.15.2", + "@fortawesome/react-fontawesome": "^0.1.14", "@tailwindcss/postcss7-compat": "^2.0.2", "autoprefixer": "^9.8.6", "formik": "^2.2.6", diff --git a/src/components/app.scss b/src/components/app.scss index d67c3c6..b23f61a 100644 --- a/src/components/app.scss +++ b/src/components/app.scss @@ -1,7 +1,13 @@ .projectPanel { - @apply w-1/6; } .app { - @apply flex bg-red-50; + @apply flex flex-row-reverse bg-red-50; + + aside { + @apply w-1/6 shadow; + } + main { + @apply flex-auto ml-px; + } } diff --git a/src/components/app.scss.d.ts b/src/components/app.scss.d.ts index a32d33d..ac73411 100644 --- a/src/components/app.scss.d.ts +++ b/src/components/app.scss.d.ts @@ -2,7 +2,6 @@ declare namespace AppScssNamespace { export interface IAppScss { app: string; - projectPanel: string; } } diff --git a/src/components/app.tsx b/src/components/app.tsx index cab5c69..552fc40 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -29,10 +29,10 @@ const Board = () => { return useObserver(() => { return ( +
{appStore.main}
-
{appStore.main}
); }); diff --git a/src/components/projects/project-details.scss b/src/components/projects/project-details.scss new file mode 100644 index 0000000..7c5ad16 --- /dev/null +++ b/src/components/projects/project-details.scss @@ -0,0 +1,20 @@ +.projectDetails { + header { + @apply bg-red-400 text-gray-50 p-2; + @apply grid grid-cols-2 grid-rows-2; + + h2 { + @apply text-white text-lg col-start-1 row-start-1 align-middle; + svg { + @apply text-xs ml-2; + } + } + small { + @apply text-sm col-start-1 row-start-2; + } + + .operations { + @apply col-start-2 row-span-2 justify-self-end self-center; + } + } +} diff --git a/src/components/projects/project-details.scss.d.ts b/src/components/projects/project-details.scss.d.ts new file mode 100644 index 0000000..9766a4c --- /dev/null +++ b/src/components/projects/project-details.scss.d.ts @@ -0,0 +1,11 @@ +// This file is automatically generated from your CSS. Any edits will be overwritten. +declare namespace ProjectDetailsScssNamespace { + export interface IProjectDetailsScss { + operations: string; + projectDetails: string; + } +} + +declare const ProjectDetailsScssModule: ProjectDetailsScssNamespace.IProjectDetailsScss; + +export = ProjectDetailsScssModule; diff --git a/src/components/projects/project-details.tsx b/src/components/projects/project-details.tsx new file mode 100644 index 0000000..4bf15a8 --- /dev/null +++ b/src/components/projects/project-details.tsx @@ -0,0 +1,39 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faEdit, faExternalLinkAlt } from '@fortawesome/free-solid-svg-icons'; +import { h } from 'preact'; +import { Project } from '../../generated/graphql'; +import styles from './project-details.scss'; +import { createOverlay } from '../commons/overlay/overlay'; +import { ProjectEditor } from './project-editor'; + +interface Props { + project: Project; +} + +export const ProjectDetails = ({ project }: Props) => { + const editProject = () => { + createOverlay({ + content: + }); + }; + return ( +
+
+

+ {project.name} + {project.webUrl ? ( + + + + ) : null} +

+ {project.comment} +
+ +
+
+
+ ); +}; diff --git a/src/components/projects/project-editor.tsx b/src/components/projects/project-editor.tsx index 0921433..206acf1 100644 --- a/src/components/projects/project-editor.tsx +++ b/src/components/projects/project-editor.tsx @@ -1,14 +1,16 @@ import { gql, useApolloClient, useMutation } from '@apollo/client'; import { Field, Form, Formik } from 'formik'; import { h } from 'preact'; -import { useState } from 'preact/compat'; -import { CreateProjectInput, Project } from '../../generated/graphql'; +import { + CreateProjectInput, + Project, + UpdateProjectInput +} from '../../generated/graphql'; import { useOverlay } from '../commons/overlay/overlay'; import styles from './project-editor.scss'; interface Props { - id?: string; - isCreate: boolean; + project?: Project; } const CREATE_PROJECT = gql` @@ -20,16 +22,28 @@ const CREATE_PROJECT = gql` sshUrl webUrl webHookSecret - deletedAt + } + } +`; +const MODIFY_PROJECT = gql` + mutation ModifyProject($id: String!, $project: UpdateProjectInput!) { + modifyProject(id: $id, project: $project) { + id + name + comment + sshUrl + webUrl + webHookSecret } } `; export const ProjectEditor = (props: Props) => { useApolloClient(); - const isCreate = props.id === undefined; + const isCreate = props.project === undefined; const [createProject] = useMutation(CREATE_PROJECT); + const [updateProject] = useMutation(MODIFY_PROJECT); const { close } = useOverlay(); const cancel = (ev: MouseEvent) => { @@ -37,18 +51,25 @@ export const ProjectEditor = (props: Props) => { close(); }; - const [project] = useState({ - name: '', - comment: '', - sshUrl: '', - webHookSecret: '' - }); - const submitForm = async (values: CreateProjectInput) => { + type FormValues = CreateProjectInput | UpdateProjectInput; + + const project: FormValues = { + name: props.project?.name ?? '', + comment: props.project?.comment ?? '', + sshUrl: props.project?.sshUrl ?? '', + webUrl: props.project?.webUrl ?? null, + webHookSecret: props.project?.webHookSecret ?? '' + }; + const submitForm = async (values: FormValues) => { try { - if (props.id === undefined) { + if (isCreate) { await createProject({ variables: { project: values } }); + } else { + await updateProject({ + variables: { project: values, id: props.project!.id } + }); } close(); } finally { @@ -76,6 +97,14 @@ export const ProjectEditor = (props: Props) => { placeholder="项目说明、简介" > +