diff options
author | 2019-10-18 21:33:54 +0200 | |
---|---|---|
committer | 2019-10-18 21:33:54 +0200 | |
commit | 8efe1d0c7adc971e7ff7c2353e5f18e9cf7f5b92 (patch) | |
tree | bfbe185cb965d2693627e75eb76d304ade092ced | |
parent | Move the query documentation to a new page (diff) | |
download | packages-5-8efe1d0c7adc971e7ff7c2353e5f18e9cf7f5b92.tar.gz packages-5-8efe1d0c7adc971e7ff7c2353e5f18e9cf7f5b92.tar.bz2 packages-5-8efe1d0c7adc971e7ff7c2353e5f18e9cf7f5b92.zip |
Add a generator for advanced search queries
So far, advanced search queries can be run by writing them manually.
Now advanced search queries can be composed using a set of predefined
forms. Similar to other advanced search interfaces.
Signed-off-by: Max Magorsch <max@magorsch.de>
-rw-r--r-- | app/assets/javascripts/index/query_generator.js | 93 | ||||
-rw-r--r-- | app/views/index/index.html.erb | 228 |
2 files changed, 156 insertions, 165 deletions
diff --git a/app/assets/javascripts/index/query_generator.js b/app/assets/javascripts/index/query_generator.js new file mode 100644 index 0000000..17cb798 --- /dev/null +++ b/app/assets/javascripts/index/query_generator.js @@ -0,0 +1,93 @@ +function updateDropdown(self) { + getThirdParent(self).querySelector('button > span:first-child').innerHTML = self.innerHTML; +} + +function buildAdvancedQuery(){ + var query = "" + document.querySelectorAll('#search-container > .row').forEach(function(element) { + var term = element.querySelector('.form-control').value; + + if(!term.replace(/\s/g, '').length){ + return; + }else{ + term = parseSearchTerm(term); + } + + var operator = parseOperator(element.querySelector('.pgo-query-operator > span:first-child').innerHTML); + var field = element.querySelector('.pgo-query-field > span:first-child').innerHTML; + + query += operator + field + ":" + term + " "; + }); + document.getElementById('q').value = query; +} + +function parseOperator(operator){ + switch(operator) { + case "should match": + return ""; + case "must match": + return "+"; + case "must not match": + return "-"; + default: + return ""; + } +} + +function parseSearchTerm(term){ + if (/\s/.test(term) && !/^\".*\"$/.test(term)) { + return "\"" + term + "\"" + }else{ + return term + } +} + +function addInput(self){ + var new_input = document.querySelector('#search-container > .row').cloneNode(true); + resetInput(new_input); + document.querySelector('#search-container').append(new_input); + checkDeleteButtons(); + checkAddButtons(); +} + +function resetInput(input) { + input.querySelector('.form-control').value = ''; + input.querySelector('.pgo-query-operator > span:first-child').innerHTML = 'should match'; + input.querySelector('.pgo-query-field > span:first-child').innerHTML = 'name'; +} + +function deleteInput(self){ + getThirdParent(self).removeChild(getSecondParent(self)); + checkDeleteButtons(); + checkAddButtons(); +} + +function checkDeleteButtons(){ + if(document.querySelectorAll('#search-container > .row').length == 1){ + document.querySelectorAll('.pgo-query-delete-btn').forEach(function(element) { + element.style.display = 'none'; + }); + }else{ + document.querySelectorAll('.pgo-query-delete-btn').forEach(function(element) { + element.style.display = 'block'; + }); + } +} + +function checkAddButtons(){ + document.querySelectorAll('.pgo-query-add-btn').forEach(function(element) { + element.style.display = 'none'; + }); + + document.querySelectorAll('.pgo-query-add-btn')[document.querySelectorAll('.pgo-query-add-btn').length - 1].style.display = 'block'; +} + +function getThirdParent(self) { + return self.parentElement.parentElement.parentElement; +} + +function getSecondParent(self) { + return self.parentElement.parentElement; +} + +checkDeleteButtons();
\ No newline at end of file diff --git a/app/views/index/index.html.erb b/app/views/index/index.html.erb index e54eb74..ee2bd7f 100644 --- a/app/views/index/index.html.erb +++ b/app/views/index/index.html.erb @@ -60,181 +60,79 @@ <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> - <h3 class="modal-title" id="searchHelpTitle"><span class="fa fa-info" style="font-size: 15px;"></span> Package Search Syntax</h3> + <h3 class="modal-title" id="searchHelpTitle"><span class="fa fa-info" style="font-size: 15px;"></span> Advanced Search Queries</h3> </div> <div class="modal-body"> - The search can be used to find Gentoo packages. You can search in two different ways: - <ul > - <li>Keywords</li> - <li>Field/Value pairs</li> - </ul> - <h4 style="margin-top:35px;">Keywords</h4> - You can use simple keywords to find packages. For instance, if you search for <i>gentoo-sources</i> you will find the package <i>sys-kernel/gentoo-sources</i>. - When searching for keywords, the - <ul > - <li><b>name</b></li> - <li> and the <b>atom</b> - </ul> - fields are searched for the keyword. - <h4 style="margin-top:35px;">Field/Value pairs</h4> - If you, however, like to run advanced queries, you can use field/value pairs combined with operators. The possible fields and operators are summarized in the following tables. - <table class="table"> - <thead> - <tr> - <th scope="col">Field</th> - <th scope="col">Description</th> - </tr> - </thead> - <tbody> - <tr> - <th scope="row">atom</th> - <td>The unique identifier of a package <br> <i style="padding-left:2em">e.g. sys-kernel/gentoo-sources</i></td> - </tr> - <tr> - <th scope="row">category</th> - <td>The category of a package <br> <i style="padding-left:2em">e.g. sys-kernel</i></td> - </tr> - <tr> - <th scope="row">name</th> - <td>The name of a package <br> <i style="padding-left:2em">e.g. gentoo-sources</i></td> - </tr> - <tr> - <th scope="row">description</th> - <td>The description of a package <br> <i style="padding-left:2em">e.g. A tiling window manager</i> </td> - </tr> - <tr> - <th scope="row">longdescription</th> - <td>The full descripiton of a package <br> <i style="padding-left:2em">e.g. xmonad is a tiling window manager for [...]</i></td> - </tr> - <tr> - <th scope="row">homepage</th> - <td>The homepage of a package <br> <i style="padding-left:2em">e.g. http://xmonad.org</i></td> - </tr> - <tr> - <th scope="row">license</th> - <td>The license of a package <br> <i style="padding-left:2em">e.g. BSD</i></td> - </tr> - <tr> - <th scope="row">Maintainers</th> - <td></td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">maintainers.name</th> - <td>The name of the maintainer <br> <i style="padding-left:2em">e.g. Gentoo Haskell</i></td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">maintainers.description</th> - <td>The description of the maintainers</td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">maintainers.type</th> - <td>The type of maintainter <br> <i style="padding-left:2em">e.g. project</i></td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">maintainers.restrict</th> - <td></td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">maintainers.email</th> - <td>The email of the maintainer <br> <i style="padding-left:2em">e.g. haskell@gentoo.org</i></td> - </tr> - <tr> - <th scope="row">Useflag</th> - <td></td> - </tr> - <tr> - <th scope="row" style="padding-left:1em">global</th> - <td></td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">useflags.global.name</th> - <td>The name of the global useflag <br> <i style="padding-left:2em">e.g. hscolour</i></td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">useflags.global.description</th> - <td>The description of the global useflag <br> <i style="padding-left:2em">e.g. Include coloured haskell sources to [...]</i></td> - </tr> - <tr> - <th scope="row" style="padding-left:1em">local</th> - <td></td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">useflags.local.name</th> - <td>The name of the local useflag</td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">useflags.local.description</th> - <td>The description of the local useflag</td> - </tr> - <tr> - <th scope="row" style="padding-left:1em">use_expand</th> - <td></td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">useflags.use_expand.name</th> - <td>The name of the local use_expand</td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">useflags.use_expand.description</th> - <td>The description of the use_expand</td> - </tr> - <tr> - <th scope="row" style="padding-left:2em">useflags.use_expand.use_expand_prefix</th> - <td>The use_expand prefix <br> <i style="padding-left:2em">e.g. python_targets</i></td> - </tr> - <tr> - <th scope="row">metadata_hash</th> - <td>The hash of the metadata <br> <i style="padding-left:2em">e.g. 5cd76e098f966b4edcd1848866dd9099</i></td> - </tr> - </tbody> - </table> - The following operators can be used to combine multiple field/value pairs: - <table class="table"> - <thead> - <tr> - <th scope="col">Operator</th> - <th scope="col">Description</th> - </tr> - </thead> - <tbody> - <tr> - <th scope="row"></th> - <td>The term <b>should</b> appear (default)</td> - </tr> - <tr> - <th scope="row">+</th> - <td>The term <b>must</b> appear</td> - </tr> - <tr> - <th scope="row">-</th> - <td>The term <b>must not</b> appear</td> - </tr> - <tr> - <th scope="row">"..."</th> - <td>Can be used to <b>group</b> phrases <br> <i style="padding-left:2em">e.g. +description:"window manager"</i></td> - </tr> - </tbody> - </table> + Using the following forms you can compose advanced search queries instead of writing them manually. - <h4>Examples</h4> + <div id="search-container" style="margin-bottom:25px;"> + <div class="row" style="margin-top:25px;"> + <div class="col-lg-2"></div> + <div class="col-lg-8"> + <div class="input-group"> + <div class="input-group-btn"> + <div class="btn-group"> + <button type="button" class="pgo-query-field btn btn-default dropdown-toggle" data-toggle="dropdown"><span>name</span> + <span class="caret"></span></button> + <ul class="dropdown-menu" role="menu"> + <li><a onclick="updateDropdown(this);">name</a></li> + <li><a onclick="updateDropdown(this);">category</a></li> + <li><a onclick="updateDropdown(this);">atom</a></li> + <li><a onclick="updateDropdown(this);">description</a></li> + <li><a onclick="updateDropdown(this);">longdescription</a></li> + <li><a onclick="updateDropdown(this);">license</a></li> + <li class="divider"></li> + <li><a onclick="updateDropdown(this);">maintainers.name</a></li> + <li><a onclick="updateDropdown(this);">maintainers.description</a></li> + <li><a onclick="updateDropdown(this);">maintainers.type</a></li> + <li><a onclick="updateDropdown(this);">maintainers.restrict</a></li> + <li><a onclick="updateDropdown(this);">maintainers.email</a></li> + <li class="divider"></li> + <li><a onclick="updateDropdown(this);">useflags.global.name</a></li> + <li><a onclick="updateDropdown(this);">useflags.global.description</a></li> + <li><a onclick="updateDropdown(this);">useflags.local.name</a></li> + <li><a onclick="updateDropdown(this);">useflags.local.description</a></li> + <li><a onclick="updateDropdown(this);">useflags.use_expand.name</a></li> + <li><a onclick="updateDropdown(this);">useflags.use_expand.description</a></li> + <li><a onclick="updateDropdown(this);">useflags.use_expand.use_expand_prefix</a></li> + <li class="divider"></li> + <li><a onclick="updateDropdown(this);">metadata_hash</a></li> + </ul> + </div> + <div class="btn-group"> + <button type="button" class="pgo-query-operator btn btn-default dropdown-toggle" data-toggle="dropdown"><span>should match</span> + <span class="caret"></span></button> + <ul class="dropdown-menu" role="menu"> + <li><a onclick="updateDropdown(this);">should match</a></li> + <li><a onclick="updateDropdown(this);">must match</a></li> + <li><a onclick="updateDropdown(this);">must not match</a></li> + </ul> + </div> + </div><!-- /btn-group --> + <input type="text" class="form-control" placeholder="e.g. gentoo-sources"> + </div><!-- /input-group --> - <ul> - <li>Find all packages named git: <br><code style="margin-left:2em">+name:git</code></li> - <li>Find all packages in the category sys-kernel: <br><code style="margin-left:2em">+category:sys-kernel</code></li> - <li>Find all packages with a BSD license: <br><code style="margin-left:2em">+license:BSD</code></li> - <li>Find all packages that neither have a BSD license nor a MIT license: <br><code style="margin-left:2em">-license:BSD -license:MIT</code></li> - <li>Find all packages maintained by the Haskell Team: <br><code style="margin-left:2em">+maintainer.email:haskell@gentoo.org</code></li> - <li>Find all packages maintained by the Haskell Team but that aren't in the 'dev-haskell' category: <br><code style="margin-left:2em">+maintainer.email:haskell@gentoo.org -category:dev-haskell</code></li> - <li>Find all packages those description contains 'window manager': <br><code style="margin-left:2em">+description:"window manager"</code></li> - <li>Find all packages that contain the use_expand 'python_targets': <br><code style="margin-left:2em">+useflags.use_expand.use_expand_prefix:python_targets</code></li> - </ul> + </div><!-- /.col-lg-6 --> + <div class="col-lg-2"> + <span class="pgo-query-delete-btn fa fa-trash pull-right" style="font-size: 20px;margin-top:5px;" onclick="deleteInput(this);"></span> + <span class="pgo-query-add-btn fa fa-plus pull-right" style="font-size: 20px;margin-top:5px;" onclick="addInput();"></span> + </div> + + </div><!-- /.row --> + + </div> + + Please refer to <a href="/about/queries">this page</a> for further information on advanced search queries and examples. </div> <div class="modal-footer"> - <button type="button" class="btn btn-primary" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> + <button type="button" class="btn btn-primary" onclick="buildAdvancedQuery();" data-dismiss="modal">Apply</button> </div> </div> </div> </div> +<%= javascript_include_tag 'index/query_generator.js' %> + <%= javascript_include_tag 'index/typeahead.js' %> |