diff --git a/bun.lockb b/bun.lockb index 07cc97e..14aea36 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 72afcdf..834421f 100644 --- a/package.json +++ b/package.json @@ -11,18 +11,18 @@ }, "private": true, "dependencies": { - "@angular-devkit/build-angular": "^18.1.1", - "@angular/animations": "^18.1.1", - "@angular/cdk": "^18.1.1", - "@angular/common": "^18.1.1", - "@angular/compiler": "^18.1.1", - "@angular/core": "^18.1.1", - "@angular/forms": "^18.1.1", - "@angular/material": "^18.1.1", - "@angular/platform-browser": "^18.1.1", - "@angular/platform-browser-dynamic": "^18.1.1", - "@angular/router": "^18.1.1", - "@angular/service-worker": "^18.1.1", + "@angular-devkit/build-angular": "^19.1.6", + "@angular/animations": "^19.1.5", + "@angular/cdk": "^19.1.3", + "@angular/common": "^19.1.5", + "@angular/compiler": "^19.1.5", + "@angular/core": "^19.1.5", + "@angular/forms": "^19.1.5", + "@angular/material": "^19.1.3", + "@angular/platform-browser": "^19.1.5", + "@angular/platform-browser-dynamic": "^19.1.5", + "@angular/router": "^19.1.5", + "@angular/service-worker": "^19.1.5", "@tauri-apps/api": "^1.6.0", "highlight.js": "^11.10.0", "monaco-editor": "^0.50.0", @@ -30,12 +30,12 @@ "protobufjs": "^7.3.2", "rxjs": "^7.8.1", "tslib": "^2.6.3", - "zone.js": "^0.14.8" + "zone.js": "^0.15.0" }, "devDependencies": { - "@angular/build": "^18.1.1", - "@angular/cli": "^18.1.1", - "@angular/compiler-cli": "^18.1.1", + "@angular/build": "^19.1.6", + "@angular/cli": "^19.1.6", + "@angular/compiler-cli": "^19.1.5", "@tauri-apps/cli": "^1.6.0", "@types/jasmine": "^5.1.4", "@types/protobufjs": "^6.0.0", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 13b57bb..2a44b6f 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,13 +1,12 @@ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { CommonModule } from '@angular/common'; -import { Component, computed, signal } from '@angular/core'; +import { Component, signal, inject } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatToolbarModule } from '@angular/material/toolbar'; import { MatTreeModule } from '@angular/material/tree'; -import { RouterOutlet } from '@angular/router'; import { EditorComponent } from './editor/editor.component'; import { FileOrFolder, @@ -15,11 +14,11 @@ import { } from './file-tree/file-tree.component'; import { ProtoMessage } from './model/proto-message.model'; import { ProtoDefinitionSelectorComponent } from './proto-definition-selector/proto-definition-selector.component'; + const mobileBreakpoints = [Breakpoints.Handset, Breakpoints.TabletPortrait]; @Component({ selector: 'app-root', - standalone: true, templateUrl: './app.component.html', styleUrl: './app.component.scss', imports: [ @@ -32,10 +31,11 @@ const mobileBreakpoints = [Breakpoints.Handset, Breakpoints.TabletPortrait]; MatToolbarModule, MatTreeModule, ProtoDefinitionSelectorComponent, - RouterOutlet, ], }) export class AppComponent { + private breakpointObserver = inject(BreakpointObserver); + protected selectedFile = signal(undefined); protected selectedMessage = signal(undefined); protected rightSideOpen = signal(true); @@ -46,7 +46,9 @@ export class AppComponent { this.breakpointObserver.isMatched(mobileBreakpoints) ); - constructor(private breakpointObserver: BreakpointObserver) { + constructor() { + const breakpointObserver = this.breakpointObserver; + breakpointObserver .observe(mobileBreakpoints) .pipe(takeUntilDestroyed()) diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 19b9088..cb0fac6 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -1,8 +1,9 @@ import { - APP_INITIALIZER, ApplicationConfig, isDevMode, provideExperimentalZonelessChangeDetection, + provideAppInitializer, + inject, } from '@angular/core'; import { provideRouter } from '@angular/router'; @@ -22,24 +23,18 @@ export const appConfig: ApplicationConfig = { provideExperimentalZonelessChangeDetection(), provideRouter(routes), provideAnimationsAsync(), - { - provide: APP_INITIALIZER, - useValue: () => { - hljs.registerLanguage('json', json); - }, - multi: true, - }, - { - provide: APP_INITIALIZER, - useFactory: (iconRegistry: MatIconRegistry) => () => { + provideAppInitializer(() => { + hljs.registerLanguage('json', json); + }), + provideAppInitializer(() => { + const initializerFn = ((iconRegistry: MatIconRegistry) => () => { iconRegistry.registerFontClassAlias( 'material-symbols-rounded', 'material-symbols-rounded' ); - }, - deps: [MatIconRegistry], - multi: true, - }, + })(inject(MatIconRegistry)); + return initializerFn(); + }), { provide: MAT_ICON_DEFAULT_OPTIONS, useValue: { fontSet: 'material-symbols-rounded' }, diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts index ee62a1a..0777718 100644 --- a/src/app/editor/editor.component.ts +++ b/src/app/editor/editor.component.ts @@ -8,6 +8,7 @@ import { input, signal, viewChild, + inject, } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; @@ -29,7 +30,6 @@ type PreviewType = 'raw' | 'edit' | 'diff'; @Component({ selector: 'app-editor', - standalone: true, imports: [ CommonModule, ProtoFieldComponent, @@ -43,6 +43,8 @@ type PreviewType = 'raw' | 'edit' | 'diff'; styleUrl: './editor.component.scss', }) export class EditorComponent { + private snackBar = inject(MatSnackBar); + selectedFile = input(); selectedMessage = input.required(); indentSize = input(2); @@ -80,7 +82,9 @@ export class EditorComponent { private code = viewChild>('code'); - constructor(sanitizer: DomSanitizer, private snackBar: MatSnackBar) { + constructor() { + const sanitizer = inject(DomSanitizer); + effect(() => { const element = this.code()?.nativeElement; if (element) { diff --git a/src/app/editor/list-field/list-field.component.ts b/src/app/editor/list-field/list-field.component.ts index 1115a8b..4ee3b73 100644 --- a/src/app/editor/list-field/list-field.component.ts +++ b/src/app/editor/list-field/list-field.component.ts @@ -14,15 +14,14 @@ import { ListMessage } from '../../model/proto-message.model'; import { ProtoFieldComponent } from '../proto-field/proto-field.component'; @Component({ - selector: 'app-list-field', - standalone: true, - imports: [ - CommonModule, - MatButtonModule, - MatIconModule, - forwardRef(() => ProtoFieldComponent), - ], - template: `

{{ label() }}

+ selector: 'app-list-field', + imports: [ + CommonModule, + MatButtonModule, + MatIconModule, + forwardRef(() => ProtoFieldComponent), + ], + template: `

{{ label() }}

@if(values()) { @for(value of values(); track $index) {
add `, - styleUrl: './list-field.component.scss', - changeDetection: ChangeDetectionStrategy.OnPush, + styleUrl: './list-field.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush }) export class ListFieldComponent { label = input(); diff --git a/src/app/editor/map-field/map-field.component.ts b/src/app/editor/map-field/map-field.component.ts index 3dcf6c1..5a840ab 100644 --- a/src/app/editor/map-field/map-field.component.ts +++ b/src/app/editor/map-field/map-field.component.ts @@ -16,15 +16,14 @@ import { ProtoFieldComponent } from '../proto-field/proto-field.component'; const keyIsEmpty = (key: string | number) => key == null || key === ''; @Component({ - selector: 'app-map-field', - standalone: true, - imports: [ - CommonModule, - forwardRef(() => ProtoFieldComponent), - MatIconModule, - MatButtonModule, - ], - template: `

{{ label() }}

+ selector: 'app-map-field', + imports: [ + CommonModule, + forwardRef(() => ProtoFieldComponent), + MatIconModule, + MatButtonModule, + ], + template: `

{{ label() }}

@if(valuePairs()) { @for(value of valuePairs(); track $index) {
key == null || key === ''; `, - styleUrl: './map-field.component.scss', - changeDetection: ChangeDetectionStrategy.OnPush, + styleUrl: './map-field.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush }) export class MapFieldComponent { label = input(); diff --git a/src/app/editor/object-field/object-field.component.ts b/src/app/editor/object-field/object-field.component.ts index 7857240..725af8d 100644 --- a/src/app/editor/object-field/object-field.component.ts +++ b/src/app/editor/object-field/object-field.component.ts @@ -11,10 +11,9 @@ import { ObjectMessage } from '../../model/proto-message.model'; import { ProtoFieldComponent } from '../proto-field/proto-field.component'; @Component({ - selector: 'app-object-field', - standalone: true, - imports: [CommonModule, forwardRef(() => ProtoFieldComponent)], - template: `

+ selector: 'app-object-field', + imports: [CommonModule, forwardRef(() => ProtoFieldComponent)], + template: `

{{ label() }} ({{ configuration().messageDefinition.name }})

@@ -27,8 +26,8 @@ import { ProtoFieldComponent } from '../proto-field/proto-field.component'; > }
`, - styleUrl: './object-field.component.scss', - changeDetection: ChangeDetectionStrategy.OnPush, + styleUrl: './object-field.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush }) export class ObjectFieldComponent { label = input(); diff --git a/src/app/editor/proto-field/proto-field.component.ts b/src/app/editor/proto-field/proto-field.component.ts index 5f1bab2..a40ecbf 100644 --- a/src/app/editor/proto-field/proto-field.component.ts +++ b/src/app/editor/proto-field/proto-field.component.ts @@ -27,21 +27,20 @@ import { ObjectFieldComponent } from '../object-field/object-field.component'; import { StringFieldComponent } from '../string-field/string-field.component'; @Component({ - selector: 'app-proto-field', - standalone: true, - imports: [ - CommonModule, - FormsModule, - ListFieldComponent, - MapFieldComponent, - MatCheckboxModule, - MatFormFieldModule, - MatSelectModule, - MatInputModule, - ObjectFieldComponent, - StringFieldComponent, - ], - template: `@switch (configuration().type) { @case (MessageTypeEnum.String) { + selector: 'app-proto-field', + imports: [ + CommonModule, + FormsModule, + ListFieldComponent, + MapFieldComponent, + MatCheckboxModule, + MatFormFieldModule, + MatSelectModule, + MatInputModule, + ObjectFieldComponent, + StringFieldComponent, + ], + template: `@switch (configuration().type) { @case (MessageTypeEnum.String) { } @case (MessageTypeEnum.Raw) {}}`, - styleUrl: './proto-field.component.scss', - changeDetection: ChangeDetectionStrategy.OnPush, + styleUrl: './proto-field.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush }) export class ProtoFieldComponent { label = input(); diff --git a/src/app/editor/string-field/string-field.component.ts b/src/app/editor/string-field/string-field.component.ts index 7a0c074..6e04ecd 100644 --- a/src/app/editor/string-field/string-field.component.ts +++ b/src/app/editor/string-field/string-field.component.ts @@ -12,16 +12,15 @@ import { MatInputModule } from '@angular/material/input'; import { MonacoEditorModule } from 'ngx-monaco-editor-v2'; @Component({ - selector: 'app-string-field', - standalone: true, - imports: [ - CommonModule, - FormsModule, - MatFormFieldModule, - MatInputModule, - MonacoEditorModule, - ], - template: ` @if(configuration().textType === 'text') { + selector: 'app-string-field', + imports: [ + CommonModule, + FormsModule, + MatFormFieldModule, + MatInputModule, + MonacoEditorModule, + ], + template: ` @if(configuration().textType === 'text') { {{ label() }} }`, - styleUrl: './string-field.component.css', - changeDetection: ChangeDetectionStrategy.OnPush, + styleUrl: './string-field.component.css', + changeDetection: ChangeDetectionStrategy.OnPush }) export class StringFieldComponent { label = input(); diff --git a/src/app/file-tree/file-tree.component.ts b/src/app/file-tree/file-tree.component.ts index 03346ea..8b424bb 100644 --- a/src/app/file-tree/file-tree.component.ts +++ b/src/app/file-tree/file-tree.component.ts @@ -40,7 +40,6 @@ const collator = new Intl.Collator(undefined, { numeric: true }); @Component({ selector: 'app-file-tree', - standalone: true, imports: [CommonModule, MatButtonModule, MatIconModule, MatTreeModule], templateUrl: './file-tree.component.html', styleUrl: './file-tree.component.scss', diff --git a/src/app/proto-definition-selector/definition-editor/definition-editor-field/definition-editor-field.component.ts b/src/app/proto-definition-selector/definition-editor/definition-editor-field/definition-editor-field.component.ts index 9ea50dc..f1b7fba 100644 --- a/src/app/proto-definition-selector/definition-editor/definition-editor-field/definition-editor-field.component.ts +++ b/src/app/proto-definition-selector/definition-editor/definition-editor-field/definition-editor-field.component.ts @@ -21,7 +21,6 @@ import { StringEditorFieldComponent } from '../string-editor-field/string-editor @Component({ selector: 'app-definition-editor-field', - standalone: true, imports: [ CommonModule, FormsModule, diff --git a/src/app/proto-definition-selector/definition-editor/definition-editor.component.ts b/src/app/proto-definition-selector/definition-editor/definition-editor.component.ts index c1e0987..ac60ea5 100644 --- a/src/app/proto-definition-selector/definition-editor/definition-editor.component.ts +++ b/src/app/proto-definition-selector/definition-editor/definition-editor.component.ts @@ -1,5 +1,5 @@ import { CommonModule } from '@angular/common'; -import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { ChangeDetectionStrategy, Component, inject } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import { @@ -14,7 +14,6 @@ import { DefinitionEditorFieldComponent } from './definition-editor-field/defini @Component({ selector: 'app-definition-editor', - standalone: true, imports: [ CommonModule, MatButtonModule, @@ -39,6 +38,8 @@ import { DefinitionEditorFieldComponent } from './definition-editor-field/defini changeDetection: ChangeDetectionStrategy.OnPush, }) export class DefinitionEditorComponent { + protected protoMessage = inject(MAT_DIALOG_DATA); + protected editableMessages = this.protoMessage.values.filter((message) => this.filterMessageConfiguration(message.configuration) ); @@ -61,6 +62,4 @@ export class DefinitionEditorComponent { // Note: Map can always be configured, as key needs to be a string or numeric type return EDITABLE_MESSAGE_TYPES.includes(configuration.type); } - - constructor(@Inject(MAT_DIALOG_DATA) protected protoMessage: ProtoMessage) {} } diff --git a/src/app/proto-definition-selector/definition-editor/list-editor-field/list-editor-field.component.ts b/src/app/proto-definition-selector/definition-editor/list-editor-field/list-editor-field.component.ts index 78efc83..3298b49 100644 --- a/src/app/proto-definition-selector/definition-editor/list-editor-field/list-editor-field.component.ts +++ b/src/app/proto-definition-selector/definition-editor/list-editor-field/list-editor-field.component.ts @@ -10,7 +10,6 @@ import { ListMessage } from '../../../model/proto-message.model'; @Component({ selector: 'app-list-editor-field', - standalone: true, imports: [CommonModule, forwardRef(() => DefinitionEditorFieldComponent)], template: ` DefinitionEditorFieldComponent)], template: `

Key Configuration

diff --git a/src/app/proto-definition-selector/definition-editor/object-editor-field/object-editor-field.component.ts b/src/app/proto-definition-selector/definition-editor/object-editor-field/object-editor-field.component.ts index 7c2129a..eb5791f 100644 --- a/src/app/proto-definition-selector/definition-editor/object-editor-field/object-editor-field.component.ts +++ b/src/app/proto-definition-selector/definition-editor/object-editor-field/object-editor-field.component.ts @@ -14,7 +14,6 @@ import { DefinitionEditorFieldComponent } from '../definition-editor-field/defin @Component({ selector: 'app-object-editor-field', - standalone: true, imports: [CommonModule, forwardRef(() => DefinitionEditorFieldComponent)], template: ` @for (field of editableFields(); track $index) { diff --git a/src/app/proto-definition-selector/definition-editor/string-editor-field/string-editor-field.component.ts b/src/app/proto-definition-selector/definition-editor/string-editor-field/string-editor-field.component.ts index 79449ff..b3b18eb 100644 --- a/src/app/proto-definition-selector/definition-editor/string-editor-field/string-editor-field.component.ts +++ b/src/app/proto-definition-selector/definition-editor/string-editor-field/string-editor-field.component.ts @@ -8,7 +8,6 @@ import { MatInputModule } from '@angular/material/input'; @Component({ selector: 'app-string-editor-field', - standalone: true, imports: [ CommonModule, FormsModule, diff --git a/src/app/proto-definition-selector/proto-definition-selector.component.ts b/src/app/proto-definition-selector/proto-definition-selector.component.ts index 77baa0a..b4666bd 100644 --- a/src/app/proto-definition-selector/proto-definition-selector.component.ts +++ b/src/app/proto-definition-selector/proto-definition-selector.component.ts @@ -1,16 +1,5 @@ import { CommonModule } from '@angular/common'; -import { - ChangeDetectionStrategy, - ChangeDetectorRef, - Component, - ElementRef, - HostBinding, - HostListener, - computed, - output, - signal, - viewChild, -} from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostBinding, HostListener, computed, output, signal, viewChild, inject } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatListModule, MatSelectionList } from '@angular/material/list'; import { ProtoMessage } from '../model/proto-message.model'; @@ -29,7 +18,6 @@ const collator = new Intl.Collator(undefined, { numeric: true }); @Component({ selector: 'app-proto-definition-selector', - standalone: true, imports: [ CommonModule, MatButtonModule, @@ -102,6 +90,10 @@ const collator = new Intl.Collator(undefined, { numeric: true }); changeDetection: ChangeDetectionStrategy.OnPush, }) export class ProtoDefinitionSelectorComponent { + private protoDefinitionService = inject(ProtoDefinitionService); + private snackBar = inject(MatSnackBar); + private dialog = inject(MatDialog); + messageSelected = output(); protected protoSelector = @@ -135,12 +127,6 @@ export class ProtoDefinitionSelectorComponent { return this.isDragging(); } - constructor( - private protoDefinitionService: ProtoDefinitionService, - private snackBar: MatSnackBar, - private dialog: MatDialog - ) {} - protected async addDefinitionFiles() { const files = this.protoSelector()?.nativeElement.files; if (files) { diff --git a/src/styles.scss b/src/styles.scss index 6bb4c59..900b0b3 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,7 +1,8 @@ @use "@angular/material" as mat; @use "./theme.scss"; -@include mat.core(); +@include mat.elevation-classes(); +@include mat.app-background(); @mixin custom-colours($theme) { .mat-toolbar { @@ -20,7 +21,8 @@ } html { - @include mat.core-theme(theme.$rose-theme); + @include mat.elevation-classes(); + @include mat.app-background(); @include mat.toolbar-theme(theme.$rose-theme); @include mat.button-theme(theme.$rose-theme); @include mat.tree-theme(theme.$rose-theme);