增加审批组件
This commit is contained in:
parent
ab4ea6e367
commit
164a39bd42
@ -9,6 +9,7 @@ import { gitRepositoriesConfig } from './presets/git';
|
||||
import { dockerRegistriesConfig } from './presets/docker';
|
||||
import { notificationChannelTypesConfig, notificationChannelsConfig } from './presets/notification';
|
||||
import { usersConfig, rolesConfig, departmentsConfig } from './presets/user';
|
||||
import { environmentsConfig, projectGroupsConfig, applicationsConfig } from './presets/deploy';
|
||||
|
||||
/**
|
||||
* 数据源配置注册表
|
||||
@ -22,7 +23,10 @@ export const DATA_SOURCE_REGISTRY: DataSourceRegistry = {
|
||||
[DataSourceType.NOTIFICATION_CHANNELS]: notificationChannelsConfig,
|
||||
[DataSourceType.USERS]: usersConfig,
|
||||
[DataSourceType.ROLES]: rolesConfig,
|
||||
[DataSourceType.DEPARTMENTS]: departmentsConfig
|
||||
[DataSourceType.DEPARTMENTS]: departmentsConfig,
|
||||
[DataSourceType.ENVIRONMENTS]: environmentsConfig,
|
||||
[DataSourceType.PROJECT_GROUPS]: projectGroupsConfig,
|
||||
[DataSourceType.APPLICATIONS]: applicationsConfig
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
55
frontend/src/domain/dataSource/presets/deploy.ts
Normal file
55
frontend/src/domain/dataSource/presets/deploy.ts
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* 部署相关数据源
|
||||
*/
|
||||
import type { DataSourceConfig } from '../types';
|
||||
|
||||
/**
|
||||
* 环境列表数据源
|
||||
*/
|
||||
export const environmentsConfig: DataSourceConfig = {
|
||||
url: '/api/v1/environments/list',
|
||||
params: { enabled: true },
|
||||
transform: (data: any[]) => {
|
||||
return data.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
code: item.code,
|
||||
type: item.type,
|
||||
description: item.description
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 项目组列表数据源
|
||||
*/
|
||||
export const projectGroupsConfig: DataSourceConfig = {
|
||||
url: '/api/v1/project-groups/list',
|
||||
params: { enabled: true },
|
||||
transform: (data: any[]) => {
|
||||
return data.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
code: item.code,
|
||||
description: item.description
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 应用列表数据源
|
||||
*/
|
||||
export const applicationsConfig: DataSourceConfig = {
|
||||
url: '/api/v1/applications/list',
|
||||
params: { enabled: true },
|
||||
transform: (data: any[]) => {
|
||||
return data.map((item: any) => ({
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
code: item.code,
|
||||
projectGroupId: item.projectGroupId,
|
||||
description: item.description
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
@ -14,7 +14,10 @@ export enum DataSourceType {
|
||||
NOTIFICATION_CHANNELS = 'NOTIFICATION_CHANNELS',
|
||||
USERS = 'USERS',
|
||||
ROLES = 'ROLES',
|
||||
DEPARTMENTS = 'DEPARTMENTS'
|
||||
DEPARTMENTS = 'DEPARTMENTS',
|
||||
ENVIRONMENTS = 'ENVIRONMENTS',
|
||||
PROJECT_GROUPS = 'PROJECT_GROUPS',
|
||||
APPLICATIONS = 'APPLICATIONS'
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { useToast } from '@/components/ui/use-toast';
|
||||
import { FormDesigner } from '@/components/FormDesigner';
|
||||
import type { FormSchema } from '@/components/FormDesigner';
|
||||
import { ArrowLeft, Workflow } from 'lucide-react';
|
||||
@ -14,6 +15,7 @@ import type { FormDefinitionRequest } from './types';
|
||||
const FormDesignerPage: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const { toast } = useToast();
|
||||
const [formSchema, setFormSchema] = useState<FormSchema | null>(null);
|
||||
const [formDefinition, setFormDefinition] = useState<any>(null);
|
||||
|
||||
@ -37,7 +39,11 @@ const FormDesignerPage: React.FC = () => {
|
||||
// 保存表单(只更新 schema,不修改基本信息)
|
||||
const handleSave = async (schema: FormSchema) => {
|
||||
if (!id || !formDefinition) {
|
||||
alert('表单信息加载失败');
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "保存失败",
|
||||
description: "表单信息加载失败,请刷新页面后重试",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -49,14 +55,22 @@ const FormDesignerPage: React.FC = () => {
|
||||
isTemplate: formDefinition.isTemplate,
|
||||
schema,
|
||||
status: formDefinition.status || 'DRAFT',
|
||||
version: formDefinition.version, // 乐观锁版本号
|
||||
};
|
||||
|
||||
try {
|
||||
await updateDefinition(Number(id), request);
|
||||
alert('保存成功');
|
||||
toast({
|
||||
title: "保存成功",
|
||||
description: `表单 "${formDefinition.name}" 已保存`,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('保存表单失败:', error);
|
||||
alert('保存失败');
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "保存失败",
|
||||
description: error instanceof Error ? error.message : '未知错误,请稍后重试',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -13,6 +13,7 @@ import { Label } from '@/components/ui/label';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { useToast } from '@/components/ui/use-toast';
|
||||
import { Loader2, FileText, Tag, Folder, AlignLeft, Copy } from 'lucide-react';
|
||||
import { getEnabledCategories } from '../../Category/service';
|
||||
import { updateDefinition } from '../service';
|
||||
@ -27,6 +28,7 @@ interface EditBasicInfoModalProps {
|
||||
}
|
||||
|
||||
const EditBasicInfoModal: React.FC<EditBasicInfoModalProps> = ({ visible, record, onClose, onSuccess }) => {
|
||||
const { toast } = useToast();
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [categories, setCategories] = useState<FormCategoryResponse[]>([]);
|
||||
const [formData, setFormData] = useState({
|
||||
@ -70,15 +72,27 @@ const EditBasicInfoModal: React.FC<EditBasicInfoModalProps> = ({ visible, record
|
||||
if (!record) return;
|
||||
|
||||
if (!formData.name.trim()) {
|
||||
alert('请输入表单名称');
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "验证失败",
|
||||
description: "请输入表单名称",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!formData.key.trim()) {
|
||||
alert('请输入表单标识');
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "验证失败",
|
||||
description: "请输入表单标识",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!/^[a-zA-Z0-9-]+$/.test(formData.key)) {
|
||||
alert('表单标识只能包含英文字母、数字和中划线');
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "验证失败",
|
||||
description: "表单标识只能包含英文字母、数字和中划线",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -92,15 +106,23 @@ const EditBasicInfoModal: React.FC<EditBasicInfoModalProps> = ({ visible, record
|
||||
schema: record.schema,
|
||||
status: record.status,
|
||||
isTemplate: formData.isTemplate,
|
||||
version: record.version, // 乐观锁版本号
|
||||
};
|
||||
|
||||
await updateDefinition(record.id, request);
|
||||
alert('更新成功');
|
||||
toast({
|
||||
title: "更新成功",
|
||||
description: `表单 "${formData.name}" 的基本信息已更新`,
|
||||
});
|
||||
onSuccess();
|
||||
onClose();
|
||||
} catch (error) {
|
||||
console.error('更新表单失败:', error);
|
||||
alert('更新表单失败: ' + (error as Error).message);
|
||||
toast({
|
||||
variant: "destructive",
|
||||
title: "更新失败",
|
||||
description: error instanceof Error ? error.message : '未知错误,请稍后重试',
|
||||
});
|
||||
} finally {
|
||||
setSubmitting(false);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { BaseQuery } from '@/types/base';
|
||||
import { BaseQuery, BaseResponse } from '@/types/base';
|
||||
import type { FormSchema } from '@/components/FormDesigner';
|
||||
|
||||
/**
|
||||
@ -19,8 +19,7 @@ export interface FormDefinitionQuery extends BaseQuery {
|
||||
/**
|
||||
* 表单定义响应
|
||||
*/
|
||||
export interface FormDefinitionResponse {
|
||||
id: number;
|
||||
export interface FormDefinitionResponse extends BaseResponse {
|
||||
name: string;
|
||||
key: string;
|
||||
formVersion: number;
|
||||
@ -30,10 +29,6 @@ export interface FormDefinitionResponse {
|
||||
tags?: string[];
|
||||
status: FormDefinitionStatus;
|
||||
isTemplate: boolean;
|
||||
createBy?: string;
|
||||
createTime?: string;
|
||||
updateBy?: string;
|
||||
updateTime?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,5 +43,6 @@ export interface FormDefinitionRequest {
|
||||
tags?: string[];
|
||||
status?: FormDefinitionStatus;
|
||||
isTemplate?: boolean;
|
||||
version?: number; // 乐观锁版本号(更新时必传)
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user