Skip to content

Commit 9281299

Browse files
authored
Fix a number of cyclic dependency imports (#9204)
This PR fixes a number of cyclic dependency imports. All fixes were simply done by moving code around. 1. `04_configure_new_dataset.tsx` --> `toast.tsx` - the method `Toast.guardedWithErrorToast` was only used in `04_confiure_new_dataset` and nowwhere else. just moved it. 2. `flycam_accessor` --> `flycam_reducer` - `rotateOnAxis` is the only import from `flycam_reducer` into `flycam_accessor`. The other way around, the reducer already imported a bunch of stuff from the accessor. So I moved this utility to the accesor. 3. `task_create_bulk_view.ts` --> `task_create_from_view.ts` - move shared methods in a new file `task_create_utils.ts` 4. `skeletontracing_accessor.ts` --> `tree_hierarchy_view_helpers.ts` --> `tree_hierarchy_view` - moved `mapGroups` and related method `mapGroupsWithRoot` to `tree_hierarchy_view_helpers` to break the cycle. One could argue, that these methods should have been there in the first place, since the all relate to tree hierarchies. ### URL of deployed dev instance (used for testing): - https://___.webknossos.xyz ### Steps to test: - CI should be enough ### Issues: - Contributes to #9243 ------ (Please delete unneeded items, merge only when none are left open) - [ ] Added changelog entry (create a `$PR_NUMBER.md` file in `unreleased_changes` or use `./tools/create-changelog-entry.py`) - [ ] Added migration guide entry if applicable (edit the same file as for the changelog) - [ ] Updated [documentation](../blob/master/docs) if applicable - [ ] Adapted [wk-libs python client](https://github.com/scalableminds/webknossos-libs/tree/master/webknossos/webknossos/client) if relevant API parts change - [ ] Removed dev-only changes like prints and application.conf edits - [ ] Considered [common edge cases](../blob/master/.github/common_edge_cases.md) - [ ] Needs datastore update after deployment
1 parent 6ba0aa7 commit 9281299

File tree

16 files changed

+151
-163
lines changed

16 files changed

+151
-163
lines changed

frontend/javascripts/admin/api/tasks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type {
33
NewNmlTask,
44
NewTask,
55
TaskCreationResponseContainer,
6-
} from "admin/task/task_create_bulk_view";
6+
} from "admin/task/task_create_utils";
77
import type { QueryObject } from "admin/task/task_search_form";
88
import type { RequestOptions } from "libs/request";
99
import Request from "libs/request";

frontend/javascripts/admin/dataset/composition_wizard/04_configure_new_dataset.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ import {
1919
} from "antd";
2020
import { FormItemWithInfo } from "dashboard/dataset/helper_components";
2121
import FolderSelection from "dashboard/folders/folder_selection";
22+
import ErrorHandling from "libs/error_handling";
2223
import { estimateAffineMatrix4x4 } from "libs/estimate_affine";
2324
import { formatNumber } from "libs/format_utils";
2425
import { useEffectOnlyOnce } from "libs/react_hooks";
2526
import { useWkSelector } from "libs/react_hooks";
26-
import Toast, { guardedWithErrorToast } from "libs/toast";
27+
import Toast from "libs/toast";
2728
import { isUserAdminOrDatasetManager } from "libs/utils";
2829
import uniqBy from "lodash-es/uniqBy";
2930
import messages from "messages";
@@ -39,6 +40,16 @@ import type { WizardComponentProps } from "./common";
3940

4041
const FormItem = Form.Item;
4142

