From fcdcf0235c0daf0c6caf65446cc23b7251657a5f Mon Sep 17 00:00:00 2001 From: Pop John Date: Thu, 23 Jan 2025 09:29:41 +0200 Subject: [PATCH] add terminal configurator base --- .../src/app/modules/admin/admin.module.ts | 4 +- .../components/admin/admin.component.html | 6 + ...terminal-style-configurator.component.html | 27 +++++ ...terminal-style-configurator.component.scss | 21 ++++ ...minal-style-configurator.component.spec.ts | 21 ++++ ...s-terminal-style-configurator.component.ts | 106 ++++++++++++++++++ .../ms-terminal/models/font-families.const.ts | 22 ++++ 7 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.html create mode 100644 frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.scss create mode 100644 frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.spec.ts create mode 100644 frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.ts create mode 100644 frontend/src/app/modules/shared/components/ms-terminal/models/font-families.const.ts diff --git a/frontend/src/app/modules/admin/admin.module.ts b/frontend/src/app/modules/admin/admin.module.ts index 81235cfa..175f5934 100644 --- a/frontend/src/app/modules/admin/admin.module.ts +++ b/frontend/src/app/modules/admin/admin.module.ts @@ -22,6 +22,7 @@ import { MatCardModule } from '@angular/material/card'; import { MatDividerModule } from '@angular/material/divider'; import { MatIconModule } from '@angular/material/icon'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { MsTerminalStyleConfiguratorComponent } from '../shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component'; import { AdminRoutingModule } from './admin-routing.module'; import { AdminComponent } from './components/admin/admin.component'; @@ -35,7 +36,8 @@ import { AdminComponent } from './components/admin/admin.component'; MatTooltipModule, MatButtonToggleModule, ReactiveFormsModule, - MatCardModule + MatCardModule, + MsTerminalStyleConfiguratorComponent ] }) export class AdminModule {} diff --git a/frontend/src/app/modules/admin/components/admin/admin.component.html b/frontend/src/app/modules/admin/components/admin/admin.component.html index 87d8383e..8c9e8d83 100644 --- a/frontend/src/app/modules/admin/components/admin/admin.component.html +++ b/frontend/src/app/modules/admin/components/admin/admin.component.html @@ -48,4 +48,10 @@ Expert + + +
Terminal styles configurator
+ + +
diff --git a/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.html b/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.html new file mode 100644 index 00000000..f17d08c9 --- /dev/null +++ b/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.html @@ -0,0 +1,27 @@ +
+
+
+
+ Font Size + + + +
+ +
+ Font Family + + + @for (font of fontFamilies; track font) { + + {{ font }} + + } + + +
+
+
+ +
+
diff --git a/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.scss b/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.scss new file mode 100644 index 00000000..3460e8b8 --- /dev/null +++ b/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.scss @@ -0,0 +1,21 @@ +.xterm-dynamic-style-wrapper { + display: flex; + gap: 1rem; + margin-top: 20px; +} + +.settings-form { + width: 300px; + display: flex; + flex-direction: column; +} + +.terminal-wrapper { + flex-grow: 1; + display: flex; + flex-direction: column; + + border: 10px solid var(--terminal-color); + background-color: var(--terminal-color); + border-radius: 10px; +} diff --git a/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.spec.ts b/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.spec.ts new file mode 100644 index 00000000..f1802b89 --- /dev/null +++ b/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { MsTerminalStyleConfiguratorComponent } from './ms-terminal-style-configurator.component'; + +describe('MsTerminalStyleConfiguratorComponent', () => { + let component: MsTerminalStyleConfiguratorComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [MsTerminalStyleConfiguratorComponent] + }).compileComponents(); + + fixture = TestBed.createComponent(MsTerminalStyleConfiguratorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.ts b/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.ts new file mode 100644 index 00000000..5f4916e6 --- /dev/null +++ b/frontend/src/app/modules/shared/components/ms-terminal/components/ms-terminal-style-configurator/ms-terminal-style-configurator.component.ts @@ -0,0 +1,106 @@ +import { CommonModule } from '@angular/common'; +import { + Component, + DestroyRef, + ElementRef, + inject, + OnDestroy, + OnInit, + ViewChild, + ViewEncapsulation +} from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatSelectModule } from '@angular/material/select'; +import { FitAddon } from '@xterm/addon-fit'; +import { Terminal } from '@xterm/xterm'; +import { fontFamilies } from '../../models/font-families.const'; + +@Component({ + selector: 'ms-terminal-style-configurator', + standalone: true, + imports: [CommonModule, FormsModule, ReactiveFormsModule, MatFormFieldModule, MatInputModule, MatSelectModule], + templateUrl: './ms-terminal-style-configurator.component.html', + styleUrl: './ms-terminal-style-configurator.component.scss', + encapsulation: ViewEncapsulation.None +}) +export class MsTerminalStyleConfiguratorComponent implements OnInit, OnDestroy { + @ViewChild('terminalContainer', { static: true }) terminalDiv!: ElementRef; + + private destroyRef = inject(DestroyRef); + private fb = inject(FormBuilder); + public fontFamilies = fontFamilies; + + private terminal!: Terminal; + private fitAddon = new FitAddon(); + private resizeObserver?: ResizeObserver; + + public form: FormGroup = this.fb.group({ + fontSize: [14], + fontFamily: ['Courier New'], + background: ['#1e1e1e'], + foreground: ['#ffffff'] + }); + + ngOnInit(): void { + this.initializeTerminal(); + + this.writeTerminalDemoText(); + this.listenToStyleChanges(); + } + + private initializeTerminal(): void { + this.terminal = new Terminal({ + cursorBlink: true, + theme: { + background: '#D0D4D9', + foreground: '#000000', + cursor: '#000000', + selectionBackground: '#FFDD00', + selectionForeground: '#000000' + }, + allowProposedApi: true, + scrollback: 1000 + }); + + this.terminal.loadAddon(this.fitAddon); + this.terminal.open(this.terminalDiv.nativeElement); + this.setupResizeObserver(); + } + + private listenToStyleChanges(): void { + this.form.valueChanges.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((values) => { + this.terminal.options.fontSize = values.fontSize; + this.terminal.options.fontFamily = values.fontFamily; + + this.fitAddon.fit(); + }); + } + + private setupResizeObserver(): void { + if (this.resizeObserver) { + this.resizeObserver.disconnect(); + } + this.resizeObserver = new ResizeObserver(() => { + this.fitAddon.fit(); + }); + this.resizeObserver.observe(this.terminalDiv.nativeElement); + } + + private writeTerminalDemoText(): void { + const demoText = + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.Vestibulum vehicula ex eu gravida cursus. Curabitur ac ultrices odio. Integer sit amet neque at elit facilisis placerat. Phasellus euismod, sapien a interdum tempus, leo sapien commodo lacus, a posuere lacus tortor at justo. Sed sit amet urna vitae tortor commodo luctus. Nulla facilisi. Vivamus at felis eget sapien volutpat tincidunt. Mauris ut massa vel nunc aliquam semper. Praesent at dui ut neque dapibus tincidunt. Etiam euismod, metus at facilisis finibus, massa arcu bibendum orci, in semper justo turpis nec arcu.'; + + this.terminal.writeln('Welcome to xterm.js!\n'); + this.terminal.writeln(demoText); + } + + ngOnDestroy(): void { + this.resizeObserver?.disconnect(); + if (this.terminal) { + this.terminal.dispose(); + } + } +} diff --git a/frontend/src/app/modules/shared/components/ms-terminal/models/font-families.const.ts b/frontend/src/app/modules/shared/components/ms-terminal/models/font-families.const.ts new file mode 100644 index 00000000..0ae06c0c --- /dev/null +++ b/frontend/src/app/modules/shared/components/ms-terminal/models/font-families.const.ts @@ -0,0 +1,22 @@ +export const fontFamilies: string[] = [ + 'Arial', + 'Helvetica', + 'Times New Roman', + 'Courier New', + 'Verdana', + 'Georgia', + 'Palatino', + 'Garamond', + 'Bookman', + 'Comic Sans MS', + 'Trebuchet MS', + 'Arial Black', + 'Impact', + 'Lucida Sans Unicode', + 'Tahoma', + 'Geneva', + 'Consolas', + 'Monaco', + 'Lucida Console', + 'Segoe UI' +];