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 * * ``` */ @localized() export class BrowserProfilesList extends LiteElement { @property({ type: Object }) authState!: AuthState; @property({ type: String }) archiveId!: string; @property({ type: Boolean }) showCreateDialog = false; @state() browserProfiles?: Profile[]; @state() private isCreateFormVisible = false; @state() private isSubmitting = false; /** Profile creation only works in Chromium-based browsers */ private isBrowserCompatible = Boolean((window as any).chrome); firstUpdated() { if (this.showCreateDialog) { this.isCreateFormVisible = true; } this.fetchBrowserProfiles(); } render() { return html`
${msg("New Browser Profile")}
${this.renderTable()} (this.isCreateFormVisible = true)} @sl-after-hide=${() => (this.isCreateFormVisible = false)} > ${this.isBrowserCompatible ? "" : html`
${msg( "Browser profile creation is only supported in Chromium-based browsers (such as Chrome) at this time. Please re-open this page in a compatible browser to proceed." )}
`} ${this.isCreateFormVisible ? this.renderCreateForm() : ""}
`; } private renderTable() { return html`
${this.browserProfiles ? this.browserProfiles.length ? html`
${this.browserProfiles.map(this.renderItem.bind(this))}
` : html`

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

` : ""}
`; } private renderItem(data: Profile) { return html`
${data.name}
${data.description}
${new Date(data.created).toLocaleDateString()}
${data.origins.join(", ")}
`; } private renderCreateForm() { return html`
http:// https://
${msg("More options")}
${this.browserProfiles?.map( (profile) => html` ${profile.name} ` )}
${msg("Cancel")} ${msg("Start Browser")}
`; } private hideDialog() { this.navTo(`/archives/${this.archiveId}/browser-profiles`); } async onSubmit(event: { detail: { formData: FormData } }) { this.isSubmitting = true; const { formData } = event.detail; const url = formData.get("url") as string; const params = { url: `${formData.get("urlPrefix")}${url.substring(url.indexOf(",") + 1)}`, baseId: formData.get("baseId"), }; try { const data = await this.apiFetch( `/archives/${this.archiveId}/profiles/browser`, this.authState!, { method: "POST", body: JSON.stringify(params), } ); this.notify({ message: msg("Starting up browser for profile creation."), type: "success", icon: "check2-circle", }); this.navTo( `/archives/${this.archiveId}/browser-profiles/profile/browser/${data.browserid}` ); } catch (e) { this.isSubmitting = false; this.notify({ message: msg("Sorry, couldn't create browser profile at this time."), type: "danger", icon: "exclamation-octagon", }); } } /** * 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."), type: "danger", icon: "exclamation-octagon", }); } } private async getProfiles(): Promise { const data = await this.apiFetch( `/archives/${this.archiveId}/profiles`, this.authState! ); return data; } /** * Stop propgation of sl-select events. * Prevents bug where sl-dialog closes when dropdown closes * https://github.com/shoelace-style/shoelace/issues/170 */ private stopProp(e: CustomEvent) { e.stopPropagation(); } } customElements.define("btrix-browser-profiles-list", BrowserProfilesList);