diff --git a/src/forge/DevOps/Dispose.jsx b/src/forge/DevOps/Dispose.jsx index 2d031de97..a4d573a68 100644 --- a/src/forge/DevOps/Dispose.jsx +++ b/src/forge/DevOps/Dispose.jsx @@ -1,6 +1,6 @@ import React , { useState , useEffect } from 'react'; -import { Spin , Pagination } from 'antd'; -import { Blueback , Banner } from '../Component/layout'; +import { Spin } from 'antd'; +import { Blueback } from '../Component/layout'; import List from './Dispose/List'; import Head from './Dispose/head'; import axios from 'axios'; @@ -11,13 +11,11 @@ import styled from 'styled-components'; const Div = styled.div`{ padding:24px 30px; }`; -const LIMIT = 15; function Dispose(props){ - const [ spining , setSpining ] = useState(false); + const [ spining , setSpining ] = useState(true); + const [ updateInfo , setUpdateInfo ] = useState(undefined); const [ list , setList ] = useState(undefined); - const [ page , setPage ] = useState(1); - const [ total , setTotal ] = useState(0); const [ permission , setPermission ] = useState(""); const [ visible , setVisible ] = useState(false); @@ -33,69 +31,94 @@ function Dispose(props){ } },[projectDetail]) - useEffect(()=>{ + function Init(){ const url = `/ci/pipelines/list.json`; - - axios.get(url).then(result=>{ + axios.get(url,{ + params:{ + identifier:projectsId + } + }).then(result=>{ if(result && result.data){ setList(result.data.pipelines); + setSpining(false); } }).catch(error=>{}) - // let l = [ - // {name:"流水线名字",fileName:"filename.jpg",time:"2021-01-06",status:"运行中"}, - // {name:"流水线名字11",fileName:"filename111.jpg",time:"2021-01-06",status:"运行中"} - // ] - - },[]) - - - - // 分页-切换页面 - function changePage(page){ - setPage(page); } + useEffect(()=>{ + Init(); + },[]) + + // 新增流水线 - function addNew(){ + function addNew(pipeline_name,id){ setVisible(true); + setUpdateInfo(undefined); + if(pipeline_name){ + let l = {pipeline_name,id} + setUpdateInfo(l); + } } - function onOk(pipeline_name){ + function onOk(pipeline_name,updateId){ if(pipeline_name){ - const url = `/ci/pipelines.json`; - axios.post(url,{ - pipeline_name, - file_name:".trustie.pipeline.yml" - }).then(result=>{ - if(result && result.data){ + if(!updateId){ + // 新增 + const url = `/ci/pipelines.json`; + axios.post(url,{ + pipeline_name, + file_name:".trustie.pipeline.yml", + identifier:projectsId + }).then(result=>{ setVisible(false); - props.showNotification("流水线新增成果,请进行工作流配置!"); - props.history.push(`/projects/${owner}/${projectsId}/devops/dispose/${result.data.id}`); - }else{ - props.showNotification("流水线新增失败,请稍后再试!"); - } - }) + if(result && result.data){ + props.showNotification("流水线新增成功,请进行工作流配置!"); + props.history.push(`/projects/${owner}/${projectsId}/devops/dispose/${result.data.id}`); + }else{ + props.showNotification("流水线新增失败,请稍后再试!"); + } + }).catch(error=>{}) + }else{ + // 修改 + const url = `/ci/pipelines/${updateId}.json`; + axios.put(url,{ + pipeline_name + }).then(result=>{ + if(result && result.data){ + setVisible(false); + Init(); + props.showNotification("流水线名称更新成功!"); + }else{ + props.showNotification("流水线名称更新失败,请稍后再试!"); + } + }).catch(error=>{}) + } }else{ props.showNotification("请输入流水线名称!"); } } + + // 删除 + function deleteFunc(id){ + const url = `/ci/pipelines/${id}.json`; + axios.delete(url).then(result=>{ + if(result && result.data){ + props.showNotification("流水线删除成功!"); + Init(); + } + }).catch(error=>{}) + } + return( - setVisible(false)} onOk={onOk}/> + {setVisible(false);}} onOk={onOk}/>
- { permission !=="Reporter" && (!list ||(list && list.length === 0)) && 新增流水线 } + { permission !=="Reporter" && (!list ||(list && list.length === 0)) && addNew(undefined,undefined)}>新增流水线 }
- - { - total > LIMIT ? -
- -
- :"" - } +
diff --git a/src/forge/DevOps/Dispose/Choosen.jsx b/src/forge/DevOps/Dispose/Choosen.jsx index 5f808e332..e65a9b825 100644 --- a/src/forge/DevOps/Dispose/Choosen.jsx +++ b/src/forge/DevOps/Dispose/Choosen.jsx @@ -1,36 +1,93 @@ import React , { useEffect , useState } from 'react'; -function Choosen({name,chooseFunc}){ - const [ index, setIndex ] = useState(undefined); - const [ models , setModels ] = useState(undefined); +function Choosen({ chooseFunc, temp , templateId , category }){ + const [ tempId, setTemId ] = useState(undefined); + const [ cate , setCate ]= useState(undefined); + const [ templates , setTemplates ] = useState(undefined); + const [ categories , setCategories ] = useState(undefined); useEffect(()=>{ - let list = [ - {id:1,name:"docker/arm64/linux"}, - {id:2,name:"docker/x86/linux"} - ] - setModels(list); - },[]) + if(templateId){ + setTemId(templateId); + } + },[templateId]) - // 选择选项 - function chooseOption(id,k){ - chooseFunc && chooseFunc(id); - setIndex(k); + useEffect(()=>{ + if(category){ + setCate(category); + } + },[category]) + + useEffect(()=>{ + if(temp && temp.length > 0){ + if(temp[0].category !== "初始化"){ + setCategories(temp) + }else{ + setCategories(undefined); + } + setTemplates(temp[0].templates); + setCate(temp[0].category); + if(category && temp[0].category !== "初始化" && category !== "初始化"){ + let c = temp.filter(item=>item.category === category); + let t = c && c.length > 0 && c[0].templates; + setTemplates(t); + setCate(category); + } + }else{ + setTemplates(undefined); + setCate(undefined); + setCategories(undefined); + } + },[temp,category]) + + // 选择类别 + function changeCate(cate){ + setCate(cate); + let c = categories && categories.filter(item=>item.category === cate); + setTemplates(c && c[0].templates); + chooseFunc && chooseFunc(undefined,undefined,cate); + } + + // 选择模板 + function chooseOption(id){ + let item = templates.filter(item=>item.id === id); + let content = item && item.length >0 && item[0].content; + chooseFunc && chooseFunc(content,id,cate); + setTemId(id); } return( -
- {name} -
    - { - models && models.map((item,key)=>{ - return( -
  • chooseOption(item.id,key+1)}>{item.name}
  • - ) - }) - } -
-
+ + { + categories && categories.length > 0 && +
+ 模板类别: +
    + { + categories.map((item,key)=>{ + return( +
  • changeCate(item.category)}>{item.category}
  • ) + }) + } +
+
+ } + { + templates && templates.length> 0 && +
+ 模板选择: +
    + { + templates.map((item,key)=>{ + return( +
  • chooseOption(item.id)}>{item.template_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 index 8b8a2bbff..94b27e38e 100644 --- a/src/forge/DevOps/Dispose/Editors.jsx +++ b/src/forge/DevOps/Dispose/Editors.jsx @@ -1,7 +1,25 @@ import React from 'react'; import Editor from 'react-monaco-editor'; -function Editors({value,onChange,theme,height}){ +function Editors({value,onChange,theme,height,visible}){ + const editor_options = { + lineNumbers: "on", + wordWrap: true, //强制换行 + selectOnLineNumbers: true, + lineHeight: 24, + renderLineHighlight: "line", + revealHorizontalRightPadding: 5, + placeholder:"请输入内容", + readOnly: visible, + cursorStyle: visible ? "underline-thin" : "line", + folding: true, + foldingStrategy: "indentation", // 代码可分小段折叠 + automaticLayout: true, // 自适应布局 + minimap: { + // 不要小地图 + enabled: false, + }, + } return( onChange(value)} + disabled={true} > ) } diff --git a/src/forge/DevOps/Dispose/Init.jsx b/src/forge/DevOps/Dispose/Init.jsx index 6a944ea30..86477482b 100644 --- a/src/forge/DevOps/Dispose/Init.jsx +++ b/src/forge/DevOps/Dispose/Init.jsx @@ -1,24 +1,64 @@ import React , { useEffect , useState } from 'react'; -import { Input , Button } from 'antd'; +import { Button } from 'antd'; import Choosen from './Choosen'; import Editors from './Editors'; -function Init(){ - const [ modelsId , setModelsId ] = useState(undefined); +function Init({ datas , templates , saveFunc , saveDatas}){ + const [ templateId , setTemplateId ] = useState(undefined); const [ ymlValue , setYmlValue ] = useState(undefined); + const [ temp , setTemp ] = useState(undefined); + useEffect(()=>{ + if(templates && templates.length > 0){ + setTemp(templates) + } + },[templates]) - function chooseFunc(id){ - setModelsId(id); + useEffect(()=>{ + if(datas && datas.length > 0){ + setTemplateId(datas[0].template_id); + setYmlValue(datas[0].content); + } + },[datas]) + + // 选择模板 + function chooseFunc(content,id,cate){ + setTemplateId(id); + setYmlValue(content); + recieveData(id,content); } + + function recieveData(id,content){ + let steps = datas; + if(datas && datas.length>0){ + steps[0].content = content || ymlValue; + steps[0].template_id = id || templateId ; + }else{ + steps = + [{ + step_name:"初始化", + show_index:1, + content:content || ymlValue, + template_id:id || templateId + }] + } + saveDatas(steps); + } + + // 点击下一步时 + function nextStep(){ + recieveData(); + saveFunc(undefined,undefined,undefined,undefined,"next"); + } + return(
- +
- +
) diff --git a/src/forge/DevOps/Dispose/List.jsx b/src/forge/DevOps/Dispose/List.jsx index 489734276..90e6b8be4 100644 --- a/src/forge/DevOps/Dispose/List.jsx +++ b/src/forge/DevOps/Dispose/List.jsx @@ -1,8 +1,8 @@ -import React, { useState } from 'react'; -import { Table } from 'antd'; +import React from 'react'; +import { Table , Popconfirm } from 'antd'; import { Link } from 'react-router-dom'; -function List({ list, permission , projectsId , owner }){ +function List({ list, permission , projectsId , owner , showModal , deleteFunc }){ const columns = [ { @@ -10,7 +10,12 @@ function List({ list, permission , projectsId , owner }){ dataIndex:"pipeline_name", key:1, width:"20%", - ellipsis:true + ellipsis:true, + render:(txt,item)=>{ + return( + showModal(txt,item.id)} style={{display:"block",cursor:"pointer"}}>{txt} + ) + } }, { title:"文件名称", @@ -27,13 +32,6 @@ function List({ list, permission , projectsId , owner }){ width:"18%", ellipsis:true }, - // { - // title:"状态", - // dataIndex:"status", - // key:1, - // width:"15%", - // ellipsis:true - // }, { title:"操作", dataIndex:"operation", @@ -42,9 +40,12 @@ function List({ list, permission , projectsId , owner }){ render:(txt,item)=>{ return( - { permission !=="Reporter" && 编辑 } - { permission !=="Reporter" && 删除 } - { permission !=="Reporter" && 运行 } + { permission !=="Reporter" && 编辑 } + { permission !=="Reporter" && + deleteFunc(item.id)} okText="确定" cancelText={"取消"}> + 删除 + + } 查看运行记录 ) diff --git a/src/forge/DevOps/Dispose/PipelineName.jsx b/src/forge/DevOps/Dispose/PipelineName.jsx index cc2707bd7..0f92f75a8 100644 --- a/src/forge/DevOps/Dispose/PipelineName.jsx +++ b/src/forge/DevOps/Dispose/PipelineName.jsx @@ -1,11 +1,18 @@ import React , { useEffect , useState } from 'react'; import { Modal , Input } from 'antd'; -function PipelineName({visible,onCancel,onOk}){ +function PipelineName({visible,onCancel,onOk,value}){ const [ name , setName ] = useState(undefined); + console.log(value); + useEffect(()=>{ + if(value){ + setName(value.pipeline_name); + } + },[value]) + function onSure(){ - onOk(name); + onOk(name,value && value.id); } return( { - let l = [ - { - "step_name": "编译构建-gradle", - "show_index": 1, - "content": "xxxxxxxxxxx", - "template_id":1 - }, - { - "step_name": "编译构建-maven", - "show_index": 1, - "content": "xxxxxxxxxxx", - "template_id":1 + if(templates && templates.length > 0){ + setTemp(templates); + } + },[templates]) + + useEffect(()=>{ + if(datas){ + if(datas.length > 0 && stepList !== datas){ + setStepList(datas); + }else if(datas.length === 0){ + let list = []; + setStepList(list); } - ] - setStepList(l); - },[]) + setSaveFlag(true); + } + },[datas]) + + // 添加步骤 + function addFunc(){ + if(saveFlag){ + let list = stepList; + let length = list ? list.length : 0; + let step = + { + "category":undefined, + "step_name": stepName+`${length + 1}`, + "show_index": length + 1, + "content":undefined, + "template_id":undefined, + "hide":false + } + list.push(step); + saveDatas(list); + setSaveFlag(false); + }else{ + showNotification(`请先选择模板!`); + } + } + + // 将修改的对应项保存在数组中 + function saveItems(content,id,cate,key){ + let item = stepList; + item[key].content = content; + item[key].template_id = id; + item[key].category = cate; + saveDatas([...item]); + setSaveFlag((id && content) ? true:false); + } + + function slideItems(key,hide){ + let item = stepList; + item[key].hide = !hide; + setStepList([...item]); + saveDatas(item); + } + + function deleteItem(id){ + setSaveFlag(true); + deleteStep(id); + } + // 点击下一步时 + function nextStep(btn){ + saveFunc(undefined,undefined,undefined,undefined,btn); + } return(
{ - stepList && stepList.map((item,key)=>{ + stepList && stepList.length > 0 && stepList.map((item,key)=>{ return( - + ) }) } - + 添加步骤 + + 添加步骤
- - - 删除 + + + + 删除 +
) diff --git a/src/forge/DevOps/Dispose/StageItem.jsx b/src/forge/DevOps/Dispose/StageItem.jsx index 882ee4efa..40d84423a 100644 --- a/src/forge/DevOps/Dispose/StageItem.jsx +++ b/src/forge/DevOps/Dispose/StageItem.jsx @@ -1,25 +1,39 @@ -import React , { useEffect , useState } from 'react'; +import React from 'react'; import { FlexAJ } from '../../Component/layout'; import Editors from './Editors'; +import Choosen from './Choosen'; +import { Popconfirm } from 'antd'; -function StageItem({item}){ - const [ value , setValue ] = useState(undefined); - +function StageItem({item, templates,saveItems,k, slideItems , deleteStep}){ + function onChangevalue(value){ - console.log(value); + saveItems(value,item.template_id,item.category,k); } + // 选择模板 + function chooseFunc(content,id,cate){ + saveItems(content,id,cate,k); + } + return(
- {item.step_name} + {item.step_name} - - + deleteStep(item.id)} + > + + + slideItems(k,item.hide)}> -
- +
+ +
) diff --git a/src/forge/DevOps/Dispose/Sure.jsx b/src/forge/DevOps/Dispose/Sure.jsx index 1aa5fb18b..9de65c79c 100644 --- a/src/forge/DevOps/Dispose/Sure.jsx +++ b/src/forge/DevOps/Dispose/Sure.jsx @@ -1,23 +1,26 @@ -import React , { useEffect , useState } from 'react'; +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); +function Sure({datas , name , saveFunc , sureSubmit}){ + const [ value , setValue ] = useState(undefined); + useEffect(()=>{ + if(datas && datas.content){ + setValue(datas.content) + } + },[datas]) return(
- 工作流名称:流水线名称 + 工作流名称:{name}
- +
- - - 取消 + + { value && }
) diff --git a/src/forge/DevOps/Dispose/head.jsx b/src/forge/DevOps/Dispose/head.jsx index cd741fd10..c178f9b5c 100644 --- a/src/forge/DevOps/Dispose/head.jsx +++ b/src/forge/DevOps/Dispose/head.jsx @@ -1,4 +1,4 @@ -import React , { useEffect , useState } from 'react'; +import React from 'react'; import { AlignCenterBetween } from '../../Component/layout'; import { Link } from 'react-router-dom'; @@ -8,7 +8,7 @@ function head(){ return( 工作流配置 - 模板使用说明 + 模板使用说明 ) } diff --git a/src/forge/DevOps/Dispose/menus.jsx b/src/forge/DevOps/Dispose/menus.jsx index fa3126111..65778bb2b 100644 --- a/src/forge/DevOps/Dispose/menus.jsx +++ b/src/forge/DevOps/Dispose/menus.jsx @@ -1,16 +1,20 @@ -import React , { useEffect , useState } from 'react'; +import React from 'react'; import MenusRename from './menusRename'; import MenusAdd from './menusAdd'; +const typeIcon = { + init:"iconinitialize",build:"iconstructure",deploy:"iconarrange",customize:"iconnewStage",confirm:'iconsure' +} -function Menus({step,changeStep,menuList}){ - - function InitActive(key){ - changeStep(key) +function Menus({step,changeStep, menuList , renameFunc , checkDatas , addFunc }){ + + function InitActive(key,stage_type,stage_id,stage_name){ + changeStep(key,stage_type,stage_id,stage_name); } - function getName(name){ - console.log(name); + // 新增阶段 + function getName(name,index){ + addFunc && addFunc(name,index); } return( @@ -19,12 +23,12 @@ function Menus({step,changeStep,menuList}){ menuList && menuList.length > 0 && menuList.map((item,key)=>{ return( -
  • InitActive(key+1)} className={key+1 === step ?"active":""}> - - +
  • InitActive(item.show_index,item.stage_type,item.id,item.stage_name)} className={item.show_index === step ?"active":""}> + +
  • - { key !== (menuList.length-1) && menuList.length <= 10 ? - :"" + { key !== (menuList.length-1) && menuList.length <= 7 ? + :"" }
    ) diff --git a/src/forge/DevOps/Dispose/menusAdd.jsx b/src/forge/DevOps/Dispose/menusAdd.jsx index d775f95c1..fc9f35a65 100644 --- a/src/forge/DevOps/Dispose/menusAdd.jsx +++ b/src/forge/DevOps/Dispose/menusAdd.jsx @@ -1,21 +1,53 @@ import React , { useState , useEffect } from 'react'; import { Input } from 'antd'; -function menusAdd ({ getName }){ +function menusAdd ({ getName , checkDatas , k }){ const [ show, setShow ] = useState(false); const [ value , setValue ] = useState(undefined); + const [ index , setIndex ] = useState(undefined); + const [ref, setRef ] = useState(undefined); + const [put, setPut ] = useState(false); + + useEffect(() => { + if (put && ref) { + ref.focus(); + } + }) + useEffect(() => { + if (k) { + setIndex(k); + } + },[k]) + function blurInput(){ if(value){ - getName(value); + getName(value , index); } setShow(false); + setPut(false); + } + + function showInput(){ + let c = checkDatas(); + if(c){ + setShow(true); + setPut(true); + } } return(
  • - { !show && setShow(true)}> } - { show && setValue(e.target.value)} onBlur={blurInput} /> } + { !show && } + setRef(el)} + size={"small"} + maxLength={8} + style={{width:"75px",display : `${show?"block":'none'}`}} + placeholder="新阶段名称" + value={value} + onChange={(e)=>setValue(e.target.value)} onBlur={blurInput} + />
  • ) } diff --git a/src/forge/DevOps/Dispose/menusRename.jsx b/src/forge/DevOps/Dispose/menusRename.jsx index 73f1af757..06cfd9193 100644 --- a/src/forge/DevOps/Dispose/menusRename.jsx +++ b/src/forge/DevOps/Dispose/menusRename.jsx @@ -1,11 +1,17 @@ import React , { useEffect , useState } from 'react'; import { Input } from 'antd'; -const regexp = /[^a-zA-Z0-9_]/g; - -function menusRename({ name , edit }){ +function menusRename({ name , edit , id , renameFunc }){ const [ n , setN ] = useState(undefined); const [ show , setShow ] = useState(false); + const [ref, setRef ] = useState(undefined); + const [put, setPut ] = useState(false); + + useEffect(() => { + if (edit && ref) { + ref.focus(); + } + }) useEffect(()=>{ if(name){ @@ -13,21 +19,32 @@ function menusRename({ name , edit }){ } },[name]) + // 显示input框编辑 function changeShow(e){ e.stopPropagation(); setShow(true); + setPut(true); } - function blurInput(){ + function blurInput(e){ + renameFunc(e.target.value,id); + setPut(false); setShow(false); } return(
    { !show && n } - { show && - e.stopPropagation()} onBlur={blurInput} style={{width:"75px"}} onChange={(e)=>setN(e.target.value)}/> - } + setRef(el)} + value={n} + size="small" + maxLength={8} + onClick={(e)=>e.stopPropagation()} + onBlur={blurInput} + style={{width:"75px",display : `${show?"block":'none'}`}} + onChange={(e)=>setN(e.target.value)} + /> { !show && edit && }
    diff --git a/src/forge/DevOps/Index.jsx b/src/forge/DevOps/Index.jsx index 026daa3b5..273d8d4da 100644 --- a/src/forge/DevOps/Index.jsx +++ b/src/forge/DevOps/Index.jsx @@ -42,27 +42,27 @@ export default ((props)=>{ () + (p) => () } > () + (p) => () } > () + (p) => () } > () + (p) => () } > () + (p) => () } > diff --git a/src/forge/DevOps/disposePipeline.jsx b/src/forge/DevOps/disposePipeline.jsx index f7bd53a11..75afd2768 100644 --- a/src/forge/DevOps/disposePipeline.jsx +++ b/src/forge/DevOps/disposePipeline.jsx @@ -1,44 +1,310 @@ import React , { useEffect , useState } from 'react'; import { WhiteBack } from '../Component/layout'; +import { Spin } from 'antd'; import Head from './Dispose/head'; import Menus from './Dispose/menus'; import Init from './Dispose/Init'; import Sure from './Dispose/Sure'; import Stage from './Dispose/Stage'; +import axios from 'axios'; +import { data } from 'autoprefixer'; - -function disposePipeline(){ - const [ step , setStep ] = useState(1); +function disposePipeline(props){ + const [ spining , setSpining ] = useState(true); + const [ stage , setStage ] = useState(1); + const [ pipeLineName , setPipeLineName ] = useState(undefined); + const [ stepName , setStepName ] = useState(undefined); + const [ stageId , setStageId ] =useState(undefined); const [ menuList , setMenuList ] = useState(undefined); + const [ stageType , setStageType ] = useState("init"); + const [ datas , setDatas ] = useState(undefined); + const [ templates , setTemplates] = useState(undefined); + const [ datasUpdataFlag , setDatasUpdataFlag ] = useState(false); + + const { disposeId } = props.match.params; + let projectsId = props.match.params.projectsId; + let owner = props.match.params.owner; + useEffect(()=>{ + if(stageType && stageType !=="confirm"){ + InitTemplates(); + } + },[stageType]) + + // 获取模板 + function InitTemplates(){ + const url = `/ci/templates/templates_by_stage.json`; + axios.get(url,{ + params:{ stage_type:stageType } + }).then(result=>{ + if(result && result.data){ + setTemplates(result.data); + } + }).catch(error=>{}) + } 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); - },[]) + if(disposeId && (stageType && stageType !=="confirm")){ + getData(0); + } + },[disposeId]) + // 获取所有阶段默认第一个阶段的数据 + function getData(index){ + const url = `/ci/pipelines/${disposeId}/stages.json`; + axios.get(url).then(result=>{ + if(result && result.data){ + setMenuList(result.data.stages); + if(index || index === 0){ + let first = result.data.stages[index]; + setStage(first.show_index); + setStageId(first.id); + setPipeLineName(`${first.pipeline_name}`); + } + } + }) + } - function changeStep(s){ - setStep(s); + useEffect(()=>{ + if(stageId){ + getStageStep(stageId); + } + },[stageId]) + // 切换阶段时获取阶段步骤数据(第一次默认查询”初始化“阶段的数据) + function getStageStep(stageId){ + let url = ""; + if(stageType && stageType === "confirm"){ + url = `/ci/pipelines/${disposeId}/content.json`; + axios.get(url,{ + params:{ + owner,repo:projectsId + } + }).then(result=>{ + if(result && result.data){ + setDatas(result.data); + } + }).catch(error=>{}) + }else{ + url = `/ci/pipelines/${disposeId}/${stageId}/steps.json`; + axios.get(url).then(result=>{ + if(result && result.data){ + let step = result.data.steps; + setDatas(step); + let flag = !step || (step && step.length === 0); + setDatasUpdataFlag(flag); + } + }).catch(error=>{}) + } + setSpining(false); + } + + // 切换阶段:s:show_index,stage_type:stage_type + function changestage(show_index,stage_type,stage_id,stage_name){ + if(show_index !== stage){ + saveFunc(show_index,stage_type,stage_id,stage_name); + } + } + + // 获取子组件传过来的数据 + function saveDatas(steps){ + setDatas([...steps]); + setDatasUpdataFlag(true); + } + + // 检查数组里面是否有空数据 + function checkDatas(){ + if(datas && datas.length > 0){ + for(let i= 0;i< datas.length;i++){ + if(datas[i] && (!datas[i].content || !datas[i].template_id)){ + props.showNotification("请先选择模板!"); + return false; + } + } + }else{ + if(stageType === "init" ){ + props.showNotification("请先选择模板!"); + return false; + }else if(stageType === "confirm" ){ + return true; + }else{ + return ""; + } + } + return true; + } + + // 保存步骤 + function saveFunc(show_index,stage_type,stage_id,stageName,btn){ + setSpining(true); + // 判断数据是否有过更新 + if(datasUpdataFlag && stageType !== "confirm"){ + // 先判断子组件传过来的数据是否有undefined --datas + let f = checkDatas(); + if(f && (datas && datas.length !== 0)){ + // 数据没问题后先保存数据再切换阶段 + saveDataFunc(btn,show_index,stage_type,stage_id,stageName); + } + else{ + setSpining(false); + f === "" && elseFunc(btn,show_index,stage_type,stage_id,stageName); + } + }else{ + elseFunc(btn,show_index,stage_type,stage_id,stageName); + } + } + + function saveDataFunc(btn,show_index,stage_type,stage_id,stageName){ + const url = `/ci/pipelines/${disposeId}/${stageId}/stage_step.json`; + axios.post(url,{ + steps:datas + }).then(result=>{ + if(result && result.data){ + props.showNotification("阶段更新成功!"); + setDatasUpdataFlag(false); + if(!btn){ + setStage(show_index); + setStageType(stage_type); + setStageId(stage_id); + setStepName(pipeLineName+`-`+stageName); + }else{ + enters(btn); + } + } + }).catch(error=>{}) + } + + function elseFunc(btn,show_index,stage_type,stage_id,stageName){ + if(btn){ + enters(btn); + }else{ + setStage(show_index); + setStageType(stage_type); + setStageId(stage_id); + setStepName(pipeLineName+`-`+stageName); + } + } + + // 上一步、下一步 + function enters(btn){ + let s; + if(btn === "next"){ + // 点击阶段里面的下一步 + s = stage+1; + }else{ + // 上一步 + s = stage-1; + } + let item = menuList && menuList.filter(i=>i.show_index === (s)); + setStage(item[0].show_index); + setStageType(item[0].stage_type); + setStageId(item[0].id); + setStepName(pipeLineName+`-`+item[0].stage_name); + } + // 删除步骤 + function deleteStep(id){ + if(id){ + const url = `/ci/pipelines/${disposeId}/${stageId}/${id}/delete_step.json`; + axios.delete(url).then(result=>{ + if(result && result.data){ + getStageStep(stageId); + props.showNotification("阶段步骤删除成功!"); + } + }).catch(error=>{}) + }else{ + let d = datas.filter(s=>s.template_id !== undefined); + setDatas(d); + } + } + function renameFunc(value,id){ + const url = `/ci/pipelines/${disposeId}/${id}/update_stage.json`; + axios.put(url,{ + stage_name:value + }).then(result=>{ + if(result && result.data){ + getData(); + } + }).catch(error=>{}) + } + + // 新增阶段 + function addMenuFunc(name,index){ + const url = `/ci/pipelines/${disposeId}/create_stage.json`; + axios.post(url,{ + show_index:index, + stage_name:name + }).then(result=>{ + if(result && result.data){ + props.showNotification("阶段新增成功!"); + getData(index-1); + } + }) + } + + // 删除阶段 + function deleteStageFunc(){ + const url = `/ci/pipelines/${disposeId}/${stageId}/delete_stage.json`; + axios.delete(url,{ + show_index:stage + }).then(result=>{ + if(result && result.data){ + props.showNotification("阶段删除成功!"); + getData(stage-1); + } + }).catch(error=>{}) + } + + // 确认提交 + function sureSubmit(){ + let sync = datas.sync || 0; + let url = ''; + const { defaultBranch } = props; + let params = { + branch: defaultBranch, + content:datas.content, + filepath:'.trustie-pipeline.yml', + message:'', + sha:datas.sha || undefined, + owner:owner, + repo:projectsId + } + if(sync === 1){ + // 为true,则是编辑否则是新建 + url = `/${owner}/${projectsId}/update_trustie_pipeline.json`; + axios.put(url,{ + ...params + }).then(result=>{ + if(result){ + props.history.push(`/projects/${owner}/${disposeId}/devops/dispose`); + } + }).catch(error=>{ + console.log(error); + }) + }else{ + url = `/ci/pipelines/${disposeId}/create_trustie_pipeline.json`; + axios.post(url,params).then(result=>{ + if(result){ + props.history.push(`/projects/${owner}/${disposeId}/devops/dispose`); + } + }).catch(error=>{ + console.log(error); + }) + } } return(
    -
    - - { - step === 1 ? - : - menuList && (step === menuList.length) ? - : - - } -
    + +
    + + { + stage === 1 ? + : + menuList && (stage === menuList.length) ? + : + + } +
    +
    ) diff --git a/src/forge/DevOps/ops.scss b/src/forge/DevOps/ops.scss index a64cb48ff..c8c7bfae5 100644 --- a/src/forge/DevOps/ops.scss +++ b/src/forge/DevOps/ops.scss @@ -341,15 +341,16 @@ text-align: center; color: #787878; font-size: 16px; - min-width: 110px; position: relative; cursor: pointer; - width: 0; + width: 110px; + flex:2; &>i{ font-size: 30px!important; height: 30px; width: 30px; line-height: 30px; + margin-bottom: 10px; } &:hover,&.active{ & > i{ @@ -368,12 +369,15 @@ } .aboutEdit{ width: 100%; + padding:0px 15px; .operateName{ position: relative; - line-height: 20px; + line-height: 22px; + height: 40px; + display: block; & > i{ position: absolute; - right:-22px; + right:-15px; top:50%; margin-top: -11px; display: none; @@ -467,7 +471,6 @@ border-radius: 4px; margin-bottom: 15px; .stepsHead{ - border-bottom: 1px solid #e1e4e8; padding:8px 15px; span > a > i{ margin-left: 8px; @@ -476,6 +479,12 @@ } .stepsBody{ padding:10px 15px; + border-top: 1px solid #e1e4e8; background-color: rgb(251, 251, 251); + display: none; + transition: 0.3s; + } + .stepsBody.active{ + display: block; } } \ No newline at end of file diff --git a/src/modules/tpm/NewHeader.js b/src/modules/tpm/NewHeader.js index d2f77f3e3..57c12a881 100644 --- a/src/modules/tpm/NewHeader.js +++ b/src/modules/tpm/NewHeader.js @@ -395,7 +395,6 @@ class NewHeader extends Component { } inputjoinclassvalue = (e) => { - console.log(e.target.value.length); if (e.target.value.length >= 7) { this.openNotification("请输入6位项目邀请码!"); return @@ -552,9 +551,7 @@ class NewHeader extends Component { let url = "/setting.json"; axios.get(url).then((response) => { if (response && response.data) { - this.setState({ mygetHelmetapi2: response.data.setting }, () => { - console.log(''); - }); + this.setState({ mygetHelmetapi2: response.data.setting }); // localStorage.setItem('chromesetting', JSON.stringify(response.data.setting)); // localStorage.setItem('chromesettingresponse', JSON.stringify(response)); try {