ModelsActions.jsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. Copyright (C) 2025 QuantumNous
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. For commercial licensing, please contact support@quantumnous.com
  14. */
  15. import React, { useState } from 'react';
  16. import MissingModelsModal from './modals/MissingModelsModal';
  17. import PrefillGroupManagement from './modals/PrefillGroupManagement';
  18. import EditPrefillGroupModal from './modals/EditPrefillGroupModal';
  19. import { Button, Modal } from '@douyinfe/semi-ui';
  20. import { showSuccess, showError, copy } from '../../../helpers';
  21. import CompactModeToggle from '../../common/ui/CompactModeToggle';
  22. import SelectionNotification from './components/SelectionNotification';
  23. const ModelsActions = ({
  24. selectedKeys,
  25. setSelectedKeys,
  26. setEditingModel,
  27. setShowEdit,
  28. batchDeleteModels,
  29. compactMode,
  30. setCompactMode,
  31. t,
  32. }) => {
  33. // Modal states
  34. const [showDeleteModal, setShowDeleteModal] = useState(false);
  35. const [showMissingModal, setShowMissingModal] = useState(false);
  36. const [showGroupManagement, setShowGroupManagement] = useState(false);
  37. const [showAddPrefill, setShowAddPrefill] = useState(false);
  38. const [prefillInit, setPrefillInit] = useState({ id: undefined });
  39. // Handle delete selected models with confirmation
  40. const handleDeleteSelectedModels = () => {
  41. setShowDeleteModal(true);
  42. };
  43. // Handle delete confirmation
  44. const handleConfirmDelete = () => {
  45. batchDeleteModels();
  46. setShowDeleteModal(false);
  47. };
  48. // Handle clear selection
  49. const handleClearSelected = () => {
  50. setSelectedKeys([]);
  51. };
  52. // Handle add selected models to prefill group
  53. const handleCopyNames = async () => {
  54. const text = selectedKeys.map(m => m.model_name).join(',');
  55. if (!text) return;
  56. const ok = await copy(text);
  57. if (ok) {
  58. showSuccess(t('已复制模型名称'));
  59. } else {
  60. showError(t('复制失败'));
  61. }
  62. };
  63. const handleAddToPrefill = () => {
  64. // Prepare initial data
  65. const items = selectedKeys.map((m) => m.model_name);
  66. setPrefillInit({ id: undefined, type: 'model', items });
  67. setShowAddPrefill(true);
  68. };
  69. return (
  70. <>
  71. <div className="flex flex-wrap gap-2 w-full md:w-auto order-2 md:order-1">
  72. <Button
  73. type="primary"
  74. className="flex-1 md:flex-initial"
  75. onClick={() => {
  76. setEditingModel({
  77. id: undefined,
  78. });
  79. setShowEdit(true);
  80. }}
  81. size="small"
  82. >
  83. {t('添加模型')}
  84. </Button>
  85. <Button
  86. type="secondary"
  87. className="flex-1 md:flex-initial"
  88. size="small"
  89. onClick={() => setShowMissingModal(true)}
  90. >
  91. {t('未配置模型')}
  92. </Button>
  93. <Button
  94. type="secondary"
  95. className="flex-1 md:flex-initial"
  96. size="small"
  97. onClick={() => setShowGroupManagement(true)}
  98. >
  99. {t('预填组管理')}
  100. </Button>
  101. <CompactModeToggle
  102. compactMode={compactMode}
  103. setCompactMode={setCompactMode}
  104. t={t}
  105. />
  106. </div>
  107. <SelectionNotification
  108. selectedKeys={selectedKeys}
  109. t={t}
  110. onDelete={handleDeleteSelectedModels}
  111. onAddPrefill={handleAddToPrefill}
  112. onClear={handleClearSelected}
  113. onCopy={handleCopyNames}
  114. />
  115. <Modal
  116. title={t('批量删除模型')}
  117. visible={showDeleteModal}
  118. onCancel={() => setShowDeleteModal(false)}
  119. onOk={handleConfirmDelete}
  120. type="warning"
  121. >
  122. <div>
  123. {t('确定要删除所选的 {{count}} 个模型吗?', { count: selectedKeys.length })}
  124. </div>
  125. </Modal>
  126. <MissingModelsModal
  127. visible={showMissingModal}
  128. onClose={() => setShowMissingModal(false)}
  129. onConfigureModel={(name) => {
  130. setEditingModel({ id: undefined, model_name: name });
  131. setShowEdit(true);
  132. setShowMissingModal(false);
  133. }}
  134. t={t}
  135. />
  136. <PrefillGroupManagement
  137. visible={showGroupManagement}
  138. onClose={() => setShowGroupManagement(false)}
  139. />
  140. <EditPrefillGroupModal
  141. visible={showAddPrefill}
  142. onClose={() => setShowAddPrefill(false)}
  143. editingGroup={prefillInit}
  144. onSuccess={() => setShowAddPrefill(false)}
  145. />
  146. </>
  147. );
  148. };
  149. export default ModelsActions;