Skip to content

Commit

Permalink
Dont crash job list for unknown jobs (#8300)
Browse files Browse the repository at this point in the history
* render unknown job types in action column

* remove action column for unknown job types

* insert example strings for infer_with_model and train_model

* use present tense

* improve wording and add link to training data

* sort imports

* lint

* remove enable-jobs to create docker image

* add changelog

* remove hardcoded job, dev change
  • Loading branch information
knollengewaechs authored Jan 13, 2025
1 parent 466ce63 commit 17ac2c9
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 44 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
- Removed the magnification slider for the TIFF export within the download modal if only one magnification is available for the selected layer. [#8297](https://github.com/scalableminds/webknossos/pull/8297)
- Fixed regression in styling of segment and skeleton tree tab. [#8307](https://github.com/scalableminds/webknossos/pull/8307)
- Fixed the template for neuron inferral using a custom workflow. [#8312](https://github.com/scalableminds/webknossos/pull/8312)
- Fixed that the list of processing jobs crashed for deleted job types. [#8300](https://github.com/scalableminds/webknossos/pull/8300)

### Removed
- Removed support for HTTP API versions 3 and 4. [#8075](https://github.com/scalableminds/webknossos/pull/8075)
Expand Down
75 changes: 71 additions & 4 deletions frontend/javascripts/admin/job/job_list_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
} from "@ant-design/icons";
import { PropTypes } from "@scalableminds/prop-types";
import { cancelJob, getJobs } from "admin/admin_rest_api";
import { Input, Spin, Table, Tooltip, Typography } from "antd";
import { Input, Modal, Spin, Table, Tooltip, Typography } from "antd";
import { AsyncLink } from "components/async_clickables";
import FormattedDate from "components/formatted_date";
import { confirmAsync } from "dashboard/dataset/helper_components";
Expand Down Expand Up @@ -60,6 +60,50 @@ const refreshInterval = 5000;
const { Column } = Table;
const { Search } = Input;

export const getShowTrainingDataLink = (
trainingAnnotations: {
annotationId: string;
}[],
) => {
return trainingAnnotations == null ? null : trainingAnnotations.length > 1 ? (
<a
href="#"
onClick={() => {
Modal.info({
content: (
<div>
The following annotations were used during training:
<ul>
{trainingAnnotations.map((annotation: { annotationId: string }, index: number) => (
<li key={`annotation_${index}`}>
<a
href={`/annotations/${annotation.annotationId}`}
target="_blank"
rel="noreferrer noopener"
>
Annotation {index + 1}
</a>
</li>
))}
</ul>
</div>
),
});
}}
>
Show Training Data
</a>
) : (
<a
href={`/annotations/${trainingAnnotations[0].annotationId}`}
target="_blank"
rel="noreferrer noopener"
>
Show Training Data
</a>
);
};

type State = {
isLoading: boolean;
jobs: Array<APIJob>;
Expand Down Expand Up @@ -215,7 +259,7 @@ function JobListView() {
) {
return (
<span>
Aligned sections for layer {job.layerName} of{" "}
Align sections for layer {job.layerName} of{" "}
<Link to={linkToDataset}>{job.datasetName}</Link>{" "}
</span>
);
Expand All @@ -233,6 +277,20 @@ function JobListView() {
: null}
</span>
);
} else if (job.type === APIJobType.TRAIN_MODEL && job.organizationId) {
const numberOfTrainingAnnotations = job.trainingAnnotations.length;
return (
<span>
{`Train model on ${numberOfTrainingAnnotations} ${Utils.pluralize("annotation", numberOfTrainingAnnotations)}. `}
{getShowTrainingDataLink(job.trainingAnnotations)}
</span>
);
} else if (job.type === APIJobType.INFER_WITH_MODEL && job.organizationId) {
return (
<span>
Run AI segmentation with custom model on <Link to={linkToDataset}>{job.datasetName}</Link>
</span>
);
} else {
return <span>{job.type}</span>;
}
Expand Down Expand Up @@ -324,8 +382,17 @@ function JobListView() {
</span>
);
} else {
// The above if-branches should be exhaustive over all job types
Utils.assertNever(job.type);
// unknown job type
return (
<span>
{job.resultLink && (
<a href={job.resultLink} title="Result">
Result
</a>
)}
{job.result && <p>{job.result}</p>}
</span>
);
}
}

Expand Down
42 changes: 2 additions & 40 deletions frontend/javascripts/admin/voxelytics/ai_model_list_view.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PlusOutlined, SyncOutlined } from "@ant-design/icons";
import { getAiModels } from "admin/admin_rest_api";
import { JobState } from "admin/job/job_list_view";
import { JobState, getShowTrainingDataLink } from "admin/job/job_list_view";
import { Button, Modal, Space, Table } from "antd";
import FormattedDate from "components/formatted_date";
import { PageNotAvailableToNormalUser } from "components/permission_enforcer";
Expand Down Expand Up @@ -177,45 +177,7 @@ const renderActionsForModel = (model: AiModel) => {
<br />
</>
) : null}
{trainingAnnotations == null ? null : trainingAnnotations.length > 1 ? (
<a
href="#"
onClick={() => {
Modal.info({
content: (
<div>
The following annotations were used during training:
<ul>
{trainingAnnotations.map(
(annotation: { annotationId: string }, index: number) => (
<li key={`annotation_${index}`}>
<a
href={`/annotations/${annotation.annotationId}`}
target="_blank"
rel="noreferrer noopener"
>
Annotation {index + 1}
</a>
</li>
),
)}
</ul>
</div>
),
});
}}
>
Show Training Data
</a>
) : (
<a
href={`/annotations/${trainingAnnotations[0].annotationId}`}
target="_blank"
rel="noreferrer noopener"
>
Show Training Data
</a>
)}
{getShowTrainingDataLink(trainingAnnotations)}
</div>
);
};

0 comments on commit 17ac2c9

Please sign in to comment.