Browse Source

Bugfixes for contributors and form comparison.

pull/411/head
Sebastian Stehle 7 years ago
parent
commit
3e31a9a2d8
  1. 18
      src/Squidex/app/features/content/pages/content/content-page.component.ts
  2. 6
      src/Squidex/app/features/content/shared/array-editor.component.html
  3. 8
      src/Squidex/app/features/content/shared/array-editor.component.ts
  4. 2
      src/Squidex/app/features/settings/pages/contributors/contributors-page.component.html
  5. 2
      src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts
  6. 20
      src/Squidex/app/framework/angular/forms/forms-helper.ts
  7. 2
      src/Squidex/app/framework/angular/modals/modal-dialog.component.ts
  8. 22
      src/Squidex/app/framework/state.ts
  9. 12
      src/Squidex/app/framework/utils/error.ts
  10. 28
      src/Squidex/app/shared/state/contents.forms.ts
  11. 10
      src/Squidex/app/shared/state/contributors.forms.ts
  12. 4
      src/Squidex/app/shared/state/contributors.state.ts

18
src/Squidex/app/features/content/pages/content/content-page.component.ts

@ -117,14 +117,14 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD
if (content) {
this.content = content;
this.loadContent(this.content.dataDraft);
this.loadContent(this.content.dataDraft, true);
}
if (autosaved) {
this.dialogs.confirm('Unsaved changes', 'You have unsaved changes. Do you want to load them now?')
.subscribe(shouldLoad => {
if (shouldLoad) {
this.loadContent(autosaved);
this.loadContent(autosaved, false);
} else {
this.autoSaveService.remove(this.autoSaveKey);
}
@ -149,7 +149,7 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD
}
public canDeactivate(): Observable<boolean> {
if (!this.contentForm.hasChanged(this.content)) {
if (!this.contentForm.hasChanged()) {
return of(true);
} else {
return this.dialogs.confirm('Unsaved changes', 'You have unsaved changes, do you want to close the current content view and discard your changes?').pipe(
@ -227,13 +227,13 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD
this.router.navigate([this.schema.name], { relativeTo: this.route.parent!.parent, replaceUrl: true });
}
private loadContent(data: any) {
private loadContent(data: any, isInitial: boolean) {
this.isLoadingContent = true;
this.autoSaveService.remove(this.autoSaveKey);
try {
this.contentForm.loadContent(data);
this.contentForm.load(data, isInitial);
this.contentForm.setEnabled(!this.content || this.content.canUpdateAny);
} finally {
this.isLoadingContent = false;
@ -267,7 +267,7 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD
if (!this.content || version === null || version.eq(this.content.version)) {
this.contentFormCompare = null;
this.contentVersion = null;
this.loadContent(this.content.dataDraft);
this.loadContent(this.content.dataDraft, true);
} else {
this.contentsState.loadVersion(this.content, version)
.subscribe(dto => {
@ -276,16 +276,16 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD
this.contentFormCompare = new EditContentForm(this.schema, this.languages);
}
this.contentFormCompare.loadContent(dto.payload);
this.contentFormCompare.load(dto.payload);
this.contentFormCompare.setEnabled(false);
this.loadContent(this.content.dataDraft);
this.loadContent(this.content.dataDraft, false);
} else {
if (this.contentFormCompare) {
this.contentFormCompare = null;
}
this.loadContent(dto.payload);
this.loadContent(dto.payload, false);
}
this.contentVersion = version;

6
src/Squidex/app/features/content/shared/array-editor.component.html

@ -14,15 +14,15 @@
[itemForm]="itemForm"
[language]="language"
[languages]="languages"
(clone)="addItem(itemForm)"
(clone)="itemAdd(itemForm)"
(move)="move(itemForm, $event)"
(remove)="removeItem(i)"
(remove)="itemRemove(i)"
(toggle)="hide($event)">
</sqx-array-item>
</div>
</div>
<button type="button" class="btn btn-success" [disabled]="field.nested.length === 0 || arrayControl.disabled" (click)="addItem(undefined)">
<button type="button" class="btn btn-success" [disabled]="field.nested.length === 0 || arrayControl.disabled" (click)="itemAdd(undefined)">
Add Item
</button>

8
src/Squidex/app/features/content/shared/array-editor.component.ts

@ -54,12 +54,12 @@ export class ArrayEditorComponent extends StatefulComponent<State> {
this.next(s => ({ ...s, isHidden }));
}
public removeItem(index: number) {
this.form.removeArrayItem(this.field, this.language, index);
public itemRemove(index: number) {
this.form.arrayItemRemove(this.field, this.language, index);
}
public addItem(value?: FormGroup) {
this.form.insertArrayItem(this.field, this.language, value);
public itemAdd(value?: FormGroup) {
this.form.arrayItemInsert(this.field, this.language, value);
}
public sort(controls: AbstractControl[]) {

2
src/Squidex/app/features/settings/pages/contributors/contributors-page.component.html

@ -92,7 +92,7 @@
</div>
<sqx-form-hint class="text-right">
Big team? <a class="force" (click)="importDialog.show()">Hide many contributors at once</a>
Big team? <a class="force" (click)="importDialog.show()">Add many contributors at once</a>
</sqx-form-hint>
</ng-container>
</ng-container>

2
src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts

@ -108,6 +108,8 @@ export class ContributorsPageComponent implements OnInit {
if (isCreated) {
this.dialogs.notifyInfo('A new user with the entered email address has been created and assigned as contributor.');
} else {
this.dialogs.notifyInfo('User has been added as contributor.');
}
}, error => {
this.assignContributorForm.submitFailed(error);

20
src/Squidex/app/framework/angular/forms/forms-helper.ts

@ -37,25 +37,11 @@ export function hasNoValue$(form: AbstractControl): Observable<boolean> {
return value$(form).pipe(map(v => !v));
}
export function fullValue(form: AbstractControl): any {
export function getRawValue(form: AbstractControl): any {
if (Types.is(form, FormGroup)) {
const groupValue = {};
for (let key in form.controls) {
if (form.controls.hasOwnProperty(key)) {
groupValue[key] = fullValue(form.controls[key]);
}
}
return groupValue;
return form.getRawValue();
} else if (Types.is(form, FormArray)) {
const arrayValue = [];
for (let child of form.controls) {
arrayValue.push(fullValue(child));
}
return arrayValue;
return form.getRawValue();
} else {
return form.value;
}

2
src/Squidex/app/framework/angular/modals/modal-dialog.component.ts

@ -68,7 +68,7 @@ export class ModalDialogComponent extends StatefulComponent<State> implements Af
const hasTabs = this.tabsElement.nativeElement.children.length > 0;
const hasFooter = this.footerElement.nativeElement.children.length > 0;
this.next(() => ({ hasTabs, hasFooter }));
this.next({ hasTabs, hasFooter });
}
public emitClose() {

22
src/Squidex/app/framework/state.ts

@ -9,13 +9,13 @@ import { AbstractControl } from '@angular/forms';
import { BehaviorSubject, Observable } from 'rxjs';
import { distinctUntilChanged, map } from 'rxjs/operators';
import { ErrorDto } from './utils/error';
import { ErrorDto, getDisplayMessage } from './utils/error';
import { ResourceLinks } from './utils/hateos';
import { Types } from './utils/types';
import { fullValue } from './angular/forms/forms-helper';
import { getRawValue } from './angular/forms/forms-helper';
export interface FormState {
submitted: boolean;
@ -70,16 +70,16 @@ export class Form<T extends AbstractControl, V> {
}
public load(value: V | undefined) {
this.state.next(() => ({ submitted: false, error: null }));
this.state.next({ submitted: false, error: null });
this.setValue(value);
}
public submit(): V | null {
this.state.next(() => ({ submitted: true }));
this.state.next({ submitted: true, error: null });
if (this.form.valid) {
const value = this.transformSubmit(fullValue(this.form));
const value = this.transformSubmit(getRawValue(this.form));
if (value) {
this.disable();
@ -92,7 +92,7 @@ export class Form<T extends AbstractControl, V> {
}
public submitCompleted(options?: { newValue?: V, noReset?: boolean }) {
this.state.next(() => ({ submitted: false, error: null }));
this.state.next({ submitted: false, error: null });
this.enable();
@ -104,18 +104,10 @@ export class Form<T extends AbstractControl, V> {
}
public submitFailed(error?: string | ErrorDto) {
this.state.next(() => ({ submitted: false, error: this.getError(error) }));
this.state.next({ submitted: false, error: getDisplayMessage(error) });
this.enable();
}
private getError(error?: string | ErrorDto) {
if (Types.is(error, ErrorDto)) {
return error.displayMessage;
} else {
return error;
}
}
}
export class Model<T> {

12
src/Squidex/app/framework/utils/error.ts

@ -5,6 +5,8 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { Types } from './types';
export class ErrorDto {
public readonly displayMessage: string;
@ -22,6 +24,16 @@ export class ErrorDto {
}
}
export function getDisplayMessage(error?: string | ErrorDto) {
if (!error) {
return null;
} else if (Types.is(error, ErrorDto)) {
return error.displayMessage;
} else {
return error;
}
}
function formatMessage(message: string, details?: string[]) {
const appendLast = (row: string, char: string) => {

28
src/Squidex/app/shared/state/contents.forms.ts

@ -395,7 +395,7 @@ export class FieldDefaultValue implements FieldPropertiesVisitor<any> {
}
export class EditContentForm extends Form<FormGroup, any> {
private isLoaded = false;
private initialData: any;
public value = value$(this.form);
@ -432,26 +432,22 @@ export class EditContentForm extends Form<FormGroup, any> {
}
}
this.initialData = this.form.getRawValue();
this.enable();
}
public hasChanged(content?: ContentDto) {
if (!this.isLoaded && !this.form.touched) {
return false;
}
public hasChanged() {
const currentValue = this.form.getRawValue();
if (content) {
return !Types.jsJsonEquals(this.form.value, content.data);
} else {
return true;
}
return !Types.jsJsonEquals(this.initialData, currentValue);
}
public removeArrayItem(field: RootFieldDto, language: AppLanguageDto, index: number) {
public arrayItemRemove(field: RootFieldDto, language: AppLanguageDto, index: number) {
this.findArrayItemForm(field, language).removeAt(index);
}
public insertArrayItem(field: RootFieldDto, language: AppLanguageDto, source?: FormGroup) {
public arrayItemInsert(field: RootFieldDto, language: AppLanguageDto, source?: FormGroup) {
if (field.nested.length > 0) {
const formControl = this.findArrayItemForm(field, language);
@ -495,9 +491,7 @@ export class EditContentForm extends Form<FormGroup, any> {
}
}
public loadContent(value: any) {
this.isLoaded = true;
public load(value: any, isInitial?: boolean) {
for (let field of this.schema.fields) {
if (field.isArray && field.nested.length > 0) {
const fieldForm = <FormGroup>this.form.get(field.name);
@ -534,6 +528,10 @@ export class EditContentForm extends Form<FormGroup, any> {
}
super.load(value);
if (isInitial) {
this.initialData = this.form.getRawValue();
}
}
public disable() {

10
src/Squidex/app/shared/state/contributors.forms.ts

@ -32,12 +32,14 @@ export class AssignContributorForm extends Form<FormGroup, AssignContributorDto>
}));
}
protected transformSubmit(value: string | UserDto) {
if (Types.is(value, UserDto)) {
value = value.id;
protected transformSubmit(value: { user: string | UserDto }) {
let contributorId = value.user;
if (Types.is(contributorId, UserDto)) {
contributorId = contributorId.id;
}
return { contributorId: value, role: 'Editor', invite: true };
return { contributorId, role: 'Editor', invite: true };
}
}

4
src/Squidex/app/shared/state/contributors.state.ts

@ -7,7 +7,7 @@
import { Injectable } from '@angular/core';
import { combineLatest, Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';
import { catchError, share, tap } from 'rxjs/operators';
import {
DialogService,
@ -82,7 +82,7 @@ export class ContributorsState extends State<Snapshot> {
this.project(x => !!x.canCreate);
public filtered =
combineLatest(this.queryRegex, this.contributors, (q, c) => getFilteredContributors(c, q));
combineLatest(this.queryRegex, this.contributors, (q, c) => getFilteredContributors(c, q)).pipe(share());
public contributorsPaged =
combineLatest(this.page, this.filtered, (p, c) => getPagedContributors(c, p));

Loading…
Cancel
Save