mirror of
https://github.com/fosrl/pangolin.git
synced 2026-03-02 16:56:39 +00:00
♻️ only show product updates if the user is an admin or the owner
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { Request, Response, NextFunction } from "express";
|
import { Request, Response, NextFunction } from "express";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { db } from "@server/db";
|
import { db, roles } from "@server/db";
|
||||||
import { Org, orgs, userOrgs } from "@server/db";
|
import { Org, orgs, userOrgs } from "@server/db";
|
||||||
import response from "@server/lib/response";
|
import response from "@server/lib/response";
|
||||||
import HttpCode from "@server/types/HttpCode";
|
import HttpCode from "@server/types/HttpCode";
|
||||||
@@ -40,7 +40,7 @@ const listOrgsSchema = z.object({
|
|||||||
// responses: {}
|
// responses: {}
|
||||||
// });
|
// });
|
||||||
|
|
||||||
type ResponseOrg = Org & { isOwner?: boolean };
|
type ResponseOrg = Org & { isOwner?: boolean; isAdmin?: boolean };
|
||||||
|
|
||||||
export type ListUserOrgsResponse = {
|
export type ListUserOrgsResponse = {
|
||||||
orgs: ResponseOrg[];
|
orgs: ResponseOrg[];
|
||||||
@@ -112,6 +112,7 @@ export async function listUserOrgs(
|
|||||||
userOrgs,
|
userOrgs,
|
||||||
and(eq(userOrgs.orgId, orgs.orgId), eq(userOrgs.userId, userId))
|
and(eq(userOrgs.orgId, orgs.orgId), eq(userOrgs.userId, userId))
|
||||||
)
|
)
|
||||||
|
.leftJoin(roles, eq(userOrgs.orgId, roles.orgId))
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
.offset(offset);
|
.offset(offset);
|
||||||
|
|
||||||
@@ -128,6 +129,9 @@ export async function listUserOrgs(
|
|||||||
if (val.userOrgs && val.userOrgs.isOwner) {
|
if (val.userOrgs && val.userOrgs.isOwner) {
|
||||||
res.isOwner = val.userOrgs.isOwner;
|
res.isOwner = val.userOrgs.isOwner;
|
||||||
}
|
}
|
||||||
|
if (val.roles && val.roles.isAdmin) {
|
||||||
|
res.isAdmin = val.roles.isAdmin;
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +1,30 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import { SidebarNav } from "@app/components/SidebarNav";
|
|
||||||
import { OrgSelector } from "@app/components/OrgSelector";
|
|
||||||
import { cn } from "@app/lib/cn";
|
|
||||||
import { ListUserOrgsResponse } from "@server/routers/org";
|
|
||||||
import SupporterStatus from "@app/components/SupporterStatus";
|
|
||||||
import {
|
|
||||||
ExternalLink,
|
|
||||||
Server,
|
|
||||||
BookOpenText,
|
|
||||||
Zap,
|
|
||||||
CreditCard,
|
|
||||||
FileText,
|
|
||||||
TicketCheck
|
|
||||||
} from "lucide-react";
|
|
||||||
import { FaDiscord, FaGithub } from "react-icons/fa";
|
|
||||||
import Link from "next/link";
|
|
||||||
import { usePathname } from "next/navigation";
|
|
||||||
import { useUserContext } from "@app/hooks/useUserContext";
|
|
||||||
import { useLicenseStatusContext } from "@app/hooks/useLicenseStatusContext";
|
|
||||||
import { useEnvContext } from "@app/hooks/useEnvContext";
|
|
||||||
import { useTranslations } from "next-intl";
|
|
||||||
import type { SidebarNavSection } from "@app/app/navigation";
|
import type { SidebarNavSection } from "@app/app/navigation";
|
||||||
|
import { OrgSelector } from "@app/components/OrgSelector";
|
||||||
|
import { SidebarNav } from "@app/components/SidebarNav";
|
||||||
|
import SupporterStatus from "@app/components/SupporterStatus";
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
TooltipTrigger
|
TooltipTrigger
|
||||||
} from "@app/components/ui/tooltip";
|
} from "@app/components/ui/tooltip";
|
||||||
|
import { useEnvContext } from "@app/hooks/useEnvContext";
|
||||||
|
import { useLicenseStatusContext } from "@app/hooks/useLicenseStatusContext";
|
||||||
|
import { useUserContext } from "@app/hooks/useUserContext";
|
||||||
|
import { cn } from "@app/lib/cn";
|
||||||
import { build } from "@server/build";
|
import { build } from "@server/build";
|
||||||
|
import { ListUserOrgsResponse } from "@server/routers/org";
|
||||||
|
import { ExternalLink, Server } from "lucide-react";
|
||||||
|
import { useTranslations } from "next-intl";
|
||||||
|
import dynamic from "next/dynamic";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { usePathname } from "next/navigation";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import { FaGithub } from "react-icons/fa";
|
||||||
import SidebarLicenseButton from "./SidebarLicenseButton";
|
import SidebarLicenseButton from "./SidebarLicenseButton";
|
||||||
import { SidebarSupportButton } from "./SidebarSupportButton";
|
import { SidebarSupportButton } from "./SidebarSupportButton";
|
||||||
import dynamic from "next/dynamic";
|
|
||||||
|
|
||||||
const ProductUpdates = dynamic(() => import("./ProductUpdates"), {
|
const ProductUpdates = dynamic(() => import("./ProductUpdates"), {
|
||||||
ssr: false
|
ssr: false
|
||||||
@@ -48,7 +40,7 @@ interface LayoutSidebarProps {
|
|||||||
|
|
||||||
export function LayoutSidebar({
|
export function LayoutSidebar({
|
||||||
orgId,
|
orgId,
|
||||||
orgs,
|
orgs = [],
|
||||||
navItems,
|
navItems,
|
||||||
defaultSidebarCollapsed,
|
defaultSidebarCollapsed,
|
||||||
hasCookiePreference
|
hasCookiePreference
|
||||||
@@ -105,6 +97,9 @@ export function LayoutSidebar({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const canShowProductUpdates =
|
||||||
|
user.serverAdmin || orgs[0]?.isOwner || orgs[0]?.isAdmin;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
@@ -159,9 +154,11 @@ export function LayoutSidebar({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="p-4 flex flex-col shrink-0">
|
<div className="p-4 flex flex-col shrink-0">
|
||||||
<div className="mb-3">
|
{canShowProductUpdates && (
|
||||||
<ProductUpdates isCollapsed={isSidebarCollapsed} />
|
<div className="mb-3">
|
||||||
</div>
|
<ProductUpdates isCollapsed={isSidebarCollapsed} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{build === "enterprise" && (
|
{build === "enterprise" && (
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user