fix(工作台): 接口CASE批量执行环境弹窗保持一致
--bug=1027073 --user=宋昌昌 【工作台】我的待办-接口用例-待完成/待更新-批量执行-未显示环境 https://www.tapd.cn/55049933/s/1390207
This commit is contained in:
parent
4d8f3b3fee
commit
df2f4bb8a6
|
@ -50,6 +50,10 @@ export function testCaseBatchRun(params) {
|
||||||
return post(CASE_URL+'batch/run', params);
|
return post(CASE_URL+'batch/run', params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getApiCaseEnvironments(param) {
|
||||||
|
return post(CASE_URL + '/get/env', param);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*sync*/
|
/*sync*/
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {get, post} from "metersphere-frontend/src/plugins/request"
|
import {get, post} from "metersphere-frontend/src/plugins/request"
|
||||||
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
|
import {getCurrentProjectID, getCurrentWorkspaceId} from "metersphere-frontend/src/utils/token";
|
||||||
|
|
||||||
export function listAllProject() {
|
export function listAllProject() {
|
||||||
return get("/project/listAll")
|
return get("/project/listAll")
|
||||||
|
@ -38,3 +38,7 @@ export function getProjectConfig(projectId) {
|
||||||
let url = '/project_application/get/config/' + projectId;
|
let url = '/project_application/get/config/' + projectId;
|
||||||
return get(url);
|
return get(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAll() {
|
||||||
|
return get('/project/listAll/' + getCurrentWorkspaceId());
|
||||||
|
}
|
||||||
|
|
|
@ -207,6 +207,7 @@
|
||||||
|
|
||||||
<api-case-run-mode-with-env
|
<api-case-run-mode-with-env
|
||||||
:project-id="projectId"
|
:project-id="projectId"
|
||||||
|
:run-case-ids="runCaseIds"
|
||||||
@handleRunBatch="runBatch"
|
@handleRunBatch="runBatch"
|
||||||
@close="initTable"
|
@close="initTable"
|
||||||
ref="batchRun"/>
|
ref="batchRun"/>
|
||||||
|
@ -472,7 +473,8 @@ export default {
|
||||||
hasEditPermission: false,
|
hasEditPermission: false,
|
||||||
store: {},
|
store: {},
|
||||||
openUpdateRule: true,
|
openUpdateRule: true,
|
||||||
showColum: false
|
showColum: false,
|
||||||
|
runCaseIds: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -941,7 +943,10 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleRunBatch() {
|
handleRunBatch() {
|
||||||
|
this.runCaseIds = Array.from(this.selectRows).map((row) => row.id);
|
||||||
|
this.$nextTick(() => {
|
||||||
this.$refs.batchRun.open();
|
this.$refs.batchRun.open();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
runBatch(config) {
|
runBatch(config) {
|
||||||
let obj = {};
|
let obj = {};
|
||||||
|
|
|
@ -7,18 +7,20 @@
|
||||||
:visible.sync="runModeVisible"
|
:visible.sync="runModeVisible"
|
||||||
>
|
>
|
||||||
<div style="margin-bottom: 10px;">
|
<div style="margin-bottom: 10px;">
|
||||||
<span class="ms-mode-span">{{ $t("commons.environment") }}:</span>
|
<div>{{ $t('commons.environment') }}:</div>
|
||||||
<env-popover :project-ids="projectIds"
|
<env-select-popover
|
||||||
:placement="'bottom-start'"
|
:project-ids="projectIds"
|
||||||
:project-list="projectList"
|
:project-list="projectList"
|
||||||
:project-env-map="projectEnvListMap"
|
:case-id-env-name-map="caseIdEnvNameMap"
|
||||||
:environment-type.sync="runConfig.environmentType"
|
:environment-type.sync="runConfig.environmentType"
|
||||||
|
:is-scenario="false"
|
||||||
|
:has-option-group="true"
|
||||||
|
:project-env-map="projectEnvListMap"
|
||||||
:group-id="runConfig.environmentGroupId"
|
:group-id="runConfig.environmentGroupId"
|
||||||
@setEnvGroup="setEnvGroup"
|
|
||||||
@setProjectEnvMap="setProjectEnvMap"
|
@setProjectEnvMap="setProjectEnvMap"
|
||||||
@showPopover="showPopover"
|
@setEnvGroup="setEnvGroup"
|
||||||
:show-env-group="false"
|
ref="envSelectPopover"
|
||||||
ref="envPopover" class="env-popover"/>
|
class="env-select-popover"></env-select-popover>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="ms-mode-span">{{ $t("run_mode.title") }}:</span>
|
<span class="ms-mode-span">{{ $t("run_mode.title") }}:</span>
|
||||||
|
@ -78,7 +80,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MsDialogFooter from "metersphere-frontend/src/components/MsDialogFooter";
|
import MsDialogFooter from "metersphere-frontend/src/components/MsDialogFooter";
|
||||||
import EnvPopover from "@/business/module/environment/EnvPopover";
|
import EnvSelectPopover from "../environment/EnvSelectPopover";
|
||||||
import {strMapToObj} from "metersphere-frontend/src/utils";
|
import {strMapToObj} from "metersphere-frontend/src/utils";
|
||||||
import {ENV_TYPE} from "metersphere-frontend/src/utils/constants";
|
import {ENV_TYPE} from "metersphere-frontend/src/utils/constants";
|
||||||
import {parseEnvironment} from "metersphere-frontend/src/model/EnvironmentModel";
|
import {parseEnvironment} from "metersphere-frontend/src/model/EnvironmentModel";
|
||||||
|
@ -86,10 +88,11 @@ import { getOwnerProjects, getProjectConfig} from "@/api/project";
|
||||||
import {getTestResourcePools} from "@/api/test-resource-pool";
|
import {getTestResourcePools} from "@/api/test-resource-pool";
|
||||||
import {getEnvironmentByProjectId} from "metersphere-frontend/src/api/environment";
|
import {getEnvironmentByProjectId} from "metersphere-frontend/src/api/environment";
|
||||||
import { getCurrentProjectID } from 'metersphere-frontend/src/utils/token';
|
import { getCurrentProjectID } from 'metersphere-frontend/src/utils/token';
|
||||||
|
import { getApiCaseEnvironments } from "@/api/api";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "MsApiCaseRunModeWithEnv",
|
name: "MsApiCaseRunModeWithEnv",
|
||||||
components: {EnvPopover, MsDialogFooter},
|
components: {EnvSelectPopover, MsDialogFooter},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
runModeVisible: false,
|
runModeVisible: false,
|
||||||
|
@ -108,15 +111,20 @@ export default {
|
||||||
projectEnvListMap: {},
|
projectEnvListMap: {},
|
||||||
projectList: [],
|
projectList: [],
|
||||||
projectIds: new Set(),
|
projectIds: new Set(),
|
||||||
|
caseIdEnvNameMap: {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: ['projectId'],
|
props: {
|
||||||
|
runCaseIds: Array,
|
||||||
|
projectId: String
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
open() {
|
open() {
|
||||||
this.runModeVisible = true;
|
this.runModeVisible = true;
|
||||||
this.getResourcePools();
|
this.getResourcePools();
|
||||||
this.getWsProjects();
|
this.getWsProjects();
|
||||||
this.getDefaultResourcePool();
|
this.getDefaultResourcePool();
|
||||||
|
this.showPopover();
|
||||||
},
|
},
|
||||||
getDefaultResourcePool() {
|
getDefaultResourcePool() {
|
||||||
getProjectConfig(getCurrentProjectID())
|
getProjectConfig(getCurrentProjectID())
|
||||||
|
@ -189,9 +197,16 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
showPopover() {
|
showPopover() {
|
||||||
|
let currentProjectID = getCurrentProjectID();
|
||||||
this.projectIds.clear();
|
this.projectIds.clear();
|
||||||
this.projectIds.add(this.projectId);
|
this.projectIds.add(currentProjectID);
|
||||||
this.$refs.envPopover.openEnvSelect();
|
getApiCaseEnvironments(this.runCaseIds).then((res) => {
|
||||||
|
let data = res.data;
|
||||||
|
if (data) {
|
||||||
|
this.caseIdEnvNameMap = data;
|
||||||
|
}
|
||||||
|
this.$refs.envSelectPopover.open();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,297 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-radio-group v-model="radio" style="width: 100%" @change="radioChange" class="radio-change">
|
||||||
|
<el-radio :label="ENV_TYPE.JSON">{{ $t('workspace.env_group.env_list') }}</el-radio>
|
||||||
|
<el-radio :label="ENV_TYPE.GROUP" v-if="isScenario">{{ $t('workspace.env_group.name') }}<i class="el-icon-tickets mode-span" @click="viewGroup"></i></el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<div v-for="(pe, pIndex) in eventData" :key="pe.id" v-show="!radio || radio === ENV_TYPE.JSON">
|
||||||
|
<el-card shadow="never" style="margin-top: 8px; background: #f5f6f7; border-radius: 4px">
|
||||||
|
<i
|
||||||
|
@click="expandCard(pIndex)"
|
||||||
|
v-if="pe.expendStatus === 'close'"
|
||||||
|
class="el-icon-caret-right"
|
||||||
|
style="color: var(--primary_color)" />
|
||||||
|
<i @click="expandCard(pIndex)" v-else class="el-icon-caret-bottom" style="color: var(--primary_color)" />
|
||||||
|
<span class="project-name" :title="getProjectName(pe.id)"> {{ getProjectName(pe.id) }} </span><br />
|
||||||
|
<div v-if="pe.expendStatus === 'open'">
|
||||||
|
<el-radio-group
|
||||||
|
v-model="pe.envRadio"
|
||||||
|
style="width: 100%"
|
||||||
|
@change="envRadioChange(pe.envRadio, pIndex)"
|
||||||
|
class="radio-change">
|
||||||
|
<el-radio label="DEFAULT_ENV" style="margin-top: 7px">{{
|
||||||
|
$t('api_test.environment.default_environment')
|
||||||
|
}}</el-radio>
|
||||||
|
<el-radio label="CUSTOMIZE_ENV" style="margin-top: 7px">{{
|
||||||
|
$t('api_test.environment.choose_new_environment')
|
||||||
|
}}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
<el-tag
|
||||||
|
v-show="!pe.showEnvSelect"
|
||||||
|
v-for="(itemName, index) in selectedEnvName.get(pe.id)"
|
||||||
|
:key="index"
|
||||||
|
size="mini"
|
||||||
|
style="margin-left: 0; margin-right: 2px; margin-top: 8px"
|
||||||
|
>{{ itemName }}</el-tag
|
||||||
|
>
|
||||||
|
<el-select
|
||||||
|
v-show="pe.showEnvSelect"
|
||||||
|
v-model="pe['selectEnv']"
|
||||||
|
:placeholder="$t('api_test.environment.select_environment')"
|
||||||
|
style="margin-top: 8px; width: 100%"
|
||||||
|
size="small"
|
||||||
|
filterable
|
||||||
|
@change="chooseEnv">
|
||||||
|
<el-option
|
||||||
|
v-for="(environment, index) in pe.envs"
|
||||||
|
:key="index"
|
||||||
|
:label="environment.name"
|
||||||
|
:value="environment.id" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<div v-show="radio === ENV_TYPE.GROUP ">
|
||||||
|
<div >
|
||||||
|
<el-select v-show="!hasOptionGroup" v-model="envGroupId" :placeholder="$t('workspace.env_group.select')" @change="chooseEnvGroup"
|
||||||
|
style="margin-top: 8px;width: 100%;" size="small">
|
||||||
|
<el-option v-for="(group, index) in groups" :key="index"
|
||||||
|
:disabled="group.disabled"
|
||||||
|
:label="group.name"
|
||||||
|
:value="group.id"/>
|
||||||
|
</el-select>
|
||||||
|
<el-select
|
||||||
|
v-show="hasOptionGroup"
|
||||||
|
v-model="envGroupId"
|
||||||
|
:placeholder="$t('workspace.env_group.select')"
|
||||||
|
style="margin-top: 8px;width: 100%;"
|
||||||
|
size="small"
|
||||||
|
@change="chooseEnvGroup"
|
||||||
|
clearable>
|
||||||
|
<el-option-group v-for="group in groups" :key="group.label" :label="group.label">
|
||||||
|
<el-option
|
||||||
|
v-for="item in group.options"
|
||||||
|
:key="item.name"
|
||||||
|
:label="item.name"
|
||||||
|
:disabled="item.disabled"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-option-group>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<el-dialog :visible="visible" append-to-body :title="$t('workspace.env_group.name')" @close="visible = false"
|
||||||
|
style="height: 800px;">
|
||||||
|
<template>
|
||||||
|
<environment-group style="overflow-y: auto;"
|
||||||
|
:screen-height="'350px'"
|
||||||
|
:read-only="true"
|
||||||
|
></environment-group>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
<!-- 对环境组选项进行分类 可用|不可用 -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ENV_TYPE } from 'metersphere-frontend/src/utils/constants';
|
||||||
|
import { environmentGetALL,getEnvironmentOptions } from 'metersphere-frontend/src/api/environment';
|
||||||
|
import MsTag from 'metersphere-frontend/src/components/MsTag';
|
||||||
|
import { parseEnvironment } from 'metersphere-frontend/src/model/EnvironmentModel';
|
||||||
|
import { getEnvironments } from '@/api/environment';
|
||||||
|
import EnvironmentGroup from './common/EnvironmentGroupList';
|
||||||
|
import EnvGroupWithOption from "./common/EnvGroupWithOption";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'EnvSelectPopover',
|
||||||
|
components: { EnvironmentGroup,MsTag,EnvGroupWithOption},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
radio: this.environmentType,
|
||||||
|
visible: false,
|
||||||
|
groups: [],
|
||||||
|
disabledGroups: [],
|
||||||
|
notDisabledGroups: [],
|
||||||
|
selectedEnvName: new Map(),
|
||||||
|
showEnvName: false,
|
||||||
|
eventData: [],
|
||||||
|
evnList: [],
|
||||||
|
selectEnvMap: new Map(),
|
||||||
|
envGroupId: this.groupId,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
ENV_TYPE() {
|
||||||
|
return ENV_TYPE;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
projectIds: Set,
|
||||||
|
projectList: Array,
|
||||||
|
projectEnvMap: Object,
|
||||||
|
caseIdEnvNameMap: Object,
|
||||||
|
envMap: Map,
|
||||||
|
environmentType: String,
|
||||||
|
groupId: {
|
||||||
|
type: String,
|
||||||
|
default() {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
isScenario: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
hasOptionGroup: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
btnStyle: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return { width: '360px' };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
groupId(val) {
|
||||||
|
this.envGroupId = val;
|
||||||
|
},
|
||||||
|
environmentType(val) {
|
||||||
|
this.radio = val;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open() {
|
||||||
|
this.envGroupId = this.groupId;
|
||||||
|
this.initDefaultEnv();
|
||||||
|
this.getgroups();
|
||||||
|
},
|
||||||
|
chooseEnvGroup(envGroupId){
|
||||||
|
this.$emit("setEnvGroup", envGroupId);
|
||||||
|
},
|
||||||
|
radioChange(val) {
|
||||||
|
this.$emit('update:environmentType', val);
|
||||||
|
},
|
||||||
|
getProjectName(id) {
|
||||||
|
const project = this.projectList.find((p) => p.id === id);
|
||||||
|
return project ? project.name : '';
|
||||||
|
},
|
||||||
|
envRadioChange(val, index) {
|
||||||
|
this.eventData[index].envRadio = val;
|
||||||
|
this.eventData[index].showEnvSelect = this.eventData[index].envRadio === 'CUSTOMIZE_ENV';
|
||||||
|
},
|
||||||
|
viewGroup() {
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
getgroups() {
|
||||||
|
if (this.hasOptionGroup) {
|
||||||
|
getEnvironmentOptions({
|
||||||
|
projectIds: [...this.projectIds],
|
||||||
|
}).then((res) => {
|
||||||
|
let groups = res.data;
|
||||||
|
this.disabledGroups = groups.filter((group) => group.disabled === true);
|
||||||
|
this.notDisabledGroups = groups.filter((group) => group.disabled === false);
|
||||||
|
this.$set(this.groups, 0, {
|
||||||
|
label: this.$t('workspace.env_group.available_group'),
|
||||||
|
options: this.notDisabledGroups,
|
||||||
|
});
|
||||||
|
this.$set(this.groups, 1, {
|
||||||
|
label: this.$t('workspace.env_group.not_available_group'),
|
||||||
|
options: this.disabledGroups,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
environmentGetALL().then((res) => {
|
||||||
|
let data = res.data;
|
||||||
|
this.groups = data ? data : [];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
chooseEnv(val) {
|
||||||
|
let filter = this.evnList.filter((e) => e.id === val);
|
||||||
|
this.selectEnvMap.set(filter[0].projectId, val);
|
||||||
|
this.$emit('setProjectEnvMap', this.selectEnvMap);
|
||||||
|
},
|
||||||
|
initDefaultEnv() {
|
||||||
|
this.selectedEnvName = new Map();
|
||||||
|
this.evnList = [];
|
||||||
|
this.projectIds.forEach((d) => {
|
||||||
|
let item = {
|
||||||
|
id: d,
|
||||||
|
envs: [],
|
||||||
|
selectEnv: '',
|
||||||
|
envRadio: 'DEFAULT_ENV',
|
||||||
|
showEnvSelect: false,
|
||||||
|
expendStatus: 'open',
|
||||||
|
};
|
||||||
|
this.eventData.push(item);
|
||||||
|
getEnvironments(d).then((res) => {
|
||||||
|
let envs = res.data;
|
||||||
|
envs.forEach((environment) => {
|
||||||
|
parseEnvironment(environment);
|
||||||
|
});
|
||||||
|
// 固定环境列表渲染顺序
|
||||||
|
let temp = this.eventData.find((dt) => dt.id === d);
|
||||||
|
temp.envs = envs;
|
||||||
|
envs.forEach((t) => {
|
||||||
|
this.evnList.push(t);
|
||||||
|
});
|
||||||
|
if (this.envMap && this.envMap.size > 0) {
|
||||||
|
let envId = this.envMap.get(id);
|
||||||
|
// 选中环境是否存在
|
||||||
|
temp.selectEnv = envs.filter((e) => e.id === envId).length === 0 ? null : envId;
|
||||||
|
}
|
||||||
|
if (this.isScenario) {
|
||||||
|
if (this.projectEnvMap) {
|
||||||
|
let projectEnvMapElement = this.projectEnvMap[d];
|
||||||
|
if (projectEnvMapElement && projectEnvMapElement.length > 0) {
|
||||||
|
projectEnvMapElement.forEach((envId) => {
|
||||||
|
let filter = envs.filter((e) => e.id === envId);
|
||||||
|
if (!this.selectedEnvName.has(d)) {
|
||||||
|
let name = [];
|
||||||
|
name.push(filter[0].name);
|
||||||
|
this.selectedEnvName.set(d, name);
|
||||||
|
} else {
|
||||||
|
this.selectedEnvName.get(d).push(filter[0].name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.caseIdEnvNameMap) {
|
||||||
|
let envName = new Set();
|
||||||
|
for (let key in this.caseIdEnvNameMap) {
|
||||||
|
envName.add(this.caseIdEnvNameMap[key]);
|
||||||
|
}
|
||||||
|
this.selectedEnvName.set(d, envName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
expandCard(index) {
|
||||||
|
if (this.eventData[index].expendStatus === 'open') {
|
||||||
|
this.eventData[index].expendStatus = 'close';
|
||||||
|
} else {
|
||||||
|
this.eventData[index].expendStatus = 'open';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.mode-span {
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.radio-change:deep(.el-radio__input.is-checked + .el-radio__label) {
|
||||||
|
color: #606266 !important;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,119 @@
|
||||||
|
<template>
|
||||||
|
<div v-loading="result">
|
||||||
|
<el-dialog
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:title="title"
|
||||||
|
:visible.sync="createVisible"
|
||||||
|
destroy-on-close
|
||||||
|
@close="handleClose"
|
||||||
|
width="60%">
|
||||||
|
<el-form :model="form" :rules="rules" ref="form" label-position="right" label-width="90px" size="small">
|
||||||
|
<el-form-item :label="$t('commons.name')" prop="name">
|
||||||
|
<el-input v-model="form.name" autocomplete="off" show-word-limit maxlength="50"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item :label="$t('commons.description')" prop="description">
|
||||||
|
<el-input
|
||||||
|
v-model="form.description"
|
||||||
|
autocomplete="off"
|
||||||
|
type="textarea"
|
||||||
|
show-word-limit
|
||||||
|
maxlength="200"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<environment-group-row
|
||||||
|
ref="environmentGroupRow"
|
||||||
|
:env-group-id="environmentId"
|
||||||
|
:read-only="false"
|
||||||
|
:show-save-btn="true" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template v-slot:footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<ms-dialog-footer btn-size="medium" @cancel="createVisible = false" @confirm="submit('form')" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { addGroupEnvironment } from 'metersphere-frontend/src/api/environment';
|
||||||
|
import MsDialogFooter from 'metersphere-frontend/src/components/MsDialogFooter';
|
||||||
|
import EnvironmentGroupRow from './EnvironmentGroupRow';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'EditEnvironmentGroup',
|
||||||
|
components: {
|
||||||
|
EnvironmentGroupRow,
|
||||||
|
MsDialogFooter,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
title: this.$t('workspace.env_group.create'),
|
||||||
|
form: {},
|
||||||
|
createVisible: false,
|
||||||
|
rules: {
|
||||||
|
name: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: this.$t('api_test.environment.please_input_env_group_name'),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
min: 1,
|
||||||
|
max: 50,
|
||||||
|
message: this.$t('commons.input_limit', [1, 50]),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
description: [
|
||||||
|
{
|
||||||
|
max: 200,
|
||||||
|
message: this.$t('commons.input_limit', [0, 200]),
|
||||||
|
trigger: 'blur',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
environmentGroup: {},
|
||||||
|
environmentId: '',
|
||||||
|
result: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleClose() {},
|
||||||
|
submit() {
|
||||||
|
this.$refs['form'].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
let sign = this.$refs.environmentGroupRow.valid();
|
||||||
|
if (!sign) {
|
||||||
|
this.$warning(this.$t('workspace.env_group.not_intact'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let envGroupProject = this.$refs.environmentGroupRow.envGroupProject;
|
||||||
|
let param = {
|
||||||
|
envGroupProject,
|
||||||
|
name: this.form.name,
|
||||||
|
description: this.form.description,
|
||||||
|
};
|
||||||
|
this.result = addGroupEnvironment(param).then(() => {
|
||||||
|
this.$success(this.$t('commons.save_success'));
|
||||||
|
this.createVisible = false;
|
||||||
|
this.$emit('refresh');
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
open() {
|
||||||
|
this.createVisible = true;
|
||||||
|
this.form = {
|
||||||
|
name: '',
|
||||||
|
description: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,148 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div style="margin-left: 20px">
|
||||||
|
<el-select
|
||||||
|
v-model="envGroupId"
|
||||||
|
:placeholder="$t('workspace.env_group.select')"
|
||||||
|
style="margin-top: 8px; width: 200px"
|
||||||
|
size="small"
|
||||||
|
clearable>
|
||||||
|
<el-option-group v-for="group in groups" :key="group.label" :label="group.label">
|
||||||
|
<el-option
|
||||||
|
v-for="item in group.options"
|
||||||
|
:key="item.name"
|
||||||
|
:label="item.name"
|
||||||
|
:disabled="item.disabled"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-option-group>
|
||||||
|
</el-select>
|
||||||
|
<span style="margin-left: 8px">{{ $t('workspace.env_group.name') }}</span>
|
||||||
|
<i class="el-icon-view icon-view-btn" @click="viewGroup"></i>
|
||||||
|
</div>
|
||||||
|
<el-button type="primary" @click="handleConfirm" size="small" class="env-confirm">
|
||||||
|
{{ $t('workspace.env_group.confirm') }}
|
||||||
|
</el-button>
|
||||||
|
<el-dialog
|
||||||
|
:visible="visible"
|
||||||
|
append-to-body
|
||||||
|
:title="$t('workspace.env_group.name')"
|
||||||
|
@close="visible = false"
|
||||||
|
style="height: 800px">
|
||||||
|
<template>
|
||||||
|
<environment-group style="overflow-y: auto" :screen-height="'350px'" :read-only="true"></environment-group>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import EnvironmentGroup from './EnvironmentGroupList';
|
||||||
|
import { getEnvironmentMapByGroupId, getEnvironmentOptions } from 'metersphere-frontend/src/api/environment';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'EnvGroupWithOption',
|
||||||
|
components: { EnvironmentGroup },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
groups: [],
|
||||||
|
envGroupId: this.groupId,
|
||||||
|
visible: false,
|
||||||
|
disabledGroups: [],
|
||||||
|
notDisabledGroups: [],
|
||||||
|
result: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
groupId: {
|
||||||
|
type: String,
|
||||||
|
default() {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
projectIds: Set,
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
groupId(val) {
|
||||||
|
this.envGroupId = val;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open() {
|
||||||
|
this.envGroupId = this.groupId;
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.result = getEnvironmentOptions({
|
||||||
|
projectIds: [...this.projectIds],
|
||||||
|
}).then((res) => {
|
||||||
|
let groups = res.data;
|
||||||
|
this.disabledGroups = groups.filter((group) => group.disabled === true);
|
||||||
|
this.notDisabledGroups = groups.filter((group) => group.disabled === false);
|
||||||
|
this.$set(this.groups, 0, {
|
||||||
|
label: this.$t('workspace.env_group.available_group'),
|
||||||
|
options: this.notDisabledGroups,
|
||||||
|
});
|
||||||
|
this.$set(this.groups, 1, {
|
||||||
|
label: this.$t('workspace.env_group.not_available_group'),
|
||||||
|
options: this.disabledGroups,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
viewGroup() {
|
||||||
|
this.visible = true;
|
||||||
|
},
|
||||||
|
async handleConfirm() {
|
||||||
|
const sign = await this.checkEnv();
|
||||||
|
if (sign) {
|
||||||
|
this.$emit('setEnvGroup', this.envGroupId);
|
||||||
|
this.$emit('close');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
checkEnv() {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (!this.envGroupId) {
|
||||||
|
this.$warning(this.$t('workspace.env_group.select'));
|
||||||
|
resolve(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
getEnvironmentMapByGroupId(this.envGroupId).then((res) => {
|
||||||
|
let data = res.data;
|
||||||
|
if (!data) {
|
||||||
|
this.$warning(this.$t('workspace.env_group.lack_env'));
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let map = new Map(Object.entries(data));
|
||||||
|
for (let id of this.projectIds) {
|
||||||
|
if (!map.get(id)) {
|
||||||
|
this.$warning(this.$t('workspace.env_group.lack_necessary_environment'));
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.env-confirm {
|
||||||
|
margin-left: 20px;
|
||||||
|
width: 360px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-view-btn {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-view-btn:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,206 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-card class="table-card" v-loading="result">
|
||||||
|
<template v-slot:header>
|
||||||
|
<ms-table-header
|
||||||
|
:create-tip="btnTips"
|
||||||
|
:condition.sync="condition"
|
||||||
|
:show-create="!readOnly"
|
||||||
|
@search="search"
|
||||||
|
@create="createEnvironment"
|
||||||
|
:create-permission="['WORKSPACE_PROJECT_ENVIRONMENT:READ+CREATE_GROUP']">
|
||||||
|
</ms-table-header>
|
||||||
|
</template>
|
||||||
|
<el-table
|
||||||
|
:data="environmentGroupList"
|
||||||
|
style="width: 100%"
|
||||||
|
ref="table"
|
||||||
|
row-key="id"
|
||||||
|
@expand-change="expandChange"
|
||||||
|
:height="screenHeight">
|
||||||
|
<el-table-column type="expand" prop="id">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<environment-group-row
|
||||||
|
:env-group-id="scope.row.id"
|
||||||
|
ref="environmentGroupRow"
|
||||||
|
:read-only="!scope.row.readOnly"
|
||||||
|
style="overflow-x: hidden; overflow-y: auto; height: 180px" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('commons.name')" prop="name" show-overflow-tooltip min-width="200">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span @click.stop v-if="scope.row.showNameInput">
|
||||||
|
<el-input
|
||||||
|
size="mini"
|
||||||
|
v-model="scope.row.name"
|
||||||
|
class="name-input"
|
||||||
|
@blur="updateGroupName(scope.row)"
|
||||||
|
show-word-limit
|
||||||
|
maxlength="50"
|
||||||
|
:placeholder="$t('commons.input_name')"
|
||||||
|
ref="nameEdit" />
|
||||||
|
</span>
|
||||||
|
<span v-else>
|
||||||
|
<span>{{ scope.row.name }}</span>
|
||||||
|
<i
|
||||||
|
class="el-icon-edit"
|
||||||
|
style="cursor: pointer; margin-left: 4px"
|
||||||
|
@click="editName(scope.row)"
|
||||||
|
v-permission="['WORKSPACE_PROJECT_ENVIRONMENT:READ+EDIT_GROUP']" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createTime" :label="$t('commons.create_time')" min-width="200">
|
||||||
|
<template v-slot:default="scope">
|
||||||
|
<span>{{ scope.row.createTime | datetimeFormat }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<ms-table-pagination :change="init" :current-page.sync="currentPage" :page-size.sync="pageSize" :total="total" />
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<edit-environment-group ref="editEnvironmentGroup" @refresh="init" />
|
||||||
|
<ms-delete-confirm :title="$t('workspace.env_group.delete')" @delete="_handleDelete" ref="deleteConfirm" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
copyEnvironment,
|
||||||
|
delEnvironment,
|
||||||
|
envGroupList,
|
||||||
|
environmentGroupModify,
|
||||||
|
} from 'metersphere-frontend/src/api/environment';
|
||||||
|
import MsTableHeader from 'metersphere-frontend/src/components/MsTableHeader';
|
||||||
|
import MsTableButton from 'metersphere-frontend/src/components/MsTableButton';
|
||||||
|
import MsTableOperator from 'metersphere-frontend/src/components/MsTableOperator';
|
||||||
|
import MsTableOperatorButton from 'metersphere-frontend/src/components/MsTableOperatorButton';
|
||||||
|
import MsTablePagination from 'metersphere-frontend/src/components/pagination/TablePagination';
|
||||||
|
import ApiEnvironmentConfig from 'metersphere-frontend/src/components/environment/ApiEnvironmentConfig';
|
||||||
|
import MsAsideItem from 'metersphere-frontend/src/components/MsAsideItem';
|
||||||
|
import MsAsideContainer from 'metersphere-frontend/src/components/MsAsideContainer';
|
||||||
|
import ProjectSwitch from 'metersphere-frontend/src/components/head/ProjectSwitch';
|
||||||
|
import EnvironmentGroupRow from './EnvironmentGroupRow';
|
||||||
|
import EditEnvironmentGroup from './EditEnvironmentGroup';
|
||||||
|
import MsDeleteConfirm from 'metersphere-frontend/src/components/MsDeleteConfirm';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'EnvironmentGroup',
|
||||||
|
components: {
|
||||||
|
EditEnvironmentGroup,
|
||||||
|
ProjectSwitch,
|
||||||
|
MsAsideContainer,
|
||||||
|
MsAsideItem,
|
||||||
|
ApiEnvironmentConfig,
|
||||||
|
MsTablePagination,
|
||||||
|
MsTableOperatorButton,
|
||||||
|
MsTableOperator,
|
||||||
|
MsTableButton,
|
||||||
|
MsTableHeader,
|
||||||
|
EnvironmentGroupRow,
|
||||||
|
MsDeleteConfirm,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
btnTips: this.$t('workspace.env_group.create'),
|
||||||
|
envGroupId: '',
|
||||||
|
condition: {},
|
||||||
|
environmentGroupList: [],
|
||||||
|
result: false,
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
showNameInput: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
screenHeight: {
|
||||||
|
type: String,
|
||||||
|
default() {
|
||||||
|
return 'calc(100vh - 170px)';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
readOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
activated() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init() {
|
||||||
|
this.result = envGroupList(this.currentPage, this.pageSize, this.condition).then((res) => {
|
||||||
|
let data = res.data;
|
||||||
|
let { listObject, itemCount } = data;
|
||||||
|
this.environmentGroupList = listObject;
|
||||||
|
this.total = itemCount;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
createEnvironment() {
|
||||||
|
this.$refs.editEnvironmentGroup.open();
|
||||||
|
},
|
||||||
|
editEnvironment(row) {
|
||||||
|
this.$refs.table.toggleRowExpansion(row, true);
|
||||||
|
this.$set(row, 'readOnly', true);
|
||||||
|
},
|
||||||
|
deleteEnvironment(row) {
|
||||||
|
if (row.system) {
|
||||||
|
this.$warning(this.$t('group.admin_not_allow_delete'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$refs.deleteConfirm.open(row);
|
||||||
|
},
|
||||||
|
copyEnvironment(row) {
|
||||||
|
if (row && row.id) {
|
||||||
|
copyEnvironment(row.id).then(() => {
|
||||||
|
this.$success(this.$t('commons.copy_success'));
|
||||||
|
this.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
search() {
|
||||||
|
this.init();
|
||||||
|
},
|
||||||
|
_handleDelete(row) {
|
||||||
|
delEnvironment(row.id).then(() => {
|
||||||
|
this.$success(this.$t('commons.delete_success'));
|
||||||
|
this.init();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
expandChange(row, expanded) {
|
||||||
|
if (expanded) {
|
||||||
|
this.$set(row, 'readOnly', false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
editName(row) {
|
||||||
|
this.$set(row, 'showNameInput', true);
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.nameEdit.focus();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateGroupName(row) {
|
||||||
|
if (!row || !row.id || !row.name) {
|
||||||
|
this.init();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let param = {
|
||||||
|
id: row.id,
|
||||||
|
name: row.name,
|
||||||
|
workspaceId: row.workspaceId,
|
||||||
|
};
|
||||||
|
environmentGroupModify(param).then(() => {
|
||||||
|
this.$success(this.$t('commons.modify_success'));
|
||||||
|
this.init();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
|
@ -0,0 +1,453 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="btn-div">
|
||||||
|
<el-button size="mini" type="primary" class="save-btn" v-if="!rowReadOnly && !showSaveBtn" @click="update">
|
||||||
|
{{ $t('commons.save') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div v-loading="result" class="group-row">
|
||||||
|
<el-form class="row-form">
|
||||||
|
<el-form-item v-for="(item, index) in envGroupProject" :key="index">
|
||||||
|
<el-row type="flex" justify="space-between" :gutter="10">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-select
|
||||||
|
v-model="item.projectId"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
style="width: 100%"
|
||||||
|
@change="projectChange(item)"
|
||||||
|
:size="itemSize"
|
||||||
|
@clear="clearProjectSelect"
|
||||||
|
:placeholder="$t('workspace.env_group.please_select_project')"
|
||||||
|
:disabled="rowReadOnly">
|
||||||
|
<el-option
|
||||||
|
v-for="(project, projectIndex) in projectList"
|
||||||
|
:key="projectIndex"
|
||||||
|
:label="project.name"
|
||||||
|
:disabled="project.disabled"
|
||||||
|
:value="project.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-select
|
||||||
|
v-model="item.environmentId"
|
||||||
|
filterable
|
||||||
|
clearable
|
||||||
|
style="width: 100%"
|
||||||
|
@change="environmentChange(item)"
|
||||||
|
:size="itemSize"
|
||||||
|
:placeholder="$t('workspace.env_group.please_select_env')"
|
||||||
|
:disabled="rowReadOnly">
|
||||||
|
<el-option
|
||||||
|
v-for="(environment, envIndex) in item.environments"
|
||||||
|
:key="envIndex"
|
||||||
|
:label="environment.name"
|
||||||
|
:value="environment.id"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="4">
|
||||||
|
<el-button
|
||||||
|
:size="itemSize"
|
||||||
|
icon="el-icon-s-data"
|
||||||
|
style="width: 100%"
|
||||||
|
@click="showDomainInfo(item)"
|
||||||
|
v-if="item.moreDomain">
|
||||||
|
{{ $t('workspace.env_group.view_details') }}
|
||||||
|
</el-button>
|
||||||
|
<el-input v-else v-model="item.domainName" :disabled="true" :size="itemSize" />
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="5">
|
||||||
|
<el-input
|
||||||
|
prop="description"
|
||||||
|
show-overflow-tooltip
|
||||||
|
:placeholder="$t('commons.description')"
|
||||||
|
maxlength="100"
|
||||||
|
v-model="item.domainDescription"
|
||||||
|
show-word-limit
|
||||||
|
:size="itemSize"
|
||||||
|
:disabled="true" />
|
||||||
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="3">
|
||||||
|
<el-button
|
||||||
|
type="info"
|
||||||
|
icon="el-icon-plus"
|
||||||
|
circle
|
||||||
|
:size="itemSize"
|
||||||
|
:disabled="rowReadOnly"
|
||||||
|
@click="change"></el-button>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
circle
|
||||||
|
:size="itemSize"
|
||||||
|
:disabled="rowReadOnly"
|
||||||
|
@click="remove(index)"></el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<el-dialog :title="$t('workspace.env_group.domain_list')" :visible.sync="domainVisible" append-to-body>
|
||||||
|
<el-table :data="conditions">
|
||||||
|
<el-table-column prop="socket" :label="$t('load_test.domain')" show-overflow-tooltip width="180">
|
||||||
|
<template v-slot:default="{ row }">
|
||||||
|
{{ row.conditionType ? row.server : getUrl(row) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column :label="$t('commons.type')" show-overflow-tooltip min-width="100px">
|
||||||
|
<template v-slot:default="{ row }">
|
||||||
|
<el-tag type="info" size="mini">{{ row.conditionType ? row.conditionType : 'HTTP' }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="type"
|
||||||
|
:label="$t('api_test.environment.condition_enable')"
|
||||||
|
show-overflow-tooltip
|
||||||
|
min-width="100px">
|
||||||
|
<template v-slot:default="{ row }">
|
||||||
|
{{ row.conditionType ? '-' : getName(row) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="details" show-overflow-tooltip min-width="120px" :label="$t('api_test.value')">
|
||||||
|
<template v-slot:default="{ row }">
|
||||||
|
{{ row.conditionType ? '-' : getDetails(row) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="description"
|
||||||
|
show-overflow-tooltip
|
||||||
|
min-width="120px"
|
||||||
|
:label="$t('commons.description')">
|
||||||
|
<template v-slot:default="{ row }">
|
||||||
|
<span>{{ row.description ? row.description : '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="createTime" show-overflow-tooltip min-width="120px" :label="$t('commons.create_time')">
|
||||||
|
<template v-slot:default="{ row }">
|
||||||
|
<span v-if="!row.conditionType">{{ row.time | datetimeFormat }}</span>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="domainVisible = false" size="small">{{ $t('commons.cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="domainVisible = false" size="small">{{ $t('commons.confirm') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getAll } from '@/api/project';
|
||||||
|
import { environmentGroupList, getEnvironmentByProjectId } from 'metersphere-frontend/src/api/environment';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'EnvironmentGroupRow',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
result: false,
|
||||||
|
envGroupProject: [],
|
||||||
|
projectList: [],
|
||||||
|
environmentList: [],
|
||||||
|
environments: [],
|
||||||
|
domainVisible: false,
|
||||||
|
conditions: [],
|
||||||
|
rowReadOnly: this.readOnly,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
readOnly: {
|
||||||
|
handler(v) {
|
||||||
|
this.rowReadOnly = v;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
envGroupId: {
|
||||||
|
type: String,
|
||||||
|
default() {
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
readOnly: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
itemSize: {
|
||||||
|
type: String,
|
||||||
|
default() {
|
||||||
|
return 'mini';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
showSaveBtn: {
|
||||||
|
type: Boolean,
|
||||||
|
default() {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getEnvironmentGroupProject();
|
||||||
|
this.getProjects();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
projectChange(item) {
|
||||||
|
if (item && item.projectId) {
|
||||||
|
let project = this.projectList.find((project) => project.id === item.projectId);
|
||||||
|
if (project) {
|
||||||
|
project.disabled = true;
|
||||||
|
}
|
||||||
|
this.clearProjectSelect();
|
||||||
|
getEnvironmentByProjectId(this.projectId).then((res) => {
|
||||||
|
this.$set(item, 'environments', res.data);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$set(item, 'environments', []);
|
||||||
|
}
|
||||||
|
this.$set(item, 'environmentId', '');
|
||||||
|
this.$set(item, 'domainName', '');
|
||||||
|
},
|
||||||
|
clearProjectSelect() {
|
||||||
|
let usedProjectId = this.envGroupProject.map((egp) => egp.projectId);
|
||||||
|
if (usedProjectId) {
|
||||||
|
this.projectList.forEach((p) => {
|
||||||
|
p.disabled = !!usedProjectId.find((id) => id === p.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
environmentChange(item) {
|
||||||
|
// todo 优化
|
||||||
|
// 环境改变时初始化判断状态
|
||||||
|
this.$set(item, 'moreDomain', false);
|
||||||
|
this.$set(item, 'domainName', '');
|
||||||
|
this.$set(item, 'domainDescription', '');
|
||||||
|
let environments = item.environments;
|
||||||
|
let index = environments.findIndex((e) => e.id === item.environmentId);
|
||||||
|
if (index === -1) {
|
||||||
|
this.$set(item, 'domainName', '');
|
||||||
|
this.$set(item, 'domainDescription', '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let environment = environments[index].config;
|
||||||
|
if (environment) {
|
||||||
|
const config = JSON.parse(environment);
|
||||||
|
if (config.httpConfig && !config.httpConfig.conditions) {
|
||||||
|
if (config.httpConfig.protocol && config.httpConfig.domain) {
|
||||||
|
let domain = config.httpConfig.protocol + '://' + config.httpConfig.domain;
|
||||||
|
this.$set(item, 'domainName', domain);
|
||||||
|
this.$set(item, 'domainDescription', config.httpConfig.description ? config.httpConfig.description : '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (config.httpConfig.conditions.length === 1) {
|
||||||
|
if (config.tcpConfig && config.tcpConfig.server) {
|
||||||
|
this.$set(item, 'moreDomain', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let obj = config.httpConfig.conditions[0];
|
||||||
|
if (obj.protocol && obj.socket) {
|
||||||
|
this.$set(item, 'domainName', obj.protocol + '://' + obj.socket);
|
||||||
|
this.$set(item, 'domainDescription', obj.description ? obj.description : '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (config.httpConfig.conditions.length > 1) {
|
||||||
|
this.$set(item, 'moreDomain', true);
|
||||||
|
return;
|
||||||
|
} else if (config.tcpConfig && config.tcpConfig.server) {
|
||||||
|
this.$set(item, 'domainName', config.tcpConfig.server);
|
||||||
|
this.$set(item, 'domainDescription', config.tcpConfig.description);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$set(item, 'domainName', environment.protocol + '://' + environment.domain);
|
||||||
|
this.$set(item, 'domainDescription', environment.description ? environment.description : '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$set(item, 'domainName', '');
|
||||||
|
this.$set(item, 'domainDescription', '');
|
||||||
|
},
|
||||||
|
showDomainInfo(item) {
|
||||||
|
const index = item.environments.findIndex((e) => e.id === item.environmentId);
|
||||||
|
if (index === -1) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
let environment = item.environments[index];
|
||||||
|
const config = JSON.parse(environment.config);
|
||||||
|
this.conditions = config.httpConfig.conditions;
|
||||||
|
if (config.tcpConfig && config.tcpConfig.server) {
|
||||||
|
let condition = {
|
||||||
|
conditionType: 'TCP',
|
||||||
|
server: config.tcpConfig.server,
|
||||||
|
description: config.tcpConfig.description,
|
||||||
|
};
|
||||||
|
this.conditions.push(condition);
|
||||||
|
}
|
||||||
|
this.domainVisible = true;
|
||||||
|
},
|
||||||
|
getProjects() {
|
||||||
|
// 工作空间下项目
|
||||||
|
getAll().then((response) => {
|
||||||
|
let data = response.data;
|
||||||
|
if (data) {
|
||||||
|
this.projectList = data;
|
||||||
|
this.projectList.forEach((project) => {
|
||||||
|
this.$set(project, 'disabled', false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getEnvironmentGroupProject() {
|
||||||
|
if (!this.envGroupId) {
|
||||||
|
this.envGroupProject = [{}];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.result = environmentGroupList(this.envGroupId).then((response) => {
|
||||||
|
this.envGroupProject = response.data;
|
||||||
|
if (this.envGroupProject) {
|
||||||
|
// 初始化环境数据
|
||||||
|
this.envGroupProject.forEach((env) => {
|
||||||
|
this.disabledOption(env.projectId, true);
|
||||||
|
this._parseDomainName(env);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.envGroupProject.length < 1) {
|
||||||
|
this.envGroupProject.push({});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_parseDomainName(item) {
|
||||||
|
let { environmentId } = item;
|
||||||
|
const index = item.environments.findIndex((e) => e.id === environmentId);
|
||||||
|
if (index === -1) {
|
||||||
|
this.$set(item, 'domainName', '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let environment = item.environments[index].config;
|
||||||
|
if (environment) {
|
||||||
|
const config = JSON.parse(environment);
|
||||||
|
if (config.httpConfig && !config.httpConfig.conditions) {
|
||||||
|
if (config.httpConfig.protocol && config.httpConfig.domain) {
|
||||||
|
let domain = config.httpConfig.protocol + '://' + config.httpConfig.domain;
|
||||||
|
this.$set(item, 'domainName', domain);
|
||||||
|
this.$set(item, 'domainDescription', config.httpConfig.description ? config.httpConfig.description : '');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (config.httpConfig.conditions.length === 1) {
|
||||||
|
if (config.tcpConfig && config.tcpConfig.server) {
|
||||||
|
this.$set(item, 'moreDomain', true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let obj = config.httpConfig.conditions[0];
|
||||||
|
if (obj.protocol && obj.socket) {
|
||||||
|
this.$set(item, 'domainName', obj.protocol + '://' + obj.socket);
|
||||||
|
this.$set(item, 'domainDescription', obj.description ? obj.description : '');
|
||||||
|
}
|
||||||
|
} else if (config.httpConfig.conditions.length > 1) {
|
||||||
|
this.$set(item, 'moreDomain', true);
|
||||||
|
return;
|
||||||
|
} else if (config.tcpConfig && config.tcpConfig.server) {
|
||||||
|
this.$set(item, 'domainName', config.tcpConfig.server);
|
||||||
|
this.$set(item, 'domainDescription', config.tcpConfig.description);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$set(item, 'domainName', environment.protocol + '://' + environment.domain);
|
||||||
|
this.$set(item, 'domainDescription', environment.description ? environment.description : '');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getName(row) {
|
||||||
|
switch (row.type) {
|
||||||
|
case 'NONE':
|
||||||
|
return this.$t('api_test.definition.document.data_set.none');
|
||||||
|
case 'MODULE':
|
||||||
|
return this.$t('test_track.module.module');
|
||||||
|
case 'PATH':
|
||||||
|
return this.$t('api_test.definition.api_path');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getUrl(row) {
|
||||||
|
return row.protocol + '://' + row.socket;
|
||||||
|
},
|
||||||
|
getDetails(row) {
|
||||||
|
if (row && row.type === 'MODULE') {
|
||||||
|
if (row.details && row.details instanceof Array) {
|
||||||
|
let value = '';
|
||||||
|
row.details.forEach((item) => {
|
||||||
|
value += item.name + ',';
|
||||||
|
});
|
||||||
|
if (value.endsWith(',')) {
|
||||||
|
value = value.substr(0, value.length - 1);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
} else if (row && row.type === 'PATH' && row.details.length > 0 && row.details[0].name) {
|
||||||
|
return row.details[0].value === 'equals'
|
||||||
|
? this.$t('commons.adv_search.operators.equals') + row.details[0].name
|
||||||
|
: this.$t('api_test.request.assertions.contains') + row.details[0].name;
|
||||||
|
} else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove(index) {},
|
||||||
|
disabledOption(projectId, sign) {
|
||||||
|
let project = this.projectList.find((project) => project.id === projectId);
|
||||||
|
if (project) {
|
||||||
|
project.disabled = sign;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
change() {
|
||||||
|
let isNeedCreate = true;
|
||||||
|
let removeIndex = -1;
|
||||||
|
this.envGroupProject.forEach((item, index) => {
|
||||||
|
if (!item.projectId && !item.environmentId) {
|
||||||
|
// 多余的空行
|
||||||
|
if (index !== this.envGroupProject.length - 1) {
|
||||||
|
removeIndex = index;
|
||||||
|
}
|
||||||
|
// 没有空行,需要创建空行
|
||||||
|
isNeedCreate = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (isNeedCreate) {
|
||||||
|
this.envGroupProject.push({});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
update() {},
|
||||||
|
valid() {
|
||||||
|
if (this.envGroupProject) {
|
||||||
|
for (let egp of this.envGroupProject) {
|
||||||
|
if (egp) {
|
||||||
|
let { projectId, environmentId, description } = egp;
|
||||||
|
let book = projectId ? environmentId : !description;
|
||||||
|
if (!book) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.row-form :deep(.el-form-item) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-div {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue