@asteby/metacore-runtime-react 46.2.1 → 46.2.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,11 @@
1
1
  # @asteby/metacore-runtime-react
2
2
 
3
+ ## 46.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 97f77eb: Una relación muchos-a-muchos distingue «sin permiso» y un error de carga de una lista vacía, igual que la subtabla de uno-a-muchos.
8
+
3
9
  ## 46.2.1
4
10
 
5
11
  ### Patch Changes
@@ -341,6 +341,9 @@ function ManyToManyRelation({ kind, through, references, foreignKey, referencesK
341
341
  const [pivotRows, setPivotRows] = useState([]);
342
342
  const [loading, setLoading] = useState(true);
343
343
  const [syncing, setSyncing] = useState(false);
344
+ // Same distinction as the 1:N sub-table (PIT-045): a 403 is not "no rows",
345
+ // and an empty pivot is not "sin permiso".
346
+ const [fetchErrorStatus, setFetchErrorStatus] = useState(null);
344
347
  // Canonical path: SDK options resolver. Only fires when no legacy
345
348
  // override is set. The hook is a no-op when `useResolver` is false.
346
349
  const resolved = useOptionsResolver({
@@ -366,6 +369,7 @@ function ManyToManyRelation({ kind, through, references, foreignKey, referencesK
366
369
  tasks.push(api.get(legacyTargetPath));
367
370
  const results = await Promise.all(tasks);
368
371
  const pivotRes = results[0];
372
+ setFetchErrorStatus(null);
369
373
  if (pivotRes.data.success)
370
374
  setPivotRows(pivotRes.data.data || []);
371
375
  let cursor = 1;
@@ -384,6 +388,7 @@ function ManyToManyRelation({ kind, through, references, foreignKey, referencesK
384
388
  }
385
389
  catch (err) {
386
390
  console.error('DynamicRelation m2m fetch error', err);
391
+ setFetchErrorStatus(err?.response?.status ?? 0);
387
392
  }
388
393
  finally {
389
394
  setLoading(false);
@@ -449,5 +454,7 @@ function ManyToManyRelation({ kind, through, references, foreignKey, referencesK
449
454
  }
450
455
  // eslint-disable-next-line react-hooks/exhaustive-deps
451
456
  }, [api, canCreate, canDelete, fetchPivotAndMeta, useResolver, resolved, foreignKey, filtersKey, onChange, parentId, pivotIndex, pivotPath, refKey, selectedIds, syncing]);
452
- return (_jsxs("div", { className: className, "data-relation-kind": kind, "data-relation-through": through, "data-relation-references": references, children: [labels.title && (_jsx("div", { className: "pb-3", children: _jsx("h3", { className: "text-sm font-medium", children: labels.title }) })), (loading || (useResolver && resolved.loading)) ? (_jsx(Skeleton, { className: "h-10 w-full" })) : options.length === 0 ? (_jsx("div", { className: "text-center text-sm text-muted-foreground py-8 border rounded-md bg-muted/30", children: labels.emptyState })) : (_jsx(MultiSelect, { options: options, selected: selectedIds, onChange: handleChange, placeholder: labels.selectPlaceholder, searchPlaceholder: labels.selectSearchPlaceholder, emptyMessage: labels.selectEmpty }))] }));
457
+ return (_jsxs("div", { className: className, "data-relation-kind": kind, "data-relation-through": through, "data-relation-references": references, children: [labels.title && (_jsx("div", { className: "pb-3", children: _jsx("h3", { className: "text-sm font-medium", children: labels.title }) })), (loading || (useResolver && resolved.loading)) ? (_jsx(Skeleton, { className: "h-10 w-full" })) : fetchErrorStatus !== null ? (_jsx("div", { className: "text-center text-sm text-muted-foreground py-8 border rounded-md bg-muted/30", children: fetchErrorStatus === 403
458
+ ? (labels.forbiddenState ?? 'Sin permiso para ver estos registros.')
459
+ : (labels.errorState ?? 'No se pudieron cargar los registros relacionados.') })) : options.length === 0 ? (_jsx("div", { className: "text-center text-sm text-muted-foreground py-8 border rounded-md bg-muted/30", children: labels.emptyState })) : (_jsx(MultiSelect, { options: options, selected: selectedIds, onChange: handleChange, placeholder: labels.selectPlaceholder, searchPlaceholder: labels.selectSearchPlaceholder, emptyMessage: labels.selectEmpty }))] }));
453
460
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asteby/metacore-runtime-react",
3
- "version": "46.2.1",
3
+ "version": "46.2.2",
4
4
  "description": "React runtime for metacore hosts — renders addon contributions dynamically",
5
5
  "repository": {
6
6
  "type": "git",
@@ -718,6 +718,9 @@ function ManyToManyRelation({
718
718
  const [pivotRows, setPivotRows] = useState<any[]>([])
719
719
  const [loading, setLoading] = useState(true)
720
720
  const [syncing, setSyncing] = useState(false)
721
+ // Same distinction as the 1:N sub-table (PIT-045): a 403 is not "no rows",
722
+ // and an empty pivot is not "sin permiso".
723
+ const [fetchErrorStatus, setFetchErrorStatus] = useState<number | null>(null)
721
724
 
722
725
  // Canonical path: SDK options resolver. Only fires when no legacy
723
726
  // override is set. The hook is a no-op when `useResolver` is false.
@@ -744,6 +747,7 @@ function ManyToManyRelation({
744
747
  if (!useResolver) tasks.push(api.get(legacyTargetPath))
745
748
  const results = await Promise.all(tasks)
746
749
  const pivotRes = results[0] as { data: ApiResponse<any[]> }
750
+ setFetchErrorStatus(null)
747
751
  if (pivotRes.data.success) setPivotRows(pivotRes.data.data || [])
748
752
  let cursor = 1
749
753
  if (!targetMeta) {
@@ -759,6 +763,7 @@ function ManyToManyRelation({
759
763
  }
760
764
  } catch (err) {
761
765
  console.error('DynamicRelation m2m fetch error', err)
766
+ setFetchErrorStatus((err as { response?: { status?: number } })?.response?.status ?? 0)
762
767
  } finally {
763
768
  setLoading(false)
764
769
  }
@@ -840,6 +845,12 @@ function ManyToManyRelation({
840
845
 
841
846
  {(loading || (useResolver && resolved.loading)) ? (
842
847
  <Skeleton className="h-10 w-full" />
848
+ ) : fetchErrorStatus !== null ? (
849
+ <div className="text-center text-sm text-muted-foreground py-8 border rounded-md bg-muted/30">
850
+ {fetchErrorStatus === 403
851
+ ? (labels.forbiddenState ?? 'Sin permiso para ver estos registros.')
852
+ : (labels.errorState ?? 'No se pudieron cargar los registros relacionados.')}
853
+ </div>
843
854
  ) : options.length === 0 ? (
844
855
  <div className="text-center text-sm text-muted-foreground py-8 border rounded-md bg-muted/30">
845
856
  {labels.emptyState}