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

[MNOE-1181] [WIP] Created My Tools section for tenant purchaseable products #302

Open
wants to merge 1 commit into
base: 2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
11,816 changes: 11,816 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
dismiss: '&'
},
templateUrl: 'app/components/mno-product-selector/mno-product-selector.html',
controller: ($window, $q, orderByFilter, MnoeProducts, MnoeApps, MnoeProvisioning) ->
controller: ($window, $q, orderByFilter, MnoeProducts, MnoeMarketplace, MnoeApps, MnoeProvisioning) ->
'ngInject'

$ctrl = this
Expand All @@ -25,11 +25,14 @@
deferred.resolve response.data
)
when 'settings-add-new-app'
$ctrl.selectedProducts = if $ctrl.purchasableType == 'user_purchasable' then $ctrl.selectedProducts else $ctrl.selectedProducts[0]
deferred.resolve $ctrl.selectedProducts
deferred.promise

$ctrl.$onInit = ->
$ctrl.flag = $ctrl.resolve.dataFlag
$ctrl.isTenantPurchasableFlag = $ctrl.resolve.isTenantPurchasable || false
$ctrl.purchasableType = $ctrl.resolve.purchasableType || 'user_purchasable'
$ctrl.resolveProducts()
$ctrl.multiple = $ctrl.resolve.multiple
$ctrl.modalHeight = ($window.innerHeight - 200) + "px"
Expand Down Expand Up @@ -58,14 +61,17 @@
when 'organization-create-order'
MnoeProducts.products(_, _, _, params)
when 'settings-add-new-app'
MnoeApps.list().then(
params = { 'where[purchasables]': $ctrl.purchasableType }
MnoeApps.list(params).then(
(response) ->
debuggerx
apps = $ctrl.resolve.enabledApps
# Copy the response, we're are modifying the response in place and
# don't want to modify the cached version in MnoeApps
resp = angular.copy(response)
enabledIds = _.map(apps, 'id')
_.remove(resp.data, (app)-> _.includes(enabledIds, app.id))
# TODO: We need to remove this check once we create the query structure for subscription based products
_.remove(resp.data, (app)-> _.includes(enabledIds, app.id)) unless $ctrl.purchasableType == 'tenant_purchasable'
resp
)

Expand Down
17 changes: 14 additions & 3 deletions src/app/components/mnoe-api/admin/apps.svc.coffee
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
# Service for managing the App catalogue.
@App.service 'MnoeApps', ($q, toastr, MnoeAdminApiSvc, MnoeObservables, OBS_KEYS) ->
@App.service 'MnoeApps', ($q, toastr, MnoeAdminApiSvc, MnoeObservables, OBS_KEYS, MnoErrorsHandler) ->
_self = @

appsPromise = null
subscribedTenantAppsPromise = null

@list = ->
@list = (params = {})->
return appsPromise if appsPromise?
appsPromise = MnoeAdminApiSvc.all('apps').getList().catch(
appsPromise = MnoeAdminApiSvc.all('apps').getList(params).catch(
(error) ->
# Something went wrong
toastr.error('mnoe_admin_panel.dashboard.settings.apps.retrieve.error')
MnoErrorsHandler.processServerError(error)
$q.reject(error)
)

@subscribedTenantAppsList = (params = {})->
return subscribedTenantAppsPromise if subscribedTenantAppsPromise?
subscribedTenantAppsPromise = MnoeAdminApiSvc.all('products').all('subscribed_tenant_products').getList(params).catch(
(error) ->
# Something went wrong
toastr.error('mnoe_admin_panel.dashboard.my-tools.apps.retrieve.error')
MnoErrorsHandler.processServerError(error)
$q.reject(error)
)

# Delete the instance of an app
@disable = (id) ->
MnoeAdminApiSvc.one('apps', id).customPATCH(null, 'disable').then(
Expand Down
1 change: 0 additions & 1 deletion src/app/components/mnoe-api/api.svc.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# Unwrap api response
RestangularProvider.addResponseInterceptor(
(data, operation, what, url, response, deferred) ->

# If the what starts with a '/', return the data as it is
# Used if the payload is not correctly formatted
# (eg. MnoeApiSvc.oneUrl('/marketplace'))
Expand Down
7 changes: 4 additions & 3 deletions src/app/components/mnoe-api/marketplace.svc.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@

# Using this syntax will not trigger the data extraction in MnoeApiSvc
# as the /marketplace payload isn't encapsulated in "{ marketplace: categories {...}, apps {...} }"
marketplaceApi = MnoeApiSvc.oneUrl('/marketplace')

marketplacePromise = null

refreshApps = ->
marketplacePromise = null
_self.getApps()

@getApps = () ->
return marketplacePromise if marketplacePromise?
@getApps = (tenant_purchasable) ->
purchasable = tenant_purchasable || 'user_purchasable'
marketplaceApi = MnoeApiSvc.oneUrl('/marketplace?purchasables='+purchasable)
return marketplacePromise if marketplacePromise? && !tenant_purchasable
marketplacePromise = marketplaceApi.get()

MnoeObservables.registerCb(OBS_KEYS.marketplaceChanged, refreshApps)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
###
# @desc Modal used to select one or multiple products
# @binding {Array} [resolve.products] The list of products to be displayed
# @binding {Boolean} [resolve.multiple] Is the user allowed to select more than one product?
###
@App.component('mnoePurchasableProductsList', {
bindings: {
purchasable: '='
},
templateUrl: 'app/components/mnoe-purchasable-products-list/mnoe-purchasable-products-list.html',
controller: ($state, $uibModal, MnoeMarketplace, MnoeApps, MnoeTenant, MnoConfirm, MnoeAdminApiSvc, MnoeCurrentUser, UserRoles) ->
'ngInject'

$ctrl = this
$ctrl.state = $state
$ctrl.enabledApps = []
$ctrl.filteredApps = []
$ctrl.selectedCategory = ''
$ctrl.searchTerm = ''
$ctrl.toolsCheck = "tools"
$ctrl.tenantManagement = false
$ctrl.purchasableType = null
# TODO: Use Tenant's organization id here based on MNOE-1187
$ctrl.organizationId = 1

$ctrl.$onInit = ->
$ctrl.purchasableType = $ctrl.purchasable || null
init()

# Filter apps by name or category
$ctrl.onSearchChange = () ->
$ctrl.selectedCategory = ''
term = $ctrl.searchTerm.toLowerCase()
$ctrl.filteredApps = (app for app in $ctrl.enabledApps when app.name.toLowerCase().indexOf(term) isnt -1)

$ctrl.onCategoryChange = () ->
$ctrl.searchTerm = ''
if ($ctrl.selectedCategory?.length > 0)
$ctrl.filteredApps = (app for app in $ctrl.enabledApps when $ctrl.selectedCategory in app.categories)
else
$ctrl.filteredApps = $ctrl.enabledApps

resetFilteredApps = () ->
MnoeMarketplace.getApps($ctrl.purchasableType).then(
(response) ->
$ctrl.enabledApps = angular.copy(response.data.apps)
$ctrl.selectedCategory = ''
$ctrl.searchTerm = ''
$ctrl.filteredApps = $ctrl.enabledApps
)

$ctrl.openRemoveAppModal = (app, $index)->
MnoConfirm.showModal(
headerText: 'mnoe_admin_panel.dashboard.settings.apps.modal.remove_app.proceed'
bodyText: 'mnoe_admin_panel.dashboard.settings.apps.modal.remove_app.perform'
bodyTextExtraData: {app_name: app.name}
type: 'danger'
actionCb: ->
MnoeApps.disable(app.id).then(
->
resetFilteredApps()
)
)

# ====================================
# App Info modal
# ====================================
$ctrl.openInfoModal = (app) ->
$uibModal.open(
templateUrl: 'app/views/settings/apps/modals/app-infos.html'
controller: 'appInfoCtrl'
controllerAs: 'vm',
size: 'lg'
resolve:
app: app
)

$ctrl.openAddAppModal = () ->
resolve = {
dataFlag: -> 'settings-add-new-app'
enabledApps: -> $ctrl.enabledApps
purchasableType: -> $ctrl.purchasableType
isTenantPurchasable: -> if $ctrl.purchasableType == 'tenant_purchasable' then true else false
multiple : -> if $ctrl.purchasableType == 'tenant_purchasable' then false else true
headerText : -> if $ctrl.purchasableType == 'tenant_purchasable' then '' else 'mnoe_admin_panel.dashboard.settings.apps.modal.add_app.title'
actionButtonText : -> 'mnoe_admin_panel.dashboard.settings.apps.modal.add_app.add'
}
modalInstance = $uibModal.open(
component: 'mnoProductSelectorModal'
backdrop: 'static'
size: 'lg'
resolve: resolve
)
modalInstance.result.then(
(response) ->
switch $ctrl.purchasableType
when "tenant_purchasable"
$state.go('dashboard.provisioning.order', {productId: response.id, orgId: $ctrl.organizationId, editAction: 'new'})
when "user_purchasable"
MnoeApps.enableMultiple(_.map(response, 'id')).then(
->
resetFilteredApps()
)
)
# Load config from the Tenant
init = ->
callUrl=''
switch $ctrl.purchasableType
when "tenant_purchasable"
params = { 'organization_id' : $ctrl.organizationId }
callUrl = MnoeApps.subscribedTenantAppsList(params)
when "user_purchasable"
callUrl = MnoeMarketplace.getApps($ctrl.purchasableType)
callUrl.then(
(response) ->
# Copy the marketplace as we will work on the cached object
$ctrl.enabledApps = angular.copy(response.data.apps)
$ctrl.filteredApps = $ctrl.enabledApps
$ctrl.categories = angular.copy(response.data.categories || null)
$ctrl.displayCategories = if $ctrl.categories then $ctrl.categories.length > 0 else false
)
MnoeTenant.get().then(
(response) ->
$ctrl.tenantManagement = response.data.app_management == "tenant")

MnoeCurrentUser.getUser().then(
(response) ->
$ctrl.isAccountManager = UserRoles.isAccountManager(response)
)
return
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<mno-widget icon="fa-th-large" heading="{{'mnoe_admin_panel.dashboard.settings.apps.available_apps' | translate}}">
<mno-widget-header>
<div class="pull-right">
<div class="apps-filter col-sm-6">
<input type="search" ng-model="$ctrl.searchTerm" placeholder="{{'mnoe_admin_panel.dashboard.settings.apps.search' | translate}}" ng-change="$ctrl.onSearchChange()"/>
</div>
<div ng-if="$ctrl.displayCategories" class="apps-filter col-sm-6">
<select class="form-control" ng-model="$ctrl.selectedCategory" ng-options="c for c in $ctrl.categories" ng-change="$ctrl.onCategoryChange($ctrl.selectedCategory)">
<option value=''>{{ 'mnoe_admin_panel.dashboard.settings.apps.select_all' | translate }}</option>
</select>
</div>

</div>
</mno-widget-header>
<mno-widget-body>
<div class="row">
<div class="col-sm-12">
<div class="row apps-box">
<div class="app-wrapper col-xs-3 col-sm-2 col-md-2" ng-repeat="app in $ctrl.filteredApps">
<div class="small-app-card ellipsis" uib-tooltip="{{::app.name}}">
<i class="fa fa-trash app-remove" ng-if="$ctrl.tenantManagement && !$ctrl.isAccountManager" ng-click="$ctrl.openRemoveAppModal(app, $index)" uib-tooltip="{{'mnoe_admin_panel.dashboard.organization.remove_app' | translate:{'app_name': app.name} }}" tooltip-append-to-body="true"></i>
<img ng-src="{{::app.logo}}" width="60" class="app-info-modal" ng-click="$ctrl.openInfoModal(app)">
<span>{{::app.name}}</span>
</div>
</div>
<div ng-if="$ctrl.tenantManagement && !$ctrl.isAccountManager" class="app-wrapper col-xs-3 col-sm-2 col-md-2">
<div class="small-app-card ellipsis add-app" ng-click="$ctrl.openAddAppModal()">
<span>{{'mnoe_admin_panel.dashboard.organization.add_an_app' | translate}}<i class="fa fa-plus"></i></span>
</div>
</div>
</div>
</div>
</div>
</mno-widget-body>
</mno-widget>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#my-tools, #settings-apps {
.apps-filter {
display: flex;
justify-content: flex-start;
padding: 0 12px;

input {
width: 30%;
min-width: 150px;
border-radius: 4px;
line-height: 20px;
padding: 5px 10px;
border: 1px solid #ccc;
}
}
}
11 changes: 11 additions & 0 deletions src/app/index.route.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@
controllerAs: 'vm'
ncyBreadcrumb:
label: 'mnoe_admin_panel.dashboard.home.title'
.state 'dashboard.tools',
data:
pageTitle: 'My Tools Selection'
url: '/my-tools'
templateUrl: 'app/views/my-tools/my-tools.html'
controller: 'MyToolsController'
controllerAs: 'vm'
ncyBreadcrumb:
label: 'mnoe_admin_panel.dashboard.my-tools.title'
resolve:
skip: (MnoeCurrentUser) -> MnoeCurrentUser.skipIfNotAdminRole(['admin', 'staff'])
.state 'dashboard.reviews',
data:
pageTitle:'Reviews'
Expand Down
3 changes: 3 additions & 0 deletions src/app/views/dashboard.layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
<li class="sidebar-list" ui-sref-active="active">
<a ui-sref="dashboard.home">{{'mnoe_admin_panel.dashboard.layout.sidebar.home' | translate}}<span class="menu-icon fa fa-tachometer"></span></a>
</li>
<li class="sidebar-list" ui-sref-active="active">
<a ui-sref="dashboard.tools">{{'mnoe_admin_panel.dashboard.layout.sidebar.my-tools' | translate}}<span class="menu-icon fa fa-wrench"></span></a>
</li>
<li class="sidebar-title"><span>{{'mnoe_admin_panel.dashboard.layout.sidebar.customer-management' | translate}}</span></li>
<li class="sidebar-list" ui-sref-active="active">
<a ui-sref="dashboard.customers">{{'mnoe_admin_panel.dashboard.layout.sidebar.customers' | translate}}<span class="menu-icon fa fa-users"></span></a>
Expand Down
Loading