1
This commit is contained in:
parent
fe6de5720a
commit
f8a9243ecd
@ -73,15 +73,21 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
|
||||
if (!open) return;
|
||||
|
||||
if (initialValues) {
|
||||
// 设置基础字段
|
||||
form.setFieldsValue({
|
||||
applicationId: initialValues.applicationId,
|
||||
enabled: initialValues.enabled
|
||||
enabled: initialValues.enabled,
|
||||
...initialValues.buildVariables // 设置所有构建变量到表单中
|
||||
});
|
||||
|
||||
const template = templates.find(t => t.buildType === initialValues.buildType && t.languageType === initialValues.languageType);
|
||||
if (template) {
|
||||
setSelectedTemplate(template);
|
||||
setBuildVariables(initialValues.buildVariables || {});
|
||||
// 只保存编辑器字段的值到 buildVariables
|
||||
const editorValues = Object.entries(initialValues.buildVariables || {})
|
||||
.filter(([key]) => template.buildVariablesSchema?.properties?.[key]?.editorConfig)
|
||||
.reduce((acc, [key, value]) => ({...acc, [key]: value}), {});
|
||||
setBuildVariables(editorValues);
|
||||
}
|
||||
} else {
|
||||
form.resetFields();
|
||||
@ -100,17 +106,30 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
|
||||
if (template) {
|
||||
setSelectedTemplate(template);
|
||||
setBuildVariables({});
|
||||
// 重置除了 applicationId 和 enabled 之外的所有字段
|
||||
const currentValues = form.getFieldsValue();
|
||||
form.setFieldsValue({
|
||||
applicationId: currentValues.applicationId,
|
||||
enabled: currentValues.enabled
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [applications, templates]);
|
||||
}, [applications, templates, form]);
|
||||
|
||||
const handleFormValuesChange = (changedValues: Record<string, any>) => {
|
||||
setBuildVariables(prev => ({
|
||||
...prev,
|
||||
...changedValues
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const values = await form.validateFields();
|
||||
const formValues = await form.validateFields();
|
||||
|
||||
// 获取选中的应用信息
|
||||
const selectedApp = applications.find(app => app.id === values.applicationId);
|
||||
const selectedApp = applications.find(app => app.id === formValues.applicationId);
|
||||
if (!selectedApp) {
|
||||
throw new Error('请选择应用');
|
||||
}
|
||||
@ -121,14 +140,20 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
|
||||
throw new Error('未找到匹配配置模板');
|
||||
}
|
||||
|
||||
// 从 formValues 中提取构建变量(排除 applicationId 和 enabled)
|
||||
const { applicationId, enabled, ...formBuildVariables } = formValues;
|
||||
|
||||
// 构建提交数据
|
||||
const submitData: CreateDeploymentConfigRequest = {
|
||||
environmentId: envId,
|
||||
applicationId: values.applicationId,
|
||||
applicationId,
|
||||
buildType: template.buildType,
|
||||
languageType: selectedApp.language,
|
||||
buildVariables,
|
||||
enabled: values.enabled
|
||||
buildVariables: {
|
||||
...formBuildVariables, // 表单中的值
|
||||
...buildVariables // 编辑器中的值
|
||||
} as Record<string, any>, // 使用类型断言确保类型兼容
|
||||
enabled
|
||||
};
|
||||
|
||||
if (isEdit) {
|
||||
@ -217,34 +242,57 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
|
||||
{/* 动态构建配置 */}
|
||||
{selectedTemplate?.buildVariablesSchema?.properties && (
|
||||
<>
|
||||
{/* 按照原始顺序渲染所有字段 */}
|
||||
{Object.entries(selectedTemplate.buildVariablesSchema.properties).map(([key, property]) => {
|
||||
// 如果是编辑器字段
|
||||
if (property.editorConfig) {
|
||||
{/* 使用 BetaSchemaForm 渲染普通字段 */}
|
||||
<BetaSchemaForm
|
||||
layoutType="Embed"
|
||||
columns={convertJsonSchemaToColumns({
|
||||
type: 'object',
|
||||
properties: Object.fromEntries(
|
||||
Object.entries(selectedTemplate.buildVariablesSchema.properties)
|
||||
.filter(([_, prop]) => !prop.editorConfig)
|
||||
.map(([key, prop]) => [key, {
|
||||
...prop,
|
||||
type: prop.type || 'string' // 确保有 type 字段
|
||||
}])
|
||||
),
|
||||
required: selectedTemplate.buildVariablesSchema.required || []
|
||||
})}
|
||||
initialValues={buildVariables}
|
||||
onValuesChange={(_, values) => {
|
||||
setBuildVariables(prev => ({
|
||||
...prev,
|
||||
...values
|
||||
}));
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 渲染编辑器字段 */}
|
||||
{Object.entries(selectedTemplate.buildVariablesSchema.properties)
|
||||
.filter(([_, prop]) => prop.editorConfig)
|
||||
.map(([key, property]) => {
|
||||
const isFullscreen = fullscreenEditor?.key === key;
|
||||
const editorConfig = property.editorConfig;
|
||||
|
||||
const editor = (
|
||||
<Editor
|
||||
height={isFullscreen ? "calc(100vh - 55px)" : "300px"}
|
||||
defaultLanguage={editorConfig.language || 'shell'}
|
||||
theme={editorConfig.theme || 'vs-dark'}
|
||||
defaultLanguage={property.editorConfig.language || 'shell'}
|
||||
theme={property.editorConfig.theme || 'vs-dark'}
|
||||
value={buildVariables[key] || property.default || ''}
|
||||
onChange={(value) => handleEditorChange(key, value)}
|
||||
options={{
|
||||
minimap: { enabled: isFullscreen ? true : (editorConfig.minimap ?? false) },
|
||||
fontSize: editorConfig.fontSize || 14,
|
||||
lineNumbers: editorConfig.lineNumbers ? 'on' : 'off',
|
||||
wordWrap: editorConfig.wordWrap ? 'on' : 'off',
|
||||
tabSize: editorConfig.tabSize || 2,
|
||||
minimap: { enabled: isFullscreen ? true : (property.editorConfig.minimap ?? false) },
|
||||
fontSize: property.editorConfig.fontSize || 14,
|
||||
lineNumbers: property.editorConfig.lineNumbers ? 'on' : 'off',
|
||||
wordWrap: property.editorConfig.wordWrap ? 'on' : 'off',
|
||||
tabSize: property.editorConfig.tabSize || 2,
|
||||
scrollBeyondLastLine: false,
|
||||
automaticLayout: true,
|
||||
folding: editorConfig.folding ?? true,
|
||||
folding: property.editorConfig.folding ?? true,
|
||||
autoClosingBrackets: 'always',
|
||||
autoClosingQuotes: 'always',
|
||||
formatOnPaste: true,
|
||||
formatOnType: true,
|
||||
suggestOnTriggerCharacters: editorConfig.autoComplete ?? true,
|
||||
suggestOnTriggerCharacters: property.editorConfig.autoComplete ?? true,
|
||||
renderWhitespace: 'boundary',
|
||||
}}
|
||||
/>
|
||||
@ -298,47 +346,6 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
|
||||
{editor}
|
||||
</Form.Item>
|
||||
);
|
||||
}
|
||||
|
||||
// 如果是普通字段,使用 BetaSchemaForm
|
||||
return (
|
||||
<BetaSchemaForm
|
||||
key={key}
|
||||
layoutType="Embed"
|
||||
columns={convertJsonSchemaToColumns({
|
||||
type: 'object',
|
||||
properties: {
|
||||
[key]: {
|
||||
type: property.type || 'string',
|
||||
title: property.title,
|
||||
description: property.description,
|
||||
default: property.default,
|
||||
enum: property.enum,
|
||||
enumNames: property.enumNames,
|
||||
format: property.format,
|
||||
minimum: property.minimum,
|
||||
maximum: property.maximum,
|
||||
minLength: property.minLength,
|
||||
maxLength: property.maxLength,
|
||||
pattern: property.pattern,
|
||||
items: property.items && {
|
||||
type: property.items.type || 'string',
|
||||
enum: property.items.enum,
|
||||
enumNames: property.items.enumNames
|
||||
}
|
||||
}
|
||||
},
|
||||
required: selectedTemplate.buildVariablesSchema.required?.includes(key) ? [key] : []
|
||||
})}
|
||||
initialValues={{
|
||||
[key]: buildVariables[key]
|
||||
}}
|
||||
onValuesChange={(_, values) => setBuildVariables(prev => ({
|
||||
...prev,
|
||||
...values
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
)}
|
||||
|
||||
@ -33,7 +33,7 @@ const CodePreviewModal: React.FC<{
|
||||
代码预览
|
||||
<Button
|
||||
type="text"
|
||||
icon={<FullscreenOutlined />}
|
||||
icon={<FullscreenOutlined/>}
|
||||
onClick={() => setIsFullscreen(!isFullscreen)}
|
||||
/>
|
||||
</Space>
|
||||
@ -51,17 +51,17 @@ const CodePreviewModal: React.FC<{
|
||||
} : undefined}
|
||||
wrapClassName={isFullscreen ? 'fullscreen-modal' : undefined}
|
||||
styles={{
|
||||
body: { padding: 0 }
|
||||
body: {padding: 0}
|
||||
}}
|
||||
destroyOnClose
|
||||
>
|
||||
<Editor
|
||||
height={isFullscreen ? "calc(100vh - 55px)" : "500px"}
|
||||
height={isFullscreen ? "calc(100vh - 100px)" : "500px"}
|
||||
defaultLanguage={language}
|
||||
value={code}
|
||||
options={{
|
||||
readOnly: true,
|
||||
minimap: { enabled: true },
|
||||
minimap: {enabled: true},
|
||||
scrollBeyondLastLine: false,
|
||||
automaticLayout: true,
|
||||
contextmenu: true,
|
||||
@ -78,7 +78,7 @@ const DeploymentConfigList: React.FC = () => {
|
||||
const [currentConfig, setCurrentConfig] = useState<DeploymentConfig>();
|
||||
const [templates, setTemplates] = useState<DeployConfigTemplate[]>([]);
|
||||
const [codePreviewVisible, setCodePreviewVisible] = useState(false);
|
||||
const [previewCode, setPreviewCode] = useState<{code: string; language?: string}>({code: ''});
|
||||
const [previewCode, setPreviewCode] = useState<{ code: string; language?: string }>({code: ''});
|
||||
const actionRef = React.useRef<ActionType>();
|
||||
|
||||
// 获取环境列表
|
||||
@ -203,7 +203,7 @@ const DeploymentConfigList: React.FC = () => {
|
||||
<Tooltip title="点击查看完整内容">
|
||||
<Button
|
||||
type="link"
|
||||
icon={<EyeOutlined />}
|
||||
icon={<EyeOutlined/>}
|
||||
onClick={() => handleCodePreview(
|
||||
value,
|
||||
fieldProperties.editorConfig?.language
|
||||
@ -234,13 +234,6 @@ const DeploymentConfigList: React.FC = () => {
|
||||
};
|
||||
|
||||
const columns: ProColumns<DeploymentConfig>[] = [
|
||||
{
|
||||
title: '应用名称',
|
||||
dataIndex: ['application', 'appName'],
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: '应用编码',
|
||||
dataIndex: ['application', 'appCode'],
|
||||
@ -248,6 +241,13 @@ const DeploymentConfigList: React.FC = () => {
|
||||
copyable: true,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '应用名称',
|
||||
dataIndex: ['application', 'appName'],
|
||||
width: 150,
|
||||
ellipsis: true,
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: '构建配置',
|
||||
children: getBuildConfigColumns()
|
||||
@ -274,7 +274,7 @@ const DeploymentConfigList: React.FC = () => {
|
||||
onClick={() => handleEdit(record)}
|
||||
>
|
||||
<Space>
|
||||
<EditOutlined />
|
||||
<EditOutlined/>
|
||||
编辑
|
||||
</Space>
|
||||
</Button>,
|
||||
@ -289,7 +289,7 @@ const DeploymentConfigList: React.FC = () => {
|
||||
danger
|
||||
>
|
||||
<Space>
|
||||
<DeleteOutlined />
|
||||
<DeleteOutlined/>
|
||||
删除
|
||||
</Space>
|
||||
</Button>
|
||||
@ -301,7 +301,7 @@ const DeploymentConfigList: React.FC = () => {
|
||||
return (
|
||||
<PageContainer
|
||||
header={{
|
||||
title: '部署配置',
|
||||
title: '部署配置管理',
|
||||
extra: [
|
||||
<Select
|
||||
key="env-select"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, {useState} from 'react';
|
||||
import {PageContainer} from '@ant-design/pro-layout';
|
||||
import {Button, Space, Popconfirm, Tag, App} from 'antd';
|
||||
import {Button, Space, Popconfirm, Tag, App, Select} from 'antd';
|
||||
import {PlusOutlined, EditOutlined, DeleteOutlined} from '@ant-design/icons';
|
||||
import {getEnvironmentPage, deleteEnvironment} from './service';
|
||||
import type {Environment, EnvironmentQueryParams} from './types';
|
||||
@ -166,7 +166,11 @@ const EnvironmentList: React.FC = () => {
|
||||
];
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
<PageContainer
|
||||
header={{
|
||||
title: '环境管理'
|
||||
}}
|
||||
>
|
||||
<ProTable<Environment>
|
||||
columns={columns}
|
||||
actionRef={actionRef}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user