diff --git a/src/Squidex/app/features/content/shared/array-editor.component.html b/src/Squidex/app/features/content/shared/array-editor.component.html index 033a1bfbc..c1b012aa8 100644 --- a/src/Squidex/app/features/content/shared/array-editor.component.html +++ b/src/Squidex/app/features/content/shared/array-editor.component.html @@ -11,7 +11,6 @@ [form]="form" [formContext]="formContext" [field]="field" - [isHidden]="snapshot.isHidden" [isDisabled]="arrayControl.disabled" [isFirst]="i === 0" [isLast]="i === arrayControl.controls.length - 1" @@ -21,16 +20,28 @@ [languages]="languages" (clone)="itemAdd(itemForm)" (move)="move(itemForm, $event)" - (remove)="itemRemove(i)" - (toggle)="hide($event)"> + (remove)="itemRemove(i)"> - +
+
+ +
+ +
+ + +
+
Add a nested field first to add items. diff --git a/src/Squidex/app/features/content/shared/array-editor.component.ts b/src/Squidex/app/features/content/shared/array-editor.component.ts index 6c6cf63df..34c527e13 100644 --- a/src/Squidex/app/features/content/shared/array-editor.component.ts +++ b/src/Squidex/app/features/content/shared/array-editor.component.ts @@ -6,20 +6,17 @@ */ import { CdkDragDrop } from '@angular/cdk/drag-drop'; -import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input, QueryList, ViewChildren } from '@angular/core'; import { AbstractControl, FormArray, FormGroup } from '@angular/forms'; import { AppLanguageDto, EditContentForm, RootFieldDto, - sorted, - StatefulComponent + sorted } from '@app/shared'; -interface State { - isHidden: boolean; -} +import { ArrayItemComponent } from './array-item.component'; @Component({ selector: 'sqx-array-editor', @@ -27,7 +24,7 @@ interface State { templateUrl: './array-editor.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) -export class ArrayEditorComponent extends StatefulComponent { +export class ArrayEditorComponent { @Input() public form: EditContentForm; @@ -46,15 +43,8 @@ export class ArrayEditorComponent extends StatefulComponent { @Input() public arrayControl: FormArray; - constructor(changeDetector: ChangeDetectorRef) { - super(changeDetector, { - isHidden: false - }); - } - - public hide(isHidden: boolean) { - this.next(s => ({ ...s, isHidden })); - } + @ViewChildren(ArrayItemComponent) + public children: QueryList; public itemRemove(index: number) { this.form.arrayItemRemove(this.field, this.language, index); @@ -68,6 +58,18 @@ export class ArrayEditorComponent extends StatefulComponent { this.sortInternal(sorted(event)); } + public collapseAll() { + this.children.forEach(component => { + component.collapse(); + }); + } + + public expandAll() { + this.children.forEach(component => { + component.expand(); + }); + } + public move(control: AbstractControl, index: number) { let controls = [...this.arrayControl.controls]; diff --git a/src/Squidex/app/features/content/shared/array-item.component.html b/src/Squidex/app/features/content/shared/array-item.component.html index d792b5f71..463f051c0 100644 --- a/src/Squidex/app/features/content/shared/array-item.component.html +++ b/src/Squidex/app/features/content/shared/array-item.component.html @@ -1,41 +1,45 @@
- - +
+
- - - Item #{{index + 1}} - - - - - - - - - - - - - - +
+
+
+ #{{index + 1}} + {{title}} +
+
+
+ + + + + + +
+
+ + + +
+
diff --git a/src/Squidex/app/features/content/shared/array-item.component.scss b/src/Squidex/app/features/content/shared/array-item.component.scss index e8609d45e..1ed7a51ec 100644 --- a/src/Squidex/app/features/content/shared/array-item.component.scss +++ b/src/Squidex/app/features/content/shared/array-item.component.scss @@ -19,13 +19,17 @@ line-height: 2.2rem; } - .header-text { + .header-index { display: inline-block; - min-width: 70px; - max-width: 100px; + min-width: 3rem; + max-width: 3rem; } } +.col { + overflow: hidden; +} + .btn-text-secondary { padding: .375rem; } diff --git a/src/Squidex/app/features/content/shared/array-item.component.ts b/src/Squidex/app/features/content/shared/array-item.component.ts index 1b6695fe6..8f4be9923 100644 --- a/src/Squidex/app/features/content/shared/array-item.component.ts +++ b/src/Squidex/app/features/content/shared/array-item.component.ts @@ -5,25 +5,31 @@ * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ -import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; +import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, OnChanges, OnDestroy, Output, SimpleChanges } from '@angular/core'; import { AbstractControl, FormGroup } from '@angular/forms'; -import { Observable } from 'rxjs'; +import { Observable, Subscription } from 'rxjs'; +import { startWith } from 'rxjs/operators'; import { AppLanguageDto, EditContentForm, FieldDto, + FieldFormatter, invalid$, RootFieldDto } from '@app/shared'; +type FieldControl = { field: FieldDto, control: AbstractControl }; + @Component({ selector: 'sqx-array-item', styleUrls: ['./array-item.component.scss'], templateUrl: './array-item.component.html', changeDetection: ChangeDetectionStrategy.OnPush }) -export class ArrayItemComponent implements OnChanges { +export class ArrayItemComponent implements OnChanges, OnDestroy { + private subscription: Subscription; + @Output() public remove = new EventEmitter(); @@ -33,9 +39,6 @@ export class ArrayItemComponent implements OnChanges { @Output() public clone = new EventEmitter(); - @Output() - public toggle = new EventEmitter(); - @Input() public form: EditContentForm; @@ -45,9 +48,6 @@ export class ArrayItemComponent implements OnChanges { @Input() public field: RootFieldDto; - @Input() - public isHidden = false; - @Input() public isFirst = false; @@ -69,22 +69,85 @@ export class ArrayItemComponent implements OnChanges { @Input() public languages: ReadonlyArray; + public isHidden = false; public isInvalid: Observable; - public fieldControls: ReadonlyArray<{ field: FieldDto, control: AbstractControl }>; + public title: string; + + public fieldControls: ReadonlyArray = []; + + constructor( + private readonly changeDetector: ChangeDetectorRef + ) { + } + + public ngOnDestroy() { + this.unsubscribeFromForm(); + } + + private unsubscribeFromForm() { + if (this.subscription) { + this.subscription.unsubscribe(); + } + } public ngOnChanges(changes: SimpleChanges) { if (changes['itemForm']) { this.isInvalid = invalid$(this.itemForm); + + this.unsubscribeFromForm(); + + this.subscription = + this.itemForm.valueChanges.pipe(startWith(this.itemForm.value)) + .subscribe(() => { + this.updateTitle(); + }); } if (changes['itemForm'] || changes['field']) { - this.fieldControls = this.field.nested.map(field => ({ field, control: this.itemForm.get(field.name)! })).filter(x => !x.field.properties.isContentField || !!x.control); + this.updateFields(); + this.updateTitle(); } } - public emitToggle(value: boolean) { - this.toggle.emit(value); + private updateFields() { + const fields: FieldControl[] = []; + + for (let field of this.field.nested) { + const control = this.itemForm.get(field.name)!; + + if (control || this.field.properties.isContentField) { + fields.push({ field, control }); + } + } + + this.fieldControls = fields; + } + + private updateTitle() { + const values: string[] = []; + + for (let { control, field } of this.fieldControls) { + const formatted = FieldFormatter.format(field, control.value); + + if (formatted) { + values.push(formatted); + } + } + + this.title = values.join(', '); + } + + public collapse() { + this.isHidden = true; + + this.changeDetector.detectChanges(); + } + + public expand() { + this.isHidden = false; + + this.changeDetector.detectChanges(); } public emitClone() {