43+
async function guardedWithErrorToast(fn: () => Promise<any>) {
44+
try {
45+
await fn();
46+
} catch (error) {
47+
Toast.error("An unexpected error occurred. Please check the console for details");
48+
console.error(error);
49+
ErrorHandling.notify(error as Error);
50+
}
51+
}
52+
4253
export function ConfigureNewDataset(props: WizardComponentProps) {
4354
const formRef = React.useRef<FormInstance<any>>(null);
4455

frontend/javascripts/admin/task/task_create_bulk_view.tsx

Lines changed: 6 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,72 +7,17 @@ import isString from "lodash-es/isString";
77
import uniq from "lodash-es/uniq";
88
import Messages from "messages";
99
import { useState } from "react";
10-
import type { APITask } from "types/api_types";
1110
import type { Vector3 } from "viewer/constants";
12-
import type { BoundingBoxObject } from "viewer/store";
11+
import {
12+
NUM_TASKS_PER_BATCH,
13+
type NewTask,
14+
type TaskCreationResponse,
15+
normalizeFileEvent,
16+
} from "./task_create_utils";
1317

1418
const FormItem = Form.Item;
1519
const { TextArea } = Input;
1620

17-
export const NUM_TASKS_PER_BATCH = 100;
18-
export type NewTask = {
19-
readonly boundingBox: BoundingBoxObject | null | undefined;
20-
readonly datasetId: string;
21-
readonly editPosition: Vector3;
22-
readonly editRotation: Vector3;
23-
readonly neededExperience: {
24-
readonly domain: string;
25-
readonly value: number;
26-
};
27-
readonly projectName: string;
28-
readonly scriptId: string | null | undefined;
29-
readonly pendingInstances: number;
30-
readonly taskTypeId: string;
31-
readonly csvFile?: File;
32-
readonly nmlFiles?: File[];
33-
readonly baseAnnotation?:
34-
| {
35-
baseId: string;
36-
}
37-
| null
38-
| undefined;
39-
};
40-
41-
export type NewNmlTask = Pick<
42-
NewTask,
43-
| "taskTypeId"
44-
| "neededExperience"
45-
| "pendingInstances"
46-
| "projectName"
47-
| "scriptId"
48-
| "boundingBox"
49-
>;
50-
51-
export type TaskCreationResponse = {
52-
status: number;
53-
success?: APITask;
54-
error?: string;
55-
};
56-
57-
export type TaskCreationResponseContainer = {
58-
tasks: TaskCreationResponse[];
59-
warnings: string[];
60-
};
61-
62-
export function normalizeFileEvent(
63-
event:
64-
| File[]
65-
| {
66-
fileList: File[];
67-
},
68-
) {
69-
if (Array.isArray(event)) {
70-
return event;
71-
}
72-
73-
return event?.fileList;
74-
}
75-
7621
function TaskCreateBulkView() {
7722
const { modal } = App.useApp();
7823

frontend/javascripts/admin/task/task_create_form_view.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,6 @@ import {
77
getTaskTypes,
88
getUnversionedAnnotationInformation,
99
} from "admin/rest_api";
10-
import type {
11-
NewNmlTask,
12-
NewTask,
13-
TaskCreationResponse,
14-
TaskCreationResponseContainer,
15-
} from "admin/task/task_create_bulk_view";
16-
import { NUM_TASKS_PER_BATCH, normalizeFileEvent } from "admin/task/task_create_bulk_view";
1710
import {
1811
Alert,
1912
App,
@@ -53,6 +46,13 @@ import { useNavigate, useParams } from "react-router-dom";
5346
import type { APIDataset, APIProject, APIScript, APITask, APITaskType } from "types/api_types";
5447
import type { Vector3, Vector6 } from "viewer/constants";
5548
import type { BoundingBoxObject } from "viewer/store";
49+
import type {
50+
NewNmlTask,
51+
NewTask,
52+
TaskCreationResponse,
53+
TaskCreationResponseContainer,
54+
} from "./task_create_utils";
55+
import { NUM_TASKS_PER_BATCH, normalizeFileEvent } from "./task_create_utils";
5656

5757
const FormItem = Form.Item;
5858
const RadioGroup = Radio.Group;
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import type { APITask } from "types/api_types";
2+
import type { BoundingBoxObject } from "types/bounding_box";
3+
import type { Vector3 } from "viewer/constants";
4+
5+
export const NUM_TASKS_PER_BATCH = 100;
6+
export type NewTask = {
7+
readonly boundingBox: BoundingBoxObject | null | undefined;
8+
readonly datasetId: string;
9+
readonly editPosition: Vector3;
10+
readonly editRotation: Vector3;
11+
readonly neededExperience: {
12+
readonly domain: string;
13+
readonly value: number;
14+
};
15+
readonly projectName: string;
16+
readonly scriptId: string | null | undefined;
17+
readonly pendingInstances: number;
18+
readonly taskTypeId: string;
19+
readonly csvFile?: File;
20+
readonly nmlFiles?: File[];
21+
readonly baseAnnotation?:
22+
| {
23+
baseId: string;
24+
}
25+
| null
26+
| undefined;
27+
};
28+
29+
export type NewNmlTask = Pick<
30+
NewTask,
31+
| "taskTypeId"
32+
| "neededExperience"
33+
| "pendingInstances"
34+
| "projectName"
35+
| "scriptId"
36+
| "boundingBox"
37+
>;
38+
39+
export type TaskCreationResponse = {
40+
status: number;
41+
success?: APITask;
42+
error?: string;
43+
};
44+
45+
export type TaskCreationResponseContainer = {
46+
tasks: TaskCreationResponse[];
47+
warnings: string[];
48+
};
49+
50+
export function normalizeFileEvent(
51+
event:
52+
| File[]
53+
| {
54+
fileList: File[];
55+
},
56+
) {
57+
if (Array.isArray(event)) {
58+
return event;
59+
}
60+
61+
return event?.fileList;
62+
}

frontend/javascripts/libs/toast.tsx

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,6 @@ type ToastParams = {
3838
details?: string;
3939
};
4040

41-
export async function guardedWithErrorToast(fn: () => Promise<any>) {
42-
try {
43-
await fn();
44-
} catch (error) {
45-
import("libs/error_handling").then((_ErrorHandling) => {
46-
const ErrorHandling = _ErrorHandling.default;
47-
Toast.error("An unexpected error occurred. Please check the console for details");
48-
console.error(error);
49-
ErrorHandling.notify(error as Error);
50-
});
51-
}
52-
}
53-
5441
const Toast = {
5542
// The notificationAPI is designed to be a singleton spawned by the ToastContextMountRoot
5643
// mounted in the GlobalThemeProvider.

frontend/javascripts/viewer/api/api_latest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ import {
7575
getTreeAndNode,
7676
getTreeAndNodeOrNull,
7777
getTreeGroupsMap,
78-
mapGroups,
7978
} from "viewer/model/accessors/skeletontracing_accessor";
8079
import { AnnotationTool, type AnnotationToolId } from "viewer/model/accessors/tool_accessor";
8180
import {
@@ -188,6 +187,7 @@ import {
188187
MISSING_GROUP_ID,
189188
callDeep,
190189
createGroupToSegmentsMap,
190+
mapGroups,
191191
moveGroupsHelper,
192192
} from "viewer/view/right-border-tabs/trees_tab/tree_hierarchy_view_helpers";
193193

frontend/javascripts/viewer/model/accessors/flycam_accessor.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ import {
4949
invertTransform,
5050
transformPointUnscaled,
5151
} from "../helpers/transformation_helpers";
52-
import { rotateOnAxis } from "../reducers/flycam_reducer";
5352
import { reuseInstanceOnEquality } from "./accessor_helpers";
5453

5554
export const ZOOM_STEP_INTERVAL = 1.1;
@@ -745,3 +744,6 @@ function _getActiveMagInfo(state: WebknossosState) {
745744
}
746745

747746
export const getActiveMagInfo = reuseInstanceOnEquality(_getActiveMagInfo);
747+
export function rotateOnAxis(currentMatrix: Matrix4x4, angle: number, axis: Vector3): Matrix4x4 {
748+
return M4x4.rotate(angle, axis, currentMatrix, []);
749+
}

frontend/javascripts/viewer/model/accessors/skeletontracing_accessor.ts

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@ import {
1515
TreeMap,
1616
} from "viewer/model/types/tree_types";
1717
import type { NumberLike, SkeletonTracing, StoreAnnotation, WebknossosState } from "viewer/store";
18-
import {
19-
MISSING_GROUP_ID,
20-
findGroup,
21-
} from "viewer/view/right-border-tabs/trees_tab/tree_hierarchy_view_helpers";
18+
import { findGroup } from "viewer/view/right-border-tabs/trees_tab/tree_hierarchy_view_helpers";
2219
import { max } from "../helpers/iterator_utils";
2320
import { invertTransform, transformPointUnscaled } from "../helpers/transformation_helpers";
2421
import {
@@ -329,30 +326,3 @@ export function* mapGroupsToGenerator<R>(
329326
}
330327
}
331328
}
332-
333-
function mapGroupAndChildrenHelper(group: TreeGroup, fn: (g: TreeGroup) => TreeGroup): TreeGroup {
334-
const newChildren = mapGroups(group.children, fn);
335-
return fn({ ...group, children: newChildren });
336-
}
337-
338-
export function mapGroups(groups: TreeGroup[], fn: (g: TreeGroup) => TreeGroup): TreeGroup[] {
339-
return groups.map((group) => mapGroupAndChildrenHelper(group, fn));
340-
}
341-
342-
export function mapGroupsWithRoot(
343-
groups: TreeGroup[],
344-
fn: (g: TreeGroup) => TreeGroup,
345-
): TreeGroup[] {
346-
// Add the virtual root group so that the map function can also mutate
347-
// the high-level elements (e.g., filtering elements in the first level).
348-
return mapGroups(
349-
[
350-
{
351-
name: "Root",
352-
groupId: MISSING_GROUP_ID,
353-
children: groups,
354-
},
355-
],
356-
fn,
357-
)[0].children; // Read the root group's children again
358-
}

frontend/javascripts/viewer/model/reducers/flycam_reducer.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
getRotationInDegrees,
1212
getRotationInRadian,
1313
getValidZoomRangeForUser,
14+
rotateOnAxis,
1415
} from "viewer/model/accessors/flycam_accessor";
1516
import type { Action } from "viewer/model/actions/actions";
1617
import Dimensions from "viewer/model/dimensions";
@@ -39,10 +40,6 @@ function cloneMatrix(m: Matrix4x4): Matrix4x4 {
3940
];
4041
}
4142

42-
export function rotateOnAxis(currentMatrix: Matrix4x4, angle: number, axis: Vector3): Matrix4x4 {
43-
return M4x4.rotate(angle, axis, currentMatrix, []);
44-
}
45-
4643
// Avoid creating new THREE object for some actions.
4744
const flycamRotationEuler = new Euler();
4845
const flycamRotationMatrix = new Matrix4();

0 commit comments

Comments
 (0)