From ddc20daaa5d4be818378c26b38a507f47b7b6ef4 Mon Sep 17 00:00:00 2001 From: vato007 Date: Sat, 29 Jun 2024 11:31:56 +0930 Subject: [PATCH] Add initial components to proto message field --- src/app/app.component.html | 11 ++- src/app/app.component.ts | 21 ++++-- src/app/editor/editor.component.html | 9 ++- src/app/editor/editor.component.ts | 21 ++++-- src/app/file-tree/file-tree.component.html | 1 + src/app/file-tree/file-tree.component.scss | 6 ++ src/app/file-tree/file-tree.component.ts | 11 +-- src/app/list-field/list-field.component.scss | 3 + src/app/list-field/list-field.component.ts | 34 +++++++++ src/app/model/proto-message.model.ts | 9 +-- .../proto-definition-selector.component.ts | 7 +- src/app/proto-definition.service.ts | 1 - .../proto-field/proto-field.component.scss | 3 + src/app/proto-field/proto-field.component.ts | 74 +++++++++++++++++++ 14 files changed, 175 insertions(+), 36 deletions(-) create mode 100644 src/app/list-field/list-field.component.scss create mode 100644 src/app/list-field/list-field.component.ts create mode 100644 src/app/proto-field/proto-field.component.scss create mode 100644 src/app/proto-field/proto-field.component.ts diff --git a/src/app/app.component.html b/src/app/app.component.html index 1144aaa..28231fc 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -24,7 +24,10 @@ [opened]="leftSideOpen()" (closed)="leftSideOpen.set(false)" > - + } - }@else { - - } + }@else { @if(selectedMessage()) { + + } } diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 648421f..f292bd7 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,6 +1,6 @@ import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; import { CommonModule } from '@angular/common'; -import { Component, signal } from '@angular/core'; +import { Component, computed, signal } from '@angular/core'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatIconModule } from '@angular/material/icon'; @@ -28,15 +28,15 @@ const mobileBreakpoints = [Breakpoints.Handset, Breakpoints.TabletPortrait]; styleUrl: './app.component.scss', imports: [ CommonModule, - RouterOutlet, - MatSidenavModule, + EditorComponent, + FileTreeComponent, MatButtonModule, + MatIconModule, + MatSidenavModule, MatToolbarModule, MatTreeModule, - FileTreeComponent, - MatIconModule, - EditorComponent, ProtoDefinitionSelectorComponent, + RouterOutlet, ], }) export class AppComponent { @@ -52,6 +52,15 @@ export class AppComponent { this.breakpointObserver.isMatched(mobileBreakpoints) ); + protected directoryName = computed(() => { + const directory = this.selectedDirectory(); + if (directory) { + const directorySplit = directory.split('/'); + return directorySplit[directorySplit.length - 1]; + } + return null; + }); + constructor(private breakpointObserver: BreakpointObserver) { breakpointObserver .observe(mobileBreakpoints) diff --git a/src/app/editor/editor.component.html b/src/app/editor/editor.component.html index 0cbf154..7fc713b 100644 --- a/src/app/editor/editor.component.html +++ b/src/app/editor/editor.component.html @@ -1,3 +1,10 @@ - +
+ @for (item of selectedMessage().values; track $index) { + + } +
{{fileContents()}}
diff --git a/src/app/editor/editor.component.ts b/src/app/editor/editor.component.ts index 822469b..1dcc59e 100644 --- a/src/app/editor/editor.component.ts +++ b/src/app/editor/editor.component.ts @@ -1,23 +1,32 @@ import { CommonModule } from '@angular/common'; -import { Component, ElementRef, effect, input, viewChild } from '@angular/core'; -import { FormsModule } from '@angular/forms'; +import { + Component, + ElementRef, + effect, + input, + signal, + viewChild, +} from '@angular/core'; import hljs from 'highlight.js/lib/core'; import { ProtoMessage } from '../model/proto-message.model'; -import { ProtoDefinitionService } from '../proto-definition.service'; +import { ProtoFieldComponent } from '../proto-field/proto-field.component'; @Component({ selector: 'app-editor', standalone: true, - imports: [CommonModule, FormsModule], + imports: [CommonModule, ProtoFieldComponent], templateUrl: './editor.component.html', styleUrl: './editor.component.scss', }) export class EditorComponent { + // TODO: This needs to be reworked so we have a local property and implement some kind of auto-save fileContents = input(); - selectedMessage = input(); + selectedMessage = input.required(); + // TODO: This needs to start with the parsed file contents, and get updated when the code value changes + protected values = signal([]); private code = viewChild>('code'); - constructor(private protoDefinitionService: ProtoDefinitionService) { + constructor() { effect(() => { const element = this.code()?.nativeElement; if (element) { diff --git a/src/app/file-tree/file-tree.component.html b/src/app/file-tree/file-tree.component.html index 3b7cbcb..99097b9 100644 --- a/src/app/file-tree/file-tree.component.html +++ b/src/app/file-tree/file-tree.component.html @@ -1,3 +1,4 @@ +

{{ workspaceName() }}

(); files = input([]); fileSelected = output(); diff --git a/src/app/list-field/list-field.component.scss b/src/app/list-field/list-field.component.scss new file mode 100644 index 0000000..5d4e87f --- /dev/null +++ b/src/app/list-field/list-field.component.scss @@ -0,0 +1,3 @@ +:host { + display: block; +} diff --git a/src/app/list-field/list-field.component.ts b/src/app/list-field/list-field.component.ts new file mode 100644 index 0000000..427dc73 --- /dev/null +++ b/src/app/list-field/list-field.component.ts @@ -0,0 +1,34 @@ +import { CommonModule } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + input, + model, +} from '@angular/core'; +import { MatButton } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { ProtoFieldComponent } from '../proto-field/proto-field.component'; +import { + EnumMessage, + ListMessage, + ProtoMessageField, +} from '../model/proto-message.model'; + +@Component({ + selector: 'app-list-field', + standalone: true, + imports: [CommonModule, MatButton, MatIconModule, ProtoFieldComponent], + template: ` @for(value of values(); track values()) { + + } + `, + styleUrl: './list-field.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ListFieldComponent { + configuration = input.required(); + values = model(); +} diff --git a/src/app/model/proto-message.model.ts b/src/app/model/proto-message.model.ts index a508780..5939ac4 100644 --- a/src/app/model/proto-message.model.ts +++ b/src/app/model/proto-message.model.ts @@ -86,10 +86,9 @@ export const EnumMessage = (options: string[]) => ({ options, }); -export interface ProtoMessageField { +export interface ProtoMessageField { name: string; - configuration: MessageConfiguration; - value: any; + configuration: T; } export interface ProtoBase { @@ -97,7 +96,7 @@ export interface ProtoBase { } export interface ProtoMessage extends ProtoBase { - values: ProtoMessageField[]; + values: ProtoMessageField[]; } export interface ProtoEnum extends ProtoBase { @@ -106,5 +105,5 @@ export interface ProtoEnum extends ProtoBase { export const UnknownProto = (name: string): ProtoMessage => ({ name, - values: [{ name: 'Raw JSON', configuration: RawMessage(), value: '' }], + values: [{ name: 'Raw JSON', configuration: RawMessage() }], }); 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 21c6f70..cc0e5da 100644 --- a/src/app/proto-definition-selector/proto-definition-selector.component.ts +++ b/src/app/proto-definition-selector/proto-definition-selector.component.ts @@ -1,26 +1,23 @@ -import { MediaMatcher } from '@angular/cdk/layout'; import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, - ChangeDetectorRef, Component, ElementRef, HostBinding, HostListener, - OnDestroy, output, signal, viewChild, } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; import { MatListModule } from '@angular/material/list'; import { ProtoMessage } from '../model/proto-message.model'; import { ProtoDefinitionService } from '../proto-definition.service'; -import { MatButtonModule } from '@angular/material/button'; @Component({ selector: 'app-proto-definition-selector', standalone: true, - imports: [CommonModule, MatListModule, MatButtonModule], + imports: [CommonModule, MatButtonModule, MatListModule], template: `

Protobuf Definitions

diff --git a/src/app/proto-definition.service.ts b/src/app/proto-definition.service.ts index c506f12..ed61208 100644 --- a/src/app/proto-definition.service.ts +++ b/src/app/proto-definition.service.ts @@ -164,7 +164,6 @@ export class ProtoDefinitionService { convertedFields.values.push({ name: field.name, configuration: type, - value: '', }); } else { console.error(`Failed to find type ${field.type}`); diff --git a/src/app/proto-field/proto-field.component.scss b/src/app/proto-field/proto-field.component.scss new file mode 100644 index 0000000..5d4e87f --- /dev/null +++ b/src/app/proto-field/proto-field.component.scss @@ -0,0 +1,3 @@ +:host { + display: block; +} diff --git a/src/app/proto-field/proto-field.component.ts b/src/app/proto-field/proto-field.component.ts new file mode 100644 index 0000000..e3815c8 --- /dev/null +++ b/src/app/proto-field/proto-field.component.ts @@ -0,0 +1,74 @@ +import { CommonModule } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + computed, + input, + model, +} from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatSelectModule } from '@angular/material/select'; +import { ListFieldComponent } from '../list-field/list-field.component'; +import { + EnumMessage, + ListMessage, + MessageConfiguration, + MessageTypeEnum, +} from '../model/proto-message.model'; + +@Component({ + selector: 'app-proto-field', + standalone: true, + imports: [ + CommonModule, + FormsModule, + ListFieldComponent, + MatCheckboxModule, + MatFormFieldModule, + MatSelectModule, + ], + template: `@switch (configuration().type) { @case (MessageTypeEnum.String) { + + } @case (MessageTypeEnum.Numeric) { + + } @case (MessageTypeEnum.Boolean) { + + } @case(MessageTypeEnum.Enum) { + + @for(option of enumConfiguration()!.options; track + enumConfiguration()!.options) { + + } + + } @case (MessageTypeEnum.List) { + + } @case (MessageTypeEnum.Map){} @case (MessageTypeEnum.Object) {} @case + (MessageTypeEnum.Raw) {}}`, + styleUrl: './proto-field.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ProtoFieldComponent { + configuration = input.required(); + value = model(); + + protected enumConfiguration = computed(() => { + if (this.configuration().type === MessageTypeEnum.Enum) { + return this.configuration() as EnumMessage; + } + return null; + }); + + protected listConfiguration = computed(() => { + if (this.configuration().type === MessageTypeEnum.List) { + return this.configuration() as ListMessage; + } + return null; + }); + + protected readonly MessageTypeEnum = MessageTypeEnum; +}