Add detailed permissions & permission summaries to user invite popup (#2003)
This commit is contained in:
parent
570dc10f2a
commit
10640feeef
@ -1,4 +1,6 @@
|
|||||||
const plugin = require("tailwindcss/plugin");
|
const plugin = require("tailwindcss/plugin");
|
||||||
module.exports = plugin(function ({ matchVariant }) {
|
module.exports = plugin(function ({ matchVariant }) {
|
||||||
matchVariant("attr", (value) => `&[${value}]`);
|
matchVariant("attr", (value) => `&[${value}]`);
|
||||||
|
matchVariant("group-attr", (value) => `:merge(.group)[${value}] &`);
|
||||||
|
matchVariant("peer-attr", (value) => `:merge(.peer)[${value}] ~ &`);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
/** @type {import('postcss-load-config').Config} */
|
/** @type {import('postcss-load-config').Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: [require("tailwindcss"), require("autoprefixer")],
|
plugins: {
|
||||||
|
"tailwindcss/nesting": {},
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
41
frontend/src/pages/org/settings/settings.stylesheet.css
Normal file
41
frontend/src/pages/org/settings/settings.stylesheet.css
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer components {
|
||||||
|
sl-radio.radio-card {
|
||||||
|
@apply cursor-pointer rounded-md border border-neutral-300 p-2 transition-colors;
|
||||||
|
&:hover {
|
||||||
|
@apply border-neutral-400;
|
||||||
|
}
|
||||||
|
&[aria-checked="true"] {
|
||||||
|
@apply border-primary bg-primary-50;
|
||||||
|
}
|
||||||
|
&::part(base) {
|
||||||
|
@apply grid grid-cols-[auto_minmax(0,1fr)] gap-x-1;
|
||||||
|
}
|
||||||
|
&::part(control) {
|
||||||
|
@apply col-start-1 col-end-2 row-start-1 row-end-2;
|
||||||
|
}
|
||||||
|
&::part(label) {
|
||||||
|
@apply col-start-1 col-end-3 row-start-1 row-end-3 ml-0 grid flex-auto grid-cols-subgrid gap-y-2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sl-details.details-card {
|
||||||
|
@apply col-span-2;
|
||||||
|
&::part(header) {
|
||||||
|
@apply p-2;
|
||||||
|
}
|
||||||
|
&::part(content) {
|
||||||
|
@apply p-2 pt-0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sl-radio.radio-card[aria-checked="true"] sl-details.details-card {
|
||||||
|
&::part(base) {
|
||||||
|
@apply border-primary/50;
|
||||||
|
}
|
||||||
|
&::part(summary-icon) {
|
||||||
|
@apply text-primary-700;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,12 +1,13 @@
|
|||||||
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 { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js";
|
import { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js";
|
||||||
import { html, type PropertyValues } from "lit";
|
import { html, unsafeCSS, type PropertyValues } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators.js";
|
import { customElement, property, state } from "lit/decorators.js";
|
||||||
import { choose } from "lit/directives/choose.js";
|
import { choose } from "lit/directives/choose.js";
|
||||||
import { ifDefined } from "lit/directives/if-defined.js";
|
import { ifDefined } from "lit/directives/if-defined.js";
|
||||||
import { when } from "lit/directives/when.js";
|
import { when } from "lit/directives/when.js";
|
||||||
|
|
||||||
|
import stylesheet from "./settings.stylesheet.css";
|
||||||
import { columns } from "./ui/columns";
|
import { columns } from "./ui/columns";
|
||||||
|
|
||||||
import { BtrixElement } from "@/classes/BtrixElement";
|
import { BtrixElement } from "@/classes/BtrixElement";
|
||||||
@ -21,6 +22,8 @@ import { formatAPIUser } from "@/utils/user";
|
|||||||
|
|
||||||
import "./components/billing";
|
import "./components/billing";
|
||||||
|
|
||||||
|
const styles = unsafeCSS(stylesheet);
|
||||||
|
|
||||||
type Tab = "information" | "members" | "billing";
|
type Tab = "information" | "members" | "billing";
|
||||||
type User = {
|
type User = {
|
||||||
email: string;
|
email: string;
|
||||||
@ -56,6 +59,8 @@ export type OrgRemoveMemberEvent = CustomEvent<{
|
|||||||
@localized()
|
@localized()
|
||||||
@customElement("btrix-org-settings")
|
@customElement("btrix-org-settings")
|
||||||
export class OrgSettings extends BtrixElement {
|
export class OrgSettings extends BtrixElement {
|
||||||
|
static styles = styles;
|
||||||
|
|
||||||
@property({ type: String })
|
@property({ type: String })
|
||||||
activePanel: Tab = "information";
|
activePanel: Tab = "information";
|
||||||
|
|
||||||
@ -422,19 +427,92 @@ export class OrgSettings extends BtrixElement {
|
|||||||
</sl-input>
|
</sl-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-5">
|
<div class="mb-5">
|
||||||
<sl-radio-group
|
<sl-radio-group name="role" label="Role" value=${AccessCode.viewer}>
|
||||||
name="role"
|
<sl-radio value=${AccessCode.viewer} class="radio-card">
|
||||||
label="Permission"
|
<div
|
||||||
value=${AccessCode.viewer}
|
class="col-start-2 flex items-baseline justify-between gap-2"
|
||||||
>
|
>
|
||||||
<sl-radio value=${AccessCode.owner}>
|
${msg("Viewer")}
|
||||||
${msg("Admin — Can create crawls and manage org members")}
|
<span class="text-xs text-gray-500">
|
||||||
|
${msg("View archived items and collections")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<sl-details
|
||||||
|
@sl-hide=${this.stopProp}
|
||||||
|
@sl-after-hide=${this.stopProp}
|
||||||
|
class="details-card text-xs"
|
||||||
|
>
|
||||||
|
<span slot="summary">Permissions</span>
|
||||||
|
<ul class="ms-4 list-disc text-gray-500">
|
||||||
|
<li>${msg("View crawl workflows")}</li>
|
||||||
|
<li>${msg("View, replay, and download archived items")}</li>
|
||||||
|
<li>${msg("View collections")}</li>
|
||||||
|
</ul>
|
||||||
|
</sl-details>
|
||||||
</sl-radio>
|
</sl-radio>
|
||||||
<sl-radio value=${AccessCode.crawler}>
|
|
||||||
${msg("Crawler — Can create crawls")}
|
<sl-radio value=${AccessCode.crawler} class="radio-card">
|
||||||
|
<div
|
||||||
|
class="col-start-2 flex items-baseline justify-between gap-2"
|
||||||
|
>
|
||||||
|
${msg("Crawler")}
|
||||||
|
<span class="text-xs text-gray-500">
|
||||||
|
${msg("Create, evaluate, and curate archived items")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<sl-details
|
||||||
|
@sl-hide=${this.stopProp}
|
||||||
|
@sl-after-hide=${this.stopProp}
|
||||||
|
class="details-card text-xs"
|
||||||
|
>
|
||||||
|
<span slot="summary">Permissions</span>
|
||||||
|
<p class="mb-1 text-gray-500">
|
||||||
|
${msg("All Viewer permissions, plus:")}
|
||||||
|
</p>
|
||||||
|
<ul class="ms-4 list-disc text-gray-500">
|
||||||
|
<li>${msg("Create crawl workflows")}</li>
|
||||||
|
<li>${msg("Create browser profiles")}</li>
|
||||||
|
<li>${msg("Upload archived items")}</li>
|
||||||
|
<li>${msg("Run QA analysis")}</li>
|
||||||
|
<li>${msg("Rate and review archived items")}</li>
|
||||||
|
<li>${msg("Create, edit, and share collections")}</li>
|
||||||
|
</ul>
|
||||||
|
</sl-details>
|
||||||
</sl-radio>
|
</sl-radio>
|
||||||
<sl-radio value=${AccessCode.viewer}>
|
|
||||||
${msg("Viewer — Can view crawls")}
|
<sl-radio value=${AccessCode.owner} class="radio-card">
|
||||||
|
<div
|
||||||
|
class="col-start-2 flex items-baseline justify-between gap-2"
|
||||||
|
>
|
||||||
|
${msg("Admin")}
|
||||||
|
<span class="text-xs text-gray-500">
|
||||||
|
${this.appState.settings?.billingEnabled
|
||||||
|
? msg("Manage org and billing settings")
|
||||||
|
: msg("Manage org")}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<sl-details
|
||||||
|
@sl-hide=${this.stopProp}
|
||||||
|
@sl-after-hide=${this.stopProp}
|
||||||
|
class="details-card text-xs"
|
||||||
|
>
|
||||||
|
<span slot="summary">${msg("Permissions")}</span>
|
||||||
|
<p class="mb-1 text-gray-500">
|
||||||
|
${msg("All Crawler permissions, plus:")}
|
||||||
|
</p>
|
||||||
|
<ul class="ms-4 list-disc text-gray-500">
|
||||||
|
${this.appState.settings?.billingEnabled &&
|
||||||
|
html`<li class="text-warning">
|
||||||
|
${msg("Manage subscription")}
|
||||||
|
</li>
|
||||||
|
<li class="text-warning">
|
||||||
|
${msg("Manage billing details")}
|
||||||
|
</li>`}
|
||||||
|
<li>${msg("Edit org name and URL")}</li>
|
||||||
|
<li>${msg("Manage org members")}</li>
|
||||||
|
<li>${msg("View and edit org defaults")}</li>
|
||||||
|
</ul>
|
||||||
|
</sl-details>
|
||||||
</sl-radio>
|
</sl-radio>
|
||||||
</sl-radio-group>
|
</sl-radio-group>
|
||||||
</div>
|
</div>
|
||||||
@ -642,4 +720,13 @@ export class OrgSettings extends BtrixElement {
|
|||||||
private async getCurrentUser(): Promise<APIUser> {
|
private async getCurrentUser(): Promise<APIUser> {
|
||||||
return this.api.fetch("/users/me");
|
return this.api.fetch("/users/me");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop propgation of sl-tooltip events.
|
||||||
|
* Prevents bug where sl-dialog closes when tooltip closes
|
||||||
|
* https://github.com/shoelace-style/shoelace/issues/170
|
||||||
|
*/
|
||||||
|
private stopProp(e: Event) {
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user