Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Genesys PGR
Genesys Website
Commits
8dba63ac
Commit
8dba63ac
authored
Jan 10, 2019
by
Oleksii Savran
Committed by
Matija Obreza
Jan 11, 2019
Browse files
Admin: Added sorting and filtering for requests
parent
f5d0bf16
Changes
11
Hide whitespace changes
Inline
Side-by-side
locales/en/translations.json
View file @
8dba63ac
...
...
@@ -115,6 +115,12 @@
"email"
:
"E-mail address"
,
"uuid"
:
"UUID"
},
"requests"
:
{
"email"
:
"E-mail address"
,
"uuid"
:
"UUID"
,
"state"
:
"State"
,
"pid"
:
"PID"
},
"dataset"
:
{
"_text"
:
"Keywords"
,
"accessionIdentifier"
:
{
...
...
@@ -1583,6 +1589,10 @@
}
},
"admin"
:
{
"f"
:
{
"title"
:
"Filter requests"
,
"pid"
:
"PID"
},
"p"
:
{
"browse"
:
{
"title"
:
"{{totalElements, number}} requests for PGR material"
...
...
@@ -1602,8 +1612,9 @@
}
},
"common"
:
{
"modelMame"
:
"Request"
,
"modelMame_plural"
:
"Requests"
,
"modelName"
:
"Request"
,
"modelName_plural"
:
"Requests"
,
"emailAddress"
:
"E-mail address"
,
"preacceptSMTA"
:
"Preaccept SMTA"
,
"stateLabel"
:
"State"
,
"state"
:
{
...
...
@@ -1621,6 +1632,10 @@
"0"
:
"Other (please elaborate in Notes field)"
,
"1"
:
"Research for food and agriculture"
}
},
"sort"
:
{
"lastModifiedDateAsc"
:
"Last modified date (old to new)"
,
"lastModifiedDateDesc"
:
"Last modified date (new to old)"
}
}
,
"subsets"
:
{
...
...
src/model/request/MaterialRequest.ts
View file @
8dba63ac
...
...
@@ -24,6 +24,17 @@ class MaterialRequest {
direction
:
'
DESC
'
,
};
public
static
STATE
:
{
[
key
:
number
]:
string
;
}
=
{
0
:
'
requests.common.state.0
'
,
1
:
'
requests.common.state.1
'
,
2
:
'
requests.common.state.2
'
,
};
public
static
SORT_OPTIONS
=
{
lastModifiedDate
:
{
property
:
'
lastModifiedDate
'
,
label
:
'
requests.sort.lastModifiedDateAsc
'
,
direction
:
'
ASC
'
},
lastModifiedDateD
:
{
property
:
'
lastModifiedDate
'
,
label
:
'
requests.sort.lastModifiedDateDesc
'
,
direction
:
'
DESC
'
},
email
:
{
property
:
'
email
'
,
label
:
'
requests.common.emailAddress
'
,
direction
:
'
ASC
'
},
};
}
export
default
MaterialRequest
;
src/requests/actions/admin.ts
View file @
8dba63ac
...
...
@@ -3,11 +3,17 @@ import * as _ from 'lodash';
// constants
import
{
ADMIN_APPEND_MATERIAL_REQUESTS
,
ADMIN_RECEIVE_MATERIAL_REQUEST
,
ADMIN_RECEIVE_MATERIAL_REQUESTS
}
from
'
requests/constants
'
;
// actions
import
navigateTo
from
'
actions/navigation
'
;
// services
import
RequestService
from
'
service/genesys/RequestService
'
;
// models
import
MaterialRequest
from
'
model/request/MaterialRequest
'
;
import
FilteredPage
from
'
model/FilteredPage
'
;
import
RequestService
from
'
service/genesys/RequestService
'
;
import
FilteredPage
,
{
IPageRequest
}
from
'
model/FilteredPage
'
;
import
Page
from
'
model/Page
'
;
import
MaterialRequestFilter
from
'
model/request/MaterialRequestFilter
'
;
const
receiveRequests
=
(
paged
:
FilteredPage
<
MaterialRequest
>
,
error
=
null
)
=>
({
...
...
@@ -94,3 +100,23 @@ export const sendValidationEmailAction = (uuid: string) => (dispatch) => {
dispatch
(
receiveRequest
(
null
,
error
));
});
};
export
const
applyFilters
=
(
filters
:
string
|
MaterialRequestFilter
,
page
:
IPageRequest
=
{
page
:
0
})
=>
(
dispatch
)
=>
{
return
RequestService
.
list
(
filters
,
page
)
.
then
((
paged
)
=>
{
if
(
paged
.
number
===
0
)
{
dispatch
(
receiveRequests
(
paged
));
}
else
{
dispatch
(
appendRequests
(
paged
));
}
dispatch
(
updateRoute
(
paged
));
}).
catch
((
error
)
=>
{
console
.
log
(
`API error`
,
error
);
dispatch
(
receiveRequests
(
null
,
error
));
});
};
export
const
updateRoute
=
(
paged
:
FilteredPage
<
MaterialRequest
>
)
=>
(
dispatch
)
=>
{
dispatch
(
navigateTo
(
paged
.
filterCode
?
`/admin/requests/
${
paged
.
filterCode
}
`
:
'
/admin/requests
'
));
};
src/requests/constants.ts
View file @
8dba63ac
...
...
@@ -8,3 +8,5 @@ export const REQUEST_INFO_FORM = 'requests/form/REQUEST_INFO_FORM';
export
const
ADMIN_RECEIVE_MATERIAL_REQUESTS
=
'
requests/admin/RECEIVE_MATERIAL_REQUESTS
'
;
export
const
ADMIN_APPEND_MATERIAL_REQUESTS
=
'
requests/admin/APPEND_MATERIAL_REQUESTS
'
;
export
const
ADMIN_RECEIVE_MATERIAL_REQUEST
=
'
requests/admin/RECEIVE_MATERIAL_REQUEST
'
;
export
const
REQUEST_FILTER_FORM
=
'
Form/request/admin/REQUEST_FILTER_FORM
'
;
src/requests/routes.ts
View file @
8dba63ac
...
...
@@ -21,6 +21,17 @@ const publicRoutes = [
];
const
adminRoutes
=
[
{
path
:
'
/requests/:filterCode(v.+)?
'
,
component
:
Loadable
({
loader
:
()
=>
import
(
/* webpackMode:"lazy", webpackChunkName: "requests" */
'
requests/ui/admin/BrowsePage
'
),
loading
:
Loading
,
}),
exact
:
true
,
extraProps
:
{
title
:
'
Requests
'
,
},
},
{
path
:
'
/requests
'
,
component
:
Loadable
({
...
...
src/requests/translations.json
View file @
8dba63ac
...
...
@@ -24,6 +24,10 @@
}
},
"admin"
:
{
"f"
:
{
"title"
:
"Filter requests"
,
"pid"
:
"PID"
},
"p"
:
{
"browse"
:
{
"title"
:
"{{totalElements, number}} requests for PGR material"
...
...
@@ -43,8 +47,9 @@
}
},
"common"
:
{
"modelMame"
:
"Request"
,
"modelMame_plural"
:
"Requests"
,
"modelName"
:
"Request"
,
"modelName_plural"
:
"Requests"
,
"emailAddress"
:
"E-mail address"
,
"preacceptSMTA"
:
"Preaccept SMTA"
,
"stateLabel"
:
"State"
,
"state"
:
{
...
...
@@ -62,5 +67,9 @@
"0"
:
"Other (please elaborate in Notes field)"
,
"1"
:
"Research for food and agriculture"
}
},
"sort"
:
{
"lastModifiedDateAsc"
:
"Last modified date (old to new)"
,
"lastModifiedDateDesc"
:
"Last modified date (new to old)"
}
}
\ No newline at end of file
src/requests/ui/admin/BrowsePage.tsx
View file @
8dba63ac
...
...
@@ -2,12 +2,14 @@ import * as React from 'react';
import
{
translate
}
from
'
react-i18next
'
;
import
{
connect
}
from
'
react-redux
'
;
import
{
bindActionCreators
}
from
'
redux
'
;
import
{
parse
}
from
'
query-string
'
;
// Actions
import
{
loadMoreRequests
}
from
'
requests/actions/admin
'
;
import
{
applyFilters
,
updateRoute
,
loadMoreRequests
}
from
'
requests/actions/admin
'
;
// Models
import
MaterialRequest
from
'
model/request/MaterialRequest
'
;
import
FilteredPage
from
'
model/FilteredPage
'
;
// UI
import
BrowsePageTemplate
from
'
ui/pages/_base/BrowsePage
'
;
...
...
@@ -15,51 +17,77 @@ import { PageContents } from 'ui/layout/PageLayout';
import
Loading
from
'
ui/common/Loading
'
;
import
PagedLoader
from
'
ui/common/PagedLoader
'
;
import
RequestCard
from
'
requests/ui/admin/c/RequestCard
'
;
import
ContentHeaderWithButton
from
'
ui/common/heading/ContentHeaderWithButton
'
;
import
PrettyFilters
from
'
ui/common/filter/PrettyFilters
'
;
import
ContentLayout
from
'
ui/layout/ContentLayout
'
;
import
MaterialRequestFilter
from
'
requests/ui/admin/c/MaterialRequestFilter
'
;
import
Grid
from
'
@material-ui/core/Grid
'
;
import
PaginationComponent
from
'
ui/common/pagination
'
;
class
BrowsePage
extends
BrowsePageTemplate
<
any
>
{
protected
static
needs
=
[
({
})
=>
loadMoreRequests
(),
({
search
,
params
:
{
filterCode
}
})
=>
{
const
qs
=
parse
(
search
||
''
);
return
applyFilters
(
filterCode
||
''
,
FilteredPage
.
fromQueryString
(
qs
));
},
];
public
componentWillMount
()
{
const
{
paged
,
loadMoreData
}
=
this
.
props
;
const
{
paged
,
applyFilters
,
filterCode
}
=
this
.
props
;
if
(
!
paged
)
{
loadMoreData
(
);
applyFilters
(
filterCode
);
}
}
public
render
()
{
const
{
paged
,
t
,
loadMoreData
}
=
this
.
props
;
const
{
paged
,
loadMoreData
}
=
this
.
props
;
const
renderRequest
=
(
r
:
MaterialRequest
,
index
:
number
)
=>
{
return
<
RequestCard
key
=
{
r
.
uuid
}
index
=
{
index
}
request
=
{
r
}
/>;
};
return
(
<
div
>
<
ContentHeaderWithButton
title
=
{
t
(
'
requests.admin.p.browse.title
'
,
{
totalElements
:
paged
?
paged
.
totalElements
:
'
-
'
})
}
/>
<
PageContents
className
=
"pt-1rem container-spacing-horizontal"
>
{
!
paged
?
<
Loading
/>
:
<
PagedLoader
paged
=
{
paged
}
loadMore
=
{
loadMoreData
}
roughItemHeight
=
{
80
}
itemRenderer
=
{
renderRequest
}
/>
}
</
PageContents
>
</
div
>
<
ContentLayout
left
=
{
<
MaterialRequestFilter
initialValues
=
{
paged
&&
paged
.
filter
||
{}
}
onSubmit
=
{
this
.
myApplyFilters
}
/>
}
customHeaderHeight
>
<
Grid
container
spacing
=
{
0
}
>
<
Grid
item
xs
=
{
12
}
>
<
PaginationComponent
pageObj
=
{
paged
}
onSortChange
=
{
this
.
onSortChange
}
displayName
=
"requests.common.modelName"
sortOptions
=
{
MaterialRequest
.
SORT_OPTIONS
}
/>
<
PrettyFilters
prefix
=
"requests"
filterObj
=
{
paged
&&
paged
.
filter
||
{}
}
onSubmit
=
{
this
.
myApplyFilters
}
/>
<
PageContents
className
=
"pt-1rem container-spacing-horizontal"
>
{
!
paged
?
<
Loading
/>
:
<
PagedLoader
paged
=
{
paged
}
loadMore
=
{
loadMoreData
}
roughItemHeight
=
{
80
}
itemRenderer
=
{
renderRequest
}
/>
}
</
PageContents
>
</
Grid
>
</
Grid
>
</
ContentLayout
>
);
}
}
const
mapStateToProps
=
(
state
)
=>
({
const
mapStateToProps
=
(
state
,
ownProps
)
=>
({
paged
:
state
.
requests
.
admin
.
paged
||
undefined
,
filterCode
:
ownProps
.
match
.
params
.
filterCode
,
});
const
mapDispatchToProps
=
(
dispatch
)
=>
bindActionCreators
({
applyFilters
,
loadMoreData
:
loadMoreRequests
,
updateRoute
,
},
dispatch
);
...
...
src/requests/ui/admin/c/MaterialRequestFilter.tsx
0 → 100644
View file @
8dba63ac
import
*
as
React
from
'
react
'
;
import
{
reduxForm
}
from
'
redux-form
'
;
import
{
REQUEST_FILTER_FORM
}
from
'
requests/constants
'
;
import
FiltersBlock
from
'
ui/common/filter/FiltersBlock
'
;
import
CollapsibleComponentSearch
from
'
ui/common/filter/CollapsibleComponentSearch
'
;
import
StringFilter
from
'
ui/common/filter/StringFilter
'
;
import
StringArrFilter
from
'
ui/common/filter/StringArrFilter
'
;
import
StatusFilter
from
'
ui/catalog/dashboard/c/StatusFilter
'
;
// move
const
MaterialRequestFilters
=
({
handleSubmit
,
initialValues
,
initialize
,
...
other
})
=>
{
return
(
<
FiltersBlock
title
=
"requests.admin.f.title"
handleSubmit
=
{
handleSubmit
}
initialize
=
{
initialize
}
{
...
other
}
>
<
CollapsibleComponentSearch
title
=
"common:f.textSearch"
>
<
StringFilter
name
=
"email"
searchType
=
"contains"
label
=
"requests.common.emailAddress"
placeholder
=
"name@domain.com"
/>
<
StringArrFilter
name
=
"uuid"
label
=
"common:label.UUID"
placeholder
=
"ihope-youk-noww-hatyouredoing"
/>
<
StringArrFilter
name
=
"pid"
label
=
"requests.admin.f.pid"
placeholder
=
"ihope-youk-noww-hatyouredoing"
/>
</
CollapsibleComponentSearch
>
<
CollapsibleComponentSearch
title
=
"common:label.status"
>
<
StatusFilter
isMaterialRequestFilter
/>
</
CollapsibleComponentSearch
>
</
FiltersBlock
>
);
};
export
default
reduxForm
({
enableReinitialize
:
true
,
form
:
REQUEST_FILTER_FORM
,
})(
MaterialRequestFilters
);
src/translations.json
View file @
8dba63ac
...
...
@@ -114,6 +114,12 @@
"email"
:
"E-mail address"
,
"uuid"
:
"UUID"
},
"requests"
:
{
"email"
:
"E-mail address"
,
"uuid"
:
"UUID"
,
"state"
:
"State"
,
"pid"
:
"PID"
},
"dataset"
:
{
"_text"
:
"Keywords"
,
"accessionIdentifier"
:
{
...
...
src/ui/catalog/dashboard/c/StatusFilter.tsx
View file @
8dba63ac
...
...
@@ -4,13 +4,24 @@ import { translate } from 'react-i18next';
import
StringArrFilter
from
'
ui/common/filter/StringArrFilter
'
;
import
{
PublishState
}
from
'
model/common.model
'
;
class
StatusFilter
extends
React
.
Component
<
any
,
any
>
{
interface
IStatusFilter
{
isMaterialRequestFilter
?:
true
;
}
class
StatusFilter
extends
React
.
Component
<
IStatusFilter
,
any
>
{
private
options
:
object
=
{};
public
componentWillMount
()
{
this
.
options
[
PublishState
.
DRAFT
]
=
'
status.inProgress
'
;
this
.
options
[
PublishState
.
REVIEWING
]
=
'
status.inReview
'
;
this
.
options
[
PublishState
.
PUBLISHED
]
=
'
status.published
'
;
const
isMaterialRequestFilter
=
this
.
props
;
if
(
isMaterialRequestFilter
)
{
this
.
options
[
0
]
=
'
requests.common.state.0
'
;
this
.
options
[
1
]
=
'
requests.common.state.1
'
;
this
.
options
[
2
]
=
'
requests.common.state.2
'
;
}
else
{
this
.
options
[
PublishState
.
DRAFT
]
=
'
status.inProgress
'
;
this
.
options
[
PublishState
.
REVIEWING
]
=
'
status.inReview
'
;
this
.
options
[
PublishState
.
PUBLISHED
]
=
'
status.published
'
;
}
}
public
render
()
{
...
...
@@ -21,3 +32,4 @@ class StatusFilter extends React.Component<any, any> {
}
export
default
translate
()(
StatusFilter
);
src/ui/common/filter/PrettyFilters.tsx
View file @
8dba63ac
...
...
@@ -12,6 +12,7 @@ import * as _ from 'lodash';
import
{
cleanFilters
}
from
'
utilities
'
;
import
Accession
from
'
model/accession/Accession
'
;
import
{
User
}
from
'
model/user/User
'
;
import
MaterialRequest
from
'
model/request/MaterialRequest
'
;
import
PrettyDate
from
'
ui/common/time/PrettyDate
'
;
/**
...
...
@@ -192,6 +193,7 @@ const mapStateToProps = (state, ownProps) => ({
true
:
'
Yes
'
,
false
:
'
No
'
,
},
state
:
MaterialRequest
.
STATE
,
},
labels
:
state
.
uuidDecoder
.
labels
,
});
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment