diff --git a/src/Squidex/Controllers/Api/Schemas/Models/UpdateFieldDto.cs b/src/Squidex/Controllers/Api/Schemas/Models/UpdateFieldDto.cs index 4bbdf9bf1..d2df340c6 100644 --- a/src/Squidex/Controllers/Api/Schemas/Models/UpdateFieldDto.cs +++ b/src/Squidex/Controllers/Api/Schemas/Models/UpdateFieldDto.cs @@ -6,10 +6,16 @@ // All rights reserved. // ========================================================================== +using System.ComponentModel.DataAnnotations; + namespace Squidex.Controllers.Api.Schemas.Models { public class UpdateFieldDto { + /// + /// The field properties. + /// + [Required] public FieldPropertiesDto Properties { get; set; } } } diff --git a/src/Squidex/Controllers/Api/Schemas/SchemasController.cs b/src/Squidex/Controllers/Api/Schemas/SchemasController.cs index 6071c1e8a..856e4f937 100644 --- a/src/Squidex/Controllers/Api/Schemas/SchemasController.cs +++ b/src/Squidex/Controllers/Api/Schemas/SchemasController.cs @@ -16,6 +16,7 @@ using Squidex.Infrastructure.CQRS.Commands; using Squidex.Infrastructure.Reflection; using Squidex.Controllers.Api.Schemas.Models; using Squidex.Controllers.Api.Schemas.Models.Converters; +using Squidex.Core.Schemas; using Squidex.Pipeline; using Squidex.Read.Schemas.Repositories; using Squidex.Write.Schemas.Commands; @@ -119,9 +120,9 @@ namespace Squidex.Controllers.Api.Schemas [Route("apps/{app}/schemas/{name}/")] public async Task PutSchema(string app, string name, [FromBody] UpdateSchemaDto request) { - var command = SimpleMapper.Map(request, new UpdateSchema()); + var properties = SimpleMapper.Map(request, new SchemaProperties()); - await CommandBus.PublishAsync(command); + await CommandBus.PublishAsync(new UpdateSchema { Properties = properties }); return NoContent(); } diff --git a/src/Squidex/Pipeline/WebpackMiddleware.cs b/src/Squidex/Pipeline/WebpackMiddleware.cs index e2b51efd7..7441352c3 100644 --- a/src/Squidex/Pipeline/WebpackMiddleware.cs +++ b/src/Squidex/Pipeline/WebpackMiddleware.cs @@ -89,7 +89,7 @@ namespace Squidex.Pipeline foreach (var file in Styles) { - stylesTag += $""; + stylesTag += $""; } response = response.Replace("", $"{stylesTag}"); diff --git a/src/Squidex/app/features/apps/pages/apps-page.component.html b/src/Squidex/app/features/apps/pages/apps-page.component.html index 626ae5181..cba22e0a4 100644 --- a/src/Squidex/app/features/apps/pages/apps-page.component.html +++ b/src/Squidex/app/features/apps/pages/apps-page.component.html @@ -1,14 +1,14 @@  -
+

You are not collaborating to any app yet

- +
-
+

{{app.name}}

