Browse Source

feat: 集成按钮可用性检查功能到多个组件

- 在FunctionArea组件中添加按钮禁用逻辑和视觉提示
- 在ImageStateControl组件中为拒绝、恢复和另存为按钮添加禁用状态检查
- 在TransferArea组件中添加发送按钮的禁用逻辑和视觉提示

改动文件:
- src/pages/view/components/FunctionArea.tsx
- src/pages/view/components/ImageStateControl.tsx
- src/pages/view/components/TransferArea.tsx
sw 1 day ago
parent
commit
46f653dd1a

+ 10 - 2
src/pages/view/components/FunctionArea.tsx

@@ -7,6 +7,7 @@ import { switchToMeasurementPanel, switchToMorePanel, switchToAdvancedProcessing
 import Icon from '@/components/Icon';
 import { showNotImplemented } from '@/utils/notificationHelper';
 import { useAppSelector } from '@/states/store';
+import { useButtonAvailability } from '@/utils/useButtonAvailability';
 
 const FunctionButton = ({
   title,
@@ -18,8 +19,14 @@ const FunctionButton = ({
   iconName: string;
 }) => {
   const dispatch = useDispatch();
-const themeType = useAppSelector((state) => state.theme.themeType);
+  const themeType = useAppSelector((state) => state.theme.themeType);
+  const { disabled } = useButtonAvailability(action);
+  
   const handleButtonClick = () => {
+    if (disabled) {
+      return;
+    }
+    
     if (action === 'AddMark' ||
       action === 'Delete Digital Mask' ||
       action === 'Crop Selected Area' ||
@@ -52,6 +59,7 @@ const themeType = useAppSelector((state) => state.theme.themeType);
   return (
     <Button
       onClick={handleButtonClick}
+      disabled={disabled}
       icon={
         <Icon
           module="module-process"
@@ -69,7 +77,7 @@ const themeType = useAppSelector((state) => state.theme.themeType);
         //minWidth: 44,            // 保险
         //overflow: 'hidden',      // 超出的文字裁掉
       }}
-      title={title}
+      title={disabled ? `${title} (多分格模式下不可用)` : title}
       className="truncate-text"
     >
       {/* {title} */}

+ 7 - 1
src/pages/view/components/ImageStateControl.tsx

@@ -12,6 +12,7 @@ import {
 } from '@/states/exam/bodyPositionListSlice';
 import { getDcmImageUrl } from '@/API/bodyPosition';
 import Icon from '@/components/Icon';
+import { useButtonAvailability } from '@/utils/useButtonAvailability';
 
 /**
  * 图像状态控制组件
@@ -28,7 +29,9 @@ import Icon from '@/components/Icon';
  */
 const ImageStateControl: React.FC = () => {
   const dispatch = useAppDispatch();
-
+  const { disabled:ofReject } = useButtonAvailability('拒绝');
+  const { disabled:ofRecover } = useButtonAvailability('恢复');
+  const { disabled:ofSaveAs } = useButtonAvailability('另存为');
   // 获取必要的状态
   const selectedViewers = useSelector(selectSelectedViewers);
   const gridLayout = useSelector(selectGridLayout);
@@ -160,6 +163,7 @@ const ImageStateControl: React.FC = () => {
             height: '1.5rem',
             padding: 0,
           }}
+          disabled={ofReject}
           title="拒绝"
         />
       )}
@@ -183,6 +187,7 @@ const ImageStateControl: React.FC = () => {
             padding: 0,
           }}
           title="恢复"
+          disabled={ofRecover}
         />
       )}
       {showSaveAsButton && (
@@ -205,6 +210,7 @@ const ImageStateControl: React.FC = () => {
             padding: 0,
           }}
           title="另存为"
+          disabled={ofSaveAs}
         />
       )}
     </Flex>

+ 7 - 0
src/pages/view/components/TransferArea.tsx

@@ -2,11 +2,16 @@ import React from 'react';
 import { Button } from 'antd';
 import { useDispatch } from 'react-redux';
 import { switchToSendPanel } from '../../../states/panelSwitchSliceForView';
+import { useButtonAvailability } from '@/utils/useButtonAvailability';
 
 const TransferArea = () => {
   const dispatch = useDispatch();
+  const { disabled } = useButtonAvailability('Send');
 
   const handleSendClick = () => {
+    if (disabled) {
+      return;
+    }
     dispatch(switchToSendPanel());
   };
 
@@ -19,6 +24,8 @@ const TransferArea = () => {
           padding: 0,
         }}
         onClick={handleSendClick}
