import { state, property, customElement } from "lit/decorators.js"; import { msg, localized } from "@lit/localize"; import type { AuthState } from "@/utils/AuthService"; import LiteElement, { html } from "@/utils/LiteElement"; import type { Profile } from "./types"; import type { APIPaginatedList } from "@/types/api"; import type { SelectNewDialogEvent } from "./index"; import type { Browser } from "@/types/browser"; import { nothing } from "lit"; /** * Usage: * ```ts * * ``` */ @localized() @customElement("btrix-browser-profiles-list") export class BrowserProfilesList extends LiteElement { @property({ type: Object }) authState!: AuthState; @property({ type: String }) orgId!: string; @state() browserProfiles?: Profile[]; firstUpdated() { void this.fetchBrowserProfiles(); } render() { return html`

${msg("Browser Profiles")}

{ this.dispatchEvent( new CustomEvent("select-new-dialog", { detail: "browser-profile", }) as SelectNewDialogEvent, ); }} > ${msg("New Browser Profile")}
${this.renderTable()}
`; } private renderTable() { return html` ${msg("Backed up status")} ${msg("Name")} ${msg("Date Created")} ${msg("Visited URLs")} ${msg("Row Actions")} ${this.browserProfiles?.length ? html` ${this.browserProfiles.map(this.renderItem)} ` : nothing} ${this.browserProfiles?.length ? nothing : html`

${msg("No browser profiles yet.")}

`} `; } private readonly renderItem = (data: Profile) => { const isBackedUp = data.resource && data.resource.replicas.length > 0; return html` ${data.name}
${data.description} ${data.description} ${data.description} ${data.description} ${data.description} ${data.description} ${data.description}
${data.origins.join(", ")} ${this.renderActions(data)}
`; }; private renderActions(data: Profile) { return html` e.preventDefault()}> { void this.duplicateProfile(data); }} > ${msg("Duplicate profile")} { void this.deleteProfile(data); }} > ${msg("Delete")} `; } private async duplicateProfile(profile: Profile) { const url = profile.origins[0]; try { const data = await this.createBrowser({ url }); this.notify({ message: msg("Starting up browser with selected profile..."), variant: "success", icon: "check2-circle", }); this.navTo( `${this.orgBasePath}/browser-profiles/profile/browser/${ data.browserid }?name=${window.encodeURIComponent( profile.name, )}&description=${window.encodeURIComponent( profile.description || "", )}&profileId=${window.encodeURIComponent(profile.id)}&navigateUrl=`, ); } catch (e) { this.notify({ message: msg("Sorry, couldn't create browser profile at this time."), variant: "danger", icon: "exclamation-octagon", }); } } private async deleteProfile(profile: Profile) { try { const data = await this.apiFetch( `/orgs/${this.orgId}/profiles/${profile.id}`, this.authState!, { method: "DELETE", }, ); if (data.error && data.crawlconfigs) { this.notify({ message: msg( html`Could not delete ${profile.name}, in use by ${data.crawlconfigs.map(({ name }) => name).join(", ")}. Please remove browser profile from Workflow to continue.`, ), variant: "warning", icon: "exclamation-triangle", duration: 15000, }); } else { this.notify({ message: msg(html`Deleted ${profile.name}.`), variant: "success", icon: "check2-circle", }); this.browserProfiles = this.browserProfiles!.filter( (p) => p.id !== profile.id, ); } } catch (e) { this.notify({ message: msg("Sorry, couldn't delete browser profile at this time."), variant: "danger", icon: "exclamation-octagon", }); } } private async createBrowser({ url }: { url: string }) { const params = { url, }; return this.apiFetch( `/orgs/${this.orgId}/profiles/browser`, this.authState!, { method: "POST", body: JSON.stringify(params), }, ); } /** * Fetch browser profiles and update internal state */ private async fetchBrowserProfiles(): Promise { try { const data = await this.getProfiles(); this.browserProfiles = data; } catch (e) { this.notify({ message: msg("Sorry, couldn't retrieve browser profiles at this time."), variant: "danger", icon: "exclamation-octagon", }); } } private async getProfiles() { const data = await this.apiFetch>( `/orgs/${this.orgId}/profiles`, this.authState!, ); return data.items; } }