Fix browser profile origins sidebar overlap (#530)
This commit is contained in:
parent
7d25565ef4
commit
f94be79364
@ -1,12 +1,12 @@
|
||||
// import { LitElement, html } from "lit";
|
||||
import { property, state } from "lit/decorators.js";
|
||||
import { ref } from "lit/directives/ref.js";
|
||||
import { property, state, query } from "lit/decorators.js";
|
||||
import { msg, localized, str } from "@lit/localize";
|
||||
|
||||
import type { AuthState } from "../utils/AuthService";
|
||||
import LiteElement, { html } from "../utils/LiteElement";
|
||||
|
||||
const POLL_INTERVAL_SECONDS = 2;
|
||||
const hiddenClassList = ["translate-x-2/3", "opacity-0", "pointer-events-none"];
|
||||
|
||||
/**
|
||||
* View embedded profile browser
|
||||
@ -26,10 +26,6 @@ const POLL_INTERVAL_SECONDS = 2;
|
||||
*/
|
||||
@localized()
|
||||
export class ProfileBrowser extends LiteElement {
|
||||
// TODO remove sidebar constaint once devtools panel
|
||||
// is hidden on the backend
|
||||
static SIDE_BAR_WIDTH = 288;
|
||||
|
||||
@property({ type: Object })
|
||||
authState!: AuthState;
|
||||
|
||||
@ -57,9 +53,21 @@ export class ProfileBrowser extends LiteElement {
|
||||
@state()
|
||||
private isFullscreen = false;
|
||||
|
||||
@state()
|
||||
private showOriginSidebar = false;
|
||||
|
||||
@state()
|
||||
private newOrigins: string[] = [];
|
||||
|
||||
@query("#profileBrowserSidebar")
|
||||
private sidebar?: HTMLElement;
|
||||
|
||||
@query("#iframeWrapper")
|
||||
private iframeWrapper?: HTMLElement;
|
||||
|
||||
@query("iframe")
|
||||
private iframe?: HTMLIFrameElement;
|
||||
|
||||
private pollTimerId?: number;
|
||||
|
||||
connectedCallback() {
|
||||
@ -73,7 +81,7 @@ export class ProfileBrowser extends LiteElement {
|
||||
document.removeEventListener("fullscreenchange", this.onFullscreenChange);
|
||||
}
|
||||
|
||||
updated(changedProperties: Map<string, any>) {
|
||||
willUpdate(changedProperties: Map<string, any>) {
|
||||
if (changedProperties.has("browserId")) {
|
||||
if (this.browserId) {
|
||||
window.clearTimeout(this.pollTimerId);
|
||||
@ -85,40 +93,84 @@ export class ProfileBrowser extends LiteElement {
|
||||
window.clearTimeout(this.pollTimerId);
|
||||
}
|
||||
}
|
||||
if (
|
||||
changedProperties.has("showOriginSidebar") &&
|
||||
changedProperties.get("showOriginSidebar") !== undefined
|
||||
) {
|
||||
this.animateSidebar();
|
||||
}
|
||||
}
|
||||
|
||||
private animateSidebar() {
|
||||
if (!this.sidebar) return;
|
||||
if (this.showOriginSidebar) {
|
||||
this.sidebar.classList.remove(...hiddenClassList);
|
||||
} else {
|
||||
this.sidebar.classList.add(...hiddenClassList);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div id="interactive-browser" class="lg:flex relative">
|
||||
<div class="grow lg:rounded-lg border overflow-hidden bg-slate-50">
|
||||
<div id="interactive-browser" class="w-full h-full flex flex-col">
|
||||
${this.renderControlBar()}
|
||||
<div
|
||||
id="iframeWrapper"
|
||||
class="${this.isFullscreen
|
||||
? "w-screen h-screen"
|
||||
: "border-t"} flex-1 relative bg-neutral-50 overflow-hidden"
|
||||
aria-live="polite"
|
||||
>
|
||||
${this.renderBrowser()}
|
||||
<div
|
||||
class="w-full ${this.isFullscreen ? "h-screen" : "h-96"}"
|
||||
aria-live="polite"
|
||||
id="profileBrowserSidebar"
|
||||
class="${hiddenClassList.join(
|
||||
" "
|
||||
)} lg:absolute top-0 right-0 bottom-0 lg:w-80 lg:p-3 flex transition-all duration-300 ease-out"
|
||||
>
|
||||
${this.renderBrowser()}
|
||||
</div>
|
||||
<div
|
||||
class="rounded-b lg:rounded-b-none lg:rounded-r border w-72 bg-white absolute h-full top-0 right-0"
|
||||
>
|
||||
${document.fullscreenEnabled ? this.renderFullscreenButton() : ""}
|
||||
${this.renderOrigins()} ${this.renderNewOrigins()}
|
||||
<div
|
||||
class="shadow-lg overflow-auto border rounded-lg bg-white flex-1"
|
||||
>
|
||||
${this.renderOrigins()} ${this.renderNewOrigins()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderControlBar() {
|
||||
if (this.isFullscreen) {
|
||||
return html`
|
||||
<div
|
||||
class="fixed top-2 left-1/2 bg-white rounded-lg shadow z-50 -translate-x-1/2 flex items-center text-base"
|
||||
>
|
||||
${this.renderSidebarButton()}
|
||||
<sl-icon-button
|
||||
name="fullscreen-exit"
|
||||
@click=${() => document.exitFullscreen()}
|
||||
></sl-icon-button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<div class="text-right text-base p-1">
|
||||
${this.renderSidebarButton()}
|
||||
<sl-icon-button
|
||||
name="arrows-fullscreen"
|
||||
@click=${() => this.enterFullscreen("interactive-browser")}
|
||||
></sl-icon-button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderBrowser() {
|
||||
if (this.hasFetchError) {
|
||||
return html`
|
||||
<div style="padding-right: ${ProfileBrowser.SIDE_BAR_WIDTH}px;">
|
||||
<btrix-alert
|
||||
variant="danger"
|
||||
style="padding-right: ${ProfileBrowser.SIDE_BAR_WIDTH}px;"
|
||||
>
|
||||
${msg(`The interactive browser is not available.`)}
|
||||
</btrix-alert>
|
||||
</div>
|
||||
<btrix-alert variant="danger">
|
||||
${msg(`The interactive browser is not available.`)}
|
||||
</btrix-alert>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -128,16 +180,12 @@ export class ProfileBrowser extends LiteElement {
|
||||
title=${msg("Interactive browser for creating browser profile")}
|
||||
src=${this.iframeSrc}
|
||||
@load=${this.onIframeLoad}
|
||||
${ref((el) => this.onIframeRef(el as HTMLIFrameElement))}
|
||||
></iframe>`;
|
||||
}
|
||||
|
||||
if (this.browserId && !this.isIframeLoaded) {
|
||||
return html`
|
||||
<div
|
||||
class="w-full h-full flex items-center justify-center text-3xl"
|
||||
style="padding-right: ${ProfileBrowser.SIDE_BAR_WIDTH}px;"
|
||||
>
|
||||
<div class="w-full h-full flex items-center justify-center text-3xl">
|
||||
<sl-spinner></sl-spinner>
|
||||
</div>
|
||||
`;
|
||||
@ -146,37 +194,13 @@ export class ProfileBrowser extends LiteElement {
|
||||
return "";
|
||||
}
|
||||
|
||||
private renderFullscreenButton() {
|
||||
if (!this.browserId) return;
|
||||
|
||||
private renderSidebarButton() {
|
||||
return html`
|
||||
<div class="p-2 text-right">
|
||||
<sl-button
|
||||
size="small"
|
||||
@click=${() =>
|
||||
this.isFullscreen
|
||||
? document.exitFullscreen()
|
||||
: this.enterFullscreen("interactive-browser")}
|
||||
>
|
||||
${this.isFullscreen
|
||||
? html`
|
||||
<sl-icon
|
||||
slot="prefix"
|
||||
name="fullscreen-exit"
|
||||
label=${msg("Exit fullscreen")}
|
||||
></sl-icon>
|
||||
${msg("Exit")}
|
||||
`
|
||||
: html`
|
||||
<sl-icon
|
||||
slot="prefix"
|
||||
name="arrows-fullscreen"
|
||||
label=${msg("Enter fullscreen")}
|
||||
></sl-icon>
|
||||
${msg("Fullscreen")}
|
||||
`}
|
||||
</sl-button>
|
||||
</div>
|
||||
<sl-icon-button
|
||||
name="layout-sidebar-reverse"
|
||||
class="${this.showOriginSidebar ? "text-blue-600" : ""}"
|
||||
@click=${() => (this.showOriginSidebar = !this.showOriginSidebar)}
|
||||
></sl-icon-button>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -353,8 +377,8 @@ export class ProfileBrowser extends LiteElement {
|
||||
private async enterFullscreen(id: string) {
|
||||
try {
|
||||
document.getElementById(id)!.requestFullscreen({
|
||||
// Show browser navigation controls
|
||||
navigationUI: "show",
|
||||
// Hide browser navigation controls
|
||||
navigationUI: "hide",
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
@ -363,31 +387,17 @@ export class ProfileBrowser extends LiteElement {
|
||||
|
||||
private onIframeLoad() {
|
||||
this.isIframeLoaded = true;
|
||||
|
||||
try {
|
||||
this.iframe?.contentWindow?.localStorage.setItem("uiTheme", '"default"');
|
||||
} catch (e) {}
|
||||
this.dispatchEvent(new CustomEvent("load", { detail: this.iframeSrc }));
|
||||
}
|
||||
|
||||
private onFullscreenChange = () => {
|
||||
private onFullscreenChange = async () => {
|
||||
if (document.fullscreenElement) {
|
||||
this.isFullscreen = true;
|
||||
} else {
|
||||
this.isFullscreen = false;
|
||||
}
|
||||
};
|
||||
|
||||
private onIframeRef(el: HTMLIFrameElement) {
|
||||
if (!el) return;
|
||||
|
||||
el.addEventListener("load", () => {
|
||||
// TODO see if we can make this work locally without CORs errors
|
||||
try {
|
||||
//el.style.width = "132%";
|
||||
el.contentWindow?.localStorage.setItem("uiTheme", '"default"');
|
||||
el.contentWindow?.localStorage.setItem(
|
||||
"InspectorView.screencastSplitViewState",
|
||||
`{"vertical":{"size":${ProfileBrowser.SIDE_BAR_WIDTH}}}`
|
||||
);
|
||||
} catch (e) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { state, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
import { when } from "lit/directives/when.js";
|
||||
import { msg, localized, str } from "@lit/localize";
|
||||
|
||||
import type { AuthState } from "../../utils/AuthService";
|
||||
import LiteElement, { html } from "../../utils/LiteElement";
|
||||
import { ProfileBrowser } from "../../components/profile-browser";
|
||||
import { Profile } from "./types";
|
||||
|
||||
/**
|
||||
@ -80,7 +80,7 @@ export class BrowserProfilesDetail extends LiteElement {
|
||||
</div>
|
||||
|
||||
<header class="md:flex items-center justify-between mb-3">
|
||||
<h2 class="text-xl md:text-2xl font-semibold md:h-9 mb-1">
|
||||
<h2 class="text-xl font-semibold md:h-9 mb-1">
|
||||
${this.profile?.name
|
||||
? html`${this.profile?.name}
|
||||
<sl-button
|
||||
@ -169,87 +169,51 @@ export class BrowserProfilesDetail extends LiteElement {
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<header>
|
||||
<h3 class="text-lg font-medium">${msg("Browser Profile")}</h3>
|
||||
</header>
|
||||
|
||||
<div class="rounded p-2 bg-slate-50">
|
||||
<div class="mb-2 flex justify-between items-center">
|
||||
<div class="text-sm text-neutral-500 mx-1">
|
||||
${this.browserId
|
||||
? html`
|
||||
${msg(
|
||||
"Interact with the browsing tool to make changes to your browser profile."
|
||||
)}
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
${this.browserId && !this.isBrowserLoading
|
||||
? html`
|
||||
<sl-button size="small" @click=${this.cancelEditBrowser}
|
||||
>${msg("Cancel")}</sl-button
|
||||
>
|
||||
<sl-button
|
||||
variant="primary"
|
||||
size="small"
|
||||
?loading=${this.isSubmittingBrowserChange}
|
||||
?disabled=${this.isSubmittingBrowserChange ||
|
||||
!this.isBrowserLoaded}
|
||||
@click=${this.saveBrowser}
|
||||
>${msg("Save")}</sl-button
|
||||
>
|
||||
`
|
||||
: html`
|
||||
<sl-button
|
||||
size="small"
|
||||
?loading=${this.isBrowserLoading}
|
||||
?disabled=${this.isBrowserLoading}
|
||||
@click=${this.duplicateProfile}
|
||||
>${msg("Duplicate")}</sl-button
|
||||
>
|
||||
`}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main class="relative">
|
||||
<btrix-profile-browser
|
||||
.authState=${this.authState}
|
||||
orgId=${this.orgId}
|
||||
browserId=${ifDefined(this.browserId)}
|
||||
.origins=${this.profile?.origins}
|
||||
@load=${() => (this.isBrowserLoaded = true)}
|
||||
></btrix-profile-browser>
|
||||
|
||||
${this.browserId || this.isBrowserLoading
|
||||
? ""
|
||||
: html`
|
||||
<div
|
||||
class="absolute top-0 left-0 h-full flex flex-col items-center justify-center"
|
||||
style="right: ${ProfileBrowser.SIDE_BAR_WIDTH}px;"
|
||||
>
|
||||
<p class="mb-4 text-neutral-600 max-w-prose">
|
||||
${msg(
|
||||
"Load browser to view or edit websites in the profile."
|
||||
)}
|
||||
</p>
|
||||
<sl-button
|
||||
variant="primary"
|
||||
outline
|
||||
@click=${this.startBrowserPreview}
|
||||
><sl-icon
|
||||
slot="prefix"
|
||||
name="collection-play-fill"
|
||||
></sl-icon>
|
||||
${msg("Load Browser")}</sl-button
|
||||
>
|
||||
</div>
|
||||
`}
|
||||
</main>
|
||||
</div>
|
||||
</section>
|
||||
<div class="flex">
|
||||
<section class="flex-1">
|
||||
<header class="mb-2">
|
||||
<h3 class="text-lg font-medium">${msg("Browser Profile")}</h3>
|
||||
</header>
|
||||
${when(
|
||||
this.browserId || this.isBrowserLoading,
|
||||
() => html`
|
||||
<div
|
||||
class="border rounded-lg overflow-hidden h-screen flex flex-col"
|
||||
>
|
||||
<btrix-profile-browser
|
||||
class="flex-1"
|
||||
.authState=${this.authState}
|
||||
orgId=${this.orgId}
|
||||
browserId=${ifDefined(this.browserId)}
|
||||
.origins=${this.profile?.origins}
|
||||
@load=${() => (this.isBrowserLoaded = true)}
|
||||
></btrix-profile-browser>
|
||||
<div class="flex-0 border-t">
|
||||
${this.renderBrowserProfileControls()}
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
() => html`<div
|
||||
class="border rounded-lg bg-neutral-50 aspect-4/3 flex flex-col items-center justify-center"
|
||||
>
|
||||
<p class="mb-4 text-neutral-600 max-w-prose">
|
||||
${msg(
|
||||
"Edit the profile to make changes or view its present configuration"
|
||||
)}
|
||||
</p>
|
||||
<sl-button @click=${this.startBrowserPreview}
|
||||
><sl-icon slot="prefix" name="pencil-square"></sl-icon> ${msg(
|
||||
"Edit Browser Profile"
|
||||
)}</sl-button
|
||||
>
|
||||
</div>`
|
||||
)}
|
||||
</section>
|
||||
${when(
|
||||
!(this.browserId || this.isBrowserLoading),
|
||||
this.renderVisitedSites
|
||||
)}
|
||||
</div>
|
||||
|
||||
<sl-dialog
|
||||
label=${msg(str`Edit Profile`)}
|
||||
@ -262,6 +226,48 @@ export class BrowserProfilesDetail extends LiteElement {
|
||||
</sl-dialog> `;
|
||||
}
|
||||
|
||||
private renderVisitedSites = () => {
|
||||
return html`
|
||||
<section class="flex-grow-1 lg:w-80 lg:pl-6 flex flex-col">
|
||||
<header class="flex-0 mb-2">
|
||||
<h3 class="text-lg font-medium">${msg("Visited Sites")}</h3>
|
||||
</header>
|
||||
<div class="border rounded-lg p-4 flex-1 overflow-auto">
|
||||
<ul class="font-monostyle text-neutral-800">
|
||||
${this.profile?.origins.map((origin) => html`<li>${origin}</li>`)}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
`;
|
||||
};
|
||||
|
||||
private renderBrowserProfileControls() {
|
||||
return html`
|
||||
<div class="flex justify-between p-4">
|
||||
<div class="max-w-prose">
|
||||
<p class="text-xs text-neutral-500 mx-1">
|
||||
${msg(
|
||||
"Interact with the browsing tool to set up the browser profile. Crawl configs that use this browser profile will behave as if they have logged into the same websites and have the same cookies that have been set here."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<sl-button size="small" @click=${this.cancelEditBrowser}
|
||||
>${msg("Cancel")}</sl-button
|
||||
>
|
||||
<sl-button
|
||||
variant="primary"
|
||||
size="small"
|
||||
?loading=${this.isSubmittingBrowserChange}
|
||||
?disabled=${this.isSubmittingBrowserChange || !this.isBrowserLoaded}
|
||||
@click=${this.saveBrowser}
|
||||
>${msg("Save Browser Profile")}</sl-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderMenu() {
|
||||
return html`
|
||||
<sl-dropdown placement="bottom-end" distance="4">
|
||||
|
@ -88,27 +88,32 @@ export class BrowserProfilesNew extends LiteElement {
|
||||
`
|
||||
: ""}
|
||||
|
||||
<div class="flex items-center justify-between mb-3 p-2 bg-slate-50">
|
||||
<p class="text-sm text-slate-600 mr-3 p-1">
|
||||
${msg(
|
||||
"Interact with the browsing tool to record your browser profile. You will complete and save your profile in the next step."
|
||||
)}
|
||||
</p>
|
||||
|
||||
<sl-button
|
||||
variant="primary"
|
||||
@click=${() => (this.isDialogVisible = true)}
|
||||
<div class="h-screen flex flex-col">
|
||||
<div
|
||||
class="flex-0 flex items-center justify-between mb-3 p-2 bg-slate-50"
|
||||
>
|
||||
${msg("Next")}
|
||||
</sl-button>
|
||||
</div>
|
||||
<p class="text-sm text-slate-600 mr-3 p-1">
|
||||
${msg(
|
||||
"Interact with the browsing tool to record your browser profile. You will complete and save your profile in the next step."
|
||||
)}
|
||||
</p>
|
||||
|
||||
<btrix-profile-browser
|
||||
.authState=${this.authState}
|
||||
orgId=${this.orgId}
|
||||
browserId=${this.browserId}
|
||||
initialNavigateUrl=${ifDefined(this.params.navigateUrl)}
|
||||
></btrix-profile-browser>
|
||||
<sl-button
|
||||
variant="primary"
|
||||
@click=${() => (this.isDialogVisible = true)}
|
||||
>
|
||||
${msg("Next")}
|
||||
</sl-button>
|
||||
</div>
|
||||
|
||||
<btrix-profile-browser
|
||||
class="flex-1 border rounded-lg overflow-hidden"
|
||||
.authState=${this.authState}
|
||||
orgId=${this.orgId}
|
||||
browserId=${this.browserId}
|
||||
initialNavigateUrl=${ifDefined(this.params.navigateUrl)}
|
||||
></btrix-profile-browser>
|
||||
</div>
|
||||
|
||||
<sl-dialog
|
||||
label=${msg(str`Save Browser Profile`)}
|
||||
@ -196,9 +201,7 @@ export class BrowserProfilesNew extends LiteElement {
|
||||
icon: "check2-circle",
|
||||
});
|
||||
|
||||
this.navTo(
|
||||
`/orgs/${this.orgId}/browser-profiles/profile/${data.id}`
|
||||
);
|
||||
this.navTo(`/orgs/${this.orgId}/browser-profiles/profile/${data.id}`);
|
||||
} catch (e) {
|
||||
this.isSubmitting = false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user