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
a3cfd20d
Commit
a3cfd20d
authored
Sep 30, 2018
by
Matija Obreza
Browse files
Show snackbars on filters change in Overview
parent
c5784ca2
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/ui/common/filter/PrettyFilters.tsx
View file @
a3cfd20d
import
*
as
React
from
'
react
'
;
import
{
bindActionCreators
}
from
'
redux
'
;
import
{
connect
}
from
'
react-redux
'
;
import
{
withStyles
}
from
'
@material-ui/core/styles
'
;
import
{
withStyles
}
from
'
@material-ui/core/styles
'
;
import
{
translate
}
from
'
react-i18next
'
;
import
{
showSnackbar
}
from
'
actions/snackbar
'
;
import
Chip
from
'
@material-ui/core/Chip
'
;
import
Paper
from
'
@material-ui/core/Paper
'
;
import
*
as
flattenjs
from
'
flattenjs
'
;
...
...
@@ -26,24 +29,25 @@ import PrettyDate from 'ui/common/time/PrettyDate';
* }
*/
interface
IPrettyFiltersProps
extends
React
.
ClassAttributes
<
any
>
{
classes
:
any
;
onSubmit
:
(
newFilter
)
=>
any
;
filterObj
:
object
;
lookups
:
object
;
prefix
:
string
;
t
:
any
;
classes
:
any
;
onSubmit
:
(
newFilter
)
=>
any
;
showSnackbar
:
(
snack
:
string
)
=>
void
;
filterObj
:
object
;
lookups
:
object
;
prefix
:
string
;
t
:
any
;
}
const
styles
=
(
theme
)
=>
({
root
:
{
display
:
'
flex
'
,
justifyContent
:
'
center
'
as
'
center
'
,
flexWrap
:
'
wrap
'
as
'
wrap
'
,
padding
:
theme
.
spacing
.
unit
/
2
,
},
chip
:
{
margin
:
theme
.
spacing
.
unit
/
2
,
},
root
:
{
display
:
'
flex
'
,
justifyContent
:
'
center
'
as
'
center
'
,
flexWrap
:
'
wrap
'
as
'
wrap
'
,
padding
:
theme
.
spacing
.
unit
/
2
,
},
chip
:
{
margin
:
theme
.
spacing
.
unit
/
2
,
},
});
// Following keywords are skipped for showing
...
...
@@ -56,20 +60,20 @@ const keywordsToSkip = ['eq', 'contains', 'sw'];
* @return IPrettyFiltersProps.filterObj.
*/
function
handleFilterObj
(
filterObj
,
path
)
{
// clone original filter in order to not mutate it
const
clone
=
_
.
cloneDeep
(
filterObj
);
// array element
if
(
path
.
endsWith
(
'
]
'
))
{
const
lastIndex
=
path
.
lastIndexOf
(
'
[
'
);
const
arrayPath
=
path
.
substring
(
0
,
lastIndex
);
const
index
=
parseInt
(
path
.
substring
(
lastIndex
).
replace
(
/
[\[\]
'
]
+/g
,
''
),
10
);
// clone original filter in order to not mutate it
const
clone
=
_
.
cloneDeep
(
filterObj
);
// array element
if
(
path
.
endsWith
(
'
]
'
))
{
const
lastIndex
=
path
.
lastIndexOf
(
'
[
'
);
const
arrayPath
=
path
.
substring
(
0
,
lastIndex
);
const
index
=
parseInt
(
path
.
substring
(
lastIndex
).
replace
(
/
[\[\]
'
]
+/g
,
''
),
10
);
_
.
get
(
clone
,
arrayPath
).
splice
(
index
,
1
);
_
.
get
(
clone
,
arrayPath
).
splice
(
index
,
1
);
return
clone
;
}
return
clone
;
}
return
_
.
omit
(
clone
,
[
path
]);
return
_
.
omit
(
clone
,
[
path
]);
}
/**
...
...
@@ -86,102 +90,107 @@ function handleFilterObj(filterObj, path) {
* @return IPrettyFiltersProps.filterObj.
*/
function
getLabelName
(
path
,
value
,
lookups
,
prefix
,
t
)
{
const
lastKey
=
path
.
replace
(
/
\[(
.+
?)\]
/g
,
''
).
split
(
'
.
'
).
pop
();
let
name
=
value
;
if
(
lookups
&&
lookups
[
lastKey
])
{
name
=
lookups
[
lastKey
][
value
]
||
value
;
}
const
prettyPath
:
string
=
path
// remove array indexes square brackets [0], [1]... from path.
.
replace
(
/
\[(
.+
?)\]
/g
,
''
)
// split path title.eq -> ['title', 'eq']
.
split
(
'
.
'
)
// skip for showing keywords such as 'contains', 'eq'...
.
filter
((
e
)
=>
keywordsToSkip
.
indexOf
(
e
)
===
-
1
)
// join
.
join
(
'
.
'
);
if
(
typeof
name
===
'
boolean
'
)
{
if
(
name
)
{
return
t
(
`f.
${
prefix
}
.
${
prettyPath
}
`
);
}
return
t
(
'
f.NOT
'
,
{
what
:
t
(
`f.
${
prefix
}
.
${
prettyPath
.
replace
(
/^NOT
\.
/
,
''
)}
`
)});
const
lastKey
=
path
.
replace
(
/
\[(
.+
?)\]
/g
,
''
).
split
(
'
.
'
).
pop
();
let
name
=
value
;
if
(
lookups
&&
lookups
[
lastKey
])
{
name
=
lookups
[
lastKey
][
value
]
||
value
;
}
const
prettyPath
:
string
=
path
// remove array indexes square brackets [0], [1]... from path.
.
replace
(
/
\[(
.+
?)\]
/g
,
''
)
// split path title.eq -> ['title', 'eq']
.
split
(
'
.
'
)
// skip for showing keywords such as 'contains', 'eq'...
.
filter
((
e
)
=>
keywordsToSkip
.
indexOf
(
e
)
===
-
1
)
// join
.
join
(
'
.
'
);
if
(
typeof
name
===
'
boolean
'
)
{
if
(
name
)
{
return
t
(
`f.
${
prefix
}
.
${
prettyPath
}
`
);
}
return
t
(
'
f.NOT
'
,
{
what
:
t
(
`f.
${
prefix
}
.
${
prettyPath
.
replace
(
/^NOT
\.
/
,
''
)}
`
)
});
}
const
translatedPrettyPath
=
prettyPath
.
startsWith
(
'
NOT
'
)
?
t
(
'
f.NOT
'
,
{
what
:
t
(
`f.
${
prefix
}
.
${
prettyPath
.
replace
(
/^NOT
\.
/
,
''
)}
`
)})
:
t
(
`f.
${
prefix
}
.
${
prettyPath
}
`
);
const
translatedPrettyPath
=
prettyPath
.
startsWith
(
'
NOT
'
)
?
t
(
'
f.NOT
'
,
{
what
:
t
(
`f.
${
prefix
}
.
${
prettyPath
.
replace
(
/^NOT
\.
/
,
''
)}
`
)
})
:
t
(
`f.
${
prefix
}
.
${
prettyPath
}
`
);
const
translatedPrettyName
=
t
(
`
${
name
}
`
);
const
translatedPrettyName
=
t
(
`
${
name
}
`
);
if
(
prettyPath
.
includes
(
'
Date
'
))
{
return
<
span
>
{
translatedPrettyPath
}
:
<
PrettyDate
value
=
{
new
Date
(
name
)
}
/></
span
>;
}
if
(
prettyPath
.
includes
(
'
Date
'
))
{
return
<
span
>
{
translatedPrettyPath
}
:
<
PrettyDate
value
=
{
new
Date
(
name
)
}
/></
span
>;
}
return
`
${
translatedPrettyPath
}
:
${
translatedPrettyName
}
`
;
return
`
${
translatedPrettyPath
}
:
${
translatedPrettyName
}
`
;
}
class
PrettyFilters
extends
React
.
Component
<
IPrettyFiltersProps
,
any
>
{
constructor
(
props
:
IPrettyFiltersProps
,
context
:
any
)
{
super
(
props
,
context
);
this
.
state
=
{
chipData
:
flattenjs
.
convert
(
cleanFilters
(
props
.
filterObj
)),
};
}
protected
handleDelete
=
(
path
)
=>
()
=>
{
const
{
filterObj
,
onSubmit
}
=
this
.
props
;
const
updated
=
handleFilterObj
(
filterObj
,
path
);
onSubmit
(
updated
);
}
public
componentWillReceiveProps
(
nextProps
)
{
const
chipData
=
flattenjs
.
convert
(
cleanFilters
(
nextProps
.
filterObj
));
if
(
!
_
.
isEqual
(
chipData
,
this
.
state
.
chipData
))
{
this
.
setState
({
chipData
});
}
}
public
render
()
{
const
{
classes
,
lookups
,
prefix
,
t
}
=
this
.
props
;
const
{
chipData
}
=
this
.
state
;
const
dataArr
=
Object
.
getOwnPropertyNames
(
chipData
);
return
dataArr
.
length
>
0
&&
(
<
Paper
square
className
=
{
classes
.
root
}
>
{
dataArr
.
map
((
key
)
=>
{
return
(
<
Chip
key
=
{
key
}
label
=
{
getLabelName
(
key
,
chipData
[
key
],
lookups
,
prefix
,
t
)
}
onDelete
=
{
this
.
handleDelete
(
key
)
}
className
=
{
classes
.
chip
}
/>
);
})
}
</
Paper
>
);
constructor
(
props
:
IPrettyFiltersProps
,
context
:
any
)
{
super
(
props
,
context
);
this
.
state
=
{
chipData
:
flattenjs
.
convert
(
cleanFilters
(
props
.
filterObj
)),
};
}
protected
handleDelete
=
(
path
)
=>
()
=>
{
const
{
filterObj
,
onSubmit
,
showSnackbar
}
=
this
.
props
;
const
updated
=
handleFilterObj
(
filterObj
,
path
);
showSnackbar
(
'
Applying filters...
'
);
onSubmit
(
updated
);
}
public
componentWillReceiveProps
(
nextProps
)
{
const
chipData
=
flattenjs
.
convert
(
cleanFilters
(
nextProps
.
filterObj
));
if
(
!
_
.
isEqual
(
chipData
,
this
.
state
.
chipData
))
{
this
.
setState
({
chipData
});
}
}
public
render
()
{
const
{
classes
,
lookups
,
prefix
,
t
}
=
this
.
props
;
const
{
chipData
}
=
this
.
state
;
const
dataArr
=
Object
.
getOwnPropertyNames
(
chipData
);
return
dataArr
.
length
>
0
&&
(
<
Paper
square
className
=
{
classes
.
root
}
>
{
dataArr
.
map
((
key
)
=>
{
return
(
<
Chip
key
=
{
key
}
label
=
{
getLabelName
(
key
,
chipData
[
key
],
lookups
,
prefix
,
t
)
}
onDelete
=
{
this
.
handleDelete
(
key
)
}
className
=
{
classes
.
chip
}
/>
);
})
}
</
Paper
>
);
}
}
const
styled
=
withStyles
(
styles
)(
PrettyFilters
);
const
mapStateToProps
=
(
state
,
ownProps
)
=>
({
lookups
:
{
crop
:
[],
category
:
''
,
sampStat
:
Accession
.
SAMPSTAT
,
storage
:
Accession
.
STORAGE
,
accessions
:
{
true
:
'
Yes
'
,
false
:
'
No
'
,
},
lookups
:
{
crop
:
[],
category
:
''
,
sampStat
:
Accession
.
SAMPSTAT
,
storage
:
Accession
.
STORAGE
,
accessions
:
{
true
:
'
Yes
'
,
false
:
'
No
'
,
},
},
});
export
default
translate
()(
connect
(
mapStateToProps
)(
styled
));
const
mapDispatchToProps
=
(
dispatch
)
=>
bindActionCreators
({
showSnackbar
,
},
dispatch
);
export
default
translate
()(
connect
(
mapStateToProps
,
mapDispatchToProps
)(
styled
));
src/ui/pages/accessions/OverviewPage.tsx
View file @
a3cfd20d
...
...
@@ -7,6 +7,7 @@ import * as _ from 'lodash';
// Actions
import
{
applyFilters
,
loadAccessionsPage
,
listAccessionsPromise
,
updateRoute
,
applyOverviewFilters
,
loadAccessionsOverviewPage
}
from
'
actions/accessions
'
;
import
{
showSnackbar
}
from
'
actions/snackbar
'
;
// Models
import
Accession
from
'
model/Accession
'
;
...
...
@@ -18,6 +19,7 @@ import AccessionOverview from 'model/AccessionOverview';
import
PageLayout
,
{
PageContents
}
from
'
ui/layout/PageLayout
'
;
import
GridLayout
from
'
ui/layout/GridLayout
'
;
import
ContentHeader
from
'
ui/common/heading/ContentHeader
'
;
import
Loading
from
'
ui/common/Loading
'
;
import
Tabs
,
{
Tab
}
from
'
ui/common/Tabs
'
;
import
PropertiesCard
from
'
ui/common/PropertiesCard
'
;
import
PrettyFilters
from
'
ui/common/filter/PrettyFilters
'
;
...
...
@@ -32,6 +34,7 @@ interface IOverviewPageProps extends React.ClassAttributes<any> {
overview
:
AccessionOverview
;
paged
:
FilteredPage
<
Accession
>
;
filterCode
:
string
;
showSnackbar
:
(
snack
:
string
)
=>
void
;
applyOverviewFilters
:
(
filters
:
string
|
AccessionFilter
,
page
?:
IPageRequest
)
=>
void
;
updateRoute
:
(
paged
:
FilteredPage
<
Accession
>
,
path
?:
string
)
=>
void
;
currentTab
:
string
;
...
...
@@ -63,7 +66,7 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
}
private
addTerm
=
(
property
,
term
)
=>
{
const
{
overview
,
applyOverviewFilters
}
=
this
.
props
;
const
{
overview
,
applyOverviewFilters
,
showSnackbar
}
=
this
.
props
;
const
updatedFilter
:
AccessionFilter
=
{
...
overview
.
filter
};
switch
(
property
)
{
...
...
@@ -89,6 +92,7 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
}
// console.log(`Updated filter for ${property} +${term}`, updatedFilter);
showSnackbar
(
'
Applying filters...
'
);
applyOverviewFilters
(
updatedFilter
);
};
...
...
@@ -147,7 +151,7 @@ class BrowsePage extends React.Component<IOverviewPageProps, any> {
filterObj
=
{
overviewWrapper
&&
overviewWrapper
.
filter
||
{}
}
onSubmit
=
{
applyOverviewFilters
}
/>
{
overview
&&
{
!
overview
?
<
Loading
/>
:
<
div
style
=
{
{
display
:
'
flex
'
,
marginTop
:
'
1em
'
,
marginBottom
:
'
1em
'
}
}
>
<
PageContents
>
<
GridLayout
>
...
...
@@ -214,6 +218,7 @@ const mapStateToProps = (state, ownProps) => ({
});
const
mapDispatchToProps
=
(
dispatch
)
=>
bindActionCreators
({
showSnackbar
,
applyFilters
,
loadDataPage
:
loadAccessionsPage
,
loadDataPromise
:
listAccessionsPromise
,
...
...
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