Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[APPINT-1044] Update frontend and components to display info about add-ons #352

Open
wants to merge 25 commits into
base: feature/app-setup
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions src/app/components/connect-addon-modal/connect-addon-modal.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
angular.module('mnoEnterpriseAngular').component('connectAddonModal', {
bindings: {
resolve: '<'
close: '&',
dismiss: '&'
},
templateUrl: 'app/components/connect-addon-modal/connect-addon-modal.html',
controller: (MnoeAppInstances, toastr, $translate) ->

ctrl = this

ctrl.app = null
ctrl.model = {}
ctrl.isFormLoading = true
ctrl.isSubmitting = false
ctrl.historicalData = false
ctrl.date = new Date()

ctrl.$onInit = ->
ctrl.app = ctrl.resolve.app
ctrl.currentStep = if ctrl.app.addon_organization.has_account_linked then 1 else 0
MnoeAppInstances.getForm(ctrl.app).then((response) ->
ctrl.schema = response.schema
ctrl.form = [ "*" ]
ctrl.isFormLoading = false
)

ctrl.submitForm = () ->
ctrl.isSubmitting = true
MnoeAppInstances.submitForm(ctrl.app, ctrl.model).then((response) ->
if response.linking_error
toastr.error(response.linking_error)
else
ctrl.app.addon_organization.has_account_linked = true
ctrl.currentStep = 1
).finally(-> ctrl.isSubmitting = false)

ctrl.unselectEntities = ->
ctrl.currentStep = 1

ctrl.forceSelectEntities = ->
ctrl.currentStep = 2

ctrl.updateEntities = ->
ctrl.isUpdating = true
synchronizedEntities = {}
_.forOwn ctrl.app.addon_organization.displayable_synchronized_entities, (value, key) ->
synchronizedEntities[key] = _.pick(value, [
'can_push_to_connec'
'can_push_to_external'
])
MnoeAppInstances.updateEntities(ctrl.app, synchronizedEntities, ctrl.app.addon_organization.id).then((response) ->
ctrl.currentStep = 2
ctrl.isUpdating = false
)

ctrl.backClick = ->
switch ctrl.currentStep
when 1 then ctrl.disconnect()
when 2 then ctrl.unselectEntities()

ctrl.nextClick = ->
switch ctrl.currentStep
when 0 then ctrl.submitForm()
when 1 then ctrl.updateEntities()
when 2 then ctrl.synchronize(ctrl.historicalData)

ctrl.disconnect = ->
ctrl.isDisconnecting = true
MnoeAppInstances.disconnect(ctrl.app)
.then((response) ->
ctrl.app.addon_organization.has_account_linked = false
ctrl.app.addon_organization.sync_enabled = false
ctrl.currentStep = 0
ctrl.isDisconnecting = false
)

ctrl.synchronize = (historicalData) ->
MnoeAppInstances.sync(ctrl.app, historicalData)
ctrl.app.addon_organization.sync_enabled = true
ctrl.close()
$translate('mno_enterprise.templates.components.addon_connect.sync.sync_launched').then((tls) ->
toastr.success(tls)
)

return
})
81 changes: 81 additions & 0 deletions src/app/components/connect-addon-modal/connect-addon-modal.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<div id="connect-addon-modal">
<div class="modal-header">
<div class="close" type="button" aria-label="Close" ng-click="$ctrl.close()">×</div>
<h3 class="modal-title"
translate="mno_enterprise.templates.components.addon_connect.title"
translate-values="{appname: $ctrl.app.name}"></h3>
</div>

<div>
<ul class="breadcrumb" ng-switch on="$ctrl.currentStep">
<li ng-switch-when="0">{{"mno_enterprise.templates.components.addon_connect.link_account.title" | translate}}</li>
<li ng-switch-when="0"><a href="#" class="not-active">{{"mno_enterprise.templates.components.addon_connect.entities.select" | translate}}</a></li>
<li ng-switch-when="0"><a href="#" class="not-active">{{"mno_enterprise.templates.components.addon_connect.sync.start_sync" | translate}}</a></li>

<li ng-switch-when="1|2" ng-switch-when-separator="|"><a href="#" class="not-active">{{"mno_enterprise.templates.components.addon_connect.link_account.title" | translate}}</a></li>
<li ng-switch-when="1">{{"mno_enterprise.templates.components.addon_connect.entities.select" | translate}}</li>
<li ng-switch-when="1"><a href="#" ng-click="$ctrl.forceSelectEntities()">{{"mno_enterprise.templates.components.addon_connect.sync.start_sync" | translate}}</a></li>

