Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/firebird-ng/src/app/components/shell/shell.component.ts is written in an unsupported language. File is not indexed.

0001 import {
0002   Component,
0003   HostListener,
0004   ViewChild,
0005   ViewContainerRef,
0006   ComponentRef,
0007   Type,
0008   EventEmitter,
0009   Output, ElementRef, Input,
0010 } from '@angular/core';
0011 import { CommonModule } from '@angular/common';
0012 import {Router} from '@angular/router';
0013 // Angular Material imports for the top bar
0014 import { MatToolbarModule } from '@angular/material/toolbar';
0015 import { MatButtonModule } from '@angular/material/button';
0016 import { MatIconModule } from '@angular/material/icon';
0017 import { MatMenuModule } from '@angular/material/menu';
0018 import {ThemeSwitcherComponent} from "../theme-switcher/theme-switcher.component";
0019 import {MatTooltip} from "@angular/material/tooltip";
0020 
0021 interface NavItem {
0022   label: string;
0023   route: string;
0024   external?: boolean;
0025   icon?: string;
0026   /** If true, shows up on wide screens directly. Otherwise in hamburger. */
0027   alwaysVisible?: boolean;
0028 }
0029 
0030 @Component({
0031   standalone: true,
0032   selector: 'app-shell',
0033   templateUrl: './shell.component.html',
0034   styleUrls: ['./shell.component.scss'],
0035   imports: [
0036     CommonModule,
0037     // Material modules needed for the top bar
0038     MatToolbarModule,
0039     MatButtonModule,
0040     MatIconModule,
0041     MatMenuModule,
0042     ThemeSwitcherComponent,
0043     MatTooltip
0044   ],
0045 })
0046 export class ShellComponent {
0047 
0048   /** The reference to the left container, for programmatic component creation */
0049   @ViewChild('leftPaneContainer', { read: ViewContainerRef, static: true })
0050   leftPaneContainer!: ViewContainerRef;
0051 
0052   /** The reference to the right container, for programmatic component creation */
0053   @ViewChild('rightPaneContainer', { read: ViewContainerRef, static: true })
0054   rightPaneContainer!: ViewContainerRef;
0055 
0056   /** The reference to main content container */
0057   @ViewChild('mainContent', { static: true }) mainContent!: ElementRef<HTMLElement>;
0058 
0059   /** Event emitted when the resizing of the left pane ends. Emits the new width. */
0060   @Output() onEndResizeLeft = new EventEmitter<number>();
0061 
0062   /** Event emitted when the resizing of the right pane ends. Emits the new width. */
0063   @Output() onEndResizeRight = new EventEmitter<number>();
0064 
0065   /** Event emitted when the visibility of the right panel is changed. */
0066   @Output() onVisibilityChangeRight = new EventEmitter<boolean>();
0067 
0068   /** Event emitted when the visibility of the left panel is changed. */
0069   @Output() onVisibilityChangeLeft = new EventEmitter<boolean>();
0070 
0071   /** Is left Pane visible by default */
0072   @Input()
0073   isLeftPaneVisible = false;
0074 
0075   /** Is right Pane visible by default */
0076   @Input()
0077   isRightPaneVisible = false;
0078 
0079   /** Shell resizing logic */
0080   private isResizingLeft = false;
0081   private isResizingRight = false;
0082   leftPaneWidth = 250;
0083   rightPaneWidth = 250;
0084 
0085 
0086 
0087   /** Top bar: whether the mobile menu is open */
0088   navOpen = false;
0089   /** Track current theme (light or dark) */
0090   isDarkTheme = false;
0091 
0092   /** Single place for nav items */
0093   navItems: NavItem[] = [
0094     { label: 'Doc', route: '/help', icon: 'menu_book', alwaysVisible: true },
0095     { label: 'Display', route: '/display', icon: 'monitor', alwaysVisible: true },
0096     { label: 'Configure', route: '/config', icon: 'tune', alwaysVisible: true },
0097     { label: 'GitHub Repo', route: 'https://github.com/eic/firebird', external: true, icon: 'code' },
0098     { label: 'Submit Ideas', route: 'https://github.com/eic/firebird/issues', external: true, icon: 'feedback' },
0099   ];
0100 
0101   constructor(
0102     private router: Router
0103   ) {}
0104 
0105   /** Resizing logic for left pane */
0106   onMouseDownLeft(event: MouseEvent) {
0107     this.isResizingLeft = true;
0108     event.preventDefault();
0109   }
0110 
0111   /** Resizing logic for right pane */
0112   onMouseDownRight(event: MouseEvent) {
0113     this.isResizingRight = true;
0114     event.preventDefault();
0115   }
0116 
0117   @HostListener('document:mousemove', ['$event'])
0118   onMouseMove(event: MouseEvent) {
0119     if (this.isResizingLeft) {
0120       const minWidth = 100;
0121       const maxWidth = window.innerWidth - this.rightPaneWidth - 100;
0122       const newWidth = event.clientX;
0123       this.leftPaneWidth = Math.max(minWidth, Math.min(newWidth, maxWidth));
0124       event.preventDefault();
0125     } else if (this.isResizingRight) {
0126       const minWidth = 100;
0127       const maxWidth = window.innerWidth - this.leftPaneWidth - 100;
0128       const newWidth = window.innerWidth - event.clientX;
0129       this.rightPaneWidth = Math.max(minWidth, Math.min(newWidth, maxWidth));
0130       event.preventDefault();
0131     }
0132   }
0133 
0134   @HostListener('document:mouseup')
0135   onMouseUp() {
0136     if (this.isResizingLeft) {
0137       this.isResizingLeft = false;
0138       this.onEndResizeLeft.emit(this.leftPaneWidth);
0139     }
0140     if (this.isResizingRight) {
0141       this.isResizingRight = false;
0142       this.onEndResizeRight.emit(this.rightPaneWidth);
0143     }
0144   }
0145 
0146   /** Programmatically add component to left pane */
0147   addComponentToLeftPane<T>(component: Type<T>, data?: Partial<T>): ComponentRef<T> {
0148     this.leftPaneContainer.clear();
0149     const componentRef = this.leftPaneContainer.createComponent(component);
0150     if (data) {
0151       Object.assign(componentRef.instance as object, data);
0152     }
0153     return componentRef;
0154   }
0155 
0156   /** Programmatically add component to right pane */
0157   addComponentToRightPane<T>(component: Type<T>, data?: Partial<T>): ComponentRef<T> {
0158     this.rightPaneContainer.clear();
0159     const componentRef = this.rightPaneContainer.createComponent(component);
0160     if (data) {
0161       Object.assign(componentRef.instance as object, data);
0162     }
0163     return componentRef;
0164   }
0165 
0166   toggleLeftPane() {
0167     this.isLeftPaneVisible = !this.isLeftPaneVisible;
0168     this.onVisibilityChangeLeft.emit(this.isLeftPaneVisible);
0169   }
0170 
0171   toggleRightPane() {
0172     this.isRightPaneVisible = !this.isRightPaneVisible;
0173     this.onVisibilityChangeRight.emit(this.isRightPaneVisible);
0174   }
0175 
0176   /** Toggle the mobile hamburger menu */
0177   toggleNavConfig() {
0178     this.navOpen = !this.navOpen;
0179   }
0180 
0181   /**
0182    * Returns the visible dimensions of the main content area.
0183    * Uses clientWidth/clientHeight to exclude scrollbars,
0184    * and subtracts side panel widths if they are visible.
0185    */
0186   getMainAreaVisibleDimensions(): { width: number; height: number } {
0187 
0188 
0189     const visibleWidth = this.mainContent.nativeElement.clientWidth -
0190       (this.isLeftPaneVisible ? this.leftPaneWidth : 0) -
0191       (this.isRightPaneVisible ? this.rightPaneWidth : 0);
0192     const visibleHeight = this.mainContent.nativeElement.clientHeight;
0193 
0194 
0195     console.log("Shell resize information: ")
0196     console.log("  mainContent.clientWidth:", this.mainContent.nativeElement.clientWidth);
0197     console.log("  mainContent.clientHeight:", this.mainContent.nativeElement.clientHeight);
0198     console.log("  isLeftPaneVisible:", this.isLeftPaneVisible);
0199     if(this.isLeftPaneVisible)
0200     {
0201       console.log("  leftPaneWidth:", this.leftPaneWidth);
0202     }
0203     console.log("  isRightPaneVisible:", this.isRightPaneVisible);
0204     if(this.isRightPaneVisible)
0205     {
0206       console.log("  rightPaneWidth:", this.rightPaneWidth);
0207     }
0208     console.log("  visibleWidth:", visibleWidth);
0209     console.log("  visibleHeight:", visibleHeight);
0210 
0211     return { width: visibleWidth, height: visibleHeight };
0212   }
0213 
0214   /** Clicking a nav item => external link or internal route */
0215   onNavItemClick(item: NavItem) {
0216     if (item.external) {
0217       window.open(item.route, '_blank');
0218     } else {
0219       this.router.navigateByUrl(item.route);
0220     }
0221     this.navOpen = false;
0222   }
0223 }