Browse Source

Allow users to edit the field after they create it in the field wizard. They can also go back and keep adding fields and editing them until they are done with that schema.

pull/328/head
Alexander Van Dyke 7 years ago
parent
commit
6ec2dadd40
  1. 63
      src/Squidex/app/features/schemas/pages/schema/field-wizard.component.html
  2. 105
      src/Squidex/app/features/schemas/pages/schema/field-wizard.component.ts
  3. 5
      src/Squidex/app/features/schemas/pages/schema/field.component.ts
  4. 26
      src/Squidex/app/features/schemas/pages/schema/forms/field-form-common.component.ts

63
src/Squidex/app/features/schemas/pages/schema/field-wizard.component.html

@ -1,16 +1,17 @@
<form [formGroup]="addFieldForm.form" (ngSubmit)="addField(false)"> <sqx-modal-dialog (closed)="complete()" large="true">
<sqx-modal-dialog (closed)="complete()" large="true">
<ng-container title> <ng-container title>
<ng-container *ngIf="parent; else noParent"> <ng-container *ngIf="parent; else noParent">
Add Nested Field Add Nested Field
</ng-container> </ng-container>
<ng-template #noParent> <ng-template #noParent>
Add Field {{step === 1 ? 'Add' : 'Edit'}} Field
</ng-template> </ng-template>
</ng-container> </ng-container>
<ng-container content> <ng-container content>
<ng-container *ngIf="step === 1">
<form [formGroup]="addFieldForm.form" (ngSubmit)="addField(false)">
<sqx-form-error [error]="addFieldForm.error | async"></sqx-form-error> <sqx-form-error [error]="addFieldForm.error | async"></sqx-form-error>
<div class="form-group"> <div class="form-group">
@ -39,7 +40,8 @@
<div class="form-group"> <div class="form-group">
<sqx-control-errors for="name" submitOnly="true" [submitted]="addFieldForm.submitted | async"></sqx-control-errors> <sqx-control-errors for="name" submitOnly="true" [submitted]="addFieldForm.submitted | async"></sqx-control-errors>
<input type="text" class="form-control" formControlName="name" maxlength="40" #nameInput placeholder="Enter field name" sqxFocusOnInit /> <input type="text" class="form-control" formControlName="name" maxlength="40" #nameInput
placeholder="Enter field name" sqxFocusOnInit />
</div> </div>
<div class="form-group" *ngIf="!parent"> <div class="form-group" *ngIf="!parent">
@ -51,18 +53,59 @@
</div> </div>
<small class="form-text text-muted"> <small class="form-text text-muted">
You can the field as localizable. It means that is dependent on the language, for example a city name. You can the field as localizable. It means that is dependent on the language, for example a
city name.
</small> </small>
</div> </div>
</form>
</ng-container>
<div class="table-items-row-details" *ngIf="step === 2">
<form [formGroup]="editForm.form" (ngSubmit)="save()">
<div class="table-items-row-details-tabs clearfix">
<ul class="nav nav-tabs2">
<li class="nav-item">
<a class="nav-link" (click)="selectTab(0)" [class.active]="selectedTab === 0">Common</a>
</li>
<li class="nav-item">
<a class="nav-link" (click)="selectTab(1)" [class.active]="selectedTab === 1">Validation</a>
</li>
<li class="nav-item">
<a class="nav-link" (click)="selectTab(2)" [class.active]="selectedTab === 2">Editing</a>
</li>
</ul>
</div>
<ng-container *ngIf="patternsState.patterns | async; let patterns">
<div class="table-items-row-details-tab" [class.hidden]="selectedTab !== 0">
<sqx-field-form-common [editForm]="editForm.form" [editFormSubmitted]="editForm.submitted | async"
[field]="field"></sqx-field-form-common>
</div>
<div class="table-items-row-details-tab" [class.hidden]="selectedTab !== 1">
<sqx-field-form-validation [patterns]="patterns" [editForm]="editForm.form" [field]="field"></sqx-field-form-validation>
</div>
<div class="table-items-row-details-tab" [class.hidden]="selectedTab !== 2">
<sqx-field-form-ui [editForm]="editForm.form" [field]="field"></sqx-field-form-ui>
</div>
</ng-container>
</form>
</div>
</ng-container> </ng-container>
<ng-container footer> <ng-container footer>
<button type="reset" class="float-left btn btn-secondary" (click)="complete()">Cancel</button> <button type="reset" class="float-left btn btn-secondary" (click)="complete()">Cancel</button>
<div class="float-right"> <div class="float-right" *ngIf="step === 1">
<button class="btn btn-success mr-1" (click)="addField(false)">Create and close</button> <button class="btn btn-success mr-1" (click)="addField(false, false)">Create and close</button>
<button class="btn btn-success" (click)="addField(true)">Create and new field</button> <button class="btn btn-success mr-1" (click)="addField(true, false)">Create and new field</button>
<button class="btn btn-success" (click)="addField(false, true)">Create and edit field</button>
</div>
<div class="float-right" *ngIf="step === 2">
<button class="btn btn-success mr-1" (click)="save(true)">Save and add field</button>
<button (click)="save()" class="btn btn-primary ml-1">Save and close</button>
</div> </div>
</ng-container> </ng-container>
</sqx-modal-dialog> </sqx-modal-dialog>
</form>

