add dialog
This commit is contained in:
		
							parent
							
								
									ebb9dc826a
								
							
						
					
					
						commit
						13b6a5b15f
					
				| @ -1,16 +1,19 @@ | |||||||
| import { localized, msg, str } from "@lit/localize"; | import { localized, msg, str } from "@lit/localize"; | ||||||
| import type { SlInput } from "@shoelace-style/shoelace"; | import type { SlInput } from "@shoelace-style/shoelace"; | ||||||
| import { type TemplateResult } from "lit"; | import { html, type TemplateResult } from "lit"; | ||||||
| import { customElement, property } from "lit/decorators.js"; | import { customElement, property, query } from "lit/decorators.js"; | ||||||
| import { when } from "lit/directives/when.js"; | import { when } from "lit/directives/when.js"; | ||||||
| 
 | 
 | ||||||
|  | import { TailwindElement } from "@/classes/TailwindElement"; | ||||||
|  | import type { Dialog } from "@/components/ui/dialog"; | ||||||
|  | import { APIController } from "@/controllers/api"; | ||||||
|  | import { NavigateController } from "@/controllers/navigate"; | ||||||
| import type { CurrentUser, UserOrg } from "@/types/user"; | import type { CurrentUser, UserOrg } from "@/types/user"; | ||||||
| import LiteElement, { html } from "@/utils/LiteElement"; |  | ||||||
| import type { OrgData } from "@/utils/orgs"; | import type { OrgData } from "@/utils/orgs"; | ||||||
| 
 | 
 | ||||||
