From 1f21a605ccec96398b92d76b21bc6b31b9f95f64 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 8 Oct 2026 17:16:59 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20a=C3=B1adir=20funcionalidad=20de=20cola?= =?UTF-8?q?pso=20y=20expansi=C3=B3n=20en=20la=20barra=20lateral?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/global.css | 87 +++++++++++++++++-- docs/componentes-de-interfaz.md | 10 +++ .../src/web/components/workspace-sidebar.tsx | 63 +++++++++++--- modules/core/src/common/locales/en.json | 4 +- modules/core/src/common/locales/es.json | 4 +- 5 files changed, 150 insertions(+), 18 deletions(-) diff --git a/apps/web/src/global.css b/apps/web/src/global.css index 15df732..319bb77 100644 --- a/apps/web/src/global.css +++ b/apps/web/src/global.css @@ -12,6 +12,7 @@ body { :root { --desk-app-background: #000; --desk-content-background: #f7f9fb; + --desk-header-background: #fff; --desk-sidebar-background: #0e282c; --desk-sidebar-top: #0c252a; --desk-sidebar-bottom: #102c30; @@ -27,6 +28,8 @@ body { --desk-radius-md: 10px; --desk-radius-shell: 20px; --desk-sidebar-width: 228px; + --desk-sidebar-inset: 20px; + --desk-sidebar-collapsed-width: 72px; --desk-header-height: 88px; --desk-search-height: 41px; --desk-nav-height: 48px; @@ -59,9 +62,12 @@ body:has(.desk-workspace) { background: var(--desk-app-background); } .desk-sidebar { + display: flex; + flex-direction: column; + min-height: 0; width: var(--desk-sidebar-width); flex: 0 0 var(--desk-sidebar-width); - overflow-y: auto; + overflow: hidden; background: linear-gradient( 180deg, var(--desk-sidebar-top), @@ -71,6 +77,7 @@ body:has(.desk-workspace) { color: var(--desk-sidebar-text); } .desk-brand { + flex-shrink: 0; display: flex; align-items: center; gap: 13px; @@ -88,10 +95,13 @@ body:has(.desk-workspace) { flex-shrink: 0; } .desk-company-rail { + flex: 1; + min-height: 0; + overflow-y: auto; display: flex; flex-direction: column; gap: 2px; - padding: 28px 13px 24px 26px; + padding: 28px var(--desk-sidebar-inset) 24px; } .desk-space-button { width: 100%; @@ -137,7 +147,7 @@ body:has(.desk-workspace) { .desk-rail-separator { height: 1px; background: rgb(255 255 255 / 12%); - margin: 26px -3px 25px -5px; + margin: 26px 0 25px; flex-shrink: 0; } .desk-catalog-navigation { @@ -156,6 +166,58 @@ body:has(.desk-workspace) { background: rgb(255 255 255 / 8%); color: white; } +.desk-sidebar-footer { + flex-shrink: 0; + display: grid; + gap: 2px; + padding: 12px var(--desk-sidebar-inset) 20px; + border-top: 1px solid rgb(255 255 255 / 12%); +} +.desk-sidebar-toggle[aria-expanded="true"] > svg { + transform: rotate(180deg); +} +.desk-catalog-navigation > button { + gap: 10px; +} +.desk-catalog-navigation > button > svg { + width: 18px; + height: 18px; + flex-shrink: 0; +} +@media (min-width: 768px) { + .desk-sidebar[data-collapsed="true"] { + width: var(--desk-sidebar-collapsed-width); + flex-basis: var(--desk-sidebar-collapsed-width); + } + .desk-sidebar[data-collapsed="true"] .desk-brand { + justify-content: center; + padding-left: 0; + } + .desk-sidebar[data-collapsed="true"] .desk-brand > span, + .desk-sidebar[data-collapsed="true"] .desk-space-button > span, + .desk-sidebar[data-collapsed="true"] .desk-nav-chevron, + .desk-sidebar[data-collapsed="true"] .desk-catalog-navigation > button > span { + display: none; + } + .desk-sidebar[data-collapsed="true"] .desk-company-rail { + padding: 28px 12px 12px; + } + .desk-sidebar[data-collapsed="true"] .desk-sidebar-footer { + padding: 12px 12px 20px; + } + .desk-sidebar[data-collapsed="true"] .desk-space-button { + justify-content: center; + gap: 0; + padding: 0; + } + .desk-sidebar[data-collapsed="true"] .desk-catalog-navigation { + padding-left: 0; + } + .desk-sidebar[data-collapsed="true"] .desk-catalog-navigation > button { + justify-content: center; + padding-inline: 0; + } +} .desk-workspace-content { flex: 1; min-width: 0; @@ -167,7 +229,9 @@ body:has(.desk-workspace) { align-items: center; gap: 28px; min-height: var(--desk-header-height); - padding: 31px 30px 16px 17px; + padding: 15px 30px 15px 17px; + background: var(--desk-header-background); + border-bottom: 1px solid var(--desk-border); color: var(--desk-navy); } .desk-search { @@ -561,7 +625,7 @@ body:has(.desk-workspace) { flex-basis: auto; } .desk-brand { - padding: 20px; + padding: 2px; } .desk-company-rail { flex-direction: row; @@ -645,3 +709,16 @@ body:has(.desk-workspace) { padding: 12px; } } + +@media (max-width: 767px) { + .desk-company-rail { + flex: none; + overflow-y: visible; + } + .desk-sidebar-footer { + padding: 10px 16px; + } + .desk-sidebar-toggle { + display: none; + } +} diff --git a/docs/componentes-de-interfaz.md b/docs/componentes-de-interfaz.md index dcb9f87..63aeb57 100644 --- a/docs/componentes-de-interfaz.md +++ b/docs/componentes-de-interfaz.md @@ -155,3 +155,13 @@ servicio de notificaciones. El perfil usa disclosure nativo con foco visible y conserva las acciones de identidad y selección de idioma. No hay primitives Avatar ni DropdownMenu instalados; el avatar muestra iniciales del usuario real, sin inventar foto ni cargo. Configuración abre un FormDialog con las acciones existentes. + +La sidebar global permite contraerse en escritorio de 228px a 72px mediante +«Contraer menú» / «Expandir menú». Conserva iconos, nombres accesibles y títulos +de ayuda también para compañías y subcatálogos. La navegación se desplaza por +separado, manteniendo Configuración y el control de anchura en el pie visible. +En móvil se conserva la navegación horizontal existente. + +El menú expandido y su pie comparten márgenes horizontales de 20px mediante +`--desk-sidebar-inset`. El header global usa `--desk-header-background` (#FFFFFF), +con un borde inferior de 1px en `--desk-border`, sobre el contenido #F7F9FB. diff --git a/modules/companies/src/web/components/workspace-sidebar.tsx b/modules/companies/src/web/components/workspace-sidebar.tsx index da1ea56..f782150 100644 --- a/modules/companies/src/web/components/workspace-sidebar.tsx +++ b/modules/companies/src/web/components/workspace-sidebar.tsx @@ -1,14 +1,19 @@ import { Button } from "@repo/shadcn-ui/components/button"; import { + BoxIcon, Building2Icon, ChevronRightIcon, DatabaseIcon, HomeIcon, + KeyRoundIcon, + LayersIcon, + LayoutTemplateIcon, SettingsIcon, TicketIcon, WrenchIcon, } from "@repo/shadcn-ui/lib/icons"; import type { ComponentProps } from "react"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; import type { WorkspaceContent } from "./workspace-content"; @@ -35,9 +40,10 @@ export function WorkspaceSidebar({ const { t: resourceTranslation } = useTranslation("resources"); const { t: assetTranslation } = useTranslation("assets"); const { t: accessTranslation } = useTranslation("access"); + const [collapsed, setCollapsed] = useState(false); return ( -