This is an automated email from the ASF dual-hosted git repository. epugh pushed a commit to branch branch_9x in repository https://gitbox.apache.org/repos/asf/solr.git
The following commit(s) were added to refs/heads/branch_9x by this push: new 0f231bdb5eb SOLR-15853 Solr paramset Admin UI implementation (#923) 0f231bdb5eb is described below commit 0f231bdb5ebe2ce08c3aa064d4cca56d0ab0f561 Author: Eric Pugh <ep...@opensourceconnections.com> AuthorDate: Fri Jul 8 10:09:00 2022 -0400 SOLR-15853 Solr paramset Admin UI implementation (#923) Co-authored-by: betulince <btl.inc...@gmail.com> --- solr/CHANGES.txt | 2 + solr/webapp/web/css/angular/menu.css | 1 + solr/webapp/web/css/angular/paramsets.css | 177 +++++++++++++++++++++ solr/webapp/web/img/ico/paramset.png | Bin 0 -> 275 bytes solr/webapp/web/index.html | 4 + solr/webapp/web/js/angular/app.js | 4 + .../webapp/web/js/angular/controllers/paramsets.js | 158 ++++++++++++++++++ solr/webapp/web/js/angular/controllers/query.js | 61 ++++++- solr/webapp/web/js/angular/services.js | 7 + solr/webapp/web/libs/angular-chosen.min.js | 20 --- solr/webapp/web/partials/paramsets.html | 93 +++++++++++ solr/webapp/web/partials/query.html | 9 ++ 12 files changed, 511 insertions(+), 25 deletions(-) diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 0c5799539ef..4a7b2631e18 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -13,6 +13,8 @@ New Features * SOLR-15921: Load jars in <solr-install-dir>/lib/ by default (janhoy) +* SOLR-15853: Admin UI support for managing Paramsets and using in Queries. (Betul Ince, Eric Pugh) + Improvements --------------------- * SOLR-15986: CommitUpdateCommand and SplitIndexCommand can write user commit metadata. (Bruno Roustant) diff --git a/solr/webapp/web/css/angular/menu.css b/solr/webapp/web/css/angular/menu.css index a89e7ca3ec6..47bf5c8458a 100644 --- a/solr/webapp/web/css/angular/menu.css +++ b/solr/webapp/web/css/angular/menu.css @@ -289,6 +289,7 @@ limitations under the License. .sub-menu .stream a { background-image: url( ../../img/ico/node.png ); } .sub-menu .analysis a { background-image: url( ../../img/ico/funnel.png ); } .sub-menu .documents a { background-image: url( ../../img/ico/documents-stack.png ); } +.sub-menu .paramsets a { background-image: url( ../../img/ico/paramset.png ); } .sub-menu .files a { background-image: url( ../../img/ico/folder.png ); } .sub-menu .schema a { background-image: url( ../../img/ico/book-open-text.png ); } .sub-menu .replication a { background-image: url( ../../img/ico/node.png ); } diff --git a/solr/webapp/web/css/angular/paramsets.css b/solr/webapp/web/css/angular/paramsets.css new file mode 100644 index 00000000000..704fe2eae61 --- /dev/null +++ b/solr/webapp/web/css/angular/paramsets.css @@ -0,0 +1,177 @@ +/* + +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#content #paramsets +{ + background-image: url( ../../img/div.gif ); + background-position: 45% 0; + background-repeat: repeat-y; +} + +#content #paramsets #form +{ + float: left; +} + +#content #paramsets #sample-paramset +{ + margin-top: 15px; +} + +#content #paramsets #delete-paramset +{ + margin-top: 5px; + margin-bottom: 5px; +} + + +#content #paramsets #form fieldset legend, #content #paramsets #form .optional.expanded legend { + display: block; + margin-left: 10px; + margin-top: 15px; + padding: 0px 5px; +} + +legend { + display: block; + padding-inline-start: 2px; + padding-inline-end: 2px; + border-width: initial; + border-style: none; + border-color: initial; + border-image: initial; +} + +#content #paramsets #form label +{ + cursor: pointer; + display: block; + margin-top: 5px; +} + +#content #paramsets #form input, +#content #paramsets #form select, +#content #paramsets #form textarea +{ + margin-bottom: 2px; +} + +#content #paramsets #form input, +#content #paramsets #form textarea +{ + margin-bottom: 2px; +} + +#content #paramsets #form #start +{ + float: left; +} + +#content #paramsets #form #rows +{ + float: right; +} + +#content #paramsets #form .checkbox input +{ + margin-bottom: 0; + width: auto; +} + +#content #paramsets #form fieldset, +#content #paramsets #form .optional.expanded +{ + border: 1px solid #fff; + border-top: 1px solid #c0c0c0; + margin-bottom: 5px; +} + +#content #paramsets #form fieldset.common +{ + margin-top: 10px; +} + +#content #paramsets #form fieldset legend, +#content #paramsets #form .optional.expanded legend +{ + display: block; + margin-left: 10px; + padding: 0px 5px; +} + +#content #paramsets #form fieldset legend label +{ + margin-top: 0; +} + +#content #paramsets #form fieldset .fieldset +{ + border-bottom: 1px solid #f0f0f0; + margin-bottom: 5px; + padding-bottom: 10px; +} + +#content #paramsets #form .optional +{ + border: 0; +} + +#content #paramsets #form .optional legend +{ + margin-left: 0; + padding-left: 0; +} + +#content #paramsets #form .optional.expanded .fieldset +{ + display: block; +} + +#content #paramsets #result +{ + float: right; + width: 54%; +} + +#content #paramsets #result #response +{ +} + +#content #paramsets #result #response pre +{ + padding-left: 20px; +} + +.description{ + font-weight: bold; +} + +#content #paramsets .chosen-container +{ + width: 71% !important; +} + +#content #paramsets .chosen-container { + margin-left: 6px; + width: 100%; +} +#content #paramsets .chosen-drop input, +#content #paramsets .chosen-results { + width: 100% !important; +} diff --git a/solr/webapp/web/img/ico/paramset.png b/solr/webapp/web/img/ico/paramset.png new file mode 100644 index 00000000000..7d2f006917c Binary files /dev/null and b/solr/webapp/web/img/ico/paramset.png differ diff --git a/solr/webapp/web/index.html b/solr/webapp/web/index.html index b9f27580193..afffe67f764 100644 --- a/solr/webapp/web/index.html +++ b/solr/webapp/web/index.html @@ -40,6 +40,7 @@ limitations under the License. <link rel="stylesheet" type="text/css" href="css/angular/menu.css?_=${version}"> <link rel="stylesheet" type="text/css" href="css/angular/plugins.css?_=${version}"> <link rel="stylesheet" type="text/css" href="css/angular/documents.css?_=${version}"> + <link rel="stylesheet" type="text/css" href="css/angular/paramsets.css?_=${version}"> <link rel="stylesheet" type="text/css" href="css/angular/query.css?_=${version}"> <link rel="stylesheet" type="text/css" href="css/angular/stream.css?_=${version}"> <link rel="stylesheet" type="text/css" href="css/angular/replication.css?_=${version}"> @@ -85,6 +86,7 @@ limitations under the License. <script src="js/angular/controllers/collection-overview.js?_=${version}"></script> <script src="js/angular/controllers/analysis.js?_=${version}"></script> <script src="js/angular/controllers/documents.js?_=${version}"></script> + <script src="js/angular/controllers/paramsets.js?_=${version}"></script> <script src="js/angular/controllers/files.js?_=${version}"></script> <script src="js/angular/controllers/query.js?_=${version}"></script> <script src="js/angular/controllers/stream.js?_=${version}"></script> @@ -212,6 +214,7 @@ limitations under the License. <li class="overview" ng-show="currentCollection.type === 'alias'" ng-class="{active:page=='alias-overview'}"><a href="#/{{currentCollection.name}}/alias-overview"><span>Overview</span></a></li> <li class="analysis" ng-show="!isMultiDestAlias(currentCollection)" ng-class="{active:page=='analysis'}"><a href="#/{{currentCollection.name}}/analysis"><span>Analysis</span></a></li> <li class="documents" ng-show="!isMultiDestAlias(currentCollection)" ng-class="{active:page=='documents'}"><a href="#/{{currentCollection.name}}/documents"><span>Documents</span></a></li> + <li class="paramsets" ng-show="!isMultiDestAlias(currentCollection)" ng-class="{active:page=='paramsets'}"><a href="#/{{currentCollection.name}}/paramsets"><span>Paramsets</span></a></li> <li class="files" ng-show="!isMultiDestAlias(currentCollection)" ng-class="{active:page=='files'}"><a href="#/{{currentCollection.name}}/files"><span>Files</span></a></li> <li class="query" ng-class="{active:page=='query'}"><a href="#/{{currentCollection.name}}/query"><span>Query</span></a></li> <li class="stream" ng-class="{active:page=='stream'}"><a href="#/{{currentCollection.name}}/stream"><span>Stream</span></a></li> @@ -237,6 +240,7 @@ limitations under the License. <li class="overview" ng-class="{active:page=='overview'}"><a href="#/{{currentCore.name}}/core-overview"><span>Overview</span></a></li> <li ng-hide="isCloudEnabled" class="analysis" ng-class="{active:page=='analysis'}"><a href="#/{{currentCore.name}}/analysis"><span>Analysis</span></a></li> <li ng-hide="isCloudEnabled" class="documents" ng-class="{active:page=='documents'}"><a href="#/{{currentCore.name}}/documents"><span>Documents</span></a></li> + <li ng-hide="isCloudEnabled" class="paramsets" ng-class="{active:page=='paramsets'}"><a href="#/{{currentCore.name}}/paramsets"><span>Paramsets</span></a></li> <li ng-hide="isCloudEnabled" class="files" ng-class="{active:page=='files'}"><a href="#/{{currentCore.name}}/files"><span>Files</span></a></li> <li class="ping" ng-class="{active:page=='ping'}"><a ng-click="ping()"><span>Ping</span><small class="qtime" ng-show="showPing"> (<span>{{pingMS}}ms</span>)</small></a></li> <li class="plugins" ng-class="{active:page=='plugins'}"><a href="#/{{currentCore.name}}/plugins"><span>Plugins / Stats</span></a></li> diff --git a/solr/webapp/web/js/angular/app.js b/solr/webapp/web/js/angular/app.js index d0de77acbee..a8bd2f5eb0e 100644 --- a/solr/webapp/web/js/angular/app.js +++ b/solr/webapp/web/js/angular/app.js @@ -135,6 +135,10 @@ solrAdminApp.config([ templateUrl: 'partials/documents.html', controller: 'DocumentsController' }). + when('/:core/paramsets', { + templateUrl: 'partials/paramsets.html', + controller: 'ParamSetsController' + }). when('/:core/files', { templateUrl: 'partials/files.html', controller: 'FilesController' diff --git a/solr/webapp/web/js/angular/controllers/paramsets.js b/solr/webapp/web/js/angular/controllers/paramsets.js new file mode 100644 index 00000000000..e18870b3ce3 --- /dev/null +++ b/solr/webapp/web/js/angular/controllers/paramsets.js @@ -0,0 +1,158 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ +//helper for formatting JSON and others + +solrAdminApp.controller('ParamSetsController', + function($scope, $location, $routeParams, ParamSet, Constants) { + + $scope.paramsetList = []; + + $scope.resetMenu("paramsets", Constants.IS_COLLECTION_PAGE); + + $scope.sampleAPICommand = { + "set": { + "myQueries": { + "defType": "edismax", + "rows": "5", + "df": "text_all" + } + } + } + + $scope.selectParamset = function() { + $location.search("paramset", $scope.name); + $scope.getParamset($scope.name); + } + + $scope.getParamset = function (paramset) { + $scope.refresh(); + + var params = {}; + params.core = $routeParams.core; + params.wt = "json"; + params.name = paramset; + + ParamSet.get(params, callback, failure); + + /////// + + function callback(success) { + $scope.responseStatus = "success"; + delete success.$promise; + delete success.$resolved; + $scope.response = JSON.stringify(success, null, ' '); + var apiPayload = { + "set": success.response.params + }; + // remove json key that is defined as "", it can't be submitted via the API. + var paramsetName = Object.keys(apiPayload.set)[0]; + delete apiPayload.set[paramsetName][""] + + $scope.paramsetContent = JSON.stringify(apiPayload, null, ' '); + } + + function failure (failure) { + $scope.responseStatus = failure; + } + } + + + $scope.getParamsets = function () { + $scope.refresh(); + + var params = {}; + params.core = $routeParams.core; + params.wt = "json"; + + ParamSet.get(params, callback, failure); + + /////// + + function callback(success) { + $scope.responseStatus = "success"; + delete success.$promise; + delete success.$resolved; + $scope.response = JSON.stringify(success, null, ' '); + $scope.paramsetList = success.response.params ? Object.keys(success.response.params) : []; + } + + function failure (failure) { + $scope.responseStatus = failure; + } + } + + $scope.getParamsets(); + if ($routeParams.paramset){ + $scope.name = $routeParams.paramset; + $scope.getParamset($routeParams.paramset); + } + + $scope.refresh = function () { + $scope.paramsetContent = ""; + $scope.placeholder = JSON.stringify($scope.sampleAPICommand, null, ' '); + }; + $scope.refresh(); + + $scope.submit = function () { + var params = {}; + + params.core = $routeParams.core; + params.wt = "json"; + + ParamSet.submit(params, $scope.paramsetContent, callback, failure); + + /////// + function callback(success) { + $scope.responseStatus = "success"; + delete success.$promise; + delete success.$resolved; + $scope.response = JSON.stringify(success, null, ' '); + $scope.name = null; + $scope.getParamsets(); + } + function failure (failure) { + $scope.responseStatus = failure; + } + } + + $scope.deleteParamset = function () { + var params = {}; + + params.core = $routeParams.core; + params.wt = "json"; + params.name = $scope.name; + + var apiPayload = { + "delete": [$scope.name] + }; + + ParamSet.submit(params, apiPayload, callback, failure); + + /////// + function callback(success) { + $scope.responseStatus = "success"; + delete success.$promise; + delete success.$resolved; + $scope.response = JSON.stringify(success, null, ' '); + $scope.getParamsets(); + } + function failure (failure) { + $scope.responseStatus = failure; + } + } + + }); diff --git a/solr/webapp/web/js/angular/controllers/query.js b/solr/webapp/web/js/angular/controllers/query.js index 5e36cfb73bd..14678d26572 100644 --- a/solr/webapp/web/js/angular/controllers/query.js +++ b/solr/webapp/web/js/angular/controllers/query.js @@ -16,7 +16,7 @@ */ solrAdminApp.controller('QueryController', - function($scope, $route, $routeParams, $location, Query, Constants){ + function($scope, $route, $routeParams, $location, Query, Constants, ParamSet){ $scope.resetMenu("query", Constants.IS_COLLECTION_PAGE); $scope._models = []; @@ -27,6 +27,31 @@ solrAdminApp.controller('QueryController', $scope.val['q.op'] = "OR"; $scope.val['defType'] = ""; $scope.val['indent'] = true; + $scope.useParams = []; + + getParamsets(); + + function getParamsets() { + + var params = {}; + params.core = $routeParams.core; + params.wt = "json"; + + ParamSet.get(params, callback, failure); + + /////// + + function callback(success) { + $scope.responseStatus = "success"; + delete success.$promise; + delete success.$resolved; + $scope.paramsetList = success.response.params ? Object.keys(success.response.params) : []; + } + + function failure (failure) { + $scope.responseStatus = failure; + } + } // get list of ng-models that have a form element function setModels(argTagName){ @@ -68,7 +93,12 @@ solrAdminApp.controller('QueryController', $scope.val[argKey] = argValue; } else if( $scope._models.map(function(field){return field.modelName}).indexOf(argKey) > -1 ) { // parameters that will only be used to generate the admin link - $scope[argKey] = argValue; + if (argKey === 'useParams'){ + $scope[argKey] = argValue.split(",") + } + else { + $scope[argKey] = argValue; + } } else { insertToRawParams(argKey, argValue); } @@ -135,16 +165,13 @@ solrAdminApp.controller('QueryController', return param.indexOf(argParam) === 0; }); } - copy(params, $scope.val); - purgeParams(params, ["q.alt", "qf", "mm", "pf", "ps", "qs", "tie", "bq", "bf"], $scope.val.defType !== "dismax" && $scope.val.defType !== "edismax"); purgeParams(params, ["uf", "pf2", "pf3", "ps2", "ps3", "boost", "stopwords", "lowercaseOperators"], $scope.val.defType !== "edismax"); purgeParams(params, getDependentFields("hl"), $scope.val.hl !== true); purgeParams(params, getDependentFields("facet"), $scope.val.facet !== true); purgeParams(params, ["spatial", "pt", "sfield", "d"], $scope.val.spatial !== true); purgeParams(params, getDependentFields("spellcheck"), $scope.val.spellcheck !== true); - var qt = $scope.qt ? $scope.qt : "/select"; for (var filter in $scope.filters) { @@ -173,17 +200,41 @@ solrAdminApp.controller('QueryController', params.handler = "select"; set("qt", qt); } + + // convert useParams to array to generate nice URL. + if (!Array.isArray($scope.useParams)){ + params.useParams = $scope.useParams.split(","); + } + else { + params.useParams = $scope.useParams; + } + // create rest result url var url = Query.url(params); + // convert useParams back to string + if (Array.isArray($scope.useParams)){ + params.useParams = $scope.useParams.join(","); + } + else { + params.useParams = $scope.useParams; + } + // create admin page url var adminParams = {...params}; delete adminParams.handler; delete adminParams.core + if (!Array.isArray(adminParams.useParams)){ + adminParams.useParams = adminParams.useParams.split(","); + } if( $scope.qt != null ) { adminParams.qt = [$scope.qt]; } if (isPageReload) { + if (!Array.isArray(params.useParams)){ + params.useParams = params.useParams.split(","); + } + Query.query(params, function (data) { $scope.lang = $scope.val['wt']; if (!$scope.lang || $scope.lang === '') { diff --git a/solr/webapp/web/js/angular/services.js b/solr/webapp/web/js/angular/services.js index f8b0b0082bc..1c0b702dbe1 100644 --- a/solr/webapp/web/js/angular/services.js +++ b/solr/webapp/web/js/angular/services.js @@ -126,6 +126,13 @@ solrAdminServices.factory('System', "postCsv": {headers: {'Content-type': 'application/csv'}, method: "POST", params: {handler: '@handler'}} }); }]) +.factory('ParamSet', + ['$resource', function($resource) { + return $resource(':core/config/params/:name', {core: '@core', wt:'json', _:Date.now()}, { + "submit": {headers: {'Content-type': 'application/json'}, method: "POST"}, + "get": {headers: {'Content-type': 'application/json'}, method: "GET"} + }); + }]) .service('FileUpload', function ($http) { this.upload = function(params, file, success, error){ var url = "" + params.core + "/" + params.handler + "?"; diff --git a/solr/webapp/web/libs/angular-chosen.min.js b/solr/webapp/web/libs/angular-chosen.min.js index b7088e2ba9a..0b12c17492b 100644 --- a/solr/webapp/web/libs/angular-chosen.min.js +++ b/solr/webapp/web/libs/angular-chosen.min.js @@ -1,23 +1,3 @@ -/* -The MIT License -Copyright (c) 2013 Localytics http://www.localytics.com -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - /** * angular-chosen-localytics - Angular Chosen directive is an AngularJS Directive that brings the Chosen jQuery in a Angular way * @version v1.9.2 diff --git a/solr/webapp/web/partials/paramsets.html b/solr/webapp/web/partials/paramsets.html new file mode 100644 index 00000000000..1867b35d927 --- /dev/null +++ b/solr/webapp/web/partials/paramsets.html @@ -0,0 +1,93 @@ +<!-- +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +--> + +<div id="paramsets" class="clearfix"> + <div id="form"> + <form> + + <fieldset> + <legend>Select Paramset</legend> + <div id="paramset-name-container"> + + <label for="paramsetName"> + <a rel="help">Paramsets</a> + </label> + <select id="paramsetName" + ng-model="name" + chosen + data-placeholder="Please select..." + ng-change="selectParamset()" + ng-options="item for item in paramsetList"><option value=""></option></select> + + </div> + + <div id="delete-paramset" ng-show="name"> + <button id="delete-paramset" class="warn" ng-click="deleteParamset()">Delete Paramset</button> + <div> + </fieldset> + + <div> + <form> + <label> + <input type="checkbox" + ng-model="switch.showSample"> + Sample Paramset + </label> + </form> + <div ng-switch="switch.showSample"> + <div id="sample-paramset" ng-switch-when="true"> + <pre class="syntax language-json"><code ng-bind-html="placeholder | highlight:'json' | unsafe"></code></pre> + </div> + </div> + + <fieldset> + <legend>Update Paramset(s)</legend> + <div class="fieldset" id="paramsetContent-container"> + <label for="paramset"> + Paramset(s) JSON + </label> + <textarea ng-model="paramsetContent" + name="paramsetContent" + id="paramsetContent" + title="Request Parameters API Payload" + rows="10" + cols="65"></textarea> + <p> + <a href="https://solr.apache.org/guide/solr/latest/configuration-guide/request-parameters-api.html" target="_out">syntax help</a> + </p> + </div> + </fieldset> + + </div> + <button type="submit" ng-click="submit()" id="submit">Submit Updates</button> + </form> + </div> + <div id="result"> + <div id="response" ng-show="response"> + <div> + <span class="description">Status: </span>{{ responseStatus }} + </div> + <div> + <span class="description">Response:</span> + <pre class="syntax language-json"><code ng-bind-html="response | highlight:'json' | unsafe"></code></pre> + </div> + </div> + + </div> +</div> diff --git a/solr/webapp/web/partials/query.html b/solr/webapp/web/partials/query.html index f0544ca2a70..58575eb8b9f 100644 --- a/solr/webapp/web/partials/query.html +++ b/solr/webapp/web/partials/query.html @@ -77,6 +77,15 @@ limitations under the License. </label> <input type="text" ng-model="val['df']" name="df" id="df" value="" title="Default search field"> + <label for="useParams">paramset(s)</label> + <select id="useParams" + ng-model="useParams" + title="The paramsets to apply to the query." + chosen + multiple + data-placeholder="Select paramset(s)..." + ng-options="item for item in paramsetList"><option value=""></option></select> + <label for="wt" title="The writer type (response format)."> <a rel="help">wt</a> </label>