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 Backend
Commits
3dec5ce0
Commit
3dec5ce0
authored
Sep 16, 2013
by
Matija Obreza
Browse files
Filtering
parent
472c4a7e
Changes
8
Hide whitespace changes
Inline
Side-by-side
.settings/org.eclipse.core.resources.prefs
View file @
3dec5ce0
...
...
@@ -3,6 +3,7 @@ encoding//src/main/resources=UTF-8
encoding//src/main/resources/content/language.properties=UTF-8
encoding//src/main/webapp/WEB-INF/jsp/accession/data.jsp=UTF-8
encoding//src/main/webapp/WEB-INF/jsp/descr/index.jsp=UTF-8
encoding//src/main/webapp/WEB-INF/jsp/filter/index.jsp=UTF-8
encoding//src/main/webapp/WEB-INF/jsp/login.jsp=UTF-8
encoding//src/main/webapp/WEB-INF/jsp/metadata/index.jsp=UTF-8
encoding//src/main/webapp/WEB-INF/jsp/metadata/view.jsp=UTF-8
...
...
src/main/java/org/crophub/rest/common/service/GenesysFilterService.java
View file @
3dec5ce0
package
org.crophub.rest.common.service
;
import
java.util.List
;
import
org.crophub.rest.common.model.genesys.Accession
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.Pageable
;
...
...
@@ -10,4 +12,13 @@ public interface GenesysFilterService {
Page
<
Accession
>
listAccessions
(
JsonNode
jsonTree
,
Pageable
pageable
);
List
<?
extends
GenesysFilter
>
listAvailableFilters
();
public
static
interface
GenesysFilter
{
public
enum
FilterType
{
FIXEDSTRING
,
STRING
,
NUMERIC
}
}
}
src/main/java/org/crophub/rest/common/service/impl/GenesysFilterServiceImpl.java
View file @
3dec5ce0
package
org.crophub.rest.common.service.impl
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map.Entry
;
...
...
@@ -14,6 +15,7 @@ import org.crophub.rest.common.model.genesys.Accession;
import
org.crophub.rest.common.persistence.domain.AccessionRepository
;
import
org.crophub.rest.common.persistence.domain.TraitValueRepository
;
import
org.crophub.rest.common.service.GenesysFilterService
;
import
org.crophub.rest.common.service.GenesysFilterService.GenesysFilter.FilterType
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.data.domain.Page
;
import
org.springframework.data.domain.PageImpl
;
...
...
@@ -32,6 +34,8 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
public
static
final
Log
LOG
=
LogFactory
.
getLog
(
GenesysFilterServiceImpl
.
class
);
private
ArrayList
<
GenesysFilterImpl
>
availableFilters
;
@Autowired
private
TraitValueRepository
traitValueRepository
;
...
...
@@ -48,6 +52,22 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
this
.
jdbcTemplate
=
new
JdbcTemplate
(
dataSource
);
}
public
GenesysFilterServiceImpl
()
{
this
.
availableFilters
=
new
ArrayList
<
GenesysFilterImpl
>();
// "origin", "institute", "lat", "lon", "alt", "genus"
this
.
availableFilters
.
add
(
new
GenesysFilterImpl
(
"origin"
,
FilterType
.
FIXEDSTRING
,
3
));
this
.
availableFilters
.
add
(
new
GenesysFilterImpl
(
"institute"
,
FilterType
.
FIXEDSTRING
,
6
));
this
.
availableFilters
.
add
(
new
GenesysFilterImpl
(
"lat"
,
FilterType
.
NUMERIC
));
this
.
availableFilters
.
add
(
new
GenesysFilterImpl
(
"lon"
,
FilterType
.
NUMERIC
));
this
.
availableFilters
.
add
(
new
GenesysFilterImpl
(
"alt"
,
FilterType
.
NUMERIC
));
this
.
availableFilters
.
add
(
new
GenesysFilterImpl
(
"genus"
,
FilterType
.
STRING
));
}
@Override
public
List
<?
extends
GenesysFilter
>
listAvailableFilters
()
{
return
Collections
.
unmodifiableList
(
this
.
availableFilters
);
}
@Override
public
Page
<
Accession
>
listAccessions
(
JsonNode
jsonTree
,
Pageable
pageable
)
{
Iterator
<
Entry
<
String
,
JsonNode
>>
fields
=
jsonTree
.
fields
();
...
...
@@ -60,7 +80,7 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
StringBuffer
sb
=
new
StringBuffer
();
sb
.
append
(
" from accession a "
);
if
(
jsonTree
.
has
(
"
taxonomy
"
))
{
if
(
jsonTree
.
has
(
"
genus
"
))
{
sb
.
append
(
" inner join all_taxonomy t on t.Taxon_Code=a.Taxon_Code "
);
}
if
(
jsonTree
.
has
(
"lat"
)
||
jsonTree
.
has
(
"lon"
)
||
jsonTree
.
has
(
"alt"
))
{
...
...
@@ -69,7 +89,7 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
createQuery
(
sb
,
"a.Origin"
,
jsonTree
.
get
(
"origin"
),
params
);
createQuery
(
sb
,
"a.Institute"
,
jsonTree
.
get
(
"institute"
),
params
);
createQuery
(
sb
,
"t.Genus"
,
jsonTree
.
get
(
"
taxonomy
"
),
params
);
createQuery
(
sb
,
"t.Genus"
,
jsonTree
.
get
(
"
genus
"
),
params
);
createQuery
(
sb
,
"env.LongitudeD"
,
jsonTree
.
get
(
"lon"
),
params
);
createQuery
(
sb
,
"env.LatitudeD"
,
jsonTree
.
get
(
"lat"
),
params
);
createQuery
(
sb
,
"env.Altitude"
,
jsonTree
.
get
(
"alt"
),
params
);
...
...
@@ -139,7 +159,8 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
int
handledCount
=
params
.
size
()
-
paramCount
;
// do we have more?
if
(
fieldQuery
.
size
()
>
handledCount
)
{
LOG
.
info
(
"FQS="
+
fieldQuery
.
size
()
+
" >? "
+
handledCount
);
if
(
handledCount
>
0
&&
fieldQuery
.
size
()
>
handledCount
)
{
sb
.
append
(
" OR "
);
}
...
...
@@ -157,7 +178,7 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
private
void
handleOperations
(
StringBuffer
sb
,
String
dbName
,
Iterator
<
JsonNode
>
elements
,
List
<
Object
>
params
)
{
int
counter
=
0
;
int
counter
=
0
;
while
(
elements
.
hasNext
())
{
JsonNode
filterValue
=
elements
.
next
();
LOG
.
debug
(
"Inspecting "
+
dbName
+
" ... "
+
filterValue
);
...
...
@@ -167,7 +188,7 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
JsonNode
range
=
filterValue
.
findValue
(
"range"
);
if
(
range
.
isArray
())
{
LOG
.
debug
(
"Adding array: "
+
range
);
if
(
counter
>
0
)
{
if
(
counter
>
0
)
{
sb
.
append
(
" or "
);
}
counter
++;
...
...
@@ -181,34 +202,41 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
JsonNode
min
=
filterValue
.
findValue
(
"min"
);
if
(
min
!=
null
&&
min
.
isNumber
())
{
LOG
.
debug
(
"Adding min number: "
+
min
);
if
(
counter
>
0
)
{
if
(
counter
>
0
)
{
sb
.
append
(
" or "
);
}
counter
++;
// must be an array
// addParam(params, filterValue);
// must be an number
sb
.
append
(
"\n ( "
).
append
(
dbName
);
sb
.
append
(
" >= ? ) "
);
addParam
(
params
,
min
);
}
JsonNode
max
=
filterValue
.
findValue
(
"max"
);
if
(
max
!=
null
&&
max
.
isNumber
())
{
LOG
.
debug
(
"Adding max number: "
+
max
);
if
(
counter
>
0
)
{
if
(
counter
>
0
)
{
sb
.
append
(
" or "
);
}
counter
++;
// must be an array
// addParam(params, filterValue);
// must be an number
sb
.
append
(
"\n ( "
).
append
(
dbName
);
sb
.
append
(
" <= ? ) "
);
addParam
(
params
,
max
);
}
JsonNode
like
=
filterValue
.
findValue
(
"like"
);
if
(
like
!=
null
&&
like
.
isTextual
())
{
LOG
.
debug
(
"Adding LIKE : "
+
like
);
if
(
counter
>
0
)
{
if
(
counter
>
0
)
{
sb
.
append
(
" or "
);
}
counter
++;
// must be an array
// addParam(params, filterValue);
// must be an number
sb
.
append
(
"\n ( "
).
append
(
dbName
);
sb
.
append
(
" LIKE ? ) "
);
addParam
(
params
,
like
);
}
}
}
...
...
@@ -226,7 +254,9 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
addParam
(
params
,
filterValue
);
}
}
if
(
counter
==
1
)
{
if
(
counter
==
0
)
{
// Nothing..
}
else
if
(
counter
==
1
)
{
sb
.
append
(
"\n ( "
).
append
(
dbName
);
sb
.
append
(
" = ? ) "
);
}
else
{
...
...
@@ -247,4 +277,35 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
else
if
(
JsonNodeType
.
NUMBER
==
value
.
getNodeType
())
params
.
add
(
value
.
asDouble
());
}
public
static
class
GenesysFilterImpl
implements
GenesysFilter
{
private
String
name
;
private
FilterType
type
;
private
Integer
maxLength
;
public
GenesysFilterImpl
(
String
name
,
FilterType
type
)
{
this
.
name
=
name
;
this
.
type
=
type
;
this
.
maxLength
=
null
;
}
public
GenesysFilterImpl
(
String
name
,
FilterType
type
,
int
i
)
{
this
.
name
=
name
;
this
.
type
=
type
;
this
.
maxLength
=
i
;
}
public
String
getName
()
{
return
name
;
}
public
FilterType
getType
()
{
return
type
;
}
public
Integer
getMaxLength
()
{
return
maxLength
;
}
}
}
src/main/java/org/crophub/rest/servlet/controller/FilterController.java
View file @
3dec5ce0
...
...
@@ -57,6 +57,34 @@ public class FilterController extends BaseController {
@Autowired
private
TaxonomyService
taxonomyService
;
@RequestMapping
(
"/filter"
)
public
String
see
(
ModelMap
model
,
@RequestParam
(
value
=
"filter"
,
required
=
false
,
defaultValue
=
"{}"
)
String
jsonFilter
)
{
_logger
.
info
(
"Filtering by: "
+
jsonFilter
);
// What filters do we support?
model
.
addAttribute
(
"availableFilters"
,
filterService
.
listAvailableFilters
());
ObjectMapper
mapper
=
new
ObjectMapper
();
JsonNode
jsonTree
=
null
;
try
{
jsonTree
=
mapper
.
readTree
(
jsonFilter
);
_logger
.
debug
(
jsonTree
.
toString
());
model
.
addAttribute
(
"jsonString"
,
jsonTree
.
toString
());
model
.
addAttribute
(
"jsonFilter"
,
jsonTree
);
Iterator
<
Entry
<
String
,
JsonNode
>>
fields
=
jsonTree
.
fields
();
while
(
fields
.
hasNext
())
{
Entry
<
String
,
JsonNode
>
entry
=
fields
.
next
();
_logger
.
debug
(
"2="
+
entry
.
getKey
()
+
" = "
+
entry
.
getValue
());
}
}
catch
(
IOException
e
)
{
_logger
.
error
(
"Invalid JSON filter:"
+
e
.
getMessage
(),
e
);
}
return
"/filter/index"
;
}
/**
* Browse all
*
...
...
@@ -66,7 +94,7 @@ public class FilterController extends BaseController {
*/
@RequestMapping
(
"/f"
)
public
String
viewFiltered
(
ModelMap
model
,
@RequestParam
(
value
=
"page"
,
required
=
false
,
defaultValue
=
"1"
)
int
page
,
@RequestParam
(
value
=
"filter"
,
required
=
fals
e
,
defaultValue
=
""
)
String
jsonFilter
)
{
@RequestParam
(
value
=
"filter"
,
required
=
tru
e
,
defaultValue
=
"
{}
"
)
String
jsonFilter
)
{
_logger
.
info
(
"Filtering by: "
+
jsonFilter
);
ObjectMapper
mapper
=
new
ObjectMapper
();
...
...
@@ -75,6 +103,9 @@ public class FilterController extends BaseController {
jsonTree
=
mapper
.
readTree
(
jsonFilter
);
_logger
.
debug
(
jsonTree
.
toString
());
model
.
addAttribute
(
"jsonString"
,
jsonTree
.
toString
());
model
.
addAttribute
(
"jsonFilter"
,
jsonTree
);
Iterator
<
Entry
<
String
,
JsonNode
>>
fields
=
jsonTree
.
fields
();
while
(
fields
.
hasNext
())
{
Entry
<
String
,
JsonNode
>
entry
=
fields
.
next
();
...
...
@@ -87,7 +118,6 @@ public class FilterController extends BaseController {
Page
<
Accession
>
accessions
=
filterService
.
listAccessions
(
jsonTree
,
new
PageRequest
(
page
-
1
,
50
,
new
Sort
(
"ACC_Numb_HI"
)));
_logger
.
info
(
"Got: "
+
accessions
);
model
.
addAttribute
(
"filter"
,
jsonTree
.
toString
());
model
.
addAttribute
(
"pagedData"
,
accessions
);
model
.
addAttribute
(
"selection"
,
selectionBean
);
...
...
src/main/resources/content/language.properties
View file @
3dec5ce0
...
...
@@ -179,10 +179,18 @@ selection.empty-list-warning=You have not added any accessions to the list.
selection.add-many
=
Check and add
selection.add-many.accessionIds
=
List accession IDs as used in Genesys separated by space or new line.
filters.page.title
=
Data filters
filters.view
=
Current filters
filter.taxonomy
=
Taxonomy
filter.crop
=
Crop
filter.countryOfOrigin
=
Country of Origin
filter.holdingInstitute
=
Holding Institute
filter.origin
=
Country of Origin
filter.institute
=
Holding Institute
filter.lat
=
Latitude
filter.lon
=
Longitude
filter.alt
=
Altitude
filter.genus
=
Genus
search.page.title
=
Full-text Search
search.no-results
=
No matches found for your query.
...
...
src/main/webapp/WEB-INF/jsp/accession/data.jsp
View file @
3dec5ce0
...
...
@@ -42,14 +42,21 @@
<c:remove
var=
"clazz"
/>
</c:forEach>
</c:if>
<c:if
test=
"
${
jsonFilter
ne
null
}
"
>
<div
class=
"clearfix filter-block"
>
Your data is filtered!
<a
href=
"
<spring:url
value=
"/acn/filter"
><spring:param
name=
"filter"
value=
"
${
jsonFilter
}
"
/></spring:url>
"
>
Modify filter
</a>
</div>
</c:if>
<div
class=
"nav-header"
>
<spring:message
code=
"accessions.number"
arguments=
"
${
pagedData
.
totalElements
}
"
/>
<br
/>
<spring:message
code=
"paged.pageOfPages"
arguments=
"
${
pagedData
.
number
+
1
}
,${pagedData.totalPages}"
/>
<a
href=
"
<spring:url
value=
""
><spring:param
name=
"page"
value=
"
${
pagedData
.
number
eq
0
?
1
:
pagedData
.
number
}
"
/><spring:param
name=
"filter"
value=
"
${
f
ilter
}
"
/></spring:url>
"
>
⇇ Previous
</a>
<a
href=
"
<spring:url
value=
""
><spring:param
name=
"page"
value=
"
${
pagedData
.
number
+
2
}
"
/><spring:param
name=
"filter"
value=
"
${
f
ilter
}
"
/></spring:url>
"
>
Next ⇉
</a>
<a
href=
"
<spring:url
value=
""
><spring:param
name=
"page"
value=
"
${
pagedData
.
number
eq
0
?
1
:
pagedData
.
number
}
"
/><spring:param
name=
"filter"
value=
"
${
jsonF
ilter
}
"
/></spring:url>
"
>
⇇ Previous
</a>
<a
href=
"
<spring:url
value=
""
><spring:param
name=
"page"
value=
"
${
pagedData
.
number
+
2
}
"
/><spring:param
name=
"filter"
value=
"
${
jsonF
ilter
}
"
/></spring:url>
"
>
Next ⇉
</a>
</div>
<table
class=
"accessions"
>
...
...
src/main/webapp/WEB-INF/jsp/filter/index.jsp
0 → 100644
View file @
3dec5ce0
<!DOCTYPE html>
<%@include
file=
"/WEB-INF/jsp/init.jsp"
%>
<html>
<head>
<title><spring:message
code=
"filters.page.title"
/></title>
</head>
<body>
<h1><spring:message
code=
"filters.view"
/></h1>
<c:forEach
items=
"
${
availableFilters
}
"
var=
"filter"
>
<div
class=
"clearfix filter-block"
>
<div
class=
"pull-left filter-name"
><spring:message
code=
"filter.${filter.name}"
/></div>
<div
class=
"clearfix pull-left"
id=
"filter-${filter.name}"
>
<div
class=
"filter-values pull-left"
></div>
<c:choose>
<c:when
test=
"
${
filter
.
type
==
'NUMERIC'
}
"
>
<div
class=
"filter-new pull-left"
>
Min:
<input
class=
"span1"
type=
"text"
/>
Max:
<input
class=
"span1"
type=
"text"
/>
<button>
+
</button></div>
</c:when>
<c:otherwise>
<div
class=
"filter-new pull-left"
><input
class=
"span2"
type=
"text"
/><button>
+
</button></div>
</c:otherwise>
</c:choose>
</div>
</div>
</c:forEach>
<a
id=
"filtersHref"
href=
""
><button>
View!
</button></a>
<div
id=
"filtersJson"
>
${jsonObject}
</div>
<script
type=
"text/javascript"
>
jQuery
(
document
).
ready
(
function
()
{
// alert('${jsonString}');
var
filters
=
$
.
parseJSON
(
'
${jsonString}
'
);
// debugger;
console
.
log
(
"
Filters:
"
+
JSON
.
stringify
(
filters
));
var
FF
=
{
updateValues
:
function
(
id
,
filterName
,
values
)
{
var
c
=
$
(
id
);
c
.
closest
(
"
.clearfix
"
).
attr
(
"
x-filtername
"
,
filterName
)
//alert(c.data("filtername"));
c
.
empty
();
if
(
values
==
null
)
return
;
values
.
forEach
(
function
(
i
,
idx
)
{
console
.
log
(
"
Adding:
"
+
i
);
//debugger;
if
(
$
.
isPlainObject
(
i
))
{
// ranges & ops
var
x
=
"
<div class='filtval complex'><span class='deleteTag close'>×</span>
"
;
if
(
i
[
"
range
"
]
!=
null
)
{
x
+=
"
Between
"
+
i
[
"
range
"
][
0
]
+
"
and
"
+
i
[
"
range
"
][
1
];
}
else
if
(
i
[
"
min
"
]
!=
null
)
{
x
+=
"
More than
"
+
i
[
"
min
"
];
}
else
if
(
i
[
"
max
"
]
!=
null
)
{
x
+=
"
Less than
"
+
i
[
"
max
"
];
}
x
+=
"
</div>
"
;
}
else
{
var
x
=
"
<div class='filtval discrete'><span class='deleteTag close'>×</span>
"
+
i
+
"
</div>
"
;
}
c
.
append
(
x
);
});
},
refreshJson
:
function
(
newFilter
)
{
$
(
"
#filtersJson
"
).
html
(
JSON
.
stringify
(
newFilter
));
$
(
"
#filtersHref
"
).
attr
(
"
href
"
,
"
/acn/f?filter=
"
+
JSON
.
stringify
(
newFilter
));
}
};
[
<c:forEach
items=
"
${
availableFilters
}
"
var=
"filter"
varStatus=
"status"
>
$
{
status
.
index
gt
0
?
'
,
'
:
''
}
"
${filter.name}
"
</c:forEach>
].
forEach
(
function
(
name
)
{
FF
.
updateValues
(
"
#filter-
"
+
name
+
"
.filter-values
"
,
name
,
filters
[
name
]);
});
$
(
"
body
"
).
on
(
"
click
"
,
"
.filter-block .filtval
"
,
function
(
event
)
{
event
.
preventDefault
();
var
idx
=
$
(
this
).
index
();
var
name
=
$
(
this
).
closest
(
"
.clearfix
"
).
attr
(
"
x-filtername
"
);
//debugger;
console
.
log
(
"
Delete!
"
+
idx
+
"
from
"
+
name
);
filters
[
name
].
splice
(
idx
,
1
);
if
(
filters
[
name
].
length
==
0
)
delete
filters
[
name
];
console
.
log
(
filters
[
name
]);
$
(
this
).
remove
();
FF
.
refreshJson
(
filters
);
});
$
(
"
body
"
).
on
(
"
click
"
,
"
.filter-block .filter-new button
"
,
function
(
event
)
{
event
.
preventDefault
();
var
name
=
$
(
this
).
closest
(
"
.clearfix
"
).
attr
(
"
x-filtername
"
);
//debugger;
var
inputs
=
$
(
this
).
parent
().
children
(
"
input
"
);
var
a
=
null
,
b
=
null
;
if
(
inputs
.
length
==
1
)
{
// add 1
a
=
b
=
inputs
[
0
].
value
;
}
else
{
var
a
=
inputs
[
0
].
value
;
var
b
=
inputs
[
1
].
value
;
}
var
r
=
null
;
if
(
a
==
''
&&
b
==
''
)
{
}
else
if
(
a
==
b
)
{
r
=
a
;
}
else
if
(
b
==
''
)
{
r
=
{
"
min
"
:
parseFloat
(
a
)};
if
(
isNaN
(
r
[
"
min
"
]))
r
=
null
;
}
else
if
(
a
==
''
)
{
r
=
{
"
max
"
:
parseFloat
(
b
)};
if
(
isNaN
(
r
[
"
max
"
]))
r
=
null
;
}
else
{
r
=
{
"
range
"
:[
parseFloat
(
a
),
parseFloat
(
b
)]};
if
(
isNaN
(
r
[
"
range
"
][
0
])
||
isNaN
(
r
[
"
range
"
][
1
]))
r
=
null
;
}
console
.
log
(
r
);
if
(
r
!=
null
)
{
if
(
filters
[
name
]
==
null
)
{
filters
[
name
]
=
[
r
];
}
else
{
filters
[
name
][
filters
[
name
].
length
]
=
r
;
}
inputs
[
0
].
value
=
''
;
inputs
[
0
].
focus
();
if
(
inputs
[
1
])
inputs
[
1
].
value
=
''
;
}
console
.
log
(
filters
);
FF
.
refreshJson
(
filters
);
FF
.
updateValues
(
"
#filter-
"
+
name
+
"
.filter-values
"
,
name
,
filters
[
name
]);
});
FF
.
refreshJson
(
filters
);
});
</script>
</body>
</html>
\ No newline at end of file
src/main/webapp/html/css/custom.css
View file @
3dec5ce0
...
...
@@ -362,3 +362,45 @@ tr.acn .sel.picked {
background-image
:
linear-gradient
(
to
bottom
,
#88ba41
,
#88ba41
);
}
.filter-block
{
margin
:
-10px
;
margin-bottom
:
10px
;
background-color
:
#b9dc81
;
padding
:
5px
10px
;
}
.filter-block
.filter-name
{
width
:
20%
;
font-weight
:
bold
;
}
.filter-block
.filter-values
{
}
.filter-block
.filtval
{
float
:
left
;
/* border: solid 1px black; */
margin
:
0
;
margin-right
:
1em
;
margin-bottom
:
5px
;
padding
:
1px
0.5em
;
background-color
:
#FCF8E3
;
border
:
1px
solid
#FBEED5
;
border-radius
:
4px
4px
4px
4px
;
text-shadow
:
0
1px
0
rgba
(
255
,
255
,
255
,
0.5
);
}
.filtval
.close
{
line-height
:
normal
;
font-size
:
12px
;
margin-left
:
1em
;
}
.filter-block
.filter-new
{
overflow
:
auto
;
}
.filter-new
input
{
margin-bottom
:
0
;
padding
:
0
5px
;
}
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