diff --git a/README.md b/README.md index bfddaa8a59120b2c8c1835ac81a578b8cd9506fc..4b6613d49b827be7f5327db4ddfc1184f91a04a3 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,12 @@ The Nyx project focuses on the neural activity and locomotion of the *Drosophila # NyxUI.jl -Web interface meant to be served at [nyx.pasteur.cloud](https://nyx.pasteur.cloud/). +Web interface meant to be served at [nyx.pasteur.cloud](https://nyx.pasteur.cloud/) (public) and [nyx.dev.pasteur.cloud](https://nyx.dev.pasteur.cloud/) (internal). -It features an app catalog, with currently a single available app: +It features an app catalog, with the following apps: -* an editor for muscular activity programs. +* an editor for muscular activity programs, +* [LarvaTagger.jl](https://gitlab.pasteur.fr/nyx/larvatagger.jl) without any automating tagging backends. ## Local installation @@ -29,3 +30,9 @@ julia --project=. routes.jl You may be asked whether to authorize ports 9284 and 9285; please give the app permission. From there, in a web browser, open http://localhost:9284/ to access the app. + +Note that the generated files can be found somewhere in directory *storage/exports*. + +The download buttons in the LarvaTagger app will not work in the web browser. +To make them work, the reverse proxy setup in the container image called *front* is required. +If you have [Podman](https://podman.io/), as an alternative to the above installation procedure, you can simply run `front/build.sh --now` and, once the container is up and running, connect to http://localhost:8080/. diff --git a/front/Manifest.toml b/front/Manifest.toml index 39d0a4e6a058f4de88521428cbb002f5968aa685..7b87bea4414da2f15a4abc08c99fb472c32226cf 100644 --- a/front/Manifest.toml +++ b/front/Manifest.toml @@ -1120,11 +1120,11 @@ version = "1.0.0" [[deps.NyxPlots]] deps = ["Bonito", "Observables", "PlotlyBase"] -git-tree-sha1 = "3d54e1c527baaf6a003e0d7a4fce5fcb9d3dd775" +git-tree-sha1 = "796b76b7aa7d642cf41b60c2f4635f4140048db9" repo-rev = "main" repo-url = "https://gitlab.com/dbc-nyx/NyxPlots.jl" uuid = "e8b8ccdb-0776-4145-b74f-57bbbfff4409" -version = "0.1.2" +version = "0.2.0" [[deps.NyxWidgets]] deps = ["Bonito", "Colors", "Format", "LazyArtifacts", "Observables"] diff --git a/k8s/front-deployment.yaml b/k8s/front-deployment.yaml deleted file mode 100644 index 6cdee87c1596605c2b807c2f750e789a7403b48f..0000000000000000000000000000000000000000 --- a/k8s/front-deployment.yaml +++ /dev/null @@ -1,38 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: ${APP_NAME}-front - labels: - app: $APP_NAME -spec: - replicas: 1 - selector: - matchLabels: - app: $APP_NAME - template: - metadata: - labels: - app: $APP_NAME - nyxui/component: front - spec: - containers: - - name: $APP_NAME - image: $FQ_IMAGE_NAME - resources: - limits: - cpu: "2" - ephemeral-storage: 1Gi - memory: 4Gi - requests: - cpu: "2" - ephemeral-storage: 1Gi - memory: 4Gi - ports: - - name: http - containerPort: 8080 - protocol: TCP - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL \ No newline at end of file diff --git a/k8s/front-service.yaml b/k8s/front-service.yaml deleted file mode 100644 index 64f770f72932c56f81bed168bf45da31af8a6c3d..0000000000000000000000000000000000000000 --- a/k8s/front-service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: ${APP_NAME}-front -spec: - selector: - app: $APP_NAME - nyxui/component: front - ports: - - protocol: TCP - port: 80 - targetPort: http - name: http diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml deleted file mode 100644 index cbaeb77f35b7d87eb9c0558c74e54e514c918842..0000000000000000000000000000000000000000 --- a/k8s/ingress.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: $APP_NAME - labels: - app: $APP_NAME -spec: - ingressClassName: internal - rules: - - host: $PUBLIC_URL - http: - paths: - - path: / - pathType: Prefix - backend: - service: - name: ${APP_NAME}-front - port: - number: 80 diff --git a/nyxui/Chart.yaml b/nyxui/Chart.yaml index 94afc3b14e04b5366844eab130c7c49b0e5bffc5..567ea86302b3a01ca09c28aa9ff20c3b221acfe9 100644 --- a/nyxui/Chart.yaml +++ b/nyxui/Chart.yaml @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 0.1.0 +version: 0.2.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "0.1" +appVersion: "0.2.0" diff --git a/src/apps/muscles/MuscleWidgets.jl b/src/apps/muscles/MuscleWidgets.jl index 0c00d1059f142e6a92cb5a9907b378b69aa5a317..0c12617989856f547b119331022cb1afdbc5c42b 100644 --- a/src/apps/muscles/MuscleWidgets.jl +++ b/src/apps/muscles/MuscleWidgets.jl @@ -22,7 +22,6 @@ struct MuscleWidget sequence::AbstractObservable colormap::AbstractObservable colorscheme::AbstractObservable - setvalue::AbstractObservable overview::Muscles.MultiSegmentMuscleWidget individualsegments::Vector{Muscles.MuscleWidget} heatmaps::Vector{Heatmap} @@ -39,7 +38,6 @@ function MuscleWidget(sequence) on(colormap) do c colorscheme[] = scale2scheme(c) end - setvalue = Observable{Float64}(1) editmode = Observable(false) # overview = Muscles.MultiSegmentMuscleWidget(; musclelabel=false, sidelabel=:right) @@ -49,7 +47,7 @@ function MuscleWidget(sequence) segmentlabel=true, style="width: 40%; margin-top: 2rem;") for segment in segments(overview)] - moveto = clipboard = zlim = nothing + moveto = clipboard = zlim = setvalue = nothing heatmaps = Heatmap[] for segment in individualsegments halfsegment = sequence[][segment.segment, segment.side] @@ -61,10 +59,12 @@ function MuscleWidget(sequence) pick=moveto, clipboard=clipboard, setvalue=setvalue, - zlim=zlim) + zlim=zlim, + prompt_on_assign=true) moveto = heatmap.pick clipboard = heatmap.clipboard zlim = heatmap.zlim + setvalue = heatmap.setvalue push!(heatmaps, heatmap) end detailedviews = [Div(widget, heatmap; style=:row) @@ -137,7 +137,7 @@ function MuscleWidget(sequence) heatmaps[layer-1].editing[] = b end end - return MuscleWidget(sequence, colormap, colorscheme, setvalue, overview, + return MuscleWidget(sequence, colormap, colorscheme, overview, individualsegments, heatmaps, animation, editmode) end diff --git a/src/apps/muscles/app.jl b/src/apps/muscles/app.jl index 082584919dcbe8e831b50d195d406f2e2ff249b1..30eb0d07a215825b8d56d59ee0258798ba59edf1 100644 --- a/src/apps/muscles/app.jl +++ b/src/apps/muscles/app.jl @@ -39,7 +39,6 @@ const bonito_app = NamedApp(:inherit, Backbone.app) @out first_time_in_editmode = true # and in the heatmap view @in editmode = false @out editmode_disable = true - @in setvalue = 1.0 @in series_length::Float64 = 21 @in time_interval = 0.05 @in start_time = 0.0 @@ -71,7 +70,6 @@ const bonito_app = NamedApp(:inherit, Backbone.app) colormap = model.colormap[] editmode = model.editmode[] sequence_name = name - setvalue = model.setvalue[] seq = model.sequence[] series_length = length(seq.times) time_interval = step(seq.times) @@ -221,6 +219,11 @@ const bonito_app = NamedApp(:inherit, Backbone.app) end @onchange editmode begin + if editmode && isempty(sequence_name) + @notify "Create a new program or load one first" :error + editmode = false + return + end model = getmodel(back_session_id) model.editmode[] = editmode editmode_disable = !editmode @@ -240,11 +243,6 @@ const bonito_app = NamedApp(:inherit, Backbone.app) @notify "Toggle the \"edit mode\" off to browse the sequence with the heatmap" :info end - @onchange setvalue begin - model = getmodel(back_session_id) - model.setvalue[] = setvalue - end - @onbutton export_sequence_click begin filepath = exportsequence(back_session_id) if isempty(filepath) @@ -298,7 +296,7 @@ const bonito_app = NamedApp(:inherit, Backbone.app) @notify "Selection copied! Press Ctrl while clicking to paste" :info end @onchange area_selected begin - @notify "Click inside the selected area to assign the setvalue, or press Ctrl while clicking to copy the selection" :info + @notify "Click inside the selected area to assign a value, or press Ctrl while clicking to copy the selection" :info end @onbutton delete_sequence_click begin @@ -331,6 +329,12 @@ const bonito_app = NamedApp(:inherit, Backbone.app) # update the view notify(sequence_names) end + + @onchange no_sequences_yet begin + if no_sequences_yet && editmode + editmode = false + end + end end function dropdown(key, options, label; margin=true, class=nothing) @@ -366,8 +370,6 @@ function muscle_view(bonito_url=""; channel=":channel") Html.div(class="edit-panel", style=col, [ toggle("Toggle edit mode", :editmode, color="blue"), textfield("Motor program name", :sequence_name, disable=:editmode_disable), - textfield("Set value", :setvalue, type="number", step="any", - disable=:editmode_disable), textfield("Number of time steps", :series_length, type="number", step="1", disable=:editmode_disable), textfield("Time interval", :time_interval, type="number", step="any", diff --git a/src/apps/muscles/bonito.css b/src/apps/muscles/bonito.css index 0feaf047580dcb279aa96fab0a9137f1febc2312..ca696314b5442f86ad184b63a4f0080ef30b64b6 100644 --- a/src/apps/muscles/bonito.css +++ b/src/apps/muscles/bonito.css @@ -1,4 +1,4 @@ -.nyx-animated-layers, .nyx-player select, .nyx-player span { +.nyx-animated-layers, .nyx-player select, .nyx-player span, .nyx-segment-side-label-left, .nyx-segment-side-label-right { font-family: Open Sans; }