feat: Add prefill group management system for models

- Add new PrefillGroup model with CRUD operations
  * Support for model, tag, and endpoint group types
  * JSON storage for group items with GORM datatypes
  * Automatic database migration support

- Implement backend API endpoints
  * GET /api/prefill_group - List groups by type with admin auth
  * POST /api/prefill_group - Create new groups
  * PUT /api/prefill_group - Update existing groups
  * DELETE /api/prefill_group/:id - Delete groups

- Add comprehensive frontend management interface
  * PrefillGroupManagement component for group listing
  * EditPrefillGroupModal for group creation/editing
  * Integration with EditModelModal for auto-filling
  * Responsive design with CardTable and SideSheet

- Enhance model editing workflow
  * Tag group selection with auto-fill functionality
  * Endpoint group selection with auto-fill functionality
  * Seamless integration with existing model forms

- Create reusable UI components
  * Extract common rendering utilities to models/ui/
  * Shared renderLimitedItems and renderDescription functions
  * Consistent styling across all model-related components

- Improve user experience
  * Empty state illustrations matching existing patterns
  * Fixed column positioning for operation buttons
  * Item content display with +x indicators for overflow
  * Tooltip support for long descriptions
This commit is contained in:
t0ng7u
2025-08-04 02:54:37 +08:00
parent b64c8ea56b
commit 9f6027325c
13 changed files with 803 additions and 45 deletions

View File

@@ -22,7 +22,8 @@ import { Modal, Table, Spin, Button, Typography, Empty, Input } from '@douyinfe/
import { IllustrationNoResult, IllustrationNoResultDark } from '@douyinfe/semi-illustrations';
import { IconSearch } from '@douyinfe/semi-icons';
import { API, showError } from '../../../../helpers';
import { MODEL_TABLE_PAGE_SIZE } from '../../../../constants/index.js';
import { MODEL_TABLE_PAGE_SIZE } from '../../../../constants';
import { useIsMobile } from '../../../../hooks/common/useIsMobile';
const MissingModelsModal = ({
visible,
@@ -34,6 +35,7 @@ const MissingModelsModal = ({
const [missingModels, setMissingModels] = useState([]);
const [searchKeyword, setSearchKeyword] = useState('');
const [currentPage, setCurrentPage] = useState(1);
const isMobile = useIsMobile();
const fetchMissing = async () => {
setLoading(true);
@@ -87,6 +89,8 @@ const MissingModelsModal = ({
{
title: '',
dataIndex: 'operate',
fixed: 'right',
width: 100,
render: (text, record) => (
<Button
type="primary"
@@ -116,7 +120,7 @@ const MissingModelsModal = ({
visible={visible}
onCancel={onClose}
footer={null}
width={700}
size={isMobile ? 'full-width' : 'medium'}
className="!rounded-lg"
>
<Spin spinning={loading}>