Add pending apps and frontend components
- apps/captain-mobile: Mobile API service - apps/flow-ui: Flow UI application - apps/mindlink: Mindlink application - apps/storage: Storage API and workers - apps/tzzr-cli: TZZR CLI tool - deck-frontend/backups: Historical TypeScript versions - hst-frontend: Standalone HST frontend Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
170
deck-frontend/backups/20260113_221902/src/modules/registry.ts
Normal file
170
deck-frontend/backups/20260113_221902/src/modules/registry.ts
Normal file
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* Module Registry - Tipos e interfaces para el sistema modular
|
||||
*/
|
||||
|
||||
import type { Store } from '@/state/store.ts';
|
||||
import type { AppState, ViewType, BaseType } from '@/types/index.ts';
|
||||
|
||||
// Tipos de renderizado de módulos
|
||||
export type ModuleRenderType =
|
||||
| 'standard' // Grid/Tree/Graph normal (taxonomía, atc)
|
||||
| 'chat' // Interfaz de chat con IA (mail, context)
|
||||
| 'custom'; // Interfaz completamente custom (key, mindlink)
|
||||
|
||||
// Categorías de módulos para agrupar en UI
|
||||
export type ModuleCategory =
|
||||
| 'taxonomy' // hst, flg, itm, loc, ply
|
||||
| 'masters' // mst, bck
|
||||
| 'registry' // atc, mth
|
||||
| 'communication' // mail, chat
|
||||
| 'services'; // key, mindlink
|
||||
|
||||
// Configuración de vistas soportadas por módulo
|
||||
export interface ModuleViews {
|
||||
grid?: boolean;
|
||||
tree?: boolean;
|
||||
graph?: boolean;
|
||||
custom?: string; // Nombre del componente custom a usar
|
||||
}
|
||||
|
||||
// Configuración de API por módulo
|
||||
export interface ModuleApiConfig {
|
||||
schema: string | null; // PostgREST schema (null = public)
|
||||
table: string; // Tabla principal
|
||||
hasLibraries?: boolean; // ¿Soporta bibliotecas?
|
||||
hasGroups?: boolean; // ¿Soporta grupos (set_hst)?
|
||||
hasGraph?: boolean; // ¿Tiene datos de grafo?
|
||||
hasTree?: boolean; // ¿Tiene datos de árbol?
|
||||
}
|
||||
|
||||
// Configuración completa de un módulo
|
||||
export interface BaseConfig {
|
||||
id: BaseType;
|
||||
name: string; // Nombre completo
|
||||
shortName: string; // Para botón (3-4 chars)
|
||||
category: ModuleCategory;
|
||||
renderType: ModuleRenderType;
|
||||
|
||||
// Vistas soportadas
|
||||
views: ModuleViews;
|
||||
defaultView: ViewType | 'custom';
|
||||
|
||||
// API
|
||||
api: ModuleApiConfig;
|
||||
|
||||
// Para módulos custom (lazy loading)
|
||||
customModule?: () => Promise<{ default: new (ctx: ModuleContext) => BaseModule }>;
|
||||
|
||||
// Estado inicial específico del módulo
|
||||
initialState?: Partial<ModuleState>;
|
||||
|
||||
// Módulo habilitado (false = mostrar "Próximamente")
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
// Estado específico de un módulo
|
||||
export interface ModuleState {
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
data: unknown;
|
||||
}
|
||||
|
||||
// Contexto pasado a cada módulo
|
||||
export interface ModuleContext {
|
||||
container: HTMLElement;
|
||||
leftPanel: HTMLElement;
|
||||
groupsBar: HTMLElement;
|
||||
store: Store<AppState>;
|
||||
config: BaseConfig;
|
||||
showDetail: (mrf: string) => void;
|
||||
}
|
||||
|
||||
// Clase base abstracta para módulos
|
||||
export abstract class BaseModule {
|
||||
protected ctx: ModuleContext;
|
||||
protected mounted = false;
|
||||
protected unsubscribe: (() => void) | null = null;
|
||||
|
||||
constructor(ctx: ModuleContext) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
// Lifecycle
|
||||
abstract mount(): Promise<void>;
|
||||
abstract unmount(): void;
|
||||
abstract render(): void;
|
||||
|
||||
// Override para carga de datos específica
|
||||
async loadData(): Promise<void> {
|
||||
// Default: no hace nada, subclases implementan
|
||||
}
|
||||
|
||||
// Override para contenido del sidebar (libraries/options)
|
||||
renderSidebar(): void {
|
||||
// Default: vacío
|
||||
this.ctx.leftPanel.innerHTML = '';
|
||||
}
|
||||
|
||||
// Override para barra de grupos
|
||||
renderGroupsBar(): void {
|
||||
// Default: vacío
|
||||
this.ctx.groupsBar.innerHTML = '';
|
||||
}
|
||||
|
||||
// Helpers
|
||||
protected getState(): Readonly<AppState> {
|
||||
return this.ctx.store.getState();
|
||||
}
|
||||
|
||||
protected setState(partial: Partial<AppState>): void {
|
||||
this.ctx.store.setState(partial);
|
||||
}
|
||||
|
||||
protected getConfig(): BaseConfig {
|
||||
return this.ctx.config;
|
||||
}
|
||||
|
||||
protected subscribe(listener: (state: AppState) => void): void {
|
||||
this.unsubscribe = this.ctx.store.subscribe(listener);
|
||||
}
|
||||
|
||||
// Verificar si una vista está soportada
|
||||
protected isViewSupported(view: ViewType): boolean {
|
||||
return !!this.ctx.config.views[view];
|
||||
}
|
||||
}
|
||||
|
||||
// Helper para obtener config de módulo
|
||||
export const getModuleConfig = (configs: Record<BaseType, BaseConfig>, base: BaseType): BaseConfig => {
|
||||
const config = configs[base];
|
||||
if (!config) {
|
||||
throw new Error(`Module config not found for base: ${base}`);
|
||||
}
|
||||
return config;
|
||||
};
|
||||
|
||||
// Helper para agrupar módulos por categoría
|
||||
export const getModulesByCategory = (
|
||||
configs: Record<BaseType, BaseConfig>
|
||||
): Record<ModuleCategory, BaseConfig[]> => {
|
||||
const result: Record<ModuleCategory, BaseConfig[]> = {
|
||||
taxonomy: [],
|
||||
masters: [],
|
||||
registry: [],
|
||||
communication: [],
|
||||
services: []
|
||||
};
|
||||
|
||||
Object.values(configs).forEach(config => {
|
||||
result[config.category].push(config);
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Helper para obtener módulos habilitados
|
||||
export const getEnabledModules = (
|
||||
configs: Record<BaseType, BaseConfig>
|
||||
): BaseConfig[] => {
|
||||
return Object.values(configs).filter(c => c.enabled !== false);
|
||||
};
|
||||
Reference in New Issue
Block a user