View browser profiles in UI (#209)

This commit is contained in:
sua yoo 2022-04-13 21:10:22 -07:00 committed by GitHub
parent 2f63c7dcf8
commit d2653ae835
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 232 additions and 1 deletions

View File

@ -430,6 +430,7 @@ export class App extends LiteElement {
case "archiveAddMember":
case "archiveNewResourceTab":
case "archiveCrawl":
case "browserProfile":
case "crawlTemplate":
case "crawlTemplateEdit":
return html`<btrix-archive
@ -442,6 +443,7 @@ export class App extends LiteElement {
.viewStateData=${this.viewState.data}
archiveId=${this.viewState.params.id}
archiveTab=${this.viewState.params.tab as ArchiveTab}
browserProfileId=${this.viewState.params.browserProfileId}
crawlConfigId=${this.viewState.params.crawlConfigId}
crawlId=${this.viewState.params.crawlId}
?isAddingMember=${this.viewState.route === "archiveAddMember"}

View File

@ -0,0 +1,57 @@
import { state, property } from "lit/decorators.js";
import { msg, localized, str } from "@lit/localize";
import type { AuthState } from "../../utils/AuthService";
import LiteElement, { html } from "../../utils/LiteElement";
import { Profile } from "./types";
/**
* Usage:
* ```ts
* <btrix-browser-profiles-detail></btrix-browser-profiles-detail>
* ```
*/
@localized()
export class BrowserProfilesDetail extends LiteElement {
@property({ type: Object })
authState!: AuthState;
@property({ type: String })
archiveId!: string;
@property({ type: String })
profileId!: string;
@state()
private profile: Partial<Profile> = {
id: "2",
name: "Twitter Webrecorder",
description: "Et netus et malesuada fames.",
created: new Date().toUTCString(),
origins: ["https://twitter.com", "https://twitter.com/webrecorder_io"],
};
render() {
return html`<div class="mb-7">
<a
class="text-neutral-500 hover:text-neutral-600 text-sm font-medium"
href=${`/archives/${this.archiveId}/browser-profiles`}
@click=${this.navLink}
>
<sl-icon
name="arrow-left"
class="inline-block align-middle"
></sl-icon>
<span class="inline-block align-middle"
>${msg("Back to Browser Profiles")}</span
>
</a>
</div>
<header>
<h2 class="text-2xl font-medium mb-3 md:h-8">${this.profile.name}</h2>
</header>`;
}
}
customElements.define("btrix-browser-profiles-detail", BrowserProfilesDetail);

View File

@ -0,0 +1,124 @@
import { state, property } from "lit/decorators.js";
import { msg, localized, str } from "@lit/localize";
import type { AuthState } from "../../utils/AuthService";
import LiteElement, { html } from "../../utils/LiteElement";
import { Profile } from "./types";
/**
* Usage:
* ```ts
* <btrix-browser-profiles-list></btrix-browser-profiles-list>
* ```
*/
@localized()
export class BrowserProfilesList extends LiteElement {
@property({ type: Object })
authState!: AuthState;
@property({ type: String })
archiveId?: string;
@state()
browserProfiles?: Profile[];
firstUpdated() {
this.fetchCrawls();
}
render() {
return html` ${this.renderTable()} `;
}
renderTable() {
return html`
<div role="table">
<div class="mb-2 px-4" role="rowgroup">
<div
class="hidden md:grid grid-cols-7 gap-3 md:gap-5 text-sm text-neutral-500"
role="row"
>
<div class="col-span-3" role="columnheader" aria-sort="none">
${msg("Description")}
</div>
<div class="col-span-1" role="columnheader" aria-sort="none">
${msg("Created")}
</div>
<div class="col-span-3" role="columnheader" aria-sort="none">
${msg("Visited URLs")}
</div>
</div>
</div>
${this.browserProfiles
? this.browserProfiles.length
? html`<div class="border rounded" role="rowgroup">
${this.browserProfiles.map(this.renderItem.bind(this))}
</div>`
: html`
<div class="border-t border-b py-5">
<p class="text-center text-0-500">
${msg("No browser profiles yet.")}
</p>
</div>
`
: ""}
</div>
`;
}
private renderItem(data: Profile) {
return html`
<a
class="block p-4 leading-none border-t first:border-t-0 transition-colors"
title=${data.name}
>
<div class="grid grid-cols-7 gap-3 md:gap-5" role="row">
<div class="col-span-7 md:col-span-3" role="cell">
<div class="font-medium mb-1">${data.name}</div>
<div class="text-sm truncate" title=${data.description}>
${data.description}
</div>
</div>
<div class="col-span-7 md:col-span-1 text-sm" role="cell">
${new Date(data.created).toLocaleDateString()}
</div>
<div class="col-span-7 md:col-span-3 text-sm" role="cell">
${data.origins.join(", ")}
</div>
</div>
</a>
`;
}
/**
* Fetch browser profiles and update internal state
*/
private async fetchCrawls(): Promise<void> {
try {
const data = await this.getProfiles();
this.browserProfiles = data;
} catch (e) {
this.notify({
message: msg("Sorry, couldn't retrieve browser profiles at this time."),
type: "danger",
icon: "exclamation-octagon",
});
}
}
private async getProfiles(): Promise<Profile[]> {
if (!this.archiveId) {
throw new Error(`Archive ID ${typeof this.archiveId}`);
}
const data = await this.apiFetch(
`/archives/${this.archiveId}/profiles`,
this.authState!
);
return data;
}
}
customElements.define("btrix-browser-profiles-list", BrowserProfilesList);

View File

@ -13,8 +13,14 @@ import "./crawl-templates-list";
import "./crawl-templates-new";
import "./crawl-detail";
import "./crawls-list";
import "./browser-profiles-detail";
import "./browser-profiles-list";
export type ArchiveTab = "crawls" | "crawl-templates" | "members";
export type ArchiveTab =
| "crawls"
| "crawl-templates"
| "browser-profiles"
| "members";
const defaultTab = "crawls";
@ -36,6 +42,9 @@ export class Archive extends LiteElement {
@property({ type: String })
archiveTab: ArchiveTab = defaultTab;
@property({ type: String })
browserProfileId?: string;
@property({ type: String })
crawlId?: string;
@ -114,6 +123,9 @@ export class Archive extends LiteElement {
case "crawl-templates":
tabPanelContent = this.renderCrawlTemplates();
break;
case "browser-profiles":
tabPanelContent = this.renderBrowserProfiles();
break;
case "members":
if (this.isAddingMember) {
tabPanelContent = this.renderAddMember();
@ -149,6 +161,10 @@ export class Archive extends LiteElement {
tabName: "crawl-templates",
label: msg("Crawl Templates"),
})}
${this.renderNavTab({
tabName: "browser-profiles",
label: msg("Browser Profiles"),
})}
${showMembersTab
? this.renderNavTab({ tabName: "members", label: msg("Members") })
: ""}
@ -245,6 +261,21 @@ export class Archive extends LiteElement {
></btrix-crawl-templates-list>`;
}
private renderBrowserProfiles() {
if (this.browserProfileId) {
return html`<btrix-browser-profiles-detail
.authState=${this.authState!}
.archiveId=${this.archiveId!}
profileId=${this.browserProfileId}
></btrix-browser-profiles-detail>`;
}
return html`<btrix-browser-profiles-list
.authState=${this.authState!}
.archiveId=${this.archiveId!}
></btrix-browser-profiles-list>`;
}
private renderMembers() {
if (!this.archive!.users) return;

View File

@ -55,3 +55,19 @@ export type CrawlTemplate = {
config: CrawlConfig;
scale: number;
};
export type Profile = {
id: string;
name: string;
description: string;
created: string;
origins: string[];
baseId: string;
baseProfileName: string;
aid: string;
resource: {
filename: string;
hash: string;
size: number;
};
};

View File

@ -15,6 +15,7 @@ export const ROUTES = {
archiveNewResourceTab: "/archives/:id/:tab/new",
archiveAddMember: "/archives/:id/:tab/add-member",
archiveCrawl: "/archives/:id/:tab/crawl/:crawlId",
browserProfile: "/archives/:id/:tab/profile/:browserProfileId",
crawlTemplate: "/archives/:id/:tab/config/:crawlConfigId",
crawlTemplateEdit: "/archives/:id/:tab/config/:crawlConfigId?edit",
users: "/users",