first commit
This commit is contained in:
328
orion-ops-vue/src/components/app/AppBuildConfigForm.vue
Normal file
328
orion-ops-vue/src/components/app/AppBuildConfigForm.vue
Normal file
@@ -0,0 +1,328 @@
|
||||
<template>
|
||||
<div id="app-build-conf-container">
|
||||
<a-spin :spinning="loading">
|
||||
<!-- 产物路径 -->
|
||||
<div id="app-bundle-container">
|
||||
<div id="app-bundle-wrapper">
|
||||
<span class="label normal-label required-label">构建产物路径</span>
|
||||
<a-textarea class="bundle-input"
|
||||
v-model="bundlePath"
|
||||
:maxLength="1024"
|
||||
:autoSize="{minRows: 1}"
|
||||
:placeholder="'基于版本仓库的相对路径 或 绝对路径, 路径不能包含 \\\ 应该用 / 替换'"/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 构建操作 -->
|
||||
<div id="app-action-container">
|
||||
<template v-for="(action, index) in actions">
|
||||
<div class="app-action-block" :key="index" v-if="action.visible">
|
||||
<!-- 分隔符 -->
|
||||
<a-divider class="action-divider">构建操作{{ index + 1 }}</a-divider>
|
||||
<div class="app-action-wrapper">
|
||||
<!-- 操作 -->
|
||||
<div class="app-action">
|
||||
<div class="action-name-wrapper">
|
||||
<span class="label normal-label required-label action-label">操作名称{{ index + 1 }}</span>
|
||||
<a-input class="action-name-input" v-model="action.name" :maxLength="32" placeholder="操作名称"/>
|
||||
</div>
|
||||
<!-- 代码块 -->
|
||||
<div class="action-editor-wrapper" v-if="action.type === BUILD_ACTION_TYPE.COMMAND.value">
|
||||
<span class="label normal-label required-label action-label">主机命令{{ index + 1 }}</span>
|
||||
<div class="app-action-editor">
|
||||
<Editor :config="editorConfig" :value="action.command" @change="(v) => action.command = v"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-type-wrapper" v-else>
|
||||
<span class="label normal-label action-label">操作类型</span>
|
||||
<a-button class="action-type-name" ghost disabled>
|
||||
{{ action.type | formatActionType('label') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作 -->
|
||||
<div class="app-action-handler">
|
||||
<a-button-group v-if="actions.length > 1">
|
||||
<a-button title="移除" @click="removeAction(index)" icon="minus-circle"/>
|
||||
<a-button title="上移" v-if="index !== 0" @click="swapAction(index, index - 1)" icon="arrow-up"/>
|
||||
<a-button title="下移" v-if="index !== actions.length - 1" @click="swapAction(index + 1, index )" icon="arrow-down"/>
|
||||
</a-button-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<!-- 底部按钮 -->
|
||||
<div id="app-action-footer">
|
||||
<a-button class="app-action-footer-button" type="dashed"
|
||||
@click="addAction(BUILD_ACTION_TYPE.COMMAND.value)">
|
||||
添加命令操作 (宿主机执行)
|
||||
</a-button>
|
||||
<a-button class="app-action-footer-button" type="dashed"
|
||||
v-if="visibleAddCheckout"
|
||||
@click="addAction(BUILD_ACTION_TYPE.CHECKOUT.value)">
|
||||
添加检出操作 (宿主机执行)
|
||||
</a-button>
|
||||
<a-button class="app-action-footer-button" type="primary" @click="save">保存</a-button>
|
||||
</div>
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { BUILD_ACTION_TYPE, enumValueOf } from '@/lib/enum'
|
||||
import Editor from '@/components/editor/Editor'
|
||||
|
||||
const editorConfig = {
|
||||
enableLiveAutocompletion: true,
|
||||
fontSize: 14
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'AppBuildConfigForm',
|
||||
props: {
|
||||
appId: Number,
|
||||
dataLoading: Boolean,
|
||||
detail: Object
|
||||
},
|
||||
components: {
|
||||
Editor
|
||||
},
|
||||
computed: {
|
||||
visibleAddCheckout() {
|
||||
return this.repoId &&
|
||||
this.repoId !== null &&
|
||||
this.actions.map(s => s.type).filter(t => t === BUILD_ACTION_TYPE.CHECKOUT.value).length < 1
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
detail(e) {
|
||||
this.initData(e)
|
||||
},
|
||||
dataLoading(e) {
|
||||
this.loading = e
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
BUILD_ACTION_TYPE,
|
||||
loading: false,
|
||||
profileId: null,
|
||||
repoId: null,
|
||||
bundlePath: undefined,
|
||||
actions: [],
|
||||
editorConfig
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initData(detail) {
|
||||
this.profileId = detail.profileId
|
||||
this.repoId = detail.repoId
|
||||
this.bundlePath = detail.env && detail.env.bundlePath
|
||||
if (detail.buildActions && detail.buildActions.length) {
|
||||
this.actions = detail.buildActions.map(s => {
|
||||
return {
|
||||
visible: true,
|
||||
name: s.name,
|
||||
type: s.type,
|
||||
command: s.command
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.actions = []
|
||||
}
|
||||
},
|
||||
addAction(type) {
|
||||
this.actions.push({
|
||||
type,
|
||||
command: '',
|
||||
name: undefined,
|
||||
visible: true
|
||||
})
|
||||
},
|
||||
removeAction(index) {
|
||||
this.actions[index].visible = false
|
||||
this.$nextTick(() => {
|
||||
this.actions.splice(index, 1)
|
||||
})
|
||||
},
|
||||
swapAction(index, target) {
|
||||
const temp = this.actions[target]
|
||||
this.$set(this.actions, target, this.actions[index])
|
||||
this.$set(this.actions, index, temp)
|
||||
},
|
||||
save() {
|
||||
if (!this.bundlePath || !this.bundlePath.trim().length) {
|
||||
this.$message.warning('请输入构建产物路径')
|
||||
return
|
||||
}
|
||||
if (this.bundlePath.includes('\\')) {
|
||||
this.$message.warning('构建产物路径不能包含 \\ 应该用 / 替换')
|
||||
return
|
||||
}
|
||||
if (!this.actions.length) {
|
||||
this.$message.warning('请设置构建操作')
|
||||
return
|
||||
}
|
||||
for (let i = 0; i < this.actions.length; i++) {
|
||||
const action = this.actions[i]
|
||||
if (!action.name) {
|
||||
this.$message.warning(`请输入操作名称 [构建操作${i + 1}]`)
|
||||
return
|
||||
}
|
||||
if (BUILD_ACTION_TYPE.COMMAND.value === action.type) {
|
||||
if (!action.command) {
|
||||
this.$message.warning(`请输入操作命令 [构建操作${i + 1}]`)
|
||||
return
|
||||
} else if (action.command.length > 2048) {
|
||||
this.$message.warning(`操作命令长度不能大于2048位 [构建操作${i + 1}] 当前: ${action.command.length}`)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
this.loading = true
|
||||
this.$api.configApp({
|
||||
appId: this.appId,
|
||||
profileId: this.profileId,
|
||||
stageType: 10,
|
||||
env: {
|
||||
bundlePath: this.bundlePath
|
||||
},
|
||||
buildActions: this.actions
|
||||
}).then(() => {
|
||||
this.$message.success('保存成功')
|
||||
this.$emit('updated')
|
||||
this.loading = false
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
formatActionType(type, f) {
|
||||
return enumValueOf(BUILD_ACTION_TYPE, type)[f]
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initData(this.detail)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@label-width: 160px;
|
||||
@action-handler-width: 120px;
|
||||
@bundle-container-width: 994px;
|
||||
@bundle-input-width: 700px;
|
||||
@app-action-container-width: 994px;
|
||||
@app-action-width: 876px;
|
||||
@action-name-input-width: 700px;
|
||||
@app-action-editor-width: 700px;
|
||||
@app-action-editor-height: 250px;
|
||||
@action-type-name-width: 700px;
|
||||
@action-divider-min-width: 830px;
|
||||
@action-divider-width: 990px;
|
||||
@app-action-footer-width: 700px;
|
||||
@footer-margin-left: 168px;
|
||||
@desc-margin-left: 168px;
|
||||
|
||||
#app-build-conf-container {
|
||||
padding: 18px 8px 0 8px;
|
||||
overflow: auto;
|
||||
|
||||
.label {
|
||||
width: @label-width;
|
||||
font-size: 15px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
#app-bundle-wrapper {
|
||||
width: @bundle-container-width;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
align-content: center;
|
||||
|
||||
.bundle-input {
|
||||
width: @bundle-input-width;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
#app-action-container {
|
||||
width: @app-action-container-width;
|
||||
margin-top: 16px;
|
||||
|
||||
.app-action-wrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
.action-label {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.app-action {
|
||||
width: @app-action-width;
|
||||
padding: 0 8px 8px 8px;
|
||||
|
||||
.action-name-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.action-name-input {
|
||||
width: @action-name-input-width;
|
||||
}
|
||||
}
|
||||
|
||||
.action-editor-wrapper {
|
||||
display: flex;
|
||||
|
||||
.app-action-editor {
|
||||
width: @app-action-editor-width;
|
||||
height: @app-action-editor-height;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.action-type-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.action-type-name {
|
||||
width: @action-type-name-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.app-action-handler {
|
||||
width: @action-handler-width;
|
||||
margin: 8px 0 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.action-divider {
|
||||
min-width: @action-divider-min-width;
|
||||
width: @action-divider-width;
|
||||
margin: 16px 0;
|
||||
}
|
||||
}
|
||||
|
||||
#app-action-footer {
|
||||
margin: 16px 0 8px @footer-margin-left;
|
||||
width: @app-action-footer-width;
|
||||
|
||||
.app-action-footer-button {
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.config-description {
|
||||
margin: 4px 0 0 @desc-margin-left;
|
||||
display: block;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user