Merge branch 'u4-4972' of https://github.com/AndyButland/Umbraco-CMS into AndyButland-u4-4972
Conflicts: src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.html
This commit is contained in:
@@ -68,6 +68,38 @@ function contentTypeResource($q, $http, umbRequestHelper) {
|
||||
"GetAllowedChildren",
|
||||
[{ contentId: contentId }])),
|
||||
'Failed to retrieve data for content id ' + contentId);
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.contentTypeResource#getContainerConfig
|
||||
* @methodOf umbraco.resources.contentTypeResource
|
||||
*
|
||||
* @description
|
||||
* Returns a JSON structure for configuration of the container content type
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* contentTypeResource.getContainerConfig(1234)
|
||||
* .then(function(config) {
|
||||
* $scope.options = {
|
||||
* pageSize: config.pageSize,
|
||||
* };
|
||||
* });
|
||||
* </pre>
|
||||
* @param {Int} contentId id of the content item to retrive the container config for
|
||||
* @returns {Promise} resourcePromise object.
|
||||
*
|
||||
*/
|
||||
getContainerConfig: function (contentId) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"contentTypeApiBaseUrl",
|
||||
"GetContainerConfig",
|
||||
[{ contentId: contentId }])),
|
||||
'Failed to retrieve container config data for content id ' + contentId);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -35,6 +35,38 @@ function mediaTypeResource($q, $http, umbRequestHelper) {
|
||||
"GetAllowedChildren",
|
||||
[{ contentId: mediaId }])),
|
||||
'Failed to retrieve allowed types for media id ' + mediaId);
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name umbraco.resources.mediaTypeResource#getContainerConfig
|
||||
* @methodOf umbraco.resources.mediaTypeResource
|
||||
*
|
||||
* @description
|
||||
* Returns a JSON structure for configuration of the container content type
|
||||
*
|
||||
* ##usage
|
||||
* <pre>
|
||||
* mediaTypeResource.getContainerConfig(1234)
|
||||
* .then(function(config) {
|
||||
* $scope.options = {
|
||||
* pageSize: config.pageSize,
|
||||
* };
|
||||
* });
|
||||
* </pre>
|
||||
* @param {Int} contentId id of the content item to retrive the container config for
|
||||
* @returns {Promise} resourcePromise object.
|
||||
*
|
||||
*/
|
||||
getContainerConfig: function (contentId) {
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"mediaTypeApiBaseUrl",
|
||||
"GetContainerConfig",
|
||||
[{ contentId: contentId }])),
|
||||
'Failed to retrieve container config data for media id ' + contentId);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -82,6 +82,13 @@
|
||||
color: @black
|
||||
}
|
||||
|
||||
.umb-listview table a.no-sort {
|
||||
cursor: default;
|
||||
}
|
||||
.umb-listview table a.no-sort:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.umb-listview .icon-star {
|
||||
color: @grayLight
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* The controller for the content editor
|
||||
*/
|
||||
function ContentEditController($scope, $routeParams, $q, $timeout, $window, appState, contentResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, treeService, fileManager, formHelper, umbRequestHelper, keyboardService, umbModelMapper, editorState, $http) {
|
||||
function ContentEditController($scope, $rootScope, $routeParams, $q, $timeout, $window, appState, contentResource, entityResource, navigationService, notificationsService, angularHelper, serverValidationManager, contentEditingHelper, treeService, fileManager, formHelper, umbRequestHelper, keyboardService, umbModelMapper, editorState, $http) {
|
||||
|
||||
//setup scope vars
|
||||
$scope.defaultButton = null;
|
||||
@@ -188,6 +188,15 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function resetLastListPageNumber(content) {
|
||||
// We're using rootScope to store the page number for list views, so if returning to the list
|
||||
// we can restore the page. If we've moved on to edit a piece of content that's not the list or it's children
|
||||
// we should remove this so as not to confuse if navigating to a different list
|
||||
if (!content.isChildOfListView && !content.isContainer) {
|
||||
$rootScope.lastListViewPageViewed = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($routeParams.create) {
|
||||
//we are creating so get an empty content item
|
||||
contentResource.getScaffold($routeParams.id, $routeParams.doctype)
|
||||
@@ -198,6 +207,8 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS
|
||||
editorState.set($scope.content);
|
||||
|
||||
configureButtons($scope.content);
|
||||
|
||||
resetLastListPageNumber($scope.content);
|
||||
});
|
||||
}
|
||||
else {
|
||||
@@ -219,6 +230,7 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS
|
||||
|
||||
syncTreeNode($scope.content, data.path, true);
|
||||
|
||||
resetLastListPageNumber($scope.content);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,12 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" ng-show="content.isChildOfListView">
|
||||
<a class="btn" href="#/content/content/edit/{{content.parentId}}">
|
||||
<localize key="buttons_returnToList">Return to list</localize>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="btn-group dropup" ng-if="defaultButton" >
|
||||
<!-- primary button -->
|
||||
<a class="btn btn-success" href="#" ng-click="performAction(defaultButton)" prevent-default>
|
||||
@@ -54,8 +60,9 @@
|
||||
<a class="btn btn-success dropdown-toggle" data-toggle="dropdown" ng-if="subButtons.length > 0">
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="#">Return to list</a>
|
||||
|
||||
<!-- sub buttons -->
|
||||
<ul class="dropdown-menu bottom-up" role="menu" aria-labelledby="dLabel" ng-if="subButtons.length > 0">
|
||||
<li ng-repeat="btn in subButtons">
|
||||
|
||||
@@ -29,46 +29,112 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
|
||||
items: []
|
||||
};
|
||||
|
||||
// Set "default default" options (i.e. those if no container configuration has been saved)
|
||||
$scope.options = {
|
||||
pageSize: 10,
|
||||
pageNumber: 1,
|
||||
filter: '',
|
||||
orderBy: 'UpdateDate',
|
||||
orderDirection: "desc"
|
||||
orderBy: 'updateDate',
|
||||
orderDirection: "desc",
|
||||
allowBulkPublish: true,
|
||||
allowBulkUnpublish: true,
|
||||
allowBulkDelete: true,
|
||||
additionalColumns: [
|
||||
{ alias: 'UpdateDate', header: 'Last edited', localizationKey: 'defaultdialogs_lastEdited' },
|
||||
{ alias: 'Updator', header: 'Last edited', localizationKey: 'content_updatedBy' }
|
||||
]
|
||||
};
|
||||
|
||||
// Retrieve the container configuration for the content type and set options before presenting initial view
|
||||
contentTypeResource.getContainerConfig($routeParams.id)
|
||||
.then(function (config) {
|
||||
if (typeof config.pageSize !== 'undefined') {
|
||||
$scope.options.pageSize = config.pageSize;
|
||||
}
|
||||
if (typeof config.additionalColumns !== 'undefined') {
|
||||
$scope.options.additionalColumns = config.additionalColumns;
|
||||
}
|
||||
if (typeof config.orderBy !== 'undefined') {
|
||||
$scope.options.orderBy = config.orderBy;
|
||||
}
|
||||
if (typeof config.orderDirection !== 'undefined') {
|
||||
$scope.options.orderDirection = config.orderDirection;
|
||||
}
|
||||
if (typeof config.allowBulkPublish !== 'undefined') {
|
||||
$scope.options.allowBulkPublish = config.allowBulkPublish;
|
||||
}
|
||||
if (typeof config.allowBulkUnpublish !== 'undefined') {
|
||||
$scope.options.allowBulkUnpublish = config.allowBulkUnpublish;
|
||||
}
|
||||
if (typeof config.allowBulkDelete !== 'undefined') {
|
||||
$scope.options.allowBulkDelete = config.allowBulkDelete;
|
||||
}
|
||||
|
||||
$scope.initView();
|
||||
});
|
||||
|
||||
$scope.next = function () {
|
||||
if ($scope.options.pageNumber < $scope.listViewResultSet.totalPages) {
|
||||
$scope.options.pageNumber++;
|
||||
$scope.reloadView($scope.contentId);
|
||||
|
||||
saveLastPageNumber();
|
||||
}
|
||||
};
|
||||
|
||||
$scope.goToPage = function (pageNumber) {
|
||||
$scope.options.pageNumber = pageNumber + 1;
|
||||
$scope.reloadView($scope.contentId);
|
||||
|
||||
saveLastPageNumber();
|
||||
};
|
||||
|
||||
$scope.sort = function (field) {
|
||||
$scope.sort = function (field, allow) {
|
||||
if (allow) {
|
||||
$scope.options.orderBy = field;
|
||||
|
||||
$scope.options.orderBy = field;
|
||||
if ($scope.options.orderDirection === "desc") {
|
||||
$scope.options.orderDirection = "asc";
|
||||
} else {
|
||||
$scope.options.orderDirection = "desc";
|
||||
}
|
||||
|
||||
|
||||
if ($scope.options.orderDirection === "desc") {
|
||||
$scope.options.orderDirection = "asc";
|
||||
} else {
|
||||
$scope.options.orderDirection = "desc";
|
||||
$scope.reloadView($scope.contentId);
|
||||
}
|
||||
|
||||
|
||||
$scope.reloadView($scope.contentId);
|
||||
};
|
||||
|
||||
$scope.prev = function () {
|
||||
if ($scope.options.pageNumber > 1) {
|
||||
$scope.options.pageNumber--;
|
||||
$scope.reloadView($scope.contentId);
|
||||
|
||||
saveLastPageNumber();
|
||||
}
|
||||
};
|
||||
|
||||
saveLastPageNumber = function () {
|
||||
// Saves the last page number into rootScope, so we can retrieve it when returning to the list and
|
||||
// re-present the correct page
|
||||
$rootScope.lastListViewPageViewed = {
|
||||
contentId: $scope.contentId,
|
||||
pageNumber: $scope.options.pageNumber
|
||||
};
|
||||
};
|
||||
|
||||
$scope.initView = function () {
|
||||
if ($routeParams.id) {
|
||||
$scope.pagination = new Array(10);
|
||||
$scope.listViewAllowedTypes = contentTypeResource.getAllowedTypes($routeParams.id);
|
||||
|
||||
$scope.contentId = $routeParams.id;
|
||||
$scope.isTrashed = $routeParams.id === "-20" || $routeParams.id === "-21";
|
||||
|
||||
// If we have a last page number saved, go straight to that one
|
||||
if ($rootScope.lastListViewPageViewed && $rootScope.lastListViewPageViewed.contentId == $scope.contentId) {
|
||||
$scope.goToPage($rootScope.lastListViewPageViewed.pageNumber - 1);
|
||||
} else {
|
||||
$scope.reloadView($scope.contentId);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -78,9 +144,8 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
|
||||
|
||||
$scope.reloadView = function (id) {
|
||||
contentResource.getChildren(id, $scope.options).then(function (data) {
|
||||
|
||||
$scope.listViewResultSet = data;
|
||||
$scope.pagination = [];
|
||||
$scope.pagination = [];
|
||||
|
||||
for (var i = $scope.listViewResultSet.totalPages - 1; i >= 0; i--) {
|
||||
$scope.pagination[i] = { index: i, name: i + 1 };
|
||||
@@ -93,6 +158,65 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
|
||||
});
|
||||
};
|
||||
|
||||
$scope.getColumnName = function (index) {
|
||||
return $scope.options.additionalColumns[index].header;
|
||||
};
|
||||
|
||||
$scope.getColumnLocalizationKey = function (index) {
|
||||
return $scope.options.additionalColumns[index].localizationKey;
|
||||
};
|
||||
|
||||
$scope.getPropertyValue = function (alias, result) {
|
||||
|
||||
// Camel-case the alias
|
||||
alias = alias.charAt(0).toLowerCase() + alias.slice(1);
|
||||
|
||||
// First try to pull the value directly from the alias (e.g. updatedBy)
|
||||
var value = result[alias];
|
||||
|
||||
// If this returns an object, look for the name property of that (e.g. owner.name)
|
||||
if (value === Object(value)) {
|
||||
value = value['name'];
|
||||
}
|
||||
|
||||
// If we've got nothing yet, look at a user defined property
|
||||
if (typeof value === 'undefined') {
|
||||
value = $scope.getCustomPropertyValue(alias, result.properties);
|
||||
}
|
||||
|
||||
// If we have a date, format it
|
||||
if (isDate(value)) {
|
||||
value = value.substring(0, value.length - 3);
|
||||
}
|
||||
|
||||
// Return what we've got
|
||||
return value;
|
||||
|
||||
};
|
||||
|
||||
isDate = function (val) {
|
||||
return val.match(/^(\d{4})\-(\d{2})\-(\d{2})\ (\d{2})\:(\d{2})\:(\d{2})$/);
|
||||
};
|
||||
|
||||
$scope.getCustomPropertyValue = function (alias, properties) {
|
||||
var value = '';
|
||||
var index = 0;
|
||||
var foundAlias = false;
|
||||
for (var i = 0; i < properties.length; i++) {
|
||||
if (properties[i].alias == alias) {
|
||||
foundAlias = true;
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
if (foundAlias) {
|
||||
value = properties[index].value;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
|
||||
//assign debounce method to the search to limit the queries
|
||||
$scope.search = _.debounce(function () {
|
||||
$scope.options.pageNumber = 1;
|
||||
@@ -236,16 +360,6 @@ function listViewController($rootScope, $scope, $routeParams, $injector, notific
|
||||
}
|
||||
};
|
||||
|
||||
if ($routeParams.id) {
|
||||
$scope.pagination = new Array(10);
|
||||
$scope.listViewAllowedTypes = contentTypeResource.getAllowedTypes($routeParams.id);
|
||||
$scope.reloadView($routeParams.id);
|
||||
|
||||
$scope.contentId = $routeParams.id;
|
||||
$scope.isTrashed = $routeParams.id === "-20" || $routeParams.id === "-21";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.ListViewController", listViewController);
|
||||
@@ -23,17 +23,17 @@
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="btn-group" ng-show="isAnythingSelected()" ng-if="entityType === 'content' && !isTrashed">
|
||||
<div class="btn-group" ng-show="isAnythingSelected()" ng-if="entityType === 'content' && !isTrashed && options.allowBulkPublish">
|
||||
<a class="btn btn-success" ng-disabled="actionInProgress" ng-click="publish()" prevent-default>
|
||||
<localize key="actions_publish">Publish</localize>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group" ng-show="isAnythingSelected()" ng-if="entityType === 'content' && !isTrashed">
|
||||
<div class="btn-group" ng-show="isAnythingSelected()" ng-if="entityType === 'content' && !isTrashed && options.allowBulkUnpublish">
|
||||
<a class="btn btn-warning" ng-disabled="actionInProgress" ng-click="unpublish()" prevent-default>
|
||||
<localize key="actions_unpublish">Unpublish</localize>
|
||||
</a>
|
||||
</div>
|
||||
<div class="btn-group" ng-show="isAnythingSelected()">
|
||||
<div class="btn-group" ng-show="isAnythingSelected()" ng-if="options.allowBulkDelete">
|
||||
<a class="btn btn-danger" ng-disabled="actionInProgress" ng-click="delete()" prevent-default>
|
||||
<localize key="actions_delete">Delete</localize>
|
||||
</a>
|
||||
@@ -45,16 +45,23 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<td style="width: 35px">
|
||||
<input type="checkbox" ng-click="selectAll($event)" ng-checked="isSelectedAll()"></td>
|
||||
<td><a href="#" ng-click="sort('Name')" prevent-default>
|
||||
<localize key="general_name">Name</localize>
|
||||
<i class="icon-sort"></i></a></td>
|
||||
<td><a href="#" ng-click="sort('UpdateDate')" prevent-default>
|
||||
<localize key="defaultdialogs_lastEdited">Last edited</localize>
|
||||
<i class="icon-sort"></i></a></td>
|
||||
<td><a href="#" ng-click="sort('Owner')" prevent-default>
|
||||
<localize key="content_updatedBy">Updated by</localize>
|
||||
<i class="icon-sort"></i></a></td>
|
||||
<input type="checkbox" ng-click="selectAll($event)" ng-checked="isSelectedAll()">
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" ng-click="sort('Name', true)" prevent-default>
|
||||
<localize key="general_name">Name</localize>
|
||||
<i class="icon-sort"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td ng-repeat="column in options.additionalColumns">
|
||||
<a href="#" ng-click="sort(column.alias, column.allowSorting)" ng-class="{'no-sort':!column.allowSorting}" prevent-default>
|
||||
<localize ng-if="getColumnLocalizationKey($index) !==''" key="{{getColumnLocalizationKey($index)}}">{{getColumnName($index)}}</localize>
|
||||
<span ng-if="getColumnLocalizationKey($index) === ''">{{getColumnName($index)}}</span>
|
||||
<i class="icon-sort"></i>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<form class="pull-right" novalidate>
|
||||
<i class="icon-search"></i>
|
||||
@@ -78,27 +85,23 @@
|
||||
|
||||
<td>
|
||||
<i class="icon {{result.icon}}" ng-class="getIcon(result)"></i>
|
||||
|
||||
<input type="checkbox" ng-model="result.selected">
|
||||
</td>
|
||||
<td>
|
||||
<a ng-class="{inactive: (entityType === 'content' && !result.published) || isTrashed}" href="#/{{entityType}}/{{entityType}}/edit/{{result.id}}">{{result.name}}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{result.updateDate|date:'medium'}}
|
||||
<!--<<span class="label label-success">Publish</span>-->
|
||||
</td>
|
||||
<td>
|
||||
{{result.owner.name}}
|
||||
<!--<span class="label">Admin</span>-->
|
||||
|
||||
<td ng-repeat="column in options.additionalColumns">
|
||||
{{getPropertyValue(column.alias, result)}}
|
||||
</td>
|
||||
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
<tfoot ng-show="pagination.length > 1">
|
||||
<tr>
|
||||
<th colspan="5">
|
||||
<th colspan="{{options.additionalColumns.length + 3}}">
|
||||
<div class="pull-left">
|
||||
</div>
|
||||
<div class="pagination pagination-right">
|
||||
|
||||
Reference in New Issue
Block a user