You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ep...@apache.org on 2022/07/08 19:06:56 UTC
[solr] branch branch_9x updated: SOLR-16005: Support add/update/delete field types in Admin UI Schema page (#753)
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 faaeceaa822 SOLR-16005: Support add/update/delete field types in Admin UI Schema page (#753)
faaeceaa822 is described below
commit faaeceaa8225a26a821708175481435a269dabb1
Author: Ahmet Can KEPENEK <ah...@gmail.com>
AuthorDate: Fri Jul 8 22:06:09 2022 +0300
SOLR-16005: Support add/update/delete field types in Admin UI Schema page (#753)
Co-authored-by: Ahmet Can Kepenek <ah...@localhost.localdomain>
---
solr/CHANGES.txt | 3 +
solr/webapp/web/css/angular/schema.css | 31 ++++++-
solr/webapp/web/js/angular/controllers/schema.js | 102 +++++++++++++++++++++++
solr/webapp/web/partials/schema.html | 45 ++++++++--
4 files changed, 175 insertions(+), 6 deletions(-)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 4a7b2631e18..61bf0edfab9 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -13,8 +13,11 @@ New Features
* SOLR-15921: Load jars in <solr-install-dir>/lib/ by default (janhoy)
+* SOLR-16005: Support add/update/delete field types in Admin UI Schema page. (Ahmet Can Kepenek, Eric Pugh)
+
* 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/schema.css b/solr/webapp/web/css/angular/schema.css
index 7fec7f2fb0d..cd5942ce55a 100644
--- a/solr/webapp/web/css/angular/schema.css
+++ b/solr/webapp/web/css/angular/schema.css
@@ -574,9 +574,11 @@ limitations under the License.
#content #schema .actions #addField span { background-image: url( ../../img/ico/document-list.png ); }
#content #schema .actions #addDynamicField span { background-image: url( ../../img/ico/documents-stack.png ); }
#content #schema .actions #addCopyField span { background-image: url( ../../img/ico/document-import.png ); }
+#content #schema .actions #manipulateFieldType span { background-image: url( ../../img/ico/property.png ); }
#content #schema .actions div.action
{
+ display: inline-table;
width: 320px;
background-color: #fff;
border: 1px solid #f0f0f0;
@@ -590,6 +592,10 @@ limitations under the License.
z-index: 2;
}
+#content #schema .actions div.action.field-type {
+ width: 450px;
+}
+
#content #schema .actions p
{
padding-bottom: 8px;
@@ -603,7 +609,15 @@ limitations under the License.
text-align: right;
width: 25%;
}
-
+#content #schema .actions .field-type label
+{
+ width: 30%;
+}
+#content #schema .actions .field-type textarea
+{
+ margin-left: 6px;
+ margin-top: 5px;
+}
#content #schema .actions input,
#content #schema .actions select,
#content #schema .actions .buttons,
@@ -730,3 +744,18 @@ limitations under the License.
opacity: 90;
bottom: -20px;
}
+#content #schema .actions .field-type .help {
+ position: absolute;
+ left: 15px;
+ padding: 6px;
+ width: 340px;
+ z-index: 200;
+ background-color: #FCF0AD;
+ border: 1px solid #f0f0f0;
+}
+
+#content #schema .actions .field-type .help p a {
+ color: #003eff;
+ text-decoration-line: underline;
+ text-decoration-color: #003eff;
+}
diff --git a/solr/webapp/web/js/angular/controllers/schema.js b/solr/webapp/web/js/angular/controllers/schema.js
index 8a80d42979c..3ff0b0e079f 100644
--- a/solr/webapp/web/js/angular/controllers/schema.js
+++ b/solr/webapp/web/js/angular/controllers/schema.js
@@ -92,6 +92,18 @@ solrAdminApp.controller('SchemaController',
};
$scope.refresh();
+ $scope.selectFieldTypeManipulationOption = function() {
+ $scope.fieldTypeObj = $scope.fieldTypeManipulationOption.template;
+ }
+
+ $scope.showHelp = function (id) {
+ if ($scope.helpId && ($scope.helpId === id || id === '')) {
+ delete $scope.helpId;
+ } else {
+ $scope.helpId = id;
+ }
+ };
+
$scope.selectFieldOrType = function() {
$location.search($scope.fieldOrType);
}
@@ -138,6 +150,7 @@ solrAdminApp.controller('SchemaController',
$scope.showAddField = false;
$scope.showAddDynamicField = false;
$scope.showAddCopyField = false;
+ $scope.showManipulateFieldType = false;
}
$scope.toggleAddField = function() {
@@ -289,6 +302,42 @@ solrAdminApp.controller('SchemaController',
}
});
}
+ $scope.toggleManipulateFieldType = function() {
+ if ($scope.showManipulateFieldType) {
+ $scope.hideAll();
+ } else {
+ $scope.hideAll();
+ $scope.showManipulateFieldType = true;
+
+ $scope.adding = "fieldType";
+
+ $scope.fieldTypeObj = ""
+ delete $scope.addErrors;
+ }
+ $scope.fieldTypeManipulationOptions = getFieldTypeManipulationOptions();
+ $scope.fieldTypeManipulationOption = $scope.fieldTypeManipulationOptions[0];
+ $scope.selectFieldTypeManipulationOption();
+ }
+
+ $scope.manipulateFieldType = function() {
+ delete $scope.manipulateFieldTypeErrors;
+ var data = JSON.parse($scope.fieldTypeObj);
+ Schema.post({core: $routeParams.core}, data, function(data) {
+ if (data.errors) {
+ $scope.manipulateFieldTypeErrors = data.errors[0].errorMessages;
+ if (typeof $scope.manipulateFieldTypeErrors === "string") {
+ $scope.manipulateFieldTypeErrors = [$scope.manipulateFieldTypeErrors];
+ }
+ } else {
+ $scope.added = true;
+ $timeout(function() {
+ $scope.showManipulateFieldType = false;
+ $scope.added = false;
+ $scope.refresh();
+ }, 1500);
+ }
+ });
+ }
}
);
@@ -598,6 +647,59 @@ var getTermInfo = function(data) {
return termInfo;
};
+var getFieldTypeManipulationOptions = function() {
+ return [
+ {
+ value: "Add FieldType Template",
+ label: "Add FieldType",
+ template: "{\n" +
+ " \"add-field-type\": {\n" +
+ " \"name\": \"myNewTxtField\",\n" +
+ " \"class\": \"solr.TextField\",\n" +
+ " \"positionIncrementGap\": \"100\",\n" +
+ " \"analyzer\": {\n" +
+ " \"charFilters\": [\n" +
+ " {\n" +
+ " \"class\": \"solr.PatternReplaceCharFilterFactory\",\n" +
+ " \"replacement\": \"$1$1\",\n" +
+ " \"pattern\": \"([a-zA-Z])\\\\\\\\1+\"\n" +
+ " }\n" +
+ " ],\n" +
+ " \"tokenizer\": {\n" +
+ " \"class\": \"solr.WhitespaceTokenizerFactory\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ },
+ {
+ value: "Delete FieldType Template",
+ label: "Delete FieldType",
+ template: "{\n" +
+ " \"delete-field-type\": {\n" +
+ " \"name\": \"myNewTxtField\"\n" +
+ " }\n" +
+ "}"
+ },
+ {
+ value: "Replace FieldType Template",
+ label: "Replace FieldType",
+ template: "{\n" +
+ " \"replace-field-type\": {\n" +
+ " \"name\": \"myNewTxtField\",\n" +
+ " \"class\": \"solr.TextField\",\n" +
+ " \"positionIncrementGap\": \"100\",\n" +
+ " \"analyzer\": {\n" +
+ " \"tokenizer\": {\n" +
+ " \"class\": \"solr.StandardTokenizerFactory\"\n" +
+ " }\n" +
+ " }\n" +
+ " }\n" +
+ "}"
+ }
+ ];
+};
+
var sortedObjectArray = function(list) {
var objarr = [];
for (var i in list) {
diff --git a/solr/webapp/web/partials/schema.html b/solr/webapp/web/partials/schema.html
index e94b6dab47e..9913dbd2f2c 100644
--- a/solr/webapp/web/partials/schema.html
+++ b/solr/webapp/web/partials/schema.html
@@ -23,6 +23,7 @@ limitations under the License.
<button id="addField" class="action" ng-click="toggleAddField()"><span>Add Field</span></button>
<button id="addDynamicField" class="action" ng-click="toggleAddDynamicField()"><span>Add Dynamic Field</span></button>
<button id="addCopyField" class="action" ng-click="toggleAddCopyField()"><span>Add Copy Field</span></button>
+ <button id="manipulateFieldType" class="action" ng-click="toggleManipulateFieldType()"><span>Manipulate Field Type</span></button>
<div class="action add" data-rel="add" ng-show="showAddField" escape-pressed="hideAll()">
@@ -49,7 +50,7 @@ limitations under the License.
indexed
</label>
</p>
-
+
<p class="clearfix">
<label class="checkbox" for="add_uninvertible">
<input type="checkbox" ng-model="newField.uninvertible" id="add_uninvertible" title="Field should be uninvertible, it is generally recomended to use docValues instead." ng-true-value="'true'" ng-false-value="'false'">
@@ -202,8 +203,41 @@ limitations under the License.
</p>
</form>
-
</div>
+ <div class="action add field-type" data-rel="add" ng-show="showManipulateFieldType" escape-pressed="hideAll()">
+ <form>
+ <select id="field_type_manipulation_options"
+ ng-model="fieldTypeManipulationOption"
+ chosen
+ disable-search="true"
+ ng-change="selectFieldTypeManipulationOption()"
+ ng-options="f.value for f in fieldTypeManipulationOptions"></select>
+ <a ng-click="showHelp('fieldTypeManipulationHelp')"><img class="help-ico" src="img/ico/question-white.png"/></a>
+ <div id="sampleDocsHelp" class="help" ng-show="helpId === 'fieldTypeManipulationHelp'">
+ <p>
+ <a target="_blank" href="https://solr.apache.org/guide/solr/latest/indexing-guide/schema-api.html#add-a-new-field-type">Add a New Field Type</a>: The <b>add-field-type</b> command adds a new field type to your schema.
+ </p>
+ <p>
+ <a target="_blank" href="https://solr.apache.org/guide/solr/latest/indexing-guide/schema-api.html#delete-a-field-type">Delete a Field Type</a>: The <b>delete-field-type</b> command removes a field type from your schema.
+ </p>
+ <p>
+ <a target="_blank" href="https://solr.apache.org/guide/solr/latest/indexing-guide/schema-api.html#replace-a-field-type">Replace a Field Type</a>: The <b>replace-field-type</b> command replaces a field type in your schema.
+ </p>
+ </div>
+
+ <p class="clearfix">
+ <textarea rows="20" cols="50" type="text" id="manipulate_field_type" ng-model="fieldTypeObj" focus-when="showManipulateFieldType" placeholder="specify field type operation(add, delete, replace) with field type patterns"></textarea>
+ </p>
+
+ <div ng-repeat="error in manipulateFieldTypeErrors" ng-show="addFieldTypeErrors" class="clearfix note error">
+ <span>{{error}}</span></div>
+ <p class="clearfix buttons">
+ <button type="submit" class="submit" ng-class="{success: added}" ng-click="manipulateFieldType()"><span>{{fieldTypeManipulationOption.label}}</span></button>
+ <button type="reset" class="reset" ng-click="hideAll()"><span>Cancel</span></button>
+ </p>
+
+ </form>
+ </div>
</div>
<div id="data">
@@ -411,15 +445,16 @@ limitations under the License.
</form>
</div>
</dd>
- <dt class="dynamic-field" ng-class="{active: selectedType=='Dynamic Field'}" ng-show="leftbar.dynamicFields">Dynamic Field {{dynamicFields}} / {{dynamicFields.length()}}</dt>
+
+ <dt class="dynamic-field" ng-class="{active: selectedType=='Dynamic Field'}" ng-show="leftbar.dynamicFields">Dynamic Field</dt>
<dd class="dynamic-field" ng-class="{active: selectedType=='Dynamic Field'}" ng-repeat="field in leftbar.dynamicFields"><a href="#/{{core}}/schema?dynamic-field={{field}}">{{field}}</a></dd>
<dt class="type" ng-class="{active: selectedType=='Type'}" ng-show="leftbar.types">Type</dt>
<dd class="type" ng-class="{active: selectedType=='Type'}" ng-repeat="type in leftbar.types"><a href="#/{{core}}/schema?type={{type}}">{{type}}</a></dd>
<dt></dt>
- <dd class="active delete-field" ng-show="isSchemaUpdatable && leftbar.fields &&!showDelete"><button ng-click="toggleDelete()"><span>delete field</span></button></dd>
- <dd class="active delete-field" ng-show="isSchemaUpdatable && leftbar.dynamicFields &&!showDelete"><button ng-click="toggleDelete()"><span>delete dynamic field</span></button></dd>
+ <dd class="active delete-field" ng-show="isSchemaUpdatable && is.field && !showDelete"><button ng-click="toggleDelete()"><span>delete field</span></button></dd>
+ <dd class="active delete-field" ng-show="isSchemaUpdatable && is.dynamicField && !showDelete"><button ng-click="toggleDelete()"><span>delete dynamic field</span></button></dd>
<div class="action delete" ng-show="showDelete">