1+ import { OverlayModule } from '@angular/cdk/overlay' ;
12import { AsyncPipe , DatePipe , DecimalPipe } from '@angular/common' ;
2- import { Component , computed , inject , TemplateRef , viewChild } from '@angular/core' ;
3+ import { Component , computed , inject , signal , TemplateRef , viewChild } from '@angular/core' ;
34import { toSignal } from '@angular/core/rxjs-interop' ;
45import { FormBuilder , ReactiveFormsModule , Validators } from '@angular/forms' ;
56import { RouterLink } from '@angular/router' ;
67import { CustomerOrganization , CustomerOrganizationFeature , CustomerOrganizationWithUsage } from '@distr-sh/distr-sdk' ;
78import { FontAwesomeModule } from '@fortawesome/angular-fontawesome' ;
89import {
910 faBuildingUser ,
11+ faChevronDown ,
1012 faCircleExclamation ,
1113 faEdit ,
1214 faMagnifyingGlass ,
@@ -18,7 +20,6 @@ import {
1820import { combineLatest , filter , firstValueFrom , map , startWith , Subject , switchMap } from 'rxjs' ;
1921import { getFormDisplayedError } from '../../../util/errors' ;
2022import { SecureImagePipe } from '../../../util/secureImage' ;
21- import { modalFlyInOut } from '../../animations/modal' ;
2223import { RequireVendorDirective } from '../../directives/required-role.directive' ;
2324import { ArtifactLicensesService } from '../../services/artifact-licenses.service' ;
2425import { AuthService } from '../../services/auth.service' ;
@@ -32,8 +33,6 @@ import {ToastService} from '../../services/toast.service';
3233import { QuotaLimitComponent } from '../quota-limit.component' ;
3334import { UuidComponent } from '../uuid' ;
3435
35- export const ALL_CUSTOMER_FEATURES : CustomerOrganizationFeature [ ] = [ 'deployment_targets' , 'artifacts' , 'alerts' ] ;
36-
3736@Component ( {
3837 templateUrl : './customer-organizations.component.html' ,
3938 imports : [
@@ -47,8 +46,8 @@ export const ALL_CUSTOMER_FEATURES: CustomerOrganizationFeature[] = ['deployment
4746 RouterLink ,
4847 RequireVendorDirective ,
4948 QuotaLimitComponent ,
49+ OverlayModule ,
5050 ] ,
51- animations : [ modalFlyInOut ] ,
5251} )
5352export class CustomerOrganizationsComponent {
5453 protected readonly faMagnifyingGlass = faMagnifyingGlass ;
@@ -59,6 +58,7 @@ export class CustomerOrganizationsComponent {
5958 protected readonly faCircleExclamation = faCircleExclamation ;
6059 protected readonly faEdit = faEdit ;
6160 protected readonly faRotate = faRotate ;
61+ protected readonly faChevronDown = faChevronDown ;
6262
6363 private readonly customerOrganizationsService = inject ( CustomerOrganizationsService ) ;
6464 private readonly toast = inject ( ToastService ) ;
@@ -106,6 +106,21 @@ export class CustomerOrganizationsComponent {
106106 } ) ;
107107 protected createFormLoading = false ;
108108
109+ protected readonly allCustomerFeatures : readonly CustomerOrganizationFeature [ ] = [
110+ 'deployment_targets' ,
111+ 'alerts' ,
112+ 'artifacts' ,
113+ ] ;
114+
115+ protected readonly openCustomerFeaturesDropdownId = signal < string | void > ( undefined ) ;
116+ protected readonly openCustomerFeaturesDropdownCustomer = computed ( ( ) => {
117+ const id = this . openCustomerFeaturesDropdownId ( ) ;
118+ const c = id ? this . customerOrganizations ( ) ?. find ( ( it ) => it . id === id ) : undefined ;
119+ console . log ( c ) ;
120+ return c ;
121+ } ) ;
122+ protected dropdownWidth = 0 ;
123+
109124 protected showCreateDialog ( ) {
110125 this . closeCreateDialog ( ) ;
111126 this . modalRef = this . overlay . showModal ( this . createCustomerDialog ( ) ) ;
@@ -226,7 +241,7 @@ export class CustomerOrganizationsComponent {
226241 this . customerOrganizationsService . updateCustomerOrganization ( customer . id , {
227242 name : customer . name ,
228243 imageId : customer . imageId ,
229- features : ALL_CUSTOMER_FEATURES ,
244+ features : [ ... this . allCustomerFeatures ] ,
230245 } )
231246 ) ;
232247 this . toast . success ( 'All features restored successfully' ) ;
@@ -240,7 +255,7 @@ export class CustomerOrganizationsComponent {
240255 }
241256
242257 protected hasAllFeatures ( customer : CustomerOrganization ) : boolean {
243- return customer . features . length === ALL_CUSTOMER_FEATURES . length ;
258+ return customer . features . length === this . allCustomerFeatures . length ;
244259 }
245260
246261 protected getFeatureLabel ( feature : CustomerOrganizationFeature ) : string {
@@ -255,4 +270,48 @@ export class CustomerOrganizationsComponent {
255270 return feature ;
256271 }
257272 }
273+
274+ protected isFeatureIndent ( feature : CustomerOrganizationFeature ) : boolean {
275+ return feature === 'alerts' ;
276+ }
277+
278+ protected async toggleFeature ( customer : CustomerOrganization , feature : CustomerOrganizationFeature ) {
279+ const featureSet = new Set ( customer . features ) ;
280+ if ( featureSet . has ( feature ) ) {
281+ featureSet . delete ( feature ) ;
282+ if ( feature === 'deployment_targets' ) {
283+ featureSet . delete ( 'alerts' ) ;
284+ }
285+ } else {
286+ featureSet . add ( feature ) ;
287+ if ( feature === 'alerts' ) {
288+ featureSet . add ( 'deployment_targets' ) ;
289+ }
290+ }
291+
292+ try {
293+ await firstValueFrom (
294+ this . customerOrganizationsService . updateCustomerOrganization ( customer . id , {
295+ ...customer ,
296+ features : Array . from ( featureSet ) ,
297+ } )
298+ ) ;
299+ this . toast . success ( 'Customer features updated' ) ;
300+ this . refresh$ . next ( ) ;
301+ } catch ( e ) {
302+ const msg = getFormDisplayedError ( e ) ;
303+ if ( msg ) {
304+ this . toast . error ( msg ) ;
305+ }
306+ }
307+ }
308+
309+ protected showCustomerFeaturesDropdown ( customer : CustomerOrganization , btn : HTMLButtonElement , i : number ) {
310+ this . dropdownWidth = btn . getBoundingClientRect ( ) . width ;
311+ this . openCustomerFeaturesDropdownId . set ( customer . id ) ;
312+ }
313+
314+ protected hideCustomerFeaturesDropdown ( ) : void {
315+ this . openCustomerFeaturesDropdownId . set ( undefined ) ;
316+ }
258317}
0 commit comments