@ai-matrx/associations 0.6.1 → 0.7.0
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 +34 -0
- package/README.md +13 -7
- package/dist/{CommentThread-E0zSQBbc.d.cts → CommentThread-HW4hLdsd.d.cts} +13 -3
- package/dist/{CommentThread-E0zSQBbc.d.ts → CommentThread-HW4hLdsd.d.ts} +13 -3
- package/dist/core/index.cjs +2 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -3
- package/dist/index.d.ts +19 -3
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +130 -15
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +130 -15
- package/dist/react/index.js.map +1 -1
- package/dist/react/lazy/index.d.cts +1 -1
- package/dist/react/lazy/index.d.ts +1 -1
- package/package.json +2 -2
package/dist/react/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, ComponentType } from 'react';
|
|
3
|
-
import { j as AssociationsNotifier, W as WindowShellPort, k as CapturePort, P as PickerOverrideMap, E as EntityDoorsPort, l as AuthorDisplayPort, m as AssociationsStore, n as CategoryMutationResult, o as CategoryDimension, p as PlatformCategory, q as CategoriesEntry, r as EntityTypeToken, s as UniversalCandidate, t as CandidateRecord, u as PlatformComment, v as CommentsEntry, w as CommentMutationResult, e as AssociationPickerProps, x as EntityDoorProps, y as EntityRefProps, z as ContentRole } from '../CommentThread-
|
|
4
|
-
export { B as AssociationCaptureToolbar, A as AssociationCaptureToolbarProps, D as AssociationCard, F as AssociationCardGrid, b as AssociationCardGridProps, a as AssociationCardProps, G as AssociationEntitySelect, H as AssociationEntitySelectAdapter, I as AssociationEntitySelectItem, c as AssociationEntitySelectProps, J as AssociationList, d as AssociationListProps, K as AssociationWindow, f as AssociationWindowProps, L as AssociationWriteResult, M as AttachedItemsSheet, g as AttachedItemsSheetProps, N as CaptureAttach, O as CaptureAttachResult, Q as CaptureToolbarAction, R as CategorySelect, C as CategorySelectProps, S as CategoryTagPicker, h as CategoryTagPickerProps, T as CommentComposer, V as CommentComposerProps, X as CommentThread, i as CommentThreadProps, Y as ContainerLink, Z as ContainerResourceRow, _ as ContainerResourcesAdapter, $ as DefaultEntityIcon, a0 as PrimaryEntity, a1 as PrimaryEntityProvider, a2 as TagPickerIcon, a3 as UniversalAssociationPicker, U as UniversalAssociationPickerProps, a4 as UseAssociationEntitySelectAdapterArgs, a5 as UseAssociationsArgs, a6 as UseAssociationsReturn, a7 as UseContainerLinksArgs, a8 as UseContainerLinksReturn, a9 as attachedKey, aa as buildCommentTree, ab as useAssociationEntitySelectAdapter, ac as useAssociations, ad as useContainerLinks, ae as useContainerLinksAdapter, af as useEntityRelationships, ag as usePrimaryEntity } from '../CommentThread-
|
|
3
|
+
import { j as AssociationsNotifier, W as WindowShellPort, k as CapturePort, P as PickerOverrideMap, E as EntityDoorsPort, l as AuthorDisplayPort, m as AssociationsStore, n as CategoryMutationResult, o as CategoryDimension, p as PlatformCategory, q as CategoriesEntry, r as EntityTypeToken, s as UniversalCandidate, t as CandidateRecord, u as PlatformComment, v as CommentsEntry, w as CommentMutationResult, e as AssociationPickerProps, x as EntityDoorProps, y as EntityRefProps, z as ContentRole } from '../CommentThread-HW4hLdsd.cjs';
|
|
4
|
+
export { B as AssociationCaptureToolbar, A as AssociationCaptureToolbarProps, D as AssociationCard, F as AssociationCardGrid, b as AssociationCardGridProps, a as AssociationCardProps, G as AssociationEntitySelect, H as AssociationEntitySelectAdapter, I as AssociationEntitySelectItem, c as AssociationEntitySelectProps, J as AssociationList, d as AssociationListProps, K as AssociationWindow, f as AssociationWindowProps, L as AssociationWriteResult, M as AttachedItemsSheet, g as AttachedItemsSheetProps, N as CaptureAttach, O as CaptureAttachResult, Q as CaptureToolbarAction, R as CategorySelect, C as CategorySelectProps, S as CategoryTagPicker, h as CategoryTagPickerProps, T as CommentComposer, V as CommentComposerProps, X as CommentThread, i as CommentThreadProps, Y as ContainerLink, Z as ContainerResourceRow, _ as ContainerResourcesAdapter, $ as DefaultEntityIcon, a0 as PrimaryEntity, a1 as PrimaryEntityProvider, a2 as TagPickerIcon, a3 as UniversalAssociationPicker, U as UniversalAssociationPickerProps, a4 as UseAssociationEntitySelectAdapterArgs, a5 as UseAssociationsArgs, a6 as UseAssociationsReturn, a7 as UseContainerLinksArgs, a8 as UseContainerLinksReturn, a9 as attachedKey, aa as buildCommentTree, ab as useAssociationEntitySelectAdapter, ac as useAssociations, ad as useContainerLinks, ae as useContainerLinksAdapter, af as useEntityRelationships, ag as usePrimaryEntity } from '../CommentThread-HW4hLdsd.cjs';
|
|
5
5
|
|
|
6
6
|
interface AssociationsUiPorts {
|
|
7
7
|
notifier?: AssociationsNotifier;
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, ComponentType } from 'react';
|
|
3
|
-
import { j as AssociationsNotifier, W as WindowShellPort, k as CapturePort, P as PickerOverrideMap, E as EntityDoorsPort, l as AuthorDisplayPort, m as AssociationsStore, n as CategoryMutationResult, o as CategoryDimension, p as PlatformCategory, q as CategoriesEntry, r as EntityTypeToken, s as UniversalCandidate, t as CandidateRecord, u as PlatformComment, v as CommentsEntry, w as CommentMutationResult, e as AssociationPickerProps, x as EntityDoorProps, y as EntityRefProps, z as ContentRole } from '../CommentThread-
|
|
4
|
-
export { B as AssociationCaptureToolbar, A as AssociationCaptureToolbarProps, D as AssociationCard, F as AssociationCardGrid, b as AssociationCardGridProps, a as AssociationCardProps, G as AssociationEntitySelect, H as AssociationEntitySelectAdapter, I as AssociationEntitySelectItem, c as AssociationEntitySelectProps, J as AssociationList, d as AssociationListProps, K as AssociationWindow, f as AssociationWindowProps, L as AssociationWriteResult, M as AttachedItemsSheet, g as AttachedItemsSheetProps, N as CaptureAttach, O as CaptureAttachResult, Q as CaptureToolbarAction, R as CategorySelect, C as CategorySelectProps, S as CategoryTagPicker, h as CategoryTagPickerProps, T as CommentComposer, V as CommentComposerProps, X as CommentThread, i as CommentThreadProps, Y as ContainerLink, Z as ContainerResourceRow, _ as ContainerResourcesAdapter, $ as DefaultEntityIcon, a0 as PrimaryEntity, a1 as PrimaryEntityProvider, a2 as TagPickerIcon, a3 as UniversalAssociationPicker, U as UniversalAssociationPickerProps, a4 as UseAssociationEntitySelectAdapterArgs, a5 as UseAssociationsArgs, a6 as UseAssociationsReturn, a7 as UseContainerLinksArgs, a8 as UseContainerLinksReturn, a9 as attachedKey, aa as buildCommentTree, ab as useAssociationEntitySelectAdapter, ac as useAssociations, ad as useContainerLinks, ae as useContainerLinksAdapter, af as useEntityRelationships, ag as usePrimaryEntity } from '../CommentThread-
|
|
3
|
+
import { j as AssociationsNotifier, W as WindowShellPort, k as CapturePort, P as PickerOverrideMap, E as EntityDoorsPort, l as AuthorDisplayPort, m as AssociationsStore, n as CategoryMutationResult, o as CategoryDimension, p as PlatformCategory, q as CategoriesEntry, r as EntityTypeToken, s as UniversalCandidate, t as CandidateRecord, u as PlatformComment, v as CommentsEntry, w as CommentMutationResult, e as AssociationPickerProps, x as EntityDoorProps, y as EntityRefProps, z as ContentRole } from '../CommentThread-HW4hLdsd.js';
|
|
4
|
+
export { B as AssociationCaptureToolbar, A as AssociationCaptureToolbarProps, D as AssociationCard, F as AssociationCardGrid, b as AssociationCardGridProps, a as AssociationCardProps, G as AssociationEntitySelect, H as AssociationEntitySelectAdapter, I as AssociationEntitySelectItem, c as AssociationEntitySelectProps, J as AssociationList, d as AssociationListProps, K as AssociationWindow, f as AssociationWindowProps, L as AssociationWriteResult, M as AttachedItemsSheet, g as AttachedItemsSheetProps, N as CaptureAttach, O as CaptureAttachResult, Q as CaptureToolbarAction, R as CategorySelect, C as CategorySelectProps, S as CategoryTagPicker, h as CategoryTagPickerProps, T as CommentComposer, V as CommentComposerProps, X as CommentThread, i as CommentThreadProps, Y as ContainerLink, Z as ContainerResourceRow, _ as ContainerResourcesAdapter, $ as DefaultEntityIcon, a0 as PrimaryEntity, a1 as PrimaryEntityProvider, a2 as TagPickerIcon, a3 as UniversalAssociationPicker, U as UniversalAssociationPickerProps, a4 as UseAssociationEntitySelectAdapterArgs, a5 as UseAssociationsArgs, a6 as UseAssociationsReturn, a7 as UseContainerLinksArgs, a8 as UseContainerLinksReturn, a9 as attachedKey, aa as buildCommentTree, ab as useAssociationEntitySelectAdapter, ac as useAssociations, ad as useContainerLinks, ae as useContainerLinksAdapter, af as useEntityRelationships, ag as usePrimaryEntity } from '../CommentThread-HW4hLdsd.js';
|
|
5
5
|
|
|
6
6
|
interface AssociationsUiPorts {
|
|
7
7
|
notifier?: AssociationsNotifier;
|
package/dist/react/index.js
CHANGED
|
@@ -366,6 +366,7 @@ var ENTITY_TYPE_TOKENS = [
|
|
|
366
366
|
"commerce_asset_reshoot_request",
|
|
367
367
|
"commerce_asset_review",
|
|
368
368
|
"commerce_asset_unknown",
|
|
369
|
+
"commerce_certified_printer",
|
|
369
370
|
"commerce_cloud_sync_connection",
|
|
370
371
|
"commerce_ebay_business_policy",
|
|
371
372
|
"commerce_ebay_category",
|
|
@@ -1051,6 +1052,12 @@ import {
|
|
|
1051
1052
|
useRef as useRef3,
|
|
1052
1053
|
useState
|
|
1053
1054
|
} from "react";
|
|
1055
|
+
function metadataRecord(metadata) {
|
|
1056
|
+
if (metadata === null || typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
1057
|
+
return metadata == null ? {} : null;
|
|
1058
|
+
}
|
|
1059
|
+
return Object.fromEntries(Object.entries(metadata));
|
|
1060
|
+
}
|
|
1054
1061
|
function useContainerLinks(args) {
|
|
1055
1062
|
const { containerType, containerId, orgId } = args;
|
|
1056
1063
|
const store = useAssociationsStore();
|
|
@@ -1172,6 +1179,31 @@ function useContainerLinks(args) {
|
|
|
1172
1179
|
}
|
|
1173
1180
|
return result;
|
|
1174
1181
|
};
|
|
1182
|
+
const setPinned = async (token, resourceId, pinned, role) => {
|
|
1183
|
+
if (!containerId) return { ok: false, error: "Missing container id" };
|
|
1184
|
+
const exactRole = role ?? null;
|
|
1185
|
+
const link = incoming.find(
|
|
1186
|
+
(candidate) => candidate.token === token && candidate.resourceId === resourceId && candidate.role === exactRole
|
|
1187
|
+
);
|
|
1188
|
+
if (!link) return { ok: false, error: "Association edge not found" };
|
|
1189
|
+
const currentMetadata = metadataRecord(link.metadata);
|
|
1190
|
+
if (!currentMetadata) {
|
|
1191
|
+
return {
|
|
1192
|
+
ok: false,
|
|
1193
|
+
error: "Association metadata is not an object and cannot be updated safely"
|
|
1194
|
+
};
|
|
1195
|
+
}
|
|
1196
|
+
return store.add({
|
|
1197
|
+
sourceType: token,
|
|
1198
|
+
sourceId: resourceId,
|
|
1199
|
+
targetType: containerType,
|
|
1200
|
+
targetId: containerId,
|
|
1201
|
+
...orgId != null ? { orgId } : {},
|
|
1202
|
+
...link.label != null ? { label: link.label } : {},
|
|
1203
|
+
...role !== void 0 ? { role } : {},
|
|
1204
|
+
metadata: { ...currentMetadata, pinned }
|
|
1205
|
+
});
|
|
1206
|
+
};
|
|
1175
1207
|
const reload = async () => {
|
|
1176
1208
|
await Promise.all([
|
|
1177
1209
|
reloadGeneric(),
|
|
@@ -1189,7 +1221,8 @@ function useContainerLinks(args) {
|
|
|
1189
1221
|
attachedIdsFor,
|
|
1190
1222
|
linksFor,
|
|
1191
1223
|
attach,
|
|
1192
|
-
detach
|
|
1224
|
+
detach,
|
|
1225
|
+
setPinned
|
|
1193
1226
|
};
|
|
1194
1227
|
}
|
|
1195
1228
|
|
|
@@ -2576,6 +2609,9 @@ function UniversalAssociationPicker(props) {
|
|
|
2576
2609
|
import { useEffect as useEffect10, useState as useState9 } from "react";
|
|
2577
2610
|
import { cn as cn5 } from "@ai-matrx/design-system";
|
|
2578
2611
|
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2612
|
+
function metadataIsPinned(metadata) {
|
|
2613
|
+
return metadata !== null && typeof metadata === "object" && !Array.isArray(metadata) && Reflect.get(metadata, "pinned") === true;
|
|
2614
|
+
}
|
|
2579
2615
|
function AttachedItemsSheet(props) {
|
|
2580
2616
|
const store = useAssociationsStore();
|
|
2581
2617
|
const info = store.registry.getEntityInfo(props.token);
|
|
@@ -2611,7 +2647,8 @@ function AttachedItemsSheet(props) {
|
|
|
2611
2647
|
enabled: props.open,
|
|
2612
2648
|
links: props.links,
|
|
2613
2649
|
...props.onAdd ? { onAdd: props.onAdd } : {},
|
|
2614
|
-
onDetach: props.onDetach
|
|
2650
|
+
onDetach: props.onDetach,
|
|
2651
|
+
...props.onSetPinned ? { onSetPinned: props.onSetPinned } : {}
|
|
2615
2652
|
}
|
|
2616
2653
|
)
|
|
2617
2654
|
}
|
|
@@ -2622,7 +2659,8 @@ function AttachedItemsBody({
|
|
|
2622
2659
|
enabled,
|
|
2623
2660
|
links,
|
|
2624
2661
|
onAdd,
|
|
2625
|
-
onDetach
|
|
2662
|
+
onDetach,
|
|
2663
|
+
onSetPinned
|
|
2626
2664
|
}) {
|
|
2627
2665
|
const store = useAssociationsStore();
|
|
2628
2666
|
const notifier = useNotifier();
|
|
@@ -2664,11 +2702,12 @@ function AttachedItemsBody({
|
|
|
2664
2702
|
cancelled = true;
|
|
2665
2703
|
};
|
|
2666
2704
|
}, [token, idKey, enabled, store]);
|
|
2667
|
-
const detach = async (
|
|
2705
|
+
const detach = async (link) => {
|
|
2706
|
+
const resourceId = link.resourceId;
|
|
2668
2707
|
if (busyId) return;
|
|
2669
2708
|
setBusyId(resourceId);
|
|
2670
2709
|
try {
|
|
2671
|
-
const res = await onDetach(resourceId);
|
|
2710
|
+
const res = await onDetach(resourceId, link.role);
|
|
2672
2711
|
if (!res.ok) {
|
|
2673
2712
|
notifier.error(`Couldn't detach${res.error ? `: ${res.error}` : ""}`);
|
|
2674
2713
|
}
|
|
@@ -2676,6 +2715,20 @@ function AttachedItemsBody({
|
|
|
2676
2715
|
setBusyId(null);
|
|
2677
2716
|
}
|
|
2678
2717
|
};
|
|
2718
|
+
const setPinned = async (link, pinned) => {
|
|
2719
|
+
if (!onSetPinned || busyId) return;
|
|
2720
|
+
setBusyId(link.resourceId);
|
|
2721
|
+
try {
|
|
2722
|
+
const res = await onSetPinned(link.resourceId, pinned, link.role);
|
|
2723
|
+
if (!res.ok) {
|
|
2724
|
+
notifier.error(
|
|
2725
|
+
`Couldn't ${pinned ? "pin" : "unpin"}${res.error ? `: ${res.error}` : ""}`
|
|
2726
|
+
);
|
|
2727
|
+
}
|
|
2728
|
+
} finally {
|
|
2729
|
+
setBusyId(null);
|
|
2730
|
+
}
|
|
2731
|
+
};
|
|
2679
2732
|
return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
2680
2733
|
titleError ? /* @__PURE__ */ jsxs7("div", { className: "mb-2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-[12px] text-destructive", children: [
|
|
2681
2734
|
"Showing names recorded at attach time \u2014 they may be out of date.",
|
|
@@ -2690,6 +2743,7 @@ function AttachedItemsBody({
|
|
|
2690
2743
|
const missing = !titles.has(link.resourceId);
|
|
2691
2744
|
const name = resolved ?? link.label ?? (missing ? null : "Untitled");
|
|
2692
2745
|
const busy = busyId === link.resourceId;
|
|
2746
|
+
const pinned = metadataIsPinned(link.metadata);
|
|
2693
2747
|
return /* @__PURE__ */ jsxs7(
|
|
2694
2748
|
"li",
|
|
2695
2749
|
{
|
|
@@ -2709,12 +2763,35 @@ function AttachedItemsBody({
|
|
|
2709
2763
|
className: "text-foreground"
|
|
2710
2764
|
}
|
|
2711
2765
|
) }),
|
|
2766
|
+
onSetPinned ? /* @__PURE__ */ jsx9(
|
|
2767
|
+
"button",
|
|
2768
|
+
{
|
|
2769
|
+
type: "button",
|
|
2770
|
+
disabled: busy,
|
|
2771
|
+
onClick: () => void setPinned(link, !pinned),
|
|
2772
|
+
title: pinned ? "Unpin (stops staying in agent context)" : "Pin \u2014 always in agent context",
|
|
2773
|
+
"aria-label": pinned ? "Unpin" : "Pin",
|
|
2774
|
+
className: cn5(
|
|
2775
|
+
"flex h-6 w-6 shrink-0 items-center justify-center rounded-md transition-colors hover:bg-accent hover:text-foreground disabled:opacity-50",
|
|
2776
|
+
pinned ? "text-primary" : "text-muted-foreground"
|
|
2777
|
+
),
|
|
2778
|
+
children: /* @__PURE__ */ jsx9(
|
|
2779
|
+
PinIcon,
|
|
2780
|
+
{
|
|
2781
|
+
className: cn5(
|
|
2782
|
+
"h-3.5 w-3.5",
|
|
2783
|
+
pinned && "fill-primary/20"
|
|
2784
|
+
)
|
|
2785
|
+
}
|
|
2786
|
+
)
|
|
2787
|
+
}
|
|
2788
|
+
) : null,
|
|
2712
2789
|
/* @__PURE__ */ jsx9(
|
|
2713
2790
|
"button",
|
|
2714
2791
|
{
|
|
2715
2792
|
type: "button",
|
|
2716
2793
|
disabled: busy,
|
|
2717
|
-
onClick: () => void detach(link
|
|
2794
|
+
onClick: () => void detach(link),
|
|
2718
2795
|
title: "Detach",
|
|
2719
2796
|
className: cn5(
|
|
2720
2797
|
"flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors",
|
|
@@ -2810,7 +2887,15 @@ function AssociationCard({
|
|
|
2810
2887
|
const role = getContentRoleMeta(info.contentRole);
|
|
2811
2888
|
const Icon = info.Icon ?? DefaultEntityIcon;
|
|
2812
2889
|
const [listOpen, setListOpen] = useState10(false);
|
|
2813
|
-
const {
|
|
2890
|
+
const {
|
|
2891
|
+
status,
|
|
2892
|
+
countFor,
|
|
2893
|
+
attachedIdsFor,
|
|
2894
|
+
linksFor,
|
|
2895
|
+
attach,
|
|
2896
|
+
detach,
|
|
2897
|
+
setPinned
|
|
2898
|
+
} = useContainerLinks({
|
|
2814
2899
|
containerType: container?.type ?? "organization",
|
|
2815
2900
|
containerId: container?.id ?? null,
|
|
2816
2901
|
orgId: container?.orgId ?? null
|
|
@@ -2907,7 +2992,8 @@ function AssociationCard({
|
|
|
2907
2992
|
setOpen(true);
|
|
2908
2993
|
}
|
|
2909
2994
|
} : {},
|
|
2910
|
-
onDetach: (resourceId) => detach(token, resourceId)
|
|
2995
|
+
onDetach: (resourceId, role2) => detach(token, resourceId, role2 ?? void 0),
|
|
2996
|
+
onSetPinned: (resourceId, pinned, role2) => setPinned(token, resourceId, pinned, role2 ?? void 0)
|
|
2911
2997
|
}
|
|
2912
2998
|
),
|
|
2913
2999
|
canAttach && /* @__PURE__ */ jsx10(
|
|
@@ -2966,6 +3052,9 @@ function AssociationCardGrid({
|
|
|
2966
3052
|
import { useState as useState11 } from "react";
|
|
2967
3053
|
import { cn as cn8, Skeleton } from "@ai-matrx/design-system";
|
|
2968
3054
|
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3055
|
+
function metadataIsPinned2(metadata) {
|
|
3056
|
+
return metadata !== null && typeof metadata === "object" && !Array.isArray(metadata) && Reflect.get(metadata, "pinned") === true;
|
|
3057
|
+
}
|
|
2969
3058
|
function useContainerLinksAdapter(container, tokens) {
|
|
2970
3059
|
const store = useAssociationsStore();
|
|
2971
3060
|
const links = useContainerLinks({
|
|
@@ -2980,6 +3069,7 @@ function useContainerLinksAdapter(container, tokens) {
|
|
|
2980
3069
|
resourceId: l.resourceId,
|
|
2981
3070
|
label: l.label,
|
|
2982
3071
|
role: l.role,
|
|
3072
|
+
pinned: metadataIsPinned2(l.metadata),
|
|
2983
3073
|
removable: true
|
|
2984
3074
|
}))
|
|
2985
3075
|
) : [];
|
|
@@ -2989,11 +3079,13 @@ function useContainerLinksAdapter(container, tokens) {
|
|
|
2989
3079
|
reload: links.reload,
|
|
2990
3080
|
rows,
|
|
2991
3081
|
attach: async (token, id, title) => links.attach(token, id, title),
|
|
2992
|
-
detach: async (token, id, role) => links.detach(token, id, role)
|
|
3082
|
+
detach: async (token, id, role) => links.detach(token, id, role),
|
|
3083
|
+
setPinned: async (token, id, pinned, role) => links.setPinned(token, id, pinned, role)
|
|
2993
3084
|
};
|
|
2994
3085
|
}
|
|
2995
3086
|
function AssociationList(props) {
|
|
2996
3087
|
const store = useAssociationsStore();
|
|
3088
|
+
const notifier = useNotifier();
|
|
2997
3089
|
const ctxEntity = usePrimaryEntity();
|
|
2998
3090
|
const container = props.container ?? ctxEntity ?? null;
|
|
2999
3091
|
const defaultAdapter = useContainerLinksAdapter(
|
|
@@ -3006,6 +3098,7 @@ function AssociationList(props) {
|
|
|
3006
3098
|
const [pickerToken, setPickerToken] = useState11(null);
|
|
3007
3099
|
const [showUniversal, setShowUniversal] = useState11(false);
|
|
3008
3100
|
const [removingKeys, setRemovingKeys] = useState11(/* @__PURE__ */ new Set());
|
|
3101
|
+
const [pinningKeys, setPinningKeys] = useState11(/* @__PURE__ */ new Set());
|
|
3009
3102
|
const rows = tokenFilter ? adapter.rows.filter((r) => tokenFilter.includes(r.token)) : adapter.rows;
|
|
3010
3103
|
const visibleRows = rows.filter((r) => !removingKeys.has(r.key));
|
|
3011
3104
|
const { titleFor } = useEntityTitles(
|
|
@@ -3029,6 +3122,31 @@ function AssociationList(props) {
|
|
|
3029
3122
|
});
|
|
3030
3123
|
return res;
|
|
3031
3124
|
};
|
|
3125
|
+
const handlePin = async (row, pinned) => {
|
|
3126
|
+
if (!adapter.setPinned) return;
|
|
3127
|
+
const info = store.registry.tryGetEntityInfo(row.token);
|
|
3128
|
+
if (!info) return;
|
|
3129
|
+
setPinningKeys((prev) => new Set(prev).add(row.key));
|
|
3130
|
+
try {
|
|
3131
|
+
const res = await adapter.setPinned(
|
|
3132
|
+
info.token,
|
|
3133
|
+
row.resourceId,
|
|
3134
|
+
pinned,
|
|
3135
|
+
row.role ?? void 0
|
|
3136
|
+
);
|
|
3137
|
+
if (!res.ok) {
|
|
3138
|
+
notifier.error(
|
|
3139
|
+
`Couldn't ${pinned ? "pin" : "unpin"} resource${res.error ? `: ${res.error}` : ""}`
|
|
3140
|
+
);
|
|
3141
|
+
}
|
|
3142
|
+
} finally {
|
|
3143
|
+
setPinningKeys((prev) => {
|
|
3144
|
+
const next = new Set(prev);
|
|
3145
|
+
next.delete(row.key);
|
|
3146
|
+
return next;
|
|
3147
|
+
});
|
|
3148
|
+
}
|
|
3149
|
+
};
|
|
3032
3150
|
const openRow = (row) => {
|
|
3033
3151
|
if (props.openEntity) {
|
|
3034
3152
|
props.openEntity(row.token, row.resourceId);
|
|
@@ -3219,18 +3337,15 @@ function AssociationList(props) {
|
|
|
3219
3337
|
"button",
|
|
3220
3338
|
{
|
|
3221
3339
|
type: "button",
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
row.resourceId,
|
|
3225
|
-
!(row.pinned ?? false)
|
|
3226
|
-
),
|
|
3340
|
+
disabled: pinningKeys.has(row.key),
|
|
3341
|
+
onClick: () => void handlePin(row, !(row.pinned ?? false)),
|
|
3227
3342
|
title: row.pinned ? "Unpin (stops staying in agent context)" : "Pin \u2014 always in agent context",
|
|
3228
3343
|
"aria-label": row.pinned ? "Unpin" : "Pin",
|
|
3229
3344
|
className: cn8(
|
|
3230
3345
|
"shrink-0 rounded p-0.5 transition-colors hover:!text-foreground",
|
|
3231
3346
|
row.pinned ? "text-primary" : "text-muted-foreground/0 group-hover:text-muted-foreground"
|
|
3232
3347
|
),
|
|
3233
|
-
children: /* @__PURE__ */ jsx12(
|
|
3348
|
+
children: pinningKeys.has(row.key) ? /* @__PURE__ */ jsx12(SpinnerIcon, { className: "h-3 w-3 animate-spin" }) : /* @__PURE__ */ jsx12(
|
|
3234
3349
|
PinIcon,
|
|
3235
3350
|
{
|
|
3236
3351
|
className: cn8(
|