Explorar o código

✨ feat(web): add model prefill group quick-add buttons to channel models selector

- Added support to fetch and render “model prefill groups” in `EditChannelModal.jsx`
- Users can now click a group button to instantly merge that group’s models into the models Select
- Mirrors the prefill-group UX used for tags/endpoints in `EditModelModal.jsx`

Details
- UI/UX:
  - Renders one button per model group inside the models field’s extra actions
  - Clicking a button merges its items into the selected models (trimmed, deduplicated), updating immediately
  - Non-destructive and works alongside existing actions (fill related/all models, fetch upstream, clear, copy)
- API:
  - GET `/api/prefill_group?type=model`
  - Handles `items` as either an array or a JSON string array for robustness
  - If request fails or returns no groups, buttons are simply not shown
- i18n:
  - Reuses existing i18n; group names come from backend and are displayed as-is
- Performance:
  - Simple set merge; negligible overhead
- Backward compatibility:
  - No changes required on the backend or elsewhere; feature is additive
- Testing (manual):
  1) Open channel modal (new or edit) and navigate to the Models section
  2) Confirm model group buttons render when groups are configured
  3) Click a group button → models Select updates with merged models (no duplicates)
  4) Verify other actions (fill related/all, fetch upstream, clear, copy) still work
  5) Close/reopen modal → state resets as expected

Implementation
- `web/src/components/table/channels/modals/EditChannelModal.jsx`
  - Added `modelGroups` state and `fetchModelGroups()` (GET `/api/prefill_group?type=model`)
  - Invoked `fetchModelGroups()` when the modal opens
  - Rendered group buttons in the models Select `extraText`, merging group items into current selection

Chore
- Verified no new linter errors were introduced.
t0ng7u hai 7 meses
pai
achega
d0fb54fbfe
Modificáronse 1 ficheiros con 39 adicións e 0 borrados
  1. 39 0
      web/src/components/table/channels/modals/EditChannelModal.jsx

+ 39 - 0
web/src/components/table/channels/modals/EditChannelModal.jsx

@@ -142,6 +142,7 @@ const EditChannelModal = (props) => {
   const [groupOptions, setGroupOptions] = useState([]);
   const [basicModels, setBasicModels] = useState([]);
   const [fullModels, setFullModels] = useState([]);
+  const [modelGroups, setModelGroups] = useState([]);
   const [customModel, setCustomModel] = useState('');
   const [modalImageUrl, setModalImageUrl] = useState('');
   const [isModalOpenurl, setIsModalOpenurl] = useState(false);
@@ -477,6 +478,17 @@ const EditChannelModal = (props) => {
     }
   };
 
+  const fetchModelGroups = async () => {
+    try {
+      const res = await API.get('/api/prefill_group?type=model');
+      if (res?.data?.success) {
+        setModelGroups(res.data.data || []);
+      }
+    } catch (error) {
+      // ignore
+    }
+  };
+
   useEffect(() => {
     const modelMap = new Map();
 
@@ -549,6 +561,7 @@ const EditChannelModal = (props) => {
       } else {
         formApiRef.current?.setValues(getInitValues());
       }
+      fetchModelGroups();
       // 重置手动输入模式状态
       setUseManualInput(false);
     } else {
@@ -1478,6 +1491,32 @@ const EditChannelModal = (props) => {
                         >
                           {t('复制所有模型')}
                         </Button>
+                        {modelGroups && modelGroups.length > 0 && modelGroups.map(group => (
+                          <Button
+                            key={group.id}
+                            size='small'
+                            type='primary'
+                            onClick={() => {
+                              let items = [];
+                              try {
+                                if (Array.isArray(group.items)) {
+                                  items = group.items;
+                                } else if (typeof group.items === 'string') {
+                                  const parsed = JSON.parse(group.items || '[]');
+                                  if (Array.isArray(parsed)) items = parsed;
+                                }
+                              } catch { }
+                              const current = formApiRef.current?.getValue('models') || inputs.models || [];
+                              const merged = Array.from(new Set([...
+                                current,
+                              ...items
+                              ].map(m => (m || '').trim()).filter(Boolean)));
+                              handleInputChange('models', merged);
+                            }}
+                          >
+                            {group.name}
+                          </Button>
+                        ))}
                       </Space>
                     )}
                   />