mirror of https://github.com/apache/lucene.git
SOLR-7241: Add document tab support to AngularJS adminUI
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1671279 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
024df3e4a0
commit
1aaf420958
|
@ -0,0 +1,118 @@
|
|||
<!--
|
||||
/*
|
||||
* 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="documents" class="clearfix">
|
||||
<div id="form">
|
||||
<form>
|
||||
<label for="qt">
|
||||
<a rel="help">Request-Handler (qt)</a>
|
||||
</label>
|
||||
<input ng-model="handler" type="text" id="qt" value="/update" title="Request handler in solrconfig.xml.">
|
||||
<label for="document-type">
|
||||
<a rel="help">Document Type</a>
|
||||
</label>
|
||||
|
||||
<div><select ng-model="type" id="document-type" ng-change="changeDocumentType()" placeholder="The type of the document field">
|
||||
<!-- TODO: support the Builder -->
|
||||
<option value="csv">CSV</option>
|
||||
<option value="wizard">Document Builder</option>
|
||||
<option value="upload">File Upload</option>
|
||||
<option value="json">JSON</option>
|
||||
<option value="solr">Solr Command (raw XML or JSON)</option>
|
||||
<option value="xml">XML</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="document-container">
|
||||
<div id="wizard" ng-show="type=='wizard'">
|
||||
<div id="wizard-fields">
|
||||
<div><span class="description">Field</span>: <select ng-model="fieldName" id="wiz-field-select" name="wiz-field-select"
|
||||
ng-options="field for field in fields"></select>
|
||||
</div>
|
||||
<div><span id="wiz-field-data"><span class="description">Field Data</span>:</span>
|
||||
<textarea ng-model="fieldData"
|
||||
id="wizard-doc"
|
||||
name="wizard-doc"
|
||||
rows="10"
|
||||
cols="40"
|
||||
placeholder="Enter your field text here and then click 'Add Field' to add the field to the document.">
|
||||
</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div id="wizard-add"><a ng-click="addWizardField()" id="add-field-href"><img border="0" src="./img/ico/plus-button.png"/>Add
|
||||
Field</a></div>
|
||||
</div>
|
||||
<label for="document">
|
||||
<a rel="help">Document(s)</a>
|
||||
</label>
|
||||
<textarea ng-show="type!='upload'" ng-model="document" name="document" id="document" title="The Document" rows="10"
|
||||
cols="70" placeholder="{{placeholder}}"></textarea>
|
||||
|
||||
<div id="file-upload" ng-show="type=='upload'">
|
||||
<input type="file" id="the-file" name="the-file" file-model="fileUpload"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="advanced">
|
||||
<!-- TODO: only show for JSON/XML-->
|
||||
<div id="attribs">
|
||||
<div id="upload-only" ng-show="type=='upload'">
|
||||
<label for="erh-params"><!-- TODO: cleaner way to do this? -->
|
||||
<a rel="help">Extracting Req. Handler Params</a>
|
||||
</label>
|
||||
<input ng-model="literalParams" type="text" id="erh-params" value="&literal.id=change.me"
|
||||
title="Extracting Request Handler Parameters" size="50">
|
||||
</div>
|
||||
<div id="general-attribs">
|
||||
<label for="commitWithin">
|
||||
<a rel="help">Commit Within</a>
|
||||
</label>
|
||||
<input type="text" ng-model="commitWithin" id="commitWithin" value="1000" title="Commit Within (ms)">
|
||||
<label for="overwrite">
|
||||
<a rel="help">Overwrite</a>
|
||||
</label>
|
||||
<input ng-model="overwrite" type="text" id="overwrite" value="true" title="Overwrite">
|
||||
</div>
|
||||
<!-- Boost is json only, since the XML has it embedded -->
|
||||
<div id="json-only" ng-show="type=='json'">
|
||||
<label for="boost">
|
||||
<a rel="help">Boost</a>
|
||||
</label>
|
||||
<input ng-model="boost" type="text" id="boost" value="1.0" title="Document Boost">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" ng-click="submit()" id="submit">Submit Document</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>
|
||||
|
||||
|
|
@ -84,6 +84,9 @@ New Features
|
|||
* SOLR-6637: Solr should have a way to restore a core from a backed up index.
|
||||
(Varun Thacker, noble, shalin)
|
||||
|
||||
* SOLR-7241, SOLR-7263, SOLR-7279: More functionality moving the Admin UI to Angular JS
|
||||
(Upayavira via Erick)
|
||||
|
||||
Bug Fixes
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
|
||||
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 #documents
|
||||
{
|
||||
background-image: url( ../../img/div.gif );
|
||||
background-position: 45% 0;
|
||||
background-repeat: repeat-y;
|
||||
}
|
||||
|
||||
#content #documents #form
|
||||
{
|
||||
float: left;
|
||||
/*width: 21%;*/
|
||||
}
|
||||
|
||||
#content #documents #form label
|
||||
{
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#content #documents #form input,
|
||||
#content #documents #form select,
|
||||
#content #documents #form textarea
|
||||
{
|
||||
margin-bottom: 2px;
|
||||
/*width: 100%;*/
|
||||
}
|
||||
|
||||
#content #documents #form input,
|
||||
#content #documents #form textarea
|
||||
{
|
||||
margin-bottom: 2px;
|
||||
/*width: 98%;*/
|
||||
}
|
||||
|
||||
#content #documents #form #start
|
||||
{
|
||||
float: left;
|
||||
/*width: 45%;*/
|
||||
}
|
||||
|
||||
#content #documents #form #rows
|
||||
{
|
||||
float: right;
|
||||
/* width: 45%;*/
|
||||
}
|
||||
|
||||
#content #documents #form .checkbox input
|
||||
{
|
||||
margin-bottom: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
#content #documents #form fieldset,
|
||||
#content #documents #form .optional.expanded
|
||||
{
|
||||
border: 1px solid #fff;
|
||||
border-top: 1px solid #c0c0c0;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
#content #documents #form fieldset.common
|
||||
{
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#content #documents #form fieldset legend,
|
||||
#content #documents #form .optional.expanded legend
|
||||
{
|
||||
display: block;
|
||||
margin-left: 10px;
|
||||
padding: 0px 5px;
|
||||
}
|
||||
|
||||
#content #documents #form fieldset legend label
|
||||
{
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#content #documents #form fieldset .fieldset
|
||||
{
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin-bottom: 5px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#content #documents #form .optional
|
||||
{
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#content #documents #form .optional legend
|
||||
{
|
||||
margin-left: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
#content #documents #form .optional.expanded .fieldset
|
||||
{
|
||||
display: block;
|
||||
}
|
||||
|
||||
#content #documents #result
|
||||
{
|
||||
float: right;
|
||||
width: 54%;
|
||||
}
|
||||
|
||||
#content #documents #result #url
|
||||
{
|
||||
margin-bottom: 10px;
|
||||
background-image: url( ../../img/ico/ui-address-bar.png );
|
||||
background-position: 5px 50%;
|
||||
border: 1px solid #f0f0f0;
|
||||
box-shadow: 1px 1px 0 #f0f0f0;
|
||||
-moz-box-shadow: 1px 1px 0 #f0f0f0;
|
||||
-webkit-box-shadow: 1px 1px 0 #f0f0f0;
|
||||
color: #c0c0c0;
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
padding: 5px;
|
||||
padding-left: 26px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#content #documents #result #url:focus,
|
||||
#content #documents #result #url:hover
|
||||
{
|
||||
border-color: #c0c0c0;
|
||||
box-shadow: 1px 1px 0 #d8d8d8;
|
||||
-moz-box-shadow: 1px 1px 0 #d8d8d8;
|
||||
-webkit-box-shadow: 1px 1px 0 #d8d8d8;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
#content #documents #result #response
|
||||
{
|
||||
}
|
||||
|
||||
#content #documents #result #response pre
|
||||
{
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.description{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#document-type{
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
#wizard-fields div{
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
#wiz-field-data, #wiz-field-data span{
|
||||
vertical-align: top;
|
||||
}
|
|
@ -35,7 +35,7 @@ limitations under the License.
|
|||
<link rel="stylesheet" type="text/css" href="css/angular/logging.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/menu.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/styles/plugins.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/styles/documents.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/documents.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/angular/query.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/styles/replication.css?_=${version}">
|
||||
<link rel="stylesheet" type="text/css" href="css/styles/schema-browser.css?_=${version}">
|
||||
|
@ -63,6 +63,7 @@ limitations under the License.
|
|||
<script src="js/angular/controllers/java-properties.js"></script>
|
||||
<script src="js/angular/controllers/core-overview.js"></script>
|
||||
<script src="js/angular/controllers/analysis.js"></script>
|
||||
<script src="js/angular/controllers/documents.js"></script>
|
||||
<script src="js/angular/controllers/query.js"></script>
|
||||
|
||||
</head>
|
||||
|
|
|
@ -67,6 +67,10 @@ solrAdminApp.config([
|
|||
templateUrl: 'partials/analysis.html',
|
||||
controller: 'AnalysisController'
|
||||
}).
|
||||
when('/:core/documents', {
|
||||
templateUrl: 'partials/documents.html',
|
||||
controller: 'DocumentsController'
|
||||
}).
|
||||
when('/:core/query', {
|
||||
templateUrl: 'partials/query.html',
|
||||
controller: 'QueryController'
|
||||
|
@ -197,9 +201,23 @@ solrAdminApp.config([
|
|||
|
||||
return {request: started, response: ended, responseError: failed};
|
||||
})
|
||||
|
||||
.config(function($httpProvider) {
|
||||
$httpProvider.interceptors.push("httpInterceptor");
|
||||
})
|
||||
.directive('fileModel', function ($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function(scope, element, attrs) {
|
||||
var model = $parse(attrs.fileModel);
|
||||
var modelSetter = model.assign;
|
||||
|
||||
element.bind('change', function(){
|
||||
scope.$apply(function(){
|
||||
modelSetter(scope, element[0].files[0]);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var solrAdminControllers = angular.module('solrAdminControllers', []);
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
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
|
||||
|
||||
var DOC_PLACEHOLDER = '<doc>\n' +
|
||||
'<field name="id">change.me</field>' +
|
||||
'<field name="title">change.me</field>' +
|
||||
'</doc>';
|
||||
|
||||
var ADD_PLACEHOLDER = '<add>\n' + DOC_PLACEHOLDER + '</add>\n';
|
||||
|
||||
solrAdminApp.controller('DocumentsController',
|
||||
function($scope, $rootScope, $routeParams, $location, Luke, Update, FileUpload) {
|
||||
$scope.resetMenu("documents");
|
||||
|
||||
$scope.refresh = function () {
|
||||
Luke.schema({core: $routeParams.core}, function(data) {
|
||||
//TODO: handle dynamic fields
|
||||
delete data.schema.fields._version_;
|
||||
$scope.fields = Object.keys(data.schema.fields);
|
||||
});
|
||||
$scope.document = "";
|
||||
$scope.handler = "/update";
|
||||
$scope.type = "json";
|
||||
$scope.commitWithin = 1000;
|
||||
$scope.overwrite = true;
|
||||
$scope.boost = "1.0";
|
||||
};
|
||||
|
||||
$scope.refresh();
|
||||
|
||||
$scope.changeDocumentType = function () {
|
||||
$scope.placeholder = "";
|
||||
if ($scope.type == 'json') {
|
||||
$scope.placeholder = '{"id":"change.me","title":"change.me"}';
|
||||
} else if ($scope.type == 'csv') {
|
||||
$scope.placeholder = "id,title\nchange.me,change.me";
|
||||
} else if ($scope.type == 'solr') {
|
||||
$scope.placeholder = ADD_PLACEHOLDER;
|
||||
} else if ($scope.type == 'xml') {
|
||||
$scope.placeholder = DOC_PLACEHOLDER;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.addWizardField = function () {
|
||||
if ($scope.document == "") $scope.document = "{}";
|
||||
var doc = JSON.parse($scope.document);
|
||||
doc[$scope.fieldName] = $scope.fieldData;
|
||||
$scope.document = JSON.stringify(doc, null, '\t');
|
||||
$scope.fieldData = "";
|
||||
};
|
||||
|
||||
$scope.submit = function () {
|
||||
var contentType = "";
|
||||
var postData = "";
|
||||
var params = {};
|
||||
var doingFileUpload = false;
|
||||
|
||||
if ($scope.handler[0] == '/') {
|
||||
params.handler = $scope.handler.substring(1);
|
||||
} else {
|
||||
params.handler = 'update';
|
||||
params.qt = $scope.handler;
|
||||
}
|
||||
|
||||
params.commitWithin = $scope.commitWithin;
|
||||
params.boost = $scope.boost;
|
||||
params.overwrite = $scope.overwrite;
|
||||
params.core = $routeParams.core;
|
||||
params.wt = "json";
|
||||
|
||||
if ($scope.type == "json" || $scope.type == "wizard") {
|
||||
postData = "[" + $scope.document + "]";
|
||||
contentType = "application/json";
|
||||
} else if ($scope.type == "csv") {
|
||||
postData = $scope.document;
|
||||
contentType = "application/csv";
|
||||
} else if ($scope.type == "xml") {
|
||||
postData = "<add>" + $scope.document + "</add>";
|
||||
contentType = "text/xml";
|
||||
} else if ($scope.type == "upload") {
|
||||
doingFileUpload = true;
|
||||
params.raw = $scope.literalParams;
|
||||
} else if ($scope.type == "solr") {
|
||||
postData = $scope.document;
|
||||
if (postData[0] == "<") {
|
||||
contentType = "text/xml";
|
||||
} else if (postData[0] == "{") {
|
||||
contentType = "application/json";
|
||||
} else {
|
||||
alert("Cannot identify content type")
|
||||
}
|
||||
}
|
||||
if (!doingFileUpload) {
|
||||
Update.post(params, postData).then(function (success) {
|
||||
$scope.responseStatus = "success";
|
||||
delete success.$promise;
|
||||
delete success.$resolved;
|
||||
$scope.response = JSON.stringify(success, null, ' ');
|
||||
}).fail(function (failure) {
|
||||
$scope.responseStatus = failure;
|
||||
});
|
||||
} else {
|
||||
var file = $scope.fileUpload;
|
||||
console.log('file is ' + JSON.stringify(file));
|
||||
var uploadUrl = "/fileUpload";
|
||||
FileUpload.upload(params, $scope.fileUpload, function (success) {
|
||||
$scope.responseStatus = "success";
|
||||
$scope.response = JSON.stringify(success, null, ' ');
|
||||
}, function (failure) {
|
||||
$scope.responseStatus = "failure";
|
||||
$scope.response = JSON.stringify(failure, null, ' ');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -77,11 +77,32 @@ solrAdminServices.factory('System',
|
|||
}])
|
||||
.factory('Update',
|
||||
['$resource', function($resource) {
|
||||
return $resource('/solr/:core/update', {core: '@core', wt:'json', _:Date.now()}, {
|
||||
return $resource('/solr/:core/:handler', {core: '@core', wt:'json', _:Date.now(), handler:'/update'}, {
|
||||
"optimize": {params: { optimize: "true"}},
|
||||
"commit": {params: {commit: "true"}}
|
||||
"commit": {params: {commit: "true"}},
|
||||
"post": {method: "POST", params: {handler: '@handler'}}
|
||||
});
|
||||
}])
|
||||
.service('FileUpload', function ($http) {
|
||||
this.upload = function(params, file, success, error){
|
||||
var url = "/solr/" + params.core + "/" + params.handler + "?";
|
||||
raw = params.raw;
|
||||
delete params.core;
|
||||
delete params.handler;
|
||||
delete params.raw;
|
||||
url += $.param(params);
|
||||
if (raw && raw.length>0) {
|
||||
if (raw[0] != "&") raw = "&" + raw;
|
||||
url += raw;
|
||||
}
|
||||
var fd = new FormData();
|
||||
fd.append('file', file);
|
||||
$http.post(url, fd, {
|
||||
transformRequest: angular.identity,
|
||||
headers: {'Content-Type': undefined}
|
||||
}).success(success).error(error);
|
||||
}
|
||||
})
|
||||
.factory('Luke',
|
||||
['$resource', function($resource) {
|
||||
return $resource('/solr/:core/admin/luke', {core: '@core', wt:'json', _:Date.now()}, {
|
||||
|
|
Loading…
Reference in New Issue