Skip to content

Commit

Permalink
Merge pull request #158 from data-intuitive/develop
Browse files Browse the repository at this point in the history
* Add perturbation replicate information in top table rows
* Make filter & perturbation replicate information sections in the top table rows expansible
* Hide server configuration files from the webserver
* Update of the Node version and npm packages
* Fix triple warning in the browser console about invalid fonts
* Bump version to 5.4.0
  • Loading branch information
Grifs authored Nov 28, 2022
2 parents 3e3d8c6 + 33a34fe commit d98bc5c
Show file tree
Hide file tree
Showing 20 changed files with 9,252 additions and 8,810 deletions.
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
# CHANGELOG

## Version 5.4.0

### Functionality

- Display a Sample Information Details section in top tables
- Change filter and sample information details to be collapsable (collapsed by default)

### Minor changes

- Fix table sample info display of dose & time so the text is properly truncated if the value string is long
- Hide table sample info fields if the API call returned either empty or "Feature not found"
- Display single cell information in sample selection and table sample info
- Solve the 3 invalid font warnings on the console
- Display perturbation information details under the expanded table sample info by clicking the 'i' icon

### Other

- Updated required node version in Dockerfile
- Updated some pinned package versions
- Use the helmet package to set/tweak server html headers
- Restructured the folder structure slightly to introduce a `public` folder
This prevents exposing server configuration files
- `dist/bundle.js` now compiles towards the public folder too

### Deployment changes

- `deployments.json` should now be placed in the `public` folder instead of the project root

## Version 5.3.0

### Functionality
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
FROM node:14.3.0
FROM node:14.21.1
USER root

WORKDIR /app

RUN apt-get install -y gcc make

RUN npm install -g node-gyp

# Get sources
# Make sure the correct branch/release is used here!
# RUN git clone https://github.com/data-intuitive/LuciusWeb
COPY . /app/LuciusWeb/

WORKDIR /app/LuciusWeb

RUN npm install -g node-gyp

# LuciusWeb
RUN npm install
RUN npm run build
Expand Down
17,557 changes: 8,917 additions & 8,640 deletions package-lock.json

Large diffs are not rendered by default.

