/* * Squidex Headless CMS * * @license * Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. */ import { CdkDragDrop } from '@angular/cdk/drag-drop'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, forwardRef, Input } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { AppLanguageDto, AppsState, ContentDto, ContentsService, DialogModel, sorted, StatefulControlComponent, Types } from '@app/shared'; export const SQX_REFERENCES_EDITOR_CONTROL_VALUE_ACCESSOR: any = { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ReferencesEditorComponent), multi: true, }; interface State { // The content items to show. contentItems: ReadonlyArray; // True, when width less than 600 pixels. isCompact?: boolean; } @Component({ selector: 'sqx-references-editor[formContext][language][languages][schemaIds]', styleUrls: ['./references-editor.component.scss'], templateUrl: './references-editor.component.html', providers: [ SQX_REFERENCES_EDITOR_CONTROL_VALUE_ACCESSOR, ], changeDetection: ChangeDetectionStrategy.OnPush, }) export class ReferencesEditorComponent extends StatefulControlComponent> { @Input() public schemaIds: ReadonlyArray; @Input() public language: AppLanguageDto; @Input() public languages: ReadonlyArray; @Input() public formContext: any; @Input() public allowDuplicates?: boolean | null = true; @Input() public set disabled(value: boolean | undefined | null) { this.setDisabledState(value === true); } public clonedContent?: ContentDto; public contentCreatorDialog = new DialogModel(); public contentSelectorDialog = new DialogModel(); constructor(changeDetector: ChangeDetectorRef, private readonly appsState: AppsState, private readonly contentsService: ContentsService, ) { super(changeDetector, { contentItems: [] }); } public writeValue(obj: any) { if (Types.isArrayOfString(obj)) { if (!Types.equals(obj, this.snapshot.contentItems.map(x => x.id))) { const contentIds: string[] = obj; this.contentsService.getAllContents(this.appsState.appName, { ids: contentIds }) .subscribe({ next: dtos => { this.setContentItems(contentIds.map(id => dtos.items.find(c => c.id === id)!).filter(r => !!r)); if (this.snapshot.contentItems.length !== contentIds.length) { this.updateValue(); } }, error: () => { this.setContentItems([]); }, }); } } else { this.setContentItems([]); } } public setContentItems(contentItems: ReadonlyArray) { this.next({ contentItems }); } public select(contents: ReadonlyArray) { this.setContentItems([...this.snapshot.contentItems, ...contents]); if (contents.length > 0) { this.updateValue(); } this.contentSelectorDialog.hide(); this.contentCreatorDialog.hide(); } public remove(content: ContentDto) { if (content && !this.snapshot.isDisabled) { this.setContentItems(this.snapshot.contentItems.filter(x => x.id !== content.id)); this.updateValue(); } } public sort(event: CdkDragDrop>) { if (event && !this.snapshot.isDisabled) { this.setContentItems(sorted(event)); this.updateValue(); } } public createContent(clone?: ContentDto) { this.clonedContent = clone; this.contentCreatorDialog.show(); } private updateValue() { const ids = this.snapshot.contentItems.map(x => x.id); if (ids.length === 0) { this.callChange(null); } else { this.callChange(ids); } this.callTouched(); } public setCompact(isCompact: boolean) { this.next({ isCompact }); } public trackByContent(_index: number, content: ContentDto) { return content.id; } }