Skip to content

Commit

Permalink
Merge branches 'pricing' and 'master' of github.com:scalableminds/web…
Browse files Browse the repository at this point in the history
…knossos into pricing

* 'pricing' of github.com:scalableminds/webknossos:
* 'master' of github.com:scalableminds/webknossos:
  Release 22.11.2 (#6629)
  Encode layer visibility in sharing link (#6634)
  Allow viewing vx workflows via link if organization matches (#6622)
  Hotfix: increase zarr chunk cache size (#6639)
  Integrate Rome Linting (#6618)
  Fix task creation with base NML (#6635)
  Fix NGFF import for datasets with no channel axis (#6637)
  • Loading branch information
hotzenklotz committed Nov 15, 2022
2 parents cb094d4 + 4b257fc commit ad03de9
Show file tree
Hide file tree
Showing 86 changed files with 322 additions and 817 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ jobs:
command: docker-compose build --pull webknossos-tracingstore

- run:
name: Lint frontend code and check formatting
name: Lint frontend code (rome and eslint) and check formatting
command: |
.circleci/not-on-master.sh docker-compose run base bash -c "yarn run lint && yarn run am-i-pretty"
- run:
Expand Down
108 changes: 3 additions & 105 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
{
"extends": [
"airbnb",
"airbnb-typescript",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:eslint-comments/recommended",
"plugin:react/recommended",
"prettier"
],
"plugins": ["@typescript-eslint", "react", "react-hooks", "import", "ava"],
"extends": [],
"plugins": ["@typescript-eslint", "react-hooks"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 8,
Expand All @@ -33,101 +26,6 @@
"Generator": false
},
"rules": {
"array-callback-return": "warn",
"class-methods-use-this": "off",
"no-constant-condition": "error",
"eslint-comments/disable-enable-pair": ["error", { "allowWholeFile": true }],
"eslint-comments/no-unused-disable": "error",
"flowtype/no-types-missing-file-annotation": "off",
"import/extensions": ["warn", { "js": "never", "jsx": "always" }],
"import/prefer-default-export": ["warn"],
"import/no-cycle": "off",
"import/no-extraneous-dependencies": [
"error",
{ "devDependencies": ["frontend/javascripts/test/**"] }
],
"import/no-named-as-default-member": "warn",
"import/no-unresolved": "off",
"jsx-a11y/anchor-is-valid": "off",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-static-element-interactions": "off",
"jsx-a11y/label-has-associated-control": "off",
"jsx-a11y/label-has-for": "off",
"lines-between-class-members": ["warn", "always", { "exceptAfterSingleLine": true }],
"max-len": ["off", 100],
"no-bitwise": "off",
"no-confusing-arrow": "off",
"no-continue": "warn",
"no-duplicate-imports": "off",
"no-else-return": "off",
"no-mixed-operators": "off",
"no-multi-str": "off",
"no-param-reassign": "warn",
"no-plusplus": "off",
"no-restricted-properties": ["off", { "object": "Math", "property": "pow" }],
"no-restricted-syntax": "warn",
"no-restricted-syntax": ["error", "ForInStatement"],
"no-restricted-globals": "warn",
"no-underscore-dangle": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{ "argsIgnorePattern": "^_", "ignoreRestSiblings": true }
],
"@typescript-eslint/no-use-before-define": ["error", { "functions": false, "classes": false }],
"no-console": "off",
"one-var": ["error", "never"],
"operator-assignment": "warn",
"prefer-destructuring": "off",
"quote-props": ["error", "as-needed", { "numbers": true }],
"quotes": ["error", "double", { "avoidEscape": true }],
"radix": "off",
"react/default-props-match-prop-types": ["error", { "allowRequiredDefaults": true }],
"react/destructuring-assignment": "off",
"react/jsx-filename-extension": "off",
"react/no-multi-comp": "off",
"react/prop-types": "off",
"react/require-default-props": "off",
"react-hooks/rules-of-hooks": "error",
"import/newline-after-import": "off",
"spaced-comment": "off",
"react/sort-comp": [
"error",
{
"order": [
"type-annotations",
"instance-variables",
"static-methods",
"lifecycle",
"everything-else",
"render"
]
}
],
"ava/no-only-test": "error",

// reconsider rules after finishing Typescript conversion
"react/static-property-placement": "off",
"react/jsx-props-no-spreading": "warn", // no opinion
"react/state-in-constructor": "off", // probably want "never",
"react/default-props-match-prop-types": "warn", // probably should be enabled
"react/jsx-fragments": "off", // debateable. could be autofixed with eslint --fix ...
"max-classes-per-file": "off", // seems useful, but requires some refactoring, set to off because it's visually distracting
"prefer-object-spread": "off", // debateable. could be autofixed with eslint --fix ...
"@typescript-eslint/lines-between-class-members": "off",
"@typescript-eslint/naming-convention": [
"off",
{
"leadingUnderscore": "allow",
"format": ["camelCase", "UPPER_CASE"],
"selector": ["variable", "function"]
}
], // interesting but hard to finetune for all cases
"react/no-unstable-nested-components": "warn", // probably should do something about it
"react/no-array-index-key": "error", // maybe sensible, maybe not
"prefer-exponentiation-operator": "off", // I find Math.pow() more readble than **
"eqeqeq": "error", // == vs ===
"react/jsx-no-bind": "off", // no opinion
"react/function-component-definition": "warn", // probably should do this. can be autofixed with eslint --fix
"@typescript-eslint/no-throw-literal": "warn" // probably should do this.
"react-hooks/rules-of-hooks": "error"
}
}
9 changes: 9 additions & 0 deletions CHANGELOG.released.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Calendar Versioning](http://calver.org/) `0Y.0M.MICRO`.
For upgrade instructions, please check the [migration guide](MIGRATIONS.released.md).

## [22.11.2](https://github.com/scalableminds/webknossos/releases/tag/22.11.2) - 2022-11-10
[Commits](https://github.com/scalableminds/webknossos/compare/22.11.1...22.11.2)

### Changed
- When merging annotations, bounding boxes are no longer duplicated. [#6576](https://github.com/scalableminds/webknossos/pull/6576)

### Fixed
- Fixed importing a dataset from disk. [#6615](https://github.com/scalableminds/webknossos/pull/6615)

## [22.11.1](https://github.com/scalableminds/webknossos/releases/tag/22.11.1) - 2022-10-27
[Commits](https://github.com/scalableminds/webknossos/compare/22.11.0...22.11.1)

Expand Down
8 changes: 5 additions & 3 deletions CHANGELOG.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ and this project adheres to [Calendar Versioning](http://calver.org/) `0Y.0M.MIC
For upgrade instructions, please check the [migration guide](MIGRATIONS.released.md).

## Unreleased
[Commits](https://github.com/scalableminds/webknossos/compare/22.11.1...HEAD)
[Commits](https://github.com/scalableminds/webknossos/compare/22.11.2...HEAD)

### Added
- Added a new Quick-Select tool for volume annotation. This tools allows to draw a rectangle over a segment to annotate it automatically. The tool operates on the intensity data of the visible color layer and automatically fills out the segment starting from the center of the rectangle. Next to the tool, there is a settings button which allows to enable a preview mode and to tweak some other parameters. If the preview is enabled, the parameters can be fine-tuned while the preview updates instantly. [#6542](https://github.com/scalableminds/webknossos/pull/6542)
Expand All @@ -21,16 +21,18 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released
### Changed
- The log viewer in the Voxelytics workflow reporting now uses a virtualized list. [#6579](https://github.com/scalableminds/webknossos/pull/6579)
- Node positions are always handled as integers. They have always been persisted as integers by the server, anyway, but the session in which a node was created handled the position as floating point in earlier versions. [#6589](https://github.com/scalableminds/webknossos/pull/6589)
- When merging annotations, bounding boxes are no longer duplicated. [#6576](https://github.com/scalableminds/webknossos/pull/6576)
- Jobs can no longer be started on datastores without workers. [#6595](https://github.com/scalableminds/webknossos/pull/6595)
- When downloading volume annotations with volume data skipped, the nml volume tag is now included anyway (but has no location attribute in this case). [#6566](https://github.com/scalableminds/webknossos/pull/6566)
- Re-phrased some backend (error) messages to improve clarity and provide helping hints. [#6616](https://github.com/scalableminds/webknossos/pull/6616)
- The layer visibility is now encoded in the sharing link. The user opening the link will see the same layers that were visible when copying the link. [#6634](https://github.com/scalableminds/webknossos/pull/6634)
- Voxelytics workflows can now be viewed by anyone with the link who is in the right organization. [#6622](https://github.com/scalableminds/webknossos/pull/6622)
- Redesigned organization page to include more infos on organization users, storage, webKnossos plan and provided opportunities to upgrade. [#6602](https://github.com/scalableminds/webknossos/pull/6602)

### Fixed
- Fixed importing a dataset from disk. [#6615](https://github.com/scalableminds/webknossos/pull/6615)
- Fixed a bug in the dataset import view, where the layer name text field would lose focus after each key press. [#6615](https://github.com/scalableminds/webknossos/pull/6615)
- Fixed importing NGFF Zarr datasets with non-scale transforms. [#6621](https://github.com/scalableminds/webknossos/pull/6621)
- Fixed a regression in NGFF Zarr import for datasets with no channel axis. [#6636](https://github.com/scalableminds/webknossos/pull/6636)<<<<<<< task-creation-nml
- Fixed broken creation of tasks using base NMLs. [#6634](https://github.com/scalableminds/webknossos/pull/6634)

### Removed

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM openjdk:8-jdk
FROM eclipse-temurin:11
RUN apt-get update \
&& apt-get -y install libblosc1 postgresql-client \
&& rm -rf /var/lib/apt/lists/*
Expand Down
21 changes: 8 additions & 13 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
FROM scalableminds/sbt:master__113
FROM scalableminds/sbt:master__3437035799
ARG VERSION_NODE="16.x"

ENV DEBIAN_FRONTEND noninteractive
ENV SBT_OPTS "${SBT_OPTS} -XX:MaxMetaspaceSize=512m -Xms1024m -Xmx1024m"

# Fixes "The method driver /usr/lib/apt/methods/https could not be found."
# See https://unix.stackexchange.com/a/478009
RUN apt-get update && apt-get install apt-transport-https

# Fixes "The repository 'https://deb.nodesource.com/node_12.x stretch Release' does no longer have a Release file."
# https://github.com/nodesource/distributions/issues/1266#issuecomment-931467582
# https://github.com/nodesource/distributions/issues/1266#issuecomment-931481002
# https://github.com/nodesource/distributions/issues/1266#issuecomment-933102213
RUN apt-get install openssl ca-certificates libgnutls30 && rm /usr/share/ca-certificates/mozilla/DST_Root_CA_X3.crt && update-ca-certificates

# add node package source
RUN curl -sL "https://deb.nodesource.com/setup_${VERSION_NODE}" | bash -

Expand All @@ -23,13 +18,13 @@ RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.lis
# Install sbt, node & build-essentials
RUN apt-get update \
&& apt-get install -y \
build-essential \
findutils \
nodejs \
postgresql-client \
yarn \
build-essential \
findutils \
nodejs \
postgresql-client \
yarn \
# The following packages are necessary to run headless-gl
&& apt-get install -y \
mesa-utils xvfb libgl1-mesa-dri libglapi-mesa libosmesa6 pkg-config x11proto-xext-dev xserver-xorg-dev libxext-dev libxi-dev \
mesa-utils xvfb libgl1-mesa-dri libglapi-mesa libosmesa6 pkg-config x11proto-xext-dev xserver-xorg-dev libxext-dev libxi-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
6 changes: 6 additions & 0 deletions MIGRATIONS.released.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ See `MIGRATIONS.unreleased.md` for the changes which are not yet part of an offi
This project adheres to [Calendar Versioning](http://calver.org/) `0Y.0M.MICRO`.
User-facing changes are documented in the [changelog](CHANGELOG.released.md).

## [22.11.2](https://github.com/scalableminds/webknossos/releases/tag/22.11.2) - 2022-11-10
[Commits](https://github.com/scalableminds/webknossos/compare/22.11.1...22.11.2)

### Postgres Evolutions:


## [22.11.1](https://github.com/scalableminds/webknossos/releases/tag/22.11.1) - 2022-10-27
[Commits](https://github.com/scalableminds/webknossos/compare/22.11.0...22.11.1)

Expand Down
2 changes: 1 addition & 1 deletion MIGRATIONS.unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ This project adheres to [Calendar Versioning](http://calver.org/) `0Y.0M.MICRO`.
User-facing changes are documented in the [changelog](CHANGELOG.released.md).

## Unreleased
[Commits](https://github.com/scalableminds/webknossos/compare/22.11.1...HEAD)
[Commits](https://github.com/scalableminds/webknossos/compare/22.11.2...HEAD)

### Postgres Evolutions:
4 changes: 2 additions & 2 deletions app/controllers/TaskController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ Expects:
_ <- bool2Fox(inputFiles.nonEmpty) ?~> "nml.file.notFound"
jsonString <- body.dataParts.get("formJSON").flatMap(_.headOption) ?~> "format.json.missing"
params <- JsonHelper.parseJsonToFox[NmlTaskParameters](jsonString) ?~> "task.create.failed"
_ <- taskCreationService.assertBatchLimit(inputFiles.length, List(params.taskTypeId))
taskTypeIdValidated <- ObjectId.fromString(params.taskTypeId) ?~> "taskType.id.invalid"
_ <- taskCreationService.assertBatchLimit(inputFiles.length, List(params.taskTypeIdOrSummary))
taskTypeIdValidated <- ObjectId.fromString(params.taskTypeIdOrSummary) ?~> "taskType.id.invalid"
taskType <- taskTypeDAO.findOne(taskTypeIdValidated) ?~> "taskType.notFound" ~> NOT_FOUND
project <- projectDAO
.findOneByNameAndOrganization(params.projectName, request.identity._organization) ?~> "project.notFound" ~> NOT_FOUND
Expand Down
14 changes: 10 additions & 4 deletions app/controllers/VoxelyticsController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class VoxelyticsController @Inject()(
for {
_ <- bool2Fox(wkConf.Features.voxelyticsEnabled) ?~> "voxelytics.disabled"
// Auth is implemented in `voxelyticsDAO.findRuns`
runs <- voxelyticsDAO.findRuns(request.identity, None, workflowHash, conf.staleTimeout)
runs <- voxelyticsDAO.findRuns(request.identity, None, workflowHash, conf.staleTimeout, allowUnlisted = false)
result <- if (runs.nonEmpty) {
listWorkflowsWithRuns(request, runs)
} else {
Expand Down Expand Up @@ -113,9 +113,15 @@ class VoxelyticsController @Inject()(
// If all runs are fetched, a combined version of the workflow report
// will be returned that contains the information of the most recent task runs
runs <- runIdValidatedOpt
.map(runIdValidated =>
voxelyticsDAO.findRuns(request.identity, Some(List(runIdValidated)), Some(workflowHash), conf.staleTimeout))
.getOrElse(voxelyticsDAO.findRuns(request.identity, None, Some(workflowHash), conf.staleTimeout))
.map(
runIdValidated =>
voxelyticsDAO.findRuns(request.identity,
Some(List(runIdValidated)),
Some(workflowHash),
conf.staleTimeout,
allowUnlisted = true))
.getOrElse(
voxelyticsDAO.findRuns(request.identity, None, Some(workflowHash), conf.staleTimeout, allowUnlisted = true))
_ <- bool2Fox(runs.nonEmpty) ?~> "voxelytics.runNotFound" ~> NOT_FOUND
sortedRuns = runs.sortBy(_.beginTime).reverse
// All workflows have at least one run, because they are created at the same time
Expand Down
7 changes: 5 additions & 2 deletions app/models/binary/explore/NgffExplorer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ class NgffExplorer extends RemoteLayerExplorer {
zarrayPath = magPath.resolve(ZarrHeader.FILENAME_DOT_ZARRAY)
zarrHeader <- parseJsonFromPath[ZarrHeader](zarrayPath) ?~> s"failed to read zarr header at $zarrayPath"
axisOrder <- extractAxisOrder(multiscale.axes) ?~> "Could not extract XYZ axis order mapping. Does the data have x, y and z axes, stated in multiscales metadata?"
channelAxisIndex <- axisOrder.c.toFox
} yield zarrHeader.shape(channelAxisIndex)
channelCount = axisOrder.c match {
case Some(channeAxislIndex) => zarrHeader.shape(channeAxislIndex)
case _ => 1
}
} yield channelCount

private def layersFromNgffMultiscale(multiscale: NgffMultiscalesItem,
remotePath: Path,
Expand Down
3 changes: 2 additions & 1 deletion app/models/task/TaskCreationParameters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ object TaskParameters {
implicit val taskParametersFormat: Format[TaskParameters] = Json.format[TaskParameters]
}

case class NmlTaskParameters(taskTypeId: String,
case class NmlTaskParameters(taskTypeIdOrSummary: String,
// taskTypeIdOrSummary named like this for compatibility, note that in NML case only ids are valid.
neededExperience: Experience,
openInstances: Int,
projectName: String,
Expand Down
2 changes: 1 addition & 1 deletion app/models/task/TaskCreationService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ class TaskCreationService @Inject()(taskTypeService: TaskTypeService,
val parsedNmlTracingBoundingBox = params._1.map(b => BoundingBox(b.topLeft, b.width, b.height, b.depth))
val bbox = if (nmlFormParams.boundingBox.isDefined) nmlFormParams.boundingBox else parsedNmlTracingBoundingBox
TaskParameters(
nmlFormParams.taskTypeId,
nmlFormParams.taskTypeIdOrSummary,
nmlFormParams.neededExperience,
nmlFormParams.openInstances,
nmlFormParams.projectName,
Expand Down
6 changes: 4 additions & 2 deletions app/models/voxelytics/VoxelyticsDAO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,11 @@ class VoxelyticsDAO @Inject()(sqlClient: SQLClient)(implicit ec: ExecutionContex
def findRuns(currentUser: User,
runIds: Option[List[ObjectId]],
workflowHash: Option[String],
staleTimeout: Duration): Fox[List[RunEntry]] = {
staleTimeout: Duration,
allowUnlisted: Boolean): Fox[List[RunEntry]] = {
val organizationId = currentUser._organization
val readAccessQ = if (currentUser.isAdmin) { "" } else { s" AND (r._user = ${escapeLiteral(currentUser._id.id)})" }
val readAccessQ =
if (currentUser.isAdmin || allowUnlisted) "" else { s" AND (r._user = ${escapeLiteral(currentUser._id.id)})" }
val runIdsQ = runIds.map(runIds => s" AND r._id IN ${writeEscapedTuple(runIds.map(_.id))}").getOrElse("")
val workflowHashQ =
workflowHash.map(workflowHash => s" AND r.workflow_hash = ${escapeLiteral(workflowHash)}").getOrElse("")
Expand Down
5 changes: 3 additions & 2 deletions docs/sharing.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,11 @@ The information is JSON-encoded in the URL fragment and has the following format
connectomeInfo?: {
connectomeName: string,
agglomerateIdsToImport?: Array<number>,
}
},
isDisabled?: boolean,
},
};

type UrlManagerState = {|
position?: Vector3,
mode?: ViewMode,
Expand Down
2 changes: 1 addition & 1 deletion frontend/javascripts/admin/api/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function getSharingTokenFromUrlParameters(): string | null | undefined {
if (location != null) {
const params = Utils.getUrlParamsObject();

if (params != null && params.token != null) {
if (params?.token != null) {
return params.token;
}
}
Expand Down
3 changes: 1 addition & 2 deletions frontend/javascripts/admin/dataset/dataset_components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export function CardContainer({
title: string;
}) {
if (withoutCard) {
// eslint-disable-next-line react/jsx-no-useless-fragment
return <React.Fragment>{children}</React.Fragment>;
return <>{children}</>;
} else {
return (
<Card
Expand Down
2 changes: 1 addition & 1 deletion frontend/javascripts/admin/dataset/dataset_upload_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ class DatasetUploadView extends React.Component<PropsWithFormAndRouter, State> {
},
{
validator: syncValidator(
(value: Vector3) => value && value.every((el) => el > 0),
(value: Vector3) => value?.every((el) => el > 0),
"Each component of the scale must be larger than 0.",
),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ class ProjectProgressReportView extends React.PureComponent<{}, State> {
updatedAt: null,
};

// @ts-expect-error ts-migrate(1015) FIXME: Parameter cannot have question mark and initialize... Remove this comment to see the full error message
async fetchData(suppressLoadingState?: boolean = false) {
async fetchData(suppressLoadingState: boolean = false) {
const { team } = this.state;

if (team == null) {
Expand Down
2 changes: 1 addition & 1 deletion frontend/javascripts/admin/task/task_annotation_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ class TaskAnnotationView extends React.PureComponent<Props, State> {
})}
</tbody>
</table>
{this.state.currentAnnotation && this.state.currentAnnotation.owner ? (
{this.state.currentAnnotation?.owner ? (
<TransferTaskModal
visible={this.state.isTransferModalVisible}
annotationId={this.state.currentAnnotation.id}
Expand Down
Loading

0 comments on commit ad03de9

Please sign in to comment.