fix(plugins): ensure records subtab fallback and provide complete schema translations (1.21.1)

main
Juan Manuel Bardallo 2026-10-26 22:06:10 +01:00
parent c178c21031
commit b169748c98
7 changed files with 309 additions and 10 deletions

View File

@ -1,5 +1,13 @@
# Changelog
## [1.21.1] - 2026-10-26
### Fixed
- **Sub-pestaña de Historial y Traducciones de Esquema en Plugins (`PluginService`, `PluginSettingsComponent`)**:
- Asegurada la visualización de la sub-pestaña "Historial y Registros" en plugins como `ogaquarium` mediante fallback preventivo en caso de retraso o indisponibilidad en la consulta del endpoint de manifiesto.
- Incorporadas las claves y diccionarios de internacionalización (`labelKey`, `descriptionKey`, `ogaquarium.schema.*`) en español, inglés y catalán para todos los parámetros de configuración del plugin.
- Inyección reactiva inmediata de los catálogos de traducción al alternar de idioma sin requerir recargas completas ni llamadas síncronas de red.
## [1.21.0] - 2026-10-26
### Added

View File

@ -24,7 +24,7 @@
</div>
@if (plugin.enabled) {
@if (plugin.recordsEndpoint) {
@if (plugin.recordsEndpoint || plugin.name === 'ogaquarium') {
<div class="subtabs-navigation-bar">
<button
type="button"
@ -172,7 +172,7 @@
}
</div>
</div>
} @else if (activeSubTab === 1 && plugin.recordsEndpoint) {
} @else if (activeSubTab === 1 && (plugin.recordsEndpoint || plugin.name === 'ogaquarium')) {
<div class="records-wrapper">
<div class="records-header-row">
<div class="records-title-group">

View File

@ -64,6 +64,9 @@ export class PluginSettingsComponent implements OnInit, OnChanges, OnDestroy {
if (!this.pluginName) return;
this.plugin = this.pluginService.getPlugin(this.pluginName);
if (this.plugin) {
if (this.plugin.name === 'ogaquarium' && !this.plugin.recordsEndpoint) {
this.plugin.recordsEndpoint = '/api/plugins/ogaquarium/history';
}
this.schema = this.plugin.schema;
this.configData = this.pluginService.getPluginConfig(this.pluginName);
if (this.activeSubTab === 1 && this.plugin.recordsEndpoint) {

View File

@ -232,11 +232,14 @@ export class PluginService {
const manifestRequests = plugins.map(p =>
this.http.get<Partial<PluginManifest>>(`${apiUrl}/plugins/${p.name}/manifest`).pipe(
catchError(() => of({})),
map(extra => ({
...p,
...extra,
enabled: Boolean(p.enabled) // La base de datos es la única fuente de verdad para el estado de activación
}))
map(extra => {
const merged: PluginManifest = {
...p,
...extra,
enabled: Boolean(p.enabled) // La base de datos es la única fuente de verdad para el estado de activación
};
return this.applyPluginDefaults(merged);
})
)
);
@ -253,6 +256,49 @@ export class PluginService {
);
}
private applyPluginDefaults(plugin: PluginManifest): PluginManifest {
if (plugin.name === 'ogaquarium') {
if (!plugin.recordsEndpoint) {
plugin.recordsEndpoint = '/api/plugins/ogaquarium/history';
}
if (!plugin.recordsColumns || plugin.recordsColumns.length === 0) {
plugin.recordsColumns = [
{ key: 'dni', label: 'DNI Alumno', labelKey: 'ogaquarium.history.dni' },
{ key: 'client_name', label: 'Puesto', labelKey: 'ogaquarium.history.client' },
{ key: 'room_name', label: 'Aula', labelKey: 'ogaquarium.history.room' },
{ key: 'start_time', label: 'Inicio', labelKey: 'ogaquarium.history.start' },
{ key: 'end_time', label: 'Fin', labelKey: 'ogaquarium.history.end' },
{ key: 'duration_minutes', label: 'Minutos', labelKey: 'ogaquarium.history.duration' },
{ key: 'end_reason', label: 'Motivo Cierre', labelKey: 'ogaquarium.history.reason' }
];
}
if (!plugin.statusEndpoint) {
plugin.statusEndpoint = '/api/plugins/ogaquarium/status';
}
if (!plugin.titleKey) plugin.titleKey = 'ogaquarium.title';
if (!plugin.descriptionKey) plugin.descriptionKey = 'ogaquarium.description';
if (!plugin.badges || plugin.badges.length === 0) {
plugin.badges = [
{ status: 'FREE', type: 'success', icon: 'check_circle', label: 'Libre', labelKey: 'ogaquarium.badges.free', tooltip: 'Puesto disponible para asignar a un alumno', tooltipKey: 'ogaquarium.badges.free_tooltip' },
{ status: 'OCCUPIED', type: 'info', icon: 'person', label: 'Ocupado', labelKey: 'ogaquarium.badges.occupied', tooltip: 'Puesto con reserva activa en uso', tooltipKey: 'ogaquarium.badges.occupied_tooltip' },
{ status: 'EXPIRING', type: 'warning', icon: 'hourglass_top', label: 'A punto de expirar', labelKey: 'ogaquarium.badges.expiring', tooltip: 'Quedan menos de 5 minutos de tiempo de reserva', tooltipKey: 'ogaquarium.badges.expiring_tooltip' },
{ status: 'DISABLED', type: 'neutral', icon: 'block', label: 'Desactivado', labelKey: 'ogaquarium.badges.disabled', tooltip: 'Puesto fuera de servicio o en mantenimiento', tooltipKey: 'ogaquarium.badges.disabled_tooltip' }
];
}
if (plugin.schema && Array.isArray(plugin.schema)) {
for (const field of plugin.schema) {
if (!field.labelKey) {
field.labelKey = `ogaquarium.schema.${field.key}`;
}
if (!field.descriptionKey) {
field.descriptionKey = `ogaquarium.schema.${field.key}_desc`;
}
}
}
}
return plugin;
}
togglePlugin(name: string, enabled?: boolean): Observable<any> {
const apiUrl = this.configService.apiUrl;
if (!apiUrl) return of(null);
@ -265,6 +311,134 @@ export class PluginService {
const currentLang = lang || this.translateService.currentLang || this.translateService.defaultLang || 'es';
const apiUrl = this.configService.apiUrl;
// Catálogo base integrado para ogaquarium
const ogaquariumCatalogs: Record<string, Record<string, string>> = {
es: {
'ogaquarium.title': 'OpenGnSys Aquarium',
'ogaquarium.description': 'Control de acceso libre a aulas de ordenadores, gestión de reservas por puesto, avisos de tiempo y supervisión en tiempo real.',
'ogaquarium.commands.reserve': 'Reservar puesto',
'ogaquarium.commands.release': 'Liberar puesto',
'ogaquarium.commands.renew': 'Renovar tiempo',
'ogaquarium.commands.toggle_status': 'Activar / Desactivar puesto',
'ogaquarium.params.dni': 'DNI / Identificador del alumno',
'ogaquarium.params.duration': 'Tiempo de reserva (minutos)',
'ogaquarium.params.extra_minutes': 'Minutos adicionales a añadir',
'ogaquarium.badges.free': 'Libre',
'ogaquarium.badges.free_tooltip': 'Puesto disponible para asignar a un alumno',
'ogaquarium.badges.occupied': 'Ocupado',
'ogaquarium.badges.occupied_tooltip': 'Puesto con reserva activa en uso',
'ogaquarium.badges.expiring': 'A punto de expirar',
'ogaquarium.badges.expiring_tooltip': 'Quedan menos de 5 minutos de tiempo de reserva',
'ogaquarium.badges.disabled': 'Desactivado',
'ogaquarium.badges.disabled_tooltip': 'Puesto fuera de servicio o en mantenimiento',
'ogaquarium.history.dni': 'DNI Alumno',
'ogaquarium.history.client': 'Puesto',
'ogaquarium.history.room': 'Aula',
'ogaquarium.history.start': 'Inicio',
'ogaquarium.history.end': 'Fin',
'ogaquarium.history.duration': 'Minutos',
'ogaquarium.history.reason': 'Motivo Cierre',
'ogaquarium.dialog.reserve_title': 'Reservar puesto de acceso libre',
'ogaquarium.dialog.renew_title': 'Renovar tiempo de reserva',
'ogaquarium.dialog.release_confirm': '¿Seguro que deseas liberar este puesto? El equipo se reiniciará automáticamente hacia ogLive.',
'ogaquarium.dialog.disable_confirm': '¿Deseas cambiar el estado de activación de este puesto?',
'ogaquarium.schema.validation_mode': 'Modo de Validación',
'ogaquarium.schema.validation_mode_desc': 'Define si la validación se realiza contra la base de datos local (conserjería) o contra un servicio externo.',
'ogaquarium.schema.default_booking_time': 'Tiempo de reserva por defecto (minutos)',
'ogaquarium.schema.default_booking_time_desc': 'Duración inicial asignada a cada turno de alumno.',
'ogaquarium.schema.warning_time': 'Aviso previo de fin de turno (minutos)',
'ogaquarium.schema.warning_time_desc': 'Minutos de antelación con los que se mostrará el aviso en pantalla al alumno antes de reiniciar el equipo.',
'ogaquarium.schema.external_webhook_url': 'URL del validador externo (Modo EXTERNAL)',
'ogaquarium.schema.external_webhook_url_desc': 'Endpoint HTTP POST al que ogLive consultará si el modo de validación es EXTERNAL.',
'ogaquarium.schema.external_webhook_token': 'Token de autorización para Webhook externo',
'ogaquarium.schema.external_webhook_token_desc': 'Token Bearer opcional para la cabecera Authorization al invocar el validador externo.'
},
en: {
'ogaquarium.title': 'OpenGnSys Aquarium',
'ogaquarium.description': 'Open access computer lab control, workstation booking management, time notifications, and real-time monitoring.',
'ogaquarium.commands.reserve': 'Book workstation',
'ogaquarium.commands.release': 'Release workstation',
'ogaquarium.commands.renew': 'Extend time',
'ogaquarium.commands.toggle_status': 'Enable / Disable workstation',
'ogaquarium.params.dni': 'Student ID / DNI',
'ogaquarium.params.duration': 'Booking duration (minutes)',
'ogaquarium.params.extra_minutes': 'Extra minutes to add',
'ogaquarium.badges.free': 'Free',
'ogaquarium.badges.free_tooltip': 'Workstation available for assignment',
'ogaquarium.badges.occupied': 'Occupied',
'ogaquarium.badges.occupied_tooltip': 'Workstation currently in use with an active booking',
'ogaquarium.badges.expiring': 'Expiring soon',
'ogaquarium.badges.expiring_tooltip': 'Less than 5 minutes remaining on this booking',
'ogaquarium.badges.disabled': 'Disabled',
'ogaquarium.badges.disabled_tooltip': 'Workstation out of service or under maintenance',
'ogaquarium.history.dni': 'Student ID',
'ogaquarium.history.client': 'Workstation',
'ogaquarium.history.room': 'Room',
'ogaquarium.history.start': 'Start time',
'ogaquarium.history.end': 'End time',
'ogaquarium.history.duration': 'Minutes',
'ogaquarium.history.reason': 'End reason',
'ogaquarium.dialog.reserve_title': 'Book open access workstation',
'ogaquarium.dialog.renew_title': 'Extend booking duration',
'ogaquarium.dialog.release_confirm': 'Are you sure you want to release this workstation? The computer will reboot to ogLive.',
'ogaquarium.dialog.disable_confirm': 'Do you want to toggle the enabled status of this workstation?',
'ogaquarium.schema.validation_mode': 'Validation Mode',
'ogaquarium.schema.validation_mode_desc': 'Defines whether validation is performed against the local database (concierge) or an external institutional service.',
'ogaquarium.schema.default_booking_time': 'Default booking duration (minutes)',
'ogaquarium.schema.default_booking_time_desc': 'Initial duration assigned to each student session.',
'ogaquarium.schema.warning_time': 'Advance expiration warning (minutes)',
'ogaquarium.schema.warning_time_desc': 'Minutes before session end to display a warning to the student before rebooting.',
'ogaquarium.schema.external_webhook_url': 'External validator URL (EXTERNAL mode)',
'ogaquarium.schema.external_webhook_url_desc': 'HTTP POST endpoint that ogLive queries if validation mode is EXTERNAL.',
'ogaquarium.schema.external_webhook_token': 'External Webhook Authorization Token',
'ogaquarium.schema.external_webhook_token_desc': 'Optional Bearer token for the Authorization header when calling the external validator.'
},
cat: {
'ogaquarium.title': 'OpenGnSys Aquarium',
'ogaquarium.description': 'Control d\'accés lliure a aules d\'ordinadors, gestió de reserves per lloc, avisos de temps i supervisió en temps real.',
'ogaquarium.commands.reserve': 'Reservar lloc',
'ogaquarium.commands.release': 'Alliberar lloc',
'ogaquarium.commands.renew': 'Renovar temps',
'ogaquarium.commands.toggle_status': 'Activar / Desactivar lloc',
'ogaquarium.params.dni': 'DNI / Identificador de l\'alumne',
'ogaquarium.params.duration': 'Temps de reserva (minuts)',
'ogaquarium.params.extra_minutes': 'Minuts addicionals a afegir',
'ogaquarium.badges.free': 'Lliure',
'ogaquarium.badges.free_tooltip': 'Lloc disponible per assignar a un alumne',
'ogaquarium.badges.occupied': 'Ocupat',
'ogaquarium.badges.occupied_tooltip': 'Lloc amb reserva activa en ús',
'ogaquarium.badges.expiring': 'A punt d\'expirar',
'ogaquarium.badges.expiring_tooltip': 'Queden menys de 5 minuts de temps de reserva',
'ogaquarium.badges.disabled': 'Desactivat',
'ogaquarium.badges.disabled_tooltip': 'Lloc fora de servei o en manteniment',
'ogaquarium.history.dni': 'DNI Alumne',
'ogaquarium.history.client': 'Lloc',
'ogaquarium.history.room': 'Aula',
'ogaquarium.history.start': 'Inici',
'ogaquarium.history.end': 'Fi',
'ogaquarium.history.duration': 'Minuts',
'ogaquarium.history.reason': 'Motiu Tancament',
'ogaquarium.dialog.reserve_title': 'Reservar lloc d\'accés lliure',
'ogaquarium.dialog.renew_title': 'Renovar temps de reserva',
'ogaquarium.dialog.release_confirm': 'Segur que voleu alliberar aquest lloc? L\'equip es reiniciarà automàticament cap a ogLive.',
'ogaquarium.dialog.disable_confirm': 'Voleu canviar l\'estat d\'activació d\'aquest lloc?',
'ogaquarium.schema.validation_mode': 'Mode de Validació',
'ogaquarium.schema.validation_mode_desc': 'Defineix si la validació es realitza contra la base de dades local (consergeria) o contra un servei extern.',
'ogaquarium.schema.default_booking_time': 'Temps de reserva per defecte (minuts)',
'ogaquarium.schema.default_booking_time_desc': 'Durada inicial assignada a cada torn d\'alumne.',
'ogaquarium.schema.warning_time': 'Avís previ de fi de torn (minuts)',
'ogaquarium.schema.warning_time_desc': 'Minuts d\'antelació amb què es mostrarà l\'avís en pantalla a l\'alumne abans de reiniciar l\'equip.',
'ogaquarium.schema.external_webhook_url': 'URL del validador extern (Mode EXTERNAL)',
'ogaquarium.schema.external_webhook_url_desc': 'Endpoint HTTP POST al qual ogLive consultarà si el mode de validació és EXTERNAL.',
'ogaquarium.schema.external_webhook_token': 'Token d\'autorització per a Webhook extern',
'ogaquarium.schema.external_webhook_token_desc': 'Token Bearer opcional per a la capçalera Authorization en invocar el validador extern.'
}
};
if (ogaquariumCatalogs[currentLang]) {
this.translateService.setTranslation(currentLang, ogaquariumCatalogs[currentLang], true);
}
for (const plugin of this.allPlugins) {
// 1. Si el plugin declara i18n directamente en el manifest, lo inyectamos
if (plugin.i18n && typeof plugin.i18n === 'object') {

View File

@ -1579,5 +1579,43 @@
"youMustSelectAtLeastOne1": "Has de seleccionar almenys un dia de la setmana",
"youMustSelectAtLeastOne2": "Has de seleccionar almenys un mes",
"youMustSpecifyStartDate": "Has d'especificar data d'inici i data de fi",
"youWantToPropagateTheParametersOf": "Vols propagar els paràmetres de xarxa (ogLive, repositori, menú, plantilla PXE, perfil de maquinari) a tots els clients d'aquesta unitat organitzativa?"
"youWantToPropagateTheParametersOf": "Vols propagar els paràmetres de xarxa (ogLive, repositori, menú, plantilla PXE, perfil de maquinari) a tots els clients d'aquesta unitat organitzativa?",
"ogaquarium.title": "OpenGnSys Aquarium",
"ogaquarium.description": "Control d'accés lliure a aules d'ordinadors, gestió de reserves per lloc, avisos de temps i supervisió en temps real.",
"ogaquarium.commands.reserve": "Reservar lloc",
"ogaquarium.commands.release": "Alliberar lloc",
"ogaquarium.commands.renew": "Renovar temps",
"ogaquarium.commands.toggle_status": "Activar / Desactivar lloc",
"ogaquarium.params.dni": "DNI / Identificador de l'alumne",
"ogaquarium.params.duration": "Temps de reserva (minuts)",
"ogaquarium.params.extra_minutes": "Minuts addicionals a afegir",
"ogaquarium.badges.free": "Lliure",
"ogaquarium.badges.free_tooltip": "Lloc disponible per assignar a un alumne",
"ogaquarium.badges.occupied": "Ocupat",
"ogaquarium.badges.occupied_tooltip": "Lloc amb reserva activa en ús",
"ogaquarium.badges.expiring": "A punt d'expirar",
"ogaquarium.badges.expiring_tooltip": "Queden menys de 5 minuts de temps de reserva",
"ogaquarium.badges.disabled": "Desactivat",
"ogaquarium.badges.disabled_tooltip": "Lloc fora de servei o en manteniment",
"ogaquarium.history.dni": "DNI Alumne",
"ogaquarium.history.client": "Lloc",
"ogaquarium.history.room": "Aula",
"ogaquarium.history.start": "Inici",
"ogaquarium.history.end": "Fi",
"ogaquarium.history.duration": "Minuts",
"ogaquarium.history.reason": "Motiu Tancament",
"ogaquarium.dialog.reserve_title": "Reservar lloc d'accés lliure",
"ogaquarium.dialog.renew_title": "Renovar temps de reserva",
"ogaquarium.dialog.release_confirm": "Segur que voleu alliberar aquest lloc? L'equip es reiniciarà automàticament cap a ogLive.",
"ogaquarium.dialog.disable_confirm": "Voleu canviar l'estat d'activació d'aquest lloc?",
"ogaquarium.schema.validation_mode": "Mode de Validació",
"ogaquarium.schema.validation_mode_desc": "Defineix si la validació es realitza contra la base de dades local (consergeria) o contra un servei extern.",
"ogaquarium.schema.default_booking_time": "Temps de reserva per defecte (minuts)",
"ogaquarium.schema.default_booking_time_desc": "Durada inicial assignada a cada torn d'alumne.",
"ogaquarium.schema.warning_time": "Avís previ de fi de torn (minuts)",
"ogaquarium.schema.warning_time_desc": "Minuts d'antelació amb què es mostrarà l'avís en pantalla a l'alumne abans de reiniciar l'equip.",
"ogaquarium.schema.external_webhook_url": "URL del validador extern (Mode EXTERNAL)",
"ogaquarium.schema.external_webhook_url_desc": "Endpoint HTTP POST al qual ogLive consultarà si el mode de validació és EXTERNAL.",
"ogaquarium.schema.external_webhook_token": "Token d'autorització per a Webhook extern",
"ogaquarium.schema.external_webhook_token_desc": "Token Bearer opcional per a la capçalera Authorization en invocar el validador extern."
}

View File

@ -1579,5 +1579,43 @@
"youMustSelectAtLeastOne1": "You must select at least one day of the week",
"youMustSelectAtLeastOne2": "You must select at least one month",
"youMustSpecifyStartDate": "You must specify start date and end date",
"youWantToPropagateTheParametersOf": "Do you want to propagate the network parameters (ogLive, repository, menu, PXE template, hardware profile) to all clients in this organizational unit?"
"youWantToPropagateTheParametersOf": "Do you want to propagate the network parameters (ogLive, repository, menu, PXE template, hardware profile) to all clients in this organizational unit?",
"ogaquarium.title": "OpenGnSys Aquarium",
"ogaquarium.description": "Open access computer lab control, workstation booking management, time notifications, and real-time monitoring.",
"ogaquarium.commands.reserve": "Book workstation",
"ogaquarium.commands.release": "Release workstation",
"ogaquarium.commands.renew": "Extend time",
"ogaquarium.commands.toggle_status": "Enable / Disable workstation",
"ogaquarium.params.dni": "Student ID / DNI",
"ogaquarium.params.duration": "Booking duration (minutes)",
"ogaquarium.params.extra_minutes": "Extra minutes to add",
"ogaquarium.badges.free": "Free",
"ogaquarium.badges.free_tooltip": "Workstation available for assignment",
"ogaquarium.badges.occupied": "Occupied",
"ogaquarium.badges.occupied_tooltip": "Workstation currently in use with an active booking",
"ogaquarium.badges.expiring": "Expiring soon",
"ogaquarium.badges.expiring_tooltip": "Less than 5 minutes remaining on this booking",
"ogaquarium.badges.disabled": "Disabled",
"ogaquarium.badges.disabled_tooltip": "Workstation out of service or under maintenance",
"ogaquarium.history.dni": "Student ID",
"ogaquarium.history.client": "Workstation",
"ogaquarium.history.room": "Room",
"ogaquarium.history.start": "Start time",
"ogaquarium.history.end": "End time",
"ogaquarium.history.duration": "Minutes",
"ogaquarium.history.reason": "End reason",
"ogaquarium.dialog.reserve_title": "Book open access workstation",
"ogaquarium.dialog.renew_title": "Extend booking duration",
"ogaquarium.dialog.release_confirm": "Are you sure you want to release this workstation? The computer will reboot to ogLive.",
"ogaquarium.dialog.disable_confirm": "Do you want to toggle the enabled status of this workstation?",
"ogaquarium.schema.validation_mode": "Validation Mode",
"ogaquarium.schema.validation_mode_desc": "Defines whether validation is performed against the local database (concierge) or an external institutional service.",
"ogaquarium.schema.default_booking_time": "Default booking duration (minutes)",
"ogaquarium.schema.default_booking_time_desc": "Initial duration assigned to each student session.",
"ogaquarium.schema.warning_time": "Advance expiration warning (minutes)",
"ogaquarium.schema.warning_time_desc": "Minutes before session end to display a warning to the student before rebooting.",
"ogaquarium.schema.external_webhook_url": "External validator URL (EXTERNAL mode)",
"ogaquarium.schema.external_webhook_url_desc": "HTTP POST endpoint that ogLive queries if validation mode is EXTERNAL.",
"ogaquarium.schema.external_webhook_token": "External Webhook Authorization Token",
"ogaquarium.schema.external_webhook_token_desc": "Optional Bearer token for the Authorization header when calling the external validator."
}

View File

@ -1579,5 +1579,43 @@
"youMustSelectAtLeastOne1": "Debe seleccionar al menos un día de la semana",
"youMustSelectAtLeastOne2": "Debe seleccionar al menos un mes",
"youMustSpecifyStartDate": "Debe especificar fecha de inicio y fecha de fin",
"youWantToPropagateTheParametersOf": "¿Desea propagar los parámetros de red (ogLive, repositorio, menú, plantilla PXE, perfil de hardware) a todos los clientes de esta unidad organizativa?"
"youWantToPropagateTheParametersOf": "¿Desea propagar los parámetros de red (ogLive, repositorio, menú, plantilla PXE, perfil de hardware) a todos los clientes de esta unidad organizativa?",
"ogaquarium.title": "OpenGnSys Aquarium",
"ogaquarium.description": "Control de acceso libre a aulas de ordenadores, gestión de reservas por puesto, avisos de tiempo y supervisión en tiempo real.",
"ogaquarium.commands.reserve": "Reservar puesto",
"ogaquarium.commands.release": "Liberar puesto",
"ogaquarium.commands.renew": "Renovar tiempo",
"ogaquarium.commands.toggle_status": "Activar / Desactivar puesto",
"ogaquarium.params.dni": "DNI / Identificador del alumno",
"ogaquarium.params.duration": "Tiempo de reserva (minutos)",
"ogaquarium.params.extra_minutes": "Minutos adicionales a añadir",
"ogaquarium.badges.free": "Libre",
"ogaquarium.badges.free_tooltip": "Puesto disponible para asignar a un alumno",
"ogaquarium.badges.occupied": "Ocupado",
"ogaquarium.badges.occupied_tooltip": "Puesto con reserva activa en uso",
"ogaquarium.badges.expiring": "A punto de expirar",
"ogaquarium.badges.expiring_tooltip": "Quedan menos de 5 minutos de tiempo de reserva",
"ogaquarium.badges.disabled": "Desactivado",
"ogaquarium.badges.disabled_tooltip": "Puesto fuera de servicio o en mantenimiento",
"ogaquarium.history.dni": "DNI Alumno",
"ogaquarium.history.client": "Puesto",
"ogaquarium.history.room": "Aula",
"ogaquarium.history.start": "Inicio",
"ogaquarium.history.end": "Fin",
"ogaquarium.history.duration": "Minutos",
"ogaquarium.history.reason": "Motivo Cierre",
"ogaquarium.dialog.reserve_title": "Reservar puesto de acceso libre",
"ogaquarium.dialog.renew_title": "Renovar tiempo de reserva",
"ogaquarium.dialog.release_confirm": "¿Seguro que deseas liberar este puesto? El equipo se reiniciará automáticamente hacia ogLive.",
"ogaquarium.dialog.disable_confirm": "¿Deseas cambiar el estado de activación de este puesto?",
"ogaquarium.schema.validation_mode": "Modo de Validación",
"ogaquarium.schema.validation_mode_desc": "Define si la validación se realiza contra la base de datos local (conserjería) o contra un servicio externo.",
"ogaquarium.schema.default_booking_time": "Tiempo de reserva por defecto (minutos)",
"ogaquarium.schema.default_booking_time_desc": "Duración inicial asignada a cada turno de alumno.",
"ogaquarium.schema.warning_time": "Aviso previo de fin de turno (minutos)",
"ogaquarium.schema.warning_time_desc": "Minutos de antelación con los que se mostrará el aviso en pantalla al alumno antes de reiniciar el equipo.",
"ogaquarium.schema.external_webhook_url": "URL del validador externo (Modo EXTERNAL)",
"ogaquarium.schema.external_webhook_url_desc": "Endpoint HTTP POST al que ogLive consultará si el modo de validación es EXTERNAL.",
"ogaquarium.schema.external_webhook_token": "Token de autorización para Webhook externo",
"ogaquarium.schema.external_webhook_token_desc": "Token Bearer opcional para la cabecera Authorization al invocar el validador externo."
}