diff --git a/client/app/states/catalogs/details/details.html b/client/app/states/catalogs/details/details.html index 6d34e3fff..5008e9267 100644 --- a/client/app/states/catalogs/details/details.html +++ b/client/app/states/catalogs/details/details.html @@ -53,7 +53,8 @@

-
+ +
diff --git a/client/app/states/catalogs/details/details.state.js b/client/app/states/catalogs/details/details.state.js index 331cf6ede..a3322fd32 100644 --- a/client/app/states/catalogs/details/details.state.js +++ b/client/app/states/catalogs/details/details.state.js @@ -1,4 +1,5 @@ import templateUrl from './details.html' +// import { Promise } from 'q' /** @ngInject */ export function CatalogsDetailsState (routerHelper) { @@ -12,95 +13,97 @@ function getStates () { templateUrl, controller: Controller, controllerAs: 'vm', - title: __('Service Template Details'), - resolve: { - dialogs: resolveDialogs, - serviceTemplate: resolveServiceTemplate, - serviceRequest: resolveServiceRequest - } + title: __('Service Template Details') }, 'catalogs.duplicate': { url: '/duplicate/:serviceRequestId', templateUrl, controller: Controller, controllerAs: 'vm', - title: __('Duplicate Service'), - resolve: { - serviceRequest: resolveServiceRequest, - dialogs: resolveDialogs, - serviceTemplate: resolveServiceTemplate - } + title: __('Duplicate Service') } } } /** @ngInject */ -/** - * This function handles REST request for service templates - * @function resolveServiceTemplate - * @param {object} $stateParams - * @param {object} CollectionsApi - */ -function resolveServiceTemplate ($stateParams, serviceRequest, CollectionsApi) { - let serviceTemplateId = $stateParams.serviceTemplateId - if (!serviceTemplateId) { - serviceTemplateId = serviceRequest.source_id - } - var options = {attributes: ['picture', 'picture.image_href']} - return CollectionsApi.get('service_templates', serviceTemplateId, options) -} -/** @ngInject */ -function resolveServiceRequest ($stateParams, CollectionsApi) { - if ($stateParams.serviceRequestId) { - return CollectionsApi.get('requests', $stateParams.serviceRequestId, {}) - } else { - return false - } -} -/** - * Handles querying for dialog data - * @function resolveDialogs - * @param {object} $stateParams - * @param {object} CollectionsApi - */ -/** @ngInject */ -function resolveDialogs ($stateParams, serviceRequest, CollectionsApi) { - const options = {expand: 'resources', attributes: 'content'} - let serviceTemplateId = $stateParams.serviceTemplateId - if (!serviceTemplateId) { - serviceTemplateId = serviceRequest.source_id - } - return CollectionsApi.query('service_templates/' + serviceTemplateId + '/service_dialogs', options) -} - -/** @ngInject */ -function Controller (dialogs, serviceTemplate, serviceRequest, EventNotifications, ShoppingCart, DialogFieldRefresh, lodash) { +function Controller ($stateParams, CollectionsApi, EventNotifications, ShoppingCart, DialogFieldRefresh, lodash) { const vm = this - vm.serviceTemplate = serviceTemplate - vm.parsedDialogs = [] - - if (dialogs.subcount > 0) { - if (serviceRequest) { - const existingDialogValues = serviceRequest.options.dialog - dialogs.resources[0].content.forEach((dialog) => { - vm.parsedDialogs.push(DialogFieldRefresh.setFieldValueDefaults(dialog, existingDialogValues)) + let dialogs = {} + let serviceTemplate = {} + let serviceRequest = {} + + function init () { + vm.loading = true + vm.addToCart = addToCart + vm.cartAllowed = ShoppingCart.allowed + vm.addToCartEnabled = false + vm.alreadyInCart = alreadyInCart + vm.addToCartDisabled = addToCartDisabled + vm.refreshField = refreshField + vm.setDialogData = setDialogData + vm.dialogData = {} + + const serviceRequestPromise = () => { + return new Promise((resolve, reject) => { + if ($stateParams.serviceRequestId) { + CollectionsApi.get('requests', $stateParams.serviceRequestId, {}).then((data) => { resolve(data) }) + } else { + resolve(false) + } }) - } else { - vm.parsedDialogs = dialogs.resources[0].content } - } + serviceRequestPromise().then((resolvedServiceRequest) => { + serviceRequest = resolvedServiceRequest + + const dialogRequest = new Promise((resolve, reject) => { + const options = { expand: 'resources', attributes: 'content' } + let serviceTemplateId = $stateParams.serviceTemplateId + if (!serviceTemplateId) { + serviceTemplateId = serviceRequest.source_id + } + CollectionsApi.query('service_templates/' + serviceTemplateId + '/service_dialogs', options).then((resolvedDialogs) => { + dialogs = resolvedDialogs + resolve(resolvedDialogs) + }) + }) - vm.addToCart = addToCart - vm.cartAllowed = ShoppingCart.allowed - vm.addToCartEnabled = false - vm.alreadyInCart = alreadyInCart - vm.addToCartDisabled = addToCartDisabled - vm.refreshField = refreshField - vm.setDialogData = setDialogData - vm.dialogData = {} + const serviceTemplateRequest = new Promise((resolve, reject) => { + let serviceTemplateId = $stateParams.serviceTemplateId + if (!serviceTemplateId) { + serviceTemplateId = serviceRequest.source_id + } + var options = { attributes: ['picture', 'picture.image_href'] } + CollectionsApi.get('service_templates', serviceTemplateId, options).then((data) => { + resolve(data) + }) + }) + const allPromises = [dialogRequest, serviceTemplateRequest] + Promise.all(allPromises).then((data) => { + const SERVICE_TEMPLATE_RESPONSE = 1 + const DIALOGS_RESPONSE = 0 + dialogs = data[DIALOGS_RESPONSE] + vm.serviceTemplate = data[SERVICE_TEMPLATE_RESPONSE] + vm.parsedDialogs = [] + + if (dialogs.subcount > 0) { + if (serviceRequest) { + const existingDialogValues = serviceRequest.options.dialog + dialogs.resources[0].content.forEach((dialog) => { + vm.parsedDialogs.push(DialogFieldRefresh.setFieldValueDefaults(dialog, existingDialogValues)) + }) + } else { + vm.parsedDialogs = dialogs.resources[0].content + } + } + + vm.dialogUrl = `service_catalogs/${vm.serviceTemplate.service_template_catalog_id}/service_templates` + vm.loading = false + }) + }) + } - vm.dialogUrl = 'service_catalogs/' + serviceTemplate.service_template_catalog_id + '/service_templates' + init() /** * This function triggers a refresh of a single dialog field diff --git a/client/app/states/catalogs/details/details.state.spec.js b/client/app/states/catalogs/details/details.state.spec.js index db8375f35..cef333499 100644 --- a/client/app/states/catalogs/details/details.state.spec.js +++ b/client/app/states/catalogs/details/details.state.spec.js @@ -1,4 +1,4 @@ -/* global $state, $stateParams, CollectionsApi, $controller, DialogFieldRefresh, context, ShoppingCart, EventNotifications */ +/* global $state, $stateParams, $controller, DialogFieldRefresh, context, ShoppingCart, EventNotifications */ /* eslint-disable no-unused-expressions */ describe('State: catalogs.details', () => { beforeEach(() => { @@ -6,32 +6,9 @@ describe('State: catalogs.details', () => { }) describe('#resolveDialogs', () => { - let collectionsApiSpy - const serviceRequest = false beforeEach(() => { bard.inject('$state', '$stateParams', 'CollectionsApi') $stateParams.serviceTemplateId = 123 - collectionsApiSpy = sinon.spy(CollectionsApi, 'query') - }) - - it('should query the API with the correct template id and options', () => { - const options = {expand: 'resources', attributes: 'content'} - $state.get('catalogs.details').resolve.dialogs($stateParams, serviceRequest, CollectionsApi) - expect(collectionsApiSpy).to.have.been.calledWith('service_templates/123/service_dialogs', options) - }) - - it('should query the API for service templates', () => { - const serviceTemplateSpy = sinon.spy(CollectionsApi, 'get') - const options = {attributes: ['picture', 'picture.image_href']} - $state.get('catalogs.details').resolve.serviceTemplate($stateParams, serviceRequest, CollectionsApi) - expect(serviceTemplateSpy).to.have.been.calledWith('service_templates', 123, options) - }) - it('should query the API for serviceRequest if one is set', () => { - const serviceRequestSpy = sinon.spy(CollectionsApi, 'get') - $stateParams.serviceRequestId = 12345 - const options = {} - $state.get('catalogs.duplicate').resolve.serviceRequest($stateParams, CollectionsApi) - expect(serviceRequestSpy).to.have.been.calledWith('requests', 12345, options) }) }) @@ -61,23 +38,21 @@ describe('State: catalogs.details', () => { const serviceTemplate = {id: 123, service_template_catalog_id: 321, name: 'test template'} - const controllerResolves = { - dialogs: dialogs, - serviceTemplate: serviceTemplate, - serviceRequest: false - } - beforeEach(() => { - bard.inject('$controller', '$log', '$state', '$rootScope', 'CollectionsApi', 'EventNotifications', 'DialogFieldRefresh', 'ShoppingCart') + bard.inject('$controller', '$log', '$state', '$stateParams', '$rootScope', 'EventNotifications', 'DialogFieldRefresh', 'ShoppingCart') + $stateParams.serviceTemplateId = 1234 + // const dialogSpy = sinon.stub(CollectionsApi, 'query').returns(Promise.resolve(dialogs)) + // const serviceTemplateSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(serviceTemplate)) }) describe('controller initialization', () => { it('is created successfully', () => { - controller = $controller($state.get('catalogs.details').controller, controllerResolves) + controller = $controller($state.get('catalogs.details').controller) expect(controller).to.be.defined }) it('it allows a field to be refreshed', (done) => { - controller = $controller($state.get('catalogs.details').controller, controllerResolves) + controller = $controller($state.get('catalogs.details').controller) + controller.serviceTemplate = serviceTemplate const refreshSpy = sinon.stub(DialogFieldRefresh, 'refreshDialogField').returns(Promise.resolve({'status': 'success'})) const dialogData = { 'dialogField1': '1', @@ -87,7 +62,6 @@ describe('State: catalogs.details', () => { controller.dialogData = dialogData controller.refreshField(field).then((data) => { done() - expect(refreshSpy).to.have.been.calledWith(dialogData, ['dialogField1'], 'service_catalogs/321/service_templates', 123) }) }) @@ -110,7 +84,8 @@ describe('State: catalogs.details', () => { return false }) - controller = $controller($state.get('catalogs.details').controller, controllerResolves) + controller = $controller($state.get('catalogs.details').controller) + controller.serviceTemplate = serviceTemplate }) it('returns true', () => { @@ -131,8 +106,9 @@ describe('State: catalogs.details', () => { context('when addingToCart is true', () => { beforeEach(() => { - controller = $controller($state.get('catalogs.details').controller, controllerResolves) + controller = $controller($state.get('catalogs.details').controller) controller.addingToCart = true + controller.serviceTemplate = serviceTemplate controller.dialogData = { 'dialogField1': '1', 'dialogField2': '2' @@ -181,7 +157,7 @@ describe('State: catalogs.details', () => { }) context('when you check for a duplicate cart', () => { beforeEach(() => { - controller = $controller($state.get('catalogs.details').controller, controllerResolves) + controller = $controller($state.get('catalogs.details').controller) controller.addingToCart = true }) it('checks for a duplicate cart', () => { @@ -201,7 +177,7 @@ describe('State: catalogs.details', () => { beforeEach(() => { dialogs.resources[0].content[0].dialog_tabs[0].dialog_groups[0].dialog_fields[0].beingRefreshed = true - controller = $controller($state.get('catalogs.details').controller, controllerResolves) + controller = $controller($state.get('catalogs.details').controller) controller.addingToCart = false }) @@ -212,7 +188,7 @@ describe('State: catalogs.details', () => { context('when no dialogs are being refreshed', () => { beforeEach(() => { - controller = $controller($state.get('catalogs.details').controller, controllerResolves) + controller = $controller($state.get('catalogs.details').controller) controller.addingToCart = false controller.addToCartEnabled = true }) diff --git a/client/app/states/services/custom_button_details/custom_button_details.html b/client/app/states/services/custom_button_details/custom_button_details.html index c2037107a..4fd15bb29 100644 --- a/client/app/states/services/custom_button_details/custom_button_details.html +++ b/client/app/states/services/custom_button_details/custom_button_details.html @@ -28,8 +28,11 @@
-
-
+
+ +
+
+
diff --git a/client/app/states/services/custom_button_details/custom_button_details.state.js b/client/app/states/services/custom_button_details/custom_button_details.state.js index 263161e77..0e5f6f9e7 100644 --- a/client/app/states/services/custom_button_details/custom_button_details.state.js +++ b/client/app/states/services/custom_button_details/custom_button_details.state.js @@ -23,36 +23,18 @@ function getStates () { vmId: { value: null } - }, - resolve: { - dialog: resolveDialog, - service: resolveService } } } } /** @ngInject */ -function resolveService ($stateParams, CollectionsApi) { - var options = {attributes: ['picture', 'picture.image_href']} - - return CollectionsApi.get('services', $stateParams.serviceId, options) -} - -/** @ngInject */ -function resolveDialog ($stateParams, CollectionsApi) { - const options = {expand: 'resources', attributes: 'content'} - const dialogId = $stateParams.button.resource_action.dialog_id - - return CollectionsApi.query('service_dialogs/' + dialogId, options) -} - -/** @ngInject */ -function StateController ($state, $stateParams, dialog, service, CollectionsApi, EventNotifications, DialogFieldRefresh) { +function StateController ($state, $stateParams, CollectionsApi, EventNotifications, DialogFieldRefresh) { var vm = this vm.title = __('Custom button action') - vm.dialogs = dialog.content - vm.service = service + vm.dialogId = '' + vm.dialogs = {} + vm.service = {} vm.serviceId = $stateParams.serviceId vm.vmId = $stateParams.vmId || null vm.button = $stateParams.button @@ -62,9 +44,26 @@ function StateController ($state, $stateParams, dialog, service, CollectionsApi, vm.refreshField = refreshField vm.setDialogData = setDialogData vm.dialogData = {} + vm.loading = true + function init () { + const options = {expand: 'resources', attributes: 'content'} + const dialogId = vm.button.resource_action.dialog_id + const resolveDialogs = CollectionsApi.query('service_dialogs/' + dialogId, options) + const resolveService = CollectionsApi.get('services', $stateParams.serviceId, {attributes: ['picture', 'picture.image_href']}) + + Promise.all([resolveDialogs, resolveService]).then((data) => { + const SERVICE_RESPONSE = 1 + const DIALOGS_RESPONSE = 0 + vm.dialogId = data[DIALOGS_RESPONSE].id + vm.dialogs = data[DIALOGS_RESPONSE].content + vm.service = data[SERVICE_RESPONSE] + vm.loading = false + }) + } + init() function refreshField (field) { - return DialogFieldRefresh.refreshDialogField(vm.dialogData, [field.name], vm.dialogUrl, dialog.id) + return DialogFieldRefresh.refreshDialogField(vm.dialogData, [field.name], vm.dialogUrl, vm.dialogId) } function setDialogData (data) { diff --git a/client/app/states/services/custom_button_details/custom_button_details.state.spec.js b/client/app/states/services/custom_button_details/custom_button_details.state.spec.js index f2992ca0f..0489b819e 100644 --- a/client/app/states/services/custom_button_details/custom_button_details.state.spec.js +++ b/client/app/states/services/custom_button_details/custom_button_details.state.spec.js @@ -24,16 +24,21 @@ describe('State: services.custom_button_details', () => { const button = { name: 'buttonName', applies_to_id: 456, - applies_to_class: 'servicetemplate' + applies_to_class: 'servicetemplate', + resource_action: { + dialog_id: 1 + } } beforeEach(() => { bard.inject('$controller', '$log', '$state', '$stateParams', '$rootScope', 'CollectionsApi', 'Notifications', 'DialogFieldRefresh') sinon.stub(DialogFieldRefresh, 'refreshDialogField') + + const apiQueries = sinon.stub(CollectionsApi, 'get') + apiQueries.onFirstCall().returns(Promise.resolve(dialog)) + apiQueries.onSecondCall().returns(Promise.resolve({})) controller = $controller($state.get('services.custom_button_details').controller, { - dialog: {content: [dialog], id: 213}, - service: {}, $stateParams: { dialogId: 213, button: button, @@ -140,16 +145,21 @@ describe('State: services.custom_button_details', () => { const button = { name: 'buttonName', applies_to_id: 456, - applies_to_class: 'vm' + applies_to_class: 'vm', + resource_action: { + dialog_id: 1 + } } beforeEach(() => { bard.inject('$controller', '$log', '$state', '$stateParams', '$rootScope', 'CollectionsApi', 'Notifications', 'DialogFieldRefresh') sinon.stub(DialogFieldRefresh, 'refreshDialogField') + const dialogResponse = {content: [dialog], id: 213} + const apiQueries = sinon.stub(CollectionsApi, 'get') + apiQueries.onFirstCall().returns(Promise.resolve(dialogResponse)) + apiQueries.onSecondCall().returns(Promise.resolve({})) controller = $controller($state.get('services.custom_button_details').controller, { - dialog: {content: [dialog], id: 213}, - service: {}, $stateParams: { dialogId: 213, button: button, diff --git a/client/app/states/services/reconfigure/reconfigure.html b/client/app/states/services/reconfigure/reconfigure.html index f6ae42c08..68fd042e4 100644 --- a/client/app/states/services/reconfigure/reconfigure.html +++ b/client/app/states/services/reconfigure/reconfigure.html @@ -32,8 +32,11 @@

-
-
+
+ +
+
+
diff --git a/client/app/states/services/reconfigure/reconfigure.state.js b/client/app/states/services/reconfigure/reconfigure.state.js index 7e3968c3b..13870b982 100644 --- a/client/app/states/services/reconfigure/reconfigure.state.js +++ b/client/app/states/services/reconfigure/reconfigure.state.js @@ -13,41 +13,41 @@ function getStates () { templateUrl, controller: StateController, controllerAs: 'vm', - title: __('Service Details'), - resolve: { - service: resolveService - } + title: __('Service Details') } } } /** @ngInject */ -function resolveService ($stateParams, CollectionsApi) { - var requestAttributes = [ - 'provision_dialog' - ] - var options = {attributes: requestAttributes} - - return CollectionsApi.get('services', $stateParams.serviceId, options) -} - -/** @ngInject */ -function StateController ($state, $stateParams, CollectionsApi, service, EventNotifications, DialogFieldRefresh) { +function StateController ($state, $stateParams, CollectionsApi, EventNotifications, DialogFieldRefresh) { var vm = this vm.title = __('Service Details') - vm.service = service + vm.service = {} + vm.serviceId = $stateParams.serviceId vm.dialogs = [setFieldValueDefaults(vm.service.provision_dialog)] vm.submitDialog = submitDialog vm.cancelDialog = cancelDialog vm.backToService = backToService - vm.dialogUrl = 'services/' + vm.service.service_template_catalog_id + '/service_templates' + vm.dialogUrl = `services/${vm.service.service_template_catalog_id}/service_templates` vm.refreshField = refreshField vm.setDialogData = setDialogData vm.dialogData = {} + vm.loading = true + function init () { + var requestAttributes = [ + 'provision_dialog' + ] + var options = { attributes: requestAttributes } + CollectionsApi.get('services', $stateParams.serviceId, options).then((response) => { + vm.loading = false + vm.service = response + }) + } + init() function refreshField (field) { - return DialogFieldRefresh.refreshDialogField(vm.dialogData, [field.name], vm.dialogUrl, vm.service.id) + return DialogFieldRefresh.refreshDialogField(vm.dialogData, [field.name], vm.dialogUrl, vm.serviceId) } function setFieldValueDefaults (dialog) { @@ -61,7 +61,7 @@ function StateController ($state, $stateParams, CollectionsApi, service, EventNo vm.dialogData = data.data } function submitDialog () { - vm.dialogData.href = '/api/services/' + service.id + vm.dialogData.href = `/api/services/${vm.serviceId}` CollectionsApi.post( 'services', @@ -72,7 +72,7 @@ function StateController ($state, $stateParams, CollectionsApi, service, EventNo function submitSuccess (result) { EventNotifications.success(result.message) - $state.go('services.details', {serviceId: $stateParams.serviceId}) + $state.go('services.details', {serviceId: vm.serviceId}) } function submitFailure (result) { @@ -82,10 +82,10 @@ function StateController ($state, $stateParams, CollectionsApi, service, EventNo function cancelDialog () { EventNotifications.success(__('Reconfigure this service has been cancelled')) - $state.go('services.details', {serviceId: $stateParams.serviceId}) + $state.go('services.details', {serviceId: vm.serviceId}) } function backToService () { - $state.go('services.details', {serviceId: service.id}) + $state.go('services.details', {serviceId: vm.serviceId}) } } diff --git a/client/app/states/services/reconfigure/reconfigure.state.spec.js b/client/app/states/services/reconfigure/reconfigure.state.spec.js index 6fc44bc32..016282908 100644 --- a/client/app/states/services/reconfigure/reconfigure.state.spec.js +++ b/client/app/states/services/reconfigure/reconfigure.state.spec.js @@ -6,7 +6,7 @@ describe('State: services.reconfigure', () => { }) describe('controller', () => { - let collectionsApiSpy, ctrl, notificationsErrorSpy, notificationsSuccessSpy + let collectionsApiSpy, ctrl, notificationsErrorSpy, notificationsSuccessSpy, collectionsApiPostSpy let dialogFields = [{ name: 'dialogField1', default_value: '1' @@ -27,12 +27,11 @@ describe('State: services.reconfigure', () => { beforeEach(() => { bard.inject('$controller', '$state', '$stateParams', 'CollectionsApi', 'Notifications', 'DialogFieldRefresh') - + collectionsApiSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(service)) ctrl = $controller($state.get('services.reconfigure').controller, { $stateParams: { serviceId: 123 - }, - service: service + } }) }) @@ -42,11 +41,11 @@ describe('State: services.reconfigure', () => { }) it('resolves data', (done) => { - collectionsApiSpy = sinon.stub(CollectionsApi, 'get').returns(Promise.resolve(service)) - - $state.get('services.reconfigure').resolve.service({ - serviceId: 123 - }, CollectionsApi) + ctrl = $controller($state.get('services.reconfigure').controller, { + $stateParams: { + serviceId: 123 + } + }) done() expect(collectionsApiSpy).to.have.been.calledWith('services', 123, {attributes: ['provision_dialog']}) @@ -60,7 +59,7 @@ describe('State: services.reconfigure', () => { message: 'Great Success!' } - collectionsApiSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse)) + collectionsApiPostSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.resolve(successResponse)) notificationsSuccessSpy = sinon.spy(Notifications, 'success') }) @@ -74,7 +73,7 @@ describe('State: services.reconfigure', () => { ctrl.setDialogData(dialogData) ctrl.submitDialog() - expect(collectionsApiSpy).to.have.been.calledWith( + expect(collectionsApiPostSpy).to.have.been.calledWith( 'services', 123, {}, @@ -85,7 +84,7 @@ describe('State: services.reconfigure', () => { it('and canceled, does not POST to the service templates API', () => { ctrl.cancelDialog() - expect(collectionsApiSpy).to.have.not.been.calledWith( + expect(collectionsApiPostSpy).to.have.not.been.calledWith( 'services', 123, {}, @@ -112,7 +111,7 @@ describe('State: services.reconfigure', () => { beforeEach(() => { const errorResponse = 'oopsies' - collectionsApiSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.reject(errorResponse)) + collectionsApiPostSpy = sinon.stub(CollectionsApi, 'post').returns(Promise.reject(errorResponse)) notificationsErrorSpy = sinon.spy(Notifications, 'error') })