@asteby/metacore-runtime-react 20.1.2 → 20.1.4

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,32 @@
1
1
  # @asteby/metacore-runtime-react
2
2
 
3
+ ## 20.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 9e50db5: fix(kanban): cards stretch to fit their content instead of clamping
8
+
9
+ The card title and field values were `line-clamp-2` (cut to two lines + ellipsis).
10
+ Per product feedback the cards should grow DOWNWARD to show their full content and
11
+ never cut text. Removed the clamps so title and fields wrap fully (`break-words`
12
+ keeps long tokens from overflowing horizontally) and the card grows as tall as it
13
+ needs; the column's ScrollArea already scrolls when a lane gets long.
14
+
15
+ ## 20.1.3
16
+
17
+ ### Patch Changes
18
+
19
+ - 8c6635c: fix(dynamic-table): preserve `view`/`group_by` in the URL when the table syncs its state
20
+
21
+ The table's url-sync rebuilt the query string from scratch (only its own
22
+ page/sort/filter keys) and `replaceState`d it, wiping the route-owned
23
+ `view`/`group_by` params. On a same-model board↔list pair (e.g. github's Board
24
+ `?view=kanban` vs Issues `?view=table`) this stripped `?view` on mount, so the
25
+ URL went bare and the sidebar active-state fell back to the model default —
26
+ highlighting the wrong sibling until you clicked again. The sync now carries
27
+ `view`/`group_by` through so the open entry stays highlighted on a single click
28
+ and `?view` deep-links survive table interaction.
29
+
3
30
  ## 20.1.2
4
31
 
5
32
  ### Patch Changes
