From ab10395d49014f5a9447f845b99bee57a4eedc94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Garde?= Date: Fri, 29 Sep 2017 14:09:32 +1000 Subject: [PATCH 1/6] [MNOE-669] Company Deletion component --- .../dashboard-company-deletion.coffee | 13 ++++++++++ .../dashboard-company-deletion.html | 25 +++++++++++++++++++ src/app/views/company/company.html | 3 ++- 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/app/components/dashboard-company-deletion/dashboard-company-deletion.coffee create mode 100644 src/app/components/dashboard-company-deletion/dashboard-company-deletion.html diff --git a/src/app/components/dashboard-company-deletion/dashboard-company-deletion.coffee b/src/app/components/dashboard-company-deletion/dashboard-company-deletion.coffee new file mode 100644 index 00000000..88cd21e8 --- /dev/null +++ b/src/app/components/dashboard-company-deletion/dashboard-company-deletion.coffee @@ -0,0 +1,13 @@ +angular.module 'mnoEnterpriseAngular' + .component('dashboardCompanyDeletion', { + restrict: 'EA' + templateUrl: 'app/components/dashboard-company-deletion/dashboard-company-deletion.html', + controllerAs: "DashboardCompanyDeletionCtrl" + controller: ($log, $stateParams, $uibModal, MnoeCurrentUser, MnoeOrganizations, MnoeAppInstances, MnoConfirm) -> + vm = this + vm.isDeletionOpen = true + vm.requestDeletion = () -> + $uibModal.open({component: "dashboardDeletionConfirm"}) + + return + }) diff --git a/src/app/components/dashboard-company-deletion/dashboard-company-deletion.html b/src/app/components/dashboard-company-deletion/dashboard-company-deletion.html new file mode 100644 index 00000000..707eda73 --- /dev/null +++ b/src/app/components/dashboard-company-deletion/dashboard-company-deletion.html @@ -0,0 +1,25 @@ +
+
+
+ Company deletion +
+

Before confirming the deletion of your organization, please ensure you understand the following: +

+
    +
  • + You will no longer have access to any 3rd party applications that you have subscribed to via Maestrano. Your data may be deleted immediately by those application providers. +
  • +
  • + All data stored on Maestrano, your dashboard will be immediately deleted and cannot be recovered +
  • +
  • + Data sharing between your applications will cease to function. +
  • +
+

+ If you need further clarification about this, please get in touch with our support team.

+ +
+
diff --git a/src/app/views/company/company.html b/src/app/views/company/company.html index eb767a11..22dee9fb 100644 --- a/src/app/views/company/company.html +++ b/src/app/views/company/company.html @@ -152,9 +152,10 @@

