Skip to content

Commit 8d2161f

Browse files
Merge branch 'master' of github.com:scalableminds/webknossos into live-m3
2 parents 2aa2de6 + 155e22a commit 8d2161f

File tree

15 files changed

+115
-36
lines changed

15 files changed

+115
-36
lines changed

app/controllers/AuthenticationController.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,13 +537,16 @@ class AuthenticationController @Inject()(
537537
}
538538

539539
def logout: Action[AnyContent] = sil.UserAwareAction.async { implicit request =>
540+
val redirectUrlStr: String = conf.SingleSignOn.OpenIdConnect.logoutRedirectUrl.getOrElse("/")
541+
val rawResultWithRedirect = Ok(Json.toJson(redirectUrlStr))
540542
request.authenticator match {
541543
case Some(authenticator) =>
542544
for {
543-
authenticatorResult <- combinedAuthenticatorService.discard(authenticator, Ok)
545+
authenticatorResult <- combinedAuthenticatorService.discard(authenticator, rawResultWithRedirect)
544546
_ = logger.info(f"User ${request.identity.map(_._id).getOrElse("id unknown")} logged out.")
545547
} yield authenticatorResult
546-
case _ => Future.successful(Ok)
548+
case _ =>
549+
Future.successful(rawResultWithRedirect)
547550
}
548551
}
549552

app/utils/WkConf.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class WkConf @Inject()(configuration: Configuration, certificateValidationServic
128128
val clientSecret: String = get[String]("singleSignOn.openIdConnect.clientSecret")
129129
val scope: String = get[String]("singleSignOn.openIdConnect.scope")
130130
val verboseLoggingEnabled: Boolean = get[Boolean]("singleSignOn.openIdConnect.verboseLoggingEnabled")
131+
val logoutRedirectUrl = getOptional[String]("singleSignOn.openIdConnect.logoutRedirectUrl")
131132
}
132133
}
133134

conf/application.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ singleSignOn {
142142
clientId = "myclient"
143143
clientSecret = "myClientSecret"
144144
scope = "openid profile email"
145+
logoutRedirectUrl = null
145146
verboseLoggingEnabled = false # always set to false in production to avoid logging secrets
146147
}
147148
}

