Skip to content

Commit 1bf9007

Browse files
View Annotations and Datasets from Command Palette (#9087)
### Steps to test: - From anywhere, open the command palette by pressing ctrl + P - click on "> View dataset..." and select any dataset -> you should be directed to its view mode - same for "> View annotaion..." - the list of annotations should be sorted like in the dashboard, so the annotation that was edited most recently should appear first - Do so in any admin view and within DS/annotation view mode - when having an annotation open, you should be able to select the annotation tools and also see the corresponding shortcuts ### Notes - This adds the library https://www.npmjs.com/package/dompurify ### TODOs: - [x] check whether closing can be done without changing the key, e.g. with pending promises in viewDatasetEntry -> didnt find anything better - [x] fix typing errors - [x] fix pipeline - [ wont do ] when hitting "view dataset" (or annotation), reset input -> does not seem feasable because input is not easy to be manipulated from outside the libs code (from what i can tell). so I just used a string that can stay there :) - [ ] ~~omit dangerouslySetInnerHTML~~ ### Issues: - contributes to #8441 Co-authored-by: MichaelBuessemeyer <39529669+MichaelBuessemeyer@users.noreply.github.com>
1 parent a4585d0 commit 1bf9007

File tree

13 files changed

+245
-45
lines changed

13 files changed

+245
-45
lines changed

.github/common_edge_cases.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Will this also work if
99
- The user is logged out and views a public dataset or annotation
1010
- User uses dark mode / light mode
1111
- There is no local datastore/tracingstore module (Compare [instructions to test this locally](https://github.com/scalableminds/webknossos/wiki/Set-up-a-standalone-datastore-locally))
12+
- An annotation is opened by multiple users at the same time
1213

1314
Consider SQL pitfalls:
1415
- `x IN ()` statements must never called with empty list

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import type { APIDataLayer, APIDataset, APITeam, LayerLink } from "types/api_typ
3232
import { syncValidator } from "types/validation";
3333
import { WkDevFlags } from "viewer/api/wk_dev";
3434
import type { Vector3 } from "viewer/constants";
35-
import { getReadableURLPart } from "viewer/model/accessors/dataset_accessor";
35+
import { getReadableURLPart, getViewDatasetURL } from "viewer/model/accessors/dataset_accessor";
3636
import { flatToNestedMatrix } from "viewer/model/accessors/dataset_layer_transformation_accessor";
3737
import { checkLandmarksForThinPlateSpline } from "viewer/model/helpers/transformation_helpers";
3838
import type { WizardComponentProps } from "./common";
@@ -372,7 +372,7 @@ function LinkedLayerForm({
372372
info="This is the layer which will be linked into the new dataset."
373373
>
374374
<a
375-
href={`/datasets/${getReadableURLPart({ name: datasetName, id: datasetId })}/view`}
375+
href={getViewDatasetURL({ name: datasetName, id: datasetId })}
376376
target="_blank"
377377
rel="noreferrer"
378378
>

frontend/javascripts/admin/dataset/dataset_add_view.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useWkSelector } from "libs/react_hooks";
99
import React, { useState } from "react";
1010
import { useNavigate } from "react-router-dom";
1111
import type { APIDataStore } from "types/api_types";
12-
import { getReadableURLPart } from "viewer/model/accessors/dataset_accessor";
12+
import { getReadableURLPart, getViewDatasetURL } from "viewer/model/accessors/dataset_accessor";
1313
import DatasetAddComposeView from "./dataset_add_compose_view";
1414

1515
const { Content, Sider } = Layout;
@@ -306,9 +306,7 @@ const getPostUploadModal = (
306306
<Button
307307
type="primary"
308308
onClick={() =>
309-
navigate(
310-
`/datasets/${getReadableURLPart({ name: uploadedDatasetName, id: datasetId })}/view`,
311-
)
309+
navigate(getViewDatasetURL({ name: uploadedDatasetName, id: datasetId }))
312310
}
313311
>
314312
View the Dataset

frontend/javascripts/admin/job/job_list_view.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import type * as React from "react";
2929
import { useEffect, useState } from "react";
3030
import { Link } from "react-router-dom";
3131
import { type APIJob, APIJobCommand } from "types/api_types";
32-
import { getReadableURLPart } from "viewer/model/accessors/dataset_accessor";
32+
import { getViewDatasetURL } from "viewer/model/accessors/dataset_accessor";
3333

3434
// Unfortunately, the twoToneColor (nor the style) prop don't support
3535
// CSS variables.
@@ -166,7 +166,10 @@ function JobListView() {
166166
function getLinkToDataset(job: APIJob) {
167167
// prefer updated link over legacy link.
168168
if (job.args.datasetId != null)
169-
return `/datasets/${getReadableURLPart({ name: job.args.datasetName || "unknown_name", id: job.args.datasetId })}/view`;
169+
return getViewDatasetURL({
170+
name: job.args.datasetName || "unknown_name",
171+
id: job.args.datasetId,
172+
});
170173
if (
171174
job.organizationId != null &&
172175
(job.args.datasetName != null || job.args.datasetDirectoryName != null)

frontend/javascripts/dashboard/advanced_dataset/dataset_action_view.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import type * as React from "react";
2020
import { useState } from "react";
2121
import { Link } from "react-router-dom";
2222
import type { APIDataset, APIDatasetCompact } from "types/api_types";
23-
import { getReadableURLPart } from "viewer/model/accessors/dataset_accessor";
23+
import { getReadableURLPart, getViewDatasetURL } from "viewer/model/accessors/dataset_accessor";
2424
import { getNoActionsAvailableMenu } from "viewer/view/context_menu";
2525

2626
const disabledStyle: React.CSSProperties = {
@@ -259,11 +259,7 @@ function DatasetActionView(props: Props) {
259259
onShowCreateExplorativeModal={() => setIsCreateExplorativeModalVisible(true)}
260260
onCloseCreateExplorativeModal={() => setIsCreateExplorativeModalVisible(false)}
261261
/>
262-
<LinkWithDisabled
263-
to={`/datasets/${getReadableURLPart(dataset)}/view`}
264-
title="View Dataset"
265-
disabled={isReloading}
266-
>
262+
<LinkWithDisabled to={getViewDatasetURL(dataset)} title="View Dataset" disabled={isReloading}>
267263
<EyeOutlined className="icon-margin-right" />
268264
View
269265
</LinkWithDisabled>
@@ -319,7 +315,7 @@ export function getDatasetActionContextMenu({
319315
key: "view",
320316
label: "View",
321317
onClick: () => {
322-
window.location.href = `/datasets/${getReadableURLPart(dataset)}/view`;
318+
window.location.href = getViewDatasetURL(dataset);
323319
},
324320
}
325321
: null,

frontend/javascripts/dashboard/advanced_dataset/dataset_table.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { Link } from "react-router-dom";
4040
import type { APIDatasetCompact, APIMaybeUnimportedDataset, FolderItem } from "types/api_types";
4141
import type { EmptyObject } from "types/globals";
4242
import { Unicode } from "viewer/constants";
43-
import { getReadableURLPart } from "viewer/model/accessors/dataset_accessor";
43+
import { getViewDatasetURL } from "viewer/model/accessors/dataset_accessor";
4444
import CategorizationLabel from "viewer/view/components/categorization_label";
4545
import EditableTextIcon from "viewer/view/components/editable_text_icon";
4646
import {
@@ -332,7 +332,7 @@ class DatasetRenderer {
332332

333333
return (
334334
<>
335-
<Link to={`/datasets/${getReadableURLPart(this.data)}/view`} title="View Dataset">
335+
<Link to={getViewDatasetURL(this.data)} title="View Dataset">
336336
<img
337337
src={imgSrc}
338338
className={`dataset-table-thumbnail ${iconClassName}`}
@@ -342,7 +342,7 @@ class DatasetRenderer {
342342
</Link>
343343
<div className="dataset-table-name-container">
344344
<Link
345-
to={`/datasets/${getReadableURLPart(this.data)}/view`}
345+
to={getViewDatasetURL(this.data)}
346346
title="View Dataset"
347347
className="incognito-link dataset-table-name"
348348
>
@@ -807,7 +807,7 @@ class DatasetTable extends React.PureComponent<Props, State> {
807807
},
808808
onDoubleClick: () => {
809809
if (isADataset) {
810-
window.location.href = `/datasets/${getReadableURLPart(data)}/view`;
810+
window.location.href = getViewDatasetURL(data);
811811
} else {
812812
context.setActiveFolderId(data.key);
813813
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,12 @@ export function getReadableURLPart(
752752
return `${getURLSanitizedName(dataset)}-${dataset.id}`;
753753
}
754754

755+
export function getViewDatasetURL(
756+
dataset: APIDataset | APIDatasetCompact | { name: string; id: string },
757+
) {
758+
return `/datasets/${getReadableURLPart(dataset)}/view`;
759+
}
760+
755761
export function getDatasetIdOrNameFromReadableURLPart(datasetNameAndId: string) {
756762
const datasetIdOrName = datasetNameAndId.split("-").pop();
757763
const isId = /^[a-f0-9]{24}$/.test(datasetIdOrName || "");

0 commit comments

Comments
 (0)