<li ng-switch-when="2"><a href="#" ng-click="$ctrl.unselectEntities()">{{"mno_enterprise.templates.components.addon_connect.entities.select" | translate}}</a></li>
<li ng-switch-when="2">{{"mno_enterprise.templates.components.addon_connect.sync.start_sync" | translate}}</li>
</ul>

<!-- Link -->
<div class="modal-body" ng-show="$ctrl.currentStep == 0">
<h4 class="text-center">{{"mno_enterprise.templates.components.addon_connect.link_account.link" | translate:{ appname: $ctrl.app.app_name} }}</h4>
<div class="top-buffer-1"></div>

<form sf-schema="$ctrl.schema" sf-form="$ctrl.form" sf-model="$ctrl.model" ng-submit="$ctrl.submit(setupForm)" name="setupForm" ng-if="!$ctrl.isFormLoading"></form>
<mno-loader ng-if="$ctrl.isFormLoading"></mno-loader>
</div>

<!-- Chose Entities -->
<div class="modal-body" ng-show="$ctrl.currentStep == 1">
<h4 class="text-center">{{"mno_enterprise.templates.components.addon_connect.entities.chose_entities" | translate}}</h4>

<table class="table-striped table-condensed" width="100%">
<tr>
<th>{{"mno_enterprise.templates.components.addon_connect.entities.entity" | translate}}</th>
<th>{{"mno_enterprise.templates.components.addon_connect.entities.to_app" | translate:{ appname: $ctrl.app.app_name} }}</th>
<th>{{"mno_enterprise.templates.components.addon_connect.entities.to_connec" | translate:{ appname: $ctrl.app.app_name} }}</th>
</tr>
<tr ng-repeat="entity in $ctrl.app.addon_organization.displayable_synchronized_entities">
<td>{{entity.connec_name}}</td>
<td align="center"><input type="checkbox" ng-model="entity.can_push_to_external" ng-checked="entity.can_push_to_external" ng-disabled="$ctrl.app.addon_organization.push_disabled"></td>
<td align="center"><input type="checkbox" ng-model="entity.can_push_to_connec" ng-checked="entity.can_push_to_connec" ng-disabled="ctrl.app.addon_organization.pull_disabled"></td>
</tr>
</table>
</div>

<!-- Historical data -->
<div class="modal-body" ng-show="$ctrl.currentStep == 2">
<h4 class="text-center">{{"mno_enterprise.templates.components.addon_connect.sync.chose_historical" | translate}}</h4>

<div>
<p translate="mno_enterprise.templates.components.addon_connect.sync.warning_hisorical_html" translate-values="{appname: $ctrl.app.name}"></p>
<input ng-model="$ctrl.historicalData" type="checkbox" display=inline-block></input>
<small ng-show="!$ctrl.historicalData"
translate="mno_enterprise.templates.components.addon_connect.sync.historical_unchecked" translate-values="{date: ($ctrl.date | amDateFormat:'LLL')}">
</small>
<small translate="mno_enterprise.templates.components.addon_connect.sync.historical_checked" translate-values="{appname: $ctrl.app.name}" ng-show="$ctrl.historicalData"></small>
</div>
</div>
</div>

<div class="modal-footer">
<div class="btn-toolbar">
<button class="btn btn-default" ng-click="$ctrl.close()">{{"mno_enterprise.webhook.o_auth.providers.cancel" | translate}}</button>
<div class="pull-right">
<button class="btn btn-warning" ng-if="$ctrl.currentStep != 0" ng-click="$ctrl.backClick()" ng-disabled="$ctrl.isDisconnecting">
<i class="fa fa-arrow-left"></i>
{{"mno_enterprise.templates.components.addon_connect.back" | translate}}
</button>
<button class="btn btn-success" ng-click="$ctrl.nextClick()" ng-disabled="$ctrl.isSubmitting || $ctrl.isUpdating">
{{"mno_enterprise.templates.components.addon_connect.next" | translate}}
<i class="fa fa-arrow-right"></i>
<i class="fa fa-refresh fa-spin" ng-if="$ctrl.isSubmitting || $ctrl.isUpdating"></i>
</button>
</div>
</div>
</div>
</div>
14 changes: 14 additions & 0 deletions src/app/components/connect-addon-modal/connect-addon-modal.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#connect-addon-modal {
.not-active {
pointer-events: none;
cursor: default;
}

