import { state, property } from "lit/decorators.js"; import { ifDefined } from "lit/directives/if-defined.js"; import { msg, localized, str } from "@lit/localize"; import { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js"; import type { AuthState } from "../utils/AuthService"; import type { CurrentUser } from "../types/user"; import type { OrgData } from "../utils/orgs"; import LiteElement, { html } from "../utils/LiteElement"; @localized() export class Home extends LiteElement { @property({ type: Object }) authState?: AuthState; @property({ type: Object }) userInfo?: CurrentUser; @property({ type: String }) orgId?: string; @state() private isInviteComplete?: boolean; @state() private orgList?: OrgData[]; @state() private isAddingOrg = false; @state() private isAddOrgFormVisible = false; @state() private isSubmittingNewOrg = false; connectedCallback() { if (this.authState) { super.connectedCallback(); if (this.userInfo && !this.orgId) { this.fetchOrgs(); } } else { this.navTo("/log-in"); } } willUpdate(changedProperties: Map) { if (changedProperties.has("orgId") && this.orgId) { this.navTo(`/orgs/${this.orgId}/crawls`); } else if (changedProperties.has("authState") && this.authState) { this.fetchOrgs(); } } render() { if (!this.userInfo || !this.orgList) { return html`
`; } let title: any; let content: any; if (this.userInfo.isAdmin === true) { title = msg("Welcome"); content = this.renderLoggedInAdmin(); } if (this.userInfo.isAdmin === false) { title = msg("Organizations"); content = this.renderLoggedInNonAdmin(); } return html`

${title}


${content}
`; } private renderLoggedInAdmin() { if (this.orgList!.length) { return this.renderAdminOrgs(); } return html`

${msg("Invite users to start archiving.")}

${this.renderInvite()}
`; } private renderAdminOrgs() { return html`
{ const formData = new FormData(e.target as HTMLFormElement); const id = formData.get("crawlId"); this.navTo(`/crawls/crawl/${id}`); }} >
${msg("Go to Crawl")}
${msg("Go")}

${msg("All Organizations")}

(this.isAddingOrg = true)} > ${msg("New Organization")}
org.default === true) )} >

${msg("Invite User to Org")}

${this.renderInvite()}
(this.isAddingOrg = false)} @sl-show=${() => (this.isAddOrgFormVisible = true)} @sl-after-hide=${() => (this.isAddOrgFormVisible = false)} > ${this.isAddOrgFormVisible ? html`
(this.isAddingOrg = false)} @submit=${this.onSubmitNewOrg} >
${msg("Cancel")} ${msg("Create Org")}
` : ""}
`; } private renderLoggedInNonAdmin() { if (this.orgList && !this.orgList.length) { return html`

${msg("You don't have any organizations.")}

`; } return html` `; } private renderInvite() { if (this.isInviteComplete) { return html` (this.isInviteComplete = false)} >${msg("Send another invite")} `; } const defaultOrg = this.userInfo?.orgs.find( (org) => org.default === true ) || { name: "" }; return html` (this.isInviteComplete = true)} > `; } private async fetchOrgs() { this.orgList = await this.getOrgs(); } private async getOrgs(): Promise { const data = await this.apiFetch("/orgs", this.authState!); return data.orgs; } private async onSubmitNewOrg(e: SubmitEvent) { e.preventDefault(); const formEl = e.target as HTMLFormElement; if (!(await this.checkFormValidity(formEl))) return; const params = serialize(formEl); this.isSubmittingNewOrg = true; try { await this.apiFetch(`/orgs/create`, this.authState!, { method: "POST", body: JSON.stringify(params), }); this.fetchOrgs(); this.notify({ message: msg(str`Created new org named "${params.name}".`), variant: "success", icon: "check2-circle", duration: 8000, }); this.isAddingOrg = false; } catch (e: any) { this.notify({ message: e.isApiError ? e.message : msg("Sorry, couldn't create organization at this time."), variant: "danger", icon: "exclamation-octagon", }); } this.isSubmittingNewOrg = false; } async checkFormValidity(formEl: HTMLFormElement) { await this.updateComplete; return !formEl.querySelector("[data-invalid]"); } }