diff --git a/apps/cyberstorm-remix/app/p/components/PackageListing/ManagementTools.tsx b/apps/cyberstorm-remix/app/p/components/PackageListing/ManagementTools.tsx index ce0fa153f..25868a0d6 100644 --- a/apps/cyberstorm-remix/app/p/components/PackageListing/ManagementTools.tsx +++ b/apps/cyberstorm-remix/app/p/components/PackageListing/ManagementTools.tsx @@ -81,7 +81,7 @@ export function ManagementTools({ )} {/* Manage package */} - {perms.can_manage && ( + {(perms.can_manage || perms.can_moderate) && (
= ({ data }) => { +export const meta: MetaFunction = ({ data }) => { return [ { title: data @@ -40,92 +38,49 @@ export const meta: MetaFunction = ({ data }) => { ]; }; +const package404 = new Response("Package not found", { status: 404 }); + export async function loader({ params }: LoaderFunctionArgs) { - if (params.communityId && params.namespaceId && params.packageId) { - try { - const publicEnvVariables = getPublicEnvVariables(["VITE_API_URL"]); - const dapper = new DapperTs(() => { - return { - apiHost: publicEnvVariables.VITE_API_URL, - sessionId: undefined, - }; - }); - return { - community: await dapper.getCommunity(params.communityId), - communityFilters: await dapper.getCommunityFilters(params.communityId), - listing: await dapper.getPackageListingDetails( - params.communityId, - params.namespaceId, - params.packageId - ), - team: await dapper.getTeamDetails(params.namespaceId), - filters: await dapper.getCommunityFilters(params.communityId), - permissions: undefined, - }; - } catch (error) { - if (error instanceof ApiError) { - throw new Response("Package not found", { status: 404 }); - } else { - // REMIX TODO: Add sentry - throw error; - } - } - } - throw new Response("Package not found", { status: 404 }); + return undefined; } -// TODO: Needs to check if package is available for the logged in user -export async function clientLoader({ params }: LoaderFunctionArgs) { - if (params.communityId && params.namespaceId && params.packageId) { - try { - const tools = getSessionTools(); - const dapper = new DapperTs(() => { - return { - apiHost: tools?.getConfig().apiHost, - sessionId: tools?.getConfig().sessionId, - }; - }); +export async function clientLoader({ params, request }: LoaderFunctionArgs) { + const { communityId, namespaceId, packageId } = params; - const permissions = await dapper.getPackagePermissions( - params.communityId, - params.namespaceId, - params.packageId - ); + if (!communityId || !namespaceId || !packageId) { + throw package404; + } - if (!permissions?.permissions.can_manage) { - throw new Response("Unauthorized", { status: 403 }); - } + try { + const dapper = getDapperForRequest(request); - return { - community: await dapper.getCommunity(params.communityId), - communityFilters: await dapper.getCommunityFilters(params.communityId), - listing: await dapper.getPackageListingDetails( - params.communityId, - params.namespaceId, - params.packageId - ), - team: await dapper.getTeamDetails(params.namespaceId), - filters: await dapper.getCommunityFilters(params.communityId), - permissions: permissions, - }; - } catch (error) { - if (error instanceof ApiError) { - throw new Response("Package not found", { status: 404 }); - } else { - throw error; - } + // Fetch everything at once for faster page load, even if we may + // overfetch in case we lack authentication/authorization. + const [listing, permissions, filters] = await Promise.all([ + getPrivateListing(dapper, { communityId, namespaceId, packageId }), + dapper.getPackagePermissions(communityId, namespaceId, packageId), + dapper.getCommunityFilters(communityId), + ]); + + if (!permissions) { + throw new Response("Unauthenticated", { status: 401 }); + } else if ( + !permissions.permissions.can_manage && + !permissions.permissions.can_moderate + ) { + throw new Response("Unauthorized", { status: 403 }); } + + return { listing, permissions, filters }; + } catch (error) { + throw error instanceof ApiError ? package404 : error; } - throw new Response("Package not found", { status: 404 }); } clientLoader.hydrate = true; export default function PackageListing() { - const { community, listing, filters, permissions } = useLoaderData< - typeof loader | typeof clientLoader - >(); - + const loaderData = useLoaderData(); const outletContext = useOutletContext() as OutletContextShape; const config = outletContext.requestConfig; const toast = useToast(); @@ -185,7 +140,7 @@ export default function PackageListing() { } const [formInputs, updateFormFieldState] = useReducer(formFieldUpdateAction, { - categories: listing.categories.map((c) => c.slug), + categories: loaderData?.listing.categories.map((c) => c.slug) ?? [], }); type SubmitorOutput = Awaited>; @@ -194,7 +149,7 @@ export default function PackageListing() { return await packageListingUpdate({ config: config, params: { - community: community.identifier, + community: listing.community_identifier, namespace: listing.namespace, package: listing.name, }, @@ -233,6 +188,12 @@ export default function PackageListing() { }, }); + if (!loaderData) { + return ; + } + + const { listing, filters, permissions } = loaderData; + return ( <> @@ -240,7 +201,7 @@ export default function PackageListing() {
- {permissions?.permissions.can_unlist ? ( + {permissions.permissions.can_unlist && ( <>
@@ -262,7 +223,7 @@ export default function PackageListing() { unlistAction({ config: config, params: { - community: community.identifier, + community: listing.community_identifier, namespace: listing.namespace, package: listing.name, }, @@ -280,8 +241,8 @@ export default function PackageListing() {
- ) : null} - {permissions?.permissions.can_manage_deprecation ? ( + )} + {permissions.permissions.can_manage_deprecation && ( <>
@@ -331,7 +292,7 @@ export default function PackageListing() {
- ) : null} + )}
Categories