|
|
|
|
@ -2,9 +2,6 @@ import { dataConfig } from './DataConfig';
|
|
|
|
|
import type {DataConfig, Rules, OptionGroup, View} from './DataConfigTypes';
|
|
|
|
|
import type { AppState } from './AppStateTypes';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DataConfigStore {
|
|
|
|
|
|
|
|
|
|
imgSrc : string = dataConfig.sources.imgViewsHi
|
|
|
|
|
@ -18,24 +15,50 @@ class DataConfigStore {
|
|
|
|
|
views: {}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// DEBUGGING
|
|
|
|
|
// ============================================
|
|
|
|
|
private debugLog(method: string, data: any) {
|
|
|
|
|
console.log(`[AppState.${method}]`, {
|
|
|
|
|
timestamp: new Date().toISOString(),
|
|
|
|
|
currentViewId: this.selection.currentViewId,
|
|
|
|
|
...data
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Método público para inspeccionar el estado completo
|
|
|
|
|
inspect() {
|
|
|
|
|
console.group('🔍 AppState Inspector');
|
|
|
|
|
console.log('Current View ID:', this.selection.currentViewId);
|
|
|
|
|
console.log('Current View:', this.currentView);
|
|
|
|
|
console.log('General Options:', this.selection.general);
|
|
|
|
|
console.log('All Views State:', this.selection.views);
|
|
|
|
|
console.log('Available Views:', Object.keys(dataConfig.options.views));
|
|
|
|
|
console.groupEnd();
|
|
|
|
|
return this.selection;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// CONSTRUCTOR E INICIALIZACIÓN
|
|
|
|
|
// ============================================
|
|
|
|
|
constructor() {
|
|
|
|
|
this.init();
|
|
|
|
|
|
|
|
|
|
// Exponer en window para debug desde consola
|
|
|
|
|
if (typeof window !== 'undefined') {
|
|
|
|
|
(window as any).appState = this;
|
|
|
|
|
console.log('✅ appState disponible en window.appState');
|
|
|
|
|
console.log('📝 Usa: window.appState.inspect() para ver el estado');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private init() {
|
|
|
|
|
// Obtener todas las vistas disponibles
|
|
|
|
|
const viewIds = Object.keys(dataConfig.options.views);
|
|
|
|
|
|
|
|
|
|
// Validar que existe al menos una vista
|
|
|
|
|
if (viewIds.length === 0) {
|
|
|
|
|
throw new Error('Configuración inválida: debe existir al menos una vista');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const state: AppState = {
|
|
|
|
|
currentViewId: viewIds[0],
|
|
|
|
|
general: {},
|
|
|
|
|
@ -58,6 +81,12 @@ class DataConfigStore {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
this.selection = state;
|
|
|
|
|
|
|
|
|
|
this.debugLog('init', {
|
|
|
|
|
initialViewId: state.currentViewId,
|
|
|
|
|
viewsCount: viewIds.length,
|
|
|
|
|
availableViews: viewIds
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
@ -66,11 +95,21 @@ class DataConfigStore {
|
|
|
|
|
|
|
|
|
|
/** Cambiar de habitación/estancia */
|
|
|
|
|
setView(viewId: string) {
|
|
|
|
|
const previousViewId = this.selection.currentViewId;
|
|
|
|
|
|
|
|
|
|
if (!dataConfig.options.views[viewId]) {
|
|
|
|
|
console.warn(`Vista ${viewId} no existe`);
|
|
|
|
|
console.error(`❌ Vista ${viewId} no existe`);
|
|
|
|
|
this.debugLog('setView', { error: 'View not found', viewId });
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.selection.currentViewId = viewId;
|
|
|
|
|
|
|
|
|
|
this.debugLog('setView', {
|
|
|
|
|
from: previousViewId,
|
|
|
|
|
to: viewId,
|
|
|
|
|
success: true
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Cambiar una opción (General o de Vista) */
|
|
|
|
|
@ -80,7 +119,17 @@ class DataConfigStore {
|
|
|
|
|
console.warn(`Grupo ${groupId} no existe en general`);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const previousValue = this.selection.general[groupId];
|
|
|
|
|
this.selection.general[groupId] = valueId;
|
|
|
|
|
|
|
|
|
|
this.debugLog('setOption', {
|
|
|
|
|
type: 'general',
|
|
|
|
|
groupId,
|
|
|
|
|
from: previousValue,
|
|
|
|
|
to: valueId
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.revalidateAll();
|
|
|
|
|
} else {
|
|
|
|
|
if (!(viewId in this.selection.views)) {
|
|
|
|
|
@ -91,7 +140,18 @@ class DataConfigStore {
|
|
|
|
|
console.warn(`Grupo ${groupId} no existe en vista ${viewId}`);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const previousValue = this.selection.views[viewId][groupId];
|
|
|
|
|
this.selection.views[viewId][groupId] = valueId;
|
|
|
|
|
|
|
|
|
|
this.debugLog('setOption', {
|
|
|
|
|
type: 'view',
|
|
|
|
|
viewId,
|
|
|
|
|
groupId,
|
|
|
|
|
from: previousValue,
|
|
|
|
|
to: valueId
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.revalidateView(viewId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -107,8 +167,11 @@ class DataConfigStore {
|
|
|
|
|
view.options.forEach((group: OptionGroup) => {
|
|
|
|
|
this.selection.views[viewId][group.id] = group.default;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.debugLog('reset', { viewId, type: 'single' });
|
|
|
|
|
} else {
|
|
|
|
|
this.init();
|
|
|
|
|
this.debugLog('reset', { type: 'all' });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -119,12 +182,12 @@ class DataConfigStore {
|
|
|
|
|
get currentView(): View {
|
|
|
|
|
const view = dataConfig.options.views[this.selection.currentViewId];
|
|
|
|
|
if (!view) {
|
|
|
|
|
console.error(`❌ Vista ${this.selection.currentViewId} no existe en la configuración`);
|
|
|
|
|
throw new Error(`Vista ${this.selection.currentViewId} no existe en la configuración`);
|
|
|
|
|
}
|
|
|
|
|
return view;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Nombre de la imagen de la vista ACTUAL */
|
|
|
|
|
get currentFileName() {
|
|
|
|
|
const viewId = this.selection.currentViewId;
|
|
|
|
|
@ -201,6 +264,16 @@ class DataConfigStore {
|
|
|
|
|
return this.selection.views[viewId]?.[groupId];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Obtener todas las vistas disponibles */
|
|
|
|
|
getAllViews(): View[] {
|
|
|
|
|
return Object.values(dataConfig.options.views);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Obtener los IDs de todas las vistas */
|
|
|
|
|
getAllViewIds(): string[] {
|
|
|
|
|
return Object.keys(dataConfig.options.views);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ============================================
|
|
|
|
|
// VALIDACIÓN
|
|
|
|
|
// ============================================
|
|
|
|
|
@ -239,6 +312,8 @@ class DataConfigStore {
|
|
|
|
|
|
|
|
|
|
/** Revalidar todas las vistas */
|
|
|
|
|
private revalidateAll() {
|
|
|
|
|
this.debugLog('revalidateAll', { trigger: 'general option changed' });
|
|
|
|
|
|
|
|
|
|
Object.keys(dataConfig.options.views).forEach(vId => {
|
|
|
|
|
this.revalidateView(vId);
|
|
|
|
|
});
|
|
|
|
|
@ -249,13 +324,25 @@ class DataConfigStore {
|
|
|
|
|
const view = dataConfig.options.views[viewId];
|
|
|
|
|
if (!view) return;
|
|
|
|
|
|
|
|
|
|
const changes: any[] = [];
|
|
|
|
|
|
|
|
|
|
view.options.forEach((group: OptionGroup) => {
|
|
|
|
|
const currentId = this.selection.views[viewId][group.id];
|
|
|
|
|
const opt = group.values.find(v => v.id === currentId);
|
|
|
|
|
if (opt?.rules && !this.isValid(opt.rules)) {
|
|
|
|
|
changes.push({
|
|
|
|
|
group: group.id,
|
|
|
|
|
from: currentId,
|
|
|
|
|
to: group.default,
|
|
|
|
|
reason: 'rule validation failed'
|
|
|
|
|
});
|
|
|
|
|
this.selection.views[viewId][group.id] = group.default;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (changes.length > 0) {
|
|
|
|
|
this.debugLog('revalidateView', { viewId, changes });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|