frontend/javascripts/admin/rest_api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ export async function loginUser(formValues: {
154154
return [activeUser, organization];
155155
}
156156

157-
export async function logoutUser(): Promise<void> {
158-
await Request.receiveJSON("/api/auth/logout", { method: "POST" });
157+
export async function logoutUser(): Promise<string> {
158+
return await Request.receiveJSON("/api/auth/logout", { method: "POST" });
159159
}
160160

161161
export async function logoutUserEverywhere(): Promise<void> {

frontend/javascripts/admin/team/create_team_modal_view.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ type Props = {
99
isOpen: boolean;
1010
};
1111

12-
function CreateTeamModalForm({ onOk: onOkCallback, onCancel, isOpen }: Props) {
12+
function CreateTeamModalForm({ onOk: onOkCallback, onCancel: onCancelCallback, isOpen }: Props) {
1313
const [form] = Form.useForm();
1414

1515
const onOk = async () => {
@@ -26,10 +26,16 @@ function CreateTeamModalForm({ onOk: onOkCallback, onCancel, isOpen }: Props) {
2626
],
2727
};
2828
const team = await createTeam(newTeam);
29+
form.resetFields();
2930
onOkCallback(team);
3031
});
3132
};
3233

34+
const onCancel = () => {
35+
form.resetFields();
36+
onCancelCallback();
37+
};
38+
3339
return (
3440
<Modal open={isOpen} title="Add a New Team" okText="Ok" onCancel={onCancel} onOk={onOk}>
3541
<Shortcut keys="enter" onTrigger={onOk} supportInputElements />

frontend/javascripts/navbar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -775,10 +775,10 @@ function Navbar({ isAuthenticated }: { isAuthenticated: boolean }) {
775775

776776
const handleLogout = async (event: React.SyntheticEvent) => {
777777
event.preventDefault();
778-
await logoutUser();
778+
const redirectUrl = await logoutUser();
779779
Store.dispatch(logoutUserAction());
780780
// Hard navigation
781-
location.href = "/";
781+
location.href = redirectUrl;
782782
};
783783

784784
const version = useFetch(getVersion, null, []);

frontend/javascripts/viewer/controller/combinations/segmentation_handlers.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import {
44
getSegmentIdForPosition,
55
getSegmentIdForPositionAsync,
66
} from "viewer/controller/combinations/volume_handlers";
7-
import { getMappingInfo } from "viewer/model/accessors/dataset_accessor";
7+
import {
8+
getMappingInfo,
9+
getVisibleSegmentationLayer,
10+
} from "viewer/model/accessors/dataset_accessor";
11+
import { globalToLayerTransformedPosition } from "viewer/model/accessors/dataset_layer_transformation_accessor";
812
import { getTreeNameForAgglomerateSkeleton } from "viewer/model/accessors/skeletontracing_accessor";
913
import { calculateGlobalPos } from "viewer/model/accessors/view_mode_accessor";
1014
import {
@@ -79,9 +83,22 @@ export function handleClickSegment(clickPosition: Point2) {
7983
const state = Store.getState();
8084
const globalPosition = calculateGlobalPos(state, clickPosition);
8185
const segmentId = getSegmentIdForPosition(globalPosition.rounded);
86+
const visibleSegmentationLayer = getVisibleSegmentationLayer(state);
87+
const positionInSegmentationLayerSpace =
88+
visibleSegmentationLayer != null
89+
? (globalToLayerTransformedPosition(
90+
globalPosition.rounded,
91+
visibleSegmentationLayer.name,
92+
"segmentation",
93+
state,
94+
).map(Math.floor) as Vector3)
95+
: null;
96+
8297
const { additionalCoordinates } = state.flycam;
8398

84-
if (segmentId > 0) {
85-
Store.dispatch(clickSegmentAction(segmentId, globalPosition.rounded, additionalCoordinates));
99+
if (segmentId > 0 && positionInSegmentationLayerSpace != null) {
100+
Store.dispatch(
101+
clickSegmentAction(segmentId, positionInSegmentationLayerSpace, additionalCoordinates),
102+
);
86103
}
87104
}

frontend/javascripts/viewer/controller/combinations/skeleton_handlers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,10 @@ export function handleOpenContextMenu(
136136
meshIntersectionPosition?: Vector3 | null | undefined,
137137
unmappedSegmentId?: number | null | undefined,
138138
) {
139-
const { activeViewport } = Store.getState().viewModeData.plane;
139+
const state = Store.getState();
140+
const { activeViewport } = state.viewModeData.plane;
140141

141142
const nodeId = maybeGetNodeIdFromPosition(planeView, position, plane, isTouch);
142-
const state = Store.getState();
143143
// Use calculateMaybeGlobalPos instead of calculateGlobalPos, since calculateGlobalPos
144144
// only works for the data viewports, but this function is also called for the 3d viewport.
145145
const globalPosition = calculateMaybeGlobalPos(state, position);

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,3 +504,24 @@ export function globalToLayerTransformedPosition(
504504
}
505505
return globalPos;
506506
}
507+
508+
export function layerToGlobalTransformedPosition(
509+
layerPos: Vector3,
510+
layerName: string,
511+
layerCategory: APIDataLayer["category"] | "skeleton",
512+
state: WebknossosState,
513+
): Vector3 {
514+
const layerDescriptor =
515+
layerCategory !== "skeleton"
516+
? getLayerByName(state.dataset, layerName, true)
517+
: ({ name: "skeleton", category: "skeleton" } as APISkeletonLayer);
518+
const layerTransforms = getTransformsForLayerOrNull(
519+
state.dataset,
520+
layerDescriptor,
521+
state.datasetConfiguration.nativelyRenderedLayerName,
522+
);
523+
if (layerTransforms) {
524+
return transformPointUnscaled(layerTransforms)(layerPos);
525+
}
526+
return layerPos;
527+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ function UiReducer(state: WebknossosState, action: Action): WebknossosState {
1818
activeOrganization: state.activeOrganization,
1919
uiInformation: {
2020
...defaultState.uiInformation,
21+
theme: state.uiInformation.theme,
2122
storedLayouts: state.uiInformation.storedLayouts,
2223
navbarHeight: state.uiInformation.navbarHeight,
2324
},

0 commit comments

Comments
 (0)