@paperbits/core
Version:
Paperbits core components.
136 lines (108 loc) • 4.88 kB
text/typescript
import * as ko from "knockout";
import { ChangeRateLimit } from "@paperbits/common/ko/consts";
import { Component, Event, OnMounted } from "@paperbits/common/ko/decorators";
import { Logger } from "@paperbits/common/logging";
import { IWidgetService, WidgetModel } from "@paperbits/common/widgets";
import { WidgetItem } from "./widgetItem";
import template from "./widgetSelector.html";
import { ViewManager } from "@paperbits/common/ui";
import { IWidgetOrder } from "@paperbits/common/editing";
import { ContentModel } from "../../../content";
({
selector: "widget-selector",
template: template
})
export class WidgetSelector {
private originalCategories: any;
public readonly filteredCategories: ko.Observable<{ name: string, items: WidgetItem[] }[]>;
public readonly categories: ko.Observable<{ name: string, items: WidgetItem[] }[]>;
public readonly widgetCount: ko.Observable<number>;
public readonly working: ko.Observable<boolean>;
public readonly searchPattern: ko.Observable<string>;
constructor(
private readonly widgetService: IWidgetService,
private readonly viewManager: ViewManager,
private readonly logger: Logger
) {
this.working = ko.observable(true);
this.searchPattern = ko.observable<string>();
this.categories = ko.observable<{ name: string, items: WidgetItem[] }[]>();
this.widgetCount = ko.observable();
}
()
public onSelect: (widgetModel: WidgetModel) => void;
()
public onRequest: () => string[];
()
public initialize(): void {
this.loadWidgetOrders();
this.searchPattern
.extend(ChangeRateLimit)
.subscribe(this.searchWidgets);
}
public async searchWidgets(pattern: string): Promise<void> {
pattern = pattern.toLowerCase();
const filteredCategories = this.originalCategories
.map(category => ({
name: category.name,
items: category.items.filter(w => w.displayName.toLowerCase().includes(pattern))
}))
.filter(category => category.items.length > 0);
this.categories(filteredCategories);
const widgetCount = filteredCategories.length > 0
? filteredCategories.map(category => category.items.length).reduce((x, y) => x += y)
: 0;
this.widgetCount(widgetCount);
}
private async getContentPartOrders(): Promise<IWidgetOrder<unknown>[]> {
const activeLayer = this.viewManager.getActiveLayer();
if (activeLayer !== "layout") {
return [];
}
const pageContentWidgetOrder: IWidgetOrder<unknown> = {
displayName: "Page content",
category: "Layout",
createModel: async () => {
const model = new ContentModel();
model.type = "page";
return model;
}
}
return [pageContentWidgetOrder];
}
private async loadWidgetOrders(): Promise<void> {
this.working(true);
const items = new Array<WidgetItem>();
const widgetOrders = await this.widgetService.getWidgetOrders();
const provided = this.onRequest();
const contentParts = await this.getContentPartOrders();
widgetOrders.push(...contentParts);
widgetOrders
.filter(widgetOrder => !widgetOrder.requires || widgetOrder.requires.every(entry => provided.includes(entry)))
.forEach(widgetOrder => {
const widgetItem = new WidgetItem();
widgetItem.name = widgetOrder.name;
widgetItem.displayName = widgetOrder.displayName;
widgetItem.css = `${widgetOrder.iconClass}`;
widgetItem.iconUrl = widgetOrder.iconUrl;
widgetItem.category = widgetOrder.category || "";
widgetItem.createModel = widgetOrder.createModel
items.push(widgetItem);
});
const groupsObj = items.reduce((result, item) => {
(result[item["category"]] = result[item["category"]] || []).push(item);
return result;
}, {});
const groups = Object.keys(groupsObj).map(category => {
return { name: category, items: groupsObj[category] };
});
this.originalCategories = groups;
this.categories(this.originalCategories);
this.working(false);
}
public async selectWidget(widgetItem: WidgetItem): Promise<void> {
const widgetModel = await widgetItem.createModel();
this.onSelect(widgetModel);
this.logger.trackEvent("WidgetAdded", { name: widgetItem.name });
}
}