From 4ef05163d7a43e0f6fb4f92dd36d604e6f75c8d2 Mon Sep 17 00:00:00 2001 From: caishi <1149225589@qq.com> Date: Mon, 11 Jan 2021 17:18:12 +0800 Subject: [PATCH] about page --- src/forge/Component/layout.jsx | 2 +- src/forge/DevOps/Dispose.jsx | 154 ++++++++--------------- src/forge/DevOps/Dispose/Choosen.jsx | 27 ++++ src/forge/DevOps/Dispose/Editors.jsx | 17 +++ src/forge/DevOps/Dispose/Init.jsx | 39 ++++++ src/forge/DevOps/Dispose/List.jsx | 14 ++- src/forge/DevOps/Dispose/Sure.jsx | 25 ++++ src/forge/DevOps/Dispose/head.jsx | 15 +++ src/forge/DevOps/Dispose/menus.jsx | 36 ++++++ src/forge/DevOps/Dispose/menusAdd.jsx | 22 ++++ src/forge/DevOps/Dispose/menusRename.jsx | 35 ++++++ src/forge/DevOps/Index.jsx | 44 +++++-- src/forge/DevOps/Infos.jsx | 10 +- src/forge/DevOps/Structure.jsx | 84 +++++++------ src/forge/DevOps/disposePipeline.jsx | 44 +++++++ src/forge/DevOps/ops.scss | 140 +++++++++++++++++++++ src/forge/Main/Detail.js | 2 +- 17 files changed, 542 insertions(+), 168 deletions(-) create mode 100644 src/forge/DevOps/Dispose/Choosen.jsx create mode 100644 src/forge/DevOps/Dispose/Editors.jsx create mode 100644 src/forge/DevOps/Dispose/Init.jsx create mode 100644 src/forge/DevOps/Dispose/Sure.jsx create mode 100644 src/forge/DevOps/Dispose/head.jsx create mode 100644 src/forge/DevOps/Dispose/menus.jsx create mode 100644 src/forge/DevOps/Dispose/menusAdd.jsx create mode 100644 src/forge/DevOps/Dispose/menusRename.jsx create mode 100644 src/forge/DevOps/disposePipeline.jsx diff --git a/src/forge/Component/layout.jsx b/src/forge/Component/layout.jsx index f59a8e34..50cdffad 100644 --- a/src/forge/Component/layout.jsx +++ b/src/forge/Component/layout.jsx @@ -94,7 +94,7 @@ export const Blueback = styled.a`{ line-height:30px; border-radius:2px; background-color:rgba(80,145,255,1); - color:#fff; + color:#fff!important; padding:0px 12px; display:inline-block; min-width:80px; diff --git a/src/forge/DevOps/Dispose.jsx b/src/forge/DevOps/Dispose.jsx index d171f606..f43e26f1 100644 --- a/src/forge/DevOps/Dispose.jsx +++ b/src/forge/DevOps/Dispose.jsx @@ -1,130 +1,74 @@ import React , { useState , useEffect } from 'react'; -import { Spin } from 'antd'; -import { Blueback } from '../Component/layout'; -import Editor from "react-monaco-editor"; -import Modals from './DisposeModal'; -import FileLanguage from '../Component/OpsFileLanguage'; +import { Spin , Pagination } from 'antd'; +import { Blueback , Banner } from '../Component/layout'; import List from './Dispose/List'; +import Head from './Dispose/head'; import axios from 'axios'; -function Dispose(props){ - const [ spining , setSpining ] = useState(true); - const [ info , setInfo ] = useState('.trustie-pipeline.yml'); - const [ visible , setVisible ] = useState(false); - const [ ymlValue , setYmlValue ] = useState(""); - const [ sha , setSha ] = useState(undefined); - const [ fileLanguage , setFileLanguage ] = useState(undefined); - const [ first , setFirst ] = useState(false); +import styled from 'styled-components'; +const Div = styled.div`{ + padding:24px 30px; +}`; +const LIMIT = 15; + +function Dispose(props){ + const [ spining , setSpining ] = useState(false); const [ list , setList ] = useState(undefined); + const [ page , setPage ] = useState(1); + const [ total , setTotal ] = useState(0); + const [ permission , setPermission ] = useState(""); + + + const projectDetail = props.projectDetail; + let projectsId = props.match.params.projectsId; + let owner = props.match.params.owner; + + // 获取用户的身份角色 + useEffect(()=>{ + if(projectDetail){ + setPermission(props.projectDetail.permission); + } + },[projectDetail]) useEffect(()=>{ let l = [ - {name:"流水线名字",fileName:"filename.jpg",time:"2021-01-06",status:"运行中"} + {name:"流水线名字",fileName:"filename.jpg",time:"2021-01-06",status:"运行中"}, + {name:"流水线名字11",fileName:"filename111.jpg",time:"2021-01-06",status:"运行中"} ] setList(l); },[]) - let projectsId = props.match.params.projectsId; - let owner = props.match.params.owner; - useEffect(()=>{ - if(projectsId){ - const url = `/${owner}/${projectsId}/get_trustie_pipeline.json`; - axios.get(url,{ - params:{ - project_id:projectsId - } - }).then(result=>{ - if(result && result.data.content){ - setInfo(result.data.name); - setYmlValue(result.data.content); - setFirst(true); - setSha(result.data.sha); - }else{ - setFirst(false); - } - setSpining(false); - }).catch(error=>{ - console.log(error); - }) - } - },[projectsId]) - // 修改文件内容 - function changeEditor(value){ - setYmlValue(value); + // 分页-切换页面 + function changePage(page){ + setPage(page); } - // 切换语言 - function select_language(value,array){ - setFileLanguage(value); - setYmlValue( array && array.content); + // 新增流水线 + function addNew(){ + props.history.push(`/projects/${owner}/${projectsId}/devops/dispose/new`); } - - // 确定提交 - function submit(){ - let url = ''; - const { defaultBranch } = props; - let params = { - branch: defaultBranch, - content:ymlValue, - filepath:info, - message:'' - } - if(first){ - // 为true,则是编辑否则是新建 - url = `/${owner}/${projectsId}/update_trustie_pipeline.json`; - axios.put(url,{ - ...params, - sha - }).then(result=>{ - if(result){ - setVisible(true); - } - }).catch(error=>{ - console.log(error); - }) - }else{ - url = `/${owner}/${projectsId}/create_file.json`; - axios.post(url,params).then(result=>{ - if(result){ - setVisible(true); - } - }).catch(error=>{ - console.log(error); - }) - } - } - function suresubmit(){ - setVisible(false); - props.history.push(`/projects/${owner}/${projectsId}/devops/list`); - } - return( - setVisible(flag)} sureFunc={suresubmit}> -

编程语言:

- -
- +
+ +
+ { permission !=="Reporter" && 新增流水线 } +
+ + { + total > LIMIT ? +
+ +
+ :"" + } +
+
-

配置脚本:

-
-

{info}

- -
- 确定提交 - ) } diff --git a/src/forge/DevOps/Dispose/Choosen.jsx b/src/forge/DevOps/Dispose/Choosen.jsx new file mode 100644 index 00000000..4e5c5e7d --- /dev/null +++ b/src/forge/DevOps/Dispose/Choosen.jsx @@ -0,0 +1,27 @@ +import React , { useEffect , useState } from 'react'; + +function Choosen({name,options,chooseFunc}){ + const [ index, setIndex ] = useState(undefined); + + // 选择选项 + function chooseOption(id,k){ + chooseFunc && chooseFunc(id); + setIndex(k); + } + + return( +
+ {name} +
    + { + options && options.map((item,key)=>{ + return( +
  • chooseOption(item.id,key+1)}>{item.name}
  • + ) + }) + } +
+
+ ) +} +export default Choosen; \ No newline at end of file diff --git a/src/forge/DevOps/Dispose/Editors.jsx b/src/forge/DevOps/Dispose/Editors.jsx new file mode 100644 index 00000000..8b8a2bbf --- /dev/null +++ b/src/forge/DevOps/Dispose/Editors.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +import Editor from 'react-monaco-editor'; + +function Editors({value,onChange,theme,height}){ + return( + onChange(value)} + > + ) +} +export default Editors; \ No newline at end of file diff --git a/src/forge/DevOps/Dispose/Init.jsx b/src/forge/DevOps/Dispose/Init.jsx new file mode 100644 index 00000000..a4ab5d10 --- /dev/null +++ b/src/forge/DevOps/Dispose/Init.jsx @@ -0,0 +1,39 @@ +import React , { useEffect , useState } from 'react'; +import { Input , Button } from 'antd'; +import Choosen from './Choosen'; +import Editors from './Editors'; + +function Init(){ + const [ name , setName ] = useState(undefined); + const [ modelsId , setModelsId ] = useState(undefined); + const [ models , setModels ] = useState(undefined); + const [ ymlValue , setYmlValue ] = useState(undefined); + + useEffect(()=>{ + let list = [ + {id:1,name:"docker/arm64/linux"}, + {id:2,name:"docker/x86/linux"} + ] + setModels(list); + },[]) + + function chooseFunc(id){ + setModelsId(id); + } + return( +
+
+ 流水线名称: + setName(e.target.value)} placeholder="请输入名称" style={{width:"340px",margin:"6px 0px"}}/> +
+ +
+ +
+
+ +
+
+ ) +} +export default Init; \ No newline at end of file diff --git a/src/forge/DevOps/Dispose/List.jsx b/src/forge/DevOps/Dispose/List.jsx index 7710f306..8b2c7cde 100644 --- a/src/forge/DevOps/Dispose/List.jsx +++ b/src/forge/DevOps/Dispose/List.jsx @@ -1,7 +1,8 @@ import React from 'react'; import { Table } from 'antd'; +import { Link } from 'react-router-dom'; -function List({list}){ +function List({ list, permission , projectsId , owner }){ const columns = [ { @@ -16,6 +17,7 @@ function List({list}){ dataIndex:"fileName", key:1, width:"17%", + className:"color-blue", ellipsis:true }, { @@ -40,17 +42,17 @@ function List({list}){ render:(txt,item)=>{ return( - 编辑 - 删除 - 运行 - 查看运行记录 + { permission !=="Reporter" && 编辑 } + { permission !=="Reporter" && 删除 } + { permission !=="Reporter" && 运行 } + 查看运行记录 ) } } ] return( - row.id}>
+ row.id} pagination={false}>
) } export default List; \ No newline at end of file diff --git a/src/forge/DevOps/Dispose/Sure.jsx b/src/forge/DevOps/Dispose/Sure.jsx new file mode 100644 index 00000000..1aa5fb18 --- /dev/null +++ b/src/forge/DevOps/Dispose/Sure.jsx @@ -0,0 +1,25 @@ +import React , { useEffect , useState } from 'react'; +import { Button } from 'antd'; +import Editors from './Editors'; +import { Cancel } from '../../Component/layout'; + +function Sure(){ + const [ ymlValue , setYmlValue ] = useState(undefined); + + return( +
+
+ 工作流名称:流水线名称 +
+
+ +
+
+ + + 取消 +
+
+ ) +} +export default Sure; \ No newline at end of file diff --git a/src/forge/DevOps/Dispose/head.jsx b/src/forge/DevOps/Dispose/head.jsx new file mode 100644 index 00000000..cd741fd1 --- /dev/null +++ b/src/forge/DevOps/Dispose/head.jsx @@ -0,0 +1,15 @@ +import React , { useEffect , useState } from 'react'; +import { AlignCenterBetween } from '../../Component/layout'; +import { Link } from 'react-router-dom'; + + + +function head(){ + return( + + 工作流配置 + 模板使用说明 + + ) +} +export default head; \ No newline at end of file diff --git a/src/forge/DevOps/Dispose/menus.jsx b/src/forge/DevOps/Dispose/menus.jsx new file mode 100644 index 00000000..fa312611 --- /dev/null +++ b/src/forge/DevOps/Dispose/menus.jsx @@ -0,0 +1,36 @@ +import React , { useEffect , useState } from 'react'; +import MenusRename from './menusRename'; +import MenusAdd from './menusAdd'; + + +function Menus({step,changeStep,menuList}){ + + function InitActive(key){ + changeStep(key) + } + + function getName(name){ + console.log(name); + } + + return( +
    + { + menuList && menuList.length > 0 && menuList.map((item,key)=>{ + return( + +
  • InitActive(key+1)} className={key+1 === step ?"active":""}> + + +
  • + { key !== (menuList.length-1) && menuList.length <= 10 ? + :"" + } +
    + ) + }) + } +
+ ) +} +export default Menus; \ No newline at end of file diff --git a/src/forge/DevOps/Dispose/menusAdd.jsx b/src/forge/DevOps/Dispose/menusAdd.jsx new file mode 100644 index 00000000..d775f95c --- /dev/null +++ b/src/forge/DevOps/Dispose/menusAdd.jsx @@ -0,0 +1,22 @@ +import React , { useState , useEffect } from 'react'; +import { Input } from 'antd'; + +function menusAdd ({ getName }){ + const [ show, setShow ] = useState(false); + const [ value , setValue ] = useState(undefined); + + function blurInput(){ + if(value){ + getName(value); + } + setShow(false); + } + + return( +
  • + { !show && setShow(true)}> } + { show && setValue(e.target.value)} onBlur={blurInput} /> } +
  • + ) +} +export default menusAdd; \ No newline at end of file diff --git a/src/forge/DevOps/Dispose/menusRename.jsx b/src/forge/DevOps/Dispose/menusRename.jsx new file mode 100644 index 00000000..de83f39a --- /dev/null +++ b/src/forge/DevOps/Dispose/menusRename.jsx @@ -0,0 +1,35 @@ +import React , { useEffect , useState } from 'react'; +import { Input } from 'antd'; + + +function menusRename({ name , edit }){ + const [ n , setN ] = useState(undefined); + const [ show , setShow ] = useState(false); + + useEffect(()=>{ + if(name){ + setN(name) + } + },[name]) + + function changeShow(e){ + e.stopPropagation(); + setShow(true); + } + + function blurInput(){ + setShow(false); + } + return( +
    + + { !show && n } + { show && + e.stopPropagation()} onBlur={blurInput} style={{width:"75px"}} onChange={(e)=>setN(e.target.value)}/> + } + + { !show && edit && } +
    + ) +} +export default menusRename \ No newline at end of file diff --git a/src/forge/DevOps/Index.jsx b/src/forge/DevOps/Index.jsx index 23e36d69..026daa3b 100644 --- a/src/forge/DevOps/Index.jsx +++ b/src/forge/DevOps/Index.jsx @@ -10,8 +10,16 @@ const About = Loadable({ loader: () => import('./About'), loading: Loading, }) -const Infos = Loadable({ - loader: () => import('./Infos'), +const New = Loadable({ + loader: () => import('./disposePipeline'), + loading: Loading, +}) +const Dispose = Loadable({ + loader: () => import('./Dispose'), + loading: Loading, +}) +const Stucture = Loadable({ + loader: () => import('./Structure'), loading: Loading, }) export default ((props)=>{ @@ -19,27 +27,37 @@ export default ((props)=>{ const open_devops = props.projectDetail && props.projectDetail.open_devops; // 工作流:两种状态进入的链接不同 - useEffect(()=>{ - if(open_devops !== undefined){ - if(open_devops){ - props.history.replace(`/projects/${owner}/${projectsId}/devops/list`); - }else{ - props.history.replace(`/projects/${owner}/${projectsId}/devops`); - } - } - },[open_devops]) + // useEffect(()=>{ + // if(open_devops !== undefined){ + // if(open_devops){ + // props.history.replace(`/projects/${owner}/${projectsId}/devops/dispose`); + // }else{ + // props.history.replace(`/projects/${owner}/${projectsId}/devops`); + // } + // } + // },[open_devops]) return( + () + } + > + () + } + > () + () => () } > () + () => () } > { return(
    - { permission !=="Reporter" && 工作流配置} - 构建列表 - { menu===true && 刷新} + { permission !=="Reporter" && 工作流配置} + {/* 构建列表 */} + {/* { menu===true && 刷新} */}
    - { menu === true && childRef.current = form} ref={childRef}/> } - { menu === false && permission !=="Reporter" && } + {/* { menu === true && childRef.current = form} ref={childRef}/> } */} +
    ) diff --git a/src/forge/DevOps/Structure.jsx b/src/forge/DevOps/Structure.jsx index 87a2b6cc..cfdfce1b 100644 --- a/src/forge/DevOps/Structure.jsx +++ b/src/forge/DevOps/Structure.jsx @@ -1,10 +1,15 @@ import React, { useState, useEffect , useImperativeHandle ,forwardRef } from "react"; -import { FlexAJ, AlignCenter } from "../Component/layout"; +import { FlexAJ, AlignCenter , Banner } from "../Component/layout"; import { Table, Pagination, Popconfirm } from "antd"; import { truncateCommitId } from "../common/util"; import {getUrl} from 'educoder'; import axios from "axios"; +import styled from 'styled-components'; + +const Div = styled.div`{ + padding:24px 30px; +}`; const STATUS = [ { name: "所有"}, { name: "运行中", value: "running" }, @@ -278,42 +283,47 @@ function Structure(props,ref){ }, ]; return ( -
    - - {renderStatus()} - {/* 手动创建 */} - {/* - 分支 - - - - 标签 - */} - - { - return{ - onClick:(event)=>clickRows(event,record) - } - }} - columns={column} - className="normalTable" - dataSource={data} - pagination={false} - loading={tableLoading} - >
    - {total > LIMIT ? -
    - -
    - : - "" } +
    + 构建列表 +
    +
    + + {renderStatus()} + {/* 手动创建 */} + {/* + 分支 + + + + 标签 + */} + + { + return{ + onClick:(event)=>clickRows(event,record) + } + }} + columns={column} + className="normalTable" + dataSource={data} + pagination={false} + loading={tableLoading} + >
    + {total > LIMIT ? +
    + +
    + : + "" } +
    +
    ); }; diff --git a/src/forge/DevOps/disposePipeline.jsx b/src/forge/DevOps/disposePipeline.jsx new file mode 100644 index 00000000..450ca928 --- /dev/null +++ b/src/forge/DevOps/disposePipeline.jsx @@ -0,0 +1,44 @@ +import React , { useEffect , useState } from 'react'; +import { WhiteBack , Banner } from '../Component/layout'; +import Head from './Dispose/head'; +import Menus from './Dispose/menus'; +import Init from './Dispose/Init'; +import Sure from './Dispose/Sure'; + + +function disposePipeline(){ + const [ step , setStep ] = useState(1); + const [ menuList , setMenuList ] = useState(undefined); + + useEffect(()=>{ + let list = [ + {stage_name:"初始化",stage_type:"init",id:1,icon:"iconinitialize"}, + {stage_name:"编辑构建",stage_type:"",id:2,icon:"iconstructure"}, + {stage_name:"部署",stage_type:"",id:3,icon:"iconarrange"}, + {stage_name:"确认",stage_type:"confirm",id:4,icon:"iconsure"} + ]; + setMenuList(list); + },[]) + + function changeStep(s){ + setStep(s); + } + + return( +
    + + +
    + + { + step === 1 && + } + { + menuList && (step === menuList.length) && + } +
    +
    +
    + ) +} +export default disposePipeline; \ No newline at end of file diff --git a/src/forge/DevOps/ops.scss b/src/forge/DevOps/ops.scss index 7a98d240..f1e4bed7 100644 --- a/src/forge/DevOps/ops.scss +++ b/src/forge/DevOps/ops.scss @@ -313,4 +313,144 @@ text-align:center; line-height:22px; color:#666; +} + +.disposeList{ + min-height: 450px; + .ant-table-body{ + margin:0px!important; + .ant-table-thead{ + background-color: #fafafa; + } + } +} +.txtright{ + text-align: right; +} +.menus{ + display: flex; + box-shadow: 0px 0px 6px rgba(0,3,8,0.1); + padding:20px 0px 10px 0px; + justify-content: space-between; + margin-bottom: 20px; + & > li{ + display: flex; + flex-flow: column; + align-items:center; + justify-content: center; + text-align: center; + color: #787878; + font-size: 16px; + min-width: 110px; + position: relative; + cursor: pointer; + width: 0; + &>i{ + font-size: 30px!important; + height: 30px; + width: 30px; + line-height: 30px; + } + &:hover,&.active{ + & > i{ + color: #1890FF; + } + } + &.active::after{ + position: absolute; + left: 50%; + margin-left: -25px; + bottom:-10px; + width: 50px; + height: 2px; + background-color: #1890FF; + content: ""; + } + & > div{ + width: 100%; + } + .aboutEdit{ + position: relative; + .operateName{ + position: relative; + line-height: 20px; + } + & > i{ + position: absolute; + right:-22px; + top:50%; + margin-top: -16px; + display: none; + } + &:hover > i{ + display: block; + } + } + } + & > li.menuAdd{ + position: relative; + flex: 1; + &:hover{ + & > i{ + color: #787878; + } + } + & > i{ + font-size: 18px!important; + position: absolute; + z-index: 1; + top:0px; + } + & > input{ + position: absolute; + z-index: 1; + top:3px; + } + &::before{ + position: absolute; + left: 0; + width: 100%; + border-bottom: 1px dashed #eee; + content: ""; + top:15px; + margin-top: -1px; + z-index: 0; + } + } +} + +.choosenList{ + display: flex; + flex-wrap: wrap; + line-height: 35px; + align-items: center; + & > span{ + display: block; + min-width: 75px; + text-align: right; + font-size: 14px; + color: #333; + height: 35px; + margin-right: 12px; + } + & > ul{ + display: flex; + flex-wrap: wrap; + li{ + padding:0px 12px; + height: 35px; + line-height: 35px; + border:1px solid #e1e4e8; + background-color: #fff; + margin:6px 0px; + margin-right: 12px; + border-radius: 5px; + cursor: pointer; + color: #333; + } + li.active{ + color: #fff; + background-color: #1890FF; + } + } } \ No newline at end of file diff --git a/src/forge/Main/Detail.js b/src/forge/Main/Detail.js index 116ef2c3..a0d74d60 100644 --- a/src/forge/Main/Detail.js +++ b/src/forge/Main/Detail.js @@ -516,7 +516,7 @@ class Detail extends Component { { platform &&
  • - + 工作流(beta版) {projectDetail && projectDetail.ops_count ? {projectDetail.ops_count} : ""}