105
src/Squidex/app/features/schemas/pages/schema/field-wizard.component.ts

@ -5,25 +5,40 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import {
import { FormBuilder } from '@angular/forms'; Component,
ElementRef,
EventEmitter,
Input,
OnInit,
Output,
ViewChild
} from "@angular/core";
import { FormBuilder } from "@angular/forms";
import { import {
AddFieldForm, AddFieldForm,
AppPatternDto,
createProperties,
EditFieldForm,
FieldDto,
fieldTypes, fieldTypes,
ImmutableArray,
PatternsState,
RootFieldDto, RootFieldDto,
SchemaDetailsDto, SchemaDetailsDto,
SchemasState, SchemasState,
Types Types,
} from '@app/shared'; UpdateFieldDto
} from "@app/shared";
import { onErrorResumeNext } from "rxjs/operators";
@Component({ @Component({
selector: 'sqx-field-wizard', selector: "sqx-field-wizard",
styleUrls: ['./field-wizard.component.scss'], styleUrls: ["./field-wizard.component.scss"],
templateUrl: './field-wizard.component.html' templateUrl: "./field-wizard.component.html"
}) })
export class FieldWizardComponent implements OnInit { export class FieldWizardComponent implements OnInit {
@ViewChild('nameInput') @ViewChild("nameInput")
public nameInput: ElementRef; public nameInput: ElementRef;
@Input() @Input()
@ -38,42 +53,94 @@ export class FieldWizardComponent implements OnInit {
public fieldTypes = fieldTypes; public fieldTypes = fieldTypes;
public addFieldForm = new AddFieldForm(this.formBuilder); public addFieldForm = new AddFieldForm(this.formBuilder);
public editForm = new EditFieldForm(this.formBuilder);
public field: FieldDto;
public isEditing = false;
public selectedTab = 0;
public patterns: ImmutableArray<AppPatternDto>;
public step = 1;
constructor( constructor(
private readonly formBuilder: FormBuilder, private readonly formBuilder: FormBuilder,
private readonly schemasState: SchemasState private readonly schemasState: SchemasState,
) { public readonly patternsState: PatternsState
} ) {}
public ngOnInit() { public ngOnInit() {
if (this.parent) { if (this.parent) {
this.fieldTypes = this.fieldTypes.filter(x => x.type !== 'Array'); this.fieldTypes = this.fieldTypes.filter(x => x.type !== "Array");
} }
this.patternsState
.load()
.pipe(onErrorResumeNext())
.subscribe();
} }
public complete() { public complete() {
this.completed.emit(); this.completed.emit();
} }
public addField(next: boolean) { public addField(next: boolean, edit: boolean) {
const value = this.addFieldForm.submit(); const value = this.addFieldForm.submit();
if (value) { if (value) {
this.schemasState.addField(this.schema, value, this.parent) this.schemasState.addField(this.schema, value, this.parent).subscribe(
.subscribe(dto => { dto => {
this.field = dto;
this.addFieldForm.submitCompleted({ type: fieldTypes[0].type }); this.addFieldForm.submitCompleted({ type: fieldTypes[0].type });
if (next) { if (next) {
if (Types.isFunction(this.nameInput.nativeElement.focus)) { if (Types.isFunction(this.nameInput.nativeElement.focus)) {
this.nameInput.nativeElement.focus(); this.nameInput.nativeElement.focus();
} }
} else if (edit) {
this.selectTab(0);
this.step++;
} else { } else {
this.complete(); this.complete();
} }
}, error => { },
error => {
this.addFieldForm.submitFailed(error); this.addFieldForm.submitFailed(error);
});
} }
);
} }
} }
public selectTab(tab: number) {
this.selectedTab = tab;
}
public save(addNew: boolean) {
const value = this.editForm.submit();
if (value) {
const properties = createProperties(
this.field.properties["fieldType"],
value
);
this.schemasState
.updateField(
this.schema,
this.field as RootFieldDto,
new UpdateFieldDto(properties)
)
.subscribe(
() => {
this.isEditing = false;
this.editForm.submitCompleted();
if (addNew) {
this.step--;
} else {
this.complete();
}
},
error => {
this.editForm.submitFailed(error);
}
);
}
}
}

5
src/Squidex/app/features/schemas/pages/schema/field.component.ts

@ -71,6 +71,11 @@ export class FieldComponent implements OnInit {
public toggleEditing() { public toggleEditing() {
this.isEditing = !this.isEditing; this.isEditing = !this.isEditing;
// Reload the defaults if they were set in the wizard
if (this.isEditing) {
this.editForm.load(this.field.properties);
}
} }
public selectTab(tab: number) { public selectTab(tab: number) {

26
src/Squidex/app/features/schemas/pages/schema/forms/field-form-common.component.ts

@ -5,8 +5,8 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/ */
import { Component, Input } from '@angular/core'; import { Component, Input, OnChanges } from '@angular/core';
import { FormGroup } from '@angular/forms'; import { FormControl, FormGroup } from '@angular/forms';
import { FieldDto } from '@app/shared'; import { FieldDto } from '@app/shared';
@ -15,7 +15,7 @@ import { FieldDto } from '@app/shared';
styleUrls: ['field-form-common.component.scss'], styleUrls: ['field-form-common.component.scss'],
templateUrl: 'field-form-common.component.html' templateUrl: 'field-form-common.component.html'
}) })
export class FieldFormCommonComponent { export class FieldFormCommonComponent implements OnChanges {
@Input() @Input()
public editForm: FormGroup; public editForm: FormGroup;
@ -27,4 +27,24 @@ export class FieldFormCommonComponent {
@Input() @Input()
public field: FieldDto; public field: FieldDto;
public ngOnChanges() {
this.editForm.setControl('isRequired',
new FormControl(this.field.properties.isRequired));
this.editForm.setControl('isListField',
new FormControl(this.field.properties.isListField));
this.editForm.setControl('editorUrl',
new FormControl(this.field.properties.editorUrl));
this.editForm.setControl('hints',
new FormControl(this.field.properties.hints));
this.editForm.setControl('placeholder',
new FormControl(this.field.properties.placeholder));
this.editForm.setControl('label',
new FormControl(this.field.properties.label));
}
} }
Loading…
Cancel
Save