diff --git a/.env.production.example b/.env.production.example index bbbed471bc..e8c592eceb 100644 --- a/.env.production.example +++ b/.env.production.example @@ -1,7 +1,32 @@ -SFTP_HOST=sftp-host-production -SFTP_PORT=sftp-port-production -SFTP_UPLOAD_FOLDER=sftp-upload-folder # e.g. uploads -SFTP_USER=sftp-user-production +# default uri of your Chemotion ELN for http links in e-mails and notification: +PUBLIC_URL='http://sld.tld' +# senders e-mail: +DEVISE_SENDER='no-reply@sld.tld' + +## SMTP config +# Remote mail server +SMTP_ADDRESS='smtp.sld.tld' +SMTP_PORT=587 +# login user name & password: +SMTP_USERNAME='no-reply@sld.tld' +SMTP_PASSWORD='s3cr3tPW' +# optional, HELO domain +SMTP_DOMAIN='sld.tld' +# detect STARTTLS +SMTP_TLS=true +# authentication type ('plain' 'login' (Base64 encoded) or 'cram_md5') +SMTP_AUTH='plain' +# how OpenSSL checks the certificate ('none' or 'peer') +SMTP_SSL_MODE='none' + +# disable mail delivery +# DISABLE_MAIL_DELIVERY='nomail' + + +#SFTP_HOST=sftp-host-production +#SFTP_PORT=sftp-port-production +#SFTP_UPLOAD_FOLDER=sftp-upload-folder # e.g. uploads +#SFTP_USER=sftp-user-production # Choose between password and ssh-key authentication. # The default key locations are ~/.ssh/id_rsa,~/.ssh/id_dsa. If you want to use diff --git a/.eslintrc b/.eslintrc index bda07eb179..12395e3e8f 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,5 +1,5 @@ { - "parser": "babel-eslint", + "parser": "@babel/eslint-parser", "plugins": [ "react" ], diff --git a/.nvmrc b/.nvmrc index 158c00641a..fa6bc3a85c 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v14.16.0 +v14.20.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ecd3c73fb..cf97c0e52f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,35 @@ * Fixes -# [v1.3.1-pre] +## [v1.4.0] +> 2022-09-26 + +* Important for admin and developers: + * change of environment variable: use PUBLIC_URL instead of HOST and SMTP_HOST + * nodejs upd to 14.20.0 + * drop support for bionic + +* Features and Improvements: + * ketcherservice: server generation of sample svg + * Reaction coefficient: improve yield calculation (https://github.com/ComPlat/chemotion_ELN/issues/544) + * Metadata-converter: v0.6.0 + * Chemspectra: v0.10.15 (allow reprocessing, read Bruker processed files if present) + * Inbox: delete multiple attachments at once (https://github.com/ComPlat/chemotion_ELN/issues/571) + * research-plan: improve context-menu in tables + + +* Fixes: + * SVG generation for sample and reaction: (https://github.com/ComPlat/chemotion_ELN/issues/846) + * Sample amount metric + * report svg composer: skip image if image file does not exist. + * chemspectra: duplicate image generation + + + + + + +## [v1.3.1] > 2022-07-07 * Features and Improvements: diff --git a/VERSION b/VERSION index 78402df0cf..e1e5a88fb6 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ -version: 1.3.1 -base_revision: d7c0c64dda79f938430e5236ce7559ab3bc17242 +version: 1.4.0 +base_revision: 9a6c2441a52356989aa69da67f8283a27a279ff6 current_revision: 0 diff --git a/app/packs/src/components/CollectionManagement.js b/app/packs/src/components/CollectionManagement.js index 3b1ffd6da2..2e9cef559a 100644 --- a/app/packs/src/components/CollectionManagement.js +++ b/app/packs/src/components/CollectionManagement.js @@ -5,7 +5,6 @@ import MyCollections from './collection_management/MyCollections'; import MySharedCollections from './collection_management/MySharedCollections'; import SharedWithMeCollections from './collection_management/SharedWithMeCollections'; import SyncWithMeCollections from './collection_management/SyncWithMeCollections'; -import XTabs from './extra/CollectionManagementXTabs'; const CollectionManagement = () => { const tabContents = [ @@ -14,17 +13,6 @@ const CollectionManagement = () => { , , ]; - const offset = tabContents.length; - for (let j = 0; j < XTabs.count; j += 1) { - if (XTabs[`on${j}`]()) { - const NoName = XTabs[`content${j}`]; - tabContents.push(( - - - - )); - } - } return (
diff --git a/app/packs/src/components/CollectionTree.js b/app/packs/src/components/CollectionTree.js index cd5f1d09b6..50c2ca3254 100644 --- a/app/packs/src/components/CollectionTree.js +++ b/app/packs/src/components/CollectionTree.js @@ -10,7 +10,6 @@ import LoadingActions from './actions/LoadingActions'; import UIStore from './stores/UIStore'; import ElementStore from './stores/ElementStore'; import InboxStore from './stores/InboxStore'; -import Xdiv from './extra/CollectionTreeXdiv'; import UserInfos from './UserInfos'; import DeviceBox from './inbox/DeviceBox'; @@ -287,11 +286,6 @@ export default class CollectionTree extends React.Component { render() { let {ownCollectionVisible, inboxVisible, inbox} = this.state - let extraDiv = []; - for (let j=0;j < Xdiv.count;j++){ - let NoName = Xdiv["content"+j]; - extraDiv.push(); - } const ownCollectionDisplay = ownCollectionVisible ? '' : 'none'; const inboxDisplay = inboxVisible ? '' : 'none'; @@ -320,7 +314,6 @@ export default class CollectionTree extends React.Component {
{this.remoteSyncInSubtrees()}
- {extraDiv.map((e)=>{return e})}
- {tdExtraContents.map(e => e)}
diff --git a/app/packs/src/components/ReactionDetails.js b/app/packs/src/components/ReactionDetails.js index e5b5d3190e..586c65bad3 100644 --- a/app/packs/src/components/ReactionDetails.js +++ b/app/packs/src/components/ReactionDetails.js @@ -20,7 +20,6 @@ import ReactionDetailsProperties from './ReactionDetailsProperties'; import GreenChemistry from './green_chem/GreenChemistry'; import Utils from './utils/Functions'; import PrintCodeButton from './common/PrintCodeButton'; -import XTabs from './extra/ReactionDetailsXTabs'; import UIStore from './stores/UIStore'; import UIActions from './actions/UIActions'; import { setReactionByType } from './ReactionDetailsShare'; @@ -231,19 +230,6 @@ export default class ReactionDetails extends Component { ); } - extraTab(ind) { - const reaction = this.state.reaction || {}; - const num = ind; - const NoName = XTabs["content"+num]; - const TabName = XTabs["title"+num]; - return ( - - - - - - ); - } reactionSVG(reaction) { if(!reaction.svgPath) { @@ -450,19 +436,6 @@ export default class ReactionDetails extends Component { green_chemistry: 'Green Chemistry' } - for (let j = 0; j < XTabs.count; j += 1) { - if (XTabs[`on${j}`](reaction)) { - const NoName = XTabs[`content${j}`]; - tabContentsMap[`xtab_${j}`] = ( - - - - - - ); - tabTitlesMap[`xtab_${j}`] = XTabs[`title${j}`]; - } - } addSegmentTabs(reaction, this.handleSegmentsChange, tabContentsMap); diff --git a/app/packs/src/components/SampleDetails.js b/app/packs/src/components/SampleDetails.js index c746fd1cd2..c53fd775cf 100644 --- a/app/packs/src/components/SampleDetails.js +++ b/app/packs/src/components/SampleDetails.js @@ -34,9 +34,6 @@ import PubchemLabels from './PubchemLabels'; import ElementReactionLabels from './ElementReactionLabels'; import SampleDetailsContainers from './SampleDetailsContainers'; -import XLabels from './extra/SampleDetailsXLabels'; -import XTabs from './extra/SampleDetailsXTabs'; - import StructureEditorModal from './structure_editor/StructureEditorModal'; import Sample from './models/Sample'; @@ -557,7 +554,6 @@ export default class SampleDetails extends React.Component { {colLabel} - {this.extraLabels().map((Lab, i) => )}
@@ -1136,13 +1132,6 @@ export default class SampleDetails extends React.Component { ); } - extraLabels() { - let labels = []; - for (let j = 0; j < XLabels.count; j += 1) { - labels.push(XLabels[`content${j}`]); - } - return labels; - } sampleIsValid() { const { sample, loadingMolecule, quickCreator } = this.state; @@ -1295,19 +1284,6 @@ export default class SampleDetails extends React.Component { measurements: 'Measurements!' }; - for (let j = 0; j < XTabs.count; j += 1) { - if (XTabs[`on${j}`](sample)) { - const NoName = XTabs[`content${j}`]; - tabContentsMap[`xtab_${j}`] = ( - - - - - - ); - tabTitlesMap[`xtab_${j}`] = XTabs[`title${j}`]; - } - } addSegmentTabs(sample, this.handleSegmentsChange, tabContentsMap); const stb = []; diff --git a/app/packs/src/components/inbox/InboxModal.js b/app/packs/src/components/inbox/InboxModal.js index d39ecac019..73987287b3 100644 --- a/app/packs/src/components/inbox/InboxModal.js +++ b/app/packs/src/components/inbox/InboxModal.js @@ -9,8 +9,6 @@ import LoadingActions from '../actions/LoadingActions'; import DeviceBox from '../inbox/DeviceBox'; import UnsortedBox from '../inbox/UnsortedBox'; -import Xdiv from '../extra/CollectionTreeXdiv'; - export default class InboxModal extends React.Component { constructor(props) { super(props); @@ -90,11 +88,6 @@ export default class InboxModal extends React.Component { const { showCollectionTree } = this.props; const { visible, inboxVisible } = this.state; - const extraDiv = []; - for (let j = 0; j < Xdiv.count; j += 1) { - const NoName = Xdiv[`Xdiv${j}`]; - extraDiv.push(); - } const panelClass = showCollectionTree ? 'small-col col-md-6' : 'small-col col-md-5'; const inboxDisplay = inboxVisible ? '' : 'none'; diff --git a/app/packs/src/components/routes.js b/app/packs/src/components/routes.js index 9fdec921e9..afd9f4c66b 100644 --- a/app/packs/src/components/routes.js +++ b/app/packs/src/components/routes.js @@ -5,18 +5,11 @@ import UserStore from './stores/UserStore'; import UIActions from './actions/UIActions'; import UserActions from './actions/UserActions'; import ElementActions from './actions/ElementActions'; -import rXr from './extra/routesXroutes'; import * as routesUtils from './routesUtils'; import UIFetcher from './fetchers/UIFetcher'; import klasses from '../../../../config/klasses.json'; -const allRoutes = (r) => { - let rts = { ...r }; - for (let i = 0; i < rXr.count; i++) { rts = { ...rts, ...rXr[`content${i}`] }; } - return rts; -} - const routes = { '/': 'root', target: { @@ -134,5 +127,5 @@ klasses && klasses.forEach((klass) => { export default function() { Aviator.root = '/mydb'; Aviator.pushStateEnabled = true; - Aviator.setRoutes(allRoutes(routes)); + Aviator.setRoutes(routes); } diff --git a/app/packs/src/components/search/SearchFilter.js b/app/packs/src/components/search/SearchFilter.js index b37da55f05..20accf6e87 100644 --- a/app/packs/src/components/search/SearchFilter.js +++ b/app/packs/src/components/search/SearchFilter.js @@ -2,7 +2,7 @@ import React from 'react' import {Button, FormControl} from 'react-bootstrap' import Select from 'react-select' import UIActions from '../actions/UIActions'; -import XSearchParams from "../extra/AdvancedSearchXSearchParams"; + export default class SearchFilter extends React.Component { constructor(props) { @@ -60,11 +60,7 @@ export default class SearchFilter extends React.Component { } ]; - for (let i = 0; i < XSearchParams.count; i++){ - if (XSearchParams[`on${i}`]) { - this.listOptions = this.listOptions.concat(XSearchParams[`content${i}`]) - } - } + this.andOrOps = [ { value: "AND", label: "AND" }, diff --git a/app/packs/src/components/stores/CollectionStore.js b/app/packs/src/components/stores/CollectionStore.js index ac61505b30..a07dc3a115 100644 --- a/app/packs/src/components/stores/CollectionStore.js +++ b/app/packs/src/components/stores/CollectionStore.js @@ -1,12 +1,6 @@ import alt from '../alt'; import CollectionActions from '../actions/CollectionActions'; -import {extraThing} from '../utils/Functions'; -import Xlisteners from '../extra/CollectionStoreXlisteners'; -import Xhandlers from '../extra/CollectionStoreXhandlers'; -import Xstate from '../extra/CollectionStoreXstate'; - - class CollectionStore { constructor() { @@ -18,15 +12,8 @@ class CollectionStore { lockedRoots: [], syncInRoots: [], visibleRootsIds: [], - ...extraThing(Xstate) }; - for (let i = 0 ; i < Xlisteners.count; i++){ - Object.keys(Xlisteners["content"+i]).map((k)=>{ - this.bindAction(Xlisteners["content" + i][k], - Xhandlers["content" + i][k].bind(this)) - }); - } this.bindListeners({ handleTakeOwnership: CollectionActions.takeOwnership, diff --git a/app/packs/src/components/stores/ElementStore.js b/app/packs/src/components/stores/ElementStore.js index 8b8905443c..ca680df78a 100644 --- a/app/packs/src/components/stores/ElementStore.js +++ b/app/packs/src/components/stores/ElementStore.js @@ -31,10 +31,6 @@ import WellplatesFetcher from '../fetchers/WellplatesFetcher'; import ScreensFetcher from '../fetchers/ScreensFetcher'; import ModalImportConfirm from '../contextActions/ModalImportConfirm'; -import { extraThing } from '../utils/Functions'; -import Xlisteners from '../extra/ElementStoreXlisteners'; -import Xhandlers from '../extra/ElementStoreXhandlers'; -import Xstate from '../extra/ElementStoreXstate'; import { elementShowOrNew } from '../routesUtils'; import DetailActions from '../actions/DetailActions'; @@ -112,18 +108,9 @@ class ElementStore { activeKey: 0, deletingElement: null, //// - ...extraThing(Xstate) }; - - for (let i = 0; i < Xlisteners.count; i++){ - Object.keys(Xlisteners["content"+i]).map((k) => { - this.bindAction(Xlisteners["content" + i][k], - Xhandlers["content" + i][k].bind(this)) - }); - } - this.bindListeners({ handleFetchAllDevices: ElementActions.fetchAllDevices, handleFetchDeviceById: ElementActions.fetchDeviceById, diff --git a/app/packs/src/components/utils/Functions.js b/app/packs/src/components/utils/Functions.js index f2d273c3e1..21bf45ca53 100644 --- a/app/packs/src/components/utils/Functions.js +++ b/app/packs/src/components/utils/Functions.js @@ -24,11 +24,6 @@ const Functions = { link.dispatchEvent(event); }, - extraThing(extra) { - let obj = {}; - for (let i = 0; i < extra['count'];i++){obj={...obj,...extra['content'+i]} } - return obj; - } }; diff --git a/app/packs/src/libHome/Home.js b/app/packs/src/libHome/Home.js index f10965a001..8d1711316c 100644 --- a/app/packs/src/libHome/Home.js +++ b/app/packs/src/libHome/Home.js @@ -3,17 +3,8 @@ import ReactDOM from 'react-dom'; import { Grid, Row } from 'react-bootstrap'; import Navigation from '../components/Navigation' -import XHome from '../components/extra/HomeXHome' import WelcomeMessage from '../components/WelcomeMessage'; -const extraHomes = () => { - const homes = []; - const count = XHome.count || 0; - for (let j = 0; j < count; j += 1) { - homes.push(XHome[`content${j}`]); - } - return homes; -}; class Home extends Component { constructor(props) { @@ -23,17 +14,14 @@ class Home extends Component { render() { return (
- { XHome.count && XHome.count > 0 - ? extraHomes().map((Annex, i) => ) - : - - - - - - - - } + + + + + + + +
); } diff --git a/config/deploy.rb b/config/deploy.rb index 72ea102fc5..51d61ec910 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -15,7 +15,7 @@ set :bundle_jobs, 4 # parallel bundler set :nvm_type, :user -set :nvm_node, File.exist?('.nvmrc') && File.read('.nvmrc').strip || 'v14.16.0' +set :nvm_node, File.exist?('.nvmrc') && File.read('.nvmrc').strip || 'v14.20.0' set :npm_version, File.exist?('.npm-version') && File.read('.npm-version').strip || '7.11.1' set :nvm_map_bins, fetch(:nvm_map_bins, []).push('rake') set :nvm_map_bins, fetch(:nvm_map_bins, []).push('bundle') diff --git a/scripts/install_development.sh b/scripts/install_development.sh index e4611544a7..f3b06280c3 100755 --- a/scripts/install_development.sh +++ b/scripts/install_development.sh @@ -19,12 +19,12 @@ PROD=chemotion # PROD_HOME=$(eval echo "~$PROD") ## RUBY -RUBY_VERSION=2.6.6 # 2.5 recommended for bionic +RUBY_VERSION=2.6.8 BUNDLER_VERSION=1.17.3 ## NODEJS NVM_VERSION='v0.38.0' -NODE_VERSION=14.16.0 +NODE_VERSION=14.20.0 NPM_VERSION=7.11.1 YARN_VERSION=1.22.10 @@ -79,12 +79,8 @@ PART_9='log-rotation' ## supported Distribution Version . /etc/os-release -V18='bionic' V20='focal' V10='buster' -# if [ "$VERSION_CODENAME" = "$V18" ]; then -# RUBY_VERSION=2.5.8 -# fi GRE='\033[0;32m' @@ -130,7 +126,7 @@ rm_tmp_repo() { trap "rm_tmp; rm_tmp_repo; red 'An error has occured'" ERR -if [ "$VERSION_CODENAME" = "$V10" ] || [ "$VERSION_CODENAME" = "$V18" ] || [ "$VERSION_CODENAME" = "$V20" ]; then +if [ "$VERSION_CODENAME" = "$V10" ] || [ "$VERSION_CODENAME" = "$V20" ]; then sharpi "Running installation for $PRETTY_NAME " else error "The installation for your distribution ($PRETTY_NAME) has not been tested" diff --git a/scripts/install_production.sh b/scripts/install_production.sh index b92a803e18..f94d6a5736 100755 --- a/scripts/install_production.sh +++ b/scripts/install_production.sh @@ -11,7 +11,7 @@ set -euo pipefail ############# VARIABLES #################### REPO='https://github.com/ComPlat/chemotion_ELN.git' -BRANCH='v1.3' +BRANCH='v1.4' TMP_REPO_DIR="/tmp/${BRANCH}.git" ## user account name (to be created or to be used) @@ -20,12 +20,12 @@ PROD=production # PROD_HOME=$(eval echo "~$PROD") ## RUBY -RUBY_VERSION=2.6.6 # 2.5 recommended for bionic +RUBY_VERSION=2.6.8 BUNDLER_VERSION=1.17.3 ## NODEJS NVM_VERSION='v0.38.0' -NODE_VERSION=14.16.0 +NODE_VERSION=14.20.0 NPM_VERSION=7.11.1 APP_NAME=chemotion_ELN # used for naming directories and files @@ -87,12 +87,8 @@ PART_11='configure NGINX' ## supported Distribution Version . /etc/os-release -V18='bionic' V20='focal' V10='buster' -# if [ "$VERSION_CODENAME" = "$V18" ]; then -# RUBY_VERSION=2.5.8 -# fi GRE='\033[0;32m' YEL='\033[0;33m' @@ -137,7 +133,7 @@ rm_tmp_repo() { trap "rm_tmp; rm_tmp_repo; red 'An error has occured'" ERR -if [ "$VERSION_CODENAME" = "$V10" ] || [ "$VERSION_CODENAME" = "$V18" ] || [ "$VERSION_CODENAME" = "$V20" ]; then +if [ "$VERSION_CODENAME" = "$V10" ] || [ "$VERSION_CODENAME" = "$V20" ]; then sharpi "Running installation for $PRETTY_NAME " else error "The installation for your distribution ($PRETTY_NAME) has not been tested" diff --git a/scripts/update_production.sh b/scripts/update_production.sh index f611f6aa93..411759bc97 100755 --- a/scripts/update_production.sh +++ b/scripts/update_production.sh @@ -9,7 +9,7 @@ set -euo pipefail ## CHEMOTION ELN GIT REPOSITORY REPO='https://github.com/ComPlat/chemotion_ELN.git' -BRANCH='v1.3' +BRANCH='v1.4' TMP_REPO_DIR="/tmp/${BRANCH}.git" ## user account name (to be created or to be used) @@ -17,12 +17,12 @@ PROD=production PROD_HOME=$(eval echo "~$PROD") ## RUBY -RUBY_VERSION=2.6.6 +RUBY_VERSION=2.6.8 BUNDLER_VERSION=1.17.3 ## NODEJS NVM_VERSION='v0.38.0' -NODE_VERSION=14.16.0 +NODE_VERSION=14.20.0 NPM_VERSION=7.11.1 ## default naming of directories and files