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.
 
 
 
 
 

237 lines
7.6 KiB

/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved.
*/
// tslint:disable: max-line-length
import { Component, OnInit, ViewChild } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AppLanguageDto, AppsState, ContentDto, ContentsState, ContributorsState, defined, fadeAnimation, LanguagesState, ModalModel, Queries, Query, queryModelFromSchema, QuerySynchronizer, ResourceOwner, Router2State, SchemaDto, SchemasState, switchSafe, TableFields, TempService, UIState } from '@app/shared';
import { combineLatest } from 'rxjs';
import { distinctUntilChanged, map, switchMap, take, tap } from 'rxjs/operators';
import { DueTimeSelectorComponent } from './../../shared/due-time-selector.component';
@Component({
selector: 'sqx-contents-page',
styleUrls: ['./contents-page.component.scss'],
templateUrl: './contents-page.component.html',
providers: [
Router2State
],
animations: [
fadeAnimation
]
})
export class ContentsPageComponent extends ResourceOwner implements OnInit {
@ViewChild('dueTimeSelector', { static: false })
public dueTimeSelector: DueTimeSelectorComponent;
public schema: SchemaDto;
public tableView: TableFields;
public tableViewModal = new ModalModel();
public searchModal = new ModalModel();
public selectedItems: { [id: string]: boolean; } = {};
public selectedAll = false;
public selectionCount = 0;
public selectionCanDelete = false;
public selectionStatuses: { [name: string]: string } = {};
public language: AppLanguageDto;
public languages: ReadonlyArray<AppLanguageDto>;
public get disableScheduler() {
return this.appsState.snapshot.selectedSettings?.hideScheduler === true;
}
public queryModel =
combineLatest([
this.schemasState.selectedSchema.pipe(defined()),
this.languagesState.isoLanguages,
this.contentsState.statuses
]).pipe(
map(values => queryModelFromSchema(values[0], values[1], values[2])));
public queries =
this.schemasState.selectedSchema.pipe(defined(),
map(schema => new Queries(this.uiState, `schemas.${schema.name}`)));
constructor(
public readonly contentsRoute: Router2State,
public readonly contentsState: ContentsState,
public readonly languagesState: LanguagesState,
private readonly appsState: AppsState,
private readonly contributorsState: ContributorsState,
private readonly route: ActivatedRoute,
private readonly router: Router,
private readonly schemasState: SchemasState,
private readonly tempService: TempService,
private readonly uiState: UIState
) {
super();
}
public ngOnInit() {
if (this.appsState.snapshot.selectedApp?.canReadContributors) {
this.contributorsState.loadIfNotLoaded();
}
this.own(
this.languagesState.isoMasterLanguage
.subscribe(language => {
this.language = language;
}));
this.own(
this.languagesState.isoLanguages
.subscribe(languages => {
this.languages = languages;
}));
this.own(
getSchemaName(this.route).pipe(switchMap(() => this.schemasState.selectedSchema.pipe(defined(), take(1))))
.subscribe(schema => {
this.resetSelection();
this.schema = schema;
this.tableView = new TableFields(this.uiState, schema);
const initial =
this.contentsRoute.mapTo(this.contentsState)
.withPaging('contents', 10)
.withSynchronizer(QuerySynchronizer.INSTANCE)
.getInitial();
this.contentsState.load(false, initial);
this.contentsRoute.listen();
}));
this.own(
this.contentsState.contents
.subscribe(() => {
this.updateSelectionSummary();
}));
}
public reload() {
this.contentsState.load(true);
}
public delete(content: ContentDto) {
this.contentsState.deleteMany([content]);
}
public deleteSelected() {
this.contentsState.deleteMany(this.selectItems());
}
public changeStatus(content: ContentDto, status: string) {
this.changeContentItems([content], status);
}
public changeSelectedStatus(status: string) {
this.changeContentItems(this.selectItems(c => c.status !== status), status);
}
private changeContentItems(contents: ReadonlyArray<ContentDto>, action: string) {
if (contents.length === 0) {
return;
}
this.dueTimeSelector.selectDueTime(action).pipe(
tap(() => {
this.resetSelection();
}),
switchSafe(d => this.contentsState.changeManyStatus(contents, action, d)))
.subscribe();
}
public clone(content: ContentDto) {
this.tempService.put(content.data);
this.router.navigate(['new'], { relativeTo: this.route });
}
public search(query: Query) {
this.contentsState.search(query);
}
public isItemSelected(content: ContentDto): boolean {
return this.selectedItems[content.id] === true;
}
public resetSelection() {
this.selectedItems = {};
this.updateSelectionSummary();
}
public selectItem(content: ContentDto, isSelected: boolean) {
this.selectedItems[content.id] = isSelected;
this.updateSelectionSummary();
}
public selectAll(isSelected: boolean) {
this.selectedItems = {};
if (isSelected) {
for (const content of this.contentsState.snapshot.contents) {
this.selectedItems[content.id] = true;
}
}
this.updateSelectionSummary();
}
private updateSelectionSummary() {
this.selectedAll = this.contentsState.snapshot.contents.length > 0;
this.selectionCount = 0;
this.selectionCanDelete = true;
this.selectionStatuses = {};
for (const content of this.contentsState.snapshot.contents) {
for (const info of content.statusUpdates) {
this.selectionStatuses[info.status] = info.color;
}
}
for (const content of this.contentsState.snapshot.contents) {
if (this.selectedItems[content.id]) {
this.selectionCount++;
for (const action in this.selectionStatuses) {
if (this.selectionStatuses.hasOwnProperty(action)) {
if (!content.statusUpdates.find(x => x.status === action)) {
delete this.selectionStatuses[action];
}
}
}
if (!content.canDelete) {
this.selectionCanDelete = false;
}
} else {
this.selectedAll = false;
}
}
}
public trackByContent(_index: number, content: ContentDto): string {
return content.id;
}
private selectItems(predicate?: (content: ContentDto) => boolean) {
return this.contentsState.snapshot.contents.filter(c => this.selectedItems[c.id] && (!predicate || predicate(c)));
}
}
function getSchemaName(route: ActivatedRoute) {
return route.params.pipe(map(x => x['schemaName'] as string), distinctUntilChanged());
}