@asteby/metacore-runtime-react 20.1.0 → 20.1.1

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,38 @@
1
1
  # @asteby/metacore-runtime-react
2
2
 
3
+ ## 20.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - eb6c65f: Kanban responsive board + cards truncate; sidebar nav lights the default view on a view-less landing
8
+
9
+ Two frontend UX fixes reported against the ops board.
10
+
11
+ **Kanban now adapts instead of overflowing (`@asteby/metacore-runtime-react`).**
12
+ `DynamicKanban` lanes were fixed-width (`w-72 shrink-0`), so with 4+ stages the
13
+ last lane was clipped off-viewport and long card text was cut by the card edge
14
+ with no ellipsis. Lanes are now responsive — `flex-1 min-w-[220px] max-w-[320px]`
15
+ — so they shrink to fit the available width and only scroll horizontally when
16
+ they genuinely can't fit. Card titles now `line-clamp-2 break-words` and the
17
+ secondary field rows carry `min-w-0` so long values ellipsize _inside_ the card
18
+ rather than being clipped by the border. The optimistic drag-to-move (PUT
19
+ `<base>/<id>`) is untouched.
20
+
21
+ **Sidebar nav active-state on the default/view-less landing (`@asteby/metacore-ui`,
22
+ `@asteby/metacore-starter-core`).** Landing on a model's bare list surface
23
+ (e.g. `/m/github_issues?per_page=15` — a transient param, no `view`) lit
24
+ _neither_ the "Tablero" (`?view=kanban`) nor the "Issues" (`?view=list`) nav
25
+ item, because the empty view bucket matched neither sibling's explicit view.
26
+ `checkIsActive` now treats the empty/`view=list`/`view=table` buckets as
27
+ "default-equivalent": a view-less current URL lights the list/default item while
28
+ the board (`?view=kanban`, never a default bucket) stays mutually exclusive. The
29
+ prior Board-vs-Issues exclusivity, `f_` filter and transient (page/sort/search)
30
+ behaviour are all preserved (18 matcher tests, +4 new). Ported to the
31
+ `starter-core` scaffold's embedded copy for parity.
32
+
33
+ - Updated dependencies [eb6c65f]
34
+ - @asteby/metacore-ui@2.6.1
35
+
3
36
  ## 20.1.0
4
37
 
5
38
  ### Minor Changes
@@ -284,7 +284,7 @@ export function DynamicKanban({ model, endpoint, refreshTrigger, onCardClick, pa
284
284
  }
285
285
  }, [api, endpoint, groupByKey, model, records, stageOfCard, t, transitions]);
286
286
  if (loading) {
287
- return (_jsx("div", { className: "flex gap-4 overflow-x-auto p-1", children: [0, 1, 2, 3].map((i) => (_jsxs("div", { className: "w-72 shrink-0 space-y-3", children: [_jsx(Skeleton, { className: "h-8 w-full" }), _jsx(Skeleton, { className: "h-24 w-full" }), _jsx(Skeleton, { className: "h-24 w-full" })] }, i))) }));
287
+ return (_jsx("div", { className: "flex gap-4 overflow-x-auto p-1", children: [0, 1, 2, 3].map((i) => (_jsxs("div", { className: "min-w-[220px] max-w-[320px] flex-1 space-y-3", children: [_jsx(Skeleton, { className: "h-8 w-full" }), _jsx(Skeleton, { className: "h-24 w-full" }), _jsx(Skeleton, { className: "h-24 w-full" })] }, i))) }));
288
288
  }
289
289
  if (!metadata || !groupByKey || stages.length === 0) {
290
290
  return (_jsx("div", { className: "rounded-md border border-dashed p-8 text-center text-sm text-muted-foreground", children: t('kanban.noStages', {
@@ -322,7 +322,7 @@ function KanbanLane({ stage, count, isDark, dimmed, disabled, children }) {
322
322
  const headerStyle = generateBadgeStyles(stage.color || optionColor(stage.key), {
323
323
  isDark,
324
324
  });
325
- return (_jsxs("div", { ref: setNodeRef, className: "flex w-72 shrink-0 flex-col rounded-lg border bg-muted/30 transition-opacity", style: {
325
+ return (_jsxs("div", { ref: setNodeRef, className: "flex min-w-[220px] max-w-[320px] flex-1 flex-col rounded-lg border bg-muted/30 transition-opacity", style: {
326
326
  opacity: dimmed ? 0.45 : 1,
327
327
  outline: isOver && !disabled ? '2px solid var(--ring, #3b82f6)' : 'none',
328
328
  outlineOffset: 2,
@@ -333,14 +333,14 @@ function KanbanCard({ card, titleCol, fieldCols, actions, locale, timeZone, curr
333
333
  id: String(card.id),
334
334
  });
335
335
  const visibleActions = actions.filter((a) => isActionAllowedForRowState(a, card));
336
- return (_jsx(Card, { ref: setNodeRef, ...attributes, ...listeners, className: "cursor-grab active:cursor-grabbing border-border/70 shadow-sm", style: { opacity: isDragging ? 0.4 : 1 }, onClick: () => onClick?.(card), "data-card-id": String(card.id), children: _jsxs(CardContent, { className: "space-y-1.5 p-3", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsx("div", { className: "min-w-0 flex-1 text-sm font-medium leading-snug", children: titleCol ? (_jsx(ActivityValueRenderer, { value: card[titleCol.key], col: titleCol, locale: locale, timeZone: timeZone, currency: currency })) : (_jsx("span", { className: "truncate", children: String(card.id) })) }), visibleActions.length > 0 && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0 -mr-1 -mt-1",
336
+ return (_jsx(Card, { ref: setNodeRef, ...attributes, ...listeners, className: "cursor-grab active:cursor-grabbing border-border/70 shadow-sm", style: { opacity: isDragging ? 0.4 : 1 }, onClick: () => onClick?.(card), "data-card-id": String(card.id), children: _jsxs(CardContent, { className: "space-y-1.5 p-3", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsx("div", { className: "line-clamp-2 min-w-0 flex-1 break-words text-sm font-medium leading-snug", children: titleCol ? (_jsx(ActivityValueRenderer, { value: card[titleCol.key], col: titleCol, locale: locale, timeZone: timeZone, currency: currency })) : (_jsx("span", { className: "truncate", children: String(card.id) })) }), visibleActions.length > 0 && (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 shrink-0 -mr-1 -mt-1",
337
337
  // Don't start a drag / card click from the menu button.
338
338
  onPointerDown: (e) => e.stopPropagation(), onClick: (e) => e.stopPropagation(), children: _jsx(MoreHorizontal, { className: "h-4 w-4" }) }) }), _jsx(DropdownMenuContent, { align: "end", onClick: (e) => e.stopPropagation(), children: visibleActions.map((a) => (_jsxs(DropdownMenuItem, { onClick: (e) => {
339
339
  e.stopPropagation();
340
340
  onAction(a, card);
341
- }, children: [_jsx(DynamicIcon, { name: a.icon || 'Zap', className: "mr-2 h-4 w-4" }), a.label] }, a.key))) })] }))] }), fieldCols.map((col) => (_jsxs("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [_jsxs("span", { className: "shrink-0 opacity-70", children: [col.label, ":"] }), _jsx("span", { className: "min-w-0 truncate", children: _jsx(ActivityValueRenderer, { value: card[col.key], col: col, locale: locale, timeZone: timeZone, currency: currency }) })] }, col.key)))] }) }));
341
+ }, children: [_jsx(DynamicIcon, { name: a.icon || 'Zap', className: "mr-2 h-4 w-4" }), a.label] }, a.key))) })] }))] }), fieldCols.map((col) => (_jsxs("div", { className: "flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground", children: [_jsxs("span", { className: "shrink-0 opacity-70", children: [col.label, ":"] }), _jsx("span", { className: "min-w-0 truncate", children: _jsx(ActivityValueRenderer, { value: card[col.key], col: col, locale: locale, timeZone: timeZone, currency: currency }) })] }, col.key)))] }) }));
342
342
  }
343
343
  // Static preview rendered inside the DragOverlay (no dnd hooks, no menu).
344
344
  function CardPreview({ card, titleCol, fieldCols, locale, timeZone, currency, }) {
345
- return (_jsx(Card, { className: "w-72 cursor-grabbing border-primary/40 shadow-lg", children: _jsxs(CardContent, { className: "space-y-1.5 p-3", children: [_jsx("div", { className: "text-sm font-medium leading-snug", children: titleCol ? (_jsx(ActivityValueRenderer, { value: card[titleCol.key], col: titleCol, locale: locale, timeZone: timeZone, currency: currency })) : (String(card.id)) }), fieldCols.map((col) => (_jsxs("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [_jsxs("span", { className: "shrink-0 opacity-70", children: [col.label, ":"] }), _jsx("span", { className: "min-w-0 truncate", children: _jsx(ActivityValueRenderer, { value: card[col.key], col: col, locale: locale, timeZone: timeZone, currency: currency }) })] }, col.key)))] }) }));
345
+ return (_jsx(Card, { className: "w-72 cursor-grabbing border-primary/40 shadow-lg", children: _jsxs(CardContent, { className: "space-y-1.5 p-3", children: [_jsx("div", { className: "line-clamp-2 break-words text-sm font-medium leading-snug", children: titleCol ? (_jsx(ActivityValueRenderer, { value: card[titleCol.key], col: titleCol, locale: locale, timeZone: timeZone, currency: currency })) : (String(card.id)) }), fieldCols.map((col) => (_jsxs("div", { className: "flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground", children: [_jsxs("span", { className: "shrink-0 opacity-70", children: [col.label, ":"] }), _jsx("span", { className: "min-w-0 truncate", children: _jsx(ActivityValueRenderer, { value: card[col.key], col: col, locale: locale, timeZone: timeZone, currency: currency }) })] }, col.key)))] }) }));
346
346
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asteby/metacore-runtime-react",
3
- "version": "20.1.0",
3
+ "version": "20.1.1",
4
4
  "description": "React runtime for metacore hosts — renders addon contributions dynamically",
5
5
  "repository": {
6
6
  "type": "git",
@@ -38,7 +38,7 @@
38
38
  "sonner": ">=1.7",
39
39
  "zustand": ">=5",
40
40
  "@asteby/metacore-sdk": "^3.2.0",
41
- "@asteby/metacore-ui": "^2.6.0"
41
+ "@asteby/metacore-ui": "^2.6.1"
42
42
  },
43
43
  "peerDependenciesMeta": {
44
44
  "@tanstack/react-router": {
@@ -68,7 +68,7 @@
68
68
  "vitest": "^4.0.0",
69
69
  "zustand": "^5.0.0",
70
70
  "@asteby/metacore-sdk": "3.2.0",
71
- "@asteby/metacore-ui": "2.6.0"
71
+ "@asteby/metacore-ui": "2.6.1"
72
72
  },
73
73
  "scripts": {
74
74
  "build": "tsc -p tsconfig.json",
@@ -441,7 +441,7 @@ export function DynamicKanban({
441
441
  return (
442
442
  <div className="flex gap-4 overflow-x-auto p-1">
443
443
  {[0, 1, 2, 3].map((i) => (
444
- <div key={i} className="w-72 shrink-0 space-y-3">
444
+ <div key={i} className="min-w-[220px] max-w-[320px] flex-1 space-y-3">
445
445
  <Skeleton className="h-8 w-full" />
446
446
  <Skeleton className="h-24 w-full" />
447
447
  <Skeleton className="h-24 w-full" />
@@ -580,7 +580,7 @@ function KanbanLane({ stage, count, isDark, dimmed, disabled, children }: Kanban
580
580
  return (
581
581
  <div
582
582
  ref={setNodeRef}
583
- className="flex w-72 shrink-0 flex-col rounded-lg border bg-muted/30 transition-opacity"
583
+ className="flex min-w-[220px] max-w-[320px] flex-1 flex-col rounded-lg border bg-muted/30 transition-opacity"
584
584
  style={{
585
585
  opacity: dimmed ? 0.45 : 1,
586
586
  outline: isOver && !disabled ? '2px solid var(--ring, #3b82f6)' : 'none',
@@ -655,7 +655,7 @@ function KanbanCard({
655
655
  >
656
656
  <CardContent className="space-y-1.5 p-3">
657
657
  <div className="flex items-start justify-between gap-2">
658
- <div className="min-w-0 flex-1 text-sm font-medium leading-snug">
658
+ <div className="line-clamp-2 min-w-0 flex-1 break-words text-sm font-medium leading-snug">
659
659
  {titleCol ? (
660
660
  <ActivityValueRenderer
661
661
  value={card[titleCol.key]}
@@ -705,7 +705,7 @@ function KanbanCard({
705
705
  {fieldCols.map((col) => (
706
706
  <div
707
707
  key={col.key}
708
- className="flex items-center gap-1.5 text-xs text-muted-foreground"
708
+ className="flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground"
709
709
  >
710
710
  <span className="shrink-0 opacity-70">{col.label}:</span>
711
711
  <span className="min-w-0 truncate">
@@ -736,7 +736,7 @@ function CardPreview({
736
736
  return (
737
737
  <Card className="w-72 cursor-grabbing border-primary/40 shadow-lg">
738
738
  <CardContent className="space-y-1.5 p-3">
739
- <div className="text-sm font-medium leading-snug">
739
+ <div className="line-clamp-2 break-words text-sm font-medium leading-snug">
740
740
  {titleCol ? (
741
741
  <ActivityValueRenderer
742
742
  value={card[titleCol.key]}
@@ -752,7 +752,7 @@ function CardPreview({
752
752
  {fieldCols.map((col) => (
753
753
  <div
754
754
  key={col.key}
755
- className="flex items-center gap-1.5 text-xs text-muted-foreground"
755
+ className="flex min-w-0 items-center gap-1.5 text-xs text-muted-foreground"
756
756
  >
757
757
  <span className="shrink-0 opacity-70">{col.label}:</span>
758
758
  <span className="min-w-0 truncate">