diff --git a/components/dashboard/src/Insights.tsx b/components/dashboard/src/Insights.tsx index 4db31ed2b8427c..c9fa6d3e69069e 100644 --- a/components/dashboard/src/Insights.tsx +++ b/components/dashboard/src/Insights.tsx @@ -27,6 +27,7 @@ import { DownloadIcon } from "lucide-react"; import { Button } from "@podkit/buttons/Button"; import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "@podkit/dropdown/DropDown"; import { useInstallationConfiguration } from "./data/installation/installation-config-query"; +import { ApplicationError, ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error"; export const Insights = () => { const toDate = useMemo(() => Timestamp.fromDate(new Date()), []); @@ -49,6 +50,9 @@ export const Insights = () => { const grouped = Object.groupBy(sessions, (ws) => ws.workspace?.id ?? "unknown"); const [page, setPage] = useState(0); + const isLackingPermissions = + errorMessage instanceof ApplicationError && errorMessage.code === ErrorCodes.PERMISSION_DENIED; + return ( <>
@@ -59,7 +63,7 @@ export const Insights = () => { "md:flex-row md:items-center md:space-x-4 md:space-y-0", )} > - +
{ {errorMessage && ( - {errorMessage instanceof Error ? errorMessage.message : "An error occurred."} + {isLackingPermissions ? ( + <> + You don't have Owner permissions to access this + organization's insights. + + ) : errorMessage instanceof Error ? ( + errorMessage.message + ) : ( + "An error occurred." + )} )} @@ -151,8 +164,9 @@ export const Insights = () => { type DownloadUsageProps = { to: Timestamp; + disabled?: boolean; }; -export const DownloadUsage = ({ to }: DownloadUsageProps) => { +export const DownloadUsage = ({ to, disabled }: DownloadUsageProps) => { const { data: org } = useCurrentOrg(); const { toast } = useToast(); // When we start the download, we disable the button for a short time @@ -184,7 +198,7 @@ export const DownloadUsage = ({ to }: DownloadUsageProps) => { return ( - diff --git a/components/dashboard/src/menu/OrganizationSelector.tsx b/components/dashboard/src/menu/OrganizationSelector.tsx index 1dd6d627c3a114..362f5bbdcc8c33 100644 --- a/components/dashboard/src/menu/OrganizationSelector.tsx +++ b/components/dashboard/src/menu/OrganizationSelector.tsx @@ -23,7 +23,7 @@ export default function OrganizationSelector() { const orgs = useOrganizations(); const currentOrg = useCurrentOrg(); const members = useListOrganizationMembers().data ?? []; - const owner = useIsOwner(); + const isOwner = useIsOwner(); const hasMemberPermission = useHasRolePermission(OrganizationRole.MEMBER); const { data: billingMode } = useOrgBillingMode(); const getOrgURL = useGetOrgURL(); @@ -78,13 +78,15 @@ export default function OrganizationSelector() { link: "/members", }); if (isDedicated) { - linkEntries.push({ - title: "Insights", - customContent: Insights, - active: false, - separator: false, - link: "/insights", - }); + if (isOwner) { + linkEntries.push({ + title: "Insights", + customContent: Insights, + active: false, + separator: false, + link: "/insights", + }); + } } else { linkEntries.push({ title: "Usage", @@ -95,7 +97,7 @@ export default function OrganizationSelector() { }); } // Show billing if user is an owner of current org - if (owner) { + if (isOwner) { if (billingMode?.mode === "usage-based") { linkEntries.push({ title: "Billing",