From 2906a9f2d755c22a93c36f562af2c34331f8beb5 Mon Sep 17 00:00:00 2001 From: Ricardo Marques Date: Thu, 10 May 2018 10:40:09 +0100 Subject: [PATCH] mgr/dashboard: Remove useless observable unsubscriptions Signed-off-by: Ricardo Marques (cherry picked from commit ae75f15dedf6e9f19744dd4ba568ceb9b2c768e4) Conflicts: src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts (retain mimic "Create an observable to add the S3 key when the form is submitted" logic but add whitespace so it blends in with the rest of the refactor) --- .../ceph/block/rbd-form/rbd-form.component.ts | 3 +- .../ceph/cephfs/cephfs/cephfs.component.ts | 13 +- .../ceph/cephfs/clients/clients.component.ts | 11 +- .../performance-counter.component.ts | 10 +- .../rgw-bucket-form.component.ts | 127 +++-- .../rgw-user-form/rgw-user-form.component.ts | 455 +++++++++--------- 6 files changed, 290 insertions(+), 329 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts index 5228063ddc304..a5f00dc97af80 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts @@ -43,7 +43,6 @@ export class RbdFormComponent implements OnInit { features: any; featuresList = []; - routeParamsSubscribe: any; pool: string; advancedEnabled = false; @@ -203,7 +202,7 @@ export class RbdFormComponent implements OnInit { if (this.mode === this.rbdFormMode.editing || this.mode === this.rbdFormMode.cloning || this.mode === this.rbdFormMode.copying) { - this.routeParamsSubscribe = this.route.params.subscribe( + this.route.params.subscribe( (params: { pool: string, name: string, snap: string }) => { const poolName = params.pool; const rbdName = params.name; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs/cephfs.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs/cephfs.component.ts index cdbbb6fef3c97..9e9b64ba749b0 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs/cephfs.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs/cephfs.component.ts @@ -1,8 +1,7 @@ -import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import * as _ from 'lodash'; -import { Subscription } from 'rxjs/Subscription'; import { CephfsService } from '../../../shared/api/cephfs.service'; import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe'; @@ -13,12 +12,10 @@ import { DimlessPipe } from '../../../shared/pipes/dimless.pipe'; templateUrl: './cephfs.component.html', styleUrls: ['./cephfs.component.scss'] }) -export class CephfsComponent implements OnInit, OnDestroy { +export class CephfsComponent implements OnInit { @ViewChild('poolUsageTpl') poolUsageTpl: TemplateRef; @ViewChild('activityTmpl') activityTmpl: TemplateRef; - routeParamsSubscribe: Subscription; - objectValues = Object.values; id: number; @@ -77,7 +74,7 @@ export class CephfsComponent implements OnInit, OnDestroy { data: [] }; - this.routeParamsSubscribe = this.route.params.subscribe((params: { id: number }) => { + this.route.params.subscribe((params: { id: number }) => { this.id = params.id; this.ranks.data = []; @@ -87,10 +84,6 @@ export class CephfsComponent implements OnInit, OnDestroy { }); } - ngOnDestroy() { - this.routeParamsSubscribe.unsubscribe(); - } - refresh() { this.cephfsService.getCephfs(this.id).subscribe((data: any) => { this.ranks.data = data.cephfs.ranks; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/clients/clients.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/clients/clients.component.ts index 6402da14ee7ad..49aacd85b6b19 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/clients/clients.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/clients/clients.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { CephfsService } from '../../../shared/api/cephfs.service'; @@ -9,8 +9,7 @@ import { ViewCacheStatus } from '../../../shared/enum/view-cache-status.enum'; templateUrl: './clients.component.html', styleUrls: ['./clients.component.scss'] }) -export class ClientsComponent implements OnInit, OnDestroy { - routeParamsSubscribe: any; +export class ClientsComponent implements OnInit { id: number; name: string; @@ -32,7 +31,7 @@ export class ClientsComponent implements OnInit, OnDestroy { data: [] }; - this.routeParamsSubscribe = this.route.params.subscribe((params: { id: number }) => { + this.route.params.subscribe((params: { id: number }) => { this.id = params.id; this.clients.data = []; this.viewCacheStatus = ViewCacheStatus.ValueNone; @@ -43,10 +42,6 @@ export class ClientsComponent implements OnInit, OnDestroy { }); } - ngOnDestroy() { - this.routeParamsSubscribe.unsubscribe(); - } - refresh() { this.cephfsService.getClients(this.id).subscribe((data: any) => { this.viewCacheStatus = data.status; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.ts index 25fa82e4e9d14..06f5a9270ac45 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/performance-counter/performance-counter/performance-counter.component.ts @@ -1,4 +1,4 @@ -import { Component, OnDestroy } from '@angular/core'; +import { Component } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ @@ -6,13 +6,12 @@ import { ActivatedRoute } from '@angular/router'; templateUrl: './performance-counter.component.html', styleUrls: ['./performance-counter.component.scss'] }) -export class PerformanceCounterComponent implements OnDestroy { +export class PerformanceCounterComponent { serviceId: string; serviceType: string; - routeParamsSubscribe: any; constructor(private route: ActivatedRoute) { - this.routeParamsSubscribe = this.route.params.subscribe( + this.route.params.subscribe( (params: { type: string; id: string }) => { this.serviceId = params.id; this.serviceType = params.type; @@ -20,7 +19,4 @@ export class PerformanceCounterComponent implements OnDestroy { ); } - ngOnDestroy() { - this.routeParamsSubscribe.unsubscribe(); - } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts index 0e9d7f5eb0a1a..b12eae02ca08a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-form/rgw-bucket-form.component.ts @@ -1,11 +1,12 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { AbstractControl, AsyncValidatorFn, FormBuilder, FormGroup, ValidationErrors, - Validators } from '@angular/forms'; + Validators +} from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import * as _ from 'lodash'; @@ -18,75 +19,62 @@ import { RgwUserService } from '../../../shared/api/rgw-user.service'; templateUrl: './rgw-bucket-form.component.html', styleUrls: ['./rgw-bucket-form.component.scss'] }) -export class RgwBucketFormComponent implements OnInit, OnDestroy { - +export class RgwBucketFormComponent implements OnInit { bucketForm: FormGroup; - routeParamsSubscribe: any; editing = false; error = false; loading = false; owners = null; - constructor(private formBuilder: FormBuilder, - private route: ActivatedRoute, - private router: Router, - private rgwBucketService: RgwBucketService, - private rgwUserService: RgwUserService) { + constructor( + private formBuilder: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private rgwBucketService: RgwBucketService, + private rgwUserService: RgwUserService + ) { this.createForm(); } createForm() { this.bucketForm = this.formBuilder.group({ - 'id': [ - null - ], - 'bucket': [ - null, - [ Validators.required ], - [ this.bucketNameValidator() ] - ], - 'owner': [ - null, - [ Validators.required ] - ] + id: [null], + bucket: [null, [Validators.required], [this.bucketNameValidator()]], + owner: [null, [Validators.required]] }); } ngOnInit() { // Get the list of possible owners. - this.rgwUserService.enumerate() - .subscribe((resp: string[]) => { - this.owners = resp.sort(); - }); + this.rgwUserService.enumerate().subscribe((resp: string[]) => { + this.owners = resp.sort(); + }); // Process route parameters. - this.routeParamsSubscribe = this.route.params - .subscribe((params: { bucket: string }) => { + this.route.params.subscribe( + (params: { bucket: string }) => { if (!params.hasOwnProperty('bucket')) { return; } this.loading = true; // Load the bucket data in 'edit' mode. this.editing = true; - this.rgwBucketService.get(params.bucket) - .subscribe((resp: object) => { - this.loading = false; - // Get the default values. - const defaults = _.clone(this.bucketForm.value); - // Extract the values displayed in the form. - let value = _.pick(resp, _.keys(this.bucketForm.value)); - // Append default values. - value = _.merge(defaults, value); - // Update the form. - this.bucketForm.setValue(value); - }); - }, (error) => { + this.rgwBucketService.get(params.bucket).subscribe((resp: object) => { + this.loading = false; + // Get the default values. + const defaults = _.clone(this.bucketForm.value); + // Extract the values displayed in the form. + let value = _.pick(resp, _.keys(this.bucketForm.value)); + // Append default values. + value = _.merge(defaults, value); + // Update the form. + this.bucketForm.setValue(value); + }); + }, + (error) => { this.error = error; - }); - } - - ngOnDestroy() { - this.routeParamsSubscribe.unsubscribe(); + } + ); } goToListView() { @@ -100,23 +88,29 @@ export class RgwBucketFormComponent implements OnInit, OnDestroy { } const bucketCtl = this.bucketForm.get('bucket'); const ownerCtl = this.bucketForm.get('owner'); - if (this.editing) { // Edit + if (this.editing) { + // Edit const idCtl = this.bucketForm.get('id'); - this.rgwBucketService.update(idCtl.value, bucketCtl.value, ownerCtl.value) - .subscribe(() => { + this.rgwBucketService.update(idCtl.value, bucketCtl.value, ownerCtl.value).subscribe( + () => { this.goToListView(); - }, () => { + }, + () => { // Reset the 'Submit' button. - this.bucketForm.setErrors({'cdSubmitButton': true}); - }); - } else { // Add - this.rgwBucketService.create(bucketCtl.value, ownerCtl.value) - .subscribe(() => { + this.bucketForm.setErrors({ cdSubmitButton: true }); + } + ); + } else { + // Add + this.rgwBucketService.create(bucketCtl.value, ownerCtl.value).subscribe( + () => { this.goToListView(); - }, () => { + }, + () => { // Reset the 'Submit' button. - this.bucketForm.setErrors({'cdSubmitButton': true}); - }); + this.bucketForm.setErrors({ cdSubmitButton: true }); + } + ); } } @@ -133,18 +127,17 @@ export class RgwBucketFormComponent implements OnInit, OnDestroy { // Validate the bucket name. const nameRe = /^[0-9A-Za-z][\w-\.]{2,254}$/; if (!nameRe.test(control.value)) { - resolve({bucketNameInvalid: true}); + resolve({ bucketNameInvalid: true }); return; } // Does any bucket with the given name already exist? - rgwBucketService.exists(control.value) - .subscribe((resp: boolean) => { - if (!resp) { - resolve(null); - } else { - resolve({bucketNameExists: true}); - } - }); + rgwBucketService.exists(control.value).subscribe((resp: boolean) => { + if (!resp) { + resolve(null); + } else { + resolve({ bucketNameExists: true }); + } + }); }); }; } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts index 01282db41ef93..d3a44f642d6ff 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts @@ -1,11 +1,12 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; import { AbstractControl, AsyncValidatorFn, FormBuilder, FormGroup, ValidationErrors, - Validators } from '@angular/forms'; + Validators +} from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; import * as _ from 'lodash'; @@ -20,28 +21,18 @@ import { RgwUserCapability } from '../models/rgw-user-capability'; import { RgwUserS3Key } from '../models/rgw-user-s3-key'; import { RgwUserSubuser } from '../models/rgw-user-subuser'; import { RgwUserSwiftKey } from '../models/rgw-user-swift-key'; -import { - RgwUserCapabilityModalComponent -} from '../rgw-user-capability-modal/rgw-user-capability-modal.component'; -import { - RgwUserS3KeyModalComponent -} from '../rgw-user-s3-key-modal/rgw-user-s3-key-modal.component'; -import { - RgwUserSubuserModalComponent -} from '../rgw-user-subuser-modal/rgw-user-subuser-modal.component'; -import { - RgwUserSwiftKeyModalComponent -} from '../rgw-user-swift-key-modal/rgw-user-swift-key-modal.component'; +import { RgwUserCapabilityModalComponent } from '../rgw-user-capability-modal/rgw-user-capability-modal.component'; +import { RgwUserS3KeyModalComponent } from '../rgw-user-s3-key-modal/rgw-user-s3-key-modal.component'; +import { RgwUserSubuserModalComponent } from '../rgw-user-subuser-modal/rgw-user-subuser-modal.component'; +import { RgwUserSwiftKeyModalComponent } from '../rgw-user-swift-key-modal/rgw-user-swift-key-modal.component'; @Component({ selector: 'cd-rgw-user-form', templateUrl: './rgw-user-form.component.html', styleUrls: ['./rgw-user-form.component.scss'] }) -export class RgwUserFormComponent implements OnInit, OnDestroy { - +export class RgwUserFormComponent implements OnInit { userForm: FormGroup; - routeParamsSubscribe: any; editing = false; error = false; loading = false; @@ -52,11 +43,13 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { swiftKeys: RgwUserSwiftKey[] = []; capabilities: RgwUserCapability[] = []; - constructor(private formBuilder: FormBuilder, - private route: ActivatedRoute, - private router: Router, - private rgwUserService: RgwUserService, - private bsModalService: BsModalService) { + constructor( + private formBuilder: FormBuilder, + private route: ActivatedRoute, + private router: Router, + private rgwUserService: RgwUserService, + private bsModalService: BsModalService + ) { this.createForm(); this.listenToChanges(); } @@ -64,95 +57,60 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { createForm() { this.userForm = this.formBuilder.group({ // General - 'user_id': [ - null, - [Validators.required], - [this.userIdValidator()] - ], - 'display_name': [ - null, - [Validators.required] - ], - 'email': [ - null, - [CdValidators.email] - ], - 'max_buckets': [ - null, - [Validators.min(0)] - ], - 'suspended': [ - false - ], + user_id: [null, [Validators.required], [this.userIdValidator()]], + display_name: [null, [Validators.required]], + email: [null, [CdValidators.email]], + max_buckets: [null, [Validators.min(0)]], + suspended: [false], // S3 key - 'generate_key': [ - true - ], - 'access_key': [ - null, - [CdValidators.requiredIf({'generate_key': false})] - ], - 'secret_key': [ - null, - [CdValidators.requiredIf({'generate_key': false})] - ], + generate_key: [true], + access_key: [null, [CdValidators.requiredIf({ generate_key: false })]], + secret_key: [null, [CdValidators.requiredIf({ generate_key: false })]], // User quota - 'user_quota_enabled': [ - false - ], - 'user_quota_max_size_unlimited': [ - true - ], - 'user_quota_max_size': [ + user_quota_enabled: [false], + user_quota_max_size_unlimited: [true], + user_quota_max_size: [ null, [ CdValidators.requiredIf({ - 'user_quota_enabled': true, - 'user_quota_max_size_unlimited': false + user_quota_enabled: true, + user_quota_max_size_unlimited: false }), this.quotaMaxSizeValidator ] ], - 'user_quota_max_objects_unlimited': [ - true - ], - 'user_quota_max_objects': [ + user_quota_max_objects_unlimited: [true], + user_quota_max_objects: [ null, [ Validators.min(0), CdValidators.requiredIf({ - 'user_quota_enabled': true, - 'user_quota_max_objects_unlimited': false + user_quota_enabled: true, + user_quota_max_objects_unlimited: false }) ] ], // Bucket quota - 'bucket_quota_enabled': [ - false - ], - 'bucket_quota_max_size_unlimited': [ - true - ], - 'bucket_quota_max_size': [ + bucket_quota_enabled: [false], + bucket_quota_max_size_unlimited: [true], + bucket_quota_max_size: [ null, [ CdValidators.requiredIf({ - 'bucket_quota_enabled': true, - 'bucket_quota_max_size_unlimited': false + bucket_quota_enabled: true, + bucket_quota_max_size_unlimited: false }), this.quotaMaxSizeValidator ] ], - 'bucket_quota_max_objects_unlimited': [ - true - ], - 'bucket_quota_max_objects': [ + bucket_quota_max_objects_unlimited: [true], + bucket_quota_max_objects: [ null, [ Validators.min(0), CdValidators.requiredIf({ - 'bucket_quota_enabled': true, - 'bucket_quota_max_objects_unlimited': false + bucket_quota_enabled: true, + bucket_quota_max_objects_unlimited: false }) ] ] @@ -165,101 +123,98 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { // validated again if the status of their prerequisites have been changed. this.userForm.get('generate_key').valueChanges.subscribe(() => { ['access_key', 'secret_key'].forEach((path) => { - this.userForm.get(path).updateValueAndValidity({onlySelf: true}); + this.userForm.get(path).updateValueAndValidity({ onlySelf: true }); }); }); this.userForm.get('user_quota_enabled').valueChanges.subscribe(() => { ['user_quota_max_size', 'user_quota_max_objects'].forEach((path) => { - this.userForm.get(path).updateValueAndValidity({onlySelf: true}); + this.userForm.get(path).updateValueAndValidity({ onlySelf: true }); }); }); this.userForm.get('user_quota_max_size_unlimited').valueChanges.subscribe(() => { - this.userForm.get('user_quota_max_size').updateValueAndValidity({onlySelf: true}); + this.userForm.get('user_quota_max_size').updateValueAndValidity({ onlySelf: true }); }); this.userForm.get('user_quota_max_objects_unlimited').valueChanges.subscribe(() => { - this.userForm.get('user_quota_max_objects').updateValueAndValidity({onlySelf: true}); + this.userForm.get('user_quota_max_objects').updateValueAndValidity({ onlySelf: true }); }); this.userForm.get('bucket_quota_enabled').valueChanges.subscribe(() => { ['bucket_quota_max_size', 'bucket_quota_max_objects'].forEach((path) => { - this.userForm.get(path).updateValueAndValidity({onlySelf: true}); + this.userForm.get(path).updateValueAndValidity({ onlySelf: true }); }); }); this.userForm.get('bucket_quota_max_size_unlimited').valueChanges.subscribe(() => { - this.userForm.get('bucket_quota_max_size').updateValueAndValidity({onlySelf: true}); + this.userForm.get('bucket_quota_max_size').updateValueAndValidity({ onlySelf: true }); }); this.userForm.get('bucket_quota_max_objects_unlimited').valueChanges.subscribe(() => { - this.userForm.get('bucket_quota_max_objects').updateValueAndValidity({onlySelf: true}); + this.userForm.get('bucket_quota_max_objects').updateValueAndValidity({ onlySelf: true }); }); } ngOnInit() { // Process route parameters. - this.routeParamsSubscribe = this.route.params - .subscribe((params: {uid: string}) => { - if (!params.hasOwnProperty('uid')) { - return; - } - this.loading = true; - // Load the user data in 'edit' mode. - this.editing = true; - // Load the user and quota information. - const observables = []; - observables.push(this.rgwUserService.get(params.uid)); - observables.push(this.rgwUserService.getQuota(params.uid)); - Observable.forkJoin(observables) - .subscribe((resp: any[]) => { - this.loading = false; - // Get the default values. - const defaults = _.clone(this.userForm.value); - // Extract the values displayed in the form. - let value = _.pick(resp[0], _.keys(this.userForm.value)); - // Map the quota values. - ['user', 'bucket'].forEach((type) => { - const quota = resp[1][type + '_quota']; - value[type + '_quota_enabled'] = quota.enabled; - if (quota.max_size < 0) { - value[type + '_quota_max_size_unlimited'] = true; - value[type + '_quota_max_size'] = null; - } else { - value[type + '_quota_max_size_unlimited'] = false; - value[type + '_quota_max_size'] = quota.max_size; - } - if (quota.max_objects < 0) { - value[type + '_quota_max_size_unlimited'] = true; - value[type + '_quota_max_size'] = null; - } else { - value[type + '_quota_max_objects_unlimited'] = false; - value[type + '_quota_max_objects'] = quota.max_objects; - } - }); - // Merge with default values. - value = _.merge(defaults, value); - // Update the form. - this.userForm.setValue(value); - - // Get the sub users. - this.subusers = resp[0].subusers; - - // Get the keys. - this.s3Keys = resp[0].keys; - this.swiftKeys = resp[0].swift_keys; - - // Process the capabilities. - const mapPerm = {'read, write': '*'}; - resp[0].caps.forEach((cap) => { - if (cap.perm in mapPerm) { - cap.perm = mapPerm[cap.perm]; - } - }); - this.capabilities = resp[0].caps; - }, (error) => { - this.error = error; + this.route.params.subscribe((params: { uid: string }) => { + if (!params.hasOwnProperty('uid')) { + return; + } + this.loading = true; + // Load the user data in 'edit' mode. + this.editing = true; + // Load the user and quota information. + const observables = []; + observables.push(this.rgwUserService.get(params.uid)); + observables.push(this.rgwUserService.getQuota(params.uid)); + Observable.forkJoin(observables).subscribe( + (resp: any[]) => { + this.loading = false; + // Get the default values. + const defaults = _.clone(this.userForm.value); + // Extract the values displayed in the form. + let value = _.pick(resp[0], _.keys(this.userForm.value)); + // Map the quota values. + ['user', 'bucket'].forEach((type) => { + const quota = resp[1][type + '_quota']; + value[type + '_quota_enabled'] = quota.enabled; + if (quota.max_size < 0) { + value[type + '_quota_max_size_unlimited'] = true; + value[type + '_quota_max_size'] = null; + } else { + value[type + '_quota_max_size_unlimited'] = false; + value[type + '_quota_max_size'] = quota.max_size; + } + if (quota.max_objects < 0) { + value[type + '_quota_max_size_unlimited'] = true; + value[type + '_quota_max_size'] = null; + } else { + value[type + '_quota_max_objects_unlimited'] = false; + value[type + '_quota_max_objects'] = quota.max_objects; + } }); - }); - } - - ngOnDestroy() { - this.routeParamsSubscribe.unsubscribe(); + // Merge with default values. + value = _.merge(defaults, value); + // Update the form. + this.userForm.setValue(value); + + // Get the sub users. + this.subusers = resp[0].subusers; + + // Get the keys. + this.s3Keys = resp[0].keys; + this.swiftKeys = resp[0].swift_keys; + + // Process the capabilities. + const mapPerm = { 'read, write': '*' }; + resp[0].caps.forEach((cap) => { + if (cap.perm in mapPerm) { + cap.perm = mapPerm[cap.perm]; + } + }); + this.capabilities = resp[0].caps; + }, + (error) => { + this.error = error; + } + ); + }); } goToListView() { @@ -271,12 +226,14 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { if (this.userForm.pristine) { this.goToListView(); } - if (this.editing) { // Edit + if (this.editing) { + // Edit if (this._isGeneralDirty()) { const args = this._getApiPostArgs(); this.submitObservables.push(this.rgwUserService.post(args)); } - } else { // Add + } else { + // Add const args = this._getApiPutArgs(); this.submitObservables.push(this.rgwUserService.put(args)); } @@ -291,13 +248,15 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { this.submitObservables.push(this.rgwUserService.putQuota(bucketQuotaArgs)); } // Finally execute all observables. - Observable.forkJoin(this.submitObservables) - .subscribe(() => { + Observable.forkJoin(this.submitObservables).subscribe( + () => { this.goToListView(); - }, () => { + }, + () => { // Reset the 'Submit' button. - this.userForm.setErrors({'cdSubmitButton': true}); - }); + this.userForm.setErrors({ cdSubmitButton: true }); + } + ); } /** @@ -308,13 +267,14 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { if (isEmptyInputValue(control.value)) { return null; } - const m = RegExp('^(\\d+)\\s*(B|K(B|iB)?|M(B|iB)?|G(B|iB)?|T(B|iB)?)?$', - 'i').exec(control.value); + const m = RegExp('^(\\d+)\\s*(B|K(B|iB)?|M(B|iB)?|G(B|iB)?|T(B|iB)?)?$', 'i').exec( + control.value + ); if (m === null) { - return {'quotaMaxSize': true}; + return { quotaMaxSize: true }; } const bytes = new FormatterService().toBytes(control.value); - return (bytes < 1024) ? {'quotaMaxSize': true} : null; + return bytes < 1024 ? { quotaMaxSize: true } : null; } /** @@ -330,14 +290,13 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { resolve(null); return; } - rgwUserService.exists(control.value) - .subscribe((resp: boolean) => { - if (!resp) { - resolve(null); - } else { - resolve({'userIdExists': true}); - } - }); + rgwUserService.exists(control.value).subscribe((resp: boolean) => { + if (!resp) { + resolve(null); + } else { + resolve({ userIdExists: true }); + } + }); }); }; } @@ -346,24 +305,37 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { * Add/Update a subuser. */ setSubuser(subuser: RgwUserSubuser, index?: number) { - if (_.isNumber(index)) { // Modify + if (_.isNumber(index)) { + // Modify // Create an observable to modify the subuser when the form is submitted. - this.submitObservables.push(this.rgwUserService.addSubuser( - this.userForm.get('user_id').value, subuser.id, subuser.permissions, - subuser.secret_key, subuser.generate_secret)); + this.submitObservables.push( + this.rgwUserService.addSubuser( + this.userForm.get('user_id').value, + subuser.id, + subuser.permissions, + subuser.secret_key, + subuser.generate_secret + ) + ); this.subusers[index] = subuser; - } else { // Add + } else { + // Add // Create an observable to add the subuser when the form is submitted. - this.submitObservables.push(this.rgwUserService.addSubuser( - this.userForm.get('user_id').value, subuser.id, subuser.permissions, - subuser.secret_key, subuser.generate_secret)); + this.submitObservables.push( + this.rgwUserService.addSubuser( + this.userForm.get('user_id').value, + subuser.id, + subuser.permissions, + subuser.secret_key, + subuser.generate_secret + ) + ); this.subusers.push(subuser); // Add a Swift key. If the secret key is auto-generated, then visualize // this to the user by displaying a notification instead of the key. this.swiftKeys.push({ - 'user': subuser.id, - 'secret_key': subuser.generate_secret ? - 'Apply your changes first...' : subuser.secret_key + user: subuser.id, + secret_key: subuser.generate_secret ? 'Apply your changes first...' : subuser.secret_key }); } // Mark the form as dirty to be able to submit it. @@ -377,8 +349,9 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { deleteSubuser(index: number) { const subuser = this.subusers[index]; // Create an observable to delete the subuser when the form is submitted. - this.submitObservables.push(this.rgwUserService.deleteSubuser( - this.userForm.get('user_id').value, subuser.id)); + this.submitObservables.push( + this.rgwUserService.deleteSubuser(this.userForm.get('user_id').value, subuser.id) + ); // Remove the associated S3 keys. this.s3Keys = this.s3Keys.filter((key) => { return key.user !== subuser.id; @@ -398,20 +371,21 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { */ setCapability(cap: RgwUserCapability, index?: number) { const uid = this.userForm.get('user_id').value; - if (_.isNumber(index)) { // Modify + if (_.isNumber(index)) { + // Modify const oldCap = this.capabilities[index]; // Note, the RadosGW Admin OPS API does not support the modification of // user capabilities. Because of that it is necessary to delete it and // then to re-add the capability with its new value/permission. - this.submitObservables.push(this.rgwUserService.deleteCapability( - uid, oldCap.type, oldCap.perm)); - this.submitObservables.push(this.rgwUserService.addCapability( - uid, cap.type, cap.perm)); + this.submitObservables.push( + this.rgwUserService.deleteCapability(uid, oldCap.type, oldCap.perm) + ); + this.submitObservables.push(this.rgwUserService.addCapability(uid, cap.type, cap.perm)); this.capabilities[index] = cap; - } else { // Add + } else { + // Add // Create an observable to add the capability when the form is submitted. - this.submitObservables.push(this.rgwUserService.addCapability( - uid, cap.type, cap.perm)); + this.submitObservables.push(this.rgwUserService.addCapability(uid, cap.type, cap.perm)); this.capabilities.push(cap); } // Mark the form as dirty to be able to submit it. @@ -427,8 +401,9 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { deleteCapability(index: number) { const cap = this.capabilities[index]; // Create an observable to delete the capability when the form is submitted. - this.submitObservables.push(this.rgwUserService.deleteCapability( - this.userForm.get('user_id').value, cap.type, cap.perm)); + this.submitObservables.push( + this.rgwUserService.deleteCapability(this.userForm.get('user_id').value, cap.type, cap.perm) + ); // Remove the capability to update the UI. this.capabilities.splice(index, 1); // Mark the form as dirty to be able to submit it. @@ -439,21 +414,29 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { * Add/Update a S3 key. */ setS3Key(key: RgwUserS3Key, index?: number) { - if (_.isNumber(index)) { // Modify + if (_.isNumber(index)) { + // Modify // Nothing to do here at the moment. - } else { // Add + } else { + // Add // Split the key's user name into its user and subuser parts. const userMatches = key.user.match(/([^:]+)(:(.+))?/); // Create an observable to add the S3 key when the form is submitted. - this.submitObservables.push(this.rgwUserService.addS3Key( - userMatches[1], userMatches[2] ? userMatches[3] : '', key.access_key, - key.secret_key, key.generate_key)); + this.submitObservables.push( + this.rgwUserService.addS3Key( + userMatches[1], + userMatches[2] ? userMatches[3] : '', + key.access_key, + key.secret_key, + key.generate_key + ) + ); // If the access and the secret key are auto-generated, then visualize // this to the user by displaying a notification instead of the key. this.s3Keys.push({ - 'user': key.user, - 'access_key': key.generate_key ? 'Apply your changes first...' : key.access_key, - 'secret_key': key.generate_key ? 'Apply your changes first...' : key.secret_key + user: key.user, + access_key: key.generate_key ? 'Apply your changes first...' : key.access_key, + secret_key: key.generate_key ? 'Apply your changes first...' : key.secret_key }); } // Mark the form as dirty to be able to submit it. @@ -467,8 +450,9 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { deleteS3Key(index: number) { const key = this.s3Keys[index]; // Create an observable to delete the S3 key when the form is submitted. - this.submitObservables.push(this.rgwUserService.deleteS3Key( - this.userForm.get('user_id').value, key.access_key)); + this.submitObservables.push( + this.rgwUserService.deleteS3Key(this.userForm.get('user_id').value, key.access_key) + ); // Remove the S3 key to update the UI. this.s3Keys.splice(index, 1); // Mark the form as dirty to be able to submit it. @@ -482,11 +466,13 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { showSubuserModal(index?: number) { const uid = this.userForm.get('user_id').value; const modalRef = this.bsModalService.show(RgwUserSubuserModalComponent); - if (_.isNumber(index)) { // Edit + if (_.isNumber(index)) { + // Edit const subuser = this.subusers[index]; modalRef.content.setEditing(); modalRef.content.setValues(uid, subuser.id, subuser.permissions); - } else { // Add + } else { + // Add modalRef.content.setEditing(false); modalRef.content.setValues(uid); modalRef.content.setSubusers(this.subusers); @@ -502,11 +488,13 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { */ showS3KeyModal(index?: number) { const modalRef = this.bsModalService.show(RgwUserS3KeyModalComponent); - if (_.isNumber(index)) { // View + if (_.isNumber(index)) { + // View const key = this.s3Keys[index]; modalRef.content.setViewing(); modalRef.content.setValues(key.user, key.access_key, key.secret_key); - } else { // Add + } else { + // Add const candidates = this._getS3KeyUserCandidates(); modalRef.content.setViewing(false); modalRef.content.setUserCandidates(candidates); @@ -532,11 +520,13 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { */ showCapabilityModal(index?: number) { const modalRef = this.bsModalService.show(RgwUserCapabilityModalComponent); - if (_.isNumber(index)) { // Edit + if (_.isNumber(index)) { + // Edit const cap = this.capabilities[index]; modalRef.content.setEditing(); modalRef.content.setValues(cap.type, cap.perm); - } else { // Add + } else { + // Add modalRef.content.setEditing(false); modalRef.content.setCapabilities(this.capabilities); } @@ -550,12 +540,7 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { * @return {Boolean} Returns TRUE if the general user settings have been modified. */ private _isGeneralDirty(): boolean { - return [ - 'display_name', - 'email', - 'max_buckets', - 'suspended' - ].some((path) => { + return ['display_name', 'email', 'max_buckets', 'suspended'].some((path) => { return this.userForm.get(path).dirty; }); } @@ -598,20 +583,20 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { */ private _getApiPutArgs() { const result = { - 'uid': this.userForm.get('user_id').value, + uid: this.userForm.get('user_id').value, 'display-name': this.userForm.get('display_name').value }; const suspendedCtl = this.userForm.get('suspended'); if (suspendedCtl.value) { - _.extend(result, {'suspended': suspendedCtl.value}); + _.extend(result, { suspended: suspendedCtl.value }); } const emailCtl = this.userForm.get('email'); if (_.isString(emailCtl.value) && emailCtl.value.length > 0) { - _.extend(result, { 'email': emailCtl.value }); + _.extend(result, { email: emailCtl.value }); } const maxBucketsCtl = this.userForm.get('max_buckets'); if (maxBucketsCtl.value > 0) { - _.extend(result, {'max-buckets': maxBucketsCtl.value}); + _.extend(result, { 'max-buckets': maxBucketsCtl.value }); } const generateKeyCtl = this.userForm.get('generate_key'); if (!generateKeyCtl.value) { @@ -620,7 +605,7 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { 'secret-key': this.userForm.get('secret_key').value }); } else { - _.extend(result, {'generate-key': true}); + _.extend(result, { 'generate-key': true }); } return result; } @@ -631,13 +616,13 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { */ private _getApiPostArgs() { const result = { - 'uid': this.userForm.get('user_id').value + uid: this.userForm.get('user_id').value }; const argsMap = { 'display-name': 'display_name', - 'email': 'email', + email: 'email', 'max-buckets': 'max_buckets', - 'suspended': 'suspended' + suspended: 'suspended' }; for (const key of Object.keys(argsMap)) { const ctl = this.userForm.get(argsMap[key]); @@ -654,16 +639,15 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { */ private _getApiUserQuotaArgs(): object { const result = { - 'uid': this.userForm.get('user_id').value, + uid: this.userForm.get('user_id').value, 'quota-type': 'user', - 'enabled': this.userForm.get('user_quota_enabled').value, + enabled: this.userForm.get('user_quota_enabled').value, 'max-size-kb': -1, 'max-objects': -1 }; if (!this.userForm.get('user_quota_max_size_unlimited').value) { // Convert the given value to bytes. - const bytes = new FormatterService().toBytes(this.userForm.get( - 'user_quota_max_size').value); + const bytes = new FormatterService().toBytes(this.userForm.get('user_quota_max_size').value); // Finally convert the value to KiB. result['max-size-kb'] = (bytes / 1024).toFixed(0) as any; } @@ -679,16 +663,17 @@ export class RgwUserFormComponent implements OnInit, OnDestroy { */ private _getApiBucketQuotaArgs(): object { const result = { - 'uid': this.userForm.get('user_id').value, + uid: this.userForm.get('user_id').value, 'quota-type': 'bucket', - 'enabled': this.userForm.get('bucket_quota_enabled').value, + enabled: this.userForm.get('bucket_quota_enabled').value, 'max-size-kb': -1, 'max-objects': -1 }; if (!this.userForm.get('bucket_quota_max_size_unlimited').value) { // Convert the given value to bytes. - const bytes = new FormatterService().toBytes(this.userForm.get( - 'bucket_quota_max_size').value); + const bytes = new FormatterService().toBytes( + this.userForm.get('bucket_quota_max_size').value + ); // Finally convert the value to KiB. result['max-size-kb'] = (bytes / 1024).toFixed(0) as any; } -- 2.39.5