Skip to content

Commit 35a23d3

Browse files
authored
[Admin Views] Use useWkSelector instead of mapStateToProps (#8774)
- Removed Redux `connect` and `mapStateToProps` from multiple admins components, including `DatasetAddRemoteView`, `DatasetAddView`, `ProjectListView`, `ScriptCreateView`, `TaskAnnotationView`, and `UserListView`. - Updated components to directly use `useWkSelector` for accessing the active user state. - Simplified props by eliminating unnecessary state props related to active user. ### URL of deployed dev instance (used for testing): - https://___.webknossos.xyz ### Steps to test: - Type checker should be enough ### Issues: - fixes # ------ (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 49d285d commit 35a23d3

File tree

6 files changed

+36
-88
lines changed

6 files changed

+36
-88
lines changed

frontend/javascripts/admin/dataset/dataset_add_remote_view.tsx

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@ import * as Utils from "libs/utils";
3232
import _ from "lodash";
3333
import messages from "messages";
3434
import React, { useEffect, useState } from "react";
35-
import { connect } from "react-redux";
3635
import { useHistory } from "react-router-dom";
37-
import type { APIDataStore, APIUser } from "types/api_types";
36+
import type { APIDataStore } from "types/api_types";
3837
import type { ArbitraryObject } from "types/globals";
3938
import type { DataLayer, DatasourceConfiguration } from "types/schemas/datasource.types";
4039
import { Unicode } from "viewer/constants";
41-
import type { WebknossosState } from "viewer/store";
40+
41+
import { useWkSelector } from "libs/react_hooks";
4242
import { Hint } from "viewer/view/action-bar/download_modal_view";
4343
import { dataPrivacyInfo } from "./dataset_upload_view";
4444

@@ -48,7 +48,7 @@ const { Password } = Input;
4848

4949
type FileList = UploadFile<any>[];
5050

51-
type OwnProps = {
51+
type Props = {
5252
onAdded: (
5353
uploadedDatasetId: string,
5454
updatedDatasetName: string,
@@ -61,17 +61,13 @@ type OwnProps = {
6161
// the exploration and import.
6262
defaultDatasetUrl?: string | null | undefined;
6363
};
64-
type StateProps = {
65-
activeUser: APIUser | null | undefined;
66-
};
67-
type Props = OwnProps & StateProps;
6864

6965
function ensureLargestSegmentIdsInPlace(datasource: DatasourceConfiguration) {
7066
for (const layer of datasource.dataLayers) {
7167
if (layer.category === "color" || layer.largestSegmentId != null) {
7268
continue;
7369
}
74-
// Make sure the property exists. Otherwise, the field would not be
70+
// Make sure the property exists. Otherwise, a field would not be
7571
// rendered in the form.
7672
layer.largestSegmentId = null;
7773
}
@@ -180,7 +176,8 @@ export function GoogleAuthFormItem({
180176
}
181177

182178
function DatasetAddRemoteView(props: Props) {
183-
const { activeUser, onAdded, datastores, defaultDatasetUrl } = props;
179+
const { onAdded, datastores, defaultDatasetUrl } = props;
180+
const activeUser = useWkSelector((state) => state.activeUser);
184181

185182
const uploadableDatastores = datastores.filter((datastore) => datastore.allowsUpload);
186183
const hasOnlyOneDatastoreOrNone = uploadableDatastores.length <= 1;
@@ -729,9 +726,4 @@ function AddRemoteLayer({
729726
);
730727
}
731728

732-
const mapStateToProps = (state: WebknossosState): StateProps => ({
733-
activeUser: state.activeUser,
734-
});
735-
736-
const connector = connect(mapStateToProps);
737-
export default connector(DatasetAddRemoteView);
729+
export default DatasetAddRemoteView;

frontend/javascripts/admin/dataset/dataset_add_view.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@ import features from "features";
77
import { useFetch } from "libs/react_helpers";
88
import { useWkSelector } from "libs/react_hooks";
99
import React, { useState } from "react";
10-
import { connect } from "react-redux";
1110
import { useHistory } from "react-router-dom";
1211
import type { APIDataStore } from "types/api_types";
1312
import { getReadableURLPart } from "viewer/model/accessors/dataset_accessor";
14-
import { enforceActiveUser } from "viewer/model/accessors/user_accessor";
15-
import type { WebknossosState } from "viewer/store";
1613
import DatasetAddComposeView from "./dataset_add_compose_view";
1714

1815
const { Content, Sider } = Layout;
@@ -261,12 +258,7 @@ function VoxelyticsBanner() {
261258
);
262259
}
263260

264-
const mapStateToProps = (state: WebknossosState) => ({
265-
activeUser: enforceActiveUser(state.activeUser),
266-
});
267-
268-
const connector = connect(mapStateToProps);
269-
export default connector(DatasetAddView);
261+
export default DatasetAddView;
270262

271263
const getPostUploadModal = (
272264
datasetNeedsConversion: boolean,

frontend/javascripts/admin/project/project_list_view.tsx

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,28 @@ import { AsyncLink } from "components/async_clickables";
2828
import FormattedDate from "components/formatted_date";
2929
import { handleGenericError } from "libs/error_handling";
3030
import Persistence from "libs/persistence";
31-
import { useEffectOnlyOnce } from "libs/react_hooks";
31+
import { useEffectOnlyOnce, useWkSelector } from "libs/react_hooks";
3232
import Toast from "libs/toast";
3333
import * as Utils from "libs/utils";
3434
import _ from "lodash";
3535
import messages from "messages";
3636
import React, { useEffect, useState } from "react";
37-
import { connect } from "react-redux";
3837
import { Link } from "react-router-dom";
3938
import {
4039
type APIProject,
4140
type APIProjectWithStatus,
42-
type APIUser,
4341
type APIUserBase,
4442
TracingTypeEnum,
4543
} from "types/api_types";
4644
import { enforceActiveUser } from "viewer/model/accessors/user_accessor";
47-
import type { WebknossosState } from "viewer/store";
4845

4946
const { Column } = Table;
5047
const { Search } = Input;
5148

52-
type OwnProps = {
49+
type Props = {
5350
initialSearchValue?: string;
5451
taskTypeId?: string;
5552
};
56-
type StateProps = {
57-
activeUser: APIUser;
58-
};
59-
type Props = OwnProps & StateProps;
6053

6154
const persistence = new Persistence<{ searchQuery: string }>(
6255
{
@@ -65,9 +58,10 @@ const persistence = new Persistence<{ searchQuery: string }>(
6558
"projectList",
6659
);
6760

68-
function ProjectListView({ initialSearchValue, taskTypeId, activeUser }: Props) {
61+
function ProjectListView({ initialSearchValue, taskTypeId }: Props) {
6962
const { modal } = App.useApp();
7063

64+
const activeUser = useWkSelector((state) => enforceActiveUser(state.activeUser));
7165
const [isLoading, setIsLoading] = useState(true);
7266
const [projects, setProjects] = useState<APIProjectWithStatus[]>([]);
7367
const [searchQuery, setSearchQuery] = useState("");
@@ -475,9 +469,4 @@ function ProjectListView({ initialSearchValue, taskTypeId, activeUser }: Props)
475469
);
476470
}
477471

478-
const mapStateToProps = (state: WebknossosState): StateProps => ({
479-
activeUser: enforceActiveUser(state.activeUser),
480-
});
481-
482-
const connector = connect(mapStateToProps);
483-
export default connector(ProjectListView);
472+
export default ProjectListView;

frontend/javascripts/admin/scripts/script_create_view.tsx

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
11
import { createScript, getScript, getTeamManagerOrAdminUsers, updateScript } from "admin/rest_api";
22
import { Button, Card, Form, Input, Select } from "antd";
3+
import { useWkSelector } from "libs/react_hooks";
34
import { useEffect, useState } from "react";
4-
import { connect } from "react-redux";
55
import { useHistory } from "react-router-dom";
66
import type { APIUser } from "types/api_types";
77
import { enforceActiveUser } from "viewer/model/accessors/user_accessor";
8-
import type { WebknossosState } from "viewer/store";
98

109
const FormItem = Form.Item;
11-
type OwnProps = {
10+
11+
type Props = {
1212
scriptId?: string | null | undefined;
1313
};
14-
type StateProps = {
15-
activeUser: APIUser;
16-
};
17-
type Props = OwnProps & StateProps;
1814

19-
function ScriptCreateView({ scriptId, activeUser }: Props) {
15+
function ScriptCreateView({ scriptId }: Props) {
16+
const activeUser = useWkSelector((state) => enforceActiveUser(state.activeUser));
2017
const history = useHistory();
2118
const [users, setUsers] = useState<APIUser[]>([]);
2219
const [isFetchingData, setIsFetchingData] = useState<boolean>(false);
2320
const [form] = Form.useForm();
21+
2422
useEffect(() => {
2523
fetchData();
2624
applyDefaults();
@@ -127,9 +125,4 @@ function ScriptCreateView({ scriptId, activeUser }: Props) {
127125
);
128126
}
129127

130-
const mapStateToProps = (state: WebknossosState): StateProps => ({
131-
activeUser: enforceActiveUser(state.activeUser),
132-
});
133-
134-
const connector = connect(mapStateToProps);
135-
export default connector(ScriptCreateView);
128+
export default ScriptCreateView;

frontend/javascripts/admin/task/task_annotation_view.tsx

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,21 @@ import { AsyncLink } from "components/async_clickables";
2323
import FormattedDate from "components/formatted_date";
2424
import TransferTaskModal from "dashboard/transfer_task_modal";
2525
import { formatSeconds } from "libs/format_utils";
26+
import { useWkSelector } from "libs/react_hooks";
2627
import Toast from "libs/toast";
2728
import messages from "messages";
2829
import { useEffect, useState } from "react";
29-
import { connect } from "react-redux";
30-
import type { APIAnnotation, APITask, APIUser } from "types/api_types";
30+
import type { APIAnnotation, APITask } from "types/api_types";
3131
import { getVolumeDescriptors } from "viewer/model/accessors/volumetracing_accessor";
32-
import type { WebknossosState } from "viewer/store";
3332

34-
type OwnProps = {
33+
type Props = {
3534
task: APITask;
3635
};
37-
type StateProps = {
38-
activeUser: APIUser | null | undefined;
39-
};
40-
type Props = OwnProps & StateProps;
4136

42-
function TaskAnnotationView({ task, activeUser }: Props) {
37+
function TaskAnnotationView({ task }: Props) {
4338
const { modal } = App.useApp();
4439

40+
const activeUser = useWkSelector((state) => state.activeUser);
4541
const [currentAnnotation, setCurrentAnnotation] = useState<APIAnnotation | undefined>(undefined);
4642
const [isTransferModalOpen, setIsTransferModalOpen] = useState(false);
4743
const [annotations, setAnnotations] = useState<APIAnnotation[]>([]);
@@ -231,9 +227,4 @@ function TaskAnnotationView({ task, activeUser }: Props) {
231227
);
232228
}
233229

234-
const mapStateToProps = (state: WebknossosState): StateProps => ({
235-
activeUser: state.activeUser,
236-
});
237-
238-
const connector = connect(mapStateToProps);
239-
export default connector(TaskAnnotationView);
230+
export default TaskAnnotationView;

frontend/javascripts/admin/user/user_list_view.tsx

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,24 @@ import { Alert, App, Button, Col, Input, Modal, Row, Spin, Table, Tag, Tooltip }
2121
import LinkButton from "components/link_button";
2222
import dayjs from "dayjs";
2323
import Persistence from "libs/persistence";
24+
import { useWkSelector } from "libs/react_hooks";
2425
import Toast from "libs/toast";
2526
import * as Utils from "libs/utils";
2627
import { location } from "libs/window";
2728
import _ from "lodash";
2829
import messages from "messages";
2930
import React, { type Key, useEffect, useState } from "react";
30-
import { connect } from "react-redux";
31-
import type { RouteComponentProps } from "react-router-dom";
3231
import { Link } from "react-router-dom";
33-
import type { APIOrganization, APITeamMembership, APIUser, ExperienceMap } from "types/api_types";
32+
import type { APITeamMembership, APIUser, ExperienceMap } from "types/api_types";
3433
import { enforceActiveOrganization } from "viewer/model/accessors/organization_accessors";
3534
import { enforceActiveUser } from "viewer/model/accessors/user_accessor";
36-
import type { WebknossosState } from "viewer/store";
3735
import EditableTextLabel from "viewer/view/components/editable_text_label";
3836
import { logoutUserAction } from "../../viewer/model/actions/user_actions";
3937
import Store from "../../viewer/store";
4038

4139
const { Column } = Table;
4240
const { Search } = Input;
4341

44-
type StateProps = {
45-
activeUser: APIUser;
46-
activeOrganization: APIOrganization;
47-
};
48-
type Props = RouteComponentProps & StateProps;
49-
5042
type ActivationFilterType = Array<"activated" | "deactivated" | "verified" | "unverified">;
5143

5244
const persistence = new Persistence<{
@@ -60,9 +52,14 @@ const persistence = new Persistence<{
6052
"userList",
6153
);
6254

63-
function UserListView({ activeUser, activeOrganization }: Props) {
55+
function UserListView() {
6456
const { modal } = App.useApp();
6557

58+
const activeUser = useWkSelector((state) => enforceActiveUser(state.activeUser));
59+
const activeOrganization = useWkSelector((state) =>
60+
enforceActiveOrganization(state.activeOrganization),
61+
);
62+
6663
const [isLoading, setIsLoading] = useState(true);
6764
const [users, setUsers] = useState<APIUser[]>([]);
6865
const [selectedUserIds, setSelectedUserIds] = useState<Key[]>([]);
@@ -650,10 +647,4 @@ function UserListView({ activeUser, activeOrganization }: Props) {
650647
);
651648
}
652649

653-
const mapStateToProps = (state: WebknossosState): StateProps => ({
654-
activeUser: enforceActiveUser(state.activeUser),
655-
activeOrganization: enforceActiveOrganization(state.activeOrganization),
656-
});
657-
658-
const connector = connect(mapStateToProps);
659-
export default connector(UserListView);
650+
export default UserListView;

0 commit comments

Comments
 (0)