diff --git a/src/app/frontend/common/components/actionbar/actionbar_module.js b/src/app/frontend/common/components/actionbar/actionbar_module.js index f566afaea407847c32df04dd3b1e756176470cce..225bd7ff9088845adf66ebcfb5de5fa224a8f774 100644 --- a/src/app/frontend/common/components/actionbar/actionbar_module.js +++ b/src/app/frontend/common/components/actionbar/actionbar_module.js @@ -13,7 +13,11 @@ // limitations under the License. import {actionbarComponent} from './actionbar_component'; +import {actionbarDeleteItemComponent} from './actionbardeleteitem_component'; import {breadcrumbsComponent} from './../breadcrumbs/breadcrumbs_component'; +import {BreadcrumbsService} from './../breadcrumbs/breadcrumbs_service'; +import resourceModule from 'common/resource/resource_module'; + /** * Module containing common actionbar. */ @@ -23,6 +27,9 @@ export default angular [ 'ngMaterial', 'ui.router', + resourceModule.name, ]) .component('kdActionbar', actionbarComponent) - .component('kdBreadcrumbs', breadcrumbsComponent); + .component('kdBreadcrumbs', breadcrumbsComponent) + .component('kdActionbarDeleteItem', actionbarDeleteItemComponent) + .service('kdBreadcrumbsService', BreadcrumbsService); diff --git a/src/app/frontend/common/components/actionbar/actionbardeleteitem.html b/src/app/frontend/common/components/actionbar/actionbardeleteitem.html new file mode 100644 index 0000000000000000000000000000000000000000..f993c34316fea4c98ac25bebe02a8b4e055bea33 --- /dev/null +++ b/src/app/frontend/common/components/actionbar/actionbardeleteitem.html @@ -0,0 +1,21 @@ + + + + delete + Delete {{::$ctrl.resourceKindName}} + diff --git a/src/app/frontend/common/components/actionbar/actionbardeleteitem_component.js b/src/app/frontend/common/components/actionbar/actionbardeleteitem_component.js new file mode 100644 index 0000000000000000000000000000000000000000..80007ba65532c76e578e23f06bb4a7ea3ccb4089 --- /dev/null +++ b/src/app/frontend/common/components/actionbar/actionbardeleteitem_component.js @@ -0,0 +1,82 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// 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. + +/** + * Controller for the action bar delete item component. It adds option to delete item from + * details page action bar. + * + * @final + */ +export class ActionbarDeleteItemController { + /** + * @param {!./../../resource/verber_service.VerberService} kdResourceVerberService + * @param {!./../breadcrumbs/breadcrumbs_service.BreadcrumbsService} kdBreadcrumbsService + * @param {!ui.router.$state} $state + * @ngInject + */ + constructor(kdResourceVerberService, kdBreadcrumbsService, $state) { + /** @export {string} Initialized from a binding. */ + this.resourceKindName; + + /** @export {!backendApi.TypeMeta} Initialized from a binding. */ + this.typeMeta; + + /** @export {!backendApi.ObjectMeta} Initialized from a binding. */ + this.objectMeta; + + /** @export {boolean} Initialized from a binding. */ + this.buttonClasses; + + /** @private {!./../../resource/verber_service.VerberService} */ + this.kdResourceVerberService_ = kdResourceVerberService; + + /** @private {!./../breadcrumbs/breadcrumbs_service.BreadcrumbsService} */ + this.kdBreadcrumbsService_ = kdBreadcrumbsService; + + /** @private {!ui.router.$state}} */ + this.state_ = $state; + } + + /** + * @export + */ + remove() { + this.kdResourceVerberService_ + .showDeleteDialog(this.resourceKindName, this.typeMeta, this.objectMeta) + .then(() => { + let parentStateName = + this.kdBreadcrumbsService_.getParentStateName(this.state_['$current']); + this.state_.go(parentStateName); + }); + } +} + +/** + * Action bar delete item component should be used only on resource details page in order to + * add button that allows deletion of this resource. + * + * @type {!angular.Component} + */ +export const actionbarDeleteItemComponent = { + templateUrl: 'common/components/actionbar/actionbardeleteitem.html', + bindings: { + 'resourceKindName': '@', + 'typeMeta': '<', + 'objectMeta': '<', + 'buttonClasses': '@', + }, + bindToController: true, + replace: true, + controller: ActionbarDeleteItemController, +}; diff --git a/src/app/frontend/common/components/breadcrumbs/breadcrumbs_component.js b/src/app/frontend/common/components/breadcrumbs/breadcrumbs_component.js index 7e540e3cd78ab64866bdd7db47d8ee3acd2fee32..837f9e2cdf6f23e99375023956797da6ce2326f8 100644 --- a/src/app/frontend/common/components/breadcrumbs/breadcrumbs_component.js +++ b/src/app/frontend/common/components/breadcrumbs/breadcrumbs_component.js @@ -14,9 +14,6 @@ import Breadcrumb from './breadcrumb'; -/** Breadcrumbs config string used on state config. **/ -export const breadcrumbsConfig = 'kdBreadcrumbs'; - /** * @final */ @@ -26,9 +23,10 @@ export default class BreadcrumbsController { * * @param {!ui.router.$state} $state * @param {!angular.$interpolate} $interpolate + * @param {!./../breadcrumbs/breadcrumbs_service.BreadcrumbsService} kdBreadcrumbsService * @ngInject */ - constructor($state, $interpolate) { + constructor($state, $interpolate, kdBreadcrumbsService) { /** @private {!ui.router.$state} */ this.state_ = $state; @@ -40,6 +38,9 @@ export default class BreadcrumbsController { /** @export {!Array} - Initialized in $onInit method. Used in template */ this.breadcrumbs; + + /** @private {!./breadcrumbs_service.BreadcrumbsService} */ + this.kdBreadcrumbsService_ = kdBreadcrumbsService; } /** @@ -67,7 +68,7 @@ export default class BreadcrumbsController { breadcrumbs.push(breadcrumb); } - state = this.getParentState_(state); + state = this.kdBreadcrumbsService_.getParentState(state); } return breadcrumbs.reverse(); @@ -85,42 +86,6 @@ export default class BreadcrumbsController { return this.limit === undefined || this.limit > breadcrumbs.length; } - /** - * Returns breadcrumb config object if it is defined on state, undefined otherwise. - * - * @param {!ui.router.$state} state - * @return {Object} - * @private - */ - getBreadcrumbConfig_(state) { - let conf = state['data']; - - if (conf) { - conf = conf[breadcrumbsConfig]; - } - - return conf; - } - - /** - * Returns parent state of the given state based on defined state parent name or if it is not - * defined then based on direct parent state. - * - * @param {!ui.router.$state} state - * @return {!ui.router.$state} - * @private - */ - getParentState_(state) { - let conf = this.getBreadcrumbConfig_(state); - let result = state['parent']; - - if (conf && conf.parent) { - result = this.state_.get(conf.parent); - } - - return result; - } - /** * Creates breadcrumb object based on state object. * @@ -149,7 +114,7 @@ export default class BreadcrumbsController { * @private */ getDisplayName_(state) { - let conf = this.getBreadcrumbConfig_(state); + let conf = this.kdBreadcrumbsService_.getBreadcrumbConfig(state); let areLocalsDefined = !!state['locals']; let interpolationContext = state; diff --git a/src/app/frontend/common/components/breadcrumbs/breadcrumbs_service.js b/src/app/frontend/common/components/breadcrumbs/breadcrumbs_service.js new file mode 100644 index 0000000000000000000000000000000000000000..4a2be2f5abe5c0ed3ea79d3ef21cb345999a326f --- /dev/null +++ b/src/app/frontend/common/components/breadcrumbs/breadcrumbs_service.js @@ -0,0 +1,77 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// 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. + +import {stateName as defaultStateName} from 'workloads/workloads_state'; + +/** Breadcrumbs config string used on state config. **/ +export const breadcrumbsConfig = 'kdBreadcrumbs'; + +export class BreadcrumbsService { + /** + * @param {!ui.router.$state} $state + * @ngInject + */ + constructor($state) { this.state_ = $state; } + + /** + * Returns breadcrumb config object if it is defined on state, undefined otherwise. + * + * @param {!ui.router.$state} state + * @return {Object} + */ + getBreadcrumbConfig(state) { + let conf = state['data']; + + if (conf) { + conf = conf[breadcrumbsConfig]; + } + + return conf; + } + + /** + * Returns parent state of the given state based on defined state parent name or if it is not + * defined then based on direct parent state. + * + * @param {!ui.router.$state} state + * @return {!ui.router.$state} + */ + getParentState(state) { + let conf = this.getBreadcrumbConfig(state); + let result = state['parent']; + + if (conf && conf.parent) { + result = this.state_.get(conf.parent); + } + + return result; + } + + /** + * Returns parent state name of the given state based on defined state parent name or if it is not + * defined then default state name is returned. + * + * @param {!ui.router.$state} state + * @return {string} + */ + getParentStateName(state) { + let conf = this.getBreadcrumbConfig(state); + + if (conf && conf.parent) { + return conf.parent; + } + + return defaultStateName; + } +} diff --git a/src/app/frontend/common/components/resourcecard/resourcecarddeletemenuitem_component.js b/src/app/frontend/common/components/resourcecard/resourcecarddeletemenuitem_component.js index 3e4e953bcc56c551864e9d4d49ee3b7b724129ef..118fc853c2135347596a7455a5f24167f825ed89 100644 --- a/src/app/frontend/common/components/resourcecard/resourcecarddeletemenuitem_component.js +++ b/src/app/frontend/common/components/resourcecard/resourcecarddeletemenuitem_component.js @@ -20,10 +20,9 @@ export class ResourceCardDeleteMenuItemController { /** * @param {!./../../resource/verber_service.VerberService} kdResourceVerberService * @param {!ui.router.$state} $state - * @param {!md.$dialog} $mdDialog * @ngInject */ - constructor(kdResourceVerberService, $state, $mdDialog) { + constructor(kdResourceVerberService, $state) { /** * Initialized from require just before $onInit is called. * @export {!./resourcecard_component.ResourceCardController} @@ -38,9 +37,6 @@ export class ResourceCardDeleteMenuItemController { /** @private {!ui.router.$state}} */ this.state_ = $state; - - /** @private {!md.$dialog} */ - this.mdDialog_ = $mdDialog; } /** @@ -50,20 +46,10 @@ export class ResourceCardDeleteMenuItemController { this.kdResourceVerberService_ .showDeleteDialog( this.resourceKindName, this.resourceCardCtrl.typeMeta, this.resourceCardCtrl.objectMeta) - .then( - () => { - // For now just reload the state. Later we can remove the item in place. - this.state_.reload(); - }, - (/** angular.$http.Response|null */ err) => { - if (err) { - // Show dialog if there was an error, not user canceling dialog. - this.mdDialog_.show(this.mdDialog_.alert() - .ok('Ok') - .title(err.statusText || 'Internal server error') - .textContent(err.data || 'Could not delete the resource')); - } - }); + .then(() => { + // For now just reload the state. Later we can remove the item in place. + this.state_.reload(); + }); } } diff --git a/src/app/frontend/common/resource/deleteresource_controller.js b/src/app/frontend/common/resource/deleteresource_controller.js index 5f4893c7cbe82dfa45df47c155f1be5f45259fca..923f98eeed1d4d2e78f954309f5e4a863aec5b8a 100644 --- a/src/app/frontend/common/resource/deleteresource_controller.js +++ b/src/app/frontend/common/resource/deleteresource_controller.js @@ -21,6 +21,7 @@ export class DeleteResourceController { /** * @param {!md.$dialog} $mdDialog * @param {!angular.$resource} $resource + * @param {string} resourceKindName * @param {!backendApi.TypeMeta} typeMeta * @param {!backendApi.ObjectMeta} objectMeta * @ngInject diff --git a/src/app/frontend/common/resource/resource_module.js b/src/app/frontend/common/resource/resource_module.js index 01f88e70b22f29132f2aa467fccc90e0bbd27feb..a20fff6c0cbd1acc9fc21819755e3b185dd54088 100644 --- a/src/app/frontend/common/resource/resource_module.js +++ b/src/app/frontend/common/resource/resource_module.js @@ -23,6 +23,7 @@ export default angular 'kubernetesDashboard.common.resource', [ 'ngMaterial', + 'ui.router', 'ngResource', ]) .service('kdResourceVerberService', VerberService); diff --git a/src/app/frontend/common/resource/verber_service.js b/src/app/frontend/common/resource/verber_service.js index e612dfb9bf69b20aaccbef68a4d8d04a5bca1ffd..6bb0750cde242f028f96dab3d66212500b26b228 100644 --- a/src/app/frontend/common/resource/verber_service.js +++ b/src/app/frontend/common/resource/verber_service.js @@ -22,11 +22,15 @@ import showDeleteDialog from './deleteresource_dialog'; export class VerberService { /** * @param {!md.$dialog} $mdDialog + * @param {!angular.$q} $q * @ngInject */ - constructor($mdDialog) { + constructor($mdDialog, $q) { /** @private {!md.$dialog} */ this.mdDialog_ = $mdDialog; + + /** @private {!angular.$q} */ + this.q_ = $q; } /** @@ -38,6 +42,30 @@ export class VerberService { * @return {!angular.$q.Promise} */ showDeleteDialog(resourceKindName, typeMeta, objectMeta) { - return showDeleteDialog(this.mdDialog_, resourceKindName, typeMeta, objectMeta); + let deferred = this.q_.defer(); + + showDeleteDialog(this.mdDialog_, resourceKindName, typeMeta, objectMeta) + .then(() => { deferred.resolve(); }) + .catch((err) => { + this.deleteErrorCallback(err); + deferred.reject(err); + }); + + return deferred.promise; + } + + /** + * Callback function to show dialog with error message if resource deletion fails. + * + * @param {angular.$http.Response|null} err + */ + deleteErrorCallback(err) { + if (err) { + // Show dialog if there was an error, not user canceling dialog. + this.mdDialog_.show(this.mdDialog_.alert() + .ok('Ok') + .title(err.statusText || 'Internal server error') + .textContent(err.data || 'Could not delete the resource')); + } } } diff --git a/src/app/frontend/deploymentlist/deploymentlist_stateconfig.js b/src/app/frontend/deploymentlist/deploymentlist_stateconfig.js index 53a2d6478a070cddb0e41850c248e0197bfe4222..2355accd94033fb72b7302dda86730238d63679e 100644 --- a/src/app/frontend/deploymentlist/deploymentlist_stateconfig.js +++ b/src/app/frontend/deploymentlist/deploymentlist_stateconfig.js @@ -13,7 +13,7 @@ // limitations under the License. import {actionbarViewName} from 'chrome/chrome_state'; -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import {DeploymentListController} from './deploymentlist_controller'; import {stateName, stateUrl} from './deploymentlist_state'; import {stateName as workloadsState} from 'workloads/workloads_state'; diff --git a/src/app/frontend/events/eventcardlist.html b/src/app/frontend/events/eventcardlist.html index a87b71d486b8cfb421b2a366775c299a864e1d0b..15f8cf27076f32f8beaed11ad5525671c574a690 100644 --- a/src/app/frontend/events/eventcardlist.html +++ b/src/app/frontend/events/eventcardlist.html @@ -19,7 +19,9 @@ limitations under the License.
- + {{type}} diff --git a/src/app/frontend/poddetail/poddetail_stateconfig.js b/src/app/frontend/poddetail/poddetail_stateconfig.js index 80f087220c64fec42306c524c0ef9ae0fbf056b6..6d78da45d62d6d12c3ba9ad564c84021b50c4d9b 100644 --- a/src/app/frontend/poddetail/poddetail_stateconfig.js +++ b/src/app/frontend/poddetail/poddetail_stateconfig.js @@ -13,7 +13,7 @@ // limitations under the License. import {actionbarViewName} from 'chrome/chrome_state'; -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import {PodDetailController} from './poddetail_controller'; import {stateName as podList, stateUrl} from 'podlist/podlist_state'; import {stateName} from './poddetail_state'; diff --git a/src/app/frontend/podlist/podlist_stateconfig.js b/src/app/frontend/podlist/podlist_stateconfig.js index d62a83c53dcd2b992abc19531f758e462349f504..8bfc2c083b0304b0ce6c999375d427be9205bd6f 100644 --- a/src/app/frontend/podlist/podlist_stateconfig.js +++ b/src/app/frontend/podlist/podlist_stateconfig.js @@ -13,7 +13,7 @@ // limitations under the License. import {actionbarViewName} from 'chrome/chrome_state'; -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import {PodListController} from './podlist_controller'; import {stateName, stateUrl} from './podlist_state'; import {stateName as workloadsState} from 'workloads/workloads_state'; diff --git a/src/app/frontend/replicasetdetail/replicasetdetail_stateconfig.js b/src/app/frontend/replicasetdetail/replicasetdetail_stateconfig.js index ea34bb68f0ddda658e588d44c78c41c84cab37ba..680555a39216c151695460edd9d0daf2d6c33202 100644 --- a/src/app/frontend/replicasetdetail/replicasetdetail_stateconfig.js +++ b/src/app/frontend/replicasetdetail/replicasetdetail_stateconfig.js @@ -13,7 +13,7 @@ // limitations under the License. import {actionbarViewName} from 'chrome/chrome_state'; -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import {ReplicaSetDetailController} from './replicasetdetail_controller'; import {stateName as replicaSetList, stateUrl} from 'replicasetlist/replicasetlist_state'; import {stateName} from './replicasetdetail_state'; diff --git a/src/app/frontend/replicasetlist/replicasetlist_stateconfig.js b/src/app/frontend/replicasetlist/replicasetlist_stateconfig.js index 23c2431e19fe728731e519d055648b9a76ac47b9..0dc6a4eae23c18445e4211bf6a0540965d853196 100644 --- a/src/app/frontend/replicasetlist/replicasetlist_stateconfig.js +++ b/src/app/frontend/replicasetlist/replicasetlist_stateconfig.js @@ -13,7 +13,7 @@ // limitations under the License. import {actionbarViewName} from 'chrome/chrome_state'; -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import {ReplicaSetListController} from './replicasetlist_controller'; import {stateName, stateUrl} from './replicasetlist_state'; import {stateName as workloadsState} from 'workloads/workloads_state'; diff --git a/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetail_stateconfig.js b/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetail_stateconfig.js index 3cb5189700b2468529c707fc651c92efbd23b776..bbd538cc87fb05e9e80ff602cbe25c96bc389d62 100644 --- a/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetail_stateconfig.js +++ b/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetail_stateconfig.js @@ -13,10 +13,10 @@ // limitations under the License. import {actionbarViewName} from 'chrome/chrome_state'; -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import {stateName} from './replicationcontrollerdetail_state'; import {stateName as replicationControllers} from 'replicationcontrollerlist/replicationcontrollerlist_state'; -import ReplicationControllerDetailActionBarController from './replicationcontrollerdetailactionbar_controller'; +import {ReplicationControllerDetailActionBarController} from './replicationcontrollerdetailactionbar_controller'; import ReplicationControllerDetailController from './replicationcontrollerdetail_controller'; /** diff --git a/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar.html b/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar.html index 686f8cb845c95b2816c5da77dce1b1a28b83f976..fa8f345ea5d88010cebc34681c3e579e56dee091 100644 --- a/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar.html +++ b/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar.html @@ -23,10 +23,11 @@ limitations under the License. mode_edit Edit number of pods - - delete - Delete replication controller - + +
@@ -38,10 +39,11 @@ limitations under the License. - - delete - Delete replication controller - + + mode_edit Edit number of pods diff --git a/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller.js b/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller.js index c1376536b3cad0faadb253c91593f3dacfbf835e..08edf376db3c6d2bc657b3f9babe9d0da7e20254 100644 --- a/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller.js +++ b/src/app/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller.js @@ -13,39 +13,29 @@ // limitations under the License. import {stateName as deploy} from 'deploy/deploy_state'; -import {stateName as replicationcontrollers} from 'replicationcontrollerlist/replicationcontrollerlist_state'; /** * @final */ -export default class ReplicationControllerDetailActionBarController { +export class ReplicationControllerDetailActionBarController { /** * Constructs action bar on rc detail page. * * @param {ui.router.$state} $state - * @param {!./replicationcontrollerdetail_state.StateParams} $stateParams - * @param {!angular.$log} $log * @param {!backendApi.ReplicationControllerDetail} replicationControllerDetail * @param {!./replicationcontroller_service.ReplicationControllerService} * kdReplicationControllerService * @ngInject */ - constructor( - $state, $stateParams, $log, replicationControllerDetail, kdReplicationControllerService) { + constructor($state, replicationControllerDetail, kdReplicationControllerService) { /** @private {ui.router.$state} */ this.state_ = $state; - /** @private {!./replicationcontrollerdetail_state.StateParams} */ - this.stateParams_ = $stateParams; - - /** @private {!angular.$log} */ - this.log_ = $log; - /** @private {!./replicationcontroller_service.ReplicationControllerService} */ this.kdReplicationControllerService_ = kdReplicationControllerService; - /** @private {!backendApi.ReplicationControllerDetail} */ - this.details_ = replicationControllerDetail; + /** @export {!backendApi.ReplicationControllerDetail} */ + this.details = replicationControllerDetail; /** @export {boolean} */ this.showFabIcons = false; @@ -72,32 +62,7 @@ export default class ReplicationControllerDetailActionBarController { */ handleUpdateReplicasDialog() { this.kdReplicationControllerService_.showUpdateReplicasDialog( - this.details_.objectMeta.namespace, this.details_.objectMeta.name, - this.details_.podInfo.current, this.details_.podInfo.desired); - } - - /** - * Handles replication controller delete dialog. - * @export - */ - handleDeleteReplicationControllerDialog() { - this.kdReplicationControllerService_ - .showDeleteDialog(this.details_.typeMeta, this.details_.objectMeta) - .then(this.onReplicationControllerDeleteSuccess_.bind(this)); - } - - /** - * Callbacks used after clicking dialog confirmation button in order to delete replication - * controller or log unsuccessful operation error. - */ - - /** - * Changes state back to replication controller list after successful deletion of replication - * controller. - * @private - */ - onReplicationControllerDeleteSuccess_() { - this.log_.info('Replication controller successfully deleted.'); - this.state_.go(replicationcontrollers); + this.details.objectMeta.namespace, this.details.objectMeta.name, + this.details.podInfo.current, this.details.podInfo.desired); } } diff --git a/src/app/frontend/replicationcontrollerlist/replicationcontrollerlist_stateconfig.js b/src/app/frontend/replicationcontrollerlist/replicationcontrollerlist_stateconfig.js index 4cd218210352f83bc81ad20bba3ee5e20781be91..2863f2254560491a9c3496ec261cca2f0a7cbfbf 100644 --- a/src/app/frontend/replicationcontrollerlist/replicationcontrollerlist_stateconfig.js +++ b/src/app/frontend/replicationcontrollerlist/replicationcontrollerlist_stateconfig.js @@ -13,7 +13,7 @@ // limitations under the License. import {actionbarViewName} from 'chrome/chrome_state'; -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import {ReplicationControllerListController} from './replicationcontrollerlist_controller'; import {stateName, stateUrl} from './replicationcontrollerlist_state'; import {stateName as workloadsState} from 'workloads/workloads_state'; diff --git a/src/app/frontend/servicedetail/servicedetail_stateconfig.js b/src/app/frontend/servicedetail/servicedetail_stateconfig.js index bb6d66d8799ccaa2853844f63e7312e99fbd1997..411e694f97d023460fbe7450d7e4fb50204ce5d5 100644 --- a/src/app/frontend/servicedetail/servicedetail_stateconfig.js +++ b/src/app/frontend/servicedetail/servicedetail_stateconfig.js @@ -13,7 +13,7 @@ // limitations under the License. import {actionbarViewName} from 'chrome/chrome_state'; -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import {stateName} from './servicedetail_state'; import {stateName as serviceList, stateUrl} from './../servicelist/servicelist_state'; import {ServiceDetailController} from './servicedetail_controller'; diff --git a/src/app/frontend/servicelist/servicelist_stateconfig.js b/src/app/frontend/servicelist/servicelist_stateconfig.js index a57116867a7d2d12add0b3bf8049628b572aa84b..125164999d471b078c481920d99adaff9375e583 100644 --- a/src/app/frontend/servicelist/servicelist_stateconfig.js +++ b/src/app/frontend/servicelist/servicelist_stateconfig.js @@ -14,7 +14,7 @@ import {ServiceListController} from './servicelist_controller'; import {actionbarViewName} from 'chrome/chrome_state'; -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import {stateName, stateUrl} from './servicelist_state'; /** diff --git a/src/test/frontend/common/components/actionbar/actionbardeleteitem_component_test.js b/src/test/frontend/common/components/actionbar/actionbardeleteitem_component_test.js new file mode 100644 index 0000000000000000000000000000000000000000..a42c19d90060cea646be857c4cf75aa8f3734ac4 --- /dev/null +++ b/src/test/frontend/common/components/actionbar/actionbardeleteitem_component_test.js @@ -0,0 +1,90 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// 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. + +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; +import componentsModule from 'common/components/components_module'; + +describe('Actionbar delete item component', () => { + /** @type {BreadcrumbsController} */ + let ctrl; + /** @type {ui.router.$state} */ + let state; + /** @type !{!common/resource/verber_service.VerberService} */ + let kdResourceVerberService; + /** @type {!angular.$q} **/ + let q; + /** @type {!angular.$scope} **/ + let scope; + + /** + * Create simple mock object for state. + * + * @param {string} stateName + * @param {string} stateLabel + * @param {string} stateParent + * @return {{name: string, kdBreadcrumbs: {label: string}}} + */ + function getStateMock(stateName, stateLabel, stateParent) { + return { + name: stateName, + data: { + [breadcrumbsConfig]: { + label: stateLabel, + parent: stateParent, + }, + }, + }; + } + + beforeEach(() => { + angular.mock.module(componentsModule.name); + + angular.mock.inject( + ($componentController, $state, _kdBreadcrumbsService_, _kdResourceVerberService_, $q, + $rootScope) => { + state = $state; + kdResourceVerberService = _kdResourceVerberService_; + q = $q; + scope = $rootScope.$new(); + ctrl = $componentController( + 'kdActionbarDeleteItem', { + $state: state, + kdBreadcrumbsService: _kdBreadcrumbsService_, + kdResourceVerberService: _kdResourceVerberService_, + }, + { + resourceKindName: 'resource', + typeMeta: {}, + objectMeta: {}, + }); + }); + }); + + it('should go to parent state on delete success', () => { + // given + let deferred = q.defer(); + let httpStatusOk = 200; + spyOn(kdResourceVerberService, 'showDeleteDialog').and.returnValue(deferred.promise); + spyOn(state, 'go'); + state.$current = getStateMock('testState', 'testLabel', 'testParent'); + + // when + ctrl.remove(); + deferred.resolve(httpStatusOk); + scope.$digest(); + + // then + expect(state.go).toHaveBeenCalledWith('testParent'); + }); +}); diff --git a/src/test/frontend/common/components/breadcrumbs/breadcrumbs_component_test.js b/src/test/frontend/common/components/breadcrumbs/breadcrumbs_component_test.js index ae562e863b668da1fbb4d4f6e22815a4602230e0..10dcd6f816fce6ec23f470da7fb425e3aa7d99ac 100644 --- a/src/test/frontend/common/components/breadcrumbs/breadcrumbs_component_test.js +++ b/src/test/frontend/common/components/breadcrumbs/breadcrumbs_component_test.js @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_component'; +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; import componentsModule from 'common/components/components_module'; describe('Breadcrumbs controller ', () => { @@ -66,13 +66,14 @@ describe('Breadcrumbs controller ', () => { beforeEach(() => { angular.mock.module(componentsModule.name); - angular.mock.inject(($componentController, $state, $interpolate) => { + angular.mock.inject(($componentController, $state, $interpolate, _kdBreadcrumbsService_) => { state = $state; interpolate = $interpolate; ctrl = $componentController( 'kdBreadcrumbs', { $state: state, $interpolate: interpolate, + kdBreadcrumbsService: _kdBreadcrumbsService_, }, { limit: breadcrumbsLimit, @@ -144,30 +145,6 @@ describe('Breadcrumbs controller ', () => { expect(canBeAdded).toBeFalsy(); }); - it('should return parent state when breadcrumb parent is not defined', () => { - // given - state.parent = getStateMock('parentState'); - - // when - let parent = ctrl.getParentState_(state); - - // expect - expect(parent).toEqual(state.parent); - }); - - it('should return defined parent when breadcrumb parent is defined', () => { - // given - state.data = {kdBreadcrumbs: {parent: 'parentState'}}; - let parent = getStateMock('parentState'); - spyOn(state, 'get').and.returnValue(parent); - - // when - let result = ctrl.getParentState_(state); - - // expect - expect(result).toEqual(parent); - }); - it('should return breadcrumb object', () => { // given spyOn(state, 'href').and.returnValue('stateLink'); @@ -221,23 +198,4 @@ describe('Breadcrumbs controller ', () => { // then expect(result).toEqual(state.name); }); - - it('should return breadcrumb config when it is defined', () => { - // given - let stateMock = getStateMock('testState'); - - // when - let result = ctrl.getBreadcrumbConfig_(stateMock); - - // then - expect(result).toBeDefined(); - }); - - it('should return undefined when breadcrumb config is not defined', () => { - // when - let result = ctrl.getBreadcrumbConfig_(state); - - // then - expect(result).toBeUndefined(); - }); }); diff --git a/src/test/frontend/common/components/breadcrumbs/breadcrumbs_service_test.js b/src/test/frontend/common/components/breadcrumbs/breadcrumbs_service_test.js new file mode 100644 index 0000000000000000000000000000000000000000..dcc74a9a35d75ff818bbf53f189883b5521098c6 --- /dev/null +++ b/src/test/frontend/common/components/breadcrumbs/breadcrumbs_service_test.js @@ -0,0 +1,115 @@ +// Copyright 2015 Google Inc. All Rights Reserved. +// +// 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. + +import {breadcrumbsConfig} from 'common/components/breadcrumbs/breadcrumbs_service'; +import {stateName as defaultStateName} from 'workloads/workloads_state'; +import componentsModule from 'common/components/components_module'; + +describe('Breadcrumbs service ', () => { + /** @type {ui.router.$state} */ + let state; + /** @type {BreadcrumbsController} */ + let breadcrumbsService; + + /** + * Create simple mock object for state. + * + * @param {string} stateName + * @param {string} stateLabel + * @param {string} stateParent + * @return {{name: string, kdBreadcrumbs: {label: string}}} + */ + function getStateMock(stateName, stateLabel, stateParent) { + return { + name: stateName, + data: { + [breadcrumbsConfig]: { + label: stateLabel, + parent: stateParent, + }, + }, + }; + } + + beforeEach(() => { + angular.mock.module(componentsModule.name); + + angular.mock.inject((_kdBreadcrumbsService_, $state) => { + state = $state; + breadcrumbsService = _kdBreadcrumbsService_; + }); + }); + + it('should return parent state when breadcrumb parent is not defined', () => { + // given + state.parent = getStateMock('parentState'); + + // when + let parent = breadcrumbsService.getParentState(state); + + // expect + expect(parent).toEqual(state.parent); + }); + + it('should return defined parent when breadcrumb parent is defined', () => { + // given + state.data = {kdBreadcrumbs: {parent: 'parentState'}}; + let parent = getStateMock('parentState'); + spyOn(state, 'get').and.returnValue(parent); + + // when + let result = breadcrumbsService.getParentState(state); + + // expect + expect(result).toEqual(parent); + }); + + it('should return breadcrumb config when it is defined', () => { + // given + let stateMock = getStateMock('testState'); + + // when + let result = breadcrumbsService.getBreadcrumbConfig(stateMock); + + // then + expect(result).toBeDefined(); + }); + + it('should return undefined when breadcrumb config is not defined', () => { + // when + let result = breadcrumbsService.getBreadcrumbConfig(state); + + // then + expect(result).toBeUndefined(); + }); + + it('should return default state name when parent not defined', () => { + // when + let result = breadcrumbsService.getParentStateName(state); + + // then + expect(result).toEqual(defaultStateName); + }); + + it('should return parent state name when it is defined', () => { + // given + let stateMock = getStateMock('testState', 'testLabel', 'testParent'); + + // when + let result = breadcrumbsService.getParentStateName(stateMock); + + // then + expect(result).toEqual('testParent'); + }); +}); diff --git a/src/test/frontend/common/components/resource/verber_service_test.js b/src/test/frontend/common/components/resource/verber_service_test.js index 5c535e6bc8efd4ee3447a1606a5227730d801d96..c58e07c74a0c27fbd8d937cc1ec54769121c366d 100644 --- a/src/test/frontend/common/components/resource/verber_service_test.js +++ b/src/test/frontend/common/components/resource/verber_service_test.js @@ -19,18 +19,29 @@ describe('Verber service', () => { let verber; /** @type {!md.$dialog} */ let mdDialog; + /** @type {!angular.$q} **/ + let q; + /** @type {!angular.$scope} **/ + let scope; + /** @type {!ui.router.State} **/ + let state; beforeEach(() => angular.mock.module(resourceModule.name)); - beforeEach(angular.mock.inject((kdResourceVerberService, $mdDialog) => { + beforeEach(angular.mock.inject((kdResourceVerberService, $mdDialog, $q, $rootScope, $state) => { verber = kdResourceVerberService; mdDialog = $mdDialog; + q = $q; + scope = $rootScope.$new(); + state = $state; })); it('should show delete dialog resource', () => { - let promise = {}; - spyOn(mdDialog, 'show').and.returnValue(promise); - let actual = verber.showDeleteDialog('Foo resource', {foo: 'bar'}, {baz: 'qux'}); + let deferred = q.defer(); + spyOn(mdDialog, 'show').and.returnValue(deferred.promise); + + verber.showDeleteDialog('Foo resource', {foo: 'bar'}, {baz: 'qux'}); + expect(mdDialog.show).toHaveBeenCalledWith(jasmine.objectContaining({ locals: { 'resourceKindName': 'Foo resource', @@ -38,6 +49,18 @@ describe('Verber service', () => { 'objectMeta': {baz: 'qux'}, }, })); - expect(actual).toBe(promise); + }); + + it('should show alert window on error', () => { + let deferred = q.defer(); + spyOn(mdDialog, 'show').and.returnValue(deferred.promise); + spyOn(state, 'reload'); + spyOn(mdDialog, 'alert').and.callThrough(); + verber.showDeleteDialog(); + + deferred.reject({data: 'foo-data', statusText: 'foo-text'}); + scope.$digest(); + expect(state.reload).not.toHaveBeenCalled(); + expect(mdDialog.alert).toHaveBeenCalled(); }); }); diff --git a/src/test/frontend/common/components/resourcecard/resourcecarddeletemenuitem_component_test.js b/src/test/frontend/common/components/resourcecard/resourcecarddeletemenuitem_component_test.js index 3d40301a27f0082f3d74c08c6949efc0f7b1c1f2..a8c0b5861ee93d32334e1c2385c58e5ac8579bce 100644 --- a/src/test/frontend/common/components/resourcecard/resourcecarddeletemenuitem_component_test.js +++ b/src/test/frontend/common/components/resourcecard/resourcecarddeletemenuitem_component_test.js @@ -50,12 +50,13 @@ describe('Delete resource menu item', () => { it('should delete the resource', () => { let deferred = q.defer(); + let httpStatusOk = 200; spyOn(kdResourceVerberService, 'showDeleteDialog').and.returnValue(deferred.promise); spyOn(state, 'reload'); ctrl.remove(); expect(state.reload).not.toHaveBeenCalled(); - deferred.resolve(); + deferred.resolve(httpStatusOk); scope.$digest(); expect(state.reload).toHaveBeenCalled(); }); @@ -72,17 +73,4 @@ describe('Delete resource menu item', () => { expect(state.reload).not.toHaveBeenCalled(); expect(mdDialog.alert).not.toHaveBeenCalled(); }); - - it('should show alert window on error', () => { - let deferred = q.defer(); - spyOn(kdResourceVerberService, 'showDeleteDialog').and.returnValue(deferred.promise); - spyOn(state, 'reload'); - spyOn(mdDialog, 'alert').and.callThrough(); - ctrl.remove(); - - deferred.reject({data: 'foo-data', statusText: 'foo-text'}); - scope.$digest(); - expect(state.reload).not.toHaveBeenCalled(); - expect(mdDialog.alert).toHaveBeenCalled(); - }); }); diff --git a/src/test/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller_test.js b/src/test/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller_test.js index 1e05fdd765171e86bdc23204caabc65161ce8218..fce536e40c57c15d404d0bba7d70bdb31d6fa95d 100644 --- a/src/test/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller_test.js +++ b/src/test/frontend/replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller_test.js @@ -12,52 +12,40 @@ // See the License for the specific language governing permissions and // limitations under the License. -import ReplicationControllerDetailActionBarController from 'replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller'; +import {ReplicationControllerDetailActionBarController} from 'replicationcontrollerdetail/replicationcontrollerdetailactionbar_controller'; import replicationControllerDetailModule from 'replicationcontrollerdetail/replicationcontrollerdetail_module'; -import {stateName as replicationcontrollers} from 'replicationcontrollerlist/replicationcontrollerlist_state'; import {stateName as deploy} from 'deploy/deploy_state'; describe('Replication Controller Detail Action Bar controller', () => { /** - * Replication Controller Detail controller. - * @type {!ReplicationControllerDetailController} + * Replication Controller Detail Action Bar controller. + * @type {!ReplicationControllerDetailActionBarController} */ let ctrl; /** @type * {!replicationcontrollerdetail/replicationcontroller_service.ReplicationControllerService} */ let kdReplicationControllerService; - /** @type {!angular.$q} */ - let q; /** @type {!ui.router.$state} */ let state; - /** @type {!angular.$log} */ - let log; beforeEach(() => { angular.mock.module(replicationControllerDetailModule.name); - angular.mock.inject( - ($controller, $state, $log, $resource, $q, _kdReplicationControllerService_) => { - q = $q; - state = $state; - log = $log; - kdReplicationControllerService = _kdReplicationControllerService_; - - ctrl = $controller(ReplicationControllerDetailActionBarController, { - $state: state, - $stateParams: { - replicationController: - {objectMeta: {name: 'foo-replicationcontroller', namespace: 'foo-namespace'}}, - }, - replicationControllerDetail: {}, - kdReplicationControllerService: _kdReplicationControllerService_, - }); - }); + angular.mock.inject(($controller, $state, $resource, _kdReplicationControllerService_) => { + state = $state; + kdReplicationControllerService = _kdReplicationControllerService_; + + ctrl = $controller(ReplicationControllerDetailActionBarController, { + $state: state, + replicationControllerDetail: {}, + kdReplicationControllerService: _kdReplicationControllerService_, + }); + }); }); it('should show edit replicas dialog', () => { // given - ctrl.details_ = { + ctrl.details = { objectMeta: { namespace: 'foo-namespace', name: 'foo-name', @@ -76,31 +64,6 @@ describe('Replication Controller Detail Action Bar controller', () => { expect(kdReplicationControllerService.showUpdateReplicasDialog).toHaveBeenCalled(); }); - it('should show delete replicas dialog', () => { - // given - let deferred = q.defer(); - spyOn(kdReplicationControllerService, 'showDeleteDialog').and.returnValue(deferred.promise); - - // when - ctrl.handleDeleteReplicationControllerDialog(); - - // then - expect(kdReplicationControllerService.showDeleteDialog).toHaveBeenCalled(); - }); - - it('should change state to replication controller and log on delete success', () => { - // given - spyOn(state, 'go'); - spyOn(log, 'info'); - - // when - ctrl.onReplicationControllerDeleteSuccess_(); - - // then - expect(state.go).toHaveBeenCalledWith(replicationcontrollers); - expect(log.info).toHaveBeenCalledWith('Replication controller successfully deleted.'); - }); - it('should redirect to deploy page', () => { // given spyOn(state, 'go');