Headless CMS and Content Managment Hub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

238 lines
6.5 KiB

/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
import { Component, OnInit, ViewChild } from '@angular/core';
import { onErrorResumeNext, switchMap, tap } from 'rxjs/operators';
import {
AppLanguageDto,
ContentDto,
ContentsState,
LanguagesState,
ModalModel,
Queries,
Query,
QueryModel,
queryModelFromSchema,
ResourceOwner,
SchemaDetailsDto,
SchemasState,
UIState
} from '@app/shared';
import { DueTimeSelectorComponent } from './../../shared/due-time-selector.component';
@Component({
selector: 'sqx-contents-page',
styleUrls: ['./contents-page.component.scss'],
templateUrl: './contents-page.component.html'
})
export class ContentsPageComponent extends ResourceOwner implements OnInit {
public schema: SchemaDetailsDto;
public searchModal = new ModalModel();
public selectedItems: { [id: string]: boolean; } = {};
public selectedAll = false;
public selectionCount = 0;
public selectionCanDelete = false;
public nextStatuses: { [name: string]: string } = {};
public language: AppLanguageDto;
public languageMaster: AppLanguageDto;
public languages: ReadonlyArray<AppLanguageDto>;
public queryModel: QueryModel;
public queries: Queries;
public minWidth: string;
@ViewChild('dueTimeSelector', { static: false })
public dueTimeSelector: DueTimeSelectorComponent;
constructor(
public readonly contentsState: ContentsState,
private readonly languagesState: LanguagesState,
private readonly schemasState: SchemasState,
private readonly uiState: UIState
) {
super();
}
public ngOnInit() {
this.own(
this.schemasState.selectedSchema
.subscribe(schema => {
this.resetSelection();
this.schema = schema;
this.minWidth = `${300 + (200 * this.schema.listFields.length)}px`;
this.contentsState.load();
this.updateQueries();
this.updateModel();
}));
this.own(
this.contentsState.statuses
.subscribe(() => {
this.updateModel();
}));
this.own(
this.contentsState.contents
.subscribe(() => {
this.updateSelectionSummary();
}));
this.own(
this.languagesState.languages
.subscribe(languages => {
this.languages = languages.map(x => x.language);
this.language = this.languages[0];
this.languageMaster = this.languages.find(x => x.isMaster)!;
this.updateModel();
}));
}
public reload() {
this.contentsState.load(true);
}
public deleteSelected() {
this.contentsState.deleteMany(this.selectItems());
}
public delete(content: ContentDto) {
this.contentsState.deleteMany([content]);
}
public changeStatus(content: ContentDto, status: string) {
this.changeContentItems([content], status);
}
public changeSelectedStatus(status: string) {
this.changeContentItems(this.selectItems(c => c.status !== status), status);
}
public clone(content: ContentDto) {
this.contentsState.create(content.dataDraft, false);
}
private changeContentItems(contents: ReadonlyArray<ContentDto>, action: string) {
if (contents.length === 0) {
return;
}
this.dueTimeSelector.selectDueTime(action).pipe(
tap(() => {
this.resetSelection();
}),
switchMap(d => this.contentsState.changeManyStatus(contents, action, d)),
onErrorResumeNext())
.subscribe();
}
public goPrev() {
this.contentsState.goPrev();
}
public goNext() {
this.contentsState.goNext();
}
public search(query: Query) {
this.contentsState.search(query);
}
public selectLanguage(language: AppLanguageDto) {
this.language = language;
}
public isItemSelected(content: ContentDto): boolean {
return !!this.selectedItems[content.id];
}
private selectItems(predicate?: (content: ContentDto) => boolean) {
return this.contentsState.snapshot.contents.filter(c => this.selectedItems[c.id] && (!predicate || predicate(c)));
}
public selectItem(content: ContentDto, isSelected: boolean) {
this.selectedItems[content.id] = isSelected;
this.updateSelectionSummary();
}
private resetSelection() {
this.selectedItems = {};
this.updateSelectionSummary();
}
public selectAll(isSelected: boolean) {
this.selectedItems = {};
if (isSelected) {
for (let content of this.contentsState.snapshot.contents) {
this.selectedItems[content.id] = true;
}
}
this.updateSelectionSummary();
}
public trackByContent(index: number, content: ContentDto): string {
return content.id;
}
private updateSelectionSummary() {
this.selectedAll = this.contentsState.snapshot.contents.length > 0;
this.selectionCount = 0;
this.selectionCanDelete = true;
this.nextStatuses = {};
for (let content of this.contentsState.snapshot.contents) {
for (const info of content.statusUpdates) {
this.nextStatuses[info.status] = info.color;
}
}
for (let content of this.contentsState.snapshot.contents) {
if (this.selectedItems[content.id]) {
this.selectionCount++;
for (const action in this.nextStatuses) {
if (!content.statusUpdates) {
delete this.nextStatuses[action];
}
}
if (!content.canDelete) {
this.selectionCanDelete = false;
}
} else {
this.selectedAll = false;
}
}
}
private updateQueries() {
if (this.schema) {
this.queries = new Queries(this.uiState, `schemas.${this.schema.name}`);
}
}
private updateModel() {
if (this.schema && this.languages) {
this.queryModel = queryModelFromSchema(this.schema, this.languages, this.contentsState.snapshot.statuses);
}
}
}