MorePanel.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import React from 'react';
  2. import { Layout, Button, Typography, Divider, Flex } from 'antd';
  3. import { ArrowLeftOutlined } from '@ant-design/icons';
  4. import { useDispatch, useSelector } from 'react-redux';
  5. import { switchToOperationPanel } from '../../../states/panelSwitchSliceForView';
  6. import {
  7. selectAllViewers,
  8. selectAllViewerUrls,
  9. selectSelectedViewers,
  10. setSelectedViewers,
  11. } from '@/states/view/viewerContainerSlice';
  12. import { RootState } from '@/states/store';
  13. import Icon from '@/components/Icon';
  14. import '@/themes/truncateText.css';
  15. const { Header, Content } = Layout;
  16. const { Title, Text } = Typography;
  17. const FunctionButton = ({
  18. title,
  19. action,
  20. iconName,
  21. onClick,
  22. }: {
  23. title: string;
  24. action: string;
  25. iconName: string;
  26. onClick: () => void;
  27. }) => {
  28. return (
  29. <Button
  30. onClick={onClick}
  31. icon={
  32. <Icon
  33. module="module-process"
  34. name={iconName}
  35. userId="base"
  36. theme="default"
  37. size="2x"
  38. state="normal"
  39. />
  40. }
  41. style={{
  42. width: '1.5rem',
  43. height: '1.5rem',
  44. padding: 0,
  45. }}
  46. title={title}
  47. className="truncate-text"
  48. />
  49. );
  50. };
  51. const MorePanel = () => {
  52. const dispatch = useDispatch();
  53. // 获取所有 viewer URLs 和当前选中的 viewer URLs
  54. const allViewers = useSelector(selectAllViewerUrls);
  55. const selectedViewers = useSelector(selectSelectedViewers);
  56. const handleReturn = () => {
  57. dispatch(switchToOperationPanel());
  58. };
  59. // 全选处理函数
  60. const handleSelectAll = () => {
  61. dispatch(selectAllViewers());
  62. };
  63. // 反选处理函数
  64. const handleInvertSelection = () => {
  65. // 获取未选中的 viewers
  66. const invertedSelection = allViewers.filter(
  67. (url) => !selectedViewers.includes(url)
  68. );
  69. // 如果反选后为空,则保持至少一个选中项(选中第一个)
  70. if (invertedSelection.length === 0 && allViewers.length > 0) {
  71. dispatch(setSelectedViewers([allViewers[0]]));
  72. } else {
  73. dispatch(setSelectedViewers(invertedSelection));
  74. }
  75. };
  76. // 图像详情按钮处理函数(待实现)
  77. const handleImageDetails = () => {
  78. // TODO: 实现图像详情功能
  79. console.log('图像详情功能待实现');
  80. };
  81. // tag信息按钮处理函数(待实现)
  82. const handleTagInfo = () => {
  83. // TODO: 实现tag信息功能
  84. console.log('tag信息功能待实现');
  85. };
  86. return (
  87. <Layout className="h-full">
  88. {/* 顶部导航栏 */}
  89. <Header
  90. style={{
  91. display: 'flex',
  92. alignItems: 'center',
  93. padding: '0 16px',
  94. }}
  95. >
  96. <Button
  97. type="text"
  98. icon={<ArrowLeftOutlined />}
  99. onClick={handleReturn}
  100. />
  101. <Title level={5} style={{ margin: 0, lineHeight: '48px' }}>
  102. 更多功能
  103. </Title>
  104. </Header>
  105. {/* 主体内容 */}
  106. <Content
  107. style={{ padding: '16px', maxHeight: '100%', overflowY: 'auto' }}
  108. >
  109. {/* 选择操作组 */}
  110. <div style={{ marginBottom: '24px' }}>
  111. <Text
  112. strong
  113. style={{ fontSize: '14px', marginBottom: '12px', display: 'block' }}
  114. >
  115. 选择操作
  116. </Text>
  117. <Flex wrap gap="small" align="center" justify="start" className="p-1">
  118. <FunctionButton
  119. title="全选"
  120. action="全选"
  121. iconName="RejectImage"
  122. onClick={handleSelectAll}
  123. />
  124. <FunctionButton
  125. title="反选"
  126. action="反选"
  127. iconName="RejectImage"
  128. onClick={handleInvertSelection}
  129. />
  130. </Flex>
  131. <div style={{ marginTop: '8px', fontSize: '12px', color: '#666' }}>
  132. 说明:全选或反选所有 viewer 中的图像
  133. </div>
  134. </div>
  135. <Divider />
  136. {/* 信息查看组 */}
  137. <div style={{ marginBottom: '24px' }}>
  138. <Text
  139. strong
  140. style={{ fontSize: '14px', marginBottom: '12px', display: 'block' }}
  141. >
  142. 信息查看
  143. </Text>
  144. <Flex wrap gap="small" align="center" justify="start" className="p-1">
  145. <FunctionButton
  146. title="图像详情"
  147. action="图像详情"
  148. iconName="RejectImage"
  149. onClick={handleImageDetails}
  150. />
  151. <FunctionButton
  152. title="tag信息"
  153. action="tag信息"
  154. iconName="RejectImage"
  155. onClick={handleTagInfo}
  156. />
  157. </Flex>
  158. <div style={{ marginTop: '8px', fontSize: '12px', color: '#666' }}>
  159. 说明:查看图像详细信息和tag相关信息(功能待实现)
  160. </div>
  161. </div>
  162. </Content>
  163. </Layout>
  164. );
  165. };
  166. export default MorePanel;