Skip to content

Commit

Permalink
simplify Schema creation
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcibotari committed Jun 5, 2024
1 parent cea63dc commit bdacd20
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 18 deletions.
8 changes: 4 additions & 4 deletions functions/src/models/schema.zod.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { z } from 'zod';
import { AssetFileType, SchemaFieldKind, SchemaType } from './schema.model';

const FIELD_NAME_PATTERN = /^[a-z]+[a-zA-Z0-9_]*[a-zA-Z0-9]+$/;
const ID_PATTERN = /^[a-zA-Z]+[a-zA-Z0-9-_.]*[a-zA-Z0-9]+$/;
// const FIELD_NAME_PATTERN = /^[a-z]+[a-zA-Z0-9_]*[a-zA-Z0-9]+$/;
// const ID_PATTERN = /^[a-zA-Z]+[a-zA-Z0-9-_.]*[a-zA-Z0-9]+$/;

export const schemaTypeSchema = z.nativeEnum(SchemaType);

export const schemaBaseSchema = z.object({
id: z.string().regex(ID_PATTERN),
id: z.string(),
type: schemaTypeSchema,
displayName: z.string().optional(),
});
Expand All @@ -20,7 +20,7 @@ export const schemaEnumValueSchema = z.object({
export const schemaFieldKindSchema = z.nativeEnum(SchemaFieldKind);

export const schemaFieldBaseSchema = z.object({
name: z.string().regex(FIELD_NAME_PATTERN),
name: z.string(),
kind: schemaFieldKindSchema,
displayName: z.string().optional(),
required: z.boolean().optional(),
Expand Down
4 changes: 3 additions & 1 deletion src/app/core/error-handler/form-error-handler.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ export class FormErrorHandlerService {
case `^${CommonPattern.JSON_NAME}$`:
return `Should contain with a-z, A-Z, 0-9, and underscore (_). Should start with a-z and end with a-z or A-Z or 0-9.`;
case `^${CommonPattern.URL_SLUG}$`:
return `Should contain only a-z, A-Z, 0-9, - and underscore (_).`;
return `Should contain with a-z, A-Z, 0-9, - and underscore (_). Should start with a-z and end with a-z or A-Z or 0-9.`;
case `^${CommonPattern.ID}$`:
return `Should contain only a-z, A-Z, 0-9, hyphen (-), dot (.) and underscore (_). Should start with a-z or A-Z and end with a-z or A-Z or 0-9.`;
case `^${CommonPattern.SCHEMA_ID}$`:
return `Should contain only a-z, A-Z, 0-9, hyphen (-), dot (.) and underscore (_). Should start with a-z and end with a-z or A-Z or 0-9.`;
default:
return `Doesn't match the pattern ${errors['pattern'].requiredPattern}`;
}
Expand Down
7 changes: 7 additions & 0 deletions src/app/core/utils/name-utils.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@ export class NameUtils {
.replace(/[!*'();:@&=+$,/?%#[\]]/g, '') // Reserved
.replace(/[.~]/g, ''); // no wish
}
public static schemaId(input: string): string {
return input
.toLowerCase()
.replace(/\s/g, '-')
.replace(/[!*'();:@&=+$,/?%#[\]]/g, '') // Reserved
.replace(/[.~]/g, ''); // no wish
}

public static random(length: number): string {
let result = '';
Expand Down
19 changes: 11 additions & 8 deletions src/app/features/schemas/add-dialog/add-dialog.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@ <h1 mat-dialog-title>Create new Schema</h1>
<mat-dialog-content>
<br />
<form [formGroup]="form">
<mat-form-field>
<mat-label>Display Name</mat-label>
<input matInput type="text" formControlName="displayName" minlength="3" maxlength="50" autocomplete="off" />
<mat-hint align="end">{{ form.controls['displayName'].value?.length || 0 }}/50</mat-hint>
@if (form.controls['displayName'].errors; as errors) {
<mat-error>{{ fe.errors(errors) }}</mat-error>
}
</mat-form-field>
<mat-form-field>
<mat-label>Id</mat-label>
<input matInput type="text" formControlName="id" required minlength="3" maxlength="30" autocomplete="off" />
<button mat-icon-button matSuffix (click)="normalizeId()">
<mat-icon>auto_fix_normal</mat-icon>
</button>
<mat-hint>Will be used in JSON structure.</mat-hint>
<mat-hint align="end">{{ form.controls['id'].value?.length || 0 }}/30</mat-hint>
@if (form.controls['id'].errors; as errors) {
<mat-error>{{ fe.errors(errors) }}</mat-error>
}
</mat-form-field>
<mat-form-field>
<mat-label>Display Name</mat-label>
<input matInput type="text" formControlName="displayName" minlength="3" maxlength="50" autocomplete="off" />
<mat-hint align="end">{{ form.controls['displayName'].value?.length || 0 }}/50</mat-hint>
@if (form.controls['displayName'].errors; as errors) {
<mat-error>{{ fe.errors(errors) }}</mat-error>
}
</mat-form-field>
<mat-form-field>
<mat-label>Type</mat-label>
<mat-select formControlName="type" required>
Expand Down
22 changes: 19 additions & 3 deletions src/app/features/schemas/add-dialog/add-dialog.component.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import { ChangeDetectionStrategy, Component, effect, Inject } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { FormBuilder, FormGroup } from '@angular/forms';
import { AddDialogModel } from './add-dialog.model';
import { SchemaValidator } from '@shared/validators/schema.validator';
import { FormErrorHandlerService } from '@core/error-handler/form-error-handler.service';
import { CommonValidator } from '@shared/validators/common.validator';
import { SchemaType } from '@shared/models/schema.model';
import { NameUtils } from '@core/utils/name-utils.service';
import { toSignal } from '@angular/core/rxjs-interop';

@Component({
selector: 'll-schema-add-dialog',
Expand All @@ -17,14 +19,28 @@ export class AddDialogComponent {
types: string[] = Object.keys(SchemaType);

form: FormGroup = this.fb.group({
id: this.fb.control('', [...SchemaValidator.ID, CommonValidator.reservedName(this.data.reservedNames)]),
displayName: this.fb.control<string | undefined>(undefined, SchemaValidator.DISPLAY_NAME),
id: this.fb.control('', [...SchemaValidator.ID, CommonValidator.reservedName(this.data.reservedNames)]),
type: this.fb.control(SchemaType.NODE, SchemaValidator.TYPE),
});

formDisplayNameValue = toSignal(this.form.controls['displayName'].valueChanges);

constructor(
private readonly fb: FormBuilder,
readonly fe: FormErrorHandlerService,
@Inject(MAT_DIALOG_DATA) public data: AddDialogModel
) {}
) {
effect(() => {
if (!this.form.controls['id'].touched) {
this.form.controls['id'].setValue(NameUtils.schemaId(this.formDisplayNameValue() || ''));
}
});
}

normalizeId() {
if (this.form.value.slug) {
this.form.controls['id'].setValue(NameUtils.schemaId(this.form.value.id));
}
}
}
3 changes: 2 additions & 1 deletion src/app/shared/validators/common.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ export const RESERVED_NAMES = ['_id', 'schema', 'kind'];

export enum CommonPattern {
JSON_NAME = '[a-z]+[a-zA-Z0-9_]*[a-zA-Z0-9]+',
URL_SLUG = '[a-zA-Z0-9-_]+',
URL_SLUG = '[a-z]+[a-zA-Z0-9-_]*[a-zA-Z0-9]+',
ID = '[a-zA-Z]+[a-zA-Z0-9-_.]*[a-zA-Z0-9]+',
SCHEMA_ID = '[a-z]+[a-zA-Z0-9-_.]*[a-zA-Z0-9]+',
//URL = ''//'(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?'
}
2 changes: 1 addition & 1 deletion src/app/shared/validators/schema.validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export class SchemaValidator {
public static ID: ValidatorFn[] = [
Validators.required,
CommonValidator.noSpace,
Validators.pattern(CommonPattern.ID),
Validators.pattern(CommonPattern.SCHEMA_ID),
Validators.minLength(3),
Validators.maxLength(30),
];
Expand Down

0 comments on commit bdacd20

Please sign in to comment.