# datahub

datahub is a frontend available as a [Node.js](https://nodejs.org/en/) package. It is based on the [React](https://reactjs.org/) framework. Through a web interface, this application provides:
- a user authentication portal
- a GUI for scientific metadata management
- a GUI for the electronic logbook which can complement data
- experimental data downloading feature
- manual DOI minting feature

Currently, datahub depends on:
- ICAT+ package. ICAT+ is the backend which stores logbook events 
- [ICAT](https://icatproject.org) metadata catalogue. ICAT stores metadata and handles the user authentication mechanism 

# Menu
1. [Installation](#installation)
2. [Configuration](#configuration)
3. [Developments](#developments)

# Installation
## Prerequisite:
1. Make sure the dependencies mentioned above are installed and properly configured.

## Installation procedure
1. Download the source code from [gitlab](https://gitlab.esrf.fr/icat/E-DataPortal) repository
2. Install dependencies

```bash
npm install
```
3. Configure datahub app. See this [section](#configuration).

4. Run the app

```bash
npm start
```

# Configuration

Datahub configuration is spread among different files located in the folder **src/config**. These files are:
- [icat.js](#icatjs) : configure access to the metadata catalogue.
- [icatPlus.js](#icatplusjs) : configure access to the ICAT+ server
- [techniques.js](#techniquesjs) : configure the known techniques
- [gui.config.js](#guiconfigjs) : configure datahub GUI


Example files for [icat.js](src/config/icat/icat.example.js) and [icatPlus.js](src/config/icat/icatPlus.example.js) are provided and needs to be copied in configuration file:

```bash
cp src/config/icat/icat.example.js src/config/icat/icat.js
cp src/config/icat/icatPlus.example.js src/config/icat/icatPlus.js
```


## icat.js
Edit the file **icat.js** with your favorite text editor and set the configuration to access the metadata catalogue following the indications below.

<!--START configurationICAT -->
```js
/**
 * icat.example.js configuration file
 */
var ICAT =
{
    /** URL of the metadata catalogue */
    server: "https://icat.esrf.fr",
    /** Connexion settings for none anonymous users */
    connection: {
        /** ICAT plugin used for authentication. */
        plugin: 'esrf'
    },
    /** Anonymous user's credentials*/
    anonymous: {
        /** ICAT plugin used for authentication. */
        plugin: '**',
        /** Username for the anonymous user */
        username: '***',
        /** Password for the anonymous user */
        password: '****'
    }
};

export default ICAT;

```
<!--END configurationICAT -->

## icatPlus.js
Edit the file **icatPlus.js** with your favorite text editor and set the configuration to access the ICAT+ application following the indications below.

<!--START configurationICATPlus -->
```js
/**
 * icatPlus.example.js configuration file
 */
var ICATPLUS =
{
    /** URL of ICAT+ server */
    server: "http://lindemaria.esrf.fr:8000",
};

export default ICATPLUS;

```
<!--END configurationICATPlus -->

## techniques.js
The file [techniques.js](src/config/techniques/techniques.js) complements short named techniques as stored in ICAT metadata catalogue. It maps a short name to a description and display settings.

To add a new technique, use the following object to fully define the technique.
```js
/** Object defining the new technique */
{
/** Full name of the technique */
name: "Ptychography",
/** Short name of the technique as stored in ICAT */
shortname: "PTYCHO",
/** Full description of the technique */
description: "Ptychography is a technique invented by Walter Hoppe that aims to solve the diffraction-pattern phase problem by interfering adjacent Bragg reflections coherently and thereby determine their relative phase.",
/** Font color */
color: "#97E0FE"
},
```

## gui.config.js

Edit the file [gui.config.js](src/config/gui.config.js) with your favorite text editor and set the GUI configuration following the indications below.

<!--START configurationGUI -->
```js
/** 
 * gui.config.js 
 * GUI configuration file
 */
export function GUI_CONFIG() {
    return {
        /** Number of logbook events to display per page. EVENTS_PER_PAGE should be lower than EVENTS_PER_DOWNLOAD */
        EVENTS_PER_PAGE: 200,

        /** Maximum number of logbook events downloaded from the server. This enables to store a larger set of 
        events than those required for a single page thus reducing HTTP requests to the server. */
        EVENTS_PER_DOWNLOAD: 400,

        /** Default sorting filter for logbook events.
        The format:
           { nameOftheMongoDBFieldToSortAgainst : theSortingOrder } 
        
        Possible values for **sortingOrder**:
           1, for an ascending sorting of nameOftheMongoDBFieldToSortAgainst
          -1, for a descending sorting of nameOftheMongoDBFieldToSortAgainst
        
        */
        DEFAULT_SORTING_FILTER: {
            createdAt: -1
        },

        /** Panel maximum height during logbook event creation */
        NEW_EVENT_MAX_HEIGHT: "500px",

        /* Default tag color used in the logbook when tag color is not set */
        DEFAULT_TAG_COLOR: "#a6bded"
    }
}

```
<!--END configurationGUI -->


# Developments
- [Widgets](#Widgets)
  - [ResponsiveTable](#responsivetable)
  - [Loader](#loader)

## Widgets
### ResponsiveTable

This widget is based on react-bootstrap-table2 (https://react-bootstrap-table.github.io/react-bootstrap-table2/) but adds responsiveness.

Columns can now be configured based on the size of the device as bootstrap does (xs, sm, md, lg)

Configuration:

```js
 const columns = [{
    text: 'Proposal',
    dataField: 'name',        
    headerStyle: (column, colIndex) => {
        return { width: '50%', textAlign: 'center' };
    },
    responsiveHeaderStyle: {         
            xs : {width: '20%', textAlign: 'center' },
            sm : {width: '50%', textAlign: 'center' },
            md : {width: '70%', textAlign: 'center' },
            lg : {width: '90%', hidden : true, textAlign: 'center' }                
    }
 }]

 var pageOptions = {    
    showTotal : true,
    hidePageListOnlyOnePage : true,
    sizePerPageList: [ {
        text: '5', value: 5
      }, {
        text: '10', value: 10
      }, {
        text: 'All', value: data.length
      } ]
 };

 <ResponsiveTable
    keyField='id'
    data={data }    
    columns={columns}
    pageOptions={pageOptions}
    />
```

If there is no responsiveHeaderStyle then headerStyle will be used as default. If there is no the used screen size (xs, sm, md, lg) configured in the responsiveHeaderStyle attribute then headerStyle will be used by default.


### Loader

It informs users that data are still been loaded

```js
import Loader from 'react-loader-advanced';
const message = <span>Loading list of authors</span>;

<Loader show={this.state.fetching} message={message}>
	<some components>
</Loader>

```
