DeploymentsTable.jsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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, { useMemo, useState } from 'react';
  16. import { Empty } from '@douyinfe/semi-ui';
  17. import CardTable from '../../common/ui/CardTable';
  18. import {
  19. IllustrationNoResult,
  20. IllustrationNoResultDark,
  21. } from '@douyinfe/semi-illustrations';
  22. import { getDeploymentsColumns } from './DeploymentsColumnDefs';
  23. // Import all the new modals
  24. import ViewLogsModal from './modals/ViewLogsModal';
  25. import ExtendDurationModal from './modals/ExtendDurationModal';
  26. import ViewDetailsModal from './modals/ViewDetailsModal';
  27. import UpdateConfigModal from './modals/UpdateConfigModal';
  28. import ConfirmationDialog from './modals/ConfirmationDialog';
  29. const DeploymentsTable = (deploymentsData) => {
  30. const {
  31. deployments,
  32. loading,
  33. searching,
  34. activePage,
  35. pageSize,
  36. deploymentCount,
  37. compactMode,
  38. visibleColumns,
  39. setSelectedKeys,
  40. handlePageChange,
  41. handlePageSizeChange,
  42. handleRow,
  43. t,
  44. COLUMN_KEYS,
  45. // Column functions and data
  46. startDeployment,
  47. restartDeployment,
  48. deleteDeployment,
  49. syncDeploymentToChannel,
  50. setEditingDeployment,
  51. setShowEdit,
  52. refresh,
  53. } = deploymentsData;
  54. // Modal states
  55. const [selectedDeployment, setSelectedDeployment] = useState(null);
  56. const [showLogsModal, setShowLogsModal] = useState(false);
  57. const [showExtendModal, setShowExtendModal] = useState(false);
  58. const [showDetailsModal, setShowDetailsModal] = useState(false);
  59. const [showConfigModal, setShowConfigModal] = useState(false);
  60. const [showConfirmDialog, setShowConfirmDialog] = useState(false);
  61. const [confirmOperation, setConfirmOperation] = useState('delete');
  62. // Enhanced modal handlers
  63. const handleViewLogs = (deployment) => {
  64. setSelectedDeployment(deployment);
  65. setShowLogsModal(true);
  66. };
  67. const handleExtendDuration = (deployment) => {
  68. setSelectedDeployment(deployment);
  69. setShowExtendModal(true);
  70. };
  71. const handleViewDetails = (deployment) => {
  72. setSelectedDeployment(deployment);
  73. setShowDetailsModal(true);
  74. };
  75. const handleUpdateConfig = (deployment, operation = 'update') => {
  76. setSelectedDeployment(deployment);
  77. if (operation === 'delete' || operation === 'destroy') {
  78. setConfirmOperation(operation);
  79. setShowConfirmDialog(true);
  80. } else {
  81. setShowConfigModal(true);
  82. }
  83. };
  84. const handleConfirmAction = () => {
  85. if (selectedDeployment && confirmOperation === 'delete') {
  86. deleteDeployment(selectedDeployment.id);
  87. }
  88. setShowConfirmDialog(false);
  89. setSelectedDeployment(null);
  90. };
  91. const handleModalSuccess = (updatedDeployment) => {
  92. // Refresh the deployments list
  93. refresh?.();
  94. };
  95. // Get all columns
  96. const allColumns = useMemo(() => {
  97. return getDeploymentsColumns({
  98. t,
  99. COLUMN_KEYS,
  100. startDeployment,
  101. restartDeployment,
  102. deleteDeployment,
  103. setEditingDeployment,
  104. setShowEdit,
  105. refresh,
  106. activePage,
  107. deployments,
  108. // Enhanced handlers
  109. onViewLogs: handleViewLogs,
  110. onExtendDuration: handleExtendDuration,
  111. onViewDetails: handleViewDetails,
  112. onUpdateConfig: handleUpdateConfig,
  113. onSyncToChannel: syncDeploymentToChannel,
  114. });
  115. }, [
  116. t,
  117. COLUMN_KEYS,
  118. startDeployment,
  119. restartDeployment,
  120. deleteDeployment,
  121. syncDeploymentToChannel,
  122. setEditingDeployment,
  123. setShowEdit,
  124. refresh,
  125. activePage,
  126. deployments,
  127. ]);
  128. // Filter columns based on visibility settings
  129. const getVisibleColumns = () => {
  130. return allColumns.filter((column) => visibleColumns[column.key]);
  131. };
  132. const visibleColumnsList = useMemo(() => {
  133. return getVisibleColumns();
  134. }, [visibleColumns, allColumns]);
  135. const tableColumns = useMemo(() => {
  136. if (compactMode) {
  137. // In compact mode, remove fixed columns and adjust widths
  138. return visibleColumnsList.map(({ fixed, width, ...rest }) => ({
  139. ...rest,
  140. width: width ? Math.max(width * 0.8, 80) : undefined, // Reduce width by 20% but keep minimum
  141. }));
  142. }
  143. return visibleColumnsList;
  144. }, [compactMode, visibleColumnsList]);
  145. return (
  146. <>
  147. <CardTable
  148. columns={tableColumns}
  149. dataSource={deployments}
  150. scroll={compactMode ? { x: 800 } : { x: 1200 }}
  151. pagination={{
  152. currentPage: activePage,
  153. pageSize: pageSize,
  154. total: deploymentCount,
  155. pageSizeOpts: [10, 20, 50, 100],
  156. showSizeChanger: true,
  157. onPageSizeChange: handlePageSizeChange,
  158. onPageChange: handlePageChange,
  159. }}
  160. hidePagination={true}
  161. expandAllRows={false}
  162. onRow={handleRow}
  163. rowSelection={{
  164. onChange: (selectedRowKeys, selectedRows) => {
  165. setSelectedKeys(selectedRows);
  166. },
  167. }}
  168. empty={
  169. <Empty
  170. image={<IllustrationNoResult style={{ width: 150, height: 150 }} />}
  171. darkModeImage={
  172. <IllustrationNoResultDark style={{ width: 150, height: 150 }} />
  173. }
  174. description={t('搜索无结果')}
  175. style={{ padding: 30 }}
  176. />
  177. }
  178. className='rounded-xl overflow-hidden'
  179. size='middle'
  180. loading={loading || searching}
  181. />
  182. {/* Enhanced Modals */}
  183. <ViewLogsModal
  184. visible={showLogsModal}
  185. onCancel={() => setShowLogsModal(false)}
  186. deployment={selectedDeployment}
  187. t={t}
  188. />
  189. <ExtendDurationModal
  190. visible={showExtendModal}
  191. onCancel={() => setShowExtendModal(false)}
  192. deployment={selectedDeployment}
  193. onSuccess={handleModalSuccess}
  194. t={t}
  195. />
  196. <ViewDetailsModal
  197. visible={showDetailsModal}
  198. onCancel={() => setShowDetailsModal(false)}
  199. deployment={selectedDeployment}
  200. t={t}
  201. />
  202. <UpdateConfigModal
  203. visible={showConfigModal}
  204. onCancel={() => setShowConfigModal(false)}
  205. deployment={selectedDeployment}
  206. onSuccess={handleModalSuccess}
  207. t={t}
  208. />
  209. <ConfirmationDialog
  210. visible={showConfirmDialog}
  211. onCancel={() => setShowConfirmDialog(false)}
  212. onConfirm={handleConfirmAction}
  213. title={t('确认操作')}
  214. type="danger"
  215. deployment={selectedDeployment}
  216. operation={confirmOperation}
  217. t={t}
  218. />
  219. </>
  220. );
  221. };
  222. export default DeploymentsTable;