@@ -6,168 +6,189 @@ import {
66} from "@thunderstore/cyberstorm" ;
77import "./Dependants.css" ;
88import { PackageSearch } from "~/commonComponents/PackageSearch/PackageSearch" ;
9- import { DapperTs } from "@thunderstore/dapper-ts" ;
109import { PackageOrderOptions } from "../../commonComponents/PackageSearch/components/PackageOrder" ;
1110import { type OutletContextShape } from "../../root" ;
1211import { PageHeader } from "~/commonComponents/PageHeader/PageHeader" ;
1312import {
14- getPublicEnvVariables ,
15- getSessionTools ,
16- } from "cyberstorm/security/publicEnvVariables " ;
13+ NimbusAwaitErrorElement ,
14+ NimbusDefaultRouteErrorBoundary ,
15+ } from "cyberstorm/utils/errors/NimbusErrorBoundary " ;
1716import type { Route } from "./+types/Dependants" ;
1817import { Suspense } from "react" ;
18+ import { throwUserFacingPayloadResponse } from "cyberstorm/utils/errors/userFacingErrorResponse" ;
19+ import { handleLoaderError } from "cyberstorm/utils/errors/handleLoaderError" ;
20+ import { createNotFoundMapping } from "cyberstorm/utils/errors/loaderMappings" ;
21+ import { getLoaderTools } from "cyberstorm/utils/getLoaderTools" ;
22+ import { parseIntegerSearchParam } from "cyberstorm/utils/searchParamsUtils" ;
23+
24+ const packageDependantsNotFoundMappings = [
25+ createNotFoundMapping (
26+ "Package not found." ,
27+ "We could not find the requested package."
28+ ) ,
29+ ] ;
1930
2031export async function loader ( { params, request } : Route . LoaderArgs ) {
2132 if ( params . communityId && params . packageId && params . namespaceId ) {
22- const publicEnvVariables = getPublicEnvVariables ( [ "VITE_API_URL" ] ) ;
23- const dapper = new DapperTs ( ( ) => {
24- return {
25- apiHost : publicEnvVariables . VITE_API_URL ,
26- sessionId : undefined ,
27- } ;
28- } ) ;
33+ const { dapper } = getLoaderTools ( ) ;
2934 const searchParams = new URL ( request . url ) . searchParams ;
3035 const ordering =
3136 searchParams . get ( "ordering" ) ?? PackageOrderOptions . Updated ;
32- const page = searchParams . get ( "page" ) ;
37+ const page = parseIntegerSearchParam ( searchParams . get ( "page" ) ) ;
3338 const search = searchParams . get ( "search" ) ;
3439 const includedCategories = searchParams . get ( "includedCategories" ) ;
3540 const excludedCategories = searchParams . get ( "excludedCategories" ) ;
3641 const section = searchParams . get ( "section" ) ;
3742 const nsfw = searchParams . get ( "nsfw" ) ;
3843 const deprecated = searchParams . get ( "deprecated" ) ;
39- const filters = await dapper . getCommunityFilters ( params . communityId ) ;
44+ try {
45+ const dataPromise = await Promise . all ( [
46+ dapper . getCommunityFilters ( params . communityId ) ,
47+ dapper . getCommunity ( params . communityId ) ,
48+ dapper . getPackageListingDetails (
49+ params . communityId ,
50+ params . namespaceId ,
51+ params . packageId
52+ ) ,
53+ dapper . getPackageListings (
54+ {
55+ kind : "package-dependants" ,
56+ communityId : params . communityId ,
57+ namespaceId : params . namespaceId ,
58+ packageName : params . packageId ,
59+ } ,
60+ ordering ?? "" ,
61+ page ,
62+ search ?? "" ,
63+ includedCategories ?. split ( "," ) ?? undefined ,
64+ excludedCategories ?. split ( "," ) ?? undefined ,
65+ section ? ( section === "all" ? "" : section ) : "" ,
66+ nsfw === "true" ? true : false ,
67+ deprecated === "true" ? true : false
68+ ) ,
69+ ] ) ;
4070
41- return {
42- community : dapper . getCommunity ( params . communityId ) ,
43- listing : dapper . getPackageListingDetails (
44- params . communityId ,
45- params . namespaceId ,
46- params . packageId
47- ) ,
48- filters : filters ,
49- listings : await dapper . getPackageListings (
50- {
51- kind : "package-dependants" ,
52- communityId : params . communityId ,
53- namespaceId : params . namespaceId ,
54- packageName : params . packageId ,
55- } ,
56- ordering ?? "" ,
57- page === null ? undefined : Number ( page ) ,
58- search ?? "" ,
59- includedCategories ?. split ( "," ) ?? undefined ,
60- excludedCategories ?. split ( "," ) ?? undefined ,
61- section ? ( section === "all" ? "" : section ) : "" ,
62- nsfw === "true" ? true : false ,
63- deprecated === "true" ? true : false
64- ) ,
65- } ;
71+ return dataPromise ;
72+ } catch ( error ) {
73+ handleLoaderError ( error , {
74+ mappings : packageDependantsNotFoundMappings ,
75+ } ) ;
76+ }
6677 }
67- throw new Response ( "Community not found" , { status : 404 } ) ;
78+ throwUserFacingPayloadResponse ( {
79+ headline : "Community not found." ,
80+ description : "We could not find the requested community." ,
81+ category : "not_found" ,
82+ status : 404 ,
83+ } ) ;
6884}
6985
7086export async function clientLoader ( {
7187 request,
7288 params,
7389} : Route . ClientLoaderArgs ) {
7490 if ( params . communityId && params . packageId && params . namespaceId ) {
75- const tools = getSessionTools ( ) ;
76- const dapper = new DapperTs ( ( ) => {
77- return {
78- apiHost : tools ?. getConfig ( ) . apiHost ,
79- sessionId : tools ?. getConfig ( ) . sessionId ,
80- } ;
81- } ) ;
91+ const { dapper } = getLoaderTools ( ) ;
8292 const searchParams = new URL ( request . url ) . searchParams ;
8393 const ordering =
8494 searchParams . get ( "ordering" ) ?? PackageOrderOptions . Updated ;
85- const page = searchParams . get ( "page" ) ;
95+ const page = parseIntegerSearchParam ( searchParams . get ( "page" ) ) ;
8696 const search = searchParams . get ( "search" ) ;
8797 const includedCategories = searchParams . get ( "includedCategories" ) ;
8898 const excludedCategories = searchParams . get ( "excludedCategories" ) ;
8999 const section = searchParams . get ( "section" ) ;
90100 const nsfw = searchParams . get ( "nsfw" ) ;
91101 const deprecated = searchParams . get ( "deprecated" ) ;
92- const filters = dapper . getCommunityFilters ( params . communityId ) ;
93- return {
94- community : dapper . getCommunity ( params . communityId ) ,
95- listing : dapper . getPackageListingDetails (
102+
103+ const dataPromise = Promise . all ( [
104+ dapper . getCommunityFilters ( params . communityId ) ,
105+ dapper . getCommunity ( params . communityId ) ,
106+ dapper . getPackageListingDetails (
96107 params . communityId ,
97108 params . namespaceId ,
98109 params . packageId
99110 ) ,
100- filters : filters ,
101- listings : dapper . getPackageListings (
111+ dapper . getPackageListings (
102112 {
103113 kind : "package-dependants" ,
104114 communityId : params . communityId ,
105115 namespaceId : params . namespaceId ,
106116 packageName : params . packageId ,
107117 } ,
108118 ordering ?? "" ,
109- page === null ? undefined : Number ( page ) ,
119+ page ,
110120 search ?? "" ,
111121 includedCategories ?. split ( "," ) ?? undefined ,
112122 excludedCategories ?. split ( "," ) ?? undefined ,
113123 section ? ( section === "all" ? "" : section ) : "" ,
114- nsfw === "true" ? true : false ,
115- deprecated === "true" ? true : false
124+ nsfw === "true" ,
125+ deprecated === "true"
116126 ) ,
117- } ;
127+ ] ) ;
128+
129+ return dataPromise ;
118130 }
119- throw new Response ( "Community not found" , { status : 404 } ) ;
131+ throwUserFacingPayloadResponse ( {
132+ headline : "Community not found." ,
133+ description : "We could not find the requested community." ,
134+ category : "not_found" ,
135+ status : 404 ,
136+ } ) ;
120137}
121138
122139export default function Dependants ( ) {
123- const { filters, listing, listings } = useLoaderData <
124- typeof loader | typeof clientLoader
125- > ( ) ;
140+ const data = useLoaderData < typeof loader | typeof clientLoader > ( ) ;
126141
127142 const outletContext = useOutletContext ( ) as OutletContextShape ;
128143
129144 return (
130- < >
131- < section className = "dependants" >
132- < Suspense fallback = { < SkeletonBox /> } >
133- < Await resolve = { listing } >
134- { ( resolvedValue ) => (
135- < PageHeader headingLevel = "1" headingSize = "3" >
136- Mods that depend on{ " " }
137- < NewLink
138- primitiveType = "cyberstormLink"
139- linkId = "Package"
140- community = { resolvedValue . community_identifier }
141- namespace = { resolvedValue . namespace }
142- package = { resolvedValue . name }
143- csVariant = "cyber"
144- >
145- { formatToDisplayName ( resolvedValue . name ) }
146- </ NewLink >
147- { " by " }
148- < NewLink
149- primitiveType = "cyberstormLink"
150- linkId = "Team"
151- community = { resolvedValue . community_identifier }
152- team = { resolvedValue . namespace }
153- csVariant = "cyber"
154- >
155- { resolvedValue . namespace }
156- </ NewLink >
157- </ PageHeader >
158- ) }
159- </ Await >
160- </ Suspense >
161- < >
162- < PackageSearch
163- listings = { listings }
164- filters = { filters }
165- config = { outletContext . requestConfig }
166- currentUser = { outletContext . currentUser }
167- dapper = { outletContext . dapper }
168- />
169- </ >
170- </ section >
171- </ >
145+ < section className = "dependants" >
146+ < Suspense fallback = { < SkeletonBox /> } >
147+ < Await resolve = { data } errorElement = { < NimbusAwaitErrorElement /> } >
148+ { ( resolvedData ) => {
149+ const [ communityFilters , community , listingDetail , listings ] =
150+ resolvedData ;
151+ return (
152+ < >
153+ < PageHeader headingLevel = "1" headingSize = "3" >
154+ Mods that depend on{ " " }
155+ < NewLink
156+ primitiveType = "cyberstormLink"
157+ linkId = "Package"
158+ community = { community . identifier }
159+ namespace = { listingDetail . namespace }
160+ package = { listingDetail . name }
161+ csVariant = "cyber"
162+ >
163+ { formatToDisplayName ( listingDetail . name ) }
164+ </ NewLink >
165+ { " by " }
166+ < NewLink
167+ primitiveType = "cyberstormLink"
168+ linkId = "Team"
169+ community = { listingDetail . community_identifier }
170+ team = { listingDetail . namespace }
171+ csVariant = "cyber"
172+ >
173+ { listingDetail . namespace }
174+ </ NewLink >
175+ </ PageHeader >
176+ < PackageSearch
177+ listings = { listings }
178+ filters = { communityFilters }
179+ config = { outletContext . requestConfig }
180+ currentUser = { outletContext . currentUser }
181+ dapper = { outletContext . dapper }
182+ />
183+ </ >
184+ ) ;
185+ } }
186+ </ Await >
187+ </ Suspense >
188+ </ section >
172189 ) ;
173190}
191+
192+ export function ErrorBoundary ( ) {
193+ return < NimbusDefaultRouteErrorBoundary /> ;
194+ }
0 commit comments