Skip to content

Commit

Permalink
Merge pull request #1258 from chalettu/dialog-loading-fix
Browse files Browse the repository at this point in the history
BZ#1499692-Added Loading indicator to Dialogs
(cherry picked from commit 8a64b77)

https://bugzilla.redhat.com/show_bug.cgi?id=1525091
  • Loading branch information
AllenBW authored and simaishi committed Dec 12, 2017
1 parent ebdd839 commit 293a5fb
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 180 deletions.
3 changes: 2 additions & 1 deletion client/app/states/catalogs/details/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ <h4 ng-bind-html="::vm.serviceTemplate.long_description || vm.serviceTemplate.de
<div class="panel panel-default ss-details-panel ss-marketplace-details-form">
<div class="panel-body">
<section>
<div class="col-md-12">
<loading status="vm.loading"></loading>
<div class="col-md-12" ng-show="!vm.loading">
<div class="row">
<div ng-repeat="dialog in ::vm.parsedDialogs">
<dialog-user class="dialog-box" dialog="dialog" refresh-field="vm.refreshField(field)" on-update="vm.setDialogData(data)"></dialog-user>
Expand Down
147 changes: 75 additions & 72 deletions client/app/states/catalogs/details/details.state.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import templateUrl from './details.html'
// import { Promise } from 'q'

/** @ngInject */
export function CatalogsDetailsState (routerHelper) {
Expand All @@ -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
Expand Down
54 changes: 15 additions & 39 deletions client/app/states/catalogs/details/details.state.spec.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,14 @@
/* 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(() => {
module('app.states')
})

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)
})
})

Expand Down Expand Up @@ -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',
Expand All @@ -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)
})
})
Expand All @@ -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', () => {
Expand All @@ -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'
Expand Down Expand Up @@ -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', () => {
Expand All @@ -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
})

Expand All @@ -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
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@
<div class="panel-body">
<section>
<div class="col-md-12">
<div class="row">
<div ng-repeat="dialog in ::vm.dialogs">
<div class="row" ng-if="vm.loading">
<loading status="vm.loading"></loading>
</div>
<div class="row" ng-if="!vm.loading">
<div ng-repeat="dialog in vm.dialogs">
<dialog-user class="dialog-box" dialog="dialog" refresh-field="vm.refreshField(field)" on-update="vm.setDialogData(data)"></dialog-user>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) {
Expand Down
Loading

0 comments on commit 293a5fb

Please sign in to comment.