Remove common module, add friendy name editing, add enum options editing, fix list option warning
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { Component, signal, inject } from '@angular/core';
|
import { Component, signal, inject } from '@angular/core';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
@@ -22,7 +21,6 @@ const mobileBreakpoints = [Breakpoints.Handset, Breakpoints.TabletPortrait];
|
|||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.scss',
|
styleUrl: './app.component.scss',
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
|
||||||
EditorComponent,
|
EditorComponent,
|
||||||
FileTreeComponent,
|
FileTreeComponent,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="editor-items">
|
<div class="editor-items">
|
||||||
@if(values()) { @for (item of selectedMessage().values; track $index) {
|
@if(values()) { @for (item of selectedMessage().values; track $index) {
|
||||||
<app-proto-field
|
<app-proto-field
|
||||||
[label]="item.name"
|
[label]="item.friendlyName || item.name"
|
||||||
[configuration]="item.configuration"
|
[configuration]="item.configuration"
|
||||||
[value]="values()[item.name]"
|
[value]="values()[item.name]"
|
||||||
(valueChange)="updateValue(item.name, $event)"
|
(valueChange)="updateValue(item.name, $event)"
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
@@ -31,7 +30,6 @@ type PreviewType = 'raw' | 'edit' | 'diff';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-editor',
|
selector: 'app-editor',
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
|
||||||
ProtoFieldComponent,
|
ProtoFieldComponent,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatButtonToggleModule,
|
MatButtonToggleModule,
|
||||||
@@ -102,17 +100,14 @@ export class EditorComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
effect(
|
effect(() => {
|
||||||
() => {
|
|
||||||
const message = this.selectedMessage();
|
const message = this.selectedMessage();
|
||||||
this.values.set(
|
this.values.set(
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
message.values.map((value) => [[value.name, undefined]])
|
message.values.map((value) => [[value.name, undefined]])
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
},
|
});
|
||||||
{ allowSignalWrites: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
effect(async () => {
|
effect(async () => {
|
||||||
const selectedFile = this.selectedFile();
|
const selectedFile = this.selectedFile();
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
AfterViewInit,
|
AfterViewInit,
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
@@ -16,7 +15,6 @@ import { ProtoFieldComponent } from '../proto-field/proto-field.component';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-list-field',
|
selector: 'app-list-field',
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
forwardRef(() => ProtoFieldComponent),
|
forwardRef(() => ProtoFieldComponent),
|
||||||
@@ -38,7 +36,7 @@ import { ProtoFieldComponent } from '../proto-field/proto-field.component';
|
|||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
</button>`,
|
</button>`,
|
||||||
styleUrl: './list-field.component.scss',
|
styleUrl: './list-field.component.scss',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class ListFieldComponent {
|
export class ListFieldComponent {
|
||||||
label = input<string>();
|
label = input<string>();
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
@@ -18,7 +17,6 @@ const keyIsEmpty = (key: string | number) => key == null || key === '';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-map-field',
|
selector: 'app-map-field',
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
|
||||||
forwardRef(() => ProtoFieldComponent),
|
forwardRef(() => ProtoFieldComponent),
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
@@ -45,7 +43,7 @@ const keyIsEmpty = (key: string | number) => key == null || key === '';
|
|||||||
<mat-icon>add</mat-icon>
|
<mat-icon>add</mat-icon>
|
||||||
</button>`,
|
</button>`,
|
||||||
styleUrl: './map-field.component.scss',
|
styleUrl: './map-field.component.scss',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class MapFieldComponent {
|
export class MapFieldComponent {
|
||||||
label = input<string>();
|
label = input<string>();
|
||||||
@@ -57,8 +55,7 @@ export class MapFieldComponent {
|
|||||||
private changedInternal = false;
|
private changedInternal = false;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
effect(
|
effect(() => {
|
||||||
() => {
|
|
||||||
// TODO: Super hacky but can't really think of another way to keep these in sync
|
// TODO: Super hacky but can't really think of another way to keep these in sync
|
||||||
// without removing an entry when the key gets blanked. Would need an alternate
|
// without removing an entry when the key gets blanked. Would need an alternate
|
||||||
// design that updated on blur only perhaps
|
// design that updated on blur only perhaps
|
||||||
@@ -70,9 +67,7 @@ export class MapFieldComponent {
|
|||||||
if (values) {
|
if (values) {
|
||||||
this.valuePairs.set(Object.entries(values));
|
this.valuePairs.set(Object.entries(values));
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
{ allowSignalWrites: true }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add() {
|
add() {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
@@ -12,14 +11,14 @@ import { ProtoFieldComponent } from '../proto-field/proto-field.component';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-object-field',
|
selector: 'app-object-field',
|
||||||
imports: [CommonModule, forwardRef(() => ProtoFieldComponent)],
|
imports: [forwardRef(() => ProtoFieldComponent)],
|
||||||
template: `<h3>
|
template: `<h3>
|
||||||
{{ label() }} ({{ configuration().messageDefinition.name }})
|
{{ label() }} ({{ configuration().messageDefinition.name }})
|
||||||
</h3>
|
</h3>
|
||||||
<div>
|
<div>
|
||||||
@for (item of configuration().messageDefinition.values; track $index) {
|
@for (item of configuration().messageDefinition.values; track $index) {
|
||||||
<app-proto-field
|
<app-proto-field
|
||||||
[label]="item.name"
|
[label]="item.friendlyName || item.name"
|
||||||
[configuration]="item.configuration"
|
[configuration]="item.configuration"
|
||||||
[value]="currentValue()[item.name]"
|
[value]="currentValue()[item.name]"
|
||||||
(valueChange)="updateValue(item.name, $event)"
|
(valueChange)="updateValue(item.name, $event)"
|
||||||
@@ -27,7 +26,7 @@ import { ProtoFieldComponent } from '../proto-field/proto-field.component';
|
|||||||
}
|
}
|
||||||
</div>`,
|
</div>`,
|
||||||
styleUrl: './object-field.component.scss',
|
styleUrl: './object-field.component.scss',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class ObjectFieldComponent {
|
export class ObjectFieldComponent {
|
||||||
label = input<string>();
|
label = input<string>();
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
@@ -29,7 +28,6 @@ import { StringFieldComponent } from '../string-field/string-field.component';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-proto-field',
|
selector: 'app-proto-field',
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ListFieldComponent,
|
ListFieldComponent,
|
||||||
MapFieldComponent,
|
MapFieldComponent,
|
||||||
@@ -57,14 +55,17 @@ import { StringFieldComponent } from '../string-field/string-field.component';
|
|||||||
[min]="numericConfiguration().min ?? null"
|
[min]="numericConfiguration().min ?? null"
|
||||||
[max]="numericConfiguration().max ?? null"
|
[max]="numericConfiguration().max ?? null"
|
||||||
/>
|
/>
|
||||||
<mat-hint *ngIf="number.hasError('min')"
|
@if(number.hasError('min')) {
|
||||||
|
<mat-hint
|
||||||
>Number should not be less than
|
>Number should not be less than
|
||||||
{{ numericConfiguration().min }}</mat-hint
|
{{ numericConfiguration().min }}</mat-hint
|
||||||
>
|
>
|
||||||
<mat-hint *ngIf="number.hasError('max')"
|
} @if(number.hasError('max')) {
|
||||||
|
<mat-hint
|
||||||
>Number should not greater than
|
>Number should not greater than
|
||||||
{{ numericConfiguration().max }}</mat-hint
|
{{ numericConfiguration().max }}</mat-hint
|
||||||
>
|
>
|
||||||
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
} @case (MessageTypeEnum.Boolean) {
|
} @case (MessageTypeEnum.Boolean) {
|
||||||
<p>
|
<p>
|
||||||
@@ -74,10 +75,11 @@ import { StringFieldComponent } from '../string-field/string-field.component';
|
|||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>{{ label() }}</mat-label>
|
<mat-label>{{ label() }}</mat-label>
|
||||||
<mat-select [(value)]="value">
|
<mat-select [(value)]="value">
|
||||||
@for(option of enumConfiguration().options; track
|
|
||||||
enumConfiguration()!.options) {
|
|
||||||
<mat-option>None</mat-option>
|
<mat-option>None</mat-option>
|
||||||
<mat-option [value]="option">{{ option }}</mat-option>
|
@for(option of enumConfiguration().options; track option) {
|
||||||
|
<mat-option [value]="option">{{
|
||||||
|
option.friendlyName || option.protoName
|
||||||
|
}}</mat-option>
|
||||||
}
|
}
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@@ -101,7 +103,7 @@ import { StringFieldComponent } from '../string-field/string-field.component';
|
|||||||
></app-object-field>
|
></app-object-field>
|
||||||
} @case (MessageTypeEnum.Raw) {}}`,
|
} @case (MessageTypeEnum.Raw) {}}`,
|
||||||
styleUrl: './proto-field.component.scss',
|
styleUrl: './proto-field.component.scss',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class ProtoFieldComponent {
|
export class ProtoFieldComponent {
|
||||||
label = input<string>();
|
label = input<string>();
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
@@ -14,7 +13,6 @@ import { MonacoEditorModule } from 'ngx-monaco-editor-v2';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-string-field',
|
selector: 'app-string-field',
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
FormsModule,
|
||||||
MatFormFieldModule,
|
MatFormFieldModule,
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
@@ -44,7 +42,7 @@ import { MonacoEditorModule } from 'ngx-monaco-editor-v2';
|
|||||||
></ngx-monaco-editor>
|
></ngx-monaco-editor>
|
||||||
}`,
|
}`,
|
||||||
styleUrl: './string-field.component.css',
|
styleUrl: './string-field.component.css',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class StringFieldComponent {
|
export class StringFieldComponent {
|
||||||
label = input();
|
label = input();
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { FlatTreeControl } from '@angular/cdk/tree';
|
import { FlatTreeControl } from '@angular/cdk/tree';
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
@@ -40,7 +39,7 @@ const collator = new Intl.Collator(undefined, { numeric: true });
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-file-tree',
|
selector: 'app-file-tree',
|
||||||
imports: [CommonModule, MatButtonModule, MatIconModule, MatTreeModule],
|
imports: [MatButtonModule, MatIconModule, MatTreeModule],
|
||||||
templateUrl: './file-tree.component.html',
|
templateUrl: './file-tree.component.html',
|
||||||
styleUrl: './file-tree.component.scss',
|
styleUrl: './file-tree.component.scss',
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -38,8 +38,13 @@ export interface ObjectMessage extends MessageConfiguration {
|
|||||||
|
|
||||||
export interface RawMessage extends MessageConfiguration {}
|
export interface RawMessage extends MessageConfiguration {}
|
||||||
|
|
||||||
|
export interface EnumMessageOption {
|
||||||
|
protoName: string;
|
||||||
|
friendlyName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface EnumMessage extends MessageConfiguration {
|
export interface EnumMessage extends MessageConfiguration {
|
||||||
options: string[];
|
options: EnumMessageOption[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MessageConfiguration {
|
export interface MessageConfiguration {
|
||||||
@@ -90,11 +95,12 @@ export const RawMessage = (): RawMessage => ({ type: MessageTypeEnum.Raw });
|
|||||||
|
|
||||||
export const EnumMessage = (options: string[]) => ({
|
export const EnumMessage = (options: string[]) => ({
|
||||||
type: MessageTypeEnum.Enum,
|
type: MessageTypeEnum.Enum,
|
||||||
options,
|
options: options.map((option) => ({ protoName: option })),
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface ProtoMessageField<T extends MessageConfiguration> {
|
export interface ProtoMessageField<T extends MessageConfiguration> {
|
||||||
name: string;
|
name: string;
|
||||||
|
friendlyName?: string;
|
||||||
configuration: T;
|
configuration: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +125,9 @@ export const UnknownProto = (
|
|||||||
): ProtoMessage => ({
|
): ProtoMessage => ({
|
||||||
name,
|
name,
|
||||||
fullName,
|
fullName,
|
||||||
values: [{ name: 'Raw JSON', configuration: RawMessage() }],
|
values: [
|
||||||
|
{ name: 'Raw JSON', friendlyName: 'Raw JSON', configuration: RawMessage() },
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
export const EDITABLE_MESSAGE_TYPES = [
|
export const EDITABLE_MESSAGE_TYPES = [
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
|
EnumMessage,
|
||||||
ListMessage,
|
ListMessage,
|
||||||
MapMessage,
|
MapMessage,
|
||||||
MessageConfiguration,
|
MessageConfiguration,
|
||||||
MessageTypeEnum,
|
MessageTypeEnum,
|
||||||
NumericMessage,
|
NumericMessage,
|
||||||
ObjectMessage,
|
ObjectMessage,
|
||||||
ProtoMessageField,
|
|
||||||
StringMessage,
|
StringMessage,
|
||||||
} from '../../../model/proto-message.model';
|
} from '../../../model/proto-message.model';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
@@ -18,11 +17,11 @@ import { ListEditorFieldComponent } from '../list-editor-field/list-editor-field
|
|||||||
import { MapEditorFieldComponent } from '../map-editor-field/map-editor-field.component';
|
import { MapEditorFieldComponent } from '../map-editor-field/map-editor-field.component';
|
||||||
import { ObjectEditorFieldComponent } from '../object-editor-field/object-editor-field.component';
|
import { ObjectEditorFieldComponent } from '../object-editor-field/object-editor-field.component';
|
||||||
import { StringEditorFieldComponent } from '../string-editor-field/string-editor-field.component';
|
import { StringEditorFieldComponent } from '../string-editor-field/string-editor-field.component';
|
||||||
|
import { EnumEditorFieldComponent } from '../enum-editor-field/enum-editor-field.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-definition-editor-field',
|
selector: 'app-definition-editor-field',
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
|
||||||
FormsModule,
|
FormsModule,
|
||||||
ListEditorFieldComponent,
|
ListEditorFieldComponent,
|
||||||
MapEditorFieldComponent,
|
MapEditorFieldComponent,
|
||||||
@@ -31,6 +30,7 @@ import { StringEditorFieldComponent } from '../string-editor-field/string-editor
|
|||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
ObjectEditorFieldComponent,
|
ObjectEditorFieldComponent,
|
||||||
StringEditorFieldComponent,
|
StringEditorFieldComponent,
|
||||||
|
EnumEditorFieldComponent,
|
||||||
],
|
],
|
||||||
template: ` @switch (fieldConfiguration().type) {
|
template: ` @switch (fieldConfiguration().type) {
|
||||||
@case(MessageTypeEnum.String) {
|
@case(MessageTypeEnum.String) {
|
||||||
@@ -48,9 +48,11 @@ import { StringEditorFieldComponent } from '../string-editor-field/string-editor
|
|||||||
[(ngModel)]="configuration.min"
|
[(ngModel)]="configuration.min"
|
||||||
[max]="configuration.max ?? null"
|
[max]="configuration.max ?? null"
|
||||||
/>
|
/>
|
||||||
<mat-hint *ngIf="min.hasError('max')"
|
@if(min.hasError('max')) {
|
||||||
|
<mat-hint
|
||||||
>Min should not be greater than {{ configuration.max }}</mat-hint
|
>Min should not be greater than {{ configuration.max }}</mat-hint
|
||||||
>
|
>
|
||||||
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field>
|
<mat-form-field>
|
||||||
<mat-label>Max</mat-label>
|
<mat-label>Max</mat-label>
|
||||||
@@ -61,9 +63,9 @@ import { StringEditorFieldComponent } from '../string-editor-field/string-editor
|
|||||||
[(ngModel)]="configuration.max"
|
[(ngModel)]="configuration.max"
|
||||||
[min]="configuration.min ?? null"
|
[min]="configuration.min ?? null"
|
||||||
/>
|
/>
|
||||||
<mat-hint *ngIf="max.hasError('min')"
|
@if(max.hasError('min')) {
|
||||||
>Max should not be less than {{ configuration.min }}</mat-hint
|
<mat-hint>Max should not be less than {{ configuration.min }}</mat-hint>
|
||||||
>
|
}
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
} @case (MessageTypeEnum.List) {
|
} @case (MessageTypeEnum.List) {
|
||||||
<app-list-editor-field
|
<app-list-editor-field
|
||||||
@@ -77,6 +79,10 @@ import { StringEditorFieldComponent } from '../string-editor-field/string-editor
|
|||||||
<app-object-editor-field
|
<app-object-editor-field
|
||||||
[field]="objectConfiguration(fieldConfiguration())"
|
[field]="objectConfiguration(fieldConfiguration())"
|
||||||
></app-object-editor-field>
|
></app-object-editor-field>
|
||||||
|
} @case(MessageTypeEnum.Enum) {
|
||||||
|
<app-enum-editor-field
|
||||||
|
[configuration]="enumConfiguration(fieldConfiguration())"
|
||||||
|
></app-enum-editor-field>
|
||||||
} }`,
|
} }`,
|
||||||
styleUrl: './definition-editor-field.component.css',
|
styleUrl: './definition-editor-field.component.css',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
@@ -104,5 +110,9 @@ export class DefinitionEditorFieldComponent {
|
|||||||
return configuration as ObjectMessage;
|
return configuration as ObjectMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected enumConfiguration(configuration: MessageConfiguration) {
|
||||||
|
return configuration as EnumMessage;
|
||||||
|
}
|
||||||
|
|
||||||
protected readonly MessageTypeEnum = MessageTypeEnum;
|
protected readonly MessageTypeEnum = MessageTypeEnum;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
mat-form-field {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
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 { MatButtonModule } from '@angular/material/button';
|
||||||
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
|
||||||
import {
|
import {
|
||||||
EDITABLE_MESSAGE_TYPES,
|
|
||||||
ListMessage,
|
ListMessage,
|
||||||
MessageConfiguration,
|
MessageConfiguration,
|
||||||
MessageTypeEnum,
|
MessageTypeEnum,
|
||||||
@@ -11,13 +9,18 @@ import {
|
|||||||
ProtoMessage,
|
ProtoMessage,
|
||||||
} from '../../model/proto-message.model';
|
} from '../../model/proto-message.model';
|
||||||
import { DefinitionEditorFieldComponent } from './definition-editor-field/definition-editor-field.component';
|
import { DefinitionEditorFieldComponent } from './definition-editor-field/definition-editor-field.component';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-definition-editor',
|
selector: 'app-definition-editor',
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
FormsModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatDialogModule,
|
MatDialogModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
DefinitionEditorFieldComponent,
|
DefinitionEditorFieldComponent,
|
||||||
],
|
],
|
||||||
template: `
|
template: `
|
||||||
@@ -25,6 +28,14 @@ import { DefinitionEditorFieldComponent } from './definition-editor-field/defini
|
|||||||
<mat-dialog-content>
|
<mat-dialog-content>
|
||||||
@for (field of editableMessages; track $index) {
|
@for (field of editableMessages; track $index) {
|
||||||
<h3>{{ field.name }}</h3>
|
<h3>{{ field.name }}</h3>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Friendly Name</mat-label>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
[(ngModel)]="field.friendlyName"
|
||||||
|
placeholder="Optional"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
<app-definition-editor-field
|
<app-definition-editor-field
|
||||||
[fieldConfiguration]="field.configuration"
|
[fieldConfiguration]="field.configuration"
|
||||||
></app-definition-editor-field>
|
></app-definition-editor-field>
|
||||||
@@ -40,26 +51,5 @@ import { DefinitionEditorFieldComponent } from './definition-editor-field/defini
|
|||||||
export class DefinitionEditorComponent {
|
export class DefinitionEditorComponent {
|
||||||
protected protoMessage = inject<ProtoMessage>(MAT_DIALOG_DATA);
|
protected protoMessage = inject<ProtoMessage>(MAT_DIALOG_DATA);
|
||||||
|
|
||||||
protected editableMessages = this.protoMessage.values.filter((message) =>
|
protected editableMessages = this.protoMessage.values;
|
||||||
this.filterMessageConfiguration(message.configuration)
|
|
||||||
);
|
|
||||||
|
|
||||||
private filterMessageConfiguration(
|
|
||||||
configuration: MessageConfiguration
|
|
||||||
): boolean {
|
|
||||||
if (configuration.type === MessageTypeEnum.List) {
|
|
||||||
return this.filterMessageConfiguration(
|
|
||||||
(configuration as ListMessage).subConfiguration
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (configuration.type === MessageTypeEnum.Object) {
|
|
||||||
// Ensure at least one nested message can be configured
|
|
||||||
return !!(configuration as ObjectMessage).messageDefinition.values.find(
|
|
||||||
(message) => this.filterMessageConfiguration(message.configuration)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: Map can always be configured, as key needs to be a string or numeric type
|
|
||||||
return EDITABLE_MESSAGE_TYPES.includes(configuration.type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
mat-form-field {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
||||||
|
import { EnumMessage } from '../../../model/proto-message.model';
|
||||||
|
import { MatFormFieldModule, MatLabel } from '@angular/material/form-field';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-enum-editor-field',
|
||||||
|
standalone: true,
|
||||||
|
imports: [FormsModule, MatFormFieldModule, MatInputModule, MatLabel],
|
||||||
|
template: `
|
||||||
|
@for (option of configuration().options; track $index) {
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>{{ option.protoName }}</mat-label>
|
||||||
|
<input
|
||||||
|
matInput
|
||||||
|
[(ngModel)]="option.friendlyName"
|
||||||
|
placeholder="Friendly Name"
|
||||||
|
/>
|
||||||
|
</mat-form-field>
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
styleUrl: './enum-editor-field.component.css',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
})
|
||||||
|
export class EnumEditorFieldComponent {
|
||||||
|
configuration = input.required<EnumMessage>();
|
||||||
|
}
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
@@ -10,7 +9,7 @@ import { ListMessage } from '../../../model/proto-message.model';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-list-editor-field',
|
selector: 'app-list-editor-field',
|
||||||
imports: [CommonModule, forwardRef(() => DefinitionEditorFieldComponent)],
|
imports: [forwardRef(() => DefinitionEditorFieldComponent)],
|
||||||
template: `<app-definition-editor-field
|
template: `<app-definition-editor-field
|
||||||
[fieldConfiguration]="field().subConfiguration"
|
[fieldConfiguration]="field().subConfiguration"
|
||||||
></app-definition-editor-field>`,
|
></app-definition-editor-field>`,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
@@ -14,7 +13,7 @@ import {
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-map-editor-field',
|
selector: 'app-map-editor-field',
|
||||||
imports: [CommonModule, forwardRef(() => DefinitionEditorFieldComponent)],
|
imports: [forwardRef(() => DefinitionEditorFieldComponent)],
|
||||||
template: `
|
template: `
|
||||||
<h4>Key Configuration</h4>
|
<h4>Key Configuration</h4>
|
||||||
<app-definition-editor-field
|
<app-definition-editor-field
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import {
|
import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
@@ -6,31 +5,43 @@ import {
|
|||||||
forwardRef,
|
forwardRef,
|
||||||
input,
|
input,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import {
|
import { ObjectMessage } from '../../../model/proto-message.model';
|
||||||
EDITABLE_MESSAGE_TYPES,
|
|
||||||
ObjectMessage,
|
|
||||||
} from '../../../model/proto-message.model';
|
|
||||||
import { DefinitionEditorFieldComponent } from '../definition-editor-field/definition-editor-field.component';
|
import { DefinitionEditorFieldComponent } from '../definition-editor-field/definition-editor-field.component';
|
||||||
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-object-editor-field',
|
selector: 'app-object-editor-field',
|
||||||
imports: [CommonModule, forwardRef(() => DefinitionEditorFieldComponent)],
|
imports: [
|
||||||
|
FormsModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
forwardRef(() => DefinitionEditorFieldComponent),
|
||||||
|
],
|
||||||
template: `
|
template: `
|
||||||
@for (field of editableFields(); track $index) {
|
@for (field of editableFields(); track $index) {
|
||||||
<h4>{{ field.name }}</h4>
|
<h4>{{ field.name }}</h4>
|
||||||
|
<mat-form-field>
|
||||||
|
<mat-label>Friendly Name</mat-label>
|
||||||
|
<input matInput [(ngModel)]="field.friendlyName" placeholder="Optional" />
|
||||||
|
</mat-form-field>
|
||||||
<app-definition-editor-field
|
<app-definition-editor-field
|
||||||
[fieldConfiguration]="field.configuration"
|
[fieldConfiguration]="field.configuration"
|
||||||
></app-definition-editor-field>
|
></app-definition-editor-field>
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
styles: `
|
||||||
|
mat-form-field {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
`,
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class ObjectEditorFieldComponent {
|
export class ObjectEditorFieldComponent {
|
||||||
field = input.required<ObjectMessage>();
|
field = input.required<ObjectMessage>();
|
||||||
|
|
||||||
protected editableFields = computed(() =>
|
protected editableFields = computed(
|
||||||
this.field().messageDefinition.values.filter((field) =>
|
() => this.field().messageDefinition.values
|
||||||
EDITABLE_MESSAGE_TYPES.includes(field.configuration.type)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
@@ -8,14 +7,9 @@ import { MatInputModule } from '@angular/material/input';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-string-editor-field',
|
selector: 'app-string-editor-field',
|
||||||
imports: [
|
imports: [FormsModule, MatFormFieldModule, MatInputModule, MatSelectModule],
|
||||||
CommonModule,
|
template: `
|
||||||
FormsModule,
|
<mat-form-field>
|
||||||
MatFormFieldModule,
|
|
||||||
MatInputModule,
|
|
||||||
MatSelectModule,
|
|
||||||
],
|
|
||||||
template: ` <mat-form-field>
|
|
||||||
<mat-label>Max Length</mat-label>
|
<mat-label>Max Length</mat-label>
|
||||||
<input matInput type="number" [(ngModel)]="configuration().maxLength" />
|
<input matInput type="number" [(ngModel)]="configuration().maxLength" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
@@ -25,7 +19,8 @@ import { MatInputModule } from '@angular/material/input';
|
|||||||
<mat-option value="text">Text</mat-option>
|
<mat-option value="text">Text</mat-option>
|
||||||
<mat-option value="sql">SQL</mat-option>
|
<mat-option value="sql">SQL</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
</mat-form-field>`,
|
</mat-form-field>
|
||||||
|
`,
|
||||||
styleUrl: './string-editor-field.component.scss',
|
styleUrl: './string-editor-field.component.scss',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,16 +1,26 @@
|
|||||||
import { CommonModule } from '@angular/common';
|
import {
|
||||||
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, HostBinding, HostListener, computed, output, signal, viewChild, inject } from '@angular/core';
|
ChangeDetectionStrategy,
|
||||||
|
Component,
|
||||||
|
ElementRef,
|
||||||
|
HostBinding,
|
||||||
|
HostListener,
|
||||||
|
computed,
|
||||||
|
inject,
|
||||||
|
output,
|
||||||
|
signal,
|
||||||
|
viewChild,
|
||||||
|
} from '@angular/core';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatListModule, MatSelectionList } from '@angular/material/list';
|
|
||||||
import { ProtoMessage } from '../model/proto-message.model';
|
|
||||||
import { ProtoDefinitionService } from './proto-definition.service';
|
|
||||||
import { MatTreeModule } from '@angular/material/tree';
|
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
||||||
import { writeTextFile } from '@tauri-apps/api/fs';
|
|
||||||
import { save } from '@tauri-apps/api/dialog';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatListModule, MatSelectionList } from '@angular/material/list';
|
||||||
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
|
import { MatTreeModule } from '@angular/material/tree';
|
||||||
|
import { save } from '@tauri-apps/api/dialog';
|
||||||
|
import { writeTextFile } from '@tauri-apps/api/fs';
|
||||||
|
import { ProtoMessage } from '../model/proto-message.model';
|
||||||
import { DefinitionEditorComponent } from './definition-editor/definition-editor.component';
|
import { DefinitionEditorComponent } from './definition-editor/definition-editor.component';
|
||||||
|
import { ProtoDefinitionService } from './proto-definition.service';
|
||||||
|
|
||||||
declare const __TAURI__: any;
|
declare const __TAURI__: any;
|
||||||
|
|
||||||
@@ -18,13 +28,7 @@ const collator = new Intl.Collator(undefined, { numeric: true });
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-proto-definition-selector',
|
selector: 'app-proto-definition-selector',
|
||||||
imports: [
|
imports: [MatButtonModule, MatIconModule, MatListModule, MatTreeModule],
|
||||||
CommonModule,
|
|
||||||
MatButtonModule,
|
|
||||||
MatIconModule,
|
|
||||||
MatListModule,
|
|
||||||
MatTreeModule,
|
|
||||||
],
|
|
||||||
template: `
|
template: `
|
||||||
<h2>Protobuf Definitions</h2>
|
<h2>Protobuf Definitions</h2>
|
||||||
<button mat-button (click)="protoSelector.click()">
|
<button mat-button (click)="protoSelector.click()">
|
||||||
@@ -66,7 +70,7 @@ const collator = new Intl.Collator(undefined, { numeric: true });
|
|||||||
>
|
>
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon>edit</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<div matListItemLine>{{ item.name }}</div>
|
<div>{{ item.name }}</div>
|
||||||
</mat-list-option>
|
</mat-list-option>
|
||||||
}
|
}
|
||||||
</mat-selection-list>
|
</mat-selection-list>
|
||||||
|
|||||||
Reference in New Issue
Block a user