mirror of
				https://github.com/richard-loafle/fuse-angular.git
				synced 2025-10-31 04:53:33 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			275 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			275 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, TemplateRef, ViewChild, ViewContainerRef, ViewEncapsulation } from '@angular/core';
 | |
| import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 | |
| import { Overlay, OverlayRef } from '@angular/cdk/overlay';
 | |
| import { TemplatePortal } from '@angular/cdk/portal';
 | |
| import { MatButton } from '@angular/material/button';
 | |
| import { takeUntil } from 'rxjs/operators';
 | |
| import { Subject } from 'rxjs';
 | |
| import { Shortcut } from 'app/layout/common/shortcuts/shortcuts.types';
 | |
| import { ShortcutsService } from 'app/layout/common/shortcuts/shortcuts.service';
 | |
| 
 | |
| @Component({
 | |
|     selector       : 'shortcuts',
 | |
|     templateUrl    : './shortcuts.component.html',
 | |
|     encapsulation  : ViewEncapsulation.None,
 | |
|     changeDetection: ChangeDetectionStrategy.OnPush,
 | |
|     exportAs       : 'shortcuts'
 | |
| })
 | |
| export class ShortcutsComponent implements OnChanges, OnInit, OnDestroy
 | |
| {
 | |
|     @Input() shortcuts: Shortcut[];
 | |
|     @ViewChild('shortcutsOrigin') private _shortcutsOrigin: MatButton;
 | |
|     @ViewChild('shortcutsPanel') private _shortcutsPanel: TemplateRef<any>;
 | |
| 
 | |
|     mode: 'view' | 'modify' | 'add' | 'edit' = 'view';
 | |
|     shortcutForm: FormGroup;
 | |
|     private _overlayRef: OverlayRef;
 | |
|     private _unsubscribeAll: Subject<any> = new Subject<any>();
 | |
| 
 | |
|     /**
 | |
|      * Constructor
 | |
|      */
 | |
|     constructor(
 | |
|         private _changeDetectorRef: ChangeDetectorRef,
 | |
|         private _formBuilder: FormBuilder,
 | |
|         private _shortcutsService: ShortcutsService,
 | |
|         private _overlay: Overlay,
 | |
|         private _viewContainerRef: ViewContainerRef
 | |
|     )
 | |
|     {
 | |
|     }
 | |
| 
 | |
|     // -----------------------------------------------------------------------------------------------------
 | |
|     // @ Lifecycle hooks
 | |
|     // -----------------------------------------------------------------------------------------------------
 | |
| 
 | |
|     /**
 | |
|      * On changes
 | |
|      *
 | |
|      * @param changes
 | |
|      */
 | |
|     ngOnChanges(changes: SimpleChanges): void
 | |
|     {
 | |
|         // Shortcuts
 | |
|         if ( 'shortcuts' in changes )
 | |
|         {
 | |
|             // Store the shortcuts on the service
 | |
|             this._shortcutsService.store(changes.shortcuts.currentValue);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * On init
 | |
|      */
 | |
|     ngOnInit(): void
 | |
|     {
 | |
|         // Initialize the form
 | |
|         this.shortcutForm = this._formBuilder.group({
 | |
|             id         : [null],
 | |
|             label      : ['', Validators.required],
 | |
|             description: [''],
 | |
|             icon       : ['', Validators.required],
 | |
|             link       : ['', Validators.required],
 | |
|             useRouter  : ['', Validators.required]
 | |
|         });
 | |
| 
 | |
|         // Get the shortcuts
 | |
|         this._shortcutsService.shortcuts$
 | |
|             .pipe(takeUntil(this._unsubscribeAll))
 | |
|             .subscribe((shortcuts: Shortcut[]) => {
 | |
| 
 | |
|                 // Load the shortcuts
 | |
|                 this.shortcuts = shortcuts;
 | |
| 
 | |
|                 // Mark for check
 | |
|                 this._changeDetectorRef.markForCheck();
 | |
|             });
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * On destroy
 | |
|      */
 | |
|     ngOnDestroy(): void
 | |
|     {
 | |
|         // Unsubscribe from all subscriptions
 | |
|         this._unsubscribeAll.next();
 | |
|         this._unsubscribeAll.complete();
 | |
| 
 | |
|         // Dispose the overlay
 | |
|         if ( this._overlayRef )
 | |
|         {
 | |
|             this._overlayRef.dispose();
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     // -----------------------------------------------------------------------------------------------------
 | |
|     // @ Public methods
 | |
|     // -----------------------------------------------------------------------------------------------------
 | |
| 
 | |
|     /**
 | |
|      * Open the shortcuts panel
 | |
|      */
 | |
|     openPanel(): void
 | |
|     {
 | |
|         // Return if the shortcuts panel or its origin is not defined
 | |
|         if ( !this._shortcutsPanel || !this._shortcutsOrigin )
 | |
|         {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         // Make sure to start in 'view' mode
 | |
|         this.mode = 'view';
 | |
| 
 | |
|         // Create the overlay if it doesn't exist
 | |
|         if ( !this._overlayRef )
 | |
|         {
 | |
|             this._createOverlay();
 | |
|         }
 | |
| 
 | |
|         // Attach the portal to the overlay
 | |
|         this._overlayRef.attach(new TemplatePortal(this._shortcutsPanel, this._viewContainerRef));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Close the messages panel
 | |
|      */
 | |
|     closePanel(): void
 | |
|     {
 | |
|         this._overlayRef.detach();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Change the mode
 | |
|      */
 | |
|     changeMode(mode: 'view' | 'modify' | 'add' | 'edit'): void
 | |
|     {
 | |
|         // Change the mode
 | |
|         this.mode = mode;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Prepare for a new shortcut
 | |
|      */
 | |
|     newShortcut(): void
 | |
|     {
 | |
|         // Reset the form
 | |
|         this.shortcutForm.reset();
 | |
| 
 | |
|         // Enter the add mode
 | |
|         this.mode = 'add';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Edit a shortcut
 | |
|      */
 | |
|     editShortcut(shortcut: Shortcut): void
 | |
|     {
 | |
|         // Reset the form with the shortcut
 | |
|         this.shortcutForm.reset(shortcut);
 | |
| 
 | |
|         // Enter the edit mode
 | |
|         this.mode = 'edit';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Save shortcut
 | |
|      */
 | |
|     save(): void
 | |
|     {
 | |
|         // Get the data from the form
 | |
|         const shortcut = this.shortcutForm.value;
 | |
| 
 | |
|         // If there is an id, update it...
 | |
|         if ( shortcut.id )
 | |
|         {
 | |
|             this._shortcutsService.update(shortcut.id, shortcut).subscribe();
 | |
|         }
 | |
|         // Otherwise, create a new shortcut...
 | |
|         else
 | |
|         {
 | |
|             this._shortcutsService.create(shortcut).subscribe();
 | |
|         }
 | |
| 
 | |
|         // Go back the modify mode
 | |
|         this.mode = 'modify';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Delete shortcut
 | |
|      */
 | |
|     delete(): void
 | |
|     {
 | |
|         // Get the data from the form
 | |
|         const shortcut = this.shortcutForm.value;
 | |
| 
 | |
|         // Delete
 | |
|         this._shortcutsService.delete(shortcut.id).subscribe();
 | |
| 
 | |
|         // Go back the modify mode
 | |
|         this.mode = 'modify';
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Track by function for ngFor loops
 | |
|      *
 | |
|      * @param index
 | |
|      * @param item
 | |
|      */
 | |
|     trackByFn(index: number, item: any): any
 | |
|     {
 | |
|         return item.id || index;
 | |
|     }
 | |
| 
 | |
|     // -----------------------------------------------------------------------------------------------------
 | |
|     // @ Private methods
 | |
|     // -----------------------------------------------------------------------------------------------------
 | |
| 
 | |
|     /**
 | |
|      * Create the overlay
 | |
|      */
 | |
|     private _createOverlay(): void
 | |
|     {
 | |
|         // Create the overlay
 | |
|         this._overlayRef = this._overlay.create({
 | |
|             hasBackdrop     : true,
 | |
|             backdropClass   : 'fuse-backdrop-on-mobile',
 | |
|             scrollStrategy  : this._overlay.scrollStrategies.block(),
 | |
|             positionStrategy: this._overlay.position()
 | |
|                                   .flexibleConnectedTo(this._shortcutsOrigin._elementRef.nativeElement)
 | |
|                                   .withLockedPosition()
 | |
|                                   .withPush(true)
 | |
|                                   .withPositions([
 | |
|                                       {
 | |
|                                           originX : 'start',
 | |
|                                           originY : 'bottom',
 | |
|                                           overlayX: 'start',
 | |
|                                           overlayY: 'top'
 | |
|                                       },
 | |
|                                       {
 | |
|                                           originX : 'start',
 | |
|                                           originY : 'top',
 | |
|                                           overlayX: 'start',
 | |
|                                           overlayY: 'bottom'
 | |
|                                       },
 | |
|                                       {
 | |
|                                           originX : 'end',
 | |
|                                           originY : 'bottom',
 | |
|                                           overlayX: 'end',
 | |
|                                           overlayY: 'top'
 | |
|                                       },
 | |
|                                       {
 | |
|                                           originX : 'end',
 | |
|                                           originY : 'top',
 | |
|                                           overlayX: 'end',
 | |
|                                           overlayY: 'bottom'
 | |
|                                       }
 | |
|                                   ])
 | |
|         });
 | |
| 
 | |
|         // Detach the overlay from the portal on backdrop click
 | |
|         this._overlayRef.backdropClick().subscribe(() => {
 | |
|             this._overlayRef.detach();
 | |
|         });
 | |
|     }
 | |
| }
 |