Fixes grunt watches, Fixes: U4-3138 Examine mgmt dashboard styling is broken, rebuilds the mgmt dashboard in angular

This commit is contained in:
Shannon
2014-09-09 18:53:47 +10:00
parent 549f0555ab
commit eb6326487f
14 changed files with 422 additions and 447 deletions

View File

@@ -193,12 +193,7 @@ module.exports = function (grunt) {
{ dest: '<%= vsdir %>/views', src: '**', expand: true, cwd: '<%= distdir %>/views' },
{ dest: '<%= vsdir %>/preview', src: '**', expand: true, cwd: '<%= distdir %>/preview' }
]
},
vsLibs: {
files: [
{ dest: '<%= vsdir %>/lib', src: '**', expand: true, cwd: '<%= distdir %>/lib' }
]
},
},
packages: {
files: [{ dest: '<%= vsdir %>/../App_Plugins', src : '**', expand: true, cwd: 'src/packages/' }]
}
@@ -347,7 +342,7 @@ module.exports = function (grunt) {
watch:{
css: {
files: '**/*.less',
files: 'src/**/*.less',
tasks: ['watch-less', 'timestamp'],
options: {
livereload: true,
@@ -374,15 +369,17 @@ module.exports = function (grunt) {
tasks:['watch-html','timestamp']
},
packages: {
files: 'src/packages/**/*.*',
tasks: ['watch-packages', 'timestamp'],
},
//SD: Removing package watching, we don't even use these anymore and they should be removed, the more watching we do the slower this gets
//packages: {
// files: 'src/packages/**/*.*',
// tasks: ['watch-packages', 'timestamp'],
//}
docs: {
files: ['src/**/*.js', 'src/*.js'],
tasks: ['docs:api'],
}
//SD: Removing watch docs, this gets run with the normal watching which we do not want
//docs: {
// files: ['src/**/*.js', 'src/*.js'],
// tasks: ['docs:api'],
//}
},

View File

@@ -18,7 +18,6 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
* @param {Array} queryStrings An array of key/value pairs
*/
dictionaryToQueryString: function (queryStrings) {
if (angular.isArray(queryStrings)) {
return _.map(queryStrings, function (item) {
@@ -35,15 +34,13 @@ function umbRequestHelper($http, $q, umbDataFormatter, angularHelper, dialogServ
return encodeURIComponent(key) + "=" + encodeURIComponent(val);
}).join("&");
}
else if (angular.isObject(queryStrings)) {
/*
//if we have a simple object, we can simply map with $.param
//but with the current structure we cant since an array is an object and an object is an array
if(angular.isObject(queryStrings)){
return decodeURIComponent($.param(queryStrings));
}*/
throw "The queryString parameter is not an array of key value pairs";
//this allows for a normal object to be passed in (ie. a dictionary)
return decodeURIComponent($.param(queryStrings));
}
throw "The queryString parameter is not an array or object of key value pairs";
},
/**

View File

@@ -0,0 +1,231 @@
<div id="examineManagement" ng-controller="Umbraco.Dashboard.ExamineMgmtController">
<h3>Examine Management</h3>
<div ng-show="loading">
Loading...
</div>
<h4>Indexers</h4>
<ul ng-hide="loading">
<li class="provider" ng-repeat="indexer in indexerDetails">
<a href="" ng-click="toggle(indexer, 'showProperties')">
{{indexer.name}}
</a>
<ul ng-show="indexer.showProperties">
<li>
<a href="" ng-click="toggle(indexer, 'showTools')">Index info & tools</a>
<div ng-show="indexer.showTools && indexer.isLuceneIndex">
<div>
<br />
<div ng-show="!indexer.isProcessing && (!indexer.processingAttempts || indexer.processingAttempts < 100)" class="btn-group">
<button class="btn btn-warning" ng-click="rebuildIndex(indexer)">Rebuild index</button>
<button class="btn btn-warning" ng-click="optimizeIndex(indexer)" ng-show="indexer.documentCount > 0">Optimize index</button>
</div>
<div ng-show="indexer.isProcessing" class="progress progress-striped active">
<div class="bar" style="width: 100%;"></div>
</div>
<div class="error" ng-show="indexer.processingAttempts >= 100">
The process is taking longer than expected, check the umbraco log to see if there have been any errors during this operation
</div>
</div>
<table class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr>
<th>Documents in index</th>
<td>{{indexer.documentCount}}</td>
</tr>
<tr>
<th>Fields in index</th>
<td>{{indexer.fieldCount}}</td>
</tr>
<tr>
<th>Has deletions?</th>
<td>
<span>{{indexer.deletionCount > 0}}</span>
(<span>{{indexer.deletionCount}}</span>)
</td>
</tr>
<tr>
<th>Optimized?</th>
<td>
<span>{{indexer.isOptimized}}</span>
</td>
</tr>
</table>
</div>
</li>
<li ng-show="indexer.indexCriteria.IncludeNodeTypes.length > 0 || indexer.indexCriteria.ExcludeNodeTypes.length > 0 || indexer.indexCriteria.ParentNodeId">
<a href="" ng-click="toggle(indexer, 'showNodeTypes')">Node types</a>
<table ng-show="indexer.showNodeTypes" class="table table-bordered table-condensed">
<tr ng-show="indexer.indexCriteria.IncludeNodeTypes.length > 0">
<th>Include node types</th>
<td>{{indexer.indexCriteria.IncludeNodeTypes | json}}</td>
</tr>
<tr ng-show="indexer.indexCriteria.ExcludeNodeTypes.length > 0">
<th>Exclude node types</th>
<td>{{indexer.indexCriteria.ExcludeNodeTypes | json}}</td>
</tr>
<tr ng-show="indexer.indexCriteria.ParentNodeId">
<th>Parent node id</th>
<td>{{indexer.indexCriteria.ParentNodeId}}</td>
</tr>
</table>
</li>
<li ng-show="indexer.indexCriteria.StandardFields.length > 0">
<a href="" ng-click="toggle(indexer, 'showSystemFields')">System fields</a>
<table ng-show="indexer.showSystemFields" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<thead>
<tr>
<th>Name</th>
<th>Enable sorting</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="field in indexer.indexCriteria.StandardFields">
<th>{{field.Name}}</th>
<td>{{field.EnableSorting}}</td>
<td>{{field.Type}}</td>
</tr>
</tbody>
</table>
</li>
<li ng-show="indexer.indexCriteria.UserFields.length > 0">
<a href="" ng-click="toggle(indexer, 'showUserFields')">User fields</a>
<table ng-show="indexer.showUserFields" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<thead>
<tr>
<th>Name</th>
<th>Enable sorting</th>
<th>Type</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="field in indexer.indexCriteria.UserFields">
<th>{{field.Name}}</th>
<td>{{field.EnableSorting}}</td>
<td>{{field.Type}}</td>
</tr>
</tbody>
</table>
</li>
<li>
<a href="" ng-click="toggle(indexer, 'showProviderProperties')">Provider properties</a>
<table ng-show="indexer.showProviderProperties" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr ng-repeat="(key, val) in indexer.providerProperties track by $index">
<th>{{key}}</th>
<td>{{val}}</td>
</tr>
</table>
</li>
</ul>
</li>
</ul>
<h4>Searchers</h4>
<ul ng-hide="loading">
<li class="provider" ng-repeat="searcher in searcherDetails">
<a href="" ng-click="toggle(searcher, 'showProperties')">
{{searcher.name}}
</a>
<ul ng-show="searcher.showProperties">
<li class="search-tools">
<a href="" ng-click="toggle(searcher, 'showTools')">Search tools</a>
<div ng-show="searcher.showTools">
<a class="hide" href="" ng-click="closeSearch(searcher)" ng-show="searcher.isSearching">Hide search results</a>
<br />
<form>
<div class="row form-search">
<div class="span8 input-append">
<input type="text" class="search-query" ng-model="searcher.searchText" />
<button type="submit" class="btn btn-info" ng-click="search(searcher)" ng-disabled="searcher.isProcessing">Search</button>
</div>
</div>
<div class="row">
<label for="textSearch" class="radio inline">
<input type="radio" name="searchType" id="textSearch" value="text" ng-model="searcher.searchType" />
Text Search
</label>
<label for="luceneSearch" class="radio inline">
<input type="radio" name="searchType" id="luceneSearch" value="lucene" ng-model="searcher.searchType" />
Lucene Search
</label>
</div>
</form>
<div class="search-results" ng-show="searcher.isSearching">
<div ng-show="indexer.isProcessing" class="progress progress-striped active">
<div class="bar" style="width: 100%;"></div>
</div>
<table ng-hide="searcher.isProcessing" class="table table-bordered table-condensed">
<thead>
<tr>
<th class="score">Score</th>
<th class="id">Id</th>
<th>Values</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="result in searcher.searchResults">
<td>{{result.Score}}</td>
<td>{{result.Id}}</td>
<td>
<span ng-repeat="(key,val) in result.Fields track by $index">
<span class=""><em>{{key}}</em>:</span>
<span class="text-info">{{val}}</span>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</li>
<li>
<a href="" ng-click="toggle(searcher, 'showProviderProperties')">Provider properties</a>
<table ng-show="searcher.showProviderProperties" class="table table-bordered table-condensed">
<caption>&nbsp;</caption>
<tr ng-repeat="(key, val) in searcher.providerProperties track by $index">
<th>{{key}}</th>
<td>{{val}}</td>
</tr>
</table>
</li>
</ul>
</li>
</ul>
</div>

View File

@@ -0,0 +1,144 @@
function examineMgmtController($scope, umbRequestHelper, $log, $http, $q) {
$scope.indexerDetails = [];
$scope.searcherDetails = [];
$scope.loading = true;
function checkProcessing(indexer, checkActionName) {
umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("examineMgmtBaseUrl", checkActionName, { indexerName: indexer.name })),
'Failed to check index processing')
.then(function(data) {
if (data) {
//copy all resulting properties
for (var k in data) {
indexer[k] = data[k];
}
indexer.isProcessing = false;
}
else {
setTimeout(function() {
//don't continue if we've tried 100 times
if (indexer.processingAttempts < 100) {
checkProcessing(indexer, checkActionName);
//add an attempt
indexer.processingAttempts++;
}
else {
//we've exceeded 100 attempts, stop processing
indexer.isProcessing = false;
}
}, 1000);
}
});
}
$scope.search = function (searcher, e) {
if (e && e.keyCode !== 13) {
return;
}
umbRequestHelper.resourcePromise(
$http.get(umbRequestHelper.getApiUrl("examineMgmtBaseUrl", "GetSearchResults", {
searcherName: searcher.name,
query: searcher.searchText,
queryType: searcher.searchType
})),
'Failed to search')
.then(function(searchResults) {
searcher.isSearching = true;
searcher.searchResults = searchResults;
});
}
$scope.toggle = function(provider, propName) {
if (provider[propName] !== undefined) {
provider[propName] = !provider[propName];
}
else {
provider[propName] = true;
}
}
$scope.rebuildIndex = function(indexer) {
if (confirm("This will cause the index to be rebuilt. " +
"Depending on how much content there is in your site this could take a while. " +
"It is not recommended to rebuild an index during times of high website traffic " +
"or when editors are editing content.")) {
indexer.isProcessing = true;
umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("examineMgmtBaseUrl", "PostRebuildIndex", { indexerName: indexer.name })),
'Failed to rebuild index')
.then(function () {
//rebuilding has started, nothing is returned accept a 200 status code.
//lets poll to see if it is done.
setTimeout(function () {
checkProcessing(indexer, "PostCheckRebuildIndex");
}, 1000);
});
}
}
$scope.optimizeIndex = function(indexer) {
if (confirm("This will cause the index to be optimized which will improve its performance. " +
"It is not recommended to optimize an index during times of high website traffic " +
"or when editors are editing content.")) {
indexer.isProcessing = true;
umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper.getApiUrl("examineMgmtBaseUrl", "PostOptimizeIndex", { indexerName: indexer.name })),
'Failed to optimize index')
.then(function () {
//optimizing has started, nothing is returned accept a 200 status code.
//lets poll to see if it is done.
setTimeout(function () {
checkProcessing(indexer, "PostCheckOptimizeIndex");
}, 1000);
});
}
}
$scope.closeSearch = function(searcher) {
searcher.isSearching = true;
}
//go get the data
//combine two promises and execute when they are both done
$q.all([
//get the indexer details
umbRequestHelper.resourcePromise(
$http.get(umbRequestHelper.getApiUrl("examineMgmtBaseUrl", "GetIndexerDetails")),
'Failed to retrieve indexer details')
.then(function(data) {
$scope.indexerDetails = data;
}),
//get the searcher details
umbRequestHelper.resourcePromise(
$http.get(umbRequestHelper.getApiUrl("examineMgmtBaseUrl", "GetSearcherDetails")),
'Failed to retrieve searcher details')
.then(function(data) {
$scope.searcherDetails = data;
for (var s in $scope.searcherDetails) {
$scope.searcherDetails[s].searchType = "text";
}
})
]).then(function () {
//all init loading is complete
$scope.loading = false;
});
}
angular.module("umbraco").controller("Umbraco.Dashboard.ExamineMgmtController", examineMgmtController);