+ + - From 9589d2b6b416042b7743084a0ce3781c502a79a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Garde?= Date: Tue, 10 Oct 2017 18:02:50 +1100 Subject: [PATCH 2/6] [MNOE-669] Deletion confirmation modal Will freeze the org upon confirmation. --- .../dashboard-company-deletion.coffee | 16 +++++-- .../dashboard-deletion-confirm.coffee | 32 ++++++++++++++ .../dashboard-deletion-confirm.html | 43 +++++++++++++++++++ .../mnoe-api/organizations.svc.coffee | 3 ++ .../views/company/company.controller.coffee | 2 + src/app/views/company/company.html | 10 ++--- 6 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.coffee create mode 100644 src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.html diff --git a/src/app/components/dashboard-company-deletion/dashboard-company-deletion.coffee b/src/app/components/dashboard-company-deletion/dashboard-company-deletion.coffee index 88cd21e8..c65a1ab2 100644 --- a/src/app/components/dashboard-company-deletion/dashboard-company-deletion.coffee +++ b/src/app/components/dashboard-company-deletion/dashboard-company-deletion.coffee @@ -3,11 +3,19 @@ angular.module 'mnoEnterpriseAngular' restrict: 'EA' templateUrl: 'app/components/dashboard-company-deletion/dashboard-company-deletion.html', controllerAs: "DashboardCompanyDeletionCtrl" - controller: ($log, $stateParams, $uibModal, MnoeCurrentUser, MnoeOrganizations, MnoeAppInstances, MnoConfirm) -> + controller: ($uibModal, MnoeCurrentUser, MnoeOrganizations, MnoeAppInstances, MnoConfirm) -> vm = this - vm.isDeletionOpen = true - vm.requestDeletion = () -> - $uibModal.open({component: "dashboardDeletionConfirm"}) + vm.isDeletionOpen = false + + vm.proceed = (reason, password) -> + MnoeOrganizations.freeze(reason, password) + vm.requestDeletion = () -> + modalInstance = $uibModal.open( + component: "dashboardDeletionConfirm", + size: "lg", + resolve: + actionCb: () -> vm.proceed + ) return }) diff --git a/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.coffee b/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.coffee new file mode 100644 index 00000000..be994317 --- /dev/null +++ b/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.coffee @@ -0,0 +1,32 @@ +angular.module 'mnoEnterpriseAngular' + .component('dashboardDeletionConfirm', { + templateUrl: 'app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.html', + bindings: { + resolve: '<' + close: '&' + dismiss: '&' + } + controllerAs: "delConfirmCtrl" + controller: ($log, toastr) -> + vm = this + vm.password = "" + vm.delReasons = "" + vm.isLoading = false + + vm.cancel = () -> + vm.dismiss({$value: "cancel"}) + + vm.ok = () -> + vm.isLoading = true + + # Launch Cb + vm.resolve.actionCb(vm.delReasons, vm.password).then( + (response) -> + toastr.success('Organization successfully frozen') + vm.close(response) + (errors) -> + $log.error(errors) + toastr.error(errors.statusText, "Error") + ).finally(-> vm.isLoading = false) + return + }) diff --git a/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.html b/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.html new file mode 100644 index 00000000..8e000622 --- /dev/null +++ b/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.html @@ -0,0 +1,43 @@ + + diff --git a/src/app/components/mnoe-api/organizations.svc.coffee b/src/app/components/mnoe-api/organizations.svc.coffee index b672d117..48b0e18e 100644 --- a/src/app/components/mnoe-api/organizations.svc.coffee +++ b/src/app/components/mnoe-api/organizations.svc.coffee @@ -178,6 +178,9 @@ angular.module 'mnoEnterpriseAngular' return defer.promise + @freeze = (reason, password) -> + MnoeApiSvc.one('organizations', _self.selectedId).doPOST({reason: reason, password: password}, 'halt') + #====================================== # User Role #====================================== diff --git a/src/app/views/company/company.controller.coffee b/src/app/views/company/company.controller.coffee index a9635b60..5838c066 100644 --- a/src/app/views/company/company.controller.coffee +++ b/src/app/views/company/company.controller.coffee @@ -32,6 +32,8 @@ angular.module 'mnoEnterpriseAngular' vm.isAuditLogShown = -> MnoeConfig.isAuditLogEnabled() && MnoeOrganizations.role.isSuperAdmin() + vm.isCompanyActive = -> + MnoeOrganizations.active() #==================================== # Post-Initialization #==================================== diff --git a/src/app/views/company/company.html b/src/app/views/company/company.html index 22dee9fb..d0effa4e 100644 --- a/src/app/views/company/company.html +++ b/src/app/views/company/company.html @@ -90,7 +90,7 @@

{{ 'mno_enterprise.templates.dashboard.organization.in -
+
{{ 'mno_enterprise.templates.dashboard.organization.index.members.title' | translate }}
@@ -106,7 +106,7 @@

{{ 'mno_enterprise.templates.dashboard.organization.in -
+
{{ 'mno_enterprise.templates.dashboard.organization.index.teams.title' | translate }}
@@ -127,7 +127,7 @@

-
+
{{ 'mno_enterprise.templates.dashboard.organization.index.audit_log.title' | translate }}
@@ -143,7 +143,7 @@

-
+
{{ 'mno_enterprise.templates.dashboard.organization.index.settings.title' | translate }}
@@ -154,7 +154,7 @@

- +
From 0013485bd342f24ce2d611eb34ebe656dd4e4f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Garde?= Date: Thu, 12 Oct 2017 17:16:16 +1100 Subject: [PATCH 3/6] [MNOE-669] Hide tabs & panels when org isn't active Will also prevent direct access via URLs --- .../dashboard-company-selectbox.coffee | 3 ++- .../dashboard-menu.controller.coffee | 1 + .../dashboard-menu/dashboard-menu.html | 22 +++++++++---------- src/app/index.run.coffee | 15 +++++++++++++ .../views/company/company.controller.coffee | 3 +-- 5 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/app/components/dashboard-company-selectbox/dashboard-company-selectbox.coffee b/src/app/components/dashboard-company-selectbox/dashboard-company-selectbox.coffee index e8f127ef..f34f1b1b 100644 --- a/src/app/components/dashboard-company-selectbox/dashboard-company-selectbox.coffee +++ b/src/app/components/dashboard-company-selectbox/dashboard-company-selectbox.coffee @@ -23,7 +23,8 @@ DashboardCompanySelectboxCtrl = ($scope, $state, $stateParams, $uibModal, MnoeCu # Switch to selected company MnoeAppInstances.emptyAppInstances() MnoeAppInstances.clearCache() - MnoeOrganizations.get(organization.id) + MnoeOrganizations.get(organization.id).then( (org) -> + if !org.organization.active then $state.go "home.company") selectBox.close() selectOrganization = -> diff --git a/src/app/components/dashboard-menu/dashboard-menu.controller.coffee b/src/app/components/dashboard-menu/dashboard-menu.controller.coffee index 0f378150..0f85a31d 100644 --- a/src/app/components/dashboard-menu/dashboard-menu.controller.coffee +++ b/src/app/components/dashboard-menu/dashboard-menu.controller.coffee @@ -20,6 +20,7 @@ angular.module 'mnoEnterpriseAngular' MnoeCurrentUser.get().then( (response) -> selectedOrg = _.find(response.organizations, {id: newValue}) + $scope.isCompanyActive = selectedOrg.active $scope.isAdmin = MnoeOrganizations.role.atLeastAdmin(selectedOrg.current_user_role) ) if newValue? ) diff --git a/src/app/components/dashboard-menu/dashboard-menu.html b/src/app/components/dashboard-menu/dashboard-menu.html index 9e91e5b0..f0c12180 100644 --- a/src/app/components/dashboard-menu/dashboard-menu.html +++ b/src/app/components/dashboard-menu/dashboard-menu.html @@ -18,17 +18,17 @@
  • - {{ 'mno_enterprise.templates.dashboard.menu.dashboard' | translate }} + {{ 'mno_enterprise.templates.dashboard.menu.dashboard' | translate }}
  • -
  • +
  • {{ 'mno_enterprise.templates.dashboard.menu.dashboard' | translate }}
  • -
  • +
  • {{ 'mno_enterprise.templates.dashboard.menu.impac' | translate }}
  • -
  • +
  • {{ 'mno_enterprise.templates.dashboard.menu.dashboard' | translate }}
  • @@ -40,11 +40,11 @@ {{ 'mno_enterprise.templates.dashboard.menu.company' | translate }} -
  • +
  • {{ 'mno_enterprise.templates.dashboard.menu.subscriptions' | translate }}
  • -
  • +
  • {{ 'mno_enterprise.templates.dashboard.menu.marketplace' | translate }}
  • @@ -66,17 +66,17 @@ diff --git a/src/app/components/dashboard-menu/dashboard-menu.html b/src/app/components/dashboard-menu/dashboard-menu.html index f0c12180..882e3afe 100644 --- a/src/app/components/dashboard-menu/dashboard-menu.html +++ b/src/app/components/dashboard-menu/dashboard-menu.html @@ -17,18 +17,19 @@ -
  • - {{ 'mno_enterprise.templates.dashboard.menu.dashboard' | translate }} + +
  • + {{ 'mno_enterprise.templates.dashboard.menu.dashboard' | translate }}
  • -
  • +
  • {{ 'mno_enterprise.templates.dashboard.menu.dashboard' | translate }}
  • -
  • +
  • {{ 'mno_enterprise.templates.dashboard.menu.impac' | translate }}
  • -
  • +
  • {{ 'mno_enterprise.templates.dashboard.menu.dashboard' | translate }}
  • @@ -40,7 +41,7 @@ {{ 'mno_enterprise.templates.dashboard.menu.company' | translate }} -
  • +
  • {{ 'mno_enterprise.templates.dashboard.menu.subscriptions' | translate }}
  • diff --git a/src/app/components/mnoe-api/organizations.svc.coffee b/src/app/components/mnoe-api/organizations.svc.coffee index 48b0e18e..65b72df9 100644 --- a/src/app/components/mnoe-api/organizations.svc.coffee +++ b/src/app/components/mnoe-api/organizations.svc.coffee @@ -179,8 +179,22 @@ angular.module 'mnoEnterpriseAngular' return defer.promise @freeze = (reason, password) -> - MnoeApiSvc.one('organizations', _self.selectedId).doPOST({reason: reason, password: password}, 'halt') + MnoeApiSvc.one('organizations', _self.selectedId).doPOST({reason: reason, password: password}, 'freeze').then((response) -> + # Reload the current user with the updated organization + MnoeCurrentUser.refresh().then( -> + # If everything wennt well, update the active flag + _self.selected.organization.active = false + response + ) + ) + @companyActiveRequired = () -> + if _self.selected + $state.go('home.company') unless _self.selected.organization.active + else + _self.getCurrentOrganisation().then((org) -> + $state.go('home.company') unless org.organization.active + ) #====================================== # User Role #====================================== diff --git a/src/app/index.route.coffee b/src/app/index.route.coffee index 93aecce1..0ab249bb 100644 --- a/src/app/index.route.coffee +++ b/src/app/index.route.coffee @@ -45,6 +45,9 @@ angular.module 'mnoEnterpriseAngular' url: '/apps' templateUrl: 'app/views/apps/dashboard-apps-list.html' controller: 'DashboardAppsListCtrl' + resolve: + companyActiveRequired: (MnoeOrganizations) -> + MnoeOrganizations.companyActiveRequired() .state 'home.impac', data: pageTitle:'Impac' @@ -52,6 +55,9 @@ angular.module 'mnoEnterpriseAngular' templateUrl: 'app/views/impac/impac.html' controller: 'ImpacController' controllerAs: 'vm' + resolve: + companyActiveRequired: (MnoeOrganizations) -> + MnoeOrganizations.companyActiveRequired() .state 'home.account', data: pageTitle:'Account' @@ -97,6 +103,8 @@ angular.module 'mnoEnterpriseAngular' resolve: loginRequired: (MnoeCurrentUser) -> MnoeCurrentUser.loginRequired() + companyActiveRequired: (MnoeOrganizations) -> + MnoeOrganizations.companyActiveRequired() .state 'onboarding.step1', data: pageTitle:'Welcome' @@ -128,6 +136,9 @@ angular.module 'mnoEnterpriseAngular' templateUrl: 'app/views/marketplace/marketplace.html' controller: 'DashboardMarketplaceCtrl' controllerAs: 'vm' + resolve: + companyActiveRequired: (MnoeOrganizations) -> + MnoeOrganizations.companyActiveRequired() .state 'home.marketplace.app', data: pageTitle:'Marketplace' diff --git a/src/app/index.run.coffee b/src/app/index.run.coffee index ffaa7b00..b7bcf91d 100644 --- a/src/app/index.run.coffee +++ b/src/app/index.run.coffee @@ -100,18 +100,3 @@ angular.module 'mnoEnterpriseAngular' $rootScope.hasNoOrganisations = true ) ) - -# Prevent access to panes other than company and account when the currrent organization isn't active -# See https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-create-rules-to-prevent-access-to-a-state - .run(($rootScope, $state, MnoeOrganizations) -> - $rootScope.$on('$stateChangeStart', (e, to) -> - MnoeOrganizations.getCurrentOrganisation().then( (org) -> - if !org.organization.active - return if to.name[0..3] != "home" || to.name == "home.company" || to.name == "home.account" - e.preventDefault() - # // Optionally set option.notify to false if you don't want - # // to retrigger another $stateChangeStart event - $state.go("home.company") - ) - ) - ) diff --git a/src/app/views/company/company.controller.coffee b/src/app/views/company/company.controller.coffee index d1cfff4a..c02a9d8a 100644 --- a/src/app/views/company/company.controller.coffee +++ b/src/app/views/company/company.controller.coffee @@ -14,7 +14,7 @@ angular.module 'mnoEnterpriseAngular' #==================================== vm.initialize = -> vm.isLoading = false - MnoeOrganizations.getCurrentOrganisation().then((x) -> vm.isCompanyActive = x.organization.active) + vm.isCompanyActive = MnoeOrganizations.getSelected().organization.active if vm.isBillingShown() vm.activeTab = 'billing' else From ea014297970197a1a1e6de8bd81d9af8c80fbc08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Garde?= Date: Wed, 20 Dec 2017 11:59:43 +1100 Subject: [PATCH 6/6] [MNOE-669] Code review - Remove empty lines - I18N the toastr - Organize the locale names --- .../dashboard-company-deletion.html | 6 +++--- .../dashboard-deletion-confirm.coffee | 4 ++-- .../dashboard-deletion-confirm.html | 10 ++++------ src/locales/en.json | 16 +++++++++------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/app/components/dashboard-company-deletion/dashboard-company-deletion.html b/src/app/components/dashboard-company-deletion/dashboard-company-deletion.html index 89bc5ce0..5f7cf69d 100644 --- a/src/app/components/dashboard-company-deletion/dashboard-company-deletion.html +++ b/src/app/components/dashboard-company-deletion/dashboard-company-deletion.html @@ -1,11 +1,11 @@
    - {{ 'mno_enterprise.templates.dashboard.organization.settings.company_deletion' | translate }} + {{ 'mno_enterprise.templates.dashboard.organization.settings.deletion.company_deletion' | translate }}
    -
    +
    diff --git a/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.coffee b/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.coffee index ad523ed3..8e03adcb 100644 --- a/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.coffee +++ b/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.coffee @@ -21,13 +21,13 @@ angular.module 'mnoEnterpriseAngular' # Launch Cb ctrl.resolve.actionCb(ctrl.delReasons, ctrl.password).then( (response) -> - toastr.success('Organization successfully frozen') + toastr.success('mno_enterprise.templates.dashboard.organization.settings.deletion.toastr_success') # Reload the state to block access to Impac!, marketplace, ... $state.reload() ctrl.close(response) (errors) -> $log.error(errors) - toastr.error(errors.statusText, "Error") + toastr.error(errors.statusText, "mno_enterprise.templates.dashboard.organization.settings.deletion.toastr_error") ).finally(-> ctrl.isLoading = false) return }) diff --git a/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.html b/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.html index 775c8f94..bc76e029 100644 --- a/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.html +++ b/src/app/components/dashboard-deletion-confirm/dashboard-deletion-confirm.html @@ -1,24 +1,22 @@ diff --git a/src/locales/en.json b/src/locales/en.json index f38bcdc4..6be0fc86 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -656,13 +656,15 @@ "mno_enterprise.templates.dashboard.organization.settings.disable": "Off", "mno_enterprise.templates.dashboard.organization.settings.cancel": "Cancel", "mno_enterprise.templates.dashboard.organization.settings.save": "Save", - "mno_enterprise.templates.dashboard.organization.settings.company_deletion": "Company deletion", - "mno_enterprise.templates.dashboard.organization.settings.deletion_info_html": "

    Before confirming the deletion of your organization, please ensure you understand the following:

    • You will no longer have access to any 3rd party applications that you have subscribed to via Maestrano. Your data may be deleted immediately by those application providers.
    • All data stored on Maestrano, your dashboard will be immediately deleted and cannot be recovered
    • Data sharing between your applications will cease to function.

    If you need further clarification about this, please get in touch with our support team.

    ", - "mno_enterprise.templates.dashboard.organization.settings.request_deletion": "Request deletion", - "mno_enterprise.templates.dashboard.organization.settings.confirm_deletion_html": "

    After confirming the deletion of this organisation:

    • All users will lose access to any 3rd party applications that have been subscribed to via the platform.
    • All users, excluding yourself, will no longer have access to this organisation.
    • You will only have access to the “Billing” section of this organisation.
    • A final invoice for your organisation, including 3rd party application charges, will be generated on the 25th of the following month.
    • Upon receiving the final payment, the deletion of the organisation will be finalised.

    Please note, individual user accounts will not be deleted. Users will retain the access that they have to any other organisations.

    ", - "mno_enterprise.templates.dashboard.organization.settings.confirm_password": "Your password:", - "mno_enterprise.templates.dashboard.organization.settings.deletion_reason": "Please tell us why you are requesting the deletion of your company", - "mno_enterprise.templates.dashboard.organization.settings.confirm_deletion": "Confirm deletion", + "mno_enterprise.templates.dashboard.organization.settings.deletion.company_deletion": "Company deletion", + "mno_enterprise.templates.dashboard.organization.settings.deletion.info_html": "

    Before confirming the deletion of your organization, please ensure you understand the following:

    • You will no longer have access to any 3rd party applications that you have subscribed to via Maestrano. Your data may be deleted immediately by those application providers.
    • All data stored on Maestrano, your dashboard will be immediately deleted and cannot be recovered
    • Data sharing between your applications will cease to function.

    If you need further clarification about this, please get in touch with our support team.

    ", + "mno_enterprise.templates.dashboard.organization.settings.deletion.request_deletion": "Request deletion", + "mno_enterprise.templates.dashboard.organization.settings.deletion.modal.body_html": "

    After confirming the deletion of this organisation:

    • All users will lose access to any 3rd party applications that have been subscribed to via the platform.
    • All users, excluding yourself, will no longer have access to this organisation.
    • You will only have access to the “Billing” section of this organisation.
    • A final invoice for your organisation, including 3rd party application charges, will be generated on the 25th of the following month.
    • Upon receiving the final payment, the deletion of the organisation will be finalised.

    Please note, individual user accounts will not be deleted. Users will retain the access that they have to any other organisations.

    ", + "mno_enterprise.templates.dashboard.organization.settings.deletion.modal.password": "Your password:", + "mno_enterprise.templates.dashboard.organization.settings.deletion.modal.reason": "Please tell us why you are requesting the deletion of your company", + "mno_enterprise.templates.dashboard.organization.settings.deletion.modal.confirm": "Confirm deletion", + "mno_enterprise.templates.dashboard.organization.settings.deletion.toastr_success": "Organization successfully frozen", + "mno_enterprise.templates.dashboard.organization.settings.deletion.toastr_error": "Error", "mno_enterprise.templates.dashboard.provisioning.breadcrumb.order": "Order", "mno_enterprise.templates.dashboard.provisioning.breadcrumb.additional_details": "Additional details", "mno_enterprise.templates.dashboard.provisioning.breadcrumb.confirm": "Confirm",