增加应用分类
This commit is contained in:
parent
edf4e9f998
commit
a1399d6d69
@ -24,7 +24,7 @@ export const getCategoryById = (id: number) =>
|
|||||||
* 查询所有启用的分类(常用)
|
* 查询所有启用的分类(常用)
|
||||||
*/
|
*/
|
||||||
export const getEnabledCategories = () =>
|
export const getEnabledCategories = () =>
|
||||||
request.get<ApplicationCategoryResponse[]>(`${BASE_URL}/enabled`);
|
request.get<ApplicationCategoryResponse[]>(`${BASE_URL}/list`);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建分类
|
* 创建分类
|
||||||
|
|||||||
@ -20,6 +20,7 @@ export interface ApplicationCategoryResponse {
|
|||||||
icon?: string;
|
icon?: string;
|
||||||
sort: number;
|
sort: number;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
applicationCount?: number;
|
||||||
createBy?: string;
|
createBy?: string;
|
||||||
createTime?: string;
|
createTime?: string;
|
||||||
updateBy?: string;
|
updateBy?: string;
|
||||||
|
|||||||
@ -41,6 +41,12 @@ import {ScrollArea} from "@/components/ui/scroll-area";
|
|||||||
import {Check, ChevronDown, Search} from "lucide-react";
|
import {Check, ChevronDown, Search} from "lucide-react";
|
||||||
import {cn} from "@/lib/utils";
|
import {cn} from "@/lib/utils";
|
||||||
import {Popover, PopoverContent, PopoverTrigger} from "@/components/ui/popover";
|
import {Popover, PopoverContent, PopoverTrigger} from "@/components/ui/popover";
|
||||||
|
import {
|
||||||
|
Accordion,
|
||||||
|
AccordionContent,
|
||||||
|
AccordionItem,
|
||||||
|
AccordionTrigger,
|
||||||
|
} from "@/components/ui/accordion";
|
||||||
|
|
||||||
interface ApplicationModalProps {
|
interface ApplicationModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -204,18 +210,43 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog open={open} onOpenChange={(open) => !open && onCancel()}>
|
<Dialog open={open} onOpenChange={(open) => !open && onCancel()}>
|
||||||
<DialogContent className="max-w-[800px] h-[75vh]">
|
<DialogContent className="max-w-[800px] max-h-[85vh] flex flex-col">
|
||||||
<DialogHeader className="pb-4">
|
<DialogHeader>
|
||||||
<DialogTitle>{isEdit ? '编辑' : '新建'}应用</DialogTitle>
|
<DialogTitle>{isEdit ? '编辑' : '新建'}应用</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form className="flex flex-col flex-1 overflow-hidden">
|
||||||
id="applicationForm"
|
<ScrollArea className="flex-1 px-6">
|
||||||
className="space-y-4 flex flex-col h-full"
|
<div className="space-y-4 pr-4">
|
||||||
>
|
|
||||||
<ScrollArea className="flex-1 -mx-6">
|
|
||||||
<div className="px-6 space-y-4">
|
|
||||||
<div className="grid grid-cols-3 gap-4">
|
<div className="grid grid-cols-3 gap-4">
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="categoryId"
|
||||||
|
render={({field}) => (
|
||||||
|
<FormItem>
|
||||||
|
<FormLabel>应用分类</FormLabel>
|
||||||
|
<Select
|
||||||
|
onValueChange={(value) => field.onChange(Number(value))}
|
||||||
|
value={field.value?.toString()}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<SelectTrigger>
|
||||||
|
<SelectValue placeholder="请选择应用分类"/>
|
||||||
|
</SelectTrigger>
|
||||||
|
</FormControl>
|
||||||
|
<SelectContent>
|
||||||
|
{categories.map((category) => (
|
||||||
|
<SelectItem key={category.id} value={category.id.toString()}>
|
||||||
|
{category.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
<FormMessage/>
|
||||||
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="appCode"
|
name="appCode"
|
||||||
@ -247,34 +278,6 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
|
|||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
|
||||||
control={form.control}
|
|
||||||
name="categoryId"
|
|
||||||
render={({field}) => (
|
|
||||||
<FormItem>
|
|
||||||
<FormLabel>应用分类</FormLabel>
|
|
||||||
<Select
|
|
||||||
onValueChange={(value) => field.onChange(Number(value))}
|
|
||||||
value={field.value?.toString()}
|
|
||||||
>
|
|
||||||
<FormControl>
|
|
||||||
<SelectTrigger>
|
|
||||||
<SelectValue placeholder="请选择应用分类"/>
|
|
||||||
</SelectTrigger>
|
|
||||||
</FormControl>
|
|
||||||
<SelectContent>
|
|
||||||
{categories.map((category) => (
|
|
||||||
<SelectItem key={category.id} value={category.id.toString()}>
|
|
||||||
{category.name}
|
|
||||||
</SelectItem>
|
|
||||||
))}
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
<FormMessage/>
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-3 gap-4">
|
<div className="grid grid-cols-3 gap-4">
|
||||||
@ -307,6 +310,13 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Git 配置区域(可折叠) */}
|
||||||
|
<Accordion type="single" collapsible className="border rounded-lg">
|
||||||
|
<AccordionItem value="git-config" className="border-0">
|
||||||
|
<AccordionTrigger className="px-4 py-3 hover:no-underline">
|
||||||
|
<span className="text-sm font-medium">Git 仓库配置(选填)</span>
|
||||||
|
</AccordionTrigger>
|
||||||
|
<AccordionContent className="px-4 pb-4">
|
||||||
<div className="grid grid-cols-3 gap-4">
|
<div className="grid grid-cols-3 gap-4">
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
@ -454,7 +464,7 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>项目</FormLabel>
|
<FormLabel>代码仓库</FormLabel>
|
||||||
<Popover open={open} onOpenChange={setOpen}>
|
<Popover open={open} onOpenChange={setOpen}>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
@ -533,6 +543,10 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</AccordionContent>
|
||||||
|
</AccordionItem>
|
||||||
|
</Accordion>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="appDesc"
|
name="appDesc"
|
||||||
@ -588,10 +602,9 @@ const ApplicationModal: React.FC<ApplicationModalProps> = ({
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="h-4" />
|
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
<DialogFooter className="pt-4">
|
<DialogFooter className="px-6 py-4 border-t mt-0">
|
||||||
<Button type="button" variant="outline" onClick={onCancel}>
|
<Button type="button" variant="outline" onClick={onCancel}>
|
||||||
取消
|
取消
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@ -270,6 +270,7 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
|
|||||||
<TableHead className="w-[160px]">分类名称</TableHead>
|
<TableHead className="w-[160px]">分类名称</TableHead>
|
||||||
<TableHead className="w-[140px]">分类代码</TableHead>
|
<TableHead className="w-[140px]">分类代码</TableHead>
|
||||||
<TableHead className="w-[60px]">图标</TableHead>
|
<TableHead className="w-[60px]">图标</TableHead>
|
||||||
|
<TableHead className="w-[120px]">应用数量</TableHead>
|
||||||
<TableHead className="w-[80px]">排序</TableHead>
|
<TableHead className="w-[80px]">排序</TableHead>
|
||||||
<TableHead className="w-[80px]">状态</TableHead>
|
<TableHead className="w-[80px]">状态</TableHead>
|
||||||
<TableHead className="min-w-[150px]">描述</TableHead>
|
<TableHead className="min-w-[150px]">描述</TableHead>
|
||||||
@ -279,7 +280,7 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
|
|||||||
<TableBody>
|
<TableBody>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={7} className="text-center py-8">
|
<TableCell colSpan={8} className="text-center py-8">
|
||||||
<div className="flex items-center justify-center">
|
<div className="flex items-center justify-center">
|
||||||
<Loader2 className="h-6 w-6 animate-spin mr-2" />
|
<Loader2 className="h-6 w-6 animate-spin mr-2" />
|
||||||
<span className="text-sm text-muted-foreground">加载中...</span>
|
<span className="text-sm text-muted-foreground">加载中...</span>
|
||||||
@ -306,6 +307,9 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
|
|||||||
<span className="text-muted-foreground text-sm">-</span>
|
<span className="text-muted-foreground text-sm">-</span>
|
||||||
)}
|
)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell className="text-center">
|
||||||
|
<span className="text-sm font-medium">{record.applicationCount || 0}</span>
|
||||||
|
</TableCell>
|
||||||
<TableCell className="text-center">{record.sort}</TableCell>
|
<TableCell className="text-center">{record.sort}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
{record.enabled ? (
|
{record.enabled ? (
|
||||||
@ -341,7 +345,7 @@ const CategoryManageDialog: React.FC<CategoryManageDialogProps> = ({
|
|||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={7} className="text-center py-12 text-muted-foreground">
|
<TableCell colSpan={8} className="text-center py-12 text-muted-foreground">
|
||||||
<div className="flex flex-col items-center gap-3">
|
<div className="flex flex-col items-center gap-3">
|
||||||
<FolderKanban className="h-12 w-12 opacity-20" />
|
<FolderKanban className="h-12 w-12 opacity-20" />
|
||||||
<p className="text-sm">暂无分类</p>
|
<p className="text-sm">暂无分类</p>
|
||||||
|
|||||||
@ -201,16 +201,6 @@ const ApplicationList: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const columns: Column[] = [
|
const columns: Column[] = [
|
||||||
{
|
|
||||||
accessorKey: 'appCode',
|
|
||||||
header: '应用编码',
|
|
||||||
size: 150,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
accessorKey: 'appName',
|
|
||||||
header: '应用名称',
|
|
||||||
size: 130,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'category',
|
id: 'category',
|
||||||
header: '应用分类',
|
header: '应用分类',
|
||||||
@ -221,6 +211,16 @@ const ApplicationList: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'appCode',
|
||||||
|
header: '应用编码',
|
||||||
|
size: 150,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'appName',
|
||||||
|
header: '应用名称',
|
||||||
|
size: 130,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
accessorKey: 'appDesc',
|
accessorKey: 'appDesc',
|
||||||
header: '应用描述',
|
header: '应用描述',
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user