diff --git a/src/components/pipelines/pipeline-list.constants.ts b/src/components/pipelines/pipeline-list.constants.ts
index 375b005..317ea3f 100644
--- a/src/components/pipelines/pipeline-list.constants.ts
+++ b/src/components/pipelines/pipeline-list.constants.ts
@@ -5,6 +5,8 @@ export const LIST_PIPELINES = gql`
pipelines: listPipelines(projectId: $projectId) {
id
name
+ branch
+ projectId
}
}
`;
diff --git a/src/components/pipelines/pipeline-list.scss b/src/components/pipelines/pipeline-list.scss
index 7374cbc..6a89403 100644
--- a/src/components/pipelines/pipeline-list.scss
+++ b/src/components/pipelines/pipeline-list.scss
@@ -1,22 +1,45 @@
.pipelineList {
- @apply bg-red-200;
+ @apply bg-red-200 w-40;
& > header {
@apply bg-white flex justify-between items-center;
-
-
}
}
+.list {
+ @apply bg-gray-100 overflow-y-auto max-h-full;
+}
.item {
- @apply bg-gray-50;
+ @apply bg-white text-gray-700;
+ @apply border-l-4 border-white transition-colors;
+ @apply px-2 py-1 my-px;
+ @apply relative;
+ small {
+ @apply text-sm text-gray-500;
+ svg {
+ @apply mr-1 h-3 text-gray-300;
+ }
+ }
+}
+.activeItem {
+ @apply border-red-500;
}
.addBtn {
@apply bg-red-400 text-white;
- @apply py-1 px-2 m-2 rounded-lg;
+ @apply py-1 px-2 m-1 rounded-lg mr-auto;
@apply hover:bg-red-500;
}
-.refetchBtn {
+.actionBtn {
@apply text-red-400 flex items-center;
- @apply w-4 h-4 m-2 rounded-full;
-}
\ No newline at end of file
+ @apply w-4 h-4 flex items-center justify-center overflow-hidden text-center m-1;
+ svg {
+ }
+}
+.editPanel {
+ @apply absolute right-1 top-0 bottom-0;
+ @apply flex flex-col items-center justify-evenly;
+ @apply text-red-400 text-xs;
+ button {
+ @apply w-3;
+ }
+}
diff --git a/src/components/pipelines/pipeline-list.scss.d.ts b/src/components/pipelines/pipeline-list.scss.d.ts
index b658987..1c7cba2 100644
--- a/src/components/pipelines/pipeline-list.scss.d.ts
+++ b/src/components/pipelines/pipeline-list.scss.d.ts
@@ -1,10 +1,13 @@
// This file is automatically generated from your CSS. Any edits will be overwritten.
declare namespace PipelineListScssNamespace {
export interface IPipelineListScss {
+ actionBtn: string;
+ activeItem: string;
addBtn: string;
+ editPanel: string;
item: string;
+ list: string;
pipelineList: string;
- refetchBtn: string;
}
}
diff --git a/src/components/pipelines/pipeline-list.tsx b/src/components/pipelines/pipeline-list.tsx
index f72703a..d1e9f51 100644
--- a/src/components/pipelines/pipeline-list.tsx
+++ b/src/components/pipelines/pipeline-list.tsx
@@ -1,16 +1,29 @@
-import { useQuery } from '@apollo/client';
+import { gql, useQuery, useMutation } from '@apollo/client';
import { makeAutoObservable } from 'mobx';
-import { useLocalObservable, useObserver } from 'mobx-react-lite';
-import { useMemo } from 'preact/hooks';
+import { useLocalObservable } from 'mobx-react-lite';
+import { useCallback, useMemo } from 'preact/hooks';
import { h } from 'preact';
import { Pipeline } from '../../generated/graphql';
import styles from './pipeline-list.scss';
import classNames from 'classnames';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faRedoAlt } from '@fortawesome/free-solid-svg-icons';
+import {
+ faCodeBranch,
+ faRedoAlt,
+ faEdit,
+ faEllipsisV,
+ faTrash
+} from '@fortawesome/free-solid-svg-icons';
import { createOverlay } from '../commons/overlay/overlay';
import { PipelineEditor } from '../../routes/pipelines/pipeline-editor';
import { LIST_PIPELINES } from './pipeline-list.constants';
+import { Observer, observer } from 'mobx-react';
+
+const DELETE_PIPELINE = gql`
+ mutation DeletePipeline($id: String!) {
+ deletePipeline(id: $id)
+ }
+`;
interface Props {
projectId: string;
@@ -19,36 +32,28 @@ interface Props {
class Store {
pipelines?: Pipeline[];
currPipelineId?: string;
+ editMode = false;
constructor() {
makeAutoObservable(this);
}
-
- get items() {
- return this.pipelines?.map(pipeline => {
- const isActive = this.currPipelineId === pipeline.id;
- return (
-
- {pipeline.name}
-
- );
- });
- }
+ refetching = false;
setPipelines(pipelines: any[] | undefined) {
this.pipelines = pipelines;
}
+ setRefetching(val: boolean) {
+ this.refetching = val;
+ }
+ setCurrPipelineId(id: string) {
+ this.currPipelineId = id;
+ }
+ toggleEditMode() {
+ this.editMode = !this.editMode;
+ }
}
export const PipelineList = ({ projectId }: Props) => {
- const { data, refetch } = useQuery<{ pipelines: Pipeline[] }>(
+ const { data, refetch, loading } = useQuery<{ pipelines: Pipeline[] }>(
LIST_PIPELINES,
{
variables: {
@@ -63,25 +68,123 @@ export const PipelineList = ({ projectId }: Props) => {
useMemo(() => store.setPipelines(pipelines), [store, pipelines]);
- const items = useObserver(() => store.items);
-
- const addPipeline = () => {
- createOverlay({
- content:
- });
- };
-
- return (
-
+ const Header = observer(() => {
+ const addPipeline = () => {
+ createOverlay({
+ content:
+ });
+ };
+ const onRefetchBtnClick = () => {
+ store.setRefetching(true);
+ refetch().finally(() => store.setRefetching(false));
+ };
+ return (
-
-
+ );
+ });
+ const items = pipelines?.map(pipeline => (
+
+ {(): any => }
+
+ ));
+
+ return (
+
);
};
+
+const Item = observer(
+ ({ pipeline, store }: { pipeline: Pipeline; store: Store }) => {
+ const [remove] = useMutation(DELETE_PIPELINE, {
+ variables: { id: pipeline.id },
+ update(cache) {
+ const cacheData = cache.readQuery<{ pipelines: Pipeline[] }>({
+ query: LIST_PIPELINES,
+ variables: { projectId: pipeline.projectId }
+ });
+ const pipelines = cacheData?.pipelines?.slice();
+ if (!pipelines) {
+ return;
+ }
+ const index = pipelines.findIndex(
+ (item: Pipeline) => item.id === pipeline.id
+ );
+ if (index === -1) {
+ return;
+ }
+ pipelines.splice(index, 1);
+ cache.writeQuery({
+ query: LIST_PIPELINES,
+ variables: { projectId: pipeline.projectId },
+ data: {
+ pipelines
+ }
+ });
+ }
+ });
+
+ const isActive = store.currPipelineId === pipeline.id;
+ const openModifyPanel = () => {
+ createOverlay({
+ content: (
+
+ )
+ });
+ };
+ const onRemoveBtnClick = () => {
+ remove();
+ };
+ const EditPanel = observer(() => {
+ return store.editMode ? (
+
+
+
+
+
+
+
+
+ ) : null;
+ });
+ return (
+ store.setCurrPipelineId(pipeline.id)}
+ >
+ {pipeline.name}
+
+
+ {pipeline.branch}
+
+ {(): any => }
+
+ );
+ }
+);
diff --git a/src/components/projects/project-panel.tsx b/src/components/projects/project-panel.tsx
index bc48153..abba436 100644
--- a/src/components/projects/project-panel.tsx
+++ b/src/components/projects/project-panel.tsx
@@ -27,7 +27,6 @@ const FIND_PROJECTS = gql`
sshUrl
webUrl
webHookSecret
- deletedAt
}
}
`;
diff --git a/src/routes/pipelines/pipeline-editor.tsx b/src/routes/pipelines/pipeline-editor.tsx
index d282103..95e19a5 100644
--- a/src/routes/pipelines/pipeline-editor.tsx
+++ b/src/routes/pipelines/pipeline-editor.tsx
@@ -1,17 +1,18 @@
-import { Field, Form, Formik } from 'formik';
+import { Field, Form, Formik, useFormik } from 'formik';
import { h } from 'preact';
import { RoutableProps } from 'preact-router';
import styles from './pipeline-editor.scss';
-import {
- CreatePipelineInput,
- Pipeline,
- UpdatePipelineInput
-} from '../../generated/graphql';
import { useOverlay } from '../../components/commons/overlay/overlay';
import { gql, useLazyQuery, useMutation } from '@apollo/client';
import { useMemo } from 'preact/hooks';
import classNames from 'classnames';
-import { WorkUnitMetadata, PipelineUnits } from '../../generated/graphql';
+import {
+ CreatePipelineInput,
+ UpdatePipelineInput,
+ WorkUnitMetadata,
+ PipelineUnits,
+ Pipeline
+} from '../../generated/graphql';
import { Message } from '../../components/commons/message/index';
import { LIST_PIPELINES } from '../../components/pipelines/pipeline-list.constants';
@@ -41,7 +42,7 @@ const FIND_PIPELINE = gql`
query FindPipeline($id: String!) {
pipeline: findPipeline(id: $id) {
name
- id
+ branch
projectId
workUnitMetadata {
version
@@ -98,18 +99,28 @@ export const PipelineEditor = ({ projectId, id }: Props) => {
};
const isCreate = !id;
- const [loadPipeline, { data: pipeline }] = useLazyQuery(FIND_PIPELINE);
+ const [loadPipeline, { data }] = useLazyQuery(FIND_PIPELINE, {
+ variables: { id }
+ });
useMemo(() => {
if (!isCreate) {
loadPipeline();
}
}, []);
- const formData: FormValues = pipeline ?? {
- name: 'test',
- projectId,
- workUnitMetadata: JSON.stringify(defaultWorkUnitMetadata, null, 2)
- };
+ const formData: FormValues = useMemo(() => {
+ if (data?.pipeline) {
+ const fd = JSON.parse(JSON.stringify(data.pipeline));
+ delete fd?.workUnitMetadata.__typename;
+ fd.workUnitMetadata.units.forEach((item: any) => {
+ delete item.__typename;
+ });
+ fd.workUnitMetadata = JSON.stringify(fd.workUnitMetadata, null, 2);
+ delete fd.__typename;
+ return fd;
+ }
+ return {};
+ }, [data, data?.pipeline]);
const [createPipeline] = useMutation<{ pipeline: Pipeline }>(
CREATE_PIPELINE,
@@ -167,10 +178,9 @@ export const PipelineEditor = ({ projectId, id }: Props) => {
//
}
};
-
return (