Enhance public access and error handling in site-related views and loaders

- Updated `DebugScopedRateThrottle` to allow public access for blueprint list requests with site filters.
- Modified `SiteViewSet` and `SiteBlueprintViewSet` to permit public read access for list requests.
- Enhanced `loadSiteDefinition` to resolve site slugs to IDs, improving the loading process for site definitions.
- Improved error handling in `SiteDefinitionView` and `loadSiteDefinition` for better user feedback.
- Adjusted CSS styles for better layout and alignment in shared components.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-18 22:40:00 +00:00
parent 8ab15d1d79
commit 6c6133a683
14 changed files with 361 additions and 76 deletions

View File

@@ -41,11 +41,53 @@ function getApiBaseUrl(): string {
const API_URL = getApiBaseUrl();
/**
* Load site definition by site ID.
* First tries to load from filesystem (deployed sites),
* Resolve site slug to site ID.
* Queries the Site API to get the site ID from the slug.
*/
async function resolveSiteIdFromSlug(siteSlug: string): Promise<number> {
try {
// Query sites by slug - slug is unique per account, but we need to search across all accounts for public sites
const response = await axios.get(`${API_URL}/v1/auth/sites/`, {
params: { slug: siteSlug },
timeout: 10000,
headers: {
'Accept': 'application/json',
},
});
const sites = Array.isArray(response.data?.results) ? response.data.results :
Array.isArray(response.data) ? response.data : [];
if (sites.length > 0) {
return sites[0].id;
}
throw new Error(`Site with slug "${siteSlug}" not found`);
} catch (error) {
if (axios.isAxiosError(error)) {
if (error.response?.status === 404) {
throw new Error(`Site with slug "${siteSlug}" not found`);
}
throw new Error(`Failed to resolve site slug: ${error.message}`);
}
throw error;
}
}
/**
* Load site definition by site slug.
* First resolves slug to ID, then tries to load from filesystem (deployed sites),
* then falls back to API.
*/
export async function loadSiteDefinition(siteId: string): Promise<SiteDefinition> {
export async function loadSiteDefinition(siteSlug: string): Promise<SiteDefinition> {
// First, resolve slug to site ID
let siteId: number;
try {
siteId = await resolveSiteIdFromSlug(siteSlug);
} catch (error) {
throw error; // Re-throw slug resolution errors
}
// Try API endpoint for deployed site definition first
try {
const response = await axios.get(`${API_URL}/v1/publisher/sites/${siteId}/definition/`, {
@@ -82,7 +124,7 @@ export async function loadSiteDefinition(siteId: string): Promise<SiteDefinition
return transformBlueprintToSiteDefinition(blueprint);
}
throw new Error(`No blueprint found for site ${siteId}`);
throw new Error(`No blueprint found for site ${siteSlug}`);
} catch (error) {
if (axios.isAxiosError(error)) {
throw new Error(`Failed to load site: ${error.message}`);
@@ -110,6 +152,7 @@ function transformBlueprintToSiteDefinition(blueprint: any): SiteDefinition {
type: page.type,
blocks: page.blocks_json || [],
status: page.status,
order: page.order || 0,
})) || [],
config: blueprint.config_json || {},
created_at: blueprint.created_at,