35 changes: 18 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "LuciusWeb",
"version": "5.3.0",
"version": "5.4.0",
"description": "Web interface for ComPass aka Lucius",
"repository": {
"type": "git",
Expand All @@ -25,41 +25,42 @@
"author": "Toni Verbeiren",
"license": "Apache v2",
"devDependencies": {
"@babel/cli": "^7.15.4",
"@babel/core": "^7.15.5",
"@babel/preset-env": "^7.15.4",
"@babel/register": "^7.15.3",
"css-loader": "^6.5.1",
"@babel/cli": "^7.19.3",
"@babel/core": "^7.20.2",
"@babel/preset-env": "^7.20.2",
"@babel/register": "^7.18.9",
"css-loader": "^6.7.2",
"file-loader": "^5.0.2",
"jquery": "^3.6.0",
"jquery": "^3.6.1",
"materialize-loader": "^3.0.1",
"mini-css-extract-plugin": "^0.8.0",
"mocha": "^9.1.1",
"sass": "^1.35.1",
"mocha": "^10.1.0",
"sass": "^1.56.1",
"sass-loader": "^11.0.1",
"style-loader": "^1.0.1",
"url-loader": "^3.0.0",
"webpack": "^5.36.2",
"webpack-cli": "^4.6.0",
"webpack-dev-server": "^4.5.0",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1",
"webpack-material-design-icons": "^0.1.0"
},
"dependencies": {
"@cycle/dom": "^23.0.0",
"@cycle/dom": "^23.1.0",
"@cycle/history": "^8.0.0",
"@cycle/http": "^15.4.0",
"@cycle/isolate": "^5.2.0",
"@cycle/run": "^5.5.0",
"@cycle/run": "^5.7.0",
"@cycle/storage": "^4.1.1",
"babel-loader": "^8.2.2",
"babel-loader": "^8.3.0",
"cycle-onionify": "^3.3.0",
"cycle-storageify": "^3.2.0",
"cyclic-router": "^6.0.0",
"datalib": "^1.9.3",
"helmet": "^6.0.0",
"materialize-css": "^1.0.0",
"ramda": "^0.27.1",
"ramda": "^0.27.2",
"switch-path": "^1.2.0",
"vega": "^5.20.2",
"vega": "^5.22.1",
"vega-parser": "^6.1.3",
"xstream": "^11.14.0"
}
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
29 changes: 24 additions & 5 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
var path = require("path");
var express = require("express");
const path = require("path");
const express = require("express");
const helmet = require("helmet");

var DIST_DIR = __dirname;
var PORT = 80;
var app = express();
const DIST_DIR = path.join(__dirname, "public");
const PORT = 80;
const app = express();

//Serving the files on the dist folder
app.use(express.static(DIST_DIR));

// Tweak rules so that it allows off-site logo & sourire images
// app.use(helmet.contentSecurityPolicy());
// app.use(helmet.crossOriginEmbedderPolicy());
// app.use(helmet.crossOriginOpenerPolicy());
app.use(helmet.crossOriginResourcePolicy({ policy: "cross-origin" }));
app.use(helmet.dnsPrefetchControl());
app.use(helmet.expectCt());
app.use(helmet.frameguard());
app.use(helmet.hidePoweredBy());
app.use(helmet.hsts());
app.use(helmet.ieNoOpen());
app.use(helmet.noSniff());
app.use(helmet.originAgentCluster());
app.use(helmet.permittedCrossDomainPolicies());
app.use(helmet.referrerPolicy());
app.use(helmet.xssFilter());


//Send index.html when the user access the web
app.get("*", function (req, res) {
res.sendFile(path.join(DIST_DIR, "index.html"));
Expand Down
40 changes: 40 additions & 0 deletions src/js/components/InformationDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import xs from 'xstream'
import sampleCombine from 'xstream/extra/sampleCombine'

export function InformationDetails(sources) {

const state$ = sources.onion.state$
const props$ = sources.props
const trigger$ = sources.trigger

// Combine with deployments to the up-to-date endpoint config
const triggerQuery$ = trigger$.filter(t => t).compose(sampleCombine(state$)).map(([t, s]) => s)

const request$ = xs.combine(triggerQuery$, props$)
.map(([state, props]) => ({
url: props.api.url + '&classPath=com.dataintuitive.luciusapi.perturbationInformationDetails',
method: 'POST',
send: {
'query': state.id
},
'category': 'perturbationInformationDetails'
})
)

const response$$ = sources.HTTP
.select('perturbationInformationDetails')

// TODO: fall back to default filters set in config file
const validResponse$ = response$$
.map(response$ =>
response$.replaceError(_ => xs.of({}))
)
.flatten()

return {
// We don't initialize the stream here so we know exactly when the
// information is available.
informationDetails: validResponse$,
HTTP: request$
}
}
21 changes: 7 additions & 14 deletions src/js/components/SampleSelection.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { TreatmentAnnotation } from "./TreatmentAnnotation"
import { SampleSelectionFilters, SampleSelectionFiltersLens } from "./SampleSelectionFilters"
import { safeModelToUi } from "../modelTranslations"
import { dirtyUiReducer, dirtyWrapperStream, busyUiReducer } from "../utils/ui"
import { maxLengthValueUnit } from "../utils/utils"

const emptyData = {
body: {
Expand Down Expand Up @@ -290,9 +291,14 @@ function SampleSelection(sources) {
.map((response$) => response$.replaceError(() => xs.of(emptyData)))
.flatten()

const getSingleCell = (input) => input.split('|')[0] ?? "N/A"

const data$ = response$
.map((res) => res.body)
.map((json) => json.result.data)
.map(array => {
return array.map(val => { return { ...val, cell: getSingleCell(val.cell) } })
})
.remember()

const sampleFilters = isolate(SampleSelectionFilters, { onion: SampleSelectionFiltersLens })(sources)
Expand Down Expand Up @@ -335,20 +341,7 @@ function SampleSelection(sources) {
entry.id.length > 40 ? entry.id.substring(0, 40) + "..." : entry.id
),
td(selectedClass(entry.use), entry.cell),
td(selectedClass(entry.use),
((_) => {
const dose = entry.dose !== "N/A" ? entry.dose + " " + entry.dose_unit : entry.dose
const maxLength = 7
if (dose.length <= maxLength)
return dose
else if (isNaN(entry.dose) || entry.dose_unit?.length >= 3)
return dose.substring(0, maxLength-1) + "..."
// adding '...' is quite small on screen (in non-monospaced fonts), so we're ignoring that
else
return Number(entry.dose).toFixed(maxLength - 3 - entry.dose_unit?.length) + " " + entry.dose_unit
// -3 = '0.' and ' '
})()
),
td(selectedClass(entry.use), maxLengthValueUnit(entry.dose, entry.dose_unit, 7)),
// td(selectedClass(entry.use), entry.batch),
// td(selectedClass(entry.use), entry.year),
td(selectedClass(entry.use), entry.time !== "N/A" ? entry.time + " " + entry.time_unit : entry.time),
Expand Down
Loading

0 comments on commit d98bc5c

Please sign in to comment.