Merge branch 'v8/feature/media-tracking' into v8/dev
# Conflicts: # src/Umbraco.Web.UI/Umbraco/config/lang/en.xml
This commit is contained in:
@@ -1,13 +1,30 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function MediaNodeInfoDirective($timeout, $location, eventsService, userService, dateHelper, editorService, mediaHelper) {
|
||||
function MediaNodeInfoDirective($timeout, $location, eventsService, userService, dateHelper, editorService, mediaHelper, mediaResource, $q) {
|
||||
|
||||
function link(scope, element, attrs, ctrl) {
|
||||
|
||||
var evts = [];
|
||||
|
||||
scope.allowChangeMediaType = false;
|
||||
scope.loading = true;
|
||||
|
||||
scope.changeContentPageNumber = changeContentPageNumber;
|
||||
scope.contentOptions = {};
|
||||
scope.contentOptions.entityType = "DOCUMENT";
|
||||
scope.hasContentReferences = false;
|
||||
|
||||
scope.changeMediaPageNumber = changeMediaPageNumber;
|
||||
scope.mediaOptions = {};
|
||||
scope.mediaOptions.entityType = "MEDIA";
|
||||
scope.hasMediaReferences = false;
|
||||
|
||||
scope.changeMemberPageNumber = changeMemberPageNumber;
|
||||
scope.memberOptions = {};
|
||||
scope.memberOptions.entityType = "MEMBER";
|
||||
scope.hasMemberReferences = false;
|
||||
|
||||
|
||||
function onInit() {
|
||||
|
||||
@@ -94,6 +111,45 @@
|
||||
setMediaExtension();
|
||||
});
|
||||
|
||||
function changeContentPageNumber(pageNumber) {
|
||||
scope.contentOptions.pageNumber = pageNumber;
|
||||
loadContentRelations();
|
||||
}
|
||||
|
||||
function changeMediaPageNumber(pageNumber) {
|
||||
scope.mediaOptions.pageNumber = pageNumber;
|
||||
loadMediaRelations();
|
||||
}
|
||||
|
||||
function changeMemberPageNumber(pageNumber) {
|
||||
scope.memberOptions.pageNumber = pageNumber;
|
||||
loadMemberRelations();
|
||||
}
|
||||
|
||||
function loadContentRelations() {
|
||||
return mediaResource.getPagedReferences(scope.node.id, scope.contentOptions)
|
||||
.then(function (data) {
|
||||
scope.contentReferences = data;
|
||||
scope.hasContentReferences = data.items.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
function loadMediaRelations() {
|
||||
return mediaResource.getPagedReferences(scope.node.id, scope.mediaOptions)
|
||||
.then(function (data) {
|
||||
scope.mediaReferences = data;
|
||||
scope.hasMediaReferences = data.items.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
function loadMemberRelations() {
|
||||
return mediaResource.getPagedReferences(scope.node.id, scope.memberOptions)
|
||||
.then(function (data) {
|
||||
scope.memberReferences = data;
|
||||
scope.hasMemberReferences = data.items.length > 0;
|
||||
});
|
||||
}
|
||||
|
||||
//ensure to unregister from all events!
|
||||
scope.$on('$destroy', function () {
|
||||
for (var e in evts) {
|
||||
@@ -102,6 +158,18 @@
|
||||
});
|
||||
|
||||
onInit();
|
||||
|
||||
// load media type references when the 'info' tab is first activated/switched to
|
||||
evts.push(eventsService.on("app.tabChange", function (event, args) {
|
||||
$timeout(function () {
|
||||
if (args.alias === "umbInfo") {
|
||||
|
||||
$q.all([loadContentRelations(), loadMediaRelations(), loadMemberRelations()]).then(function () {
|
||||
scope.loading = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
var directive = {
|
||||
|
||||
@@ -552,6 +552,36 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) {
|
||||
"Search",
|
||||
args)),
|
||||
'Failed to retrieve media items for search: ' + query);
|
||||
},
|
||||
|
||||
getPagedReferences: function (id, options) {
|
||||
|
||||
var defaults = {
|
||||
pageSize: 25,
|
||||
pageNumber: 1,
|
||||
entityType: "DOCUMENT"
|
||||
};
|
||||
if (options === undefined) {
|
||||
options = {};
|
||||
}
|
||||
//overwrite the defaults if there are any specified
|
||||
angular.extend(defaults, options);
|
||||
//now copy back to the options we will use
|
||||
options = defaults;
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"mediaApiBaseUrl",
|
||||
"GetPagedReferences",
|
||||
{
|
||||
id: id,
|
||||
entityType: options.entityType,
|
||||
pageNumber: options.pageNumber,
|
||||
pageSize: options.pageSize
|
||||
}
|
||||
)),
|
||||
"Failed to retrieve usages for media of id " + id);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -114,6 +114,34 @@ function relationTypeResource($q, $http, umbRequestHelper, umbDataFormatter) {
|
||||
$http.post(umbRequestHelper.getApiUrl("relationTypeApiBaseUrl", "DeleteById", [{ id: id }])),
|
||||
"Failed to delete item " + id
|
||||
);
|
||||
},
|
||||
|
||||
getPagedResults: function (id, options) {
|
||||
|
||||
var defaults = {
|
||||
pageSize: 25,
|
||||
pageNumber: 1
|
||||
};
|
||||
if (options === undefined) {
|
||||
options = {};
|
||||
}
|
||||
//overwrite the defaults if there are any specified
|
||||
angular.extend(defaults, options);
|
||||
//now copy back to the options we will use
|
||||
options = defaults;
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"relationTypeApiBaseUrl",
|
||||
"GetPagedResults",
|
||||
{
|
||||
id: id,
|
||||
pageNumber: options.pageNumber,
|
||||
pageSize: options.pageSize
|
||||
}
|
||||
)),
|
||||
'Failed to get paged relations for id ' + id);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -1,20 +1,25 @@
|
||||
<div class="umb-package-details">
|
||||
<div class="umb-package-details__main-content">
|
||||
<umb-box data-element="node-info-urls">
|
||||
|
||||
<umb-load-indicator ng-if="loading === true"></umb-load-indicator>
|
||||
|
||||
<!-- Main Column -->
|
||||
<div class="umb-package-details__main-content" ng-if="loading === false">
|
||||
|
||||
<!-- Links -->
|
||||
<umb-box data-element="node-info-urls" class="mb4">
|
||||
<umb-box-header title-key="general_links"></umb-box-header>
|
||||
<umb-box-content class="block-form">
|
||||
|
||||
<umb-empty-state
|
||||
ng-if="!nodeUrl"
|
||||
size="small">
|
||||
<umb-empty-state ng-if="!nodeUrl"
|
||||
size="small">
|
||||
<localize key="content_noMediaLink"></localize>
|
||||
</umb-empty-state>
|
||||
|
||||
<ul ng-if="nodeUrl" class="nav nav-stacked" style="margin-bottom: 0;">
|
||||
<li>
|
||||
<a ng-attr-href="{{node.extension !== 'svg' ? nodeUrl : undefined}}" ng-click="node.extension === 'svg' && openSVG()" target="_blank">
|
||||
<i class="icon icon-out"></i>
|
||||
<span>{{nodeFileName}}</span>
|
||||
<i class="icon icon-out"></i>
|
||||
<span>{{nodeFileName}}</span>
|
||||
|
||||
</a>
|
||||
</li>
|
||||
@@ -23,9 +28,132 @@
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
<!-- Media Tracking (NO Items) -->
|
||||
<umb-box ng-if="(hasContentReferences === false) && (hasMediaReferences === false) && (hasMemberReferences === false) && loading === false">
|
||||
<umb-box-header title-key="references_tabName"></umb-box-header>
|
||||
<umb-box-content>
|
||||
<umb-empty-state size="small">
|
||||
This Media item has no references.
|
||||
</umb-empty-state>
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
<!-- Media Tracking (With Items) -->
|
||||
<div ng-if="loading === false">
|
||||
<!-- Content -->
|
||||
<div ng-if="contentReferences.items.length > 0">
|
||||
|
||||
<h5 class="mt0" style="margin-bottom: 20px;">
|
||||
<localize key="references_labelUsedByDocuments">Used in Documents</localize>
|
||||
</h5>
|
||||
|
||||
<div class="umb-table">
|
||||
<div class="umb-table-head">
|
||||
<div class="umb-table-row">
|
||||
<div class="umb-table-cell"></div>
|
||||
<div class="umb-table-cell umb-table__name not-fixed"><localize key="general_name">Name</localize></div>
|
||||
<div class="umb-table-cell"><localize key="content_alias">Alias</localize></div>
|
||||
<div class="umb-table-cell umb-table-cell--nano"><localize key="general_open" style="visibility:hidden;">Open</localize></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="umb-table-body">
|
||||
<div class="umb-table-row" ng-repeat="reference in contentReferences.items">
|
||||
<div class="umb-table-cell"><i class="umb-table-body__icon {{reference.icon}}"></i></div>
|
||||
<div class="umb-table-cell umb-table__name"><span>{{::reference.name}}</span></div>
|
||||
<div class="umb-table-cell"><span title="{{::reference.alias}}">{{::reference.alias}}</span></div>
|
||||
<div class="umb-table-cell umb-table-cell--nano"><a ng-href="#/content/content/edit/{{::reference.id}}"><localize key="general_open">Open</localize></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="flex justify-center">
|
||||
<umb-pagination ng-if="contentReferences.totalPages"
|
||||
page-number="contentReferences.pageNumber"
|
||||
total-pages="contentReferences.totalPages"
|
||||
on-change="changeContentPageNumber(pageNumber)">
|
||||
</umb-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Members -->
|
||||
<div ng-if="memberReferences.items.length > 0">
|
||||
|
||||
<h5 class="mt0" style="margin-bottom: 20px;">
|
||||
<localize key="references_labelUsedByMembers">Used in Members</localize>
|
||||
</h5>
|
||||
|
||||
<div class="umb-table">
|
||||
<div class="umb-table-head">
|
||||
<div class="umb-table-row">
|
||||
<div class="umb-table-cell"></div>
|
||||
<div class="umb-table-cell umb-table__name not-fixed"><localize key="general_name">Name</localize></div>
|
||||
<div class="umb-table-cell"><localize key="content_alias">Alias</localize></div>
|
||||
<div class="umb-table-cell umb-table-cell--nano"><localize key="general_open" style="visibility:hidden;">Open</localize></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="umb-table-body">
|
||||
<div class="umb-table-row" ng-repeat="reference in memberReferences.items">
|
||||
<div class="umb-table-cell"><i class="umb-table-body__icon {{reference.icon}}"></i></div>
|
||||
<div class="umb-table-cell umb-table__name"><span>{{::reference.name}}</span></div>
|
||||
<div class="umb-table-cell"><span title="{{::reference.alias}}">{{::reference.alias}}</span></div>
|
||||
<div class="umb-table-cell umb-table-cell--nano"><a href="#/member/member/edit/{{::reference.key}}"><localize key="general_open">Open</localize></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="flex justify-center">
|
||||
<umb-pagination ng-if="memberReferences.totalPages"
|
||||
page-number="memberReferences.pageNumber"
|
||||
total-pages="memberReferences.totalPages"
|
||||
on-change="changeMemberPageNumber(pageNumber)">
|
||||
</umb-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media -->
|
||||
<div ng-if="mediaReferences.items.length > 0">
|
||||
|
||||
<h5 class="mt0" style="margin-bottom: 20px;">
|
||||
<localize key="references_labelUsedByMedia">Used in Media</localize>
|
||||
</h5>
|
||||
|
||||
<div class="umb-table">
|
||||
<div class="umb-table-head">
|
||||
<div class="umb-table-row">
|
||||
<div class="umb-table-cell"></div>
|
||||
<div class="umb-table-cell umb-table__name not-fixed"><localize key="general_name">Name</localize></div>
|
||||
<div class="umb-table-cell"><localize key="content_alias">Alias</localize></div>
|
||||
<div class="umb-table-cell umb-table-cell--nano"><localize key="general_open" style="visibility:hidden;">Open</localize></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="umb-table-body">
|
||||
<div class="umb-table-row" ng-repeat="reference in mediaReferences.items">
|
||||
<div class="umb-table-cell"><i class="umb-table-body__icon {{reference.icon}}"></i></div>
|
||||
<div class="umb-table-cell umb-table__name"><span>{{::reference.name}}</span></div>
|
||||
<div class="umb-table-cell"><span title="{{::reference.alias}}">{{::reference.alias}}</span></div>
|
||||
<div class="umb-table-cell umb-table-cell--nano"><a href="#/media/media/edit/{{::reference.id}}"><localize key="general_open">Open</localize></a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="flex justify-center">
|
||||
<umb-pagination ng-if="mediaReferences.totalPages"
|
||||
page-number="mediaReferences.pageNumber"
|
||||
total-pages="mediaReferences.totalPages"
|
||||
on-change="changeMediaPageNumber(pageNumber)">
|
||||
</umb-pagination>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-package-details__sidebar">
|
||||
<!-- Sidebar -->
|
||||
<div class="umb-package-details__sidebar" ng-if="loading === false">
|
||||
<!-- General Info -->
|
||||
<umb-box data-element="node-info-general">
|
||||
<umb-box-header title-key="general_general"></umb-box-header>
|
||||
<umb-box-content class="block-form">
|
||||
@@ -39,12 +167,11 @@
|
||||
</umb-control-group>
|
||||
|
||||
<umb-control-group data-element="node-info-media-type" label="@content_mediatype">
|
||||
<umb-node-preview
|
||||
style="max-width: 100%; margin-bottom: 0px;"
|
||||
icon="node.icon"
|
||||
name="node.contentTypeName"
|
||||
allow-open="allowChangeMediaType"
|
||||
on-open="openMediaType(mediaType)">
|
||||
<umb-node-preview style="max-width: 100%; margin-bottom: 0px;"
|
||||
icon="node.icon"
|
||||
name="node.contentTypeName"
|
||||
allow-open="allowChangeMediaType"
|
||||
on-open="openMediaType(mediaType)">
|
||||
</umb-node-preview>
|
||||
</umb-control-group>
|
||||
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
<umb-control-group label="@relationType_parent">
|
||||
<select name="relationType-parent"
|
||||
ng-model="vm.relationType.parentObjectType"
|
||||
class="umb-property-editor umb-dropdown"
|
||||
required>
|
||||
class="umb-property-editor umb-dropdown">
|
||||
<option ng-repeat="objectType in vm.objectTypes" value="{{objectType.id}}">{{objectType.name}}</option>
|
||||
</select>
|
||||
</umb-control-group>
|
||||
@@ -41,8 +40,7 @@
|
||||
<umb-control-group label="@relationType_child">
|
||||
<select name="relationType-child"
|
||||
ng-model="vm.relationType.childObjectType"
|
||||
class="umb-property-editor umb-dropdown"
|
||||
required>
|
||||
class="umb-property-editor umb-dropdown">
|
||||
<option ng-repeat="objectType in vm.objectTypes" value="{{objectType.id}}">{{objectType.name}}</option>
|
||||
</select>
|
||||
</umb-control-group>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* The controller for editing relation types.
|
||||
*/
|
||||
function RelationTypeEditController($scope, $routeParams, relationTypeResource, editorState, navigationService, dateHelper, userService, entityResource, formHelper, contentEditingHelper, localizationService) {
|
||||
function RelationTypeEditController($scope, $routeParams, relationTypeResource, editorState, navigationService, dateHelper, userService, entityResource, formHelper, contentEditingHelper, localizationService, eventsService) {
|
||||
|
||||
var vm = this;
|
||||
|
||||
@@ -25,6 +25,10 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
|
||||
|
||||
function init() {
|
||||
vm.page.loading = true;
|
||||
vm.relationsLoading = true;
|
||||
|
||||
vm.changePageNumber = changePageNumber;
|
||||
vm.options = {};
|
||||
|
||||
var labelKeys = [
|
||||
"relationType_tabRelationType",
|
||||
@@ -49,17 +53,39 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
|
||||
];
|
||||
});
|
||||
|
||||
// load references when the 'relations' tab is first activated/switched to
|
||||
eventsService.on("app.tabChange", function (event, args) {
|
||||
if (args.alias === "relations") {
|
||||
loadRelations();
|
||||
}
|
||||
});
|
||||
|
||||
// Inital page/overview API call of relation type
|
||||
relationTypeResource.getById($routeParams.id)
|
||||
.then(function(data) {
|
||||
.then(function (data) {
|
||||
bindRelationType(data);
|
||||
vm.page.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
function bindRelationType(relationType) {
|
||||
formatDates(relationType.relations);
|
||||
getRelationNames(relationType);
|
||||
function changePageNumber(pageNumber) {
|
||||
vm.options.pageNumber = pageNumber;
|
||||
loadRelations();
|
||||
}
|
||||
|
||||
|
||||
/** Loads in the references one time when content app changed */
|
||||
function loadRelations() {
|
||||
relationTypeResource.getPagedResults($routeParams.id, vm.options)
|
||||
.then(function (data) {
|
||||
formatDates(data.items);
|
||||
vm.relationsLoading = false;
|
||||
vm.relations = data;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function bindRelationType(relationType) {
|
||||
// Convert property value to string, since the umb-radiobutton component at the moment only handle string values.
|
||||
// Sometime later the umb-radiobutton might be able to handle value as boolean.
|
||||
relationType.isBidirectional = (relationType.isBidirectional || false).toString();
|
||||
@@ -74,7 +100,7 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
|
||||
}
|
||||
|
||||
function formatDates(relations) {
|
||||
if(relations) {
|
||||
if (relations) {
|
||||
userService.getCurrentUser().then(function (currentUser) {
|
||||
angular.forEach(relations, function (relation) {
|
||||
relation.timestampFormatted = dateHelper.getLocalDate(relation.createDate, currentUser.locale, 'LLL');
|
||||
@@ -83,41 +109,6 @@ function RelationTypeEditController($scope, $routeParams, relationTypeResource,
|
||||
}
|
||||
}
|
||||
|
||||
function getRelationNames(relationType) {
|
||||
if (relationType.relations) {
|
||||
// can we grab app entity types in one go?
|
||||
if (relationType.parentObjectType === relationType.childObjectType) {
|
||||
// yep, grab the distinct list of parent and child entities
|
||||
var entityIds = _.uniq(_.union(_.pluck(relationType.relations, "parentId"), _.pluck(relationType.relations, "childId")));
|
||||
entityResource.getByIds(entityIds, relationType.parentObjectTypeName).then(function (entities) {
|
||||
updateRelationNames(relationType, entities);
|
||||
});
|
||||
} else {
|
||||
// nope, grab the parent and child entities individually
|
||||
var parentEntityIds = _.uniq(_.pluck(relationType.relations, "parentId"));
|
||||
var childEntityIds = _.uniq(_.pluck(relationType.relations, "childId"));
|
||||
entityResource.getByIds(parentEntityIds, relationType.parentObjectTypeName).then(function (entities) {
|
||||
updateRelationNames(relationType, entities);
|
||||
});
|
||||
entityResource.getByIds(childEntityIds, relationType.childObjectTypeName).then(function (entities) {
|
||||
updateRelationNames(relationType, entities);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateRelationNames(relationType, entities) {
|
||||
var entitiesById = _.indexBy(entities, "id");
|
||||
_.each(relationType.relations, function(relation) {
|
||||
if (entitiesById[relation.parentId]) {
|
||||
relation.parentName = entitiesById[relation.parentId].name;
|
||||
}
|
||||
if (entitiesById[relation.childId]) {
|
||||
relation.childName = entitiesById[relation.childId].name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function saveRelationType() {
|
||||
|
||||
if (formHelper.submitForm({ scope: $scope, statusMessage: "Saving..." })) {
|
||||
|
||||
@@ -1,28 +1,39 @@
|
||||
<umb-box>
|
||||
<umb-load-indicator ng-if="model.relationsLoading"></umb-load-indicator>
|
||||
|
||||
<umb-box ng-if="model.relationsLoading === false">
|
||||
<umb-box-content class="block-form">
|
||||
|
||||
<umb-empty-state size="small" ng-if="model.relationType.relations.length === 0">
|
||||
<umb-empty-state size="small" ng-if="model.relations.totalItems === 0">
|
||||
<localize key="relationType_noRelations">No relations for this relation type.</localize>
|
||||
</umb-empty-state>
|
||||
|
||||
<!-- Relations -->
|
||||
<umb-control-group label="@relationType_relations" ng-if="model.relationType.relations.length > 0">
|
||||
<div>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th><localize key="relationType_parent">Parent</localize></th>
|
||||
<th><localize key="relationType_child">Child</localize></th>
|
||||
<th><localize key="relationType_created">Created</localize></th>
|
||||
<th><localize key="relationType_comment">Comment</localize></th>
|
||||
</tr>
|
||||
<tr ng-repeat="relation in model.relationType.relations">
|
||||
<td>{{relation.parentName}}</td>
|
||||
<td>{{relation.childName}}</td>
|
||||
<td>{{relation.timestampFormatted}}</td>
|
||||
<td>{{relation.comment}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</umb-control-group>
|
||||
<umb-control-group label="@relationType_relations" ng-if="model.relations.items.length > 0">
|
||||
<div>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th><localize key="relationType_parent">Parent</localize></th>
|
||||
<th><localize key="relationType_child">Child</localize></th>
|
||||
<th><localize key="relationType_created">Created</localize></th>
|
||||
<th><localize key="relationType_comment">Comment</localize></th>
|
||||
</tr>
|
||||
<tr ng-repeat="relation in model.relations.items">
|
||||
<td>{{relation.parentName}}</td>
|
||||
<td>{{relation.childName}}</td>
|
||||
<td>{{relation.timestampFormatted}}</td>
|
||||
<td>{{relation.comment}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div class="flex justify-center">
|
||||
<umb-pagination ng-if="model.relations.totalPages"
|
||||
page-number="model.relations.pageNumber"
|
||||
total-pages="model.relations.totalPages"
|
||||
on-change="model.changePageNumber(pageNumber)">
|
||||
</umb-pagination>
|
||||
</div>
|
||||
</umb-control-group>
|
||||
</umb-box-content>
|
||||
</umb-box>
|
||||
|
||||
Reference in New Issue
Block a user