Skip to content

Commit 4263a91

Browse files
committed
do not block the grab with selection
1 parent 543ea0b commit 4263a91

File tree

4 files changed

+80
-5
lines changed

4 files changed

+80
-5
lines changed

compose/neurosynth-frontend/src/pages/Study/components/EditStudyAnnotationsHotTable.tsx

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
useAnnotationNoteKeys,
1616
useCreateAnnotationColumn,
1717
useRemoveAnnotationColumn,
18+
useReorderAnnotationColumns,
1819
useUpdateAnnotationNotes,
1920
} from 'stores/AnnotationStore.actions';
2021

@@ -24,6 +25,7 @@ const EditStudyAnnotationsHotTable: React.FC<{ readonly?: boolean }> = ({ readon
2425
const updateNotes = useUpdateAnnotationNotes();
2526
const createAnnotationColumn = useCreateAnnotationColumn();
2627
const removeAnnotationColumn = useRemoveAnnotationColumn();
28+
const reorderAnnotationColumns = useReorderAnnotationColumns();
2729
const { colWidths, colHeaders, columns, hiddenRows, data } = useEditStudyAnnotationsHotTable(readonly);
2830
const projectUser = useProjectUser();
2931
const canEdit = useUserCanEdit(projectUser || undefined);
@@ -87,11 +89,47 @@ const EditStudyAnnotationsHotTable: React.FC<{ readonly?: boolean }> = ({ readon
8789

8890
const handleCellMouseUp = (event: MouseEvent, coords: CellCoords, TD: HTMLTableCellElement) => {
8991
const target = event.target as HTMLButtonElement;
90-
if (coords.row < 0 && (target.tagName === 'svg' || target.tagName === 'path')) {
91-
setConfirmationDialogState({
92-
isOpen: true,
93-
colKey: TD.innerText,
94-
});
92+
if (coords.row < 0) {
93+
const removeTarget = (target as HTMLElement).closest('[data-remove-col="true"]');
94+
if (removeTarget) {
95+
const colKey = (target as HTMLElement).closest('[data-col-key]')?.getAttribute('data-col-key');
96+
if (!colKey) return;
97+
setConfirmationDialogState({
98+
isOpen: true,
99+
colKey: colKey,
100+
});
101+
}
102+
}
103+
};
104+
105+
const handleColumnMove = (movedColumns: number[], finalIndex: number) => {
106+
if (readonly || !canEdit) return;
107+
if (!movedColumns.length) return;
108+
109+
const fromVisualIndex = movedColumns[0];
110+
const toVisualIndex = finalIndex;
111+
112+
// first two columns are static (analysis name/description)
113+
if (fromVisualIndex < 2 || toVisualIndex < 2) return;
114+
115+
const from = fromVisualIndex - 2;
116+
let to = toVisualIndex - 2;
117+
118+
if (!noteKeys) return;
119+
if (to >= noteKeys.length) to = noteKeys.length - 1;
120+
121+
reorderAnnotationColumns(from, to);
122+
hotTableRef.current?.hotInstance?.getPlugin('manualColumnMove').clearMoves();
123+
};
124+
125+
const handleBeforeOnCellMouseDown = (event: MouseEvent, coords: CellCoords) => {
126+
if (coords.row < 0) {
127+
const target = event.target as HTMLElement;
128+
const isDragHandle = target?.closest('[data-drag-handle="true"]');
129+
if (isDragHandle) {
130+
// allow drag to proceed; prevent default selection highlighting
131+
event.preventDefault();
132+
}
95133
}
96134
};
97135

@@ -145,6 +183,9 @@ const EditStudyAnnotationsHotTable: React.FC<{ readonly?: boolean }> = ({ readon
145183
indicators: false,
146184
}}
147185
afterOnCellMouseUp={handleCellMouseUp}
186+
beforeOnCellMouseDown={handleBeforeOnCellMouseDown}
187+
manualColumnMove={!readonly && canEdit}
188+
afterColumnMove={handleColumnMove}
148189
colWidths={colWidths}
149190
columns={columns}
150191
colHeaders={colHeaders}

compose/neurosynth-frontend/src/stores/AnnotationStore.actions.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ export const useCreateAnnotationNote = () => useAnnotationStore((state) => state
2020

2121
export const useDeleteAnnotationNote = () => useAnnotationStore((state) => state.deleteAnnotationNote);
2222
export const useUpdateAnnotationNoteName = () => useAnnotationStore((state) => state.updateAnnotationNoteName);
23+
export const useReorderAnnotationColumns = () => useAnnotationStore((state) => state.reorderAnnotationColumns);

compose/neurosynth-frontend/src/stores/AnnotationStore.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,38 @@ export const useAnnotationStore = create<
208208
},
209209
}));
210210
},
211+
reorderAnnotationColumns: (fromIndex, toIndex) => {
212+
setUnloadHandler('annotation');
213+
set((state) => {
214+
if (!state.annotation.note_keys) return state;
215+
if (fromIndex === toIndex) return state;
216+
const noteKeysOnly = [...state.annotation.note_keys];
217+
if (fromIndex < 0 || fromIndex >= noteKeysOnly.length) return state;
218+
if (toIndex < 0 || toIndex >= noteKeysOnly.length) return state;
219+
220+
const updatedNoteKeys = normalizeNoteKeyOrder(
221+
noteKeysOnly.reduce((acc, curr, idx) => {
222+
acc.push(curr);
223+
return acc;
224+
}, [] as NoteKeyType[])
225+
);
226+
227+
const [removed] = updatedNoteKeys.splice(fromIndex, 1);
228+
updatedNoteKeys.splice(toIndex, 0, removed);
229+
230+
return {
231+
...state,
232+
annotation: {
233+
...state.annotation,
234+
note_keys: normalizeNoteKeyOrder(updatedNoteKeys),
235+
},
236+
storeMetadata: {
237+
...state.storeMetadata,
238+
annotationIsEdited: true,
239+
},
240+
};
241+
});
242+
},
211243
createAnnotationNote: (analysisId, studyId, analysisName) => {
212244
setUnloadHandler('annotation');
213245
set((state) => {

compose/neurosynth-frontend/src/stores/AnnotationStore.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export type AnnotationStoreActions = {
2828
deleteAnnotationNote: (analysisId: string) => void;
2929
updateAnnotationNoteName: (analysis: Partial<IStoreNoteCollectionReturn>) => void;
3030
removeAnnotationColumn: (noteKey: string) => void;
31+
reorderAnnotationColumns: (fromIndex: number, toIndex: number) => void;
3132
};
3233

3334
export type AnnotationNoteType = {

0 commit comments

Comments
 (0)