refactor org list
This commit is contained in:
parent
2664fd0f0e
commit
35469915a8
@ -1,6 +1,6 @@
|
|||||||
import { localized, msg, str } from "@lit/localize";
|
import { localized, msg, str } from "@lit/localize";
|
||||||
import type { SlChangeEvent, SlInput } from "@shoelace-style/shoelace";
|
import type { SlChangeEvent, SlInput } from "@shoelace-style/shoelace";
|
||||||
import { html, type TemplateResult } from "lit";
|
import { css, html, nothing } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators.js";
|
import { customElement, property, query, state } from "lit/decorators.js";
|
||||||
import { when } from "lit/directives/when.js";
|
import { when } from "lit/directives/when.js";
|
||||||
|
|
||||||
@ -8,12 +8,18 @@ import { TailwindElement } from "@/classes/TailwindElement";
|
|||||||
import type { Dialog } from "@/components/ui/dialog";
|
import type { Dialog } from "@/components/ui/dialog";
|
||||||
import { APIController } from "@/controllers/api";
|
import { APIController } from "@/controllers/api";
|
||||||
import { NavigateController } from "@/controllers/navigate";
|
import { NavigateController } from "@/controllers/navigate";
|
||||||
import type { CurrentUser, UserOrg } from "@/types/user";
|
import type { CurrentUser } from "@/types/user";
|
||||||
|
import { formatNumber } from "@/utils/localization";
|
||||||
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 TailwindElement {
|
export class OrgsList extends TailwindElement {
|
||||||
|
static styles = css`
|
||||||
|
btrix-table {
|
||||||
|
grid-template-columns: [clickable-start] auto auto [clickable-end] min-content;
|
||||||
|
}
|
||||||
|
`;
|
||||||
@property({ type: Object })
|
@property({ type: Object })
|
||||||
userInfo?: CurrentUser;
|
userInfo?: CurrentUser;
|
||||||
|
|
||||||
@ -43,14 +49,20 @@ export class OrgsList extends TailwindElement {
|
|||||||
return this.renderSkeleton();
|
return this.renderSkeleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultOrg = this.userInfo?.orgs.find((org) => org.default === true);
|
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ul class="overflow-hidden rounded-lg border">
|
<btrix-table>
|
||||||
${this.orgList?.map(this.renderOrg(defaultOrg))}
|
<btrix-table-head class="mb-2">
|
||||||
${this.renderOrgDelete()}
|
<btrix-table-header-cell>${msg("Name")}</btrix-table-header-cell>
|
||||||
${this.renderOrgQuotas()}
|
<btrix-table-header-cell>${msg("Members")}</btrix-table-header-cell>
|
||||||
</ul>
|
<btrix-table-header-cell>
|
||||||
|
<span class="sr-only">${msg("Actions")}</span>
|
||||||
|
</btrix-table-header-cell>
|
||||||
|
</btrix-table-head>
|
||||||
|
<btrix-table-body class="rounded border">
|
||||||
|
${this.orgList?.map(this.renderOrg)}
|
||||||
|
</btrix-table-body>
|
||||||
|
</btrix-table>
|
||||||
|
${this.renderOrgDelete()} ${this.renderOrgQuotas()}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,40 +241,31 @@ export class OrgsList extends TailwindElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly renderOrg = (defaultOrg?: UserOrg) => (org: OrgData) => {
|
private readonly renderOrg = (org: OrgData) => {
|
||||||
if (!this.userInfo) return;
|
if (!this.userInfo) return;
|
||||||
|
|
||||||
// There shouldn't really be a case where an org is in the org list but
|
// // There shouldn't really be a case where an org is in the org list but
|
||||||
// not in user info, but disable clicking into the org just in case
|
// // not in user info, but disable clicking into the org just in case
|
||||||
const isUserOrg = this.userInfo.orgs.some(({ id }) => id === org.id);
|
// const isUserOrg = this.userInfo.orgs.some(({ id }) => id === org.id);
|
||||||
|
|
||||||
let defaultLabel: TemplateResult | undefined;
|
|
||||||
|
|
||||||
if (defaultOrg && org.id === defaultOrg.id) {
|
|
||||||
defaultLabel = html`<sl-tag size="small" variant="primary" class="mr-2"
|
|
||||||
>${msg("Default")}</sl-tag
|
|
||||||
>`;
|
|
||||||
}
|
|
||||||
const memberCount = Object.keys(org.users || {}).length;
|
const memberCount = Object.keys(org.users || {}).length;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<li
|
<btrix-table-row
|
||||||
class="${isUserOrg
|
class="cursor-pointer select-none border-b bg-neutral-0 transition-colors first-of-type:rounded-t last-of-type:rounded-b last-of-type:border-none focus-within:bg-neutral-50 hover:bg-neutral-50"
|
||||||
? ""
|
|
||||||
: "select-none cursor-not-allowed opacity-50"} flex items-center justify-between border-t bg-white p-3 text-primary first:border-t-0 hover:text-indigo-400"
|
|
||||||
role="button"
|
|
||||||
@click=${this.makeOnOrgClick(org)}
|
|
||||||
aria-disabled="${isUserOrg}"
|
|
||||||
>
|
>
|
||||||
<div class="mr-2 font-medium transition-colors">
|
<btrix-table-cell class="p-2" rowClickTarget="a">
|
||||||
${defaultLabel}${org.name}
|
<a href="/orgs/${org.slug}" @click=${this.navigate.link}>
|
||||||
</div>
|
${org.default
|
||||||
<div class="flex flex-row items-center">
|
? html`<btrix-tag class="mr-1">${msg("Default")}</btrix-tag>`
|
||||||
<div class="text-s font-monostyle mr-4 text-neutral-400">
|
: nothing}
|
||||||
${memberCount === 1
|
${org.name}
|
||||||
? msg(`1 member`)
|
</a>
|
||||||
: msg(str`${memberCount} members`)}
|
</btrix-table-cell>
|
||||||
</div>
|
<btrix-table-cell class="p-2">
|
||||||
|
${formatNumber(memberCount)}
|
||||||
|
</btrix-table-cell>
|
||||||
|
<btrix-table-cell class="p-1">
|
||||||
<btrix-overflow-dropdown
|
<btrix-overflow-dropdown
|
||||||
@click=${(e: MouseEvent) => e.stopPropagation()}
|
@click=${(e: MouseEvent) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
@ -288,8 +291,8 @@ export class OrgsList extends TailwindElement {
|
|||||||
</sl-menu-item>
|
</sl-menu-item>
|
||||||
</sl-menu>
|
</sl-menu>
|
||||||
</btrix-overflow-dropdown>
|
</btrix-overflow-dropdown>
|
||||||
</div>
|
</btrix-table-cell>
|
||||||
</li>
|
</btrix-table-row>
|
||||||
`;
|
`;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -302,21 +305,4 @@ export class OrgsList extends TailwindElement {
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private makeOnOrgClick(org: OrgData) {
|
|
||||||
const navigate = () => this.navigate.to(`/orgs/${org.slug}`);
|
|
||||||
|
|
||||||
if (typeof window.getSelection !== "undefined") {
|
|
||||||
return () => {
|
|
||||||
// Prevent navigation on user text selection
|
|
||||||
if (window.getSelection()?.type === "Range") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
navigate();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return navigate;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ export type OrgData = {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
slug: string;
|
slug: string;
|
||||||
|
default: boolean;
|
||||||
quotas?: Record<string, number>;
|
quotas?: Record<string, number>;
|
||||||
bytesStored: number;
|
bytesStored: number;
|
||||||
bytesStoredCrawls: number;
|
bytesStoredCrawls: number;
|
||||||
|
Loading…
Reference in New Issue
Block a user