+        disabled={disabled}
+        title={disabled ? 'Send (多分格模式下不可用)' : 'Send'}
       >
         Send
       </Button>

+ 75 - 0
src/utils/buttonAvailabilityConfig.ts

@@ -0,0 +1,75 @@
+// 按钮可用性配置
+export interface ButtonAvailabilityConfig {
+  action: string;
+  multiGridDisabled?: boolean;
+  singleGridDisabled?: boolean;
+  tooltip?: string;
+}
+
+// 多分格时不可用的按钮列表
+export const MULTI_GRID_DISABLED_BUTTONS = [
+  'Add L Mark',
+  'Add R Mark',
+  'AddMark',
+  'Delete Selected Mark',
+  'Add Mask',
+  'Delete Mask',
+  'Rotate Any Angle',
+  'Crop Selected Area',
+  'Delete Digital Mask',
+  'Magnifier',
+  'Invert Image',
+  'Reset Image',
+  'Snapshot',
+  'Advanced Processing',
+  'Image Measurement',
+  'Rectangle Crop',
+  'More'
+];
+
+// 单分格时不可用的按钮列表(如果有的话)
+export const SINGLE_GRID_DISABLED_BUTTONS :string[]= [];
+
+// 获取按钮可用性配置
+export const getButtonAvailabilityConfig = (action: string): ButtonAvailabilityConfig => {
+  // 默认配置
+  const config: ButtonAvailabilityConfig = {
+    action,
+    multiGridDisabled: MULTI_GRID_DISABLED_BUTTONS.includes(action),
+    singleGridDisabled: SINGLE_GRID_DISABLED_BUTTONS.includes(action),
+  };
+
+  // 特殊按钮的额外配置
+  switch (action) {
+    case 'Send':
+      config.multiGridDisabled = false;
+      config.singleGridDisabled = false;
+      break;
+    case '拒绝':
+      config.multiGridDisabled = true;
+      config.singleGridDisabled = true;
+      break;
+    case '恢复':
+      config.multiGridDisabled = true;
+      config.singleGridDisabled = true;
+      break;
+    case '另存为':
+      config.multiGridDisabled = true;
+      config.singleGridDisabled = true;
+      break;
+    default:
+      break;
+  }
+
+  return config;
+};
+
+// 判断按钮是否应该在多分格模式下禁用
+export const isButtonDisabledInMultiGrid = (action: string): boolean => {
+  return MULTI_GRID_DISABLED_BUTTONS.includes(action);
+};
+
+// 判断按钮是否应该在单分格模式下禁用
+export const isButtonDisabledInSingleGrid = (action: string): boolean => {
+  return SINGLE_GRID_DISABLED_BUTTONS.includes(action);
+};

+ 42 - 0
src/utils/useButtonAvailability.ts

@@ -0,0 +1,42 @@
+import { useSelector } from 'react-redux';
+import { selectGridLayout } from '@/states/view/viewerContainerSlice';
+import { getButtonAvailabilityConfig } from './buttonAvailabilityConfig';
+
+/**
+ * 自定义 Hook 用于判断按钮可用性
+ * @param action 按钮动作名称
+ * @returns 按钮可用性配置对象
+ */
+export const useButtonAvailability = (action: string) => {
+  // 获取当前网格布局
+  const gridLayout = useSelector(selectGridLayout);
+  
+  // 获取按钮可用性配置
+  const config = getButtonAvailabilityConfig(action);
+  
+  // 根据布局状态确定按钮是否应该禁用
+  const isDisabled = gridLayout !== '1x1' ? config.multiGridDisabled : config.singleGridDisabled;
+  
+  return {
+    ...config,
+    disabled: isDisabled,
+  };
+};
+
+/**
+ * 判断按钮是否应该在多分格模式下禁用
+ * @param action 按钮动作名称
+ * @returns 是否禁用
+ */
+export const useIsButtonDisabledInMultiGrid = (action: string) => {
+  return getButtonAvailabilityConfig(action).multiGridDisabled;
+};
+
+/**
+ * 判断按钮是否应该在单分格模式下禁用
+ * @param action 按钮动作名称
+ * @returns 是否禁用
+ */
+export const useIsButtonDisabledInSingleGrid = (action: string) => {
+  return getButtonAvailabilityConfig(action).singleGridDisabled;
+};