This commit is contained in:
chenjianxing 2020-06-23 13:09:58 +08:00
commit 4972b11b4b
13 changed files with 171 additions and 85 deletions

View File

@ -229,6 +229,7 @@ export class HTTPSamplerProxy extends DefaultTestElement {
this.stringProp("HTTPSampler.protocol", this.request.protocol.split(":")[0]);
this.stringProp("HTTPSampler.path", this.request.pathname);
this.stringProp("HTTPSampler.method", this.request.method);
this.stringProp("HTTPSampler.contentEncoding", this.request.encoding, "UTF-8");
if (!this.request.port) {
this.stringProp("HTTPSampler.port", "");
} else {

View File

@ -69,10 +69,11 @@
import MsTableHeader from "../common/components/MsTableHeader";
import MsTableOperator from "../common/components/MsTableOperator";
import MsDialogFooter from "../common/components/MsDialogFooter";
import {_sort, getCurrentUser} from "../../../common/js/utils";
import {_sort, getCurrentOrganizationId, getCurrentUser, refreshSessionAndCookies} from "../../../common/js/utils";
import MsContainer from "../common/components/MsContainer";
import MsMainContainer from "../common/components/MsMainContainer";
import MsDeleteConfirm from "../common/components/MsDeleteConfirm";
import {DEFAULT} from "../../../common/js/constants";
export default {
name: "MsProject",
@ -179,9 +180,20 @@
this.$refs.deleteConfirm.open(project);
},
_handleDelete(project) {
this.$get('/project/delete/' + project.id, () => {
Message.success(this.$t('commons.delete_success'));
this.list();
this.$confirm(this.$t('project.delete_tip'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.$get('/project/delete/' + project.id, () => {
Message.success(this.$t('commons.delete_success'));
this.list();
});
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('commons.delete_cancelled')
});
});
},
search() {

View File

@ -15,7 +15,7 @@
<ms-roles-tag :roles="scope.row.roles"/>
</template>
</el-table-column>
<el-table-column>
<el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator :tip2="$t('commons.remove')" @editClick="edit(scope.row)" @deleteClick="del(scope.row)"/>
</template>

View File

@ -14,7 +14,7 @@
</el-button>
</template>
</el-table-column>
<el-table-column>
<el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator @editClick="edit(scope.row)" @deleteClick="handleDelete(scope.row)"/>
</template>
@ -159,7 +159,12 @@
import MsTableOperator from "../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
import MsDialogFooter from "../../common/components/MsDialogFooter";
import {getCurrentUser, getCurrentWorkspaceId, refreshSessionAndCookies} from "../../../../common/js/utils";
import {
getCurrentOrganizationId,
getCurrentUser,
getCurrentWorkspaceId,
refreshSessionAndCookies
} from "../../../../common/js/utils";
import MsDeleteConfirm from "../../common/components/MsDeleteConfirm";
export default {
@ -212,16 +217,28 @@
this.$refs.deleteConfirm.open(workspace);
},
_handleDelete(workspace) {
this.$get('/workspace/delete/' + workspace.id, () => {
let lastWorkspaceId = getCurrentWorkspaceId();
let sourceId = workspace.id;
if (lastWorkspaceId === sourceId) {
let sign = DEFAULT;
refreshSessionAndCookies(sign, sourceId);
}
this.$success(this.$t('commons.delete_success'));
this.list();
this.$confirm(this.$t('organization.delete_confirm'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.$get('/workspace/delete/' + workspace.id, () => {
let lastWorkspaceId = getCurrentWorkspaceId();
let sourceId = workspace.id;
if (lastWorkspaceId === sourceId) {
let sign = DEFAULT;
refreshSessionAndCookies(sign, sourceId);
}
this.$success(this.$t('commons.delete_success'));
this.list();
});
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('commons.delete_cancelled')
});
});
},
list() {
let url = '/workspace/list/' + this.currentPage + '/' + this.pageSize;

View File

@ -318,18 +318,29 @@
});
},
handleDelete(organization) {
this.$refs.deleteConfirm.open(organization);
this.$refs.deleteConfirm.open(organization);
},
_handleDelete(organization) {
this.result = this.$get(this.deletePath + organization.id, () => {
let lastOrganizationId = getCurrentOrganizationId();
let sourceId = organization.id;
if (lastOrganizationId === sourceId) {
let sign = DEFAULT;
refreshSessionAndCookies(sign, sourceId);
}
this.$success(this.$t('commons.delete_success'));
this.initTableData();
this.$confirm(this.$t('organization.delete_confirm'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.result = this.$get(this.deletePath + organization.id, () => {
let lastOrganizationId = getCurrentOrganizationId();
let sourceId = organization.id;
if (lastOrganizationId === sourceId) {
let sign = DEFAULT;
refreshSessionAndCookies(sign, sourceId);
}
this.$success(this.$t('commons.delete_success'));
this.initTableData();
});
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('commons.delete_cancelled')
});
});
},
delMember(row) {

View File

@ -17,7 +17,7 @@
</el-button>
</template>
</el-table-column>
<el-table-column>
<el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator @editClick="edit(scope.row)" @deleteClick="handleDelete(scope.row)"/>
</template>
@ -199,7 +199,12 @@
import MsTableOperator from "../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
import MsDialogFooter from "../../common/components/MsDialogFooter";
import {getCurrentUser, getCurrentWorkspaceId, refreshSessionAndCookies} from "../../../../common/js/utils";
import {
getCurrentOrganizationId,
getCurrentUser,
getCurrentWorkspaceId,
refreshSessionAndCookies
} from "../../../../common/js/utils";
import {DEFAULT, WORKSPACE} from "../../../../common/js/constants";
import MsDeleteConfirm from "../../common/components/MsDeleteConfirm";
@ -373,15 +378,26 @@
this.$refs.deleteConfirm.open(workspace);
},
_handleDelete(workspace) {
this.$get('/workspace/special/delete/' + workspace.id, () => {
let lastWorkspaceId = getCurrentWorkspaceId();
let sourceId = workspace.id;
if (lastWorkspaceId === sourceId) {
let sign = DEFAULT;
refreshSessionAndCookies(sign, sourceId);
}
Message.success(this.$t('commons.delete_success'));
this.list();
this.$confirm(this.$t('workspace.delete_confirm'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.$get('/workspace/special/delete/' + workspace.id, () => {
let lastWorkspaceId = getCurrentWorkspaceId();
let sourceId = workspace.id;
if (lastWorkspaceId === sourceId) {
let sign = DEFAULT;
refreshSessionAndCookies(sign, sourceId);
}
Message.success(this.$t('commons.delete_success'));
this.list();
});
}).catch(() => {
this.$message({
type: 'info',
message: this.$t('commons.delete_cancelled')
});
});
},
delMember(row) {

View File

@ -34,7 +34,7 @@
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column>
<el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator @editClick="edit(scope.row)" @deleteClick="del(scope.row)"/>
</template>

View File

@ -15,7 +15,7 @@
<ms-roles-tag :roles="scope.row.roles" type="success"/>
</template>
</el-table-column>
<el-table-column>
<el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator :tip2="$t('commons.remove')" @editClick="edit(scope.row)" @deleteClick="del(scope.row)"
v-permission="['test_manager']"/>

View File

@ -2,8 +2,9 @@
<div>
<el-dialog :title="operationType == 'edit' ? ( readOnly ? $t('test_track.case.view_case') : $t('test_track.case.edit_case')) : $t('test_track.case.create')"
:visible.sync="dialogFormVisible" width="65%">
<el-dialog
:title="operationType == 'edit' ? ( readOnly ? $t('test_track.case.view_case') : $t('test_track.case.edit_case')) : $t('test_track.case.create')"
:visible.sync="dialogFormVisible" width="65%">
<el-form :model="form" :rules="rules" ref="caseFrom" v-loading="result.loading">
@ -39,7 +40,8 @@
<el-row>
<el-col :span="10" :offset="1">
<el-form-item :label="$t('test_track.case.maintainer')" :label-width="formLabelWidth" prop="maintainer">
<el-select :disabled="readOnly" v-model="form.maintainer" :placeholder="$t('test_track.case.input_maintainer')" filterable>
<el-select :disabled="readOnly" v-model="form.maintainer"
:placeholder="$t('test_track.case.input_maintainer')" filterable>
<el-option
v-for="item in maintainerOptions"
:key="item.id"
@ -51,7 +53,8 @@
</el-col>
<el-col :span="12">
<el-form-item :label="$t('test_track.case.priority')" :label-width="formLabelWidth" prop="priority">
<el-select :disabled="readOnly" v-model="form.priority" clearable :placeholder="$t('test_track.case.input_priority')">
<el-select :disabled="readOnly" v-model="form.priority" clearable
:placeholder="$t('test_track.case.input_priority')">
<el-option label="P0" value="P0"></el-option>
<el-option label="P1" value="P1"></el-option>
<el-option label="P2" value="P2"></el-option>
@ -64,7 +67,8 @@
<el-row>
<el-col :span="10" :offset="1">
<el-form-item :label="$t('test_track.case.type')" :label-width="formLabelWidth" prop="type">
<el-select @change="typeChange" :disabled="readOnly" v-model="form.type" :placeholder="$t('test_track.case.input_type')">
<el-select @change="typeChange" :disabled="readOnly" v-model="form.type"
:placeholder="$t('test_track.case.input_type')">
<el-option :label="$t('commons.functional')" value="functional"></el-option>
<el-option :label="$t('commons.performance')" value="performance"></el-option>
<el-option :label="$t('commons.api')" value="api"></el-option>
@ -88,7 +92,8 @@
<el-row v-if="form.method && form.method == 'auto'">
<el-col :span="10" :offset="1">
<el-form-item :label="$t('test_track.case.relate_test')" :label-width="formLabelWidth" prop="testId">
<el-select filterable :disabled="readOnly" v-model="form.testId" :placeholder="$t('test_track.case.input_type')">
<el-select filterable :disabled="readOnly" v-model="form.testId"
:placeholder="$t('test_track.case.input_type')">
<el-option
v-for="item in testOptions"
:key="item.id"
@ -126,7 +131,7 @@
class="tb-edit"
border
size="mini"
:default-sort = "{prop: 'num', order: 'ascending'}"
:default-sort="{prop: 'num', order: 'ascending'}"
highlight-current-row>
<el-table-column :label="$t('test_track.case.number')" prop="num" min-width="15%"></el-table-column>
<el-table-column :label="$t('test_track.case.step_desc')" prop="desc" min-width="35%">
@ -196,12 +201,12 @@
<template v-slot:footer>
<el-switch v-if="operationType == 'add'"
v-model="isCreateContinue"
:active-text="$t('test_track.case.save_create_continue')">
v-model="isCreateContinue"
:active-text="$t('test_track.case.save_create_continue')">
</el-switch>
<ms-dialog-footer v-if="!readOnly"
@cancel="dialogFormVisible = false"
@confirm="saveCase"/>
@cancel="dialogFormVisible = false"
@confirm="saveCase"/>
</template>
</el-dialog>
@ -234,7 +239,7 @@
prerequisite: '',
testId: '',
steps: [{
num: 1 ,
num: 1,
desc: '',
result: ''
}],
@ -245,19 +250,19 @@
methodOptions: [],
testOptions: [],
workspaceId: '',
rules:{
name :[
rules: {
name: [
{required: true, message: this.$t('test_track.case.input_name'), trigger: 'blur'},
{ max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur' }
{max: 30, message: this.$t('test_track.length_less_than') + '30', trigger: 'blur'}
],
module :[{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
maintainer :[{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
priority :[{required: true, message: this.$t('test_track.case.input_priority'), trigger: 'change'}],
type :[{required: true, message: this.$t('test_track.case.input_type'), trigger: 'change'}],
testId :[{required: true, message: '请选择测试', trigger: 'change'}],
method :[{required: true, message: this.$t('test_track.case.input_method'), trigger: 'change'}],
prerequisite :[{ max: 300, message: this.$t('test_track.length_less_than') + '300', trigger: 'blur'}],
remark :[{ max: 300, message: this.$t('test_track.length_less_than') + '300', trigger: 'blur'}]
module: [{required: true, message: this.$t('test_track.case.input_module'), trigger: 'change'}],
maintainer: [{required: true, message: this.$t('test_track.case.input_maintainer'), trigger: 'change'}],
priority: [{required: true, message: this.$t('test_track.case.input_priority'), trigger: 'change'}],
type: [{required: true, message: this.$t('test_track.case.input_type'), trigger: 'change'}],
testId: [{required: true, message: '请选择测试', trigger: 'change'}],
method: [{required: true, message: this.$t('test_track.case.input_method'), trigger: 'change'}],
prerequisite: [{max: 300, message: this.$t('test_track.length_less_than') + '300', trigger: 'blur'}],
remark: [{max: 300, message: this.$t('test_track.length_less_than') + '300', trigger: 'blur'}]
},
formLabelWidth: "120px",
operationType: '',
@ -327,8 +332,8 @@
step.desc = null;
step.result = null;
this.form.steps.forEach(step => {
if(step.num > data.num){
step.num ++;
if (step.num > data.num) {
step.num++;
}
});
this.form.steps.splice(index + 1, 0, step);
@ -336,12 +341,12 @@
handleDeleteStep(index, data) {
this.form.steps.splice(index, 1);
this.form.steps.forEach(step => {
if(step.num > data.num){
step.num --;
if (step.num > data.num) {
step.num--;
}
});
},
saveCase(){
saveCase() {
this.$refs['caseFrom'].validate((valid) => {
if (valid) {
let param = this.buildParam();
@ -350,6 +355,7 @@
this.$success(this.$t('commons.save_success'));
if (this.operationType == 'add' && this.isCreateContinue) {
this.form.name = '';
this.$emit("refresh");
return;
}
this.dialogFormVisible = false;
@ -367,7 +373,7 @@
param.steps = JSON.stringify(this.form.steps);
param.nodeId = this.form.module;
this.moduleOptions.forEach(item => {
if(this.form.module === item.id){
if (this.form.module === item.id) {
param.nodePath = item.path;
}
});
@ -381,11 +387,11 @@
return param;
},
validate(param) {
for (let i = 0; i < param.steps.length; i++){
for (let i = 0; i < param.steps.length; i++) {
if ((param.steps[i].desc && param.steps[i].desc.length > 300) ||
(param.steps[i].result && param.steps[i].result.length > 300)) {
this.$warning(this.$t('test_track.case.step_desc') + ","
+ this.$t('test_track.case.expected_results') + this.$t('test_track.length_less_than') + '300');
+ this.$t('test_track.case.expected_results') + this.$t('test_track.length_less_than') + '300');
return false;
}
}
@ -409,7 +415,7 @@
},
getMaintainerOptions() {
let workspaceId = localStorage.getItem(WORKSPACE_ID);
this.$post('/user/ws/member/tester/list', {workspaceId:workspaceId}, response => {
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
this.maintainerOptions = response.data;
});
},
@ -444,8 +450,8 @@
option.path = option.path + '/' + node.name;
moduleOptions.push(option);
if (node.children) {
for (let i = 0; i < node.children.length; i++){
this.buildNodePath(node.children[i], { path: option.path }, moduleOptions);
for (let i = 0; i < node.children.length; i++) {
this.buildNodePath(node.children[i], {path: option.path}, moduleOptions);
}
}
},
@ -464,7 +470,7 @@
this.form.remark = '';
this.form.testId = '';
this.form.steps = [{
num: 1 ,
num: 1,
desc: '',
result: ''
}];
@ -481,10 +487,12 @@
.tb-edit .el-textarea {
display: none;
}
.tb-edit .current-row .el-textarea {
display: block;
}
.tb-edit .current-row .el-textarea+span {
.tb-edit .current-row .el-textarea + span {
display: none;
}

View File

@ -9,8 +9,11 @@
<el-tree
class="filter-tree node-tree"
:data="treeNodes"
:default-expanded-keys="expandedNode"
node-key="id"
@node-drag-end="handleDragEnd"
@node-expand="nodeExpand"
@node-collapse="nodeCollapse"
:filter-node-method="filterNode"
:expand-on-click-node="false"
highlight-current
@ -64,6 +67,7 @@ export default {
data() {
return {
result: {},
expandedNode: [],
filterText: "",
defaultProps: {
children: "children",
@ -216,6 +220,12 @@ export default {
},
refreshNode() {
this.$emit("refresh");
},
nodeExpand(data) {
this.expandedNode.push(data.id);
},
nodeCollapse(data) {
this.expandedNode.splice(this.expandedNode.indexOf(data.id), 1);
}
}
};

View File

@ -1,5 +1,6 @@
export default {
commons: {
'delete_cancelled': 'Delete cancelled',
'workspace': 'Workspace',
'organization': 'Organization',
'setting': 'Setting',
@ -105,7 +106,7 @@ export default {
'create': 'Create Workspace',
'update': 'Update Workspace',
'delete': 'Delete Workspace',
'delete_confirm': 'Are you sure you want to delete this workspace?',
'delete_confirm': 'Deleting the workspace will delete all resources (such as related projects, test cases, etc.) under the workspace. Are you sure you want to delete?',
'add': 'Add Workspace',
'input_name': 'Please enter a workspace name',
'search_by_name': 'Search by name',
@ -115,18 +116,21 @@ export default {
'none': 'None Workspace',
'select': 'Select Workspace',
'special_characters_are_not_supported': 'Incorrect format (special characters are not supported and cannot end with \'-\')',
},
organization: {
'create': 'Create Organization',
'modify': 'Modify',
'delete': 'Delete Organization',
'delete_confirm': 'Are you sure you want to delete this workspace?',
'delete_confirm': 'Deleting this organization will delete all resources (such as related workspaces, projects, test cases, etc.) under this organization. Are you sure you want to delete?',
'input_name': 'Please enter a organization name',
'select_organization': 'Please select organization',
'search_by_name': 'Search by name',
'special_characters_are_not_supported': 'Incorrect format (special characters are not supported and cannot end with \'-\')',
'none': 'None Organization',
'select': 'Select Organization',
},
project: {
'name': 'Project name',
@ -134,8 +138,8 @@ export default {
'create': 'Create Project',
'edit': 'Edit Project',
'delete': 'Delete project',
'delete_confirm': 'Are you sure you want to delete this project?',
'delete_tip': 'These resources will be deleted:',
'delete_confirm': 'Deleting this project will delete all test resources under this project. Are you sure you want to delete?',
'delete_tip': 'Deleting this project will delete all test resources under this project. Are you sure you want to delete?',
'search_by_name': 'Search by name',
'input_name': 'Please enter a workspace name',
'owning_workspace': 'Owning Workspace',

View File

@ -1,5 +1,6 @@
export default {
commons: {
'delete_cancelled': '已取消删除',
'workspace': '工作空间',
'organization': '组织',
'setting': '设置',
@ -105,7 +106,7 @@ export default {
'create': '创建工作空间',
'update': '修改工作空间',
'delete': '删除工作空间',
'delete_confirm': '删除工作空间会关联删除该工作空间下的资源,确定要删除吗?',
'delete_confirm': '删除工作空间会关联删除该工作空间下的所有资源(如:相关项目,测试用例等),确定要删除吗?',
'add': '添加工作空间',
'input_name': '请输入工作空间名称',
'search_by_name': '根据名称搜索',
@ -115,18 +116,20 @@ export default {
'none': '无工作空间',
'select': '选择工作空间',
'special_characters_are_not_supported': '格式错误(不支持特殊字符,且不能以\'-\'开头结尾)',
'delete_warning': '删除该工作空间将同步删除该工作空间下所有项目,以及项目中的所有用例、接口测试、性能测试等,确定要删除吗?',
},
organization: {
'create': '创建组织',
'modify': '修改组织',
'delete': '删除组织',
'delete_confirm': '删除组织会关联删除该组织下的资源,确定要删除吗?',
'delete_confirm': '删除组织会关联删除该组织下的所有资源(如:相关工作空间,项目,测试用例等),确定要删除吗?',
'input_name': '请输入组织名称',
'select_organization': '请选择组织',
'search_by_name': '根据名称搜索',
'special_characters_are_not_supported': '格式错误(不支持特殊字符,且不能以\'-\'开头结尾)',
'none': '无组织',
'select': '选择组织',
'delete_warning': '删除该组织将同步删除该组织下所有相关工作空间和相关工作空间下的所有项目,以及项目中的所有用例、接口测试、性能测试等,确定要删除吗?',
},
project: {
'recent': '最近的项目',
@ -134,7 +137,7 @@ export default {
'edit': '编辑项目',
'delete': '删除项目',
'delete_confirm': '确定要删除这个项目吗?',
'delete_tip': '删除该项目,会删除以下资源:',
'delete_tip': '删除该项目,会删除该项目下所有测试资源,确定要删除吗?',
'search_by_name': '根据名称搜索',
'input_name': '请输入项目名称',
'owning_workspace': '所属工作空间',

View File

@ -1,5 +1,6 @@
export default {
commons: {
'delete_cancelled': '已取消删除',
'workspace': '工作空間',
'organization': '組織',
'setting': '設置',
@ -103,7 +104,7 @@ export default {
'create': '創建工作空間',
'update': '修改工作空間',
'delete': '刪除工作空間',
'delete_confirm': '刪除工作空間會關聯刪除該工作空間下的資源,確定要刪除嗎?',
'delete_confirm': '删除該工作空間會關聯删除該工作空間下的所有資源(如:相關項目,測試用例等),確定要删除嗎?',
'add': '添加工作空間',
'input_name': '請輸入工作空間名稱',
'search_by_name': '根據名稱搜索',
@ -113,18 +114,21 @@ export default {
'none': '無工作空間',
'select': '選擇工作空間',
'special_characters_are_not_supported': '格式錯誤(不支持特殊字符,且不能以\'-\'開頭結尾)',
'delete_warning': '删除该工作空间将同步删除该工作空间下所有项目,以及项目中的所有用例、接口测试、性能测试等,确定要删除吗?',
},
organization: {
'create': '創建組織',
'modify': '修改組織',
'delete': '刪除組織',
'delete_confirm': '刪除組織會關聯刪除該組織下的資源,確定要刪除嗎?',
'delete_confirm': '删除該組織會關聯删除該組織下的所有資源(如:相關工作空間,項目,測試用例等),確定要删除嗎?',
'input_name': '請輸入組織名稱',
'select_organization': '請選擇組織',
'search_by_name': '根據名稱搜索',
'special_characters_are_not_supported': 'Incorrect format (special characters are not supported and cannot end with \'-\')',
'none': '無組織',
'select': '選擇組織',
'delete_warning': '删除该组织将同步删除该组织下所有相关工作空间和相关工作空间下的所有项目,以及项目中的所有用例、接口测试、性能测试等,确定要删除吗?',
},
project: {
'recent': '最近的項目',
@ -132,7 +136,7 @@ export default {
'edit': '編輯項目',
'delete': '刪除項目',
'delete_confirm': '確定要刪除這個項目嗎?',
'delete_tip': '刪除該項目,會刪除以下資源:',
'delete_tip': '删除該項目,會删除該項目下所有測試資源,確定要删除嗎?',
'search_by_name': '根據名稱搜索',
'input_name': '請輸入項目名稱',
'owning_workspace': '所屬工作空間',