| @localized() | @localized() | ||||||
| @customElement("btrix-orgs-list") | @customElement("btrix-orgs-list") | ||||||
| export class OrgsList extends LiteElement { | export class OrgsList extends TailwindElement { | ||||||
|   @property({ type: Object }) |   @property({ type: Object }) | ||||||
|   userInfo?: CurrentUser; |   userInfo?: CurrentUser; | ||||||
| 
 | 
 | ||||||
| @ -23,6 +26,15 @@ export class OrgsList extends LiteElement { | |||||||
|   @property({ type: Object }) |   @property({ type: Object }) | ||||||
|   currOrg?: OrgData | null = null; |   currOrg?: OrgData | null = null; | ||||||
| 
 | 
 | ||||||
|  |   @query("#orgDeleteDialog") | ||||||
|  |   orgDeleteDialog?: Dialog | null; | ||||||
|  | 
 | ||||||
|  |   @query("#orgQuotaDialog") | ||||||
|  |   orgQuotaDialog?: Dialog | null; | ||||||
|  | 
 | ||||||
|  |   private readonly api = new APIController(this); | ||||||
|  |   private readonly navigate = new NavigateController(this); | ||||||
|  | 
 | ||||||
|   render() { |   render() { | ||||||
|     if (this.skeleton) { |     if (this.skeleton) { | ||||||
|       return this.renderSkeleton(); |       return this.renderSkeleton(); | ||||||
| @ -33,17 +45,108 @@ export class OrgsList extends LiteElement { | |||||||
|     return html` |     return html` | ||||||
|       <ul class="overflow-hidden rounded-lg border"> |       <ul class="overflow-hidden rounded-lg border"> | ||||||
|         ${this.orgList?.map(this.renderOrg(defaultOrg))} |         ${this.orgList?.map(this.renderOrg(defaultOrg))} | ||||||
|  |         ${this.renderOrgDelete()} | ||||||
|         ${this.renderOrgQuotas()} |         ${this.renderOrgQuotas()} | ||||||
|       </ul> |       </ul> | ||||||
|     `;
 |     `;
 | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   private renderOrgDelete() { | ||||||
|  |     return html` | ||||||
|  |       <btrix-dialog | ||||||
|  |         class="[--width:36rem]" | ||||||
|  |         id="orgDeleteDialog" | ||||||
|  |         .label=${msg(str`Confirm Org Deletion: ${this.currOrg?.name || ""}`)} | ||||||
|  |         @sl-after-hide=${() => (this.currOrg = null)} | ||||||
|  |       > | ||||||
|  |         ${when(this.currOrg, (org) => { | ||||||
|  |           const confirmationStr = msg(str`Delete ${org.name}`); | ||||||
|  |           return html` | ||||||
|  |             <p class="mb-3"> | ||||||
|  |               ${msg( | ||||||
|  |                 html`Are you sure you want to delete
 | ||||||
|  |                   <a | ||||||
|  |                     class="font-semibold text-primary" | ||||||
|  |                     href="/orgs/${org.slug}" | ||||||
|  |                     target="_blank" | ||||||
|  |                   > | ||||||
|  |                     ${org.name} | ||||||
|  |                     <sl-icon | ||||||
|  |                       name="box-arrow-up-right" | ||||||
|  |                       label=${msg("Open in new window")} | ||||||
|  |                     ></sl-icon> </a | ||||||
|  |                   >? This cannot be undone.`,
 | ||||||
|  |               )} | ||||||
|  |             </p> | ||||||
|  |             <ul class="mb-3 text-neutral-600"> | ||||||
|  |               <li>${msg(str`Slug: ${org.slug}`)}</li> | ||||||
|  |               <li> | ||||||
|  |                 ${msg( | ||||||
|  |                   str`Members: ${Object.keys(org.users || {}).length.toLocaleString()}`, | ||||||
|  |                 )} | ||||||
|  |               </li> | ||||||
|  |             </ul> | ||||||
|  |             <p class="mb-3"> | ||||||
|  |               ${msg( | ||||||
|  |                 html`Deleting an org will delete all
 | ||||||
|  |                   <strong class="font-semibold"> | ||||||
|  |                     <sl-format-bytes value=${org.bytesStored}></sl-format-bytes> | ||||||
|  |                   </strong> | ||||||
|  |                   of data associated with the org.`,
 | ||||||
|  |               )} | ||||||
|  |             </p> | ||||||
|  |             <ul class="mb-3 text-neutral-600"> | ||||||
|  |               <li> | ||||||
|  |                 ${msg( | ||||||
|  |                   html`Crawls:
 | ||||||
|  |                     <sl-format-bytes | ||||||
|  |                       value=${org.bytesStoredCrawls} | ||||||
|  |                     ></sl-format-bytes>`, | ||||||
|  |                 )} | ||||||
|  |               </li> | ||||||
|  |               <li> | ||||||
|  |                 ${msg( | ||||||
|  |                   html`Uploads:
 | ||||||
|  |                     <sl-format-bytes | ||||||
|  |                       value=${org.bytesStoredUploads} | ||||||
|  |                     ></sl-format-bytes>`, | ||||||
|  |                 )} | ||||||
|  |               </li> | ||||||
|  |               <li> | ||||||
|  |                 ${msg( | ||||||
|  |                   html`Profiles:
 | ||||||
|  |                     <sl-format-bytes | ||||||
|  |                       value=${org.bytesStoredProfiles} | ||||||
|  |                     ></sl-format-bytes>`, | ||||||
|  |                 )} | ||||||
|  |               </li> | ||||||
|  |             </ul> | ||||||
|  |             <sl-divider></sl-divider> | ||||||
|  |             <sl-input placeholder=${confirmationStr}> | ||||||
|  |               <strong slot="label" class="font-semibold"> | ||||||
|  |                 ${msg(str`Type "${confirmationStr}" to confirm`)} | ||||||
|  |               </strong> | ||||||
|  |             </sl-input> | ||||||
|  |           `;
 | ||||||
|  |         })} | ||||||
|  |         <div slot="footer" class="flex justify-end"> | ||||||
|  |           <sl-button | ||||||
|  |             size="small" | ||||||
|  |             @click="${this.onSubmitQuotas}" | ||||||
|  |             variant="danger" | ||||||
|  |             >${msg("Delete Org")} | ||||||
|  |           </sl-button> | ||||||
|  |         </div> | ||||||
|  |       </btrix-dialog> | ||||||
|  |     `;
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   private renderOrgQuotas() { |   private renderOrgQuotas() { | ||||||
|     return html` |     return html` | ||||||
|       <btrix-dialog |       <btrix-dialog | ||||||
|  |         id="orgQuotaDialog" | ||||||
|         .label=${msg(str`Quotas for: ${this.currOrg?.name || ""}`)} |         .label=${msg(str`Quotas for: ${this.currOrg?.name || ""}`)} | ||||||
|         .open=${!!this.currOrg} |         @sl-after-hide=${() => (this.currOrg = null)} | ||||||
|         @sl-request-close=${() => (this.currOrg = null)} |  | ||||||
|       > |       > | ||||||
|         ${when(this.currOrg?.quotas, (quotas) => |         ${when(this.currOrg?.quotas, (quotas) => | ||||||
|           Object.entries(quotas).map(([key, value]) => { |           Object.entries(quotas).map(([key, value]) => { | ||||||
| @ -72,6 +175,7 @@ export class OrgsList extends LiteElement { | |||||||
|                 label = msg("Unlabeled"); |                 label = msg("Unlabeled"); | ||||||
|             } |             } | ||||||
|             return html` <sl-input
 |             return html` <sl-input
 | ||||||
|  |               class="mb-3 last:mb-0" | ||||||
|               name=${key} |               name=${key} | ||||||
|               label=${label} |               label=${label} | ||||||
|               value=${value} |               value=${value} | ||||||
| @ -110,18 +214,6 @@ export class OrgsList extends LiteElement { | |||||||
|         new CustomEvent("update-quotas", { detail: this.currOrg }), |         new CustomEvent("update-quotas", { detail: this.currOrg }), | ||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|     this.currOrg = null; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   private showQuotas(org: OrgData) { |  | ||||||
|     const stop = (e: Event) => { |  | ||||||
|       e.preventDefault(); |  | ||||||
|       e.stopPropagation(); |  | ||||||
|       this.currOrg = org; |  | ||||||
|       return false; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     return stop; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   private readonly renderOrg = (defaultOrg?: UserOrg) => (org: OrgData) => { |   private readonly renderOrg = (defaultOrg?: UserOrg) => (org: OrgData) => { | ||||||
| @ -158,12 +250,31 @@ export class OrgsList extends LiteElement { | |||||||
|               ? msg(`1 member`) |               ? msg(`1 member`) | ||||||
|               : msg(str`${memberCount} members`)} |               : msg(str`${memberCount} members`)} | ||||||
|           </div> |           </div> | ||||||
|           <sl-icon-button |           <btrix-overflow-dropdown | ||||||
|             name="gear" |             @click=${(e: MouseEvent) => e.stopPropagation()} | ||||||
|             slot="prefix" |           > | ||||||
|             label=${msg("Edit org quotas")} |             <sl-menu> | ||||||
|             @click="${this.showQuotas(org)}" |               <sl-menu-item | ||||||
|           ></sl-icon-button> |                 @click=${() => { | ||||||
|  |                   this.currOrg = org; | ||||||
|  |                   void this.orgQuotaDialog?.show(); | ||||||
|  |                 }} | ||||||
|  |               > | ||||||
|  |                 <sl-icon slot="prefix" name="gear"></sl-icon> | ||||||
|  |                 ${msg("Edit Quotas")} | ||||||
|  |               </sl-menu-item> | ||||||
|  |               <sl-menu-item | ||||||
|  |                 style="--sl-color-neutral-700: var(--danger)" | ||||||
|  |                 @click=${() => { | ||||||
|  |                   this.currOrg = org; | ||||||
|  |                   void this.orgDeleteDialog?.show(); | ||||||
|  |                 }} | ||||||
|  |               > | ||||||
|  |                 <sl-icon slot="prefix" name="trash3"></sl-icon> | ||||||
|  |                 ${msg("Delete Org")} | ||||||
|  |               </sl-menu-item> | ||||||
|  |             </sl-menu> | ||||||
|  |           </btrix-overflow-dropdown> | ||||||
|         </div> |         </div> | ||||||
|       </li> |       </li> | ||||||
|     `;
 |     `;
 | ||||||
| @ -180,7 +291,7 @@ export class OrgsList extends LiteElement { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   private makeOnOrgClick(org: OrgData) { |   private makeOnOrgClick(org: OrgData) { | ||||||
|     const navigate = () => this.navTo(`/orgs/${org.slug}`); |     const navigate = () => this.navigate.to(`/orgs/${org.slug}`); | ||||||
| 
 | 
 | ||||||
|     if (typeof window.getSelection !== "undefined") { |     if (typeof window.getSelection !== "undefined") { | ||||||
|       return () => { |       return () => { | ||||||
|  | |||||||
| @ -19,6 +19,9 @@ export type OrgData = { | |||||||
|   slug: string; |   slug: string; | ||||||
|   quotas?: Record<string, number>; |   quotas?: Record<string, number>; | ||||||
|   bytesStored: number; |   bytesStored: number; | ||||||
|  |   bytesStoredCrawls: number; | ||||||
|  |   bytesStoredUploads: number; | ||||||
|  |   bytesStoredProfiles: number; | ||||||
|   usage: { [key: YearMonth]: number } | null; |   usage: { [key: YearMonth]: number } | null; | ||||||
|   crawlExecSeconds?: { [key: YearMonth]: number }; |   crawlExecSeconds?: { [key: YearMonth]: number }; | ||||||
|   monthlyExecSeconds?: { [key: YearMonth]: number }; |   monthlyExecSeconds?: { [key: YearMonth]: number }; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user