feat: color-coded visibility badges and contextual space display names
- Visibility badges now color-coded: green (public), yellow (permissioned), red (private) with matching card border tints - Public spaces show eye icon instead of lock - Private spaces display as "username's (you)rSpace" instead of raw name - Applied consistently across space switcher dropdown and My Spaces modal Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
aeb9247f96
commit
c7674ac526
|
|
@ -926,23 +926,36 @@ export class RStackIdentity extends HTMLElement {
|
|||
overlay.addEventListener("click", (e) => { if (e.target === overlay) close(); });
|
||||
};
|
||||
|
||||
const visIcon = (v: string) =>
|
||||
v === "members_only" ? "🔒" : v === "authenticated" ? "🔑" : "🔓";
|
||||
const visInfo = (v: string) =>
|
||||
v === "members_only" ? { icon: "🔒", cls: "vis-private", label: "private" }
|
||||
: v === "authenticated" ? { icon: "🔑", cls: "vis-permissioned", label: "permissioned" }
|
||||
: { icon: "👁", cls: "vis-public", label: "public" };
|
||||
|
||||
const displayName = (s: any) => {
|
||||
const v = s.visibility || "public_read";
|
||||
if (v === "members_only") {
|
||||
const username = getUsername();
|
||||
return username ? `${username}'s (you)rSpace` : "(you)rSpace";
|
||||
}
|
||||
return `${(s.name || s.slug).replace(/</g, "<")} rSpace`;
|
||||
};
|
||||
|
||||
const renderSpaces = (spaces: any[]) => {
|
||||
const yourSpaces = spaces.filter((s) => s.role);
|
||||
const publicSpaces = spaces.filter((s) => !s.role && s.accessible);
|
||||
|
||||
const cardHTML = (s: any) => `
|
||||
<button class="space-card" data-slug="${s.slug}">
|
||||
const cardHTML = (s: any) => {
|
||||
const vis = visInfo(s.visibility || "public_read");
|
||||
return `
|
||||
<button class="space-card ${vis.cls}" data-slug="${s.slug}">
|
||||
<div class="space-card-initial">${(s.name || s.slug).charAt(0).toUpperCase()}</div>
|
||||
<div class="space-card-name">${(s.name || s.slug).replace(/</g, "<")}</div>
|
||||
<div class="space-card-name">${displayName(s)}</div>
|
||||
<div class="space-card-meta">
|
||||
<span class="space-vis">${visIcon(s.visibility)} ${s.visibility.replace(/_/g, " ")}</span>
|
||||
<span class="space-vis ${vis.cls}">${vis.icon} ${vis.label}</span>
|
||||
${s.role ? `<span class="space-role">${s.role}</span>` : ""}
|
||||
</div>
|
||||
</button>
|
||||
`;
|
||||
`;};
|
||||
|
||||
const yourSection = yourSpaces.length
|
||||
? `<div class="spaces-section-label">Your Spaces</div>
|
||||
|
|
@ -1290,6 +1303,12 @@ const SPACES_STYLES = `
|
|||
font-size: 0.7rem; color: #94a3b8; background: rgba(255,255,255,0.06);
|
||||
padding: 2px 8px; border-radius: 10px;
|
||||
}
|
||||
.space-vis.vis-public { background: rgba(52,211,153,0.15); color: #34d399; }
|
||||
.space-vis.vis-private { background: rgba(248,113,113,0.15); color: #f87171; }
|
||||
.space-vis.vis-permissioned { background: rgba(251,191,36,0.15); color: #fbbf24; }
|
||||
.space-card.vis-public { border-color: rgba(52,211,153,0.3); }
|
||||
.space-card.vis-private { border-color: rgba(248,113,113,0.3); }
|
||||
.space-card.vis-permissioned { border-color: rgba(251,191,36,0.3); }
|
||||
.space-role {
|
||||
font-size: 0.7rem; color: #06b6d4; background: rgba(6,182,212,0.1);
|
||||
padding: 2px 8px; border-radius: 10px; font-weight: 600;
|
||||
|
|
|
|||
|
|
@ -118,7 +118,17 @@ export class RStackSpaceSwitcher extends HTMLElement {
|
|||
const v = s.visibility || "public_read";
|
||||
if (v === "members_only") return { cls: "vis-private", label: "🔒" };
|
||||
if (v === "authenticated") return { cls: "vis-permissioned", label: "🔑" };
|
||||
return { cls: "vis-public", label: "🔓" };
|
||||
return { cls: "vis-public", label: "👁" };
|
||||
}
|
||||
|
||||
/** Format display name based on visibility type */
|
||||
#displayName(s: SpaceInfo): string {
|
||||
const v = s.visibility || "public_read";
|
||||
if (v === "members_only") {
|
||||
const username = getUsername();
|
||||
return username ? `${username}'s (you)rSpace` : "(you)rSpace";
|
||||
}
|
||||
return `${s.name} rSpace`;
|
||||
}
|
||||
|
||||
#renderMenu(menu: HTMLElement, current: string) {
|
||||
|
|
@ -178,7 +188,7 @@ export class RStackSpaceSwitcher extends HTMLElement {
|
|||
<div class="item-row ${vis.cls} ${s.slug === current ? "active" : ""}">
|
||||
<a class="item" href="${rspaceNavUrl(s.slug, moduleId)}">
|
||||
<span class="item-icon">${s.icon || "🌐"}</span>
|
||||
<span class="item-name">${s.name}</span>
|
||||
<span class="item-name">${this.#displayName(s)}</span>
|
||||
<span class="item-vis ${vis.cls}">${vis.label}</span>
|
||||
</a>${canEdit ? `<button class="item-gear" data-edit-slug="${s.slug}" data-edit-name="${s.name.replace(/"/g, """)}" title="Edit Space">⚙</button>` : ""}
|
||||
</div>`;
|
||||
|
|
@ -197,7 +207,7 @@ export class RStackSpaceSwitcher extends HTMLElement {
|
|||
<a class="item ${vis.cls} ${s.slug === current ? "active" : ""}"
|
||||
href="${rspaceNavUrl(s.slug, moduleId)}">
|
||||
<span class="item-icon">${s.icon || "🌐"}</span>
|
||||
<span class="item-name">${s.name}</span>
|
||||
<span class="item-name">${this.#displayName(s)}</span>
|
||||
<span class="item-vis ${vis.cls}">${vis.label}</span>
|
||||
</a>`;
|
||||
})
|
||||
|
|
@ -215,7 +225,7 @@ export class RStackSpaceSwitcher extends HTMLElement {
|
|||
return `
|
||||
<div class="item item--discover ${vis.cls}">
|
||||
<span class="item-icon">${s.icon || "🌐"}</span>
|
||||
<span class="item-name">${s.name}</span>
|
||||
<span class="item-name">${this.#displayName(s)}</span>
|
||||
<span class="item-vis ${vis.cls}">${vis.label}</span>
|
||||
${pending
|
||||
? `<span class="item-badge item-badge--pending">Requested</span>`
|
||||
|
|
|
|||
Loading…
Reference in New Issue