feat: Workflow form collapsible section enhancements (#2381)

Resolves https://github.com/webrecorder/browsertrix/issues/2359

## Changes

- Track when a workflow form section is opened
- Hide workflow form section navigation on small screens

---------

Co-authored-by: Ilya Kreymer <ikreymer@users.noreply.github.com>
Co-authored-by: Emma Segal-Grossman <hi@emma.cafe>
Co-authored-by: Ilya Kreymer <ikreymer@gmail.com>
This commit is contained in:
sua yoo 2025-02-20 18:42:00 -08:00 committed by GitHub
parent 3ca68bf1d2
commit 8db80f5570
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 90 additions and 35 deletions

View File

@ -5,8 +5,6 @@ import { ifDefined } from "lit/directives/if-defined.js";
import { TailwindElement } from "@/classes/TailwindElement";
const DEFAULT_PANEL_ID = "default-panel";
// postcss-lit-disable-next-line
export const TWO_COL_SCREEN_MIN_CSS = css`64.5rem`;
const tabTagName = "btrix-tab-list-tab" as const;
@ -58,12 +56,6 @@ export class TabList extends TailwindElement {
--track-width: 4px;
}
@media only screen and (min-width: ${TWO_COL_SCREEN_MIN_CSS}) {
.navWrapper {
overflow: initial;
}
}
.header {
grid-area: header;
font-size: var(--sl-font-size-large);
@ -94,12 +86,6 @@ export class TabList extends TailwindElement {
margin-left: var(--track-width);
}
@media only screen and (min-width: ${TWO_COL_SCREEN_MIN_CSS}) {
.tablist {
flex-direction: column;
}
}
.track {
display: none;
position: absolute;
@ -118,13 +104,6 @@ export class TabList extends TailwindElement {
border-radius: var(--track-width);
background-color: var(--sl-color-primary-500);
}
@media only screen and (min-width: ${TWO_COL_SCREEN_MIN_CSS}) {
.show-indicator .track,
.show-indicator .indicator {
display: block;
}
}
`;
// ID of active tab
@ -178,7 +157,9 @@ export class TabList extends TailwindElement {
}
render() {
return html`<div class="navWrapper min-w-0">${this.renderNav()}</div>`;
return html`<div class="min-w-0 lg:overflow-hidden">
${this.renderNav()}
</div>`;
}
renderNav() {
@ -193,11 +174,14 @@ export class TabList extends TailwindElement {
? "hide-indicator"
: "show-indicator"} -mx-3 overflow-x-hidden px-3"
>
<div class="track" role="presentation">
<div class="indicator" role="presentation"></div>
<div class="track lg:block" role="presentation">
<div class="indicator lg:block" role="presentation"></div>
</div>
<ul class="tablist -mx-3 overflow-x-auto px-3" role="tablist">
<ul
class="tablist -mx-3 overflow-x-auto px-3 lg:flex-col"
role="tablist"
>
<slot></slot>
</ul>
</div>

View File

@ -59,9 +59,11 @@ import { panel } from "@/layouts/panel";
import infoTextStrings from "@/strings/crawl-workflows/infoText";
import scopeTypeLabels from "@/strings/crawl-workflows/scopeType";
import sectionStrings from "@/strings/crawl-workflows/section";
import { AnalyticsTrackEvent } from "@/trackEvents";
import { ScopeType, type Seed, type WorkflowParams } from "@/types/crawler";
import type { UnderlyingFunction } from "@/types/utils";
import { NewWorkflowOnlyScopeType } from "@/types/workflow";
import { track } from "@/utils/analytics";
import { isApiError } from "@/utils/api";
import { DEPTH_SUPPORTED_SCOPES, isPageScopeType } from "@/utils/crawler";
import {
@ -69,6 +71,7 @@ import {
humanizeNextDate,
humanizeSchedule,
} from "@/utils/cron";
import { makeCurrentTargetHandler, stopProp } from "@/utils/events";
import { formValidator, maxLengthValidator } from "@/utils/form";
import localize from "@/utils/localize";
import { isArchivingDisabled } from "@/utils/orgs";
@ -234,6 +237,7 @@ export class WorkflowEditor extends BtrixElement {
threshold: 0.2, // stricter; default is 0.6
});
private readonly handleCurrentTarget = makeCurrentTargetHandler(this);
private readonly checkFormValidity = formValidator(this);
private readonly validateNameMax = maxLengthValidator(50);
private readonly validateDescriptionMax = maxLengthValidator(350);
@ -405,7 +409,10 @@ export class WorkflowEditor extends BtrixElement {
};
return html`
<btrix-tab-list tab=${ifDefined(this.progressState?.activeTab)}>
<btrix-tab-list
class="hidden lg:block"
tab=${ifDefined(this.progressState?.activeTab)}
>
${STEPS.map(button)}
</btrix-tab-list>
`;
@ -436,13 +443,17 @@ export class WorkflowEditor extends BtrixElement {
activeTab: name,
});
}}
@sl-show=${() => {
@sl-show=${this.handleCurrentTarget(() => {
this.pauseObserve();
this.updateProgressState({
activeTab: name,
});
}}
@sl-hide=${(e: SlHideEvent) => {
track(AnalyticsTrackEvent.ExpandWorkflowFormSection, {
section: name,
});
})}
@sl-hide=${this.handleCurrentTarget((e: SlHideEvent) => {
const el = e.currentTarget as SlDetails;
// Check if there's any invalid elements before hiding
@ -461,12 +472,19 @@ export class WorkflowEditor extends BtrixElement {
invalidEl.focus();
invalidEl.checkValidity();
}
}}
@sl-after-show=${this.resumeObserve}
@sl-after-hide=${this.resumeObserve}
})}
@sl-after-show=${this.handleCurrentTarget(this.resumeObserve)}
@sl-after-hide=${this.handleCurrentTarget(this.resumeObserve)}
>
<div slot="expand-icon" class="flex items-center">
<sl-tooltip content=${msg("Show section")} hoist>
<sl-tooltip
content=${msg("Show section")}
hoist
@sl-show=${stopProp}
@sl-hide=${stopProp}
@sl-after-show=${stopProp}
@sl-after-hide=${stopProp}
>
<sl-icon name="chevron-down" class="size-5"></sl-icon>
</sl-tooltip>
</div>
@ -477,6 +495,10 @@ export class WorkflowEditor extends BtrixElement {
<sl-tooltip
content=${msg("Please fix all errors in this section")}
hoist
@sl-show=${stopProp}
@sl-hide=${stopProp}
@sl-after-show=${stopProp}
@sl-after-hide=${stopProp}
>
<sl-icon
name="exclamation-lg"

View File

@ -3,7 +3,17 @@
*/
export enum AnalyticsTrackEvent {
/**
* Generic
*/
PageView = "pageview",
/**
* Collections
*/
CopyShareCollectionLink = "Copy share collection link",
DownloadPublicCollection = "Download public collection",
/**
* Workflows
*/
ExpandWorkflowFormSection = "Expand workflow form section",
}

View File

@ -8,9 +8,10 @@
import { AnalyticsTrackEvent } from "../trackEvents";
export type AnalyticsTrackProps = {
org_slug: string | null;
collection_slug?: string | null;
org_slug?: string | null;
logged_in?: boolean;
collection_slug?: string;
section?: string;
};
declare global {

View File

@ -0,0 +1,38 @@
/**
* Ignore events bubbling from children. Common use case would be
* ignoring @sl-hide events from tooltips within a dialog.
*
* @example Usage:
* ```
* <btrix-element
* @sl-hide=${makeCurrentTargetHandler(this)(() => console.log("Only current target!"))}
* >
* </btrix-element>
* ```
*/
export function makeCurrentTargetHandler(t: EventTarget) {
const currentTargetHandler: <T extends Event = CustomEvent>(
handler: (event: T) => void,
) => (event: T) => void = (handler) => (e) => {
if (e.target === e.currentTarget) {
handler.bind(t)(e);
}
};
return currentTargetHandler;
}
/**
* Stop propgation shorthand.
*
* @example Usage:
* ```
* <btrix-element
* @sl-show=${stopProp}
* >
* </btrix-element>
* ```
*/
export function stopProp(e: Event) {
e.stopPropagation();
}