From 51d514e950f090275cedfdca017e715859624fd6 Mon Sep 17 00:00:00 2001 From: pkupczyk <piotr.kupczyk@id.ethz.ch> Date: Fri, 18 Mar 2022 11:25:30 +0100 Subject: [PATCH] Move logic to AppController --- openbis_ng_ui/src/js/components/App.jsx | 60 +-- .../src/js/components/AppController.js | 409 +++++++++++++++++- .../js/components/common/ComponentContext.js | 5 - .../js/components/common/browser/Browser.jsx | 23 +- .../common/browser/BrowserController.js | 6 +- .../js/components/common/content/Content.jsx | 41 +- .../components/common/form/LinkToObject.jsx | 19 +- .../src/js/components/common/menu/Menu.jsx | 58 ++- .../common/page/PageControllerChanged.js | 9 +- .../common/page/PageControllerLoad.js | 4 +- .../common/page/PageControllerSave.js | 28 +- .../src/js/components/login/Login.jsx | 20 +- .../tools/browser/ToolBrowserController.js | 10 +- .../components/tools/common/HistoryGrid.jsx | 5 +- .../plugin/PluginFormControllerEvaluate.js | 4 +- .../form/query/QueryFormControllerExecute.js | 4 +- .../js/components/tools/search/ToolSearch.jsx | 5 +- .../types/browser/TypeBrowserController.js | 10 +- .../EntityTypeFormPreviewProperty.jsx | 8 +- .../js/components/types/search/TypeSearch.jsx | 5 +- .../users/browser/UserBrowserController.js | 18 +- .../js/components/users/search/UserSearch.jsx | 5 +- openbis_ng_ui/src/js/store/history.js | 4 +- 23 files changed, 518 insertions(+), 242 deletions(-) diff --git a/openbis_ng_ui/src/js/components/App.jsx b/openbis_ng_ui/src/js/components/App.jsx index e06b48c7d88..4e3396549f2 100644 --- a/openbis_ng_ui/src/js/components/App.jsx +++ b/openbis_ng_ui/src/js/components/App.jsx @@ -1,12 +1,10 @@ import React from 'react' import _ from 'lodash' -import { connect } from 'react-redux' +import autoBind from 'auto-bind' import { withStyles } from '@material-ui/core/styles' import logger from '@src/js/common/logger.js' import util from '@src/js/common/util.js' import pages from '@src/js/common/consts/pages.js' -import actions from '@src/js/store/actions/actions.js' -import selectors from '@src/js/store/selectors/selectors.js' import Loading from '@src/js/components/common/loading/Loading.jsx' import Error from '@src/js/components/common/error/Error.jsx' @@ -45,30 +43,10 @@ const pageToComponent = { [pages.TOOLS]: Tools } -function mapStateToProps(state) { - return { - initialized: selectors.getInitialized(state), - loading: selectors.getLoading(state), - session: selectors.getSession(state), - currentPage: selectors.getCurrentPage(state), - error: selectors.getError(state) - } -} - -function mapDispatchToProps(dispatch) { - return { - init: () => { - dispatch(actions.init()) - }, - errorClosed: () => { - dispatch(actions.errorChange(null)) - } - } -} - class App extends React.Component { constructor(props) { super(props) + autoBind(this) this.state = {} @@ -82,34 +60,39 @@ class App extends React.Component { } componentDidMount() { - this.props.init() + this.controller.load() + } + + handleErrorClosed() { + AppController.errorChange(null) } render() { logger.log(logger.DEBUG, 'App.render') return ( - <AppController.LastObjectModificationsContext.Provider - value={AppController.getLastObjectModifications()} - > - <Loading loading={this.props.loading}> - <Error error={this.props.error} errorClosed={this.props.errorClosed}> - {this.props.initialized && this.renderPage()} + <AppController.AppContext.Provider value={this.state}> + <Loading loading={AppController.getLoading()}> + <Error + error={AppController.getError()} + errorClosed={this.handleErrorClosed} + > + {AppController.getLoaded() && this.renderPage()} </Error> </Loading> - </AppController.LastObjectModificationsContext.Provider> + </AppController.AppContext.Provider> ) } renderPage() { const classes = this.props.classes - if (this.props.session) { + if (AppController.getSession()) { return ( <div className={classes.container}> - <Menu page={this.props.currentPage} /> + <Menu /> {_.map(pageToComponent, (PageComponent, page) => { - let visible = this.props.currentPage === page + let visible = AppController.getCurrentPage() === page return ( <div key={page} @@ -125,12 +108,9 @@ class App extends React.Component { </div> ) } else { - return <Login disabled={this.props.loading} /> + return <Login disabled={AppController.getLoading()} /> } } } -export default _.flow( - connect(mapStateToProps, mapDispatchToProps), - withStyles(styles) -)(App) +export default _.flow(withStyles(styles), AppController.withState())(App) diff --git a/openbis_ng_ui/src/js/components/AppController.js b/openbis_ng_ui/src/js/components/AppController.js index 34e2ef349b0..a686d679798 100644 --- a/openbis_ng_ui/src/js/components/AppController.js +++ b/openbis_ng_ui/src/js/components/AppController.js @@ -1,25 +1,404 @@ +import _ from 'lodash' import React from 'react' +import openbis from '@src/js/services/openbis.js' +import objectType from '@src/js/common/consts/objectType.js' +import objectOperation from '@src/js/common/consts/objectOperation.js' +import routes from '@src/js/common/consts/routes.js' +import cookie from '@src/js/common/cookie.js' +import history from '@src/js/store/history.js' export class AppController { constructor() { - this.LastObjectModificationsContext = React.createContext() + this.AppContext = React.createContext() } init(context) { this.context = context + context.initState(this.initialState()) + } - const initialState = { + initialState() { + return { + loaded: false, + loading: false, + session: null, + route: null, + search: null, + pages: [], + error: null, lastObjectModifications: {} } + } + + async load() { + const { loaded } = this.context.getState() + + if (!loaded) { + try { + await this.context.setState({ loading: true }) + await openbis.init() + + const sessionToken = cookie.read(cookie.OPENBIS_COOKIE) + + if (sessionToken) { + try { + openbis.useSession(sessionToken) + + const sessionInformation = await openbis.getSessionInformation() + + if (sessionInformation) { + await this.context.setState({ + session: { + sessionToken: sessionToken, + userName: sessionInformation.userName + } + }) + } else { + openbis.useSession(null) + } + } catch (e) { + openbis.useSession(null) + } + } + + await this.context.setState({ loaded: true }) + } catch (e) { + await this.context.setState({ error: e }) + } finally { + await this.context.setState({ loading: false }) + } + } + } + + async login(username, password) { + try { + await this.context.setState({ loading: true }) + + const sessionToken = await openbis.login(username, password) + + this.context.setState({ + session: { + sessionToken: sessionToken, + userName: username + } + }) + cookie.create(cookie.OPENBIS_COOKIE, sessionToken, 7) + + const { route } = this.context.getState() + const routeObject = routes.parse(route) + await this.context.setState({ route: routeObject.path }) + } catch (e) { + await this.context.setState({ error: 'Incorrect user or password' }) + } finally { + await this.context.setState({ loading: false }) + } + } + + async logout() { + try { + await this.context.setState({ loading: true }) + await openbis.logout() + this.context.setState(state => ({ + ...this.initialState(), + loaded: state.loaded + })) + cookie.erase(cookie.OPENBIS_COOKIE) + await this.context.setState({ route: '/' }) + } catch (e) { + await this.context.setState({ error: e }) + } finally { + await this.context.setState({ loading: false }) + } + } + + async search(page, text) { + if (text.trim().length > 0) { + await this.objectOpen(page, objectType.SEARCH, text.trim()) + } + await this.context.setState({ search: '' }) + } + + async searchChange(text) { + await this.context.setState({ search: text }) + } + + async pageChange(page) { + const pageRoute = this.getCurrentRoute(page) + if (pageRoute) { + await this.context.setState({ route: pageRoute }) + } else { + const route = routes.format({ page }) + await this.context.setState({ route: route }) + } + } + + async errorChange(error) { + await this.context.setState({ error: error }) + } + + async routeChange(path) { + const route = routes.parse(path) + + if (route.type && route.id) { + const object = { type: route.type, id: route.id } + const openTabs = this.getOpenTabs(route.page) + + if (openTabs) { + let found = false + let id = 1 + + openTabs.forEach(openTab => { + if (_.isMatch(openTab.object, object)) { + found = true + } + if (openTab.id >= id) { + id = openTab.id + 1 + } + }) + + if (!found) { + await this.addOpenTab(route.page, id, { id, object }) + } + } + } + + await this.context.setState({ route: path }) + await this.setCurrentRoute(route.page, path) + } + + async routeReplace(route, state) { + history.replace(route, state) + } + + async objectNew(page, type) { + let id = 1 + const openObjects = this.getOpenObjects(page) + openObjects.forEach(openObject => { + if (openObject.type === type) { + id++ + } + }) + + const route = routes.format({ page, type, id }) + await this.context.setState({ route: route }) + } + + async objectCreate(page, oldType, oldId, newType, newId) { + const openTabs = this.getOpenTabs(page) + const oldTab = _.find(openTabs, { object: { type: oldType, id: oldId } }) + + if (oldTab) { + const newTab = { + ...oldTab, + object: { type: newType, id: newId }, + changed: false + } + await this.replaceOpenTab(page, oldTab.id, newTab) + await this.setLastObjectModification( + newType, + objectOperation.CREATE, + Date.now() + ) + + const route = routes.format({ page, type: newType, id: newId }) + await this.routeReplace(route) + } + } + + async objectOpen(page, type, id) { + const route = routes.format({ page, type, id }) + await this.routeChange(route) + } + + async objectUpdate(type) { + await this.setLastObjectModification( + type, + objectOperation.UPDATE, + Date.now() + ) + } + + async objectDelete(page, type, id) { + await this.objectClose(page, type, id) + await this.setLastObjectModification( + type, + objectOperation.DELETE, + Date.now() + ) + } + + async objectChange(page, type, id, changed) { + const openTabs = this.getOpenTabs(page) + const oldTab = _.find(openTabs, { object: { type, id } }) + + if (oldTab) { + const newTab = { ...oldTab, changed } + await this.replaceOpenTab(page, oldTab.id, newTab) + } + } + + async objectClose(page, type, id) { + const openTabs = this.getOpenTabs(page) + const objectToClose = { type, id } + + let selectedObject = this.getSelectedObject(page) + if (selectedObject && _.isEqual(selectedObject, objectToClose)) { + if (_.size(openTabs) === 1) { + selectedObject = null + } else { + let selectedIndex = _.findIndex(openTabs, { object: selectedObject }) + if (selectedIndex === 0) { + selectedObject = openTabs[selectedIndex + 1].object + } else { + selectedObject = openTabs[selectedIndex - 1].object + } + } + } + + let tabToClose = _.find(openTabs, { object: objectToClose }) + if (tabToClose) { + await this.removeOpenTab(page, tabToClose.id) + } + + if (selectedObject) { + const route = routes.format({ + page, + type: selectedObject.type, + id: selectedObject.id + }) + await this.routeChange(route) + } else { + const route = routes.format({ page }) + await this.routeChange(route) + } + } + + getLoaded() { + return this.context.getState().loaded + } + + getLoading() { + return this.context.getState().loading + } + + getSession() { + return this.context.getState().session + } + + getRoute() { + return this.context.getState().route + } + + getSearch() { + return this.context.getState().search + } + + getError() { + return this.context.getState().error + } + + getCurrentPage() { + const { route } = this.context.getState() + return routes.parse(route).page + } - context.initState(initialState) + getCurrentRoute(page) { + const { pages } = this.context.getState() + return pages[page] ? pages[page].currentRoute : null + } + + async setCurrentRoute(page, route) { + await this.context.setState(state => ({ + pages: { + ...state.pages, + [page]: { + ...state.pages[page], + currentRoute: route + } + } + })) + } + + getSelectedObject(page) { + const path = this.getCurrentRoute(page) + if (path) { + const route = routes.parse(path) + if (route && route.type && route.id) { + return { type: route.type, id: route.id } + } + } + return null + } + + getSelectedTab(page) { + const selectedObject = this.getSelectedObject(page) + if (selectedObject) { + const openTabs = this.getOpenTabs(page) + return _.find(openTabs, { object: selectedObject }) + } else { + return null + } + } + + getOpenObjects(page) { + const openTabs = this.getOpenTabs(page) + return openTabs.map(openTab => { + return openTab.object + }) + } + + getOpenTabs(page) { + const { pages } = this.context.getState() + return (pages[page] && pages[page].openTabs) || [] + } + + async setOpenTabs(page, newOpenTabs) { + await this.context.setState(state => ({ + pages: { + ...state.pages, + [page]: { + ...state.pages[page], + openTabs: newOpenTabs + } + } + })) + } + + async addOpenTab(page, id, tab) { + const openTabs = this.getOpenTabs(page) + const index = _.findIndex(openTabs, { id: id }, _.isMatch) + if (index === -1) { + const newOpenTabs = Array.from(openTabs) + newOpenTabs.push(tab) + await this.setOpenTabs(page, newOpenTabs) + } + } + + async removeOpenTab(page, id) { + const openTabs = this.getOpenTabs(page) + const index = _.findIndex(openTabs, { id: id }, _.isMatch) + if (index !== -1) { + const newOpenTabs = Array.from(openTabs) + newOpenTabs.splice(index, 1) + await this.setOpenTabs(page, newOpenTabs) + } + } + + async replaceOpenTab(page, id, tab) { + const openTabs = this.getOpenTabs(page) + const index = _.findIndex(openTabs, { id: id }, _.isMatch) + if (index !== -1) { + const newOpenTabs = Array.from(openTabs) + newOpenTabs[index] = tab + await this.setOpenTabs(page, newOpenTabs) + } } getLastObjectModifications() { return this.context.getState().lastObjectModifications } - setLastObjectModification(type, operation, timestamp) { + async setLastObjectModification(type, operation, timestamp) { const { lastObjectModifications } = this.context.getState() if ( @@ -27,7 +406,7 @@ export class AppController { !lastObjectModifications[type][operation] || lastObjectModifications[type][operation] < timestamp ) { - this.context.setState({ + await this.context.setState({ lastObjectModifications: { ...lastObjectModifications, [type]: { ...lastObjectModifications[type], [operation]: timestamp } @@ -36,22 +415,18 @@ export class AppController { } } - withLastObjectModifications() { - return this._withContext( - this.LastObjectModificationsContext, - 'lastObjectModifications' - ) - } - - _withContext(Context, propertyName) { + withState(additionalPropertiesFn) { const WithContext = Component => { const WithConsumer = props => { - return React.createElement(Context.Consumer, {}, value => - React.createElement(Component, { + return React.createElement(this.AppContext.Consumer, {}, () => { + const additionalProperties = additionalPropertiesFn + ? additionalPropertiesFn(props) + : {} + return React.createElement(Component, { ...props, - [propertyName]: value + ...additionalProperties }) - ) + }) } WithConsumer.displayName = 'WithConsumer' return WithConsumer diff --git a/openbis_ng_ui/src/js/components/common/ComponentContext.js b/openbis_ng_ui/src/js/components/common/ComponentContext.js index 35c7f64f2b3..bbcf0830ff2 100644 --- a/openbis_ng_ui/src/js/components/common/ComponentContext.js +++ b/openbis_ng_ui/src/js/components/common/ComponentContext.js @@ -13,7 +13,6 @@ export default class ComponentContext { return component.state } this.setStateFn = component.setState.bind(component) - this.dispatchFn = component.props.dispatch } initState(initialState) { @@ -36,10 +35,6 @@ export default class ComponentContext { }) } - dispatch(action) { - this.dispatchFn(action) - } - getFacade() { return this.facade } diff --git a/openbis_ng_ui/src/js/components/common/browser/Browser.jsx b/openbis_ng_ui/src/js/components/common/browser/Browser.jsx index f1980f18cc7..e8919babdea 100644 --- a/openbis_ng_ui/src/js/components/common/browser/Browser.jsx +++ b/openbis_ng_ui/src/js/components/common/browser/Browser.jsx @@ -1,6 +1,5 @@ import _ from 'lodash' import React from 'react' -import { connect } from 'react-redux' import { Resizable } from 're-resizable' import { withStyles } from '@material-ui/core/styles' import FilterField from '@src/js/components/common/form/FilterField.jsx' @@ -9,7 +8,6 @@ import BrowserNodes from '@src/js/components/common/browser/BrowserNodes.jsx' import BrowserButtons from '@src/js/components/common/browser/BrowserButtons.jsx' import BrowserDialogRemoveNode from '@src/js/components/common/browser/BrowserDialogRemoveNode.jsx' import AppController from '@src/js/components/AppController.js' -import selectors from '@src/js/store/selectors/selectors.js' import logger from '@src/js/common/logger.js' const styles = theme => ({ @@ -29,18 +27,6 @@ const styles = theme => ({ } }) -function mapStateToProps() { - return (state, ownProps) => { - return { - session: selectors.getSession(state), - selectedObject: selectors.getSelectedObject( - state, - ownProps.controller.getPage() - ) - } - } -} - class Browser extends React.PureComponent { constructor(props) { super(props) @@ -125,7 +111,12 @@ class Browser extends React.PureComponent { } export default _.flow( - connect(mapStateToProps), withStyles(styles), - AppController.withLastObjectModifications() + AppController.withState(ownProps => ({ + session: AppController.getSession(), + selectedObject: AppController.getSelectedObject( + ownProps.controller.getPage() + ), + lastObjectModifications: AppController.getLastObjectModifications() + })) )(Browser) diff --git a/openbis_ng_ui/src/js/components/common/browser/BrowserController.js b/openbis_ng_ui/src/js/components/common/browser/BrowserController.js index 2565f94de6b..6dae7cd134b 100644 --- a/openbis_ng_ui/src/js/components/common/browser/BrowserController.js +++ b/openbis_ng_ui/src/js/components/common/browser/BrowserController.js @@ -1,6 +1,6 @@ import _ from 'lodash' import autoBind from 'auto-bind' -import actions from '@src/js/store/actions/actions.js' +import AppController from '@src/js/components/AppController.js' export default class BrowserController { doGetPage() { @@ -175,9 +175,7 @@ export default class BrowserController { }) if (nodeObject) { - this.context.dispatch( - actions.objectOpen(this.getPage(), nodeObject.type, nodeObject.id) - ) + AppController.objectOpen(this.getPage(), nodeObject.type, nodeObject.id) } const newNodes = this._setNodesSelected(nodes, nodeId, nodeObject) diff --git a/openbis_ng_ui/src/js/components/common/content/Content.jsx b/openbis_ng_ui/src/js/components/common/content/Content.jsx index c034a4ac1dd..b84766ad618 100644 --- a/openbis_ng_ui/src/js/components/common/content/Content.jsx +++ b/openbis_ng_ui/src/js/components/common/content/Content.jsx @@ -1,11 +1,9 @@ import _ from 'lodash' import React from 'react' -import { connect } from 'react-redux' import { withStyles } from '@material-ui/core/styles' import ErrorBoundary from '@src/js/components/common/error/ErrorBoundary.jsx' import ContentTabs from '@src/js/components/common/content/ContentTabs.jsx' -import selectors from '@src/js/store/selectors/selectors.js' -import actions from '@src/js/store/actions/actions.js' +import AppController from '@src/js/components/AppController.js' import util from '@src/js/common/util.js' import logger from '@src/js/common/logger.js' @@ -31,31 +29,15 @@ const styles = { } } -function mapStateToProps() { - return (state, ownProps) => { - return { - openTabs: selectors.getOpenTabs(state, ownProps.page), - selectedTab: selectors.getSelectedTab(state, ownProps.page) - } +class Content extends React.Component { + handleTabSelect(tab) { + AppController.objectOpen(this.props.page, tab.object.type, tab.object.id) } -} -function mapDispatchToProps(dispatch, ownProps) { - return { - tabSelect: tab => { - dispatch( - actions.objectOpen(ownProps.page, tab.object.type, tab.object.id) - ) - }, - tabClose: tab => { - dispatch( - actions.objectClose(ownProps.page, tab.object.type, tab.object.id) - ) - } + handleTabClose(tab) { + AppController.objectClose(this.props.page, tab.object.type, tab.object.id) } -} -class Content extends React.Component { render() { logger.log(logger.DEBUG, 'Content.render') @@ -66,8 +48,8 @@ class Content extends React.Component { <ContentTabs tabs={this.props.openTabs} selectedTab={this.props.selectedTab} - tabSelect={this.props.tabSelect} - tabClose={this.props.tabClose} + tabSelect={this.handleTabSelect} + tabClose={this.handleTabClose} renderTab={this.props.renderTab} /> {this.props.openTabs.map(openTab => { @@ -93,6 +75,9 @@ class Content extends React.Component { } export default _.flow( - connect(mapStateToProps, mapDispatchToProps), - withStyles(styles) + withStyles(styles), + AppController.withState(ownProps => ({ + openTabs: AppController.getOpenTabs(ownProps.page), + selectedTab: AppController.getSelectedTab(ownProps.page) + })) )(Content) diff --git a/openbis_ng_ui/src/js/components/common/form/LinkToObject.jsx b/openbis_ng_ui/src/js/components/common/form/LinkToObject.jsx index 5d5e3c1a972..76c6903752c 100644 --- a/openbis_ng_ui/src/js/components/common/form/LinkToObject.jsx +++ b/openbis_ng_ui/src/js/components/common/form/LinkToObject.jsx @@ -1,10 +1,8 @@ -import _ from 'lodash' import React from 'react' import autoBind from 'auto-bind' -import { connect } from 'react-redux' import { withStyles } from '@material-ui/core/styles' +import AppController from '@src/js/components/AppController.js' import Link from '@material-ui/core/Link' -import actions from '@src/js/store/actions/actions.js' const styles = () => ({ link: { @@ -12,14 +10,6 @@ const styles = () => ({ } }) -function mapDispatchToProps(dispatch) { - return { - objectOpen: (page, objectType, objectId) => { - dispatch(actions.objectOpen(page, objectType, objectId)) - } - } -} - class LinkToObject extends React.Component { constructor(props) { super(props) @@ -28,7 +18,7 @@ class LinkToObject extends React.Component { handleClick() { const { page, object } = this.props - this.props.objectOpen(page, object.type, object.id) + AppController.objectOpen(page, object.type, object.id) } render() { @@ -45,7 +35,4 @@ class LinkToObject extends React.Component { } } -export default _.flow( - connect(null, mapDispatchToProps), - withStyles(styles) -)(LinkToObject) +export default withStyles(styles)(LinkToObject) diff --git a/openbis_ng_ui/src/js/components/common/menu/Menu.jsx b/openbis_ng_ui/src/js/components/common/menu/Menu.jsx index b0937a7ed1d..04ac927a3a5 100644 --- a/openbis_ng_ui/src/js/components/common/menu/Menu.jsx +++ b/openbis_ng_ui/src/js/components/common/menu/Menu.jsx @@ -1,3 +1,5 @@ +import _ from 'lodash' +import autoBind from 'auto-bind' import React from 'react' import AppBar from '@material-ui/core/AppBar' import Toolbar from '@material-ui/core/Toolbar' @@ -9,10 +11,8 @@ import SearchIcon from '@material-ui/icons/Search' import CloseIcon from '@material-ui/icons/Close' import LogoutIcon from '@material-ui/icons/PowerSettingsNew' import { alpha } from '@material-ui/core/styles/colorManipulator' -import { connect } from 'react-redux' import { withStyles } from '@material-ui/core/styles' -import actions from '@src/js/store/actions/actions.js' -import selectors from '@src/js/store/selectors/selectors.js' +import AppController from '@src/js/components/AppController.js' import Button from '@src/js/components/common/form/Button.jsx' import pages from '@src/js/common/consts/pages.js' import messages from '@src/js/common/messages.js' @@ -57,48 +57,37 @@ const styles = theme => ({ } }) -function mapStateToProps(state) { - return { - currentPage: selectors.getCurrentPage(state), - searchText: selectors.getSearch(state) - } -} - -function mapDispatchToProps(dispatch, ownProps) { - return { - currentPageChange: (event, value) => - dispatch(actions.currentPageChange(value)), - searchChange: value => dispatch(actions.searchChange(value)), - search: value => dispatch(actions.search(ownProps.page, value)), - logout: () => dispatch(actions.logout()) - } -} - class Menu extends React.Component { constructor(props) { super(props) + autoBind(this) this.searchRef = React.createRef() - this.handleSearchChange = this.handleSearchChange.bind(this) - this.handleSearchKeyPress = this.handleSearchKeyPress.bind(this) - this.handleSearchClear = this.handleSearchClear.bind(this) + } + + handlePageChange(event, value) { + AppController.pageChange(value) } handleSearchChange(event) { - this.props.searchChange(event.target.value) + AppController.searchChange(event.target.value) } handleSearchKeyPress(event) { if (event.key === 'Enter') { - this.props.search(this.props.searchText) + AppController.search(this.props.currentPage, this.props.searchText) } } handleSearchClear(event) { event.preventDefault() - this.props.searchChange('') + AppController.searchChange('') this.searchRef.current.focus() } + handleLogout() { + AppController.logout() + } + render() { logger.log(logger.DEBUG, 'Menu.render') @@ -109,7 +98,7 @@ class Menu extends React.Component { <Toolbar variant='dense' classes={{ root: classes.toolBar }}> <Tabs value={this.props.currentPage} - onChange={this.props.currentPageChange} + onChange={this.handlePageChange} classes={{ root: classes.tabs }} > <Tab value={pages.TYPES} label={messages.get(messages.TYPES)} /> @@ -118,7 +107,7 @@ class Menu extends React.Component { </Tabs> <TextField placeholder={messages.get(messages.SEARCH)} - value={searchText} + value={searchText || ''} onChange={this.handleSearchChange} onKeyPress={this.handleSearchKeyPress} InputProps={{ @@ -134,7 +123,7 @@ class Menu extends React.Component { <Button label={<LogoutIcon fontSize='small' />} type='final' - onClick={this.props.logout} + onClick={this.handleLogout} /> </Toolbar> </AppBar> @@ -168,7 +157,10 @@ class Menu extends React.Component { } } -export default connect( - mapStateToProps, - mapDispatchToProps -)(withStyles(styles)(Menu)) +export default _.flow( + withStyles(styles), + AppController.withState(() => ({ + currentPage: AppController.getCurrentPage(), + searchText: AppController.getSearch() + })) +)(Menu) diff --git a/openbis_ng_ui/src/js/components/common/page/PageControllerChanged.js b/openbis_ng_ui/src/js/components/common/page/PageControllerChanged.js index 22a47b70acc..a76054bde38 100644 --- a/openbis_ng_ui/src/js/components/common/page/PageControllerChanged.js +++ b/openbis_ng_ui/src/js/components/common/page/PageControllerChanged.js @@ -1,4 +1,4 @@ -import actions from '@src/js/store/actions/actions.js' +import AppController from '@src/js/components/AppController.js' export default class PageControllerChanged { constructor(controller) { @@ -16,8 +16,11 @@ export default class PageControllerChanged { const { id, type } = this.controller.getObject() - this.context.dispatch( - actions.objectChange(this.controller.getPage(), type, id, newChanged) + AppController.objectChange( + this.controller.getPage(), + type, + id, + newChanged ) } } diff --git a/openbis_ng_ui/src/js/components/common/page/PageControllerLoad.js b/openbis_ng_ui/src/js/components/common/page/PageControllerLoad.js index 7f75c48df35..c1a9b1cb7fe 100644 --- a/openbis_ng_ui/src/js/components/common/page/PageControllerLoad.js +++ b/openbis_ng_ui/src/js/components/common/page/PageControllerLoad.js @@ -1,7 +1,7 @@ import _ from 'lodash' import PageMode from '@src/js/components/common/page/PageMode.js' import FormValidator from '@src/js/components/common/form/FormValidator.js' -import actions from '@src/js/store/actions/actions.js' +import AppController from '@src/js/components/AppController.js' export default class PageControllerLoad { constructor(controller) { @@ -44,7 +44,7 @@ export default class PageControllerLoad { await this.load(this.object, isNew) } catch (error) { - this.context.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } finally { if (_.isFunction(this.controller.changed)) { this.controller.changed(false) diff --git a/openbis_ng_ui/src/js/components/common/page/PageControllerSave.js b/openbis_ng_ui/src/js/components/common/page/PageControllerSave.js index fddcf10eb13..141d85e5da2 100644 --- a/openbis_ng_ui/src/js/components/common/page/PageControllerSave.js +++ b/openbis_ng_ui/src/js/components/common/page/PageControllerSave.js @@ -1,6 +1,6 @@ import _ from 'lodash' import FormValidator from '@src/js/components/common/form/FormValidator.js' -import actions from '@src/js/store/actions/actions.js' +import AppController from '@src/js/components/AppController.js' export default class PageControllerSave { constructor(controller) { @@ -45,27 +45,23 @@ export default class PageControllerSave { await this.controller.load() if (oldObject.type === this.controller.getNewObjectType()) { - this.context.dispatch( - actions.objectCreate( - this.controller.getPage(), - oldObject.type, - oldObject.id, - newObject.type, - newObject.id - ) + AppController.objectCreate( + this.controller.getPage(), + oldObject.type, + oldObject.id, + newObject.type, + newObject.id ) } else if (oldObject.type === this.controller.getExistingObjectType()) { - this.context.dispatch( - actions.objectUpdate( - this.controller.getPage(), - oldObject.type, - oldObject.id - ) + AppController.objectUpdate( + this.controller.getPage(), + oldObject.type, + oldObject.id ) } } } catch (error) { - this.context.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } finally { this.context.setState({ loading: false diff --git a/openbis_ng_ui/src/js/components/login/Login.jsx b/openbis_ng_ui/src/js/components/login/Login.jsx index 5149eac54e8..7e417abf6d6 100644 --- a/openbis_ng_ui/src/js/components/login/Login.jsx +++ b/openbis_ng_ui/src/js/components/login/Login.jsx @@ -1,7 +1,6 @@ import _ from 'lodash' import React from 'react' import { withStyles } from '@material-ui/core/styles' -import { connect } from 'react-redux' import flow from 'lodash/flow' import Card from '@material-ui/core/Card' @@ -14,8 +13,8 @@ import TextField from '@src/js/components/common/form/TextField.jsx' import SelectField from '@src/js/components/common/form/SelectField.jsx' import Button from '@src/js/components/common/form/Button.jsx' +import AppController from '@src/js/components/AppController.js' import openbis from '@src/js/services/openbis.js' -import actions from '@src/js/store/actions/actions.js' import messages from '@src/js/common/messages.js' import logger from '@src/js/common/logger.js' @@ -42,16 +41,6 @@ const styles = theme => ({ } }) -function mapStateToProps() { - return {} -} - -function mapDispatchToProps(dispatch) { - return { - login: (user, password) => dispatch(actions.login(user, password)) - } -} - const AUTHENTICATION_SERVICE_OPENBIS = 'openBIS' const AUTHENTICATION_SERVICE_SWITCH_AAI = 'SWITCHaai' @@ -176,7 +165,7 @@ class WithLogin extends React.Component { }, () => { if (this.validate(true)) { - this.props.login(this.state.user.value, this.state.password.value) + AppController.login(this.state.user.value, this.state.password.value) } } ) @@ -353,7 +342,4 @@ class WithLogin extends React.Component { } } -export default flow( - connect(mapStateToProps, mapDispatchToProps), - withStyles(styles) -)(WithLogin) +export default flow(withStyles(styles))(WithLogin) diff --git a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js index 1b78036308c..2b31d38bfc8 100644 --- a/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js +++ b/openbis_ng_ui/src/js/components/tools/browser/ToolBrowserController.js @@ -1,10 +1,10 @@ import openbis from '@src/js/services/openbis.js' -import actions from '@src/js/store/actions/actions.js' import pages from '@src/js/common/consts/pages.js' import objectType from '@src/js/common/consts/objectType.js' import objectOperation from '@src/js/common/consts/objectOperation.js' import ImportType from '@src/js/components/tools/form/import/ImportType.js' import BrowserController from '@src/js/components/common/browser/BrowserController.js' +import AppController from '@src/js/components/AppController.js' import messages from '@src/js/common/messages.js' export default class ToolBrowserController extends BrowserController { @@ -162,9 +162,7 @@ export default class ToolBrowserController extends BrowserController { doNodeAdd(node) { if (node && node.childrenType) { - this.context.dispatch( - actions.objectNew(this.getPage(), node.childrenType) - ) + AppController.objectNew(this.getPage(), node.childrenType) } } @@ -183,10 +181,10 @@ export default class ToolBrowserController extends BrowserController { return openbis.executeOperations(operations, options) }) .then(() => { - this.context.dispatch(actions.objectDelete(this.getPage(), type, id)) + AppController.objectDelete(this.getPage(), type, id) }) .catch(error => { - this.context.dispatch(actions.errorChange(error)) + AppController.errorChange(error) }) } diff --git a/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx b/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx index 4fac0c10d78..137928647ef 100644 --- a/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx +++ b/openbis_ng_ui/src/js/components/tools/common/HistoryGrid.jsx @@ -9,12 +9,11 @@ import DateRangeField from '@src/js/components/common/form/DateRangeField.jsx' import FormUtil from '@src/js/components/common/form/FormUtil.js' import EntityType from '@src/js/components/common/dto/EntityType.js' import HistoryGridContentCell from '@src/js/components/tools/common/HistoryGridContentCell.jsx' +import AppController from '@src/js/components/AppController.js' import openbis from '@src/js/services/openbis.js' import messages from '@src/js/common/messages.js' import date from '@src/js/common/date.js' import ids from '@src/js/common/consts/ids.js' -import store from '@src/js/store/store.js' -import actions from '@src/js/store/actions/actions.js' import logger from '@src/js/common/logger.js' class HistoryGrid extends React.PureComponent { @@ -27,7 +26,7 @@ class HistoryGrid extends React.PureComponent { try { return await this.loadHistory(this.props.eventType, params) } catch (error) { - store.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } } diff --git a/openbis_ng_ui/src/js/components/tools/form/plugin/PluginFormControllerEvaluate.js b/openbis_ng_ui/src/js/components/tools/form/plugin/PluginFormControllerEvaluate.js index 8c851457490..95ed8d1a5e9 100644 --- a/openbis_ng_ui/src/js/components/tools/form/plugin/PluginFormControllerEvaluate.js +++ b/openbis_ng_ui/src/js/components/tools/form/plugin/PluginFormControllerEvaluate.js @@ -1,6 +1,6 @@ import PageMode from '@src/js/components/common/page/PageMode.js' +import AppController from '@src/js/components/AppController.js' import openbis from '@src/js/services/openbis.js' -import actions from '@src/js/store/actions/actions.js' export default class PluginFormControllerEvaluate { constructor(controller) { @@ -31,7 +31,7 @@ export default class PluginFormControllerEvaluate { } })) } catch (error) { - this.context.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } finally { this.context.setState(state => ({ ...state, diff --git a/openbis_ng_ui/src/js/components/tools/form/query/QueryFormControllerExecute.js b/openbis_ng_ui/src/js/components/tools/form/query/QueryFormControllerExecute.js index cd1a8120c37..a70ae909f60 100644 --- a/openbis_ng_ui/src/js/components/tools/form/query/QueryFormControllerExecute.js +++ b/openbis_ng_ui/src/js/components/tools/form/query/QueryFormControllerExecute.js @@ -1,6 +1,6 @@ import PageMode from '@src/js/components/common/page/PageMode.js' +import AppController from '@src/js/components/AppController.js' import openbis from '@src/js/services/openbis.js' -import actions from '@src/js/store/actions/actions.js' export default class QueryFormControllerExecute { constructor(controller) { @@ -41,7 +41,7 @@ export default class QueryFormControllerExecute { } })) } catch (error) { - this.context.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } finally { this.context.setState(state => ({ ...state, diff --git a/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx b/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx index 9d8012962ca..76dc82fba71 100644 --- a/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx +++ b/openbis_ng_ui/src/js/components/tools/search/ToolSearch.jsx @@ -4,14 +4,13 @@ import React from 'react' import { withStyles } from '@material-ui/core/styles' import Container from '@src/js/components/common/form/Container.jsx' import GridContainer from '@src/js/components/common/grid/GridContainer.jsx' +import AppController from '@src/js/components/AppController.js' import PluginsGrid from '@src/js/components/tools/common/PluginsGrid.jsx' import QueriesGrid from '@src/js/components/tools/common/QueriesGrid.jsx' import Message from '@src/js/components/common/form/Message.jsx' import FormUtil from '@src/js/components/common/form/FormUtil.js' import ids from '@src/js/common/consts/ids.js' import objectTypes from '@src/js/common/consts/objectType.js' -import store from '@src/js/store/store.js' -import actions from '@src/js/store/actions/actions.js' import openbis from '@src/js/services/openbis.js' import util from '@src/js/common/util.js' import messages from '@src/js/common/messages.js' @@ -50,7 +49,7 @@ class ToolSearch extends React.Component { loaded: true })) } catch (error) { - store.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } } diff --git a/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js index c0e8d02a680..e71fd11b98e 100644 --- a/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js +++ b/openbis_ng_ui/src/js/components/types/browser/TypeBrowserController.js @@ -1,10 +1,10 @@ import _ from 'lodash' import openbis from '@src/js/services/openbis.js' -import actions from '@src/js/store/actions/actions.js' import pages from '@src/js/common/consts/pages.js' import objectType from '@src/js/common/consts/objectType.js' import objectOperation from '@src/js/common/consts/objectOperation.js' import BrowserController from '@src/js/components/common/browser/BrowserController.js' +import AppController from '@src/js/components/AppController.js' import users from '@src/js/common/consts/users' import messages from '@src/js/common/messages.js' @@ -147,9 +147,7 @@ export default class TypeBrowserController extends BrowserController { doNodeAdd(node) { if (node && node.childrenType) { - this.context.dispatch( - actions.objectNew(this.getPage(), node.childrenType) - ) + AppController.objectNew(this.getPage(), node.childrenType) } } @@ -166,9 +164,9 @@ export default class TypeBrowserController extends BrowserController { const options = new openbis.SynchronousOperationExecutionOptions() options.setExecuteInOrder(true) await openbis.executeOperations(operations, options) - this.context.dispatch(actions.objectDelete(this.getPage(), type, id)) + AppController.objectDelete(this.getPage(), type, id) } catch (error) { - this.context.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } } diff --git a/openbis_ng_ui/src/js/components/types/form/entitytype/EntityTypeFormPreviewProperty.jsx b/openbis_ng_ui/src/js/components/types/form/entitytype/EntityTypeFormPreviewProperty.jsx index d32609d2c0f..21921ee4320 100644 --- a/openbis_ng_ui/src/js/components/types/form/entitytype/EntityTypeFormPreviewProperty.jsx +++ b/openbis_ng_ui/src/js/components/types/form/entitytype/EntityTypeFormPreviewProperty.jsx @@ -9,8 +9,8 @@ import TextField from '@src/js/components/common/form/TextField.jsx' import SelectField from '@src/js/components/common/form/SelectField.jsx' import EntityTypeFormSelectionType from '@src/js/components/types/form/entitytype/EntityTypeFormSelectionType.js' import DataType from '@src/js/components/common/dto/DataType.js' +import AppController from '@src/js/components/AppController.js' import openbis from '@src/js/services/openbis.js' -import actions from '@src/js/store/actions/actions.js' import messages from '@src/js/common/messages.js' import logger from '@src/js/common/logger.js' import util from '@src/js/common/util.js' @@ -161,7 +161,7 @@ class EntityTypeFormPreviewProperty extends React.PureComponent { })) }) .catch(error => { - controller.getContext().dispatch(actions.errorChange(error)) + AppController.errorChange(error) }) } @@ -177,7 +177,7 @@ class EntityTypeFormPreviewProperty extends React.PureComponent { })) }) .catch(error => { - controller.getContext().dispatch(actions.errorChange(error)) + AppController.errorChange(error) }) } @@ -194,7 +194,7 @@ class EntityTypeFormPreviewProperty extends React.PureComponent { })) }) .catch(error => { - controller.getContext().dispatch(actions.errorChange(error)) + AppController.errorChange(error) }) } else { this.setState(() => ({ diff --git a/openbis_ng_ui/src/js/components/types/search/TypeSearch.jsx b/openbis_ng_ui/src/js/components/types/search/TypeSearch.jsx index be427619773..2c0c0e9eadb 100644 --- a/openbis_ng_ui/src/js/components/types/search/TypeSearch.jsx +++ b/openbis_ng_ui/src/js/components/types/search/TypeSearch.jsx @@ -3,6 +3,7 @@ import autoBind from 'auto-bind' import React from 'react' import { withStyles } from '@material-ui/core/styles' import Container from '@src/js/components/common/form/Container.jsx' +import AppController from '@src/js/components/AppController.js' import GridContainer from '@src/js/components/common/grid/GridContainer.jsx' import EntityTypesGrid from '@src/js/components/types/common/EntityTypesGrid.jsx' import VocabularyTypesGrid from '@src/js/components/types/common/VocabularyTypesGrid.jsx' @@ -10,8 +11,6 @@ import PropertyTypesGrid from '@src/js/components/types/common/PropertyTypesGrid import Message from '@src/js/components/common/form/Message.jsx' import ids from '@src/js/common/consts/ids.js' import objectTypes from '@src/js/common/consts/objectType.js' -import store from '@src/js/store/store.js' -import actions from '@src/js/store/actions/actions.js' import openbis from '@src/js/services/openbis.js' import util from '@src/js/common/util.js' import messages from '@src/js/common/messages.js' @@ -53,7 +52,7 @@ class TypeSearch extends React.Component { loaded: true })) } catch (error) { - store.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } } diff --git a/openbis_ng_ui/src/js/components/users/browser/UserBrowserController.js b/openbis_ng_ui/src/js/components/users/browser/UserBrowserController.js index c7d40660cac..93cfca99bac 100644 --- a/openbis_ng_ui/src/js/components/users/browser/UserBrowserController.js +++ b/openbis_ng_ui/src/js/components/users/browser/UserBrowserController.js @@ -1,9 +1,9 @@ import openbis from '@src/js/services/openbis.js' -import actions from '@src/js/store/actions/actions.js' import pages from '@src/js/common/consts/pages.js' import objectType from '@src/js/common/consts/objectType.js' import objectOperation from '@src/js/common/consts/objectOperation.js' import BrowserController from '@src/js/components/common/browser/BrowserController.js' +import AppController from '@src/js/components/AppController.js' import messages from '@src/js/common/messages.js' export default class UserBrowserController extends BrowserController { @@ -67,9 +67,7 @@ export default class UserBrowserController extends BrowserController { doNodeAdd(node) { if (node && node.childrenType) { - this.context.dispatch( - actions.objectNew(this.getPage(), node.childrenType) - ) + AppController.objectNew(this.getPage(), node.childrenType) } } @@ -88,7 +86,7 @@ export default class UserBrowserController extends BrowserController { return openbis.executeOperations(operations, options) }) .then(() => { - this.context.dispatch(actions.objectDelete(this.getPage(), type, id)) + AppController.objectDelete(this.getPage(), type, id) }) .catch(error => { if ( @@ -96,15 +94,13 @@ export default class UserBrowserController extends BrowserController { error.message && error.message.startsWith('Could not commit Hibernate transaction') ) { - this.context.dispatch( - actions.errorChange( - messages.get( - messages.USERS_WHO_REGISTERED_SOME_DATA_CANNOT_BE_REMOVED - ) + AppController.errorChange( + messages.get( + messages.USERS_WHO_REGISTERED_SOME_DATA_CANNOT_BE_REMOVED ) ) } else { - this.context.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } }) } diff --git a/openbis_ng_ui/src/js/components/users/search/UserSearch.jsx b/openbis_ng_ui/src/js/components/users/search/UserSearch.jsx index 6b3fe8d432d..3c934b3e15d 100644 --- a/openbis_ng_ui/src/js/components/users/search/UserSearch.jsx +++ b/openbis_ng_ui/src/js/components/users/search/UserSearch.jsx @@ -3,6 +3,7 @@ import autoBind from 'auto-bind' import React from 'react' import { withStyles } from '@material-ui/core/styles' import Container from '@src/js/components/common/form/Container.jsx' +import AppController from '@src/js/components/AppController.js' import GridContainer from '@src/js/components/common/grid/GridContainer.jsx' import UsersGrid from '@src/js/components/users/common/UsersGrid.jsx' import UserGroupsGrid from '@src/js/components/users/common/UserGroupsGrid.jsx' @@ -11,8 +12,6 @@ import Message from '@src/js/components/common/form/Message.jsx' import FormUtil from '@src/js/components/common/form/FormUtil.js' import ids from '@src/js/common/consts/ids.js' import objectTypes from '@src/js/common/consts/objectType.js' -import store from '@src/js/store/store.js' -import actions from '@src/js/store/actions/actions.js' import openbis from '@src/js/services/openbis.js' import util from '@src/js/common/util.js' import messages from '@src/js/common/messages.js' @@ -55,7 +54,7 @@ class UserSearch extends React.Component { loaded: true })) } catch (error) { - store.dispatch(actions.errorChange(error)) + AppController.errorChange(error) } } diff --git a/openbis_ng_ui/src/js/store/history.js b/openbis_ng_ui/src/js/store/history.js index a37412205f6..49da3566429 100644 --- a/openbis_ng_ui/src/js/store/history.js +++ b/openbis_ng_ui/src/js/store/history.js @@ -1,5 +1,5 @@ import { createBrowserHistory } from 'history' -import actions from '@src/js/store/actions/actions.js' +import AppController from '@src/js/components/AppController.js' import routes from '@src/js/common/consts/routes.js' import url from '@src/js/common/url.js' @@ -12,7 +12,7 @@ history.configure = store => { let route = routes.parse(location.pathname) if (route.path !== store.getState().route) { - store.dispatch(actions.routeChange(route.path, location.state)) + AppController.routeChange(route.path, location.state) } }) -- GitLab