Sin resultados para esa búsqueda.
)}
- {filteredProcesses.map((p) => {
- const group = groups.find((g) => g.id === p.groupId)
- return (
-
{/* Tag cloud (wow): visible cuando hay >= 3 tags distintos */}
{cloud.length >= 3 && (
@@ -575,59 +502,89 @@ function HomeView({
)}
- {/* Header sección grupos */}
-
-
- {settings.groupLabel}s
-
-
- {groups.length}
-
-
+ {/* Grupos org → área */}
+ {orgGroups.map(({ orgId, orgName, processes: orgProcesses }) => {
+ const isCollapsed = collapsedOrgs.has(orgId)
+ const areaGroups = getAreaGroups(orgProcesses)
- {/* Grid de grupos */}
-
- {groups.map((group) => {
- const groupProcesses = visibleProcesses.filter((p) => p.groupId === group.id)
- const lastUpdated = groupProcesses.length > 0
- ? Math.max(...groupProcesses.map((p) => p.updatedAt))
- : null
- return (
-
-
onNavigateToGroup(group.id)}
+ return (
+
+ {/* Header de org — colapsable */}
+
- )
- })}
- createGroup(name, user!.id)}
- />
-
+
- {/* Sin clasificar */}
- {unclassifiedProcesses.length > 0 && (
-
+ )
+ })}
+
+ {/* Empty state: admin sin procesos */}
+ {orgGroups.length === 0 && (
+
+
+
+ Tu biblioteca está vacía
+
+
+ Importá tu primer BPMN para empezar
+
+
+
)}
- >
+
)}
{/* Vista cliente: lista plana de procesos (sin grupos, RLS garantiza que solo ven los suyos) */}
@@ -774,10 +731,8 @@ function GroupView({
export function LibraryPage() {
const navigate = useNavigate()
- const { load, processes, groups, settings, isLoading } = useLibraryStore()
+ const { load, processes } = useLibraryStore()
const { user, isProfileLoaded } = useAuth()
- const searchStr = useRouterState({ select: (s) => s.location.search })
- const orgParam = new URLSearchParams(searchStr).get('org')
const [view, setView] = useState<'home' | 'group'>('home')
const [activeGroupId, setActiveGroupId] = useState
(null)
const [transitioning, setTransitioning] = useState(false)
@@ -789,25 +744,6 @@ export function LibraryPage() {
load()
}, [load, user?.id])
- // Cuando la biblioteca cargó con ?org=, hacer scroll al grupo que contiene ese org
- useEffect(() => {
- if (!orgParam || isLoading || processes.length === 0) return
- const proc = processes.find((p) => p.orgId === orgParam)
- if (!proc?.groupId) return
- requestAnimationFrame(() => {
- document.getElementById(`group-${proc.groupId}`)?.scrollIntoView({ behavior: 'smooth', block: 'start' })
- })
- }, [orgParam, isLoading, processes])
-
- function navigateToGroup(groupId: string | null) {
- setTransitioning(true)
- setTimeout(() => {
- setActiveGroupId(groupId)
- setView('group')
- setTransitioning(false)
- }, 150)
- }
-
function navigateHome() {
setTransitioning(true)
setTimeout(() => {
@@ -817,12 +753,8 @@ export function LibraryPage() {
}, 150)
}
- function handleImport(groupId?: string) {
- if (groupId) {
- navigate({ to: '/import', search: { groupId } })
- } else {
- navigate({ to: '/import' })
- }
+ function handleImport() {
+ navigate({ to: '/import' })
}
// Esperar a que syncProfileFromDB complete antes de renderizar UI rol-dependiente.
@@ -848,8 +780,8 @@ export function LibraryPage() {
const currentUserId = user.id
const currentUserName = user.name
- const totalGroups = groups.length
const isClientRole = user.platformRole === 'client_editor' || user.platformRole === 'client_viewer'
+ const orgCount = new Set(processes.map(p => p.orgId).filter(Boolean)).size
return (
@@ -860,7 +792,10 @@ export function LibraryPage() {
Biblioteca de procesos
- {processes.length} proceso{processes.length !== 1 ? 's' : ''} · {totalGroups} {settings.groupLabel.toLowerCase()}{totalGroups !== 1 ? 's' : ''}
+ {isClientRole
+ ? `${processes.length} proceso${processes.length !== 1 ? 's' : ''}`
+ : `${processes.length} proceso${processes.length !== 1 ? 's' : ''} · ${orgCount} cliente${orgCount !== 1 ? 's' : ''}`
+ }
@@ -888,16 +823,18 @@ export function LibraryPage() {
-
{!isClientRole && (
+ )}
+ {!isClientRole && (
+