fix: version 3.1.2 -- Panel sin datos de proyectos para usuarios sin ese modulo
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
# Changelog - project.linkedcorp.net
|
# Changelog - project.linkedcorp.net
|
||||||
|
|
||||||
|
## [3.1.2] - 2026-10-23
|
||||||
|
### Fixed
|
||||||
|
- Panel: un usuario sin el módulo Proyectos ya no ve KPIs ni detalle de proyectos; ve solo una
|
||||||
|
bienvenida. El backend bloquea `/api/dashboard/*` con 403 sin ese módulo.
|
||||||
|
|
||||||
## [3.1.1] - 2026-10-23
|
## [3.1.1] - 2026-10-23
|
||||||
### Fixed
|
### Fixed
|
||||||
- El popup de actualización quedaba en "Reiniciando servicios" hasta agotar los 10 minutos: el
|
- El popup de actualización quedaba en "Reiniciando servicios" hasta agotar los 10 minutos: el
|
||||||
|
|||||||
@@ -176,8 +176,6 @@ y recargar. Pendiente verificar el flujo completo en un despliegue autorizado; n
|
|||||||
roles fijos codificados).
|
roles fijos codificados).
|
||||||
- Integracion IA (API Claude) — ideas: plan de proyecto generado desde una descripcion, resumen
|
- Integracion IA (API Claude) — ideas: plan de proyecto generado desde una descripcion, resumen
|
||||||
semanal del Panel. Clave cifrada en `system_settings` como el SMTP; la IA solo sugiere.
|
semanal del Panel. Clave cifrada en `system_settings` como el SMTP; la IA solo sugiere.
|
||||||
- Panel: con el modulo Proyectos deshabilitado, los KPIs del Panel siguen mostrando datos de
|
|
||||||
proyectos del usuario (revisar si se deben ocultar).
|
|
||||||
- Notificaciones por email/WhatsApp (hoy: solo in-app).
|
- Notificaciones por email/WhatsApp (hoy: solo in-app).
|
||||||
- Job programado para detectar actividades vencidas/por vencer (hoy: solo se notifica al asignar).
|
- Job programado para detectar actividades vencidas/por vencer (hoy: solo se notifica al asignar).
|
||||||
- DatePicker: sigue usando `<input type="date">` nativo (simplificacion deliberada del MVP).
|
- DatePicker: sigue usando `<input type="date">` nativo (simplificacion deliberada del MVP).
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "project-linkedcorp-backend",
|
"name": "project-linkedcorp-backend",
|
||||||
"version": "3.1.1",
|
"version": "3.1.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/server.js",
|
"main": "src/server.js",
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { Router } from 'express';
|
import { Router } from 'express';
|
||||||
import { requireAuth } from '../../middleware/auth.js';
|
import { requireAuth } from '../../middleware/auth.js';
|
||||||
|
import { requireModule } from '../../middleware/modules.js';
|
||||||
import { getSummary, getCalendar } from './controller.js';
|
import { getSummary, getCalendar } from './controller.js';
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.use(requireAuth);
|
router.use(requireAuth);
|
||||||
|
router.use(requireModule('projects'));
|
||||||
router.get('/summary', getSummary);
|
router.get('/summary', getSummary);
|
||||||
router.get('/calendar', getCalendar);
|
router.get('/calendar', getCalendar);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "project-linkedcorp-frontend",
|
"name": "project-linkedcorp-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "3.1.1",
|
"version": "3.1.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ export const messages = {
|
|||||||
user_modules: 'Módulos',
|
user_modules: 'Módulos',
|
||||||
user_modules_hint: 'Marca los módulos que este usuario puede usar. Lo que no esté marcado no aparece en su menú y el sistema le niega el acceso.',
|
user_modules_hint: 'Marca los módulos que este usuario puede usar. Lo que no esté marcado no aparece en su menú y el sistema le niega el acceso.',
|
||||||
user_modules_saved: 'Módulos actualizados. El usuario verá el cambio al recargar.',
|
user_modules_saved: 'Módulos actualizados. El usuario verá el cambio al recargar.',
|
||||||
|
dashboard_no_projects_module: 'Bienvenido. Usa el menú de la izquierda para ir a los módulos que tienes habilitados.',
|
||||||
nav_projects: 'Proyectos',
|
nav_projects: 'Proyectos',
|
||||||
nav_organization: 'Organizacion',
|
nav_organization: 'Organizacion',
|
||||||
nav_config: 'Configuracion',
|
nav_config: 'Configuracion',
|
||||||
@@ -527,6 +528,7 @@ export const messages = {
|
|||||||
user_modules: 'Modules',
|
user_modules: 'Modules',
|
||||||
user_modules_hint: 'Check the modules this user can use. Unchecked modules are hidden from their menu and access is denied.',
|
user_modules_hint: 'Check the modules this user can use. Unchecked modules are hidden from their menu and access is denied.',
|
||||||
user_modules_saved: 'Modules updated. The user will see the change after reloading.',
|
user_modules_saved: 'Modules updated. The user will see the change after reloading.',
|
||||||
|
dashboard_no_projects_module: 'Welcome. Use the menu on the left to open the modules enabled for you.',
|
||||||
nav_projects: 'Projects',
|
nav_projects: 'Projects',
|
||||||
nav_organization: 'Organization',
|
nav_organization: 'Organization',
|
||||||
nav_config: 'Settings',
|
nav_config: 'Settings',
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { useState } from 'react';
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useUi } from '../../context/ui-context.jsx';
|
import { useUi } from '../../context/ui-context.jsx';
|
||||||
import { useAuth } from '../../context/auth-context.jsx';
|
import { useAuth } from '../../context/auth-context.jsx';
|
||||||
|
import { hasModule } from '../../utils/modules.js';
|
||||||
import { useAsync } from '../../hooks/useAsync.js';
|
import { useAsync } from '../../hooks/useAsync.js';
|
||||||
import { getSummary } from '../../services/dashboard.js';
|
import { getSummary } from '../../services/dashboard.js';
|
||||||
import { KpiCard } from '../../components/KpiCard.jsx';
|
import { KpiCard } from '../../components/KpiCard.jsx';
|
||||||
@@ -78,7 +79,23 @@ function ActivityRows({ activities, onOpen }) {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Todo el Panel son datos de proyectos: sin ese modulo se muestra solo la bienvenida, sin llamar
|
||||||
|
// a /dashboard (que el backend tambien bloquea con 403).
|
||||||
export default function DashboardPage() {
|
export default function DashboardPage() {
|
||||||
|
const { t } = useUi();
|
||||||
|
const { user } = useAuth();
|
||||||
|
if (!hasModule(user, 'projects')) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2 className="page-title mt-0">{t('dashboard_title')}</h2>
|
||||||
|
<p className="text-muted">{t('dashboard_no_projects_module')}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return <ProjectsDashboard />;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProjectsDashboard() {
|
||||||
const { t } = useUi();
|
const { t } = useUi();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
|||||||
Reference in New Issue
Block a user