Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Squidex/squidex
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianStehle committed Feb 11, 2020
2 parents 26d2ada + aa49450 commit bdec13b
Show file tree
Hide file tree
Showing 16 changed files with 139 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD
}

private checkPendingChanges(action: string) {
if (this.content && !this.content.canUpdateAny) {
return of(true);
}

return this.contentForm.hasChanged() ?
this.dialogs.confirm('Unsaved changes', `You have unsaved changes.\n\nWhen you ${action} you will loose them.\n\n**Do you want to continue anyway?**`) :
of(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnDestroy, Output, QueryList, SimpleChanges, ViewChildren } from '@angular/core';
import { AbstractControl, FormGroup } from '@angular/forms';
import { Observable, Subscription } from 'rxjs';
import { startWith } from 'rxjs/operators';

import {
AppLanguageDto,
EditContentForm,
FieldDto,
FieldFormatter,
invalid$,
RootFieldDto
RootFieldDto,
value$
} from '@app/shared';

import { FieldEditorComponent } from './field-editor.component';
Expand Down Expand Up @@ -103,7 +103,7 @@ export class ArrayItemComponent implements OnChanges, OnDestroy {
this.unsubscribeFromForm();

this.subscription =
this.itemForm.valueChanges.pipe(startWith(this.itemForm.value))
value$(this.itemForm)
.subscribe(() => {
this.updateTitle();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<i class="icon-close"></i>
</button>

<div *ngIf="valueThumb | async; let thumbUrl; else noThumb" class="preview">
<img [src]="thumbUrl" />
<div *ngIf="stockPhotoThumbnail | async; let url; else noThumb" class="preview">
<img [src]="url" />
</div>

<ng-template #noThumb>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, OnInit } from '@angular/core';
import { FormControl, NG_VALUE_ACCESSOR } from '@angular/forms';
import { of } from 'rxjs';
import { debounceTime, distinctUntilChanged, map, shareReplay, startWith, switchMap, tap } from 'rxjs/operators';
import { debounceTime, map, switchMap, tap } from 'rxjs/operators';

import {
StatefulControlComponent,
StockPhotoDto,
StockPhotoService,
thumbnail,
Types
Types,
value$
} from '@app/shared';

interface State {
Expand All @@ -30,6 +31,8 @@ export const SQX_STOCK_PHOTO_EDITOR_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => StockPhotoEditorComponent), multi: true
};

const NO_EMIT = { emitEvent: false };

@Component({
selector: 'sqx-stock-photo-editor',
styleUrls: ['./stock-photo-editor.component.scss'],
Expand All @@ -42,18 +45,11 @@ export const SQX_STOCK_PHOTO_EDITOR_CONTROL_VALUE_ACCESSOR: any = {
export class StockPhotoEditorComponent extends StatefulControlComponent<State, string> implements OnInit {
public valueControl = new FormControl('');

public valueThumb =
this.valueControl.valueChanges.pipe(
startWith(this.valueControl.value),
shareReplay(1),
map(value => thumbnail(value, 400) || value));

public stockPhotoThumbnail = value$(this.valueControl).pipe(map(v => thumbnail(v, 400) || v));
public stockPhotoSearch = new FormControl('');

public stockPhotos =
this.stockPhotoSearch.valueChanges.pipe(
startWith(this.stockPhotoSearch.value),
distinctUntilChanged(),
value$(this.stockPhotoSearch).pipe(
debounceTime(500),
tap(query => {
if (query && query.length > 0) {
Expand All @@ -78,8 +74,6 @@ export class StockPhotoEditorComponent extends StatefulControlComponent<State, s
}

public ngOnInit() {
this.own(this.valueThumb);

this.own(
this.valueControl.valueChanges
.subscribe(value => {
Expand All @@ -89,9 +83,19 @@ export class StockPhotoEditorComponent extends StatefulControlComponent<State, s

public writeValue(obj: string) {
if (Types.isString(obj)) {
this.valueControl.setValue(obj, { emitEvent: true });
this.valueControl.setValue(obj);
} else {
this.valueControl.setValue('');
}
}

public setDisabledState(isDisabled: boolean): void {
super.setDisabledState(isDisabled);

if (isDisabled) {
this.stockPhotoSearch.disable(NO_EMIT);
} else {
this.valueControl.setValue('', { emitEvent: true });
this.stockPhotoSearch.enable(NO_EMIT);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@

<div class="form-group2 row">
<label class="col-3 col-form-label">
Allowed Extensions
File Extensions
</label>

<div class="col-6">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ <h4>Suggestions</h4>
{{patternName}}
</small>
</div>
<div class="form-group row" *ngIf="showPatternMessage">
<div class="form-group row" *ngIf="showPatternMessage | async">
<label class="col-3 col-form-label" for="{{field.fieldId}}_fieldPatternMessage">Pattern Message</label>

<div class="col-6">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/

import { Component, Input, OnInit } from '@angular/core';
import { Component, Input, OnChanges, OnInit } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { Observable } from 'rxjs';

import {
fadeAnimation,
FieldDto,
hasNoValue$,
hasValue$,
ModalModel,
PatternDto,
ResourceOwner,
RootFieldDto,
StringFieldPropertiesDto,
Types
Types,
value$
} from '@app/shared';

@Component({
Expand All @@ -29,7 +31,7 @@ import {
fadeAnimation
]
})
export class StringValidationComponent extends ResourceOwner implements OnInit {
export class StringValidationComponent extends ResourceOwner implements OnChanges, OnInit {
@Input()
public editForm: FormGroup;

Expand All @@ -43,7 +45,7 @@ export class StringValidationComponent extends ResourceOwner implements OnInit {
public patterns: ReadonlyArray<PatternDto>;

public showDefaultValue: Observable<boolean>;
public showPatternMessage: boolean;
public showPatternMessage: Observable<boolean>;
public showPatternSuggestions: Observable<boolean>;

public patternName: string;
Expand Down Expand Up @@ -80,13 +82,16 @@ export class StringValidationComponent extends ResourceOwner implements OnInit {
this.showPatternSuggestions =
hasNoValue$(this.editForm.controls['pattern']);

this.showPatternSuggestions =
hasNoValue$(this.editForm.controls['pattern']);

this.showPatternMessage =
this.editForm.controls['pattern'].value && this.editForm.controls['pattern'].value.trim().length > 0;
hasValue$(this.editForm.controls['pattern']);

this.own(
this.editForm.controls['pattern'].valueChanges
value$(this.editForm.controls['pattern'])
.subscribe((value: string) => {
if (!value || value.length === 0) {
if (!value) {
this.editForm.controls['patternMessage'].setValue(undefined);
}

Expand All @@ -96,22 +101,28 @@ export class StringValidationComponent extends ResourceOwner implements OnInit {
this.setPatternName();
}

public ngOnChanges() {
this.setPatternName();
}

public setPattern(pattern: PatternDto) {
this.patternName = pattern.name;
this.editForm.controls['pattern'].setValue(pattern.pattern);
this.editForm.controls['patternMessage'].setValue(pattern.message);
this.showPatternMessage = true;
}

private setPatternName() {
const matchingPattern = this.patterns.find(x => x.pattern === this.editForm.controls['pattern'].value);
const value = this.editForm.controls['pattern'].value;

if (matchingPattern) {
this.patternName = matchingPattern.name;
} else if (this.editForm.controls['pattern'].value && this.editForm.controls['pattern'].value.trim() !== '') {
this.patternName = 'Advanced';
} else {
if (!value) {
this.patternName = '';
} else {
const matchingPattern = this.patterns.find(x => x.pattern === this.editForm.controls['pattern'].value);

if (matchingPattern) {
this.patternName = matchingPattern.name;
} else {
this.patternName = 'Advanced';
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ export interface AutocompleteSource {
find(query: string): Observable<ReadonlyArray<any>>;
}

const NO_EMIT = { emitEvent: false };

export const SQX_AUTOCOMPLETE_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => AutocompleteComponent), multi: true
};
Expand All @@ -34,6 +32,8 @@ interface State {
suggestedIndex: number;
}

const NO_EMIT = { emitEvent: false };

@Component({
selector: 'sqx-autocomplete',
styleUrls: ['./autocomplete.component.scss'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<ng-container *sqxModal="dropdown">
<div class="control-dropdown" [sqxAnchoredTo]="input" position="bottom-left">
<div *ngIf="canSearch" class="search-form">
<input class="form-control search" [formControl]="queryInput" [disabled]="snapshot.isDisabled" placeholder="Search" (keydown)="onKeyDown($event)" sqxFocusOnInit />
<input class="form-control search" [formControl]="queryInput" placeholder="Search" (keydown)="onKeyDown($event)" sqxFocusOnInit />
</div>

<div class="control-dropdown-items" #container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ interface State {
query?: RegExp;
}

const NO_EMIT = { emitEvent: false };

@Component({
selector: 'sqx-dropdown',
styleUrls: ['./dropdown.component.scss'],
Expand Down Expand Up @@ -134,6 +136,16 @@ export class DropdownComponent extends StatefulControlComponent<State, ReadonlyA
this.selectIndex(this.items && obj ? this.items.indexOf(obj) : 0, false);
}

public setDisabledState(isDisabled: boolean): void {
super.setDisabledState(isDisabled);

if (isDisabled) {
this.queryInput.disable(NO_EMIT);
} else {
this.queryInput.enable(NO_EMIT);
}
}

public onKeyDown(event: KeyboardEvent) {
switch (event.keyCode) {
case Keys.UP:
Expand Down Expand Up @@ -208,6 +220,5 @@ export class DropdownComponent extends StatefulControlComponent<State, ReadonlyA

this.next(s => ({ ...s, selectedIndex, selectedItem: value }));
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ interface State {
items: ReadonlyArray<TagValue>;
}

const NO_EMIT = { emitEvent: false };

@Component({
selector: 'sqx-tag-editor',
styleUrls: ['./tag-editor.component.scss'],
Expand Down Expand Up @@ -302,9 +304,9 @@ export class TagEditorComponent extends StatefulControlComponent<State, Readonly
super.setDisabledState(isDisabled);

if (isDisabled) {
this.addInput.disable();
this.addInput.disable(NO_EMIT);
} else {
this.addInput.enable();
this.addInput.enable(NO_EMIT);
}
}

Expand Down
46 changes: 46 additions & 0 deletions frontend/app/framework/angular/forms/forms-helper.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/

import { FormControl, Validators } from '@angular/forms';

import { value$ } from './forms-helper';

describe('FormHelpers', () => {
describe('value$', () => {
it('should provide change values', () => {
const form = new FormControl('1', Validators.required);

const values: any[] = [];

value$(form).subscribe(x => {
values.push(x);
});

form.setValue('2');
form.setValue('3');

expect(values).toEqual(['1', '2', '3']);
});

it('should not trigger on disable', () => {
const form = new FormControl('1', Validators.required);

const values: any[] = [];

value$(form).subscribe(x => {
values.push(x);
});

form.setValue('2');
form.enable();
form.setValue('3');
form.disable();

expect(values).toEqual(['1', '2', '3']);
});
});
});
4 changes: 2 additions & 2 deletions frontend/app/framework/angular/forms/forms-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { AbstractControl, FormArray, FormGroup } from '@angular/forms';
import { Observable } from 'rxjs';
import { distinctUntilChanged, map, startWith } from 'rxjs/operators';
import { distinctUntilChanged, filter, map, startWith } from 'rxjs/operators';

import { Types } from './../../utils/types';

Expand All @@ -26,7 +26,7 @@ export function invalid$(form: AbstractControl): Observable<boolean> {
}

export function value$<T = any>(form: AbstractControl): Observable<T> {
return form.valueChanges.pipe(startWith(form.value));
return form.valueChanges.pipe(startWith(form.value), filter(_ => form.enabled), distinctUntilChanged());
}

export function hasValue$(form: AbstractControl): Observable<boolean> {
Expand Down
Loading

0 comments on commit bdec13b

Please sign in to comment.