UNPKG

@paperbits/core

Version:
118 lines (93 loc) 3.63 kB
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"; @Component({ selector: "url-selector", template: template }) 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); } @Event() public onSelect: (selection: UrlContract) => void; @Event() public onHyperlinkSelect: (selection: HyperlinkModel) => void; @OnMounted() 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(); } }