@@ -18,12 +18,12 @@
-
+ + \ No newline at end of file diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.scss b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.scss index d85043aa8..5f3b41a9a 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.scss +++ b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.scss @@ -15,4 +15,16 @@ &:disabled { @include opacity(1); } +} + +.schema { + &-edit { + color: $color-border-dark; + font-size: .9rem; + font-weight: normal; + padding: .6rem .3rem; + border: 0; + background: transparent; + vertical-align: baseline; + } } \ No newline at end of file diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts index 3b9ff0398..96e7f4742 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts @@ -20,12 +20,14 @@ import { HistoryChannelUpdated, ImmutableArray, MessageBus, + ModalView, NotificationService, SchemasService, UpdateFieldDto, UsersProviderService } from 'shared'; +import { SchemaPropertiesDto } from './schema-properties'; import { SchemaUpdated } from './../messages'; @Component({ @@ -47,6 +49,9 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, public schemaName: string; public schemaFields = ImmutableArray.empty(); + public schemaProperties: SchemaPropertiesDto; + + public editSchemaDialog = new ModalView(); public isPublished: boolean; @@ -92,6 +97,7 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, .switchMap(app => this.schemasService.getSchema(app, this.schemaName)).retry(2) .subscribe(dto => { this.schemaFields = ImmutableArray.of(dto.fields); + this.schemaProperties = new SchemaPropertiesDto(dto.name, dto.label, dto.hints); this.isPublished = dto.isPublished; }, error => { this.notifyError(error); @@ -103,7 +109,7 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, .switchMap(app => this.schemasService.publishSchema(app, this.schemaName)).retry(2) .subscribe(() => { this.isPublished = true; - this.updateAll(this.schemaFields); + this.notify(); }, error => { this.notifyError(error); }); @@ -114,7 +120,7 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, .switchMap(app => this.schemasService.unpublishSchema(app, this.schemaName)).retry(2) .subscribe(() => { this.isPublished = false; - this.updateAll(this.schemaFields); + this.notify(); }, error => { this.notifyError(error); }); @@ -164,7 +170,7 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, this.appName() .switchMap(app => this.schemasService.deleteField(app, this.schemaName, field.fieldId)).retry(2) .subscribe(() => { - this.updateAll(this.schemaFields.remove(field)); + this.updateFields(this.schemaFields.remove(field)); }, error => { this.notifyError(error); }); @@ -207,7 +213,7 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, false, properties); - this.updateAll(this.schemaFields.push(newField)); + this.updateFields(this.schemaFields.push(newField)); reset(); }, error => { this.notifyError(error); @@ -220,15 +226,33 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, this.schemaFields = ImmutableArray.empty(); } + public onSchemaSaved(properties: SchemaPropertiesDto) { + this.updateProperties(properties); + + this.editSchemaDialog.hide(); + } + + public updateProperties(properties: SchemaPropertiesDto) { + this.schemaProperties = properties; + + this.notify(); + } + public updateField(field: FieldDto, newField: FieldDto) { - this.updateAll(this.schemaFields.replace(field, newField)); + this.schemaFields = this.schemaFields.replace(field, newField); + + this.notify(); } - private updateAll(fields: ImmutableArray) { + private updateFields(fields: ImmutableArray) { this.schemaFields = fields; + this.notify(); + } + + private notify() { this.messageBus.publish(new HistoryChannelUpdated()); - this.messageBus.publish(new SchemaUpdated(this.schemaName, this.isPublished)); + this.messageBus.publish(new SchemaUpdated(this.schemaName, this.schemaProperties.label, this.isPublished)); } } diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-properties.ts b/src/Squidex/app/features/schemas/pages/schema/schema-properties.ts new file mode 100644 index 000000000..ed6889942 --- /dev/null +++ b/src/Squidex/app/features/schemas/pages/schema/schema-properties.ts @@ -0,0 +1,15 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Sebastian Stehle. All rights reserved + */ + +export class SchemaPropertiesDto { + constructor( + public readonly name: string, + public readonly label: string, + public readonly hints: string + ) { + } +} \ No newline at end of file diff --git a/src/Squidex/app/features/schemas/pages/schema/types/boolean-ui.component.ts b/src/Squidex/app/features/schemas/pages/schema/types/boolean-ui.component.ts index 0bea79119..f2b310b7d 100644 --- a/src/Squidex/app/features/schemas/pages/schema/types/boolean-ui.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/types/boolean-ui.component.ts @@ -7,13 +7,8 @@ import { Component, Input, OnInit } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; -import { Observable } from 'rxjs'; -import { - fadeAnimation, - FloatConverter, - BooleanFieldPropertiesDto -} from 'shared'; +import { fadeAnimation, BooleanFieldPropertiesDto } from 'shared'; @Component({ selector: 'sqx-boolean-ui', @@ -30,10 +25,6 @@ export class BooleanUIComponent implements OnInit { @Input() public properties: BooleanFieldPropertiesDto; - public converter = new FloatConverter(); - - public hideAllowedValues: Observable; - public ngOnInit() { this.editForm.addControl('editor', new FormControl(this.properties.editor, [ diff --git a/src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.ts b/src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.ts index b14fd900a..ad69e6065 100644 --- a/src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/types/number-ui.component.ts @@ -36,6 +36,10 @@ export class NumberUIComponent implements OnDestroy, OnInit { public hideAllowedValues: Observable; + public ngOnDestroy() { + this.editorSubscription.unsubscribe(); + } + public ngOnInit() { this.editForm.addControl('editor', new FormControl(this.properties.editor, [ @@ -60,8 +64,4 @@ export class NumberUIComponent implements OnDestroy, OnInit { } }); } - - public ngOnDestroy() { - this.editorSubscription.unsubscribe(); - } } \ No newline at end of file diff --git a/src/Squidex/app/features/schemas/pages/schema/types/string-ui.component.ts b/src/Squidex/app/features/schemas/pages/schema/types/string-ui.component.ts index 4d63fb444..1acee345f 100644 --- a/src/Squidex/app/features/schemas/pages/schema/types/string-ui.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/types/string-ui.component.ts @@ -30,6 +30,10 @@ export class StringUIComponent implements OnDestroy, OnInit { public hideAllowedValues: Observable; + public ngOnDestroy() { + this.editorSubscription.unsubscribe(); + } + public ngOnInit() { this.editForm.setControl('editor', new FormControl(this.properties.editor, [ @@ -56,8 +60,4 @@ export class StringUIComponent implements OnDestroy, OnInit { } }); } - - public ngOnDestroy() { - this.editorSubscription.unsubscribe(); - } } \ No newline at end of file diff --git a/src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.ts b/src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.ts index f55804e22..37c75cee6 100644 --- a/src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/types/string-validation.component.ts @@ -25,8 +25,12 @@ export class StringValidationComponent implements OnDestroy, OnInit { @Input() public properties: StringFieldPropertiesDto; - public hidePatternMessage: Observable; public hideDefaultValue: Observable; + public hidePatternMessage: Observable; + + public ngOnDestroy() { + this.patternSubscription.unsubscribe(); + } public ngOnInit() { this.editForm.setControl('maxLength', @@ -61,8 +65,4 @@ export class StringValidationComponent implements OnDestroy, OnInit { } }); } - - public ngOnDestroy() { - this.patternSubscription.unsubscribe(); - } } \ No newline at end of file diff --git a/src/Squidex/app/features/schemas/pages/schemas/schema-form.component.html b/src/Squidex/app/features/schemas/pages/schemas/schema-form.component.html index f4cad156c..f461fbb30 100644 --- a/src/Squidex/app/features/schemas/pages/schemas/schema-form.component.html +++ b/src/Squidex/app/features/schemas/pages/schemas/schema-form.component.html @@ -26,7 +26,7 @@

- The schema name becomes part of the api url,
e.g https://{{appName}}.squidex.io/{{schemaName}}/. + The schema name becomes part of the api url,
e.g https://{{appName}}.squidex.io/{{schemaName | async}}/.

It must contain lower case letters (a-z), numbers and dashes only, and cannot be longer than 40 characters. The name cannot be changed later. @@ -36,6 +36,6 @@

- +
\ No newline at end of file diff --git a/src/Squidex/app/features/schemas/pages/schemas/schema-form.component.ts b/src/Squidex/app/features/schemas/pages/schemas/schema-form.component.ts index 2a809f150..8765e1c20 100644 --- a/src/Squidex/app/features/schemas/pages/schemas/schema-form.component.ts +++ b/src/Squidex/app/features/schemas/pages/schemas/schema-form.component.ts @@ -5,8 +5,9 @@ * Copyright (c) Sebastian Stehle. All rights reserved */ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, Output } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Observable } from 'rxjs'; import { AuthService, @@ -27,10 +28,7 @@ const FALLBACK_NAME = 'my-schema'; fadeAnimation ] }) -export class SchemaFormComponent implements OnInit { - @Input() - public showClose = false; - +export class SchemaFormComponent { @Input() public appName: string; @@ -51,7 +49,9 @@ export class SchemaFormComponent implements OnInit { ]] }); - public schemaName = FALLBACK_NAME; + public schemaName = + Observable.of(FALLBACK_NAME) + .merge(this.createForm.get('name').valueChanges.map(n => n || FALLBACK_NAME)); constructor( private readonly schemas: SchemasService, @@ -60,43 +60,41 @@ export class SchemaFormComponent implements OnInit { ) { } - public ngOnInit() { - this.createForm.get('name').valueChanges.subscribe(value => { - this.schemaName = value || FALLBACK_NAME; - }); - } - public createSchema() { this.createForm.markAsTouched(); - if (this.createForm.valid && this.authService.user) { + if (this.createForm.valid) { this.createForm.disable(); const name = this.createForm.get('name').value; - const now = DateTime.now(); const requestDto = new CreateSchemaDto(name); - const me = `subject:${this.authService.user.id}`; - this.schemas.postSchema(this.appName, requestDto) .subscribe(dto => { - this.createForm.reset(); - this.created.emit(new SchemaDto(dto.id, name, now, now, me, me, false)); - }, error => { this.reset(); + this.created.emit(this.createSchemaDto(dto.id, name)); + }, error => { + this.createForm.enable(); this.creationError = error.displayMessage; }); } } - private reset() { - this.createForm.enable(); + public reset() { this.creationError = ''; + this.createForm.reset(); } public cancel() { this.reset(); this.cancelled.emit(); } + + private createSchemaDto(id: string, name: string) { + const user = this.authService.user!.token; + const now = DateTime.now(); + + return new SchemaDto(id, name, undefined, false, user, user, now, now); + } } \ No newline at end of file diff --git a/src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.html b/src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.html index 3d0c72af5..5f6fa0cca 100644 --- a/src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.html +++ b/src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.html @@ -10,7 +10,7 @@
- @@ -29,7 +29,7 @@
- {{schema.name}} + {{schema|displayName}}
@@ -49,12 +49,12 @@
-