ul.breadcrumb {
margin-bottom: 0px;
}

h4 {
margin-bottom: 25px;
}
}
58 changes: 38 additions & 20 deletions src/app/components/dashboard-apps-dock/dashboard-apps-dock.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,15 @@ DashboardAppsDockCtrl = ($scope, $cookies, $uibModal, $window, MnoeOrganizations
$scope.helper.isNewOfficeApp(app)

$scope.helper.isOauthConnectBtnShown = (instance) ->
instance.app_nid != 'office-365' &&
(instance.app_nid != 'office-365' &&
instance.stack == 'connector' &&
!instance.oauth_keys_valid
!instance.oauth_keys_valid) ||
$scope.helper.isCreateAccountShown(instance) ||
(MnoeAppInstances.isAddOnWithOrg(instance) && !instance.addon_organization.sync_enabled)

$scope.helper.isCreateAccountShown = (instance) ->
MnoeAppInstances.isAddOnWithOrg(instance) &&
!instance.addon_organization.has_account_linked

$scope.helper.isNewOfficeApp = (instance) ->
instance.stack == 'connector' && instance.appNid == 'office-365' && (moment(instance.createdAt) > moment().subtract({minutes:5}))
Expand All @@ -55,6 +61,12 @@ DashboardAppsDockCtrl = ($scope, $cookies, $uibModal, $window, MnoeOrganizations
$window.open("/mnoe/launch/#{app.uid}", '_blank')
return true

$scope.redirectToExternal = (app, event) ->
$scope.setActiveApp(event, app.id)
$window.open(app.addon_organization.account_creation_link, '_blank')
$scope.showConnectModal(app)
return true

$scope.setActiveApp = (event, app) ->
if $scope.isActiveApp(app)
$scope.activeApp = null
Expand Down Expand Up @@ -87,24 +99,30 @@ DashboardAppsDockCtrl = ($scope, $cookies, $uibModal, $window, MnoeOrganizations
# App Connect modal
#====================================
$scope.showConnectModal = (app) ->
switch app.app_nid
when "xero" then modalInfo = {
template: "app/views/apps/modals/app-connect-modal-xero.html",
controller: 'DashboardAppConnectXeroModalCtrl'
}
when "myob" then modalInfo = {
template: "app/views/apps/modals/app-connect-modal-myob.html",
controller: 'DashboardAppConnectMyobModalCtrl'
}
else $scope.helper.oAuthConnectPath(app)

modalInstance = $uibModal.open(
templateUrl: modalInfo.template
controller: modalInfo.controller
resolve:
app: ->
app
)
if app.stack == 'cloud'
modalInstance = $uibModal.open({
component: 'connectAddonModal'
resolve:
app: -> app
})
else
switch app.app_nid
when "xero" then modalInfo = {
template: "app/views/apps/modals/app-connect-modal-xero.html",
controller: 'DashboardAppConnectXeroModalCtrl'
}
when "myob" then modalInfo = {
template: "app/views/apps/modals/app-connect-modal-myob.html",
controller: 'DashboardAppConnectMyobModalCtrl'
}
else $scope.helper.oAuthConnectPath(app)

modalInstance = $uibModal.open(
templateUrl: modalInfo.template
controller: modalInfo.controller
resolve:
app: -> app
)

#====================================
# Post-Initialization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@
<div class="dock-arrow"><i class="fa fa-chevron-up"></i></div>
<div class="inner-dock-menu">
<!-- EO Connectors Buttons -->
<div class="menu-item ng-hide" ng-hide="helper.isLaunchHidden(app)">
<div class="menu-item" ng-show="helper.isCreateAccountShown(app)" uib-tooltip="{{ 'mno_enterprise.templates.components.app_install_btn.create_account_tooltip' | translate }}">
<a ng-click="redirectToExternal(app,$event);"><i class="fa fa-user-plus"></i>{{ 'mno_enterprise.templates.components.app_install_btn.create_account' | translate }}</a>
</div>
<div class="menu-item" ng-hide="helper.isLaunchHidden(app)">
<a ng-click="launchAction(app,$event);"><i class="fa fa-play-circle"></i>{{ 'mno_enterprise.templates.impac.dock.launch' | translate }}</a>
</div>
<div class="menu-item ng-hide" ng-show="helper.isOauthConnectBtnShown(app)">
<div class="menu-item" ng-show="helper.isOauthConnectBtnShown(app)" uib-tooltip="{{ 'mno_enterprise.templates.components.app_install_btn.connect_app' | translate }}">
<a ng-click="showConnectModal(app)"><i class="fa fa-play-circle" >
</i> {{ 'mno_enterprise.templates.impac.dock.connect' | translate }}</a>
</div>
<div class="menu-item ng-hide" ng-show="helper.displaySettings()">
<div class="menu-item" ng-show="helper.displaySettings()">
<a ng-click="showSettingsModal(app)"><i class="fa fa-cog"></i> {{ 'mno_enterprise.templates.impac.dock.settings.settings' | translate }} </a>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
top: 0;
right: 0;
text-align: center;

.top-right-corner {
line-height: 0;
margin-right: -10px;
Expand Down Expand Up @@ -128,6 +128,7 @@ ul.dock {
.box-shadow(@mno-dock-sub-menu-box-shadow);
.menu-item {
cursor: pointer;
white-space: nowrap;

&:hover {
background-color: @mno-dock-sub-menu-hover;
Expand Down
35 changes: 34 additions & 1 deletion src/app/components/mnoe-api/app-instances.svc.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
angular.module 'mnoEnterpriseAngular'
.service 'MnoeAppInstances', ($q, MnoeApiSvc, MnoeOrganizations, MnoLocalStorage, MnoeCurrentUser, LOCALSTORAGE) ->
.service 'MnoeAppInstances', ($q, MnoeApiSvc, MnoeFullApiSvc, MnoeOrganizations, MnoLocalStorage, MnoeCurrentUser, LOCALSTORAGE) ->
_self = @

# Store selected organization app instances
Expand Down Expand Up @@ -32,6 +32,12 @@ angular.module 'mnoEnterpriseAngular'
_self.emptyAppInstances()
fetchAppInstances()

# Return true if the app from the app_instance parameter is an add_on,
# and we managed to retrieve the organization from the connector
@isAddOnWithOrg = (instance) ->
instance.add_on &&
instance.addon_organization

# Retrieve app instances from the backend
fetchAppInstances = ->
# Workaround as the API is not standard (return a hash map not an array)
Expand Down Expand Up @@ -62,6 +68,33 @@ angular.module 'mnoEnterpriseAngular'
Array.prototype.push.apply(_self.appInstances, arr)
return _self.appInstances

@getForm = (instance) ->
MnoeApiSvc.one('/app_instances', instance.id).doGET('/setup_form')

@submitForm = (instance, model) ->
data = {}
for key of model
if model.hasOwnProperty(key)
data[key] = model[key]
MnoeApiSvc.one('/app_instances', instance.id).post('/create_omniauth', data)

@getSyncs = (instance, params) ->
MnoeFullApiSvc.one('/app_instances', instance.id).doGET('/sync_history', params)

@getIdMaps = (instance, params) ->
MnoeFullApiSvc.one('/app_instances', instance.id).doGET('/id_maps', params)

@disconnect = (instance) ->
MnoeApiSvc.one('/app_instances', instance.id).post('/disconnect')

@sync = (instance, fullSync = false) ->
data = {full_sync: fullSync}
MnoeApiSvc.one('/app_instances', instance.id).post('/sync', data)

@updateEntities = (instance, entities, orgId) ->
data = {entities: entities, org_id: orgId}
MnoeApiSvc.one('/app_instances', instance.id).customPUT(data, '/update_addon_synchronized_entities')

# Path to connect this app instance and redirect to the current page
@oAuthConnectPath = (instance, extra_params = '') ->
_self.clearCache()
Expand Down
4 changes: 3 additions & 1 deletion src/app/index.module.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ angular.module 'mnoEnterpriseAngular', [
'ngSanitize',
'ui.router',
'ui.bootstrap',
'smart-table',
'toastr',
'restangular',
'platanus.inflector',
Expand All @@ -23,5 +24,6 @@ angular.module 'mnoEnterpriseAngular', [
'angular.filter',
'textAngular',
'user-friendly-angular-json-tree',
'angularSpectrumColorpicker'
'angularSpectrumColorpicker',
'mnoUiElements'
]
Loading