Browse Source

Merge pull request #4 from Avd6977/FieldEditWizard

Allow users to edit the field after they create it in the field wizar…
pull/328/head
Avd6977 7 years ago
committed by GitHub
parent
commit
5948c45d7e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 155
      src/Squidex/app/features/schemas/pages/schema/field-wizard.component.html
  2. 173
      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

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

@ -1,68 +1,111 @@
<form [formGroup]="addFieldForm.form" (ngSubmit)="addField(false)">
<sqx-modal-dialog (closed)="complete()" large="true">
<ng-container title>
<ng-container *ngIf="parent; else noParent">
Add Nested Field
</ng-container>
<ng-template #noParent>
Add Field
</ng-template>
<sqx-modal-dialog (closed)="complete()" large="true">
<ng-container title>
<ng-container *ngIf="parent; else noParent">
Add Nested Field
</ng-container>
<ng-container content>
<sqx-form-error [error]="addFieldForm.error | async"></sqx-form-error>
<div class="form-group">
<div class="row">
<div class="col-4 type" *ngFor="let fieldType of fieldTypes">
<label>
<input type="radio" class="radio-input" formControlName="type" value="{{fieldType.type}}" />
<div class="row no-gutters">
<div class="col col-auto">
<div class="type-icon" [class.active]="addFieldForm.form.controls['type'].value === fieldType.type">
<i class="icon-type-{{fieldType.type}}"></i>
<ng-template #noParent>
{{step === 1 ? 'Add' : 'Edit'}} Field
</ng-template>
</ng-container>
<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>
<div class="form-group">
<div class="row">
<div class="col-4 type" *ngFor="let fieldType of fieldTypes">
<label>
<input type="radio" class="radio-input" formControlName="type" value="{{fieldType.type}}" />
<div class="row no-gutters">
<div class="col col-auto">
<div class="type-icon" [class.active]="addFieldForm.form.controls['type'].value === fieldType.type">
<i class="icon-type-{{fieldType.type}}"></i>
</div>
</div>
<div class="col-lg">
<div class="type-title">{{fieldType.type}}</div>
<div class="type-text text-muted">{{fieldType.description}}</div>
</div>
</div>
<div class="col-lg">
<div class="type-title">{{fieldType.type}}</div>
<div class="type-text text-muted">{{fieldType.description}}</div>
</div>
</div>
</label>
</label>
</div>
</div>
</div>
</div>
<div class="form-group">
<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 />
</div>
<div class="form-group" *ngIf="!parent">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="isLocalizable" formControlName="isLocalizable" />
<label class="form-check-label" for="isLocalizable">
Localizable
</label>
<div class="form-group">
<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 />
</div>
<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.
</small>
</div>
<div class="form-group" *ngIf="!parent">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="isLocalizable" formControlName="isLocalizable" />
<label class="form-check-label" for="isLocalizable">
Localizable
</label>
</div>
<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.
</small>
</div>
</form>
</ng-container>
<ng-container footer>
<button type="reset" class="float-left btn btn-secondary" (click)="complete()">Cancel</button>
<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>
<div class="float-right">
<button class="btn btn-success mr-1" (click)="addField(false)">Create and close</button>
<button class="btn btn-success" (click)="addField(true)">Create and new field</button>
</div>
</ng-container>
</sqx-modal-dialog>
</form>
<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 footer>
<button type="reset" class="float-left btn btn-secondary" (click)="complete()">Cancel</button>
<div class="float-right" *ngIf="step === 1">
<button class="btn btn-success mr-1" (click)="addField(false, false)">Create and close</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>
</ng-container>
</sqx-modal-dialog>

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

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

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.
*/
import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { Component, Input, OnChanges } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { FieldDto } from '@app/shared';
@ -15,7 +15,7 @@ import { FieldDto } from '@app/shared';
styleUrls: ['field-form-common.component.scss'],
templateUrl: 'field-form-common.component.html'
})
export class FieldFormCommonComponent {
export class FieldFormCommonComponent implements OnChanges {
@Input()
public editForm: FormGroup;
@ -27,4 +27,24 @@ export class FieldFormCommonComponent {
@Input()
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