Allow admin users to change org name (#506)
This commit is contained in:
parent
0486d50fe9
commit
7dc85cc33c
@ -583,6 +583,7 @@ export class App extends LiteElement {
|
||||
class="w-full"
|
||||
@navigate=${this.onNavigateTo}
|
||||
@need-login=${this.onNeedLogin}
|
||||
@update-user-info=${this.updateUserInfo}
|
||||
@notify="${this.onNotify}"
|
||||
.authState=${this.authService.authState}
|
||||
.userInfo=${this.userInfo}
|
||||
@ -681,7 +682,10 @@ export class App extends LiteElement {
|
||||
tabName: "browser-profiles",
|
||||
label: msg("Browser Profiles"),
|
||||
})}
|
||||
${this.renderNavTab({ tabName: "members", label: msg("Members") })}
|
||||
${this.renderNavTab({
|
||||
tabName: "settings",
|
||||
label: msg("Org Settings"),
|
||||
})}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { state, property } from "lit/decorators.js";
|
||||
import { msg, localized, str } from "@lit/localize";
|
||||
import { when } from "lit/directives/when.js";
|
||||
import { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js";
|
||||
|
||||
import type { ViewState } from "../../utils/APIRouter";
|
||||
import type { AuthState } from "../../utils/AuthService";
|
||||
@ -16,12 +18,13 @@ import "./crawls-list";
|
||||
import "./browser-profiles-detail";
|
||||
import "./browser-profiles-list";
|
||||
import "./browser-profiles-new";
|
||||
import { SlButton } from "@shoelace-style/shoelace";
|
||||
|
||||
export type OrgTab =
|
||||
| "crawls"
|
||||
| "crawl-configs"
|
||||
| "browser-profiles"
|
||||
| "members";
|
||||
| "settings";
|
||||
|
||||
const defaultTab = "crawls";
|
||||
|
||||
@ -71,6 +74,12 @@ export class Org extends LiteElement {
|
||||
@state()
|
||||
private successfullyInvitedEmail?: string;
|
||||
|
||||
@state()
|
||||
private isEditingOrgName = false;
|
||||
|
||||
@state()
|
||||
private isSavingOrgName = false;
|
||||
|
||||
async willUpdate(changedProperties: Map<string, any>) {
|
||||
if (changedProperties.has("orgId") && this.orgId) {
|
||||
try {
|
||||
@ -125,11 +134,11 @@ export class Org extends LiteElement {
|
||||
case "browser-profiles":
|
||||
tabPanelContent = this.renderBrowserProfiles();
|
||||
break;
|
||||
case "members":
|
||||
case "settings":
|
||||
if (this.isAddingMember) {
|
||||
tabPanelContent = this.renderAddMember();
|
||||
} else {
|
||||
tabPanelContent = this.renderMembers();
|
||||
tabPanelContent = this.renderOrgSettings();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -225,6 +234,74 @@ export class Org extends LiteElement {
|
||||
></btrix-browser-profiles-list>`;
|
||||
}
|
||||
|
||||
private renderOrgSettings() {
|
||||
return html`<btrix-section-heading
|
||||
>${msg("Org Information")}</btrix-section-heading
|
||||
>
|
||||
<section class="mt-5 mb-10">${this.renderOrgName()}</section>
|
||||
<btrix-section-heading>${msg("Org Members")}</btrix-section-heading>
|
||||
<section class="mt-5">${this.renderMembers()}</section>`;
|
||||
}
|
||||
|
||||
private renderOrgName() {
|
||||
if (!this.org || !this.userInfo) return;
|
||||
const memberInfo = (this.org.users ?? {})[this.userInfo.id];
|
||||
if (!memberInfo || !isOwner(memberInfo.role)) {
|
||||
return html`
|
||||
<sl-input
|
||||
label=${msg("Org Name")}
|
||||
value=${this.org.name}
|
||||
readonly
|
||||
></sl-input>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`<form
|
||||
@submit=${this.onOrgNameSubmit}
|
||||
@reset=${() => (this.isEditingOrgName = false)}
|
||||
>
|
||||
<div class="flex items-end">
|
||||
<div class="flex-1 mr-3">
|
||||
<sl-input
|
||||
name="orgName"
|
||||
label=${msg("Org Name")}
|
||||
autocomplete="off"
|
||||
value=${this.org.name}
|
||||
?readonly=${!this.isEditingOrgName}
|
||||
?required=${this.isEditingOrgName}
|
||||
></sl-input>
|
||||
</div>
|
||||
<div class="flex-0">
|
||||
${when(
|
||||
this.isEditingOrgName,
|
||||
() => html`
|
||||
<sl-button type="reset" class="mr-1">${msg("Cancel")}</sl-button>
|
||||
<sl-button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
?disabled=${this.isSavingOrgName}
|
||||
?loading=${this.isSavingOrgName}
|
||||
>${msg("Save Changes")}</sl-button
|
||||
>
|
||||
`,
|
||||
() => html`
|
||||
<sl-button
|
||||
@click=${(e: MouseEvent) => {
|
||||
this.isEditingOrgName = true;
|
||||
(e.target as SlButton)
|
||||
.closest("form")
|
||||
?.querySelector("sl-input")
|
||||
?.focus();
|
||||
}}
|
||||
>${msg("Edit")}</sl-button
|
||||
>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</form>`;
|
||||
}
|
||||
|
||||
private renderMembers() {
|
||||
if (!this.org!.users) return;
|
||||
|
||||
@ -245,8 +322,7 @@ export class Org extends LiteElement {
|
||||
|
||||
<div class="text-right">
|
||||
<sl-button
|
||||
href=${`/orgs/${this.orgId}/members/add-member`}
|
||||
variant="primary"
|
||||
href=${`/orgs/${this.orgId}/settings/add-member`}
|
||||
@click=${this.navLink}
|
||||
>${msg("Add Member")}</sl-button
|
||||
>
|
||||
@ -298,7 +374,7 @@ export class Org extends LiteElement {
|
||||
class="inline-block align-middle"
|
||||
></sl-icon>
|
||||
<span class="inline-block align-middle"
|
||||
>${msg("Back to Members")}</span
|
||||
>${msg("Back to Settings")}</span
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
@ -321,6 +397,45 @@ export class Org extends LiteElement {
|
||||
return data;
|
||||
}
|
||||
|
||||
private async onOrgNameSubmit(e: SubmitEvent) {
|
||||
e.preventDefault();
|
||||
if (!this.org) return;
|
||||
const { orgName } = serialize(e.target as HTMLFormElement);
|
||||
|
||||
this.isSavingOrgName = true;
|
||||
|
||||
try {
|
||||
await this.apiFetch(`/orgs/${this.org.id}/rename`, this.authState!, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ name: orgName }),
|
||||
});
|
||||
|
||||
this.notify({
|
||||
message: msg("Updated organization name."),
|
||||
variant: "success",
|
||||
icon: "check2-circle",
|
||||
duration: 8000,
|
||||
});
|
||||
|
||||
this.org = {
|
||||
...this.org,
|
||||
name: orgName as string,
|
||||
};
|
||||
|
||||
this.isEditingOrgName = false;
|
||||
this.dispatchEvent(new CustomEvent("update-user-info"));
|
||||
} catch (e) {
|
||||
console.debug(e);
|
||||
this.notify({
|
||||
message: msg("Sorry, couldn't update organization name at this time."),
|
||||
variant: "danger",
|
||||
icon: "exclamation-octagon",
|
||||
});
|
||||
}
|
||||
|
||||
this.isSavingOrgName = false;
|
||||
}
|
||||
|
||||
onInviteSuccess(
|
||||
event: CustomEvent<{ inviteEmail: string; isExistingUser: boolean }>
|
||||
) {
|
||||
|
Loading…
Reference in New Issue
Block a user