kopia lustrzana https://github.com/OpenDroneMap/WebODM
Project tags only search
rodzic
8a51317774
commit
c852f72b20
|
@ -47,7 +47,14 @@ class ProjectFilter(filters.FilterSet):
|
|||
def filter_search(self, qs, name, value):
|
||||
value = value.replace(":", "#")
|
||||
tag_pattern = re.compile("#[^\s]+")
|
||||
tags = re.findall(tag_pattern, value)
|
||||
tags = set(re.findall(tag_pattern, value))
|
||||
|
||||
project_tags = set([t for t in tags if t.startswith("##")])
|
||||
deep_tags = tags - project_tags
|
||||
|
||||
project_tags = [t.replace("##", "") for t in project_tags]
|
||||
deep_tags = [t.replace("#", "") for t in deep_tags]
|
||||
|
||||
names = re.sub("\s+", " ", re.sub(tag_pattern, "", value)).strip()
|
||||
|
||||
if len(names) > 0:
|
||||
|
@ -56,13 +63,20 @@ class ProjectFilter(filters.FilterSet):
|
|||
name_query = SearchQuery(names, search_type="plain")
|
||||
qs = qs.annotate(n_search=project_name_vec + task_name_vec).filter(n_search=name_query)
|
||||
|
||||
if len(tags) > 0:
|
||||
if len(deep_tags) > 0:
|
||||
project_tags_vec = SearchVector("tags")
|
||||
task_tags_vec = SearchVector(StringAgg("task__tags", delimiter=' '))
|
||||
tags_query = SearchQuery(tags[0])
|
||||
for t in tags[1:]:
|
||||
tags_query = SearchQuery(deep_tags[0])
|
||||
for t in deep_tags[1:]:
|
||||
tags_query = tags_query & SearchQuery(t)
|
||||
qs = qs.annotate(t_search=project_tags_vec + task_tags_vec).filter(t_search=tags_query)
|
||||
qs = qs.annotate(dt_search=project_tags_vec + task_tags_vec).filter(dt_search=tags_query)
|
||||
|
||||
if len(project_tags) > 0:
|
||||
project_tags_vec = SearchVector("tags")
|
||||
tags_query = SearchQuery(project_tags[0])
|
||||
for t in project_tags[1:]:
|
||||
tags_query = tags_query & SearchQuery(t)
|
||||
qs = qs.annotate(pt_search=project_tags_vec).filter(pt_search=tags_query)
|
||||
|
||||
return qs.distinct()
|
||||
|
||||
|
|
|
@ -41,9 +41,11 @@ class Paginator extends React.Component {
|
|||
this.searchButton.addEventListener("click", this.toggleSearch);
|
||||
this.btnSearch.addEventListener("click", this.search);
|
||||
document.body.addEventListener("click", this.closeSearch);
|
||||
document.addEventListener("onProjectListTagClicked", this.addTagAndSearch);
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
document.removeEventListener("onProjectListTagClicked", this.addTagAndSearch);
|
||||
document.body.removeEventListener("click", this.closeSearch);
|
||||
this.btnSearch.removeEventListener("click", this.search);
|
||||
this.searchButton.removeEventListener("click", this.toggleSearch);
|
||||
|
@ -100,6 +102,20 @@ class Paginator extends React.Component {
|
|||
});
|
||||
}
|
||||
|
||||
addTagAndSearch = e => {
|
||||
const tag = e.detail;
|
||||
if (tag === undefined) return;
|
||||
|
||||
let { searchText } = this.state;
|
||||
if (searchText === "") searchText += "##" + tag;
|
||||
else searchText += " ##" + tag;
|
||||
|
||||
this.setState({searchText});
|
||||
setTimeout(() => {
|
||||
this.search();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { itemsPerPage, totalItems, currentPage } = this.props;
|
||||
const { searchText } = this.state;
|
||||
|
@ -125,7 +141,6 @@ class Paginator extends React.Component {
|
|||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="javascript:void(0);"><i className="fa fa-filter" title={_("Filter")}></i></a></li>
|
||||
<li className="btn-group">
|
||||
<a href="javascript:void(0);" className="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><i className="fa fa-sort-alpha-down" title={_("Sort")}></i></a>
|
||||
<SortPanel selected={this.state.sortKey} items={this.sortItems} onChange={this.sortChanged} />
|
||||
|
|
|
@ -491,6 +491,13 @@ class ProjectListItem extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
handleTagClick = tag => {
|
||||
return e => {
|
||||
const evt = new CustomEvent("onProjectListTagClicked", { detail: tag });
|
||||
document.dispatchEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { refreshing, data } = this.state;
|
||||
const numTasks = data.tasks.length;
|
||||
|
@ -555,7 +562,7 @@ class ProjectListItem extends React.Component {
|
|||
<div className="project-name">
|
||||
{data.name}
|
||||
{userTags.length > 0 ?
|
||||
userTags.map((t, i) => <div key={i} className="tag-badge small-badge">{t}</div>)
|
||||
userTags.map((t, i) => <div key={i} className="tag-badge small-badge" onClick={this.handleTagClick(t)}>{t}</div>)
|
||||
: ""}
|
||||
</div>
|
||||
<div className="project-description">
|
||||
|
|
|
@ -119,5 +119,8 @@
|
|||
font-size: 90%;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
&:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue