-
- {c.name}
- {c.trade_name && ({c.trade_name})}
-
-
- {c.tin &&
{c.tin}}
-
+ return React.useMemo
[]>(
+ () => [
+ // Identidad + estado + metadatos (columna compuesta)
+ {
+ id: "customer",
+ header: ({ column }) => (
+
+ ),
+ accessorFn: (row) => row.name, // para ordenar/buscar por nombre
+ enableHiding: false,
+ size: 140,
+ minSize: 120,
+ cell: ({ row }) => {
+ const c = row.original;
+ const isCompany = String(c.is_company).toLowerCase() === "true";
+ return (
+
+
+ {initials(c.name)}
+
+
+
+ {" "}
+ {c.name}
+ {c.trade_name && ({c.trade_name})}
+
+
+ {c.tin && {c.tin}}
+
+
-
- );
+ );
+ },
},
- },
- // Contacto (emails, teléfonos, web)
- {
- id: "contact",
- header: ({ column }) => (
-
- ),
- accessorFn: (r) => `${r.email_primary} ${r.phone_primary} ${r.mobile_primary} ${r.website}`,
- size: 140,
- minSize: 120,
- cell: ({ row }) =>
,
- },
+ // Contacto (emails, teléfonos, web)
+ {
+ id: "contact",
+ header: ({ column }) => (
+
+ ),
+ accessorFn: (r) => `${r.email_primary} ${r.phone_primary} ${r.mobile_primary} ${r.website}`,
+ size: 140,
+ minSize: 120,
+ cell: ({ row }) =>
,
+ },
- // Dirección (múltiples campos en bloque)
- {
- id: "address",
- header: t("pages.list.grid_columns.address"),
- accessorFn: (r) =>
- `${r.street} ${r.street2} ${r.city} ${r.postal_code} ${r.province} ${r.country}`,
- size: 140,
- minSize: 120,
- cell: ({ row }) =>
,
- },
+ // Dirección (múltiples campos en bloque)
+ {
+ id: "address",
+ header: t("pages.list.grid_columns.address"),
+ accessorFn: (r) =>
+ `${r.street} ${r.street2} ${r.city} ${r.postal_code} ${r.province} ${r.country}`,
+ size: 140,
+ minSize: 120,
+ cell: ({ row }) =>
,
+ },
- // Acciones
- {
- id: "actions",
- header: ({ column }) => (
-
- ),
- size: 64,
- minSize: 64,
- enableSorting: false,
- enableHiding: false,
- cell: ({ row }) => {
- const customer = row.original;
- const { website, email_primary } = customer;
- return (
-
-
-
-
-
-
-
-
- Actions
-
- onView?.(customer)}>Open
- onEdit?.(customer)}>Edit
-
- window.open(safeHttp(website), "_blank")}>
- Visit website
-
- navigator.clipboard.writeText(email_primary)}>
- Copy email
-
-
- onDelete?.(customer)}
- >
- Delete
-
-
-
+ // Acciones
+ {
+ id: "actions",
+ header: ({ column }) => (
+
+ ),
+ size: 64,
+ minSize: 64,
+ enableSorting: false,
+ enableHiding: false,
+ cell: ({ row }) => {
+ const customer = row.original;
+ const { website, email_primary } = customer;
+ return (
+
+
+
+
+
+
+
+
+ Actions
+
+ onView?.(customer)}>Open
+ onEdit?.(customer)}>Edit
+
+ window.open(safeHttp(website), "_blank")}>
+ Visit website
+
+ navigator.clipboard.writeText(email_primary)}>
+ Copy email
+
+
+ onDelete?.(customer)}
+ >
+ Delete
+
+
+
+
-
- );
+ );
+ },
},
- },
- ], [t, onEdit, onView, onDelete]);
+ ],
+ [t, onEdit, onView, onDelete]
+ );
}
diff --git a/packages/rdx-criteria/src/criteria-to-sequelize-converter.ts b/packages/rdx-criteria/src/criteria-to-sequelize-converter.ts
index b02303c8..f5d09496 100644
--- a/packages/rdx-criteria/src/criteria-to-sequelize-converter.ts
+++ b/packages/rdx-criteria/src/criteria-to-sequelize-converter.ts
@@ -17,7 +17,23 @@ export class CriteriaToSequelizeConverter implements ICriteriaToOrmConverter {
this.applyOrder(options, criteria, mappings, params);
this.applyPagination(options, criteria);
- return options;
+ const normalizedOrder = Array.isArray(options.order)
+ ? options.order
+ : options.order
+ ? [options.order]
+ : [];
+
+ const normalizedInclude = Array.isArray(options.include)
+ ? options.include
+ : options.include
+ ? [options.include]
+ : [];
+
+ return {
+ ...options,
+ order: normalizedOrder,
+ include: normalizedInclude,
+ };
}
/** Filtros simples (sin anidaciones complejas) */
diff --git a/packages/rdx-criteria/src/utils.ts b/packages/rdx-criteria/src/utils.ts
index ced92e0a..72efe76d 100644
--- a/packages/rdx-criteria/src/utils.ts
+++ b/packages/rdx-criteria/src/utils.ts
@@ -1,4 +1,4 @@
-import { FindOptions } from "sequelize";
+import type { FindOptions } from "sequelize";
// orderItem puede ser: ['campo', 'ASC'|'DESC']
// o [Sequelize.literal('score'), 'DESC']
diff --git a/packages/rdx-ui/src/components/layout/app-sidebar.tsx b/packages/rdx-ui/src/components/layout/app-sidebar.tsx
index 0bbf8b7a..3d366098 100644
--- a/packages/rdx-ui/src/components/layout/app-sidebar.tsx
+++ b/packages/rdx-ui/src/components/layout/app-sidebar.tsx
@@ -1,31 +1,3 @@
-import {
- AudioWaveform,
- Command,
- FileCheckIcon,
- Frame,
- GalleryVerticalEnd,
- HomeIcon,
- MapIcon,
- PieChart,
-} from "lucide-react";
-
-import {
- BarChartIcon,
- CameraIcon,
- ClipboardListIcon,
- DatabaseIcon,
- FileCodeIcon,
- FileIcon,
- FileTextIcon,
- FolderIcon,
- HelpCircleIcon,
- LayoutDashboardIcon,
- ListIcon,
- SettingsIcon,
- UsersIcon,
-} from "lucide-react";
-import * as React from "react";
-
import {
Sidebar,
SidebarContent,
@@ -33,6 +5,31 @@ import {
SidebarHeader,
SidebarRail,
} from "@repo/shadcn-ui/components";
+import {
+ AudioWaveform,
+ BarChartIcon,
+ CameraIcon,
+ ClipboardListIcon,
+ Command,
+ DatabaseIcon,
+ FileCheckIcon,
+ FileCodeIcon,
+ FileIcon,
+ FileTextIcon,
+ FolderIcon,
+ Frame,
+ GalleryVerticalEnd,
+ HelpCircleIcon,
+ HomeIcon,
+ LayoutDashboardIcon,
+ ListIcon,
+ MapIcon,
+ PieChart,
+ SettingsIcon,
+ UsersIcon,
+} from "lucide-react";
+import type * as React from "react";
+
import { NavMain } from "./nav-main.tsx";
import { NavSecondary } from "./nav-secondary.tsx";
import { NavUser } from "./nav-user.tsx";
@@ -203,7 +200,7 @@ const data2 = {
items: [
{
title: "Listado de proformas",
- url: "/customer-proforma",
+ url: "/proformas",
},
{
title: "Enviar a Veri*Factu",
@@ -243,8 +240,8 @@ const data2 = {
export function AppSidebar({ ...props }: React.ComponentProps
) {
return (
-
-
+
+
@@ -252,7 +249,7 @@ export function AppSidebar({ ...props }: React.ComponentProps) {
-
+
diff --git a/packages/shadcn-ui/src/styles/globals.css b/packages/shadcn-ui/src/styles/globals.css
index 4f37eb2d..1a70f7b0 100644
--- a/packages/shadcn-ui/src/styles/globals.css
+++ b/packages/shadcn-ui/src/styles/globals.css
@@ -65,7 +65,7 @@
--shadow-xl: 1px 1px 6px 0px hsl(0 0% 0% / 0.1), 1px 8px 10px -1px hsl(0 0% 0% / 0.1);
--shadow-2xl: 1px 1px 6px 0px hsl(0 0% 0% / 0.25);
--tracking-normal: 0rem;
- --spacing: 0.20rem;
+ --spacing: 0.22rem;
}
.dark {