Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
Datahub
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
32
Issues
32
List
Boards
Labels
Service Desk
Milestones
Jira
Jira
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ICAT
Datahub
Commits
ae15fa32
Commit
ae15fa32
authored
Sep 02, 2020
by
Axel Bocciarelli
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
WIP
parent
bf3dfb6b
Pipeline
#32956
passed with stage
in 3 minutes and 8 seconds
Changes
42
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
42 changed files
with
571 additions
and
755 deletions
+571
-755
src/App.js
src/App.js
+16
-23
src/actions/investigations.js
src/actions/investigations.js
+0
-50
src/api/icat-plus/catalogue.js
src/api/icat-plus/catalogue.js
+0
-20
src/components/Address/AddressFormModal.js
src/components/Address/AddressFormModal.js
+11
-10
src/components/Address/AddressFormModal.module.css
src/components/Address/AddressFormModal.module.css
+1
-1
src/components/Address/MyAddressesSummary.js
src/components/Address/MyAddressesSummary.js
+10
-4
src/components/Investigation/InvestigationTable.js
src/components/Investigation/InvestigationTable.js
+11
-11
src/components/Investigation/InvestigationWidget.js
src/components/Investigation/InvestigationWidget.js
+5
-8
src/components/Investigation/utils.js
src/components/Investigation/utils.js
+43
-70
src/components/LoadingBoundary.js
src/components/LoadingBoundary.js
+20
-11
src/components/Logbook/Menu/EventListMenu.js
src/components/Logbook/Menu/EventListMenu.js
+1
-1
src/components/Menu/ManagerMenu.js
src/components/Menu/ManagerMenu.js
+45
-108
src/components/Menu/Menu.js
src/components/Menu/Menu.js
+24
-45
src/components/Menu/Menu.module.css
src/components/Menu/Menu.module.css
+5
-1
src/components/ModalLoadingBoundary.js
src/components/ModalLoadingBoundary.js
+35
-0
src/components/Parcels/MyParcelsSummary.js
src/components/Parcels/MyParcelsSummary.js
+2
-6
src/components/Shipping/ParcelsSection.js
src/components/Shipping/ParcelsSection.js
+7
-17
src/constants/actionTypes.js
src/constants/actionTypes.js
+0
-23
src/containers/AddressesPage.js
src/containers/AddressesPage.js
+5
-8
src/containers/BeamlineData/BeamlineDataPage.js
src/containers/BeamlineData/BeamlineDataPage.js
+38
-0
src/containers/BeamlineData/BeamlineDataTable.js
src/containers/BeamlineData/BeamlineDataTable.js
+23
-0
src/containers/ClosedData/ClosedDataPage.js
src/containers/ClosedData/ClosedDataPage.js
+34
-0
src/containers/ClosedData/EmbargoedInvestigationsTable.js
src/containers/ClosedData/EmbargoedInvestigationsTable.js
+14
-0
src/containers/EventsPage.js
src/containers/EventsPage.js
+2
-1
src/containers/Logbook/LogbookContainer.js
src/containers/Logbook/LogbookContainer.js
+13
-30
src/containers/MyData/MyDataPage.js
src/containers/MyData/MyDataPage.js
+41
-0
src/containers/MyData/MyIndustryProposalsPanel.js
src/containers/MyData/MyIndustryProposalsPanel.js
+46
-0
src/containers/MyData/MyInvestigationsTable.js
src/containers/MyData/MyInvestigationsTable.js
+25
-0
src/containers/MyDataPage.js
src/containers/MyDataPage.js
+0
-83
src/containers/MyParcelsPage.js
src/containers/MyParcelsPage.js
+5
-8
src/containers/OpenData/OpenDataPage.js
src/containers/OpenData/OpenDataPage.js
+11
-18
src/containers/OpenData/ReleasedInvestigationsTable.js
src/containers/OpenData/ReleasedInvestigationsTable.js
+20
-0
src/containers/ShippingPage.js
src/containers/ShippingPage.js
+1
-5
src/helpers/hooks.js
src/helpers/hooks.js
+16
-16
src/helpers/index.js
src/helpers/index.js
+0
-7
src/reducers/index.js
src/reducers/index.js
+0
-8
src/reducers/investigations.js
src/reducers/investigations.js
+0
-48
src/reducers/myInvestigations.js
src/reducers/myInvestigations.js
+0
-34
src/reducers/releasedInvestigations.js
src/reducers/releasedInvestigations.js
+0
-34
src/reducers/scientistInstrumentInvestigations.js
src/reducers/scientistInstrumentInvestigations.js
+0
-34
src/resources/instrument.js
src/resources/instrument.js
+25
-0
src/resources/investigation.js
src/resources/investigation.js
+16
-12
No files found.
src/App.js
View file @
ae15fa32
...
...
@@ -5,7 +5,7 @@ import Footer from './components/Footer';
import
UI
from
'
./config/ui
'
;
import
AddressesPage
from
'
./containers/AddressesPage
'
;
import
LoginPage
from
'
./containers/LoginPage
'
;
import
MyDataPage
from
'
./containers/MyDataPage
'
;
import
MyDataPage
from
'
./containers/MyData
/MyData
Page
'
;
import
MyParcelsPage
from
'
./containers/MyParcelsPage
'
;
import
ParcelPage
from
'
./containers/ParcelPage
'
;
import
ShippingPage
from
'
./containers/ShippingPage
'
;
...
...
@@ -13,8 +13,8 @@ import OfflinePage from './containers/OfflinePage';
import
DOIPage
from
'
./containers/DOIPage
'
;
import
UserManagementPage
from
'
./containers/UserManagementPage
'
;
import
SearchPage
from
'
./containers/SearchPage
'
;
import
OpenDataPage
from
'
./containers/OpenDataPage
'
;
import
ClosedDataPage
from
'
./containers/ClosedDataPage
'
;
import
OpenDataPage
from
'
./containers/OpenData
/OpenData
Page
'
;
import
ClosedDataPage
from
'
./containers/ClosedData
/ClosedData
Page
'
;
import
DatasetsPage
from
'
./containers/DatasetsPage
'
;
import
EventTagPage
from
'
./containers/EventTagPage
'
;
import
EventsPage
from
'
./containers/EventsPage
'
;
...
...
@@ -22,12 +22,11 @@ import SelectionPage from './containers/Selection/SelectionPage';
import
CameraPage
from
'
./containers/CameraPage
'
;
import
DataStatisticsPage
from
'
./containers/DataStatisticsPage
'
;
import
MintSelectionPage
from
'
./containers/Selection/MintSelectionPage
'
;
import
BeamlineDataPage
from
'
./containers/BeamlineDataPage
'
;
import
BeamlineDataPage
from
'
./containers/BeamlineData
/BeamlineData
Page
'
;
import
{
getRemainingSessionTime
}
from
'
./helpers/auth
'
;
import
{
doLogOut
,
doSilentRefreshFromSSO
}
from
'
./actions/login
'
;
import
keycloak
from
'
./keycloak
'
;
import
Menu
from
'
./components/Menu/Menu
'
;
import
{
fetchAllInvestigations
}
from
'
./actions/investigations
'
;
import
{
useQuery
}
from
'
./helpers/hooks
'
;
import
PageNotFound
from
'
./containers/PageNotFound
'
;
import
LoadingBoundary
from
'
./components/LoadingBoundary
'
;
...
...
@@ -43,12 +42,6 @@ function App() {
const
dispatch
=
useDispatch
();
useEffect
(()
=>
{
if
(
user
.
sessionId
)
{
dispatch
(
fetchAllInvestigations
(
user
.
sessionId
));
}
},
[
dispatch
,
user
.
sessionId
]);
useEffect
(()
=>
{
if
(
!
user
.
expirationTime
)
{
return
;
...
...
@@ -107,24 +100,20 @@ function App() {
<
Menu
/>
<
Switch
>
<
Route
exact
path
=
{[
'
/
'
,
'
/home
'
,
'
/investigations
'
]}
component
=
{
MyDataPage
}
/
>
<
Route
exact
path
=
{[
'
/
'
,
'
/home
'
,
'
/investigations
'
]}
>
<
MyDataPage
/>
<
/Route
>
<
Route
exact
path
=
"
/search
"
component
=
{
SearchPage
}
/
>
<
Route
exact
path
=
"
/usermanagement
"
component
=
{
UserManagementPage
}
/
>
<
Route
exact
path
=
"
/usermanagement
"
>
<
UserManagementPage
/>
<
/Route
>
<
Route
exact
path
=
"
/public
"
component
=
{
OpenDataPage
}
/
>
<
Route
exact
path
=
"
/public/:prefix/:suffix
"
component
=
{
DOIPage
}
/
>
<
Route
exact
path
=
"
/closed
"
component
=
{
ClosedDataPage
}
/
>
<
Route
exact
path
=
"
/beamline/:
id
"
component
=
{
BeamlineDataPage
}
/
>
<
Route
exact
path
=
"
/beamline/:
name
"
component
=
{
BeamlineDataPage
}
/
>
{
isSampleTrackingEnabled
&&
(
<
Route
exact
path
=
"
/parcels
"
component
=
{
MyParcelsPage
}
/
>
...
...
@@ -171,7 +160,11 @@ function App() {
<
Route
exact
path
=
"
/selection
"
component
=
{
SelectionPage
}
/
>
<
Route
exact
path
=
"
/selection/mint
"
component
=
{
MintSelectionPage
}
/
>
<
Route
exact
path
=
"
/manager/stats
"
component
=
{
DataStatisticsPage
}
/
>
{
user
.
isAdministrator
&&
(
<
Route
exact
path
=
"
/manager/stats
"
>
<
DataStatisticsPage
/>
<
/Route
>
)}
<
Route
exact
path
=
"
/login
"
>
<
Redirect
...
...
src/actions/investigations.js
deleted
100644 → 0
View file @
bf3dfb6b
import
axios
from
'
axios
'
;
import
{
getEmbargoedInvestigations
,
getInvestigationsByInstrumentScientist
,
getInvestigationsByUser
,
getReleasedInvestigations
,
}
from
'
../api/icat-plus/catalogue
'
;
import
{
FETCH_INSTRUMENT_SCIENTIST_INVESTIGATIONS
,
FETCH_INVESTIGATIONS
,
FETCH_MY_INVESTIGATIONS
,
FETCH_RELEASED_INVESTIGATIONS
,
}
from
'
../constants/actionTypes
'
;
export
function
fetchMyInvestigations
(
sessionId
)
{
return
{
type
:
FETCH_MY_INVESTIGATIONS
,
payload
:
axios
.
get
(
getInvestigationsByUser
(
sessionId
)),
};
}
export
function
fetchEmbargoedInvestigations
(
sessionId
)
{
return
{
type
:
FETCH_INVESTIGATIONS
,
payload
:
axios
.
get
(
getEmbargoedInvestigations
(
sessionId
)),
};
}
export
function
fetchReleasedInvestigations
(
sessionId
)
{
return
{
type
:
FETCH_RELEASED_INVESTIGATIONS
,
payload
:
axios
.
get
(
getReleasedInvestigations
(
sessionId
)),
};
}
export
function
fetchInvestigationsAsInstrumentScientist
(
sessionId
)
{
return
{
type
:
FETCH_INSTRUMENT_SCIENTIST_INVESTIGATIONS
,
payload
:
axios
.
get
(
getInvestigationsByInstrumentScientist
(
sessionId
)),
};
}
export
function
fetchAllInvestigations
(
sessionId
)
{
return
(
dispatch
)
=>
{
dispatch
(
fetchMyInvestigations
(
sessionId
));
dispatch
(
fetchReleasedInvestigations
(
sessionId
));
dispatch
(
fetchEmbargoedInvestigations
(
sessionId
));
dispatch
(
fetchInvestigationsAsInstrumentScientist
(
sessionId
));
};
}
src/api/icat-plus/catalogue.js
View file @
ae15fa32
...
...
@@ -13,26 +13,6 @@ export function getUsersByInvestigationIds(sessionId, investigationIds) {
return
`
${
ICATPLUS
.
server
}
/catalogue/
${
sessionId
}
/investigation/id/
${
investigationIds
}
/investigationusers`
;
}
export
function
getInvestigationById
(
sessionId
,
investigationId
)
{
return
`
${
ICATPLUS
.
server
}
/catalogue/
${
sessionId
}
/investigation/id/
${
investigationId
}
/investigation`
;
}
export
function
getEmbargoedInvestigations
(
sessionId
)
{
return
`
${
ICATPLUS
.
server
}
/catalogue/
${
sessionId
}
/investigation/status/embargoed/investigation`
;
}
export
function
getReleasedInvestigations
(
sessionId
)
{
return
`
${
ICATPLUS
.
server
}
/catalogue/
${
sessionId
}
/investigation/status/released/investigation`
;
}
export
function
getInvestigationsByUser
(
sessionId
)
{
return
`
${
ICATPLUS
.
server
}
/catalogue/
${
sessionId
}
/investigation?useris=participant`
;
}
export
function
getInvestigationsByInstrumentScientist
(
sessionId
)
{
return
`
${
ICATPLUS
.
server
}
/catalogue/
${
sessionId
}
/investigation/useris/instrumentscientist/investigation`
;
}
export
function
getDatasetsById
(
sessionId
,
datasetIds
)
{
return
`
${
ICATPLUS
.
server
}
/catalogue/
${
sessionId
}
/dataset/id/
${
datasetIds
}
/dataset`
;
}
...
...
src/components/Address/AddressFormModal.js
View file @
ae15fa32
...
...
@@ -14,16 +14,17 @@ import {
Row
,
}
from
'
react-bootstrap
'
;
import
{
useForm
,
FormProvider
}
from
'
react-hook-form
'
;
import
{
useSelector
}
from
'
react-redux
'
;
import
FieldAlert
from
'
../Form/FieldAlert
'
;
import
TextFieldGroup
from
'
../Form/TextFieldGroup
'
;
import
styles
from
'
./AddressFormModal.module.css
'
;
import
{
useResource
}
from
'
rest-hooks
'
;
import
InvestigationResource
from
'
../../resources/investigation
'
;
function
AddressFormModal
(
props
)
{
const
{
investigation
,
address
,
onSubmitAsync
,
onCloseModal
}
=
props
;
const
userInvestigations
=
useSelector
(
(
state
)
=>
state
.
myInvestigations
.
data
);
const
myInvestigations
=
useResource
(
InvestigationResource
.
listShape
(),
{
filter
:
'
participant
'
,
}
);
const
methods
=
useForm
({
defaultValues
:
address
});
const
{
handleSubmit
,
errors
,
register
,
formState
}
=
methods
;
...
...
@@ -75,18 +76,18 @@ function AddressFormModal(props) {
)
:
(
<
FormGroup
controlId
=
"
formInvestigation
"
>
<
div
className
=
{
styles
.
row
}
>
<
ControlLabel
className
=
{
styles
.
proposal
Label
}
>
Proposal
<
ControlLabel
className
=
{
styles
.
investigation
Label
}
>
Investigation
<
/ControlLabel
>
<
div
>
<
FormControl
name
=
"
investigationId
"
componentClass
=
"
select
"
placeholder
=
"
Select a
proposal
"
placeholder
=
"
Select a
n investigation
"
inputRef
=
{
register
({
required
:
true
})}
>
{
user
Investigations
&&
user
Investigations
.
map
((
investigation
)
=>
(
{
my
Investigations
&&
my
Investigations
.
map
((
investigation
)
=>
(
<
option
key
=
{
investigation
.
id
}
value
=
{
investigation
.
id
}
...
...
@@ -98,7 +99,7 @@ function AddressFormModal(props) {
<
/div
>
{
errors
.
investigationId
&&
(
<
FieldAlert
fieldLabel
=
"
Proposal
"
fieldLabel
=
"
Investigation
"
error
=
{
errors
.
investigationId
}
/
>
)}
...
...
src/components/Address/AddressFormModal.module.css
View file @
ae15fa32
...
...
@@ -4,7 +4,7 @@
justify-content
:
flex-start
;
}
.
proposal
Label
{
.
investigation
Label
{
margin-left
:
1rem
;
margin-right
:
1rem
;
}
src/components/Address/MyAddressesSummary.js
View file @
ae15fa32
...
...
@@ -16,6 +16,7 @@ import { useQuery } from '../../helpers/hooks';
import
{
useHistory
}
from
'
react-router
'
;
import
AddressPanel
from
'
./AddressPanel
'
;
import
AddressFormModal
from
'
./AddressFormModal
'
;
import
ModalLoadingBoundary
from
'
../ModalLoadingBoundary
'
;
function
MyAddressesSummary
()
{
const
[
alert
,
setAlert
]
=
useState
();
...
...
@@ -100,11 +101,16 @@ function MyAddressesSummary() {
return
(
<>
{(
isCreating
||
editingId
)
&&
(
<
AddressFormModal
address
=
{
editedAddress
}
onSubmitAsync
=
{
handleSubmit
}
<
ModalLoadingBoundary
message
=
"
Loading investigations...
"
onCloseModal
=
{
handleCloseModal
}
/
>
>
<
AddressFormModal
address
=
{
editedAddress
}
onSubmitAsync
=
{
handleSubmit
}
onCloseModal
=
{
handleCloseModal
}
/
>
<
/ModalLoadingBoundary
>
)}
{
alert
&&
<
Alert
bsStyle
=
{
alert
.
style
}
>
{
alert
.
message
}
<
/Alert>
}
<
Grid
fluid
>
...
...
src/components/Investigation/InvestigationTable.js
View file @
ae15fa32
...
...
@@ -67,9 +67,9 @@ function getColumns({ showProposalLinks, showInvestigationStats, showFiles }) {
{
text
:
'
Beamline
'
,
dataField
:
'
visitId
'
,
formatter
:
(
visitId
,
investigation
)
=>
(
formatter
:
(
_
,
investigation
)
=>
(
<
span
style
=
{{
fontWeight
:
'
bold
'
}}
>
{
beamlineFormatter
(
investigation
,
visitId
)}
{
beamlineFormatter
(
investigation
)}
<
/span
>
),
sort
:
true
,
...
...
@@ -99,7 +99,7 @@ function getColumns({ showProposalLinks, showInvestigationStats, showFiles }) {
{
text
:
'
Datasets
'
,
dataField
:
'
datasets
'
,
formatter
:
datasetCountFormatter
,
formatter
:
(
_
,
{
parameters
})
=>
datasetCountFormatter
(
parameters
)
,
responsiveHeaderStyle
:
getLgHeaderStyle
(
130
,
!
showInvestigationStats
),
},
{
...
...
@@ -107,7 +107,7 @@ function getColumns({ showProposalLinks, showInvestigationStats, showFiles }) {
hidden
:
!
showFiles
,
dataField
:
'
dummy-1
'
,
isDummyField
:
true
,
formatter
:
fileCountFormatter
,
formatter
:
(
_
,
{
parameters
})
=>
fileCountFormatter
(
parameters
)
,
responsiveHeaderStyle
:
getLgHeaderStyle
(
80
,
!
showInvestigationStats
),
},
{
...
...
@@ -130,11 +130,11 @@ function getColumns({ showProposalLinks, showInvestigationStats, showFiles }) {
function
InvestigationTable
(
props
)
{
const
{
investigations
,
show
ProposalLinks
=
false
,
show
InvestigationStats
=
false
,
with
ProposalLinks
=
false
,
with
InvestigationStats
=
false
,
}
=
props
;
const
user
=
useSelector
((
state
)
=>
state
.
user
);
const
{
sessionId
,
isAdministrator
}
=
useSelector
((
state
)
=>
state
.
user
);
const
history
=
useHistory
();
const
query
=
useQuery
();
...
...
@@ -188,7 +188,7 @@ function InvestigationTable(props) {
renderer
:
(
investigation
)
=>
(
<
InvestigationWidget
investigation
=
{
investigation
}
sessionId
=
{
user
.
sessionId
}
sessionId
=
{
sessionId
}
/
>
),
};
...
...
@@ -221,9 +221,9 @@ function InvestigationTable(props) {
<
ResponsiveTable
data
=
{
investigations
.
filter
(
isInvestigationMatching
)}
columns
=
{
getColumns
({
showProposalLinks
:
showProposalLinks
||
user
.
isAdministrator
,
showInvestigationStats
,
showFiles
:
user
.
isAdministrator
,
showProposalLinks
:
withProposalLinks
||
isAdministrator
,
showInvestigationStats
:
withInvestigationStats
||
isAdministrator
,
showFiles
:
isAdministrator
,
})}
expandRow
=
{
expandRow
}
/
>
...
...
src/components/Investigation/InvestigationWidget.js
View file @
ae15fa32
import
React
,
{
Suspense
}
from
'
react
'
;
import
React
from
'
react
'
;
import
{
Panel
,
Tab
,
Tabs
}
from
'
react-bootstrap
'
;
import
{
NetworkErrorBoundary
}
from
'
rest-hooks
'
;
import
Loader
from
'
../Loader
'
;
import
SamplesTable
from
'
./SamplesTable
'
;
import
ParticipantsPanel
from
'
./ParticipantsPanel
'
;
import
LoadingBoundary
from
'
../LoadingBoundary
'
;
function
InvestigationWidget
(
props
)
{
const
{
investigation
}
=
props
;
...
...
@@ -16,11 +15,9 @@ function InvestigationWidget(props) {
<
ParticipantsPanel
investigationId
=
{
investigation
.
id
}
/
>
<
/Tab
>
<
Tab
style
=
{{
margin
:
30
}}
eventKey
=
{
2
}
title
=
"
Samples
"
>
<
Suspense
fallback
=
{
<
Loader
message
=
"
Loading samples
"
/>
}
>
<
NetworkErrorBoundary
>
<
SamplesTable
investigationId
=
{
investigation
.
id
}
/
>
<
/NetworkErrorBoundary
>
<
/Suspense
>
<
LoadingBoundary
message
=
"
Loading samples
"
>
<
SamplesTable
investigationId
=
{
investigation
.
id
}
/
>
<
/LoadingBoundary
>
<
/Tab
>
<
/Tabs
>
<
/Panel.Body
>
...
...
src/components/Investigation/utils.js
View file @
ae15fa32
...
...
@@ -11,49 +11,34 @@ import { INVESTIGATION_DATE_FORMAT } from '../../constants';
import
DOIBadge
from
'
../doi/DOIBadge
'
;
import
{
stringifyBytesSize
}
from
'
../../helpers
'
;
export
function
getInstrumentName
(
investigation
)
{
if
(
!
investigation
)
{
return
undefined
;
}
const
{
investigationInstruments
}
=
investigation
;
return
(
investigationInstruments
&&
investigationInstruments
[
0
]?.
instrument
?.
name
);
}
export
function
dateFormatter
(
date
)
{
return
date
?
moment
(
date
).
format
(
INVESTIGATION_DATE_FORMAT
)
:
''
;
}
export
function
beamlineFormatter
(
investigation
,
placeHolder
=
''
)
{
const
instrumentName
=
getInstrumentName
(
investigation
);
return
instrumentName
?
instrumentName
.
toUpperCase
()
:
placeHolder
;
export
function
beamlineFormatter
(
investigation
)
{
return
(
investigation
?.
instrument
.
name
||
''
).
toUpperCase
();
}
export
function
nameFormatter
(
investigation
,
showLink
)
{
const
{
id
,
name
}
=
investigation
;
if
(
!
showLink
)
{
return
<
span
style
=
{{
fontWeight
:
'
bold
'
}}
>
{
investigation
.
name
}
<
/span>
;
return
<
span
style
=
{{
fontWeight
:
'
bold
'
}}
>
{
name
}
<
/span>
;
}
return
(
<
Link
to
=
{
`/investigation/
${
i
nvestigation
.
i
d
}
/datasets`
}
>
<
Link
to
=
{
`/investigation/
${
id
}
/datasets`
}
>
<
Button
bsSize
=
"
xsmall
"
style
=
{{
width
:
120
,
textAlign
:
'
left
'
}}
>
<
Glyphicon
glyph
=
"
circle-arrow-right
"
/>
<
span
style
=
{{
marginLeft
:
10
}}
>
{
investigation
.
name
}
<
/span
>
<
span
style
=
{{
marginLeft
:
10
}}
>
{
name
}
<
/span
>
<
/Button
>
<
/Link
>
);
}
export
function
volumeFormatter
(
_
,
investigation
)
{
const
volume
=
investigation
.
parameters
.
find
((
o
)
=>
o
.
name
===
VOLUME
);
if
(
volume
&&
volume
.
value
&&
volume
.
value
!==
0
)
{
return
stringifyBytesSize
(
volume
.
value
);
}
}
export
function
experimentFormatter
(
investigation
,
showLink
)
{
const
{
summary
,
doi
}
=
investigation
;
return
(
<
Grid
style
=
{{
textAlign
:
'
center
'
}}
>
<
Row
className
=
"
show-grid
"
>
...
...
@@ -64,43 +49,29 @@ export function experimentFormatter(investigation, showLink) {
<
Row
className
=
"
show-grid
"
>
<
Col
xs
=
{
12
}
md
=
{
12
}
>
<
span
style
=
{{
fontWeight
:
'
bold
'
}}
>
{
beamlineFormatter
(
investigation
,
investigation
.
visitId
)}
{
beamlineFormatter
(
investigation
)}
<
/span
>
<
/Col
>
<
/Row
>
<
Row
className
=
"
show-grid
"
>
<
Col
xs
=
{
12
}
>
<
div
style
=
{{
color
:
'
gray
'
,
fontStyle
:
'
italic
'
}}
>
{
investigation
.
summary
}
<
/div
>
<
div
style
=
{{
color
:
'
gray
'
,
fontStyle
:
'
italic
'
}}
>
{
summary
}
<
/div
>
<
/Col
>
<
/Row
>
<
Row
className
=
"
show-grid
"
style
=
{{
fontSize
:
10
}}
>
<
Col
xs
=
{
12
}
>
<
DOIBadge
doi
=
{
investigation
.
doi
}
/
>
<
DOIBadge
doi
=
{
doi
}
/
>
<
/Col
>
<
/Row
>
<
/Grid
>
);
}
/**
* This looks into the parameters of the investigation
*/
export
function
getParameter
(
investigation
,
parameterName
)
{
const
parameter
=
investigation
.
parameters
.
find
(
(
o
)
=>
o
.
name
===
parameterName
);
if
(
parameter
&&
parameter
.
value
)
{
return
parameter
.
value
;
}
}
export
function
fileCountFormatter
(
_
,
investigation
)
{
const
fileCount
=
getParameter
(
investigation
,
FILE_COUNT
);
export
function
fileCountFormatter
(
parameters
)
{
const
fileCount
=
parameters
[
FILE_COUNT
];
if
(
!
fileCount
)
{
return
undefined
;
if
(
fileCount
===
undefined
)
{
return
''
;
}
return
(
...
...
@@ -110,29 +81,31 @@ export function fileCountFormatter(_, investigation) {
);
}
export
function
datasetCountFormatter
(
cell
,
investigation
)
{
const
datasetCount
=
investigation
.
parameters
.
find
(
(
o
)
=>
o
.
name
===
DATASET_COUNT
);
if
(
datasetCount
&&
datasetCount
.
value
)
{
return
(
<>
<
span
style
=
{{
width
:
40
,
textAlign
:
'
right
'
,
float
:
'
left
'
}}
>
{
datasetCount
.
value
}
<
/span
>
<
span
style
=
{{
width
:
70
,
marginLeft
:
5
,
float
:
'
left
'
,
fontStyle
:
'
italic
'
,
color
:
'
#999
'
,
fontSize
:
12
,
}}
>
({
volumeFormatter
(
cell
,
investigation
)})
<
/span
>
<
/
>
);
export
function
datasetCountFormatter
(
parameters
)
{
const
datasetCount
=
parameters
[
DATASET_COUNT
];
const
volume
=
parameters
[
VOLUME
];
if
(
datasetCount
===
undefined
)
{
return
''
;
}
return
(
<>
<
span
style
=
{{
width
:
40
,
textAlign
:
'
right
'
,
float
:
'
left
'
}}
>
{
parameters
[
DATASET_COUNT
]}
<
/span
>
<
span
style
=
{{
width
:
70
,
marginLeft
:
5
,
float
:
'
left
'
,
fontStyle
:
'
italic
'
,
color
:
'
#999
'
,
fontSize
:
12
,
}}
>
{
volume
!==
undefined
&&
volume
!==
0
&&
stringifyBytesSize
(
volume
)}
<
/span
>
<
/
>
);
}
src/components/LoadingBoundary.js
View file @
ae15fa32
...
...
@@ -4,18 +4,27 @@ import Loader from './Loader';
import
{
NetworkErrorBoundary
}
from
'
rest-hooks
'
;
function
LoadingBoundary
(
props
)
{
const
{
authError
,
children
,
...
loaderProps
}
=
props
;
const
{
customLoader
,
withSilentError
=
false
,
children
,
...
loaderProps
}
=
props
;
const
loader
=
customLoader
!==
undefined
?
customLoader
:
<
Loader
{...
loaderProps
}
/>
;
const
errorFallback
=
withSilentError
?
()
=>
null
:
({
error
})
=>
(
<
Alert
bsStyle
=
"
warning
"
style
=
{{
marginTop
:
16
}}
>
An
error
occured
:
{
error
.
message
}
<
/Alert
>
);
return
(
<
Suspense
fallback
=
{
<
Loader
{...
loaderProps
}
/>}
>
<
NetworkErrorBoundary
fallbackComponent
=
{({
error
})
=>
(
<
Alert
bsStyle
=
"
warning
"
style
=
{{
marginTop
:
16
}}
>
{
error
.
status
===
403
?
authError
||
'
Not allowed
'
:
`An error occured:
${
error
.
message
}
`
}
<
/Alert
>
)}
>
<
Suspense
fallback
=
{
loader
}
>
<
NetworkErrorBoundary
fallbackComponent
=
{
errorFallback
}
>
{
children
}
<
/NetworkErrorBoundary
>
<
/Suspense
>
...
...
src/components/Logbook/Menu/EventListMenu.js
View file @
ae15fa32
...
...
@@ -303,7 +303,7 @@ EventListMenu.propTypes = {
/** Callback function used to trigger event list update */
getEvents: PropTypes.func,
/** Identifier of the current investigation */
investigationId: PropTypes.
string
,
investigationId: PropTypes.
number
,
/** whether the event list refreshes automatically when a new event has arrived */
autorefreshEventList: PropTypes.bool,
/** Whether the New button is enabled or not */
...
...
src/components/Menu/ManagerMenu.js
View file @
ae15fa32
import
{
uniq
}
from
'
lodash-es
'
;
import
React
from
'
react
'
;
import
{
Button
,
Glyphicon
,
MenuItem
,
NavDropdown
}
from
'
react-bootstrap
'
;
import
{
Glyphicon
,
MenuItem
,
NavDropdown
}
from
'
react-bootstrap
'
;
import
{
LinkContainer
}
from
'
react-router-bootstrap
'
;
import
styles
from
'
./Menu.module.css
'
;
import
{
useSelector
}
from
'
react-redux
'
;
import
{
useResource
}
from
'
rest-hooks
'
;
import
InstrumentResource
from
'
../../resources/instrument
'
;
class
ManagerMenu
extends
React
.
Component
{
getBeamlineList
(
instruments
)
{
if
(
this
.
props
.
scientistInstrumentInvestigations
.
fetching
)
{
return
(
<
LinkContainer
to
=
"
/usermanagement
"
>
<
MenuItem
eventKey
=
{
3.3
}
>
Fetching
beamlines
<
Glyphicon
style
=
{{
marginLeft
:
10
}}
className
=
"
spin
"
glyph
=
"
repeat
"
/>
<
/MenuItem
>
<
/LinkContainer
>
);
}
function
ManagerMenu
()
{
const
{
isAdministrator
}
=
useSelector
((
state
)
=>
state
.
user
);
if
(
instruments
&&
instruments
.
length
>
0
)
{
const
items
=
instruments
.
slice
(
0
)
.
filter
((
value
)
=>
!!
value
)
.
sort
()
.
map
((
value
,
index
)
=>
(
<
LinkContainer
key
=
{
value
+
index
}
to
=
{
`/beamline/
${
value
.
toLowerCase
()}
`
}
>
<
MenuItem
eventKey
=
{
`
${
3
}
.
${
index
}
`
}
key
=
{
index
}
>