horizon/openstack_dashboard/static/app/core/images/table/images.controller.js

178 lines
5.6 KiB
JavaScript

/**
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
*
* Licensed 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.
*/
(function() {
'use strict';
angular
.module('horizon.app.core.images')
.controller('horizon.app.core.images.table.ImagesController', ImagesTableController);
ImagesTableController.$inject = [
'$q',
'$scope',
'horizon.app.core.images.detailsRoute',
'horizon.app.core.images.events',
'horizon.app.core.images.resourceType',
'horizon.app.core.openstack-service-api.glance',
'horizon.app.core.openstack-service-api.userSession',
'horizon.framework.conf.resource-type-registry.service',
'horizon.framework.util.actions.action-result.service',
'imageVisibilityFilter'
];
/**
* @ngdoc controller
* @name horizon.app.core.images.table.ImagesTableController
*
* @param {Object} $q
* @param {Object} $scope
* @param {String} detailsRoute
* @param {Object} events
* @param {Object} imageResourceType
* @param {Object} glance
* @param {Object} userSession
* @param {Object} typeRegistry
* @param {Object} imageVisibilityFilter
* @description
* Controller for the images table.
* Serves as the focal point for table actions.
*
* @returns {undefined} No return value
*/
function ImagesTableController(
$q,
$scope,
detailsRoute,
events,
imageResourceType,
glance,
userSession,
typeRegistry,
actionResultService,
imageVisibilityFilter
) {
var ctrl = this;
ctrl.detailsRoute = detailsRoute;
ctrl.checked = {};
ctrl.metadataDefs = null;
ctrl.imageResourceType = typeRegistry.getResourceType(imageResourceType);
ctrl.actionResultHandler = actionResultHandler;
typeRegistry.initActions(imageResourceType, $scope);
loadImages();
////////////////////////////////
function loadImages() {
ctrl.images = [];
ctrl.imagesSrc = [];
$q.all(
{
images: glance.getImages(),
session: userSession.get()
}
).then(onInitialized);
}
function onInitialized(d) {
ctrl.imagesSrc.length = 0;
angular.forEach(d.images.data.items, function itemFilter (image) {
//This sets up data expected by the table for display or sorting.
image.filtered_visibility = imageVisibilityFilter(image, d.session.project_id);
ctrl.imagesSrc.push(image);
});
// MetadataDefinitions are only used in expandable rows and are non-critical.
// Defer loading them until critical data is loaded.
applyMetadataDefinitions();
}
function difference(currentList, otherList, key) {
return currentList.filter(filter);
function filter(elem) {
return otherList.filter(function filterDeletedItem(deletedItem) {
return deletedItem === elem[key];
}).length === 0;
}
}
function applyMetadataDefinitions() {
glance.getNamespaces({resource_type: imageResourceType}, true)
.then(function setMetadefs(data) {
ctrl.metadataDefs = data.data.items;
});
}
function actionResultHandler(returnValue) {
return $q.when(returnValue, actionSuccessHandler);
}
function actionSuccessHandler(result) { // eslint-disable-line no-unused-vars
// The action has completed (for whatever "complete" means to that
// action. Notice the view doesn't really need to know the semantics of the
// particular action because the actions return data in a standard form.
// That return includes the id and type of each created, updated, deleted
// and failed item.
//
// This handler is also careful to check the type of each item. This
// is important because actions which create non-images are launched from
// the images page (like create "volume" from image).
var deletedIds, updatedIds, createdIds, failedIds;
if ( result ) {
// Reduce the results to just image ids ignoring other types the action
// may have produced
deletedIds = actionResultService.getIdsOfType(result.deleted, imageResourceType);
updatedIds = actionResultService.getIdsOfType(result.updated, imageResourceType);
createdIds = actionResultService.getIdsOfType(result.created, imageResourceType);
failedIds = actionResultService.getIdsOfType(result.failed, imageResourceType);
// Handle deleted images
if (deletedIds.length) {
ctrl.imagesSrc = difference(ctrl.imagesSrc, deletedIds,'id');
}
// Handle updated and created images
if ( updatedIds.length || createdIds.length ) {
// Ideally, get each created image individually, but
// this is simple and robust for the common use case.
// TODO: If we want more detailed updates, we could do so here.
loadImages();
}
// Handle failed images
if ( failedIds.length ) {
// Do nothing for now
}
} else {
// promise resolved, but no result returned. Because the action didn't
// tell us what happened...reload the displayed images just in case.
loadImages();
}
}
}
})();