|
|
@@ -1,135 +1,138 @@
|
|
|
-// src/features/imageAnnotation/state/annotationSlice.ts
|
|
|
-// Redux状态管理 - 注释相关状态
|
|
|
-
|
|
|
-import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
|
-import type { AnnotationState } from '../types/annotation';
|
|
|
-import { AnnotationStatus } from '../types/annotation';
|
|
|
-
|
|
|
-const initialState: AnnotationState = {
|
|
|
- annotations: new Map(),
|
|
|
- status: AnnotationStatus.IDLE,
|
|
|
- error: null,
|
|
|
- lastSaved: null,
|
|
|
-};
|
|
|
-
|
|
|
-const annotationSlice = createSlice({
|
|
|
- name: 'annotation',
|
|
|
- initialState,
|
|
|
- reducers: {
|
|
|
- // 设置加载状态
|
|
|
- setLoading: (state) => {
|
|
|
- state.status = AnnotationStatus.LOADING;
|
|
|
- state.error = null;
|
|
|
- },
|
|
|
-
|
|
|
- // 设置保存状态
|
|
|
- setSaving: (state) => {
|
|
|
- state.status = AnnotationStatus.SAVING;
|
|
|
- state.error = null;
|
|
|
- },
|
|
|
-
|
|
|
- // 设置成功状态
|
|
|
- setSuccess: (state) => {
|
|
|
- state.status = AnnotationStatus.SUCCESS;
|
|
|
- state.error = null;
|
|
|
- state.lastSaved = new Date();
|
|
|
- },
|
|
|
-
|
|
|
- // 设置错误状态
|
|
|
- setError: (state, action: PayloadAction<string>) => {
|
|
|
- state.status = AnnotationStatus.ERROR;
|
|
|
- state.error = action.payload;
|
|
|
- },
|
|
|
-
|
|
|
- // 重置状态
|
|
|
- resetStatus: (state) => {
|
|
|
- state.status = AnnotationStatus.IDLE;
|
|
|
- state.error = null;
|
|
|
- },
|
|
|
-
|
|
|
- // 添加注释
|
|
|
- addAnnotation: (state, action: PayloadAction<any>) => {
|
|
|
- state.annotations.set(action.payload.id || action.payload.annotationUID, action.payload);
|
|
|
- },
|
|
|
-
|
|
|
- // 更新注释
|
|
|
- updateAnnotation: (state, action: PayloadAction<any>) => {
|
|
|
- state.annotations.set(action.payload.id || action.payload.annotationUID, action.payload);
|
|
|
- },
|
|
|
-
|
|
|
- // 删除注释
|
|
|
- removeAnnotation: (state, action: PayloadAction<string>) => {
|
|
|
- state.annotations.delete(action.payload);
|
|
|
- },
|
|
|
-
|
|
|
- // 批量设置注释
|
|
|
- setAnnotations: (state, action: PayloadAction<any[]>) => {
|
|
|
- state.annotations.clear();
|
|
|
- action.payload.forEach(annotation => {
|
|
|
- state.annotations.set(annotation.id || annotation.annotationUID, annotation);
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- // 清空注释
|
|
|
- clearAnnotations: (state) => {
|
|
|
- state.annotations.clear();
|
|
|
- state.lastSaved = null;
|
|
|
- },
|
|
|
-
|
|
|
- // 设置注释高亮状态
|
|
|
- setAnnotationHighlighted: (state, action: PayloadAction<{ id: string; highlighted: boolean }>) => {
|
|
|
- const annotation = state.annotations.get(action.payload.id);
|
|
|
- if (annotation) {
|
|
|
- annotation.highlighted = action.payload.highlighted;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- // 设置注释选中状态
|
|
|
- setAnnotationSelected: (state, action: PayloadAction<{ id: string; selected: boolean }>) => {
|
|
|
- const annotation = state.annotations.get(action.payload.id);
|
|
|
- if (annotation) {
|
|
|
- annotation.isSelected = action.payload.selected;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- // 批量更新注释状态
|
|
|
- updateAnnotationsStatus: (state, action: PayloadAction<{ ids: string[]; status: any }>) => {
|
|
|
- action.payload.ids.forEach(id => {
|
|
|
- const annotation = state.annotations.get(id);
|
|
|
- if (annotation) {
|
|
|
- Object.assign(annotation, action.payload.status);
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- },
|
|
|
-});
|
|
|
-
|
|
|
-export const {
|
|
|
- setLoading,
|
|
|
- setSaving,
|
|
|
- setSuccess,
|
|
|
- setError,
|
|
|
- resetStatus,
|
|
|
- addAnnotation,
|
|
|
- updateAnnotation,
|
|
|
- removeAnnotation,
|
|
|
- setAnnotations,
|
|
|
- clearAnnotations,
|
|
|
- setAnnotationHighlighted,
|
|
|
- setAnnotationSelected,
|
|
|
- updateAnnotationsStatus,
|
|
|
-} = annotationSlice.actions;
|
|
|
-
|
|
|
-// 选择器
|
|
|
-export const selectAnnotations = (state: { annotation: AnnotationState }) => state.annotation.annotations;
|
|
|
-export const selectAnnotationStatus = (state: { annotation: AnnotationState }) => state.annotation.status;
|
|
|
-export const selectAnnotationError = (state: { annotation: AnnotationState }) => state.annotation.error;
|
|
|
-export const selectAnnotationLastSaved = (state: { annotation: AnnotationState }) => state.annotation.lastSaved;
|
|
|
-export const selectAnnotationById = (id: string) => (state: { annotation: AnnotationState }) =>
|
|
|
- state.annotation.annotations.get(id);
|
|
|
-export const selectAnnotationsByImage = (imageId: string) => (state: { annotation: AnnotationState }) =>
|
|
|
- Array.from(state.annotation.annotations.values()).filter(
|
|
|
- annotation => annotation.sopInstanceUid === imageId || annotation.metadata?.referencedImageId === imageId
|
|
|
- );
|
|
|
-
|
|
|
-export default annotationSlice.reducer;
|
|
|
+// // src/features/imageAnnotation/state/annotationSlice.ts
|
|
|
+// // Redux状态管理 - 注释相关状态
|
|
|
+
|
|
|
+// import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
|
|
+// import type { AnnotationState } from '../types/annotation';
|
|
|
+// import { AnnotationStatus } from '../types/annotation';
|
|
|
+
|
|
|
+// const initialState: AnnotationState = {
|
|
|
+// annotations: Object.create(null),// 使用 as Record<string, any> ,避免控制台出现error
|
|
|
+// status: AnnotationStatus.IDLE,
|
|
|
+// error: null,
|
|
|
+// lastSaved: null,
|
|
|
+// };
|
|
|
+
|
|
|
+// const annotationSlice = createSlice({
|
|
|
+// name: 'annotation',
|
|
|
+// initialState,
|
|
|
+// reducers: {
|
|
|
+// // 设置加载状态
|
|
|
+// setLoading: (state) => {
|
|
|
+// state.status = AnnotationStatus.LOADING;
|
|
|
+// state.error = null;
|
|
|
+// },
|
|
|
+
|
|
|
+// // 设置保存状态
|
|
|
+// setSaving: (state) => {
|
|
|
+// state.status = AnnotationStatus.SAVING;
|
|
|
+// state.error = null;
|
|
|
+// },
|
|
|
+
|
|
|
+// // 设置成功状态
|
|
|
+// setSuccess: (state) => {
|
|
|
+// state.status = AnnotationStatus.SUCCESS;
|
|
|
+// state.error = null;
|
|
|
+// state.lastSaved = new Date().toISOString();
|
|
|
+// },
|
|
|
+
|
|
|
+// // 设置错误状态
|
|
|
+// setError: (state, action: PayloadAction<string>) => {
|
|
|
+// state.status = AnnotationStatus.ERROR;
|
|
|
+// state.error = action.payload;
|
|
|
+// },
|
|
|
+
|
|
|
+// // 重置状态
|
|
|
+// resetStatus: (state) => {
|
|
|
+// state.status = AnnotationStatus.IDLE;
|
|
|
+// state.error = null;
|
|
|
+// },
|
|
|
+
|
|
|
+// // 添加注释
|
|
|
+// addAnnotation: (state, action: PayloadAction<any>) => {
|
|
|
+// const key = action.payload.id || action.payload.annotationUID;
|
|
|
+// state.annotations[key] = action.payload;
|
|
|
+// },
|
|
|
+
|
|
|
+// // 更新注释
|
|
|
+// updateAnnotation: (state, action: PayloadAction<any>) => {
|
|
|
+// const key = action.payload.id || action.payload.annotationUID;
|
|
|
+// state.annotations[key] = action.payload;
|
|
|
+// },
|
|
|
+
|
|
|
+// // 删除注释
|
|
|
+// removeAnnotation: (state, action: PayloadAction<string>) => {
|
|
|
+// delete state.annotations[action.payload];
|
|
|
+// },
|
|
|
+
|
|
|
+// // 批量设置注释
|
|
|
+// setAnnotations: (state, action: PayloadAction<any[]>) => {
|
|
|
+// state.annotations = {};
|
|
|
+// action.payload.forEach(annotation => {
|
|
|
+// const key = annotation.id || annotation.annotationUID;
|
|
|
+// state.annotations[key] = annotation;
|
|
|
+// });
|
|
|
+// },
|
|
|
+
|
|
|
+// // 清空注释
|
|
|
+// clearAnnotations: (state) => {
|
|
|
+// state.annotations = {};
|
|
|
+// state.lastSaved = null;
|
|
|
+// },
|
|
|
+
|
|
|
+// // 设置注释高亮状态
|
|
|
+// setAnnotationHighlighted: (state, action: PayloadAction<{ id: string; highlighted: boolean }>) => {
|
|
|
+// const annotation = state.annotations[action.payload.id];
|
|
|
+// if (annotation) {
|
|
|
+// annotation.highlighted = action.payload.highlighted;
|
|
|
+// }
|
|
|
+// },
|
|
|
+
|
|
|
+// // 设置注释选中状态
|
|
|
+// setAnnotationSelected: (state, action: PayloadAction<{ id: string; selected: boolean }>) => {
|
|
|
+// const annotation = state.annotations[action.payload.id];
|
|
|
+// if (annotation) {
|
|
|
+// annotation.isSelected = action.payload.selected;
|
|
|
+// }
|
|
|
+// },
|
|
|
+
|
|
|
+// // 批量更新注释状态
|
|
|
+// updateAnnotationsStatus: (state, action: PayloadAction<{ ids: string[]; status: any }>) => {
|
|
|
+// action.payload.ids.forEach(id => {
|
|
|
+// const annotation = state.annotations[id];
|
|
|
+// if (annotation) {
|
|
|
+// Object.assign(annotation, action.payload.status);
|
|
|
+// }
|
|
|
+// });
|
|
|
+// },
|
|
|
+// },
|
|
|
+// });
|
|
|
+
|
|
|
+// export const {
|
|
|
+// setLoading,
|
|
|
+// setSaving,
|
|
|
+// setSuccess,
|
|
|
+// setError,
|
|
|
+// resetStatus,
|
|
|
+// addAnnotation,
|
|
|
+// updateAnnotation,
|
|
|
+// removeAnnotation,
|
|
|
+// setAnnotations,
|
|
|
+// clearAnnotations,
|
|
|
+// setAnnotationHighlighted,
|
|
|
+// setAnnotationSelected,
|
|
|
+// updateAnnotationsStatus,
|
|
|
+// } = annotationSlice.actions;
|
|
|
+
|
|
|
+// // 选择器
|
|
|
+// export const selectAnnotations = (state: { annotation: AnnotationState }) => state.annotation.annotations;
|
|
|
+// export const selectAnnotationStatus = (state: { annotation: AnnotationState }) => state.annotation.status;
|
|
|
+// export const selectAnnotationError = (state: { annotation: AnnotationState }) => state.annotation.error;
|
|
|
+// export const selectAnnotationLastSaved = (state: { annotation: AnnotationState }) => state.annotation.lastSaved;
|
|
|
+// export const selectAnnotationById = (id: string) => (state: { annotation: AnnotationState }) =>
|
|
|
+// state.annotation.annotations[id];
|
|
|
+// export const selectAnnotationsByImage = (imageId: string) => (state: { annotation: AnnotationState }) =>
|
|
|
+// Object.values(state.annotation.annotations).filter(
|
|
|
+// annotation => annotation.sopInstanceUid === imageId || annotation.metadata?.referencedImageId === imageId
|
|
|
+// );
|
|
|
+
|
|
|
+// export default annotationSlice.reducer;
|