You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.0 KiB
110 lines
3.0 KiB
|
8 months ago
|
// view.ts
|
||
|
|
|
||
|
|
import type { Hotspot, SectionView, AttrID, SectionID} from "../types/all.ts";
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// UTILITIES
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Obtener la vista por defecto de una lista de vistas
|
||
|
|
*/
|
||
|
|
export function getDefaultView(views: SectionView[]): SectionView | null {
|
||
|
|
const defaultView = views.find(v => v.isDefault === true);
|
||
|
|
return defaultView || views[0] || null;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Filtrar vistas visibles según condiciones
|
||
|
|
*/
|
||
|
|
export function getVisibleViews(
|
||
|
|
views: SectionView[],
|
||
|
|
attributeValues: Record<AttrID, any>,
|
||
|
|
evaluator: any
|
||
|
|
): SectionView[] {
|
||
|
|
return views.filter(view => {
|
||
|
|
if (view.visible === undefined || view.visible === true) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
if (view.visible === false) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
// Es JsonLogic, evaluar
|
||
|
|
const data = { attributes: attributeValues };
|
||
|
|
return evaluator.evaluate(view.visible, data);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Obtener hotspots visibles de una vista
|
||
|
|
*/
|
||
|
|
export function getVisibleHotspots(
|
||
|
|
view: SectionView,
|
||
|
|
attributeValues: Record<AttrID, any>,
|
||
|
|
evaluator: any
|
||
|
|
): Hotspot[] {
|
||
|
|
if (!view.hotspots) return [];
|
||
|
|
|
||
|
|
return view.hotspots.filter(hotspot => {
|
||
|
|
if (hotspot.visible === undefined || hotspot.visible === true) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
if (hotspot.visible === false) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
// Es JsonLogic, evaluar
|
||
|
|
const data = { attributes: attributeValues };
|
||
|
|
return evaluator.evaluate(hotspot.visible, data);
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Generar URL de imagen para una vista específica
|
||
|
|
*/
|
||
|
|
export function generateViewImageUrl(
|
||
|
|
view: SectionView,
|
||
|
|
sectionId: SectionID,
|
||
|
|
globalAttributes : Record<AttrID, any>,
|
||
|
|
sectionAttributes: Record<AttrID, any>
|
||
|
|
): string {
|
||
|
|
const config = view.visualConfig;
|
||
|
|
|
||
|
|
if (!config.imageUrlTemplate) {
|
||
|
|
return config.fallbackImage || '/images/fallback.jpg';
|
||
|
|
}
|
||
|
|
|
||
|
|
let url = config.imageUrlTemplate;
|
||
|
|
|
||
|
|
// Reemplazar {basePath}
|
||
|
|
if (config.basePath) {
|
||
|
|
url = url.replace('{basePath}', config.basePath);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Reemplazar {sectionId}
|
||
|
|
url = url.replace('{sectionId}', sectionId.split(':')[1]);
|
||
|
|
|
||
|
|
// Reemplazar {viewId}
|
||
|
|
url = url.replace('{viewId}', view.id.split(':')[1]);
|
||
|
|
|
||
|
|
// Reemplazar atributos globales
|
||
|
|
config.globalAttributeDependencies?.forEach(attrId => {
|
||
|
|
const attrName = attrId.split(':')[1];
|
||
|
|
const value = globalAttributes[attrId];
|
||
|
|
if (value !== undefined) {
|
||
|
|
url = url.replace(`{global.${attrName}}`, String(value));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// Reemplazar atributos de sección
|
||
|
|
config.sectionAttributeDependencies?.forEach(attrId => {
|
||
|
|
const attrName = attrId.split(':')[1];
|
||
|
|
const value = sectionAttributes[attrId];
|
||
|
|
if (value !== undefined) {
|
||
|
|
url = url.replace(`{section.${attrName}}`, String(value));
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
return url;
|
||
|
|
}
|
||
|
|
|