@@ -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: "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",
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 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 min-w-0 items-start gap-1.5 text-xs text-muted-foreground", children: [_jsxs("span", { className: "shrink-0 opacity-70", children: [col.label, ":"] }), _jsx("span", { className: "line-clamp-2 min-w-0 break-words", 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-start 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 break-words", 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: "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-start gap-1.5 text-xs text-muted-foreground", children: [_jsxs("span", { className: "shrink-0 opacity-70", children: [col.label, ":"] }), _jsx("span", { className: "line-clamp-2 min-w-0 break-words", 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: "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-start 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 break-words", children: _jsx(ActivityValueRenderer, { value: card[col.key], col: col, locale: locale, timeZone: timeZone, currency: currency }) })] }, col.key)))] }) }));
346
346
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-table.d.ts","sourceRoot":"","sources":["../src/dynamic-table.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAKH,KAAK,SAAS,EAajB,MAAM,uBAAuB,CAAA;AAgC9B,OAAO,KAAK,EAAsB,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAWnF,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;IAC7C;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;IAC/B,cAAc,CAAC,EAAE,GAAG,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACpC,YAAY,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAA;IAC/B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,YAAY,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,aAAoB,EACpB,aAAkB,EAClB,QAAQ,EACR,UAAU,EACV,cAAc,EACd,cAAc,EACd,YAAiB,EACjB,iBAA4C,EAC5C,QAAQ,EACR,QAAQ,GACX,EAAE,iBAAiB,+BA24BnB"}
1
+ {"version":3,"file":"dynamic-table.d.ts","sourceRoot":"","sources":["../src/dynamic-table.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAKH,KAAK,SAAS,EAajB,MAAM,uBAAuB,CAAA;AAgC9B,OAAO,KAAK,EAAsB,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAWnF,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;IAC7C;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAA;IAC/B,cAAc,CAAC,EAAE,GAAG,CAAA;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACpC,YAAY,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAA;IAC/B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAA;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,YAAY,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,aAAoB,EACpB,aAAkB,EAClB,QAAQ,EACR,UAAU,EACV,cAAc,EACd,cAAc,EACd,YAAiB,EACjB,iBAA4C,EAC5C,QAAQ,EACR,QAAQ,GACX,EAAE,iBAAiB,+BAw5BnB"}
@@ -147,6 +147,20 @@ export function DynamicTable({ model, endpoint, enableUrlSync = true, hiddenColu
147
147
  if (!enableUrlSync || !initializedFromUrl.current)
148
148
  return;
149
149
  const params = new URLSearchParams();
150
+ // Preserve the route-owned view params. The table rebuilds the query
151
+ // string from scratch (it only knows its own page/sort/filter keys), but
152
+ // `view`/`group_by` belong to the renderer choice + the sidebar's
153
+ // active-state matcher. Carrying them over keeps `?view=table` (vs
154
+ // `?view=kanban`) in the URL so the open sibling stays highlighted and a
155
+ // deep-link survives — without this the table wipes `?view` on mount,
156
+ // the URL goes bare, and the sidebar falls back to the model default
157
+ // (the "click twice to move the active to the right entry" bug).
158
+ const current = new URLSearchParams(window.location.search);
159
+ for (const key of ['view', 'group_by']) {
160
+ const v = current.get(key);
161
+ if (v)
162
+ params.set(key, v);
163
+ }
150
164
  if (pagination.pageIndex > 0)
151
165
  params.set('page', String(pagination.pageIndex + 1));
152
166
  if (pagination.pageSize !== 10)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asteby/metacore-runtime-react",
3
- "version": "20.1.2",
3
+ "version": "20.1.4",
4
4
  "description": "React runtime for metacore hosts — renders addon contributions dynamically",
5
5
  "repository": {
6
6
  "type": "git",
@@ -67,8 +67,8 @@
67
67
  "typescript": "^6.0.0",
68
68
  "vitest": "^4.0.0",
69
69
  "zustand": "^5.0.0",
70
- "@asteby/metacore-ui": "2.6.2",
71
- "@asteby/metacore-sdk": "3.2.0"
70
+ "@asteby/metacore-sdk": "3.2.0",
71
+ "@asteby/metacore-ui": "2.6.2"
72
72
  },
73
73
  "scripts": {
74
74
  "build": "tsc -p tsconfig.json",
@@ -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="line-clamp-2 min-w-0 flex-1 break-words text-sm font-medium leading-snug">
658
+ <div className="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]}
@@ -708,7 +708,7 @@ function KanbanCard({
708
708
  className="flex min-w-0 items-start gap-1.5 text-xs text-muted-foreground"
709
709
  >
710
710
  <span className="shrink-0 opacity-70">{col.label}:</span>
711
- <span className="line-clamp-2 min-w-0 break-words">
711
+ <span className="min-w-0 break-words">
712
712
  <ActivityValueRenderer
713
713
  value={card[col.key]}
714
714
  col={col}
@@ -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="line-clamp-2 break-words text-sm font-medium leading-snug">
739
+ <div className="break-words text-sm font-medium leading-snug">
740
740
  {titleCol ? (
741
741
  <ActivityValueRenderer
742
742
  value={card[titleCol.key]}
@@ -755,7 +755,7 @@ function CardPreview({
755
755
  className="flex min-w-0 items-start gap-1.5 text-xs text-muted-foreground"
756
756
  >
757
757
  <span className="shrink-0 opacity-70">{col.label}:</span>
758
- <span className="line-clamp-2 min-w-0 break-words">
758
+ <span className="min-w-0 break-words">
759
759
  <ActivityValueRenderer
760
760
  value={card[col.key]}
761
761
  col={col}
@@ -257,6 +257,19 @@ export function DynamicTable({
257
257
  useEffect(() => {
258
258
  if (!enableUrlSync || !initializedFromUrl.current) return
259
259
  const params = new URLSearchParams()
260
+ // Preserve the route-owned view params. The table rebuilds the query
261
+ // string from scratch (it only knows its own page/sort/filter keys), but
262
+ // `view`/`group_by` belong to the renderer choice + the sidebar's
263
+ // active-state matcher. Carrying them over keeps `?view=table` (vs
264
+ // `?view=kanban`) in the URL so the open sibling stays highlighted and a
265
+ // deep-link survives — without this the table wipes `?view` on mount,
266
+ // the URL goes bare, and the sidebar falls back to the model default
267
+ // (the "click twice to move the active to the right entry" bug).
268
+ const current = new URLSearchParams(window.location.search)
269
+ for (const key of ['view', 'group_by']) {
270
+ const v = current.get(key)
271
+ if (v) params.set(key, v)
272
+ }
260
273
  if (pagination.pageIndex > 0) params.set('page', String(pagination.pageIndex + 1))
261
274
  if (pagination.pageSize !== 10) params.set('per_page', String(pagination.pageSize))
262
275
  if (sorting.length > 0) {