@asteby/metacore-runtime-react 7.1.0 → 7.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @asteby/metacore-runtime-react
2
2
 
3
+ ## 7.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - c00d7f9: Fix DynamicTable horizontal scrollbar appearing mid-card.
8
+
9
+ `<Table>` from `@asteby/metacore-ui` ships its own `overflow-x-auto` wrapper sized to content height. Combined with DynamicTable's outer `flex-1 min-h-0 overflow-auto` card, the inner scrollbar drew at the bottom of the rendered rows (mid-card) instead of pinned to the card's bottom edge — wide tables felt visually broken when there were few rows.
10
+
11
+ Pass `noWrapper` to opt out of shadcn's inner wrapper. The outer SDK wrapper now owns the scroll; horizontal scrollbar pins to the bottom of the card as expected.
12
+
13
+ ## 7.1.1
14
+
15
+ ### Patch Changes
16
+
17
+ - 76d4b58: Align SDK dialogs to the kernel's `/dynamic/:model` path namespace.
18
+
19
+ `<DynamicRecordDialog>`, `<ExportDialog>` and `<ImportDialog>` were posting to `/data/:model[/...]`, which had no kernel handler — apps that didn't ship their own `handlers/export.go` got 404s the moment a user clicked Export, Import or "Descargar plantilla".
20
+
21
+ Switches every hardcoded path from `/data/${model}` to `/dynamic/${model}`. Pairs with `metacore-kernel v0.5.0`, which exposes the canonical `/dynamic/:model/export`, `/dynamic/:model/export/template`, `/dynamic/:model/import`, `/dynamic/:model/import/validate` endpoints — so the SDK toolbar now wires straight to the kernel out of the box, no app glue.
22
+
3
23
  ## 7.1.0
4
24
 
5
25
  ### Minor Changes
@@ -94,7 +94,7 @@ export function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId,
94
94
  else {
95
95
  const recordEndpoint = endpoint
96
96
  ? `${endpoint}/${recordId}`
97
- : `/data/${model}/${recordId}`;
97
+ : `/dynamic/${model}/${recordId}`;
98
98
  const recRes = await api.get(recordEndpoint);
99
99
  if (cancelled)
100
100
  return;
@@ -142,13 +142,13 @@ export function DynamicRecordDialog({ open, onOpenChange, mode, model, recordId,
142
142
  try {
143
143
  let res;
144
144
  if (isCreate) {
145
- const createEndpoint = endpoint || `/data/${model}`;
145
+ const createEndpoint = endpoint || `/dynamic/${model}`;
146
146
  res = await api.post(createEndpoint, formValues);
147
147
  }
148
148
  else {
149
149
  const updateEndpoint = endpoint
150
150
  ? `${endpoint}/${recordId}`
151
- : `/data/${model}/${recordId}`;
151
+ : `/dynamic/${model}/${recordId}`;
152
152
  res = await api.put(updateEndpoint, formValues);
153
153
  }
154
154
  if (res.data?.success !== false) {
@@ -110,7 +110,7 @@ export function ExportDialog({ open, onOpenChange, model, metadata, currentFilte
110
110
  }
111
111
  });
112
112
  }
113
- const response = await api.get(`/data/${model}/export`, {
113
+ const response = await api.get(`/dynamic/${model}/export`, {
114
114
  params,
115
115
  responseType: 'blob',
116
116
  validateStatus: () => true,
@@ -36,7 +36,7 @@ export function ImportDialog({ open, onOpenChange, model, metadata, onImported,
36
36
  };
37
37
  const handleDownloadTemplate = async () => {
38
38
  try {
39
- const response = await api.get(`/data/${model}/export/template`, {
39
+ const response = await api.get(`/dynamic/${model}/export/template`, {
40
40
  responseType: 'blob',
41
41
  });
42
42
  const url = window.URL.createObjectURL(response.data);
@@ -61,7 +61,7 @@ export function ImportDialog({ open, onOpenChange, model, metadata, onImported,
61
61
  try {
62
62
  const formData = new FormData();
63
63
  formData.append('file', file);
64
- const res = await api.post(`/data/${model}/import/validate`, formData, {
64
+ const res = await api.post(`/dynamic/${model}/import/validate`, formData, {
65
65
  headers: { 'Content-Type': 'multipart/form-data' },
66
66
  });
67
67
  const data = res.data?.data ?? res.data;
@@ -87,7 +87,7 @@ export function ImportDialog({ open, onOpenChange, model, metadata, onImported,
87
87
  try {
88
88
  const formData = new FormData();
89
89
  formData.append('file', file);
90
- const res = await api.post(`/data/${model}/import`, formData, {
90
+ const res = await api.post(`/dynamic/${model}/import`, formData, {
91
91
  headers: { 'Content-Type': 'multipart/form-data' },
92
92
  onUploadProgress: (progressEvent) => {
93
93
  if (progressEvent.total) {
@@ -539,12 +539,12 @@ export function DynamicTable({ model, endpoint, enableUrlSync = true, hiddenColu
539
539
  });
540
540
  const TableSkeleton = () => (_jsx(_Fragment, { children: Array.from({ length: 5 }).map((_, i) => (_jsxs(TableRow, { className: "hover:bg-transparent", children: [_jsx(TableCell, { className: "py-3 w-10", children: _jsx(Skeleton, { className: "h-4 w-4" }) }), _jsx(TableCell, { className: "py-3", children: _jsx(Skeleton, { className: "h-4 w-[70%]" }) }), _jsx(TableCell, { className: "py-3", children: _jsx(Skeleton, { className: "h-4 w-[50%]" }) }), _jsx(TableCell, { className: "py-3", children: _jsx(Skeleton, { className: "h-4 w-[60%]" }) }), _jsx(TableCell, { className: "py-3 w-16", children: _jsx(Skeleton, { className: "h-6 w-6" }) })] }, `skeleton-${i}`))) }));
541
541
  if (loading) {
542
- return (_jsxs("div", { className: 'flex flex-col h-full min-h-0 w-full', children: [_jsx("div", { className: 'pb-4 shrink-0', children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Skeleton, { className: "h-9 w-[280px]" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Skeleton, { className: "h-9 w-9" }), _jsx(Skeleton, { className: "h-9 w-[70px]" })] })] }) }), _jsx("div", { className: 'flex-1 min-h-0 overflow-auto border rounded-md bg-card', children: _jsxs(Table, { className: 'min-w-max w-full', children: [_jsx(TableHeader, { className: 'sticky top-0 z-10', children: _jsxs(TableRow, { className: 'border-b-0 hover:bg-transparent', children: [_jsx(TableHead, { className: 'bg-card border-b h-10 w-10', children: _jsx(Skeleton, { className: "h-4 w-4" }) }), _jsx(TableHead, { className: 'bg-card border-b h-10', children: _jsx(Skeleton, { className: "h-4 w-16" }) }), _jsx(TableHead, { className: 'bg-card border-b h-10', children: _jsx(Skeleton, { className: "h-4 w-14" }) }), _jsx(TableHead, { className: 'bg-card border-b h-10', children: _jsx(Skeleton, { className: "h-4 w-20" }) }), _jsx(TableHead, { className: 'bg-card border-b h-10 w-16', children: _jsx(Skeleton, { className: "h-4 w-12" }) })] }) }), _jsx(TableBody, { children: _jsx(TableSkeleton, {}) })] }) })] }));
542
+ return (_jsxs("div", { className: 'flex flex-col h-full min-h-0 w-full', children: [_jsx("div", { className: 'pb-4 shrink-0', children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx(Skeleton, { className: "h-9 w-[280px]" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Skeleton, { className: "h-9 w-9" }), _jsx(Skeleton, { className: "h-9 w-[70px]" })] })] }) }), _jsx("div", { className: 'flex-1 min-h-0 overflow-auto border rounded-md bg-card', children: _jsxs(Table, { noWrapper: true, className: "min-w-max w-full", children: [_jsx(TableHeader, { className: 'sticky top-0 z-10', children: _jsxs(TableRow, { className: 'border-b-0 hover:bg-transparent', children: [_jsx(TableHead, { className: 'bg-card border-b h-10 w-10', children: _jsx(Skeleton, { className: "h-4 w-4" }) }), _jsx(TableHead, { className: 'bg-card border-b h-10', children: _jsx(Skeleton, { className: "h-4 w-16" }) }), _jsx(TableHead, { className: 'bg-card border-b h-10', children: _jsx(Skeleton, { className: "h-4 w-14" }) }), _jsx(TableHead, { className: 'bg-card border-b h-10', children: _jsx(Skeleton, { className: "h-4 w-20" }) }), _jsx(TableHead, { className: 'bg-card border-b h-10 w-16', children: _jsx(Skeleton, { className: "h-4 w-12" }) })] }) }), _jsx(TableBody, { children: _jsx(TableSkeleton, {}) })] }) })] }));
543
543
  }
544
544
  if (!metadata) {
545
545
  return _jsx("div", { className: "text-center text-muted-foreground py-8", children: "Error al cargar la configuraci\u00F3n de la tabla." });
546
546
  }
547
- return (_jsxs(OptionsContext.Provider, { value: { optionsMap }, children: [_jsxs("div", { className: 'flex flex-col h-full min-h-0 w-full', children: [_jsx("div", { className: 'pb-4 shrink-0', children: _jsx(DataTableToolbar, { table: table, searchPlaceholder: metadata.searchPlaceholder || 'Buscar...', filters: filters, activeFilters: dynamicFilters, onDynamicFilterChange: handleDynamicFilterChange, dateFilter: { value: dateRange, onChange: setDateRange, placeholder: 'Filtrar por fecha' }, perPageOptions: metadata.perPageOptions, onRefresh: handleRefresh, isLoading: loadingData, selectedCount: Object.keys(rowSelection).length, onBulkDelete: () => setShowBulkDeleteConfirm(true), extraActions: _jsxs(_Fragment, { children: [metadata.canExport && (_jsxs(Button, { variant: "outline", size: "sm", className: "h-8", onClick: () => setExportOpen(true), children: [_jsx(Download, { className: "h-4 w-4 mr-1" }), " Exportar"] })), metadata.canImport && (_jsxs(Button, { variant: "outline", size: "sm", className: "h-8", onClick: () => setImportOpen(true), children: [_jsx(Upload, { className: "h-4 w-4 mr-1" }), " Importar"] }))] }) }) }), _jsx("div", { className: 'flex-1 min-h-0 overflow-auto border rounded-md bg-card', children: _jsxs(Table, { className: 'min-w-max w-full', children: [_jsx(TableHeader, { className: 'sticky top-0 z-10', children: table.getHeaderGroups().map((headerGroup) => (_jsx(TableRow, { className: 'border-b-0 hover:bg-transparent', children: headerGroup.headers.map((header) => {
547
+ return (_jsxs(OptionsContext.Provider, { value: { optionsMap }, children: [_jsxs("div", { className: 'flex flex-col h-full min-h-0 w-full', children: [_jsx("div", { className: 'pb-4 shrink-0', children: _jsx(DataTableToolbar, { table: table, searchPlaceholder: metadata.searchPlaceholder || 'Buscar...', filters: filters, activeFilters: dynamicFilters, onDynamicFilterChange: handleDynamicFilterChange, dateFilter: { value: dateRange, onChange: setDateRange, placeholder: 'Filtrar por fecha' }, perPageOptions: metadata.perPageOptions, onRefresh: handleRefresh, isLoading: loadingData, selectedCount: Object.keys(rowSelection).length, onBulkDelete: () => setShowBulkDeleteConfirm(true), extraActions: _jsxs(_Fragment, { children: [metadata.canExport && (_jsxs(Button, { variant: "outline", size: "sm", className: "h-8", onClick: () => setExportOpen(true), children: [_jsx(Download, { className: "h-4 w-4 mr-1" }), " Exportar"] })), metadata.canImport && (_jsxs(Button, { variant: "outline", size: "sm", className: "h-8", onClick: () => setImportOpen(true), children: [_jsx(Upload, { className: "h-4 w-4 mr-1" }), " Importar"] }))] }) }) }), _jsx("div", { className: 'flex-1 min-h-0 overflow-auto border rounded-md bg-card', children: _jsxs(Table, { noWrapper: true, className: "min-w-max w-full", children: [_jsx(TableHeader, { className: 'sticky top-0 z-10', children: table.getHeaderGroups().map((headerGroup) => (_jsx(TableRow, { className: 'border-b-0 hover:bg-transparent', children: headerGroup.headers.map((header) => {
548
548
  const isActionsColumn = header.id === 'actions';
549
549
  return (_jsx(TableHead, { colSpan: header.colSpan, style: header.column.columnDef.size ? { width: header.column.columnDef.size } : undefined, className: cn('bg-card border-b h-10', isActionsColumn && 'sticky right-0 z-20 bg-card shadow-[-2px_0_5px_-2px_rgba(0,0,0,0.1)]'), children: header.isPlaceholder ? null : flexRender(header.column.columnDef.header, header.getContext()) }, header.id));
550
550
  }) }, headerGroup.id))) }), _jsx(TableBody, { children: loadingData && data.length === 0 ? (_jsx(TableSkeleton, {})) : table.getRowModel().rows?.length ? (table.getRowModel().rows.map((row) => (_jsx(TableRow, { "data-state": row.getIsSelected() && 'selected', children: row.getVisibleCells().map((cell) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asteby/metacore-runtime-react",
3
- "version": "7.1.0",
3
+ "version": "7.1.2",
4
4
  "description": "React runtime for metacore hosts — renders addon contributions dynamically",
5
5
  "repository": {
6
6
  "type": "git",
@@ -172,7 +172,7 @@ export function DynamicRecordDialog({
172
172
  } else {
173
173
  const recordEndpoint = endpoint
174
174
  ? `${endpoint}/${recordId}`
175
- : `/data/${model}/${recordId}`
175
+ : `/dynamic/${model}/${recordId}`
176
176
 
177
177
  const recRes = await api.get(recordEndpoint)
178
178
  if (cancelled) return
@@ -223,12 +223,12 @@ export function DynamicRecordDialog({
223
223
  try {
224
224
  let res
225
225
  if (isCreate) {
226
- const createEndpoint = endpoint || `/data/${model}`
226
+ const createEndpoint = endpoint || `/dynamic/${model}`
227
227
  res = await api.post(createEndpoint, formValues)
228
228
  } else {
229
229
  const updateEndpoint = endpoint
230
230
  ? `${endpoint}/${recordId}`
231
- : `/data/${model}/${recordId}`
231
+ : `/dynamic/${model}/${recordId}`
232
232
  res = await api.put(updateEndpoint, formValues)
233
233
  }
234
234
 
@@ -158,7 +158,7 @@ export function ExportDialog({
158
158
  })
159
159
  }
160
160
 
161
- const response = await api.get(`/data/${model}/export`, {
161
+ const response = await api.get(`/dynamic/${model}/export`, {
162
162
  params,
163
163
  responseType: 'blob',
164
164
  validateStatus: () => true,
@@ -87,7 +87,7 @@ export function ImportDialog({
87
87
 
88
88
  const handleDownloadTemplate = async () => {
89
89
  try {
90
- const response = await api.get(`/data/${model}/export/template`, {
90
+ const response = await api.get(`/dynamic/${model}/export/template`, {
91
91
  responseType: 'blob',
92
92
  })
93
93
  const url = window.URL.createObjectURL(response.data)
@@ -114,7 +114,7 @@ export function ImportDialog({
114
114
  const formData = new FormData()
115
115
  formData.append('file', file)
116
116
 
117
- const res = await api.post(`/data/${model}/import/validate`, formData, {
117
+ const res = await api.post(`/dynamic/${model}/import/validate`, formData, {
118
118
  headers: { 'Content-Type': 'multipart/form-data' },
119
119
  })
120
120
 
@@ -143,7 +143,7 @@ export function ImportDialog({
143
143
  const formData = new FormData()
144
144
  formData.append('file', file)
145
145
 
146
- const res = await api.post(`/data/${model}/import`, formData, {
146
+ const res = await api.post(`/dynamic/${model}/import`, formData, {
147
147
  headers: { 'Content-Type': 'multipart/form-data' },
148
148
  onUploadProgress: (progressEvent: { loaded: number; total?: number }) => {
149
149
  if (progressEvent.total) {
@@ -602,7 +602,7 @@ export function DynamicTable({
602
602
  </div>
603
603
  </div>
604
604
  <div className='flex-1 min-h-0 overflow-auto border rounded-md bg-card'>
605
- <Table className='min-w-max w-full'>
605
+ <Table noWrapper className="min-w-max w-full">
606
606
  <TableHeader className='sticky top-0 z-10'>
607
607
  <TableRow className='border-b-0 hover:bg-transparent'>
608
608
  <TableHead className='bg-card border-b h-10 w-10'><Skeleton className="h-4 w-4" /></TableHead>
@@ -656,7 +656,7 @@ export function DynamicTable({
656
656
  />
657
657
  </div>
658
658
  <div className='flex-1 min-h-0 overflow-auto border rounded-md bg-card'>
659
- <Table className='min-w-max w-full'>
659
+ <Table noWrapper className="min-w-max w-full">
660
660
  <TableHeader className='sticky top-0 z-10'>
661
661
  {table.getHeaderGroups().map((headerGroup: HeaderGroup<any>) => (
662
662
  <TableRow key={headerGroup.id} className='border-b-0 hover:bg-transparent'>