Update to Angular 19 (#1)
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
@@ -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<FileOrFolder | undefined>(undefined);
|
||||
protected selectedMessage = signal<ProtoMessage | undefined>(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())
|
||||
|
||||
@@ -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' },
|
||||
|
||||
@@ -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<FileOrFolder>();
|
||||
selectedMessage = input.required<ProtoMessage>();
|
||||
indentSize = input<number>(2);
|
||||
@@ -80,7 +82,9 @@ export class EditorComponent {
|
||||
|
||||
private code = viewChild<ElementRef<HTMLElement>>('code');
|
||||
|
||||
constructor(sanitizer: DomSanitizer, private snackBar: MatSnackBar) {
|
||||
constructor() {
|
||||
const sanitizer = inject(DomSanitizer);
|
||||
|
||||
effect(() => {
|
||||
const element = this.code()?.nativeElement;
|
||||
if (element) {
|
||||
|
||||
@@ -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: `<h3>{{ label() }}</h3>
|
||||
selector: 'app-list-field',
|
||||
imports: [
|
||||
CommonModule,
|
||||
MatButtonModule,
|
||||
MatIconModule,
|
||||
forwardRef(() => ProtoFieldComponent),
|
||||
],
|
||||
template: `<h3>{{ label() }}</h3>
|
||||
@if(values()) { @for(value of values(); track $index) {
|
||||
<div class="row-wrapper">
|
||||
<app-proto-field
|
||||
@@ -38,8 +37,8 @@ import { ProtoFieldComponent } from '../proto-field/proto-field.component';
|
||||
<button mat-icon-button class="add-button" (click)="add()">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>`,
|
||||
styleUrl: './list-field.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
styleUrl: './list-field.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ListFieldComponent {
|
||||
label = input<string>();
|
||||
|
||||
@@ -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: `<h3>{{ label() }}</h3>
|
||||
selector: 'app-map-field',
|
||||
imports: [
|
||||
CommonModule,
|
||||
forwardRef(() => ProtoFieldComponent),
|
||||
MatIconModule,
|
||||
MatButtonModule,
|
||||
],
|
||||
template: `<h3>{{ label() }}</h3>
|
||||
@if(valuePairs()) { @for(value of valuePairs(); track $index) {
|
||||
<div class="row-wrapper">
|
||||
<app-proto-field
|
||||
@@ -45,8 +44,8 @@ const keyIsEmpty = (key: string | number) => key == null || key === '';
|
||||
<button mat-icon-button class="add-button" (click)="add()">
|
||||
<mat-icon>add</mat-icon>
|
||||
</button>`,
|
||||
styleUrl: './map-field.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
styleUrl: './map-field.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class MapFieldComponent {
|
||||
label = input<string>();
|
||||
|
||||
@@ -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: `<h3>
|
||||
selector: 'app-object-field',
|
||||
imports: [CommonModule, forwardRef(() => ProtoFieldComponent)],
|
||||
template: `<h3>
|
||||
{{ label() }} ({{ configuration().messageDefinition.name }})
|
||||
</h3>
|
||||
<div>
|
||||
@@ -27,8 +26,8 @@ import { ProtoFieldComponent } from '../proto-field/proto-field.component';
|
||||
></app-proto-field>
|
||||
}
|
||||
</div>`,
|
||||
styleUrl: './object-field.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
styleUrl: './object-field.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ObjectFieldComponent {
|
||||
label = input<string>();
|
||||
|
||||
@@ -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) {
|
||||
<app-string-field
|
||||
[label]="label()"
|
||||
[configuration]="stringConfiguration()"
|
||||
@@ -101,8 +100,8 @@ import { StringFieldComponent } from '../string-field/string-field.component';
|
||||
[configuration]="objectConfiguration()"
|
||||
></app-object-field>
|
||||
} @case (MessageTypeEnum.Raw) {}}`,
|
||||
styleUrl: './proto-field.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
styleUrl: './proto-field.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ProtoFieldComponent {
|
||||
label = input<string>();
|
||||
|
||||
@@ -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') {
|
||||
<mat-form-field>
|
||||
<mat-label>{{ label() }}</mat-label>
|
||||
<input
|
||||
@@ -44,8 +43,8 @@ import { MonacoEditorModule } from 'ngx-monaco-editor-v2';
|
||||
[options]="editorOptions"
|
||||
></ngx-monaco-editor>
|
||||
}`,
|
||||
styleUrl: './string-field.component.css',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
styleUrl: './string-field.component.css',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class StringFieldComponent {
|
||||
label = input();
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -21,7 +21,6 @@ import { StringEditorFieldComponent } from '../string-editor-field/string-editor
|
||||
|
||||
@Component({
|
||||
selector: 'app-definition-editor-field',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
|
||||
@@ -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<ProtoMessage>(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) {}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import { ListMessage } from '../../../model/proto-message.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-list-editor-field',
|
||||
standalone: true,
|
||||
imports: [CommonModule, forwardRef(() => DefinitionEditorFieldComponent)],
|
||||
template: `<app-definition-editor-field
|
||||
[fieldConfiguration]="field().subConfiguration"
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
|
||||
@Component({
|
||||
selector: 'app-map-editor-field',
|
||||
standalone: true,
|
||||
imports: [CommonModule, forwardRef(() => DefinitionEditorFieldComponent)],
|
||||
template: `
|
||||
<h4>Key Configuration</h4>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -8,7 +8,6 @@ import { MatInputModule } from '@angular/material/input';
|
||||
|
||||
@Component({
|
||||
selector: 'app-string-editor-field',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
|
||||
@@ -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<ProtoMessage>();
|
||||
|
||||
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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user