diff --git a/frontend/src/components/dialog.ts b/frontend/src/components/dialog.ts new file mode 100644 index 00000000..03b4ad1d --- /dev/null +++ b/frontend/src/components/dialog.ts @@ -0,0 +1,38 @@ +import { css } from "lit"; +import SLDialog from "@shoelace-style/shoelace/dist/components/dialog/dialog.js"; +import dialogStyles from "@shoelace-style/shoelace/dist/components/dialog/dialog.styles.js"; + +/** + * Customized + * + * Usage: see https://shoelace.style/components/dialog + */ +export class Dialog extends SLDialog { + static styles = css` + ${dialogStyles} .dialog__panel { + overflow: hidden; + } + + .dialog__header { + background-color: var(--sl-color-neutral-50); + border-bottom: 1px solid var(--sl-color-neutral-100); + } + + .dialog__title { + padding-top: var(--sl-spacing-small); + padding-bottom: var(--sl-spacing-small); + font-size: var(--sl-font-size-medium); + font-weight: var(--sl-font-weight-medium); + } + + .dialog__close { + --header-spacing: var(--sl-spacing-2x-small); + } + + .dialog__footer { + padding-top: var(--sl-spacing-small); + padding-bottom: var(--sl-spacing-small); + border-top: 1px solid var(--sl-color-neutral-100); + } + `; +} diff --git a/frontend/src/components/index.ts b/frontend/src/components/index.ts index 9ceab8d3..9be28e66 100644 --- a/frontend/src/components/index.ts +++ b/frontend/src/components/index.ts @@ -10,9 +10,6 @@ import("./locale-picker").then(({ LocalePicker }) => { import("./account-settings").then(({ AccountSettings }) => { customElements.define("btrix-account-settings", AccountSettings); }); -import("./org-invite-form").then(({ OrgInviteForm }) => { - customElements.define("btrix-org-invite-form", OrgInviteForm); -}); import("./config-editor").then(({ ConfigEditor }) => { customElements.define("btrix-config-editor", ConfigEditor); }); @@ -101,6 +98,9 @@ import("./tag-input").then(({ TagInput }) => { import("./tag").then(({ Tag }) => { customElements.define("btrix-tag", Tag); }); +import("./dialog").then(({ Dialog }) => { + customElements.define("btrix-dialog", Dialog); +}); customElements.define("btrix-alert", Alert); customElements.define("btrix-input", Input); diff --git a/frontend/src/components/org-invite-form.ts b/frontend/src/components/org-invite-form.ts deleted file mode 100644 index ab2595c6..00000000 --- a/frontend/src/components/org-invite-form.ts +++ /dev/null @@ -1,132 +0,0 @@ -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 { AccessCode } from "../utils/orgs"; - -@localized() -export class OrgInviteForm extends LiteElement { - @property({ type: String }) - orgId?: string; - - @property({ type: Object }) - authState?: AuthState; - - @state() - private isSubmitting: boolean = false; - - @state() - private serverError?: string; - - render() { - let formError; - - if (this.serverError) { - formError = html` -
- ${this.serverError} -
- `; - } - - return html` -
-
- - -
-
- - - ${msg("Admin")} - ${msg("Can manage crawls and invite others")} - - - ${msg("Crawler")} - ${msg("Can manage crawls")} - - - ${msg("Viewer")} - ${msg("Can view crawls")} - - -
- - ${formError} - -
- ${msg("Invite")} - this.dispatchEvent(new CustomEvent("cancel"))} - >${msg("Cancel")} -
-
- `; - } - - async onSubmit(event: SubmitEvent) { - event.preventDefault(); - if (!this.authState) return; - - this.isSubmitting = true; - - const formData = new FormData(event.target as HTMLFormElement); - const inviteEmail = formData.get("inviteEmail") as string; - - try { - const data = await this.apiFetch( - `/orgs/${this.orgId}/invite`, - this.authState, - { - method: "POST", - body: JSON.stringify({ - email: inviteEmail, - role: Number(formData.get("role")), - }), - } - ); - - this.dispatchEvent( - new CustomEvent("success", { - detail: { - inviteEmail, - isExistingUser: data.invited === "existing_user", - }, - }) - ); - } catch (e: any) { - if (e?.isApiError) { - this.serverError = e?.message; - } else { - this.serverError = msg("Something unexpected went wrong"); - } - } - - this.isSubmitting = false; - } -} diff --git a/frontend/src/components/tab-list.ts b/frontend/src/components/tab-list.ts index 0ba01d28..e6574cd3 100644 --- a/frontend/src/components/tab-list.ts +++ b/frontend/src/components/tab-list.ts @@ -168,15 +168,19 @@ export class TabList extends LitElement { top: var(--sl-spacing-medium); } - ul { + .tablist { display: flex; - margin: 0 0 0 var(--track-width); + margin: 0; list-style: none; padding: 0; } + .show-indicator .tablist { + margin-left: var(--track-width); + } + @media only screen and (min-width: ${SCREEN_LG}px) { - ul { + .tablist { display: block; } } @@ -201,9 +205,9 @@ export class TabList extends LitElement { } @media only screen and (min-width: ${SCREEN_LG}px) { - ul, - .track, - .indicator { + .tablist, + .show-indicator .track, + .show-indicator .indicator { display: block; } } @@ -217,6 +221,9 @@ export class TabList extends LitElement { @property({ type: String }) progressPanel?: string; + @property({ type: Boolean }) + hideIndicator = false; + @queryAsync(".track") private trackElem!: HTMLElement; @@ -233,7 +240,7 @@ export class TabList extends LitElement { } private async repositionIndicator(activeTab?: TabElement, animate = true) { - if (!activeTab) return; + if (!activeTab || this.hideIndicator) return; const trackElem = await this.trackElem; const indicatorElem = await this.indicatorElem; @@ -274,12 +281,17 @@ export class TabList extends LitElement { @sl-resize=${() => this.repositionIndicator(this.getTab(this.progressPanel))} > -