feat(项目管理): 环境管理环境组
This commit is contained in:
parent
2f0ff19744
commit
65b1266370
|
@ -2,3 +2,15 @@ export interface EnvListItem {
|
|||
name: string;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export interface EnvGroupProjectListItem {
|
||||
name: string;
|
||||
env: string;
|
||||
host: string;
|
||||
description: string;
|
||||
}
|
||||
export interface EnvGroupListItem {
|
||||
name: string;
|
||||
id: string;
|
||||
projectList: EnvGroupProjectListItem[];
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { defineStore } from 'pinia';
|
||||
|
||||
import { EnvGroupListItem } from '@/models/projectManagement/environmental';
|
||||
|
||||
export const ALL_PARAM = 'allParam';
|
||||
|
||||
const useProjectEnvStore = defineStore(
|
||||
|
@ -7,8 +9,11 @@ const useProjectEnvStore = defineStore(
|
|||
() => {
|
||||
const currentId = ref<string | number>(1);
|
||||
const httpNoWarning = ref(true);
|
||||
const envGroupList = ref<EnvGroupListItem[]>([]);
|
||||
|
||||
const getCurrentId = computed(() => currentId.value);
|
||||
const getHttpNoWarning = computed(() => httpNoWarning.value);
|
||||
const getGroupLength = computed(() => 1);
|
||||
|
||||
const getDatabaseList = computed(() => [{ id: 1, name: 'test' }]);
|
||||
function setCurrentId(id: string | number) {
|
||||
|
@ -25,6 +30,8 @@ const useProjectEnvStore = defineStore(
|
|||
setHttpNoWarning,
|
||||
getHttpNoWarning,
|
||||
getDatabaseList,
|
||||
envGroupList,
|
||||
getGroupLength,
|
||||
};
|
||||
},
|
||||
{
|
||||
|
|
|
@ -0,0 +1,132 @@
|
|||
<template>
|
||||
<div class="page">
|
||||
<template v-if="store.getGroupLength">
|
||||
<div class="header">
|
||||
<a-form ref="envGroupForm" layout="vertical" :model="form">
|
||||
<a-form-item
|
||||
class="mb-[16px]"
|
||||
asterisk-position="end"
|
||||
field="name"
|
||||
:label="t('project.environmental.group.envGroupName')"
|
||||
:rules="[{ required: true, message: t('project.environmental.group.envGroupNameIsRequire') }]"
|
||||
>
|
||||
<a-input
|
||||
v-model="form.name"
|
||||
show-word-limit
|
||||
:max-length="255"
|
||||
class="w-[732px]"
|
||||
:placeholder="t('project.environmental.group.envGroupPlaceholder')"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
class="mb-[16px]"
|
||||
asterisk-position="end"
|
||||
field="description"
|
||||
:label="t('project.environmental.group.desc')"
|
||||
>
|
||||
<a-textarea v-model="form.description" auto-size class="w-[732px]" :placeholder="t('common.pleaseInput')" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<AllParamsTable
|
||||
v-model:params="innerParams"
|
||||
:show-setting="false"
|
||||
:columns="columns"
|
||||
@change="handleParamTableChange"
|
||||
/>
|
||||
</div>
|
||||
<div class="footer" :style="{ width: '100%' }">
|
||||
<a-button :disabled="!canSave" @click="handleReset">{{ t('common.cancel') }}</a-button>
|
||||
<a-button :disabled="!canSave" type="primary" @click="handleSave">{{ t('common.save') }}</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="flex h-[400px] items-center justify-center">
|
||||
<a-empty description="暂无数据" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { MsTableColumn } from '@/components/pure/ms-table/type';
|
||||
import AllParamsTable from '../allParams/AllParamsTable.vue';
|
||||
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import useProjectEnvStore from '@/store/modules/setting/useProjectEnvStore';
|
||||
|
||||
const envGroupForm = ref();
|
||||
const form = reactive({
|
||||
name: '',
|
||||
description: '',
|
||||
});
|
||||
const store = useProjectEnvStore();
|
||||
const columns: MsTableColumn = [
|
||||
{
|
||||
title: 'project.environmental.project',
|
||||
dataIndex: 'project',
|
||||
slotName: 'project',
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.env',
|
||||
dataIndex: 'env',
|
||||
slotName: 'env',
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.host',
|
||||
dataIndex: 'host',
|
||||
slotName: 'host',
|
||||
},
|
||||
{
|
||||
title: 'project.environmental.desc',
|
||||
dataIndex: 'desc',
|
||||
slotName: 'desc',
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
slotName: 'operation',
|
||||
width: 50,
|
||||
},
|
||||
];
|
||||
|
||||
const innerParams = ref<any[]>([]);
|
||||
|
||||
const canSave = ref(true);
|
||||
|
||||
const handleReset = () => {
|
||||
envGroupForm.value?.resetFields();
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
envGroupForm.value?.validate(async (valid) => {
|
||||
if (valid) {
|
||||
console.log('form', form);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function handleParamTableChange(resultArr: any[]) {
|
||||
innerParams.value = [...resultArr];
|
||||
}
|
||||
|
||||
const { t } = useI18n();
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page {
|
||||
transform: scale3d(1, 1, 1);
|
||||
.header {
|
||||
padding: 24px 24px 0;
|
||||
}
|
||||
.footer {
|
||||
gap: 16px;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 999;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 24px;
|
||||
box-shadow: 0 -1px 4px rgb(2 2 2 / 10%);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -7,50 +7,117 @@
|
|||
<a-radio value="PROJECT">{{ t('project.environmental.project') }}</a-radio>
|
||||
<a-radio value="PROJECT_GROUP">{{ t('project.environmental.projectGroup') }}</a-radio>
|
||||
</a-radio-group>
|
||||
<a-input-search
|
||||
:placeholder="t('project.environmental.searchHolder')"
|
||||
allow-clear
|
||||
@press-enter="enterData"
|
||||
@search="searchData"
|
||||
/>
|
||||
<!-- 全局参数-->
|
||||
<div class="p-[8px] text-[var(--color-text-4)]">
|
||||
{{ t('project.environmental.allParam') }}
|
||||
</div>
|
||||
<div
|
||||
class="env-item justify-between font-medium text-[rgb(var(--primary-5))] hover:bg-[rgb(var(--primary-1))]"
|
||||
:class="{ 'bg-[rgb(var(--primary-1))]': activeKey === ALL_PARAM }"
|
||||
@click="handleListItemClick({ id: 'allParam', name: 'allParam' })"
|
||||
>
|
||||
{{ t('project.environmental.allParam') }}
|
||||
<div class="node-extra">
|
||||
<MsMoreAction
|
||||
:list="allMoreAction"
|
||||
@select="(value) => handleMoreAction(value, 'all', EnvAuthTypeEnum.GLOBAL)"
|
||||
/>
|
||||
<template v-if="showType === 'PROJECT'">
|
||||
<a-input-search
|
||||
:placeholder="t('project.environmental.searchHolder')"
|
||||
allow-clear
|
||||
@press-enter="enterData"
|
||||
@search="searchData"
|
||||
/>
|
||||
<!-- 全局参数-->
|
||||
<div class="p-[8px] text-[var(--color-text-4)]">
|
||||
{{ t('project.environmental.allParam') }}
|
||||
</div>
|
||||
</div>
|
||||
<a-divider :margin="6" />
|
||||
<!-- 环境-->
|
||||
<div class="env-row p-[8px] hover:bg-[rgb(var(--primary-1))]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('project.environmental.env') }}</div>
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="env-row-extra">
|
||||
<div
|
||||
class="env-item justify-between font-medium text-[rgb(var(--primary-5))] hover:bg-[rgb(var(--primary-1))]"
|
||||
:class="{ 'bg-[rgb(var(--primary-1))]': activeKey === ALL_PARAM }"
|
||||
@click="handleListItemClick({ id: 'allParam', name: 'allParam' })"
|
||||
>
|
||||
{{ t('project.environmental.allParam') }}
|
||||
<div class="node-extra">
|
||||
<MsMoreAction
|
||||
:list="allMoreAction"
|
||||
@select="(value) => handleMoreAction(value, 'all', EnvAuthTypeEnum.ENVIRONMENT)"
|
||||
@select="(value) => handleMoreAction(value, 'all', EnvAuthTypeEnum.GLOBAL)"
|
||||
/>
|
||||
</div>
|
||||
<MsButton type="icon" class="!mr-0 p-[2px]">
|
||||
<MsIcon
|
||||
type="icon-icon_create_planarity"
|
||||
size="18"
|
||||
class="text-[rgb(var(--primary-5))] hover:text-[rgb(var(--primary-4))]"
|
||||
/>
|
||||
</MsButton>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a-divider :margin="6" />
|
||||
<!-- 环境-->
|
||||
<div class="env-row p-[8px] hover:bg-[rgb(var(--primary-1))]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('project.environmental.env') }}</div>
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="env-row-extra">
|
||||
<MsMoreAction
|
||||
:list="allMoreAction"
|
||||
@select="(value) => handleMoreAction(value, 'all', EnvAuthTypeEnum.ENVIRONMENT)"
|
||||
/>
|
||||
</div>
|
||||
<MsButton type="icon" class="!mr-0 p-[2px]">
|
||||
<MsIcon
|
||||
type="icon-icon_create_planarity"
|
||||
size="18"
|
||||
class="text-[rgb(var(--primary-5))] hover:text-[rgb(var(--primary-4))]"
|
||||
/>
|
||||
</MsButton>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<!-- 环境list-->
|
||||
<div v-if="envList.length">
|
||||
<VueDraggable v-model="envList" ghost-class="ghost">
|
||||
<div
|
||||
v-for="element in envList"
|
||||
:key="element.id"
|
||||
class="env-item hover:bg-[rgb(var(--primary-1))]"
|
||||
@click="handleListItemClick(element)"
|
||||
>
|
||||
<RenamePop
|
||||
:list="envList"
|
||||
:type="(showType as EnvAuthScopeEnum)"
|
||||
v-bind="popVisible[element.id]"
|
||||
@cancel="handleRenameCancel(element)"
|
||||
@submit="handleRenameCancel(element, element.id)"
|
||||
>
|
||||
<div class="flex max-w-[100%] grow flex-row items-center justify-between">
|
||||
<a-tooltip :content="element.name">
|
||||
<div
|
||||
class="one-line-text"
|
||||
:class="{ 'font-medium text-[rgb(var(--primary-5))]': element.id === activeKey }"
|
||||
>{{ element.name }}</div
|
||||
>
|
||||
</a-tooltip>
|
||||
<div class="node-extra">
|
||||
<div class="flex flex-row items-center gap-[8px]">
|
||||
<MsButton type="icon" class="!mr-0 p-[2px]">
|
||||
<MsIcon
|
||||
type="icon-icon_drag"
|
||||
size="16"
|
||||
class="text-[rgb(var(--primary-5))] hover:text-[rgb(var(--primary-4))]"
|
||||
/>
|
||||
</MsButton>
|
||||
<MsMoreAction
|
||||
:list="envMoreAction"
|
||||
@select="
|
||||
(value) => handleMoreAction(value, element.id, EnvAuthTypeEnum.ENVIRONMENT_PARAM)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</RenamePop>
|
||||
</div>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
<!-- 环境无数据 -->
|
||||
<div v-else class="bg-[var(--color-text-n9)] p-[8px] text-[12px] text-[var(--color-text-4)]">
|
||||
{{ t('project.environmental.envListIsNull') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<!-- 环境组 -->
|
||||
<div class="env-row mt-[8px] p-[8px]">
|
||||
<div class="text-[var(--color-text-4)]">{{ t('project.environmental.group.envGroup') }}</div>
|
||||
<div class="flex flex-row items-center">
|
||||
<MsButton type="icon" class="!mr-0 p-[2px]">
|
||||
<MsIcon
|
||||
type="icon-icon_create_planarity"
|
||||
size="18"
|
||||
class="text-[rgb(var(--primary-5))] hover:text-[rgb(var(--primary-4))]"
|
||||
/>
|
||||
</MsButton>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 环境list-->
|
||||
<div v-if="envList.length">
|
||||
<VueDraggable v-model="envList" ghost-class="ghost">
|
||||
|
@ -95,18 +162,20 @@
|
|||
</div>
|
||||
</VueDraggable>
|
||||
</div>
|
||||
|
||||
<!-- 环境无数据 -->
|
||||
<div v-else class="bg-[var(--color-text-n9)] p-[8px] text-[12px] text-[var(--color-text-4)]">
|
||||
{{ t('project.environmental.envListIsNull') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<template #second>
|
||||
<!-- 全局参数 -->
|
||||
<AllParamBox v-if="activeKey === ALL_PARAM" />
|
||||
<AllParamBox v-if="showType === 'PROJECT' && activeKey === ALL_PARAM" />
|
||||
<!-- 环境变量 -->
|
||||
<EnvParamBox v-else />
|
||||
<EnvParamBox v-else-if="showType === 'PROJECT' && activeKey !== ALL_PARAM" />
|
||||
<!-- 环境组 -->
|
||||
<EnvGroupBox v-else-if="showType === 'PROJECT_GROUP'" />
|
||||
</template>
|
||||
</MsSplitBox>
|
||||
</div>
|
||||
|
@ -119,6 +188,7 @@
|
|||
import MsMoreAction from '@/components/pure/ms-table-more-action/index.vue';
|
||||
import { ActionsItem } from '@/components/pure/ms-table-more-action/types';
|
||||
import AllParamBox from './components/AllParamBox.vue';
|
||||
import EnvGroupBox from './components/envGroup/EnvGroupBox.vue';
|
||||
import EnvParamBox from './components/envParams/EnvParamBox.vue';
|
||||
import RenamePop from './components/RenamePop.vue';
|
||||
|
||||
|
@ -189,6 +259,7 @@
|
|||
default:
|
||||
break;
|
||||
}
|
||||
console.log(item, id, scopeType);
|
||||
};
|
||||
|
||||
function changeShowType(value: string | number | boolean) {
|
||||
|
|
|
@ -74,4 +74,9 @@ export default {
|
|||
'project.environmental.host.hostNamePlaceholder': '请输入域名',
|
||||
'project.environmental.host.desc': '描述',
|
||||
'project.environmental.host.descPlaceholder': '请输入描述',
|
||||
'project.environmental.group.desc': '描述',
|
||||
'project.environmental.group.envGroup': '环境组',
|
||||
'project.environmental.group.envGroupName': '环境组名称',
|
||||
'project.environmental.group.envGroupNameIsRequire': '环境组名称不能为空',
|
||||
'project.environmental.group.envGroupPlaceholder': '请输入环境组',
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue