@paperbits/core
Version:
Paperbits core components.
118 lines (93 loc) • 3.63 kB
text/typescript
import * as ko from "knockout";
import template from "./urlSelector.html";
import { UrlItem } from "./urlItem";
import { IUrlService, UrlContract } from "@paperbits/common/urls";
import { Component, Event, OnMounted } from "@paperbits/common/ko/decorators";
import { ChangeRateLimit } from "@paperbits/common/ko/consts";
import { Query, Operator, Page } from "@paperbits/common/persistence";
import { HyperlinkModel } from "@paperbits/common/permalinks";
export class UrlSelector {
private currentPage: Page<UrlContract>;
public readonly searchPattern: ko.Observable<string>;
public readonly urls: ko.ObservableArray<UrlItem>;
public readonly uri: ko.Observable<string>;
public readonly working: ko.Observable<boolean>;
public readonly selectedUrl: ko.Observable<UrlItem>;
constructor(private readonly urlService: IUrlService) {
this.uri = ko.observable<string>("https://");
this.urls = ko.observableArray();
this.selectedUrl = ko.observable();
this.searchPattern = ko.observable();
this.working = ko.observable(false);
}
public onSelect: (selection: UrlContract) => void;
public onHyperlinkSelect: (selection: HyperlinkModel) => void;
public async onMounted(): Promise<void> {
await this.searchUrls();
this.searchPattern
.extend(ChangeRateLimit)
.subscribe(this.searchUrls);
}
public async searchUrls(searchPattern: string = ""): Promise<void> {
this.working(true);
this.urls([]);
const query = Query
.from<UrlContract>()
.orderBy(`title`);
if (searchPattern) {
query.where(`title`, Operator.contains, searchPattern);
}
const pageOfResults = await this.urlService.search(query);
this.currentPage = pageOfResults;
const urlItems = pageOfResults.value.map(media => new UrlItem(media));
this.urls.push(...urlItems);
this.working(false);
}
public async loadNextPage(): Promise<void> {
if (!this.currentPage?.takeNext || this.working()) {
return;
}
this.working(true);
this.currentPage = await this.currentPage.takeNext();
const urlItems = this.currentPage.value.map(page => new UrlItem(page));
this.urls.push(...urlItems);
this.working(false);
}
public async selectUrl(urlItem: UrlItem): Promise<void> {
const uri = this.selectedUrl();
if (uri) {
uri.hasFocus(false);
}
urlItem.hasFocus(true);
this.selectedUrl(urlItem);
if (this.onSelect) {
this.onSelect(urlItem.toContract());
}
if (this.onHyperlinkSelect) {
this.onHyperlinkSelect(urlItem.getHyperlink());
}
}
public async createUrl(): Promise<void> {
const newUri = this.uri();
const urlContract = await this.urlService.createUrl(newUri, newUri);
const urlItem = new UrlItem(urlContract);
if (this.onHyperlinkSelect) {
this.onHyperlinkSelect(urlItem.getHyperlink());
}
}
public async deleteUrl(): Promise<void> {
const uri = this.selectedUrl();
if (uri) {
await this.urlService.deleteUrl(uri.toContract());
}
this.uri("https://");
await this.searchUrls();
}
}