@ai-matrx/associations 0.3.0 → 0.4.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 +54 -0
- package/dist/core/index.cjs +71 -0
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +19 -1
- package/dist/core/index.d.ts +19 -1
- package/dist/core/index.js +71 -0
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -2
- package/dist/index.d.ts +50 -2
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +747 -0
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +85 -2
- package/dist/react/index.d.ts +85 -2
- package/dist/react/index.js +784 -0
- package/dist/react/index.js.map +1 -1
- package/package.json +4 -4
package/dist/react/index.js
CHANGED
|
@@ -503,6 +503,7 @@ var ENTITY_TYPE_TOKENS = [
|
|
|
503
503
|
"platform_actor_session",
|
|
504
504
|
"platform_actor_token",
|
|
505
505
|
"platform_actor_token_event",
|
|
506
|
+
"platform_continued_access",
|
|
506
507
|
"platform_outcome_event",
|
|
507
508
|
"platform_outsider_consumer",
|
|
508
509
|
"platform_saved_view",
|
|
@@ -531,6 +532,7 @@ var ENTITY_TYPE_TOKENS = [
|
|
|
531
532
|
"research_tag",
|
|
532
533
|
"research_template",
|
|
533
534
|
"research_topic",
|
|
535
|
+
"route_manifest_entry",
|
|
534
536
|
"rulebook",
|
|
535
537
|
"sandbox_instance",
|
|
536
538
|
"sch_agent_task",
|
|
@@ -609,6 +611,7 @@ var ENTITY_TYPE_TOKENS = [
|
|
|
609
611
|
"seo_topic",
|
|
610
612
|
"seo_web_analytics_daily",
|
|
611
613
|
"shared_canvas_item",
|
|
614
|
+
"short_link",
|
|
612
615
|
"skill",
|
|
613
616
|
"skill_render_definition",
|
|
614
617
|
"sms_consent",
|
|
@@ -1418,6 +1421,27 @@ function ExternalLinkIcon(props) {
|
|
|
1418
1421
|
/* @__PURE__ */ jsx3("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" })
|
|
1419
1422
|
] });
|
|
1420
1423
|
}
|
|
1424
|
+
function ChevronDownIcon(props) {
|
|
1425
|
+
return /* @__PURE__ */ jsx3("svg", { ...base(props), children: /* @__PURE__ */ jsx3("path", { d: "m6 9 6 6 6-6" }) });
|
|
1426
|
+
}
|
|
1427
|
+
function ChevronsUpDownIcon(props) {
|
|
1428
|
+
return /* @__PURE__ */ jsxs("svg", { ...base(props), children: [
|
|
1429
|
+
/* @__PURE__ */ jsx3("path", { d: "m7 15 5 5 5-5" }),
|
|
1430
|
+
/* @__PURE__ */ jsx3("path", { d: "m7 9 5-5 5 5" })
|
|
1431
|
+
] });
|
|
1432
|
+
}
|
|
1433
|
+
function CornerDownRightIcon(props) {
|
|
1434
|
+
return /* @__PURE__ */ jsxs("svg", { ...base(props), children: [
|
|
1435
|
+
/* @__PURE__ */ jsx3("polyline", { points: "15 10 20 15 15 20" }),
|
|
1436
|
+
/* @__PURE__ */ jsx3("path", { d: "M4 4v7a4 4 0 0 0 4 4h12" })
|
|
1437
|
+
] });
|
|
1438
|
+
}
|
|
1439
|
+
function TagIcon(props) {
|
|
1440
|
+
return /* @__PURE__ */ jsxs("svg", { ...base(props), children: [
|
|
1441
|
+
/* @__PURE__ */ jsx3("path", { d: "M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z" }),
|
|
1442
|
+
/* @__PURE__ */ jsx3("circle", { cx: "7.5", cy: "7.5", r: ".5", fill: "currentColor" })
|
|
1443
|
+
] });
|
|
1444
|
+
}
|
|
1421
1445
|
function DefaultEntityIcon(props) {
|
|
1422
1446
|
return /* @__PURE__ */ jsxs("svg", { ...base(props), children: [
|
|
1423
1447
|
/* @__PURE__ */ jsx3("path", { d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" }),
|
|
@@ -3106,11 +3130,769 @@ function CaptureToolbarAction({
|
|
|
3106
3130
|
}
|
|
3107
3131
|
);
|
|
3108
3132
|
}
|
|
3133
|
+
|
|
3134
|
+
// src/react/components/AssociationEntitySelect.tsx
|
|
3135
|
+
import { useState as useState12 } from "react";
|
|
3136
|
+
import {
|
|
3137
|
+
cn as cn10,
|
|
3138
|
+
Command,
|
|
3139
|
+
CommandEmpty,
|
|
3140
|
+
CommandGroup,
|
|
3141
|
+
CommandInput,
|
|
3142
|
+
CommandItem,
|
|
3143
|
+
CommandList,
|
|
3144
|
+
EditableLabel,
|
|
3145
|
+
Popover,
|
|
3146
|
+
PopoverContent,
|
|
3147
|
+
PopoverTrigger
|
|
3148
|
+
} from "@ai-matrx/design-system";
|
|
3149
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3150
|
+
function AssociationEntitySelect({
|
|
3151
|
+
token,
|
|
3152
|
+
adapter,
|
|
3153
|
+
className,
|
|
3154
|
+
labelClassName,
|
|
3155
|
+
align = "end",
|
|
3156
|
+
showIcon = true,
|
|
3157
|
+
renameActivation = "click",
|
|
3158
|
+
emptyLabel,
|
|
3159
|
+
iconClassName,
|
|
3160
|
+
createSlot
|
|
3161
|
+
}) {
|
|
3162
|
+
const store = useAssociationsStore();
|
|
3163
|
+
const { entityDoors } = useAssociationsUiPorts();
|
|
3164
|
+
const notifier = useNotifier();
|
|
3165
|
+
const info = store.registry.getEntityInfo(token);
|
|
3166
|
+
const InfoIcon = info.Icon ?? DefaultEntityIcon;
|
|
3167
|
+
const DoorControls = entityDoors?.DoorControls;
|
|
3168
|
+
const { items, activeId } = adapter;
|
|
3169
|
+
const active = items.find((i) => i.id === activeId) ?? null;
|
|
3170
|
+
const activeIndex = active ? items.indexOf(active) : -1;
|
|
3171
|
+
const [open, setOpen] = useState12(false);
|
|
3172
|
+
const [query, setQuery] = useState12("");
|
|
3173
|
+
const [creating, setCreating] = useState12(false);
|
|
3174
|
+
const [draftName, setDraftName] = useState12("");
|
|
3175
|
+
const [busy, setBusy] = useState12(false);
|
|
3176
|
+
const entityLabel = info.label.toLowerCase();
|
|
3177
|
+
const close = () => {
|
|
3178
|
+
setOpen(false);
|
|
3179
|
+
setQuery("");
|
|
3180
|
+
setCreating(false);
|
|
3181
|
+
setDraftName("");
|
|
3182
|
+
};
|
|
3183
|
+
const create = async (title) => {
|
|
3184
|
+
const name = title.trim();
|
|
3185
|
+
if (!name || busy || !adapter.createAndAttach) return;
|
|
3186
|
+
setBusy(true);
|
|
3187
|
+
const id = await adapter.createAndAttach(name);
|
|
3188
|
+
setBusy(false);
|
|
3189
|
+
if (id) close();
|
|
3190
|
+
else notifier.error(`Couldn't create the ${entityLabel}`);
|
|
3191
|
+
};
|
|
3192
|
+
return /* @__PURE__ */ jsxs11(
|
|
3193
|
+
"div",
|
|
3194
|
+
{
|
|
3195
|
+
className: cn10(
|
|
3196
|
+
"group/entity-ref flex min-w-0 items-center gap-0.5",
|
|
3197
|
+
className
|
|
3198
|
+
),
|
|
3199
|
+
children: [
|
|
3200
|
+
showIcon ? /* @__PURE__ */ jsx13(
|
|
3201
|
+
InfoIcon,
|
|
3202
|
+
{
|
|
3203
|
+
className: cn10(
|
|
3204
|
+
"size-3.5 shrink-0",
|
|
3205
|
+
iconClassName ?? "text-muted-foreground"
|
|
3206
|
+
),
|
|
3207
|
+
"aria-hidden": true
|
|
3208
|
+
}
|
|
3209
|
+
) : null,
|
|
3210
|
+
active ? /* @__PURE__ */ jsx13(
|
|
3211
|
+
EditableLabel,
|
|
3212
|
+
{
|
|
3213
|
+
value: active.title,
|
|
3214
|
+
onCommit: async (next) => {
|
|
3215
|
+
const ok = await adapter.rename(active.id, next);
|
|
3216
|
+
if (!ok) {
|
|
3217
|
+
notifier.error(`Couldn't rename the ${entityLabel}`);
|
|
3218
|
+
throw new Error("rename failed");
|
|
3219
|
+
}
|
|
3220
|
+
},
|
|
3221
|
+
commitMode: "await",
|
|
3222
|
+
activation: renameActivation,
|
|
3223
|
+
ariaLabel: info.label,
|
|
3224
|
+
className: cn10("max-w-[14rem]", labelClassName),
|
|
3225
|
+
displayClassName: "text-xs font-medium text-foreground",
|
|
3226
|
+
inputClassName: "text-xs font-medium"
|
|
3227
|
+
}
|
|
3228
|
+
) : null,
|
|
3229
|
+
active && DoorControls ? /* @__PURE__ */ jsx13(DoorControls, { token, id: active.id, name: active.title }) : null,
|
|
3230
|
+
!active ? /* @__PURE__ */ jsx13(
|
|
3231
|
+
"span",
|
|
3232
|
+
{
|
|
3233
|
+
className: cn10(
|
|
3234
|
+
"truncate px-1 text-xs font-medium text-muted-foreground",
|
|
3235
|
+
labelClassName
|
|
3236
|
+
),
|
|
3237
|
+
children: adapter.loading ? "\u2026" : emptyLabel ?? info.labelPlural
|
|
3238
|
+
}
|
|
3239
|
+
) : null,
|
|
3240
|
+
/* @__PURE__ */ jsxs11(
|
|
3241
|
+
Popover,
|
|
3242
|
+
{
|
|
3243
|
+
open,
|
|
3244
|
+
onOpenChange: (next) => next ? setOpen(true) : close(),
|
|
3245
|
+
children: [
|
|
3246
|
+
/* @__PURE__ */ jsx13(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(
|
|
3247
|
+
"button",
|
|
3248
|
+
{
|
|
3249
|
+
type: "button",
|
|
3250
|
+
className: "inline-flex h-6 shrink-0 items-center gap-0.5 rounded-md px-1 text-[10px] font-medium text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
3251
|
+
title: `Switch or add ${info.labelPlural.toLowerCase()}`,
|
|
3252
|
+
"aria-label": `Switch or add ${info.labelPlural.toLowerCase()}`,
|
|
3253
|
+
children: [
|
|
3254
|
+
items.length > 1 ? /* @__PURE__ */ jsxs11("span", { className: "tabular-nums", children: [
|
|
3255
|
+
activeIndex >= 0 ? activeIndex + 1 : "\u2014",
|
|
3256
|
+
"/",
|
|
3257
|
+
items.length
|
|
3258
|
+
] }) : null,
|
|
3259
|
+
/* @__PURE__ */ jsx13(ChevronDownIcon, { className: "size-3 opacity-60" })
|
|
3260
|
+
]
|
|
3261
|
+
}
|
|
3262
|
+
) }),
|
|
3263
|
+
/* @__PURE__ */ jsx13(PopoverContent, { className: "w-60 p-0", align, children: /* @__PURE__ */ jsxs11(Command, { children: [
|
|
3264
|
+
items.length > 5 ? /* @__PURE__ */ jsx13(
|
|
3265
|
+
CommandInput,
|
|
3266
|
+
{
|
|
3267
|
+
value: query,
|
|
3268
|
+
onValueChange: setQuery,
|
|
3269
|
+
placeholder: `Search ${info.labelPlural.toLowerCase()}\u2026`
|
|
3270
|
+
}
|
|
3271
|
+
) : null,
|
|
3272
|
+
/* @__PURE__ */ jsxs11(CommandList, { children: [
|
|
3273
|
+
/* @__PURE__ */ jsx13(CommandEmpty, { children: "No match." }),
|
|
3274
|
+
items.length > 0 ? /* @__PURE__ */ jsx13(CommandGroup, { children: items.map((item) => /* @__PURE__ */ jsxs11(
|
|
3275
|
+
CommandItem,
|
|
3276
|
+
{
|
|
3277
|
+
value: `${item.title} ${item.id}`,
|
|
3278
|
+
onSelect: () => {
|
|
3279
|
+
if (item.id !== activeId)
|
|
3280
|
+
void adapter.setActive(item.id);
|
|
3281
|
+
close();
|
|
3282
|
+
},
|
|
3283
|
+
className: "group/entity-ref group gap-2",
|
|
3284
|
+
children: [
|
|
3285
|
+
/* @__PURE__ */ jsx13(
|
|
3286
|
+
CheckIcon,
|
|
3287
|
+
{
|
|
3288
|
+
className: cn10(
|
|
3289
|
+
"size-3.5 shrink-0",
|
|
3290
|
+
item.id === activeId ? "opacity-100" : "opacity-0"
|
|
3291
|
+
)
|
|
3292
|
+
}
|
|
3293
|
+
),
|
|
3294
|
+
/* @__PURE__ */ jsx13("span", { className: "min-w-0 flex-1 truncate", children: item.title }),
|
|
3295
|
+
DoorControls ? /* @__PURE__ */ jsx13(
|
|
3296
|
+
"span",
|
|
3297
|
+
{
|
|
3298
|
+
className: "inline-flex shrink-0 items-center",
|
|
3299
|
+
onPointerDown: (e) => {
|
|
3300
|
+
e.preventDefault();
|
|
3301
|
+
e.stopPropagation();
|
|
3302
|
+
},
|
|
3303
|
+
children: /* @__PURE__ */ jsx13(
|
|
3304
|
+
DoorControls,
|
|
3305
|
+
{
|
|
3306
|
+
token,
|
|
3307
|
+
id: item.id,
|
|
3308
|
+
name: item.title
|
|
3309
|
+
}
|
|
3310
|
+
)
|
|
3311
|
+
}
|
|
3312
|
+
) : null,
|
|
3313
|
+
adapter.detach && item.id !== activeId ? /* @__PURE__ */ jsx13(
|
|
3314
|
+
"button",
|
|
3315
|
+
{
|
|
3316
|
+
type: "button",
|
|
3317
|
+
onPointerDown: (e) => {
|
|
3318
|
+
e.preventDefault();
|
|
3319
|
+
e.stopPropagation();
|
|
3320
|
+
},
|
|
3321
|
+
onClick: (e) => {
|
|
3322
|
+
e.stopPropagation();
|
|
3323
|
+
void adapter.detach?.(item.id);
|
|
3324
|
+
},
|
|
3325
|
+
className: "grid size-5 shrink-0 place-items-center rounded text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-destructive group-hover:opacity-100",
|
|
3326
|
+
title: `Remove this ${entityLabel} from here (does not delete it)`,
|
|
3327
|
+
"aria-label": `Remove ${item.title}`,
|
|
3328
|
+
children: /* @__PURE__ */ jsx13(XIcon, { className: "size-3" })
|
|
3329
|
+
}
|
|
3330
|
+
) : null
|
|
3331
|
+
]
|
|
3332
|
+
},
|
|
3333
|
+
item.id
|
|
3334
|
+
)) }) : null
|
|
3335
|
+
] }),
|
|
3336
|
+
createSlot !== void 0 ? /* @__PURE__ */ jsx13("div", { className: "border-t border-border p-1", children: typeof createSlot === "function" ? createSlot(close) : createSlot }) : null,
|
|
3337
|
+
createSlot === void 0 && adapter.createAndAttach ? /* @__PURE__ */ jsx13("div", { className: "border-t border-border p-1", children: creating ? /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 px-1 py-0.5", children: [
|
|
3338
|
+
/* @__PURE__ */ jsx13(
|
|
3339
|
+
"input",
|
|
3340
|
+
{
|
|
3341
|
+
autoFocus: true,
|
|
3342
|
+
type: "text",
|
|
3343
|
+
value: draftName,
|
|
3344
|
+
disabled: busy,
|
|
3345
|
+
placeholder: `New ${entityLabel} name\u2026`,
|
|
3346
|
+
onChange: (e) => setDraftName(e.target.value),
|
|
3347
|
+
onKeyDown: (e) => {
|
|
3348
|
+
if (e.key === "Enter") {
|
|
3349
|
+
e.preventDefault();
|
|
3350
|
+
void create(draftName);
|
|
3351
|
+
} else if (e.key === "Escape") {
|
|
3352
|
+
e.preventDefault();
|
|
3353
|
+
e.stopPropagation();
|
|
3354
|
+
setCreating(false);
|
|
3355
|
+
setDraftName("");
|
|
3356
|
+
}
|
|
3357
|
+
},
|
|
3358
|
+
className: "h-6 w-full min-w-0 rounded-sm bg-transparent px-1 text-base outline-none focus:bg-background focus:ring-1 focus:ring-ring md:text-xs",
|
|
3359
|
+
"aria-label": `New ${entityLabel} name`
|
|
3360
|
+
}
|
|
3361
|
+
),
|
|
3362
|
+
/* @__PURE__ */ jsx13(
|
|
3363
|
+
"button",
|
|
3364
|
+
{
|
|
3365
|
+
type: "button",
|
|
3366
|
+
disabled: busy || !draftName.trim(),
|
|
3367
|
+
onClick: () => void create(draftName),
|
|
3368
|
+
className: "inline-flex h-6 shrink-0 items-center rounded-md px-1.5 text-[10px] font-medium text-primary transition-colors hover:bg-accent disabled:opacity-50",
|
|
3369
|
+
children: busy ? /* @__PURE__ */ jsx13(SpinnerIcon, { className: "size-3 animate-spin" }) : "Create"
|
|
3370
|
+
}
|
|
3371
|
+
)
|
|
3372
|
+
] }) : /* @__PURE__ */ jsxs11(
|
|
3373
|
+
"button",
|
|
3374
|
+
{
|
|
3375
|
+
type: "button",
|
|
3376
|
+
disabled: busy,
|
|
3377
|
+
onClick: () => {
|
|
3378
|
+
if (query.trim()) void create(query);
|
|
3379
|
+
else setCreating(true);
|
|
3380
|
+
},
|
|
3381
|
+
className: "flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-xs text-muted-foreground transition-colors hover:bg-accent hover:text-foreground",
|
|
3382
|
+
children: [
|
|
3383
|
+
busy ? /* @__PURE__ */ jsx13(SpinnerIcon, { className: "size-3.5 animate-spin" }) : /* @__PURE__ */ jsx13(PlusIcon, { className: "size-3.5" }),
|
|
3384
|
+
query.trim() ? `Create "${query.trim()}"` : `New ${info.label}`
|
|
3385
|
+
]
|
|
3386
|
+
}
|
|
3387
|
+
) }) : null
|
|
3388
|
+
] }) })
|
|
3389
|
+
]
|
|
3390
|
+
}
|
|
3391
|
+
)
|
|
3392
|
+
]
|
|
3393
|
+
}
|
|
3394
|
+
);
|
|
3395
|
+
}
|
|
3396
|
+
|
|
3397
|
+
// src/react/components/CategorySelect.tsx
|
|
3398
|
+
import { useState as useState13 } from "react";
|
|
3399
|
+
import {
|
|
3400
|
+
CreatablePicker,
|
|
3401
|
+
Select,
|
|
3402
|
+
SelectContent,
|
|
3403
|
+
SelectItem,
|
|
3404
|
+
SelectTrigger,
|
|
3405
|
+
SelectValue
|
|
3406
|
+
} from "@ai-matrx/design-system";
|
|
3407
|
+
|
|
3408
|
+
// src/core/categoryHierarchy.ts
|
|
3409
|
+
function buildCategoryHierarchy(categories) {
|
|
3410
|
+
const byId = new Map(categories.map((category) => [category.id, category]));
|
|
3411
|
+
const hasHierarchy = categories.some(
|
|
3412
|
+
(category) => category.parentId !== null && byId.has(category.parentId)
|
|
3413
|
+
);
|
|
3414
|
+
if (!hasHierarchy) {
|
|
3415
|
+
return {
|
|
3416
|
+
items: categories.map((category) => ({
|
|
3417
|
+
category,
|
|
3418
|
+
depth: 0,
|
|
3419
|
+
parent: null,
|
|
3420
|
+
displayName: category.name
|
|
3421
|
+
})),
|
|
3422
|
+
roots: categories.filter((category) => category.parentId === null),
|
|
3423
|
+
hasHierarchy: false
|
|
3424
|
+
};
|
|
3425
|
+
}
|
|
3426
|
+
const roots = categories.filter(
|
|
3427
|
+
(category) => category.parentId === null || !byId.has(category.parentId)
|
|
3428
|
+
);
|
|
3429
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
3430
|
+
for (const category of categories) {
|
|
3431
|
+
if (!category.parentId || !byId.has(category.parentId)) continue;
|
|
3432
|
+
const children = childrenByParent.get(category.parentId) ?? [];
|
|
3433
|
+
children.push(category);
|
|
3434
|
+
childrenByParent.set(category.parentId, children);
|
|
3435
|
+
}
|
|
3436
|
+
const items = [];
|
|
3437
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3438
|
+
for (const root of roots) {
|
|
3439
|
+
items.push({
|
|
3440
|
+
category: root,
|
|
3441
|
+
depth: 0,
|
|
3442
|
+
parent: null,
|
|
3443
|
+
displayName: root.name
|
|
3444
|
+
});
|
|
3445
|
+
seen.add(root.id);
|
|
3446
|
+
for (const child of childrenByParent.get(root.id) ?? []) {
|
|
3447
|
+
items.push({
|
|
3448
|
+
category: child,
|
|
3449
|
+
depth: 1,
|
|
3450
|
+
parent: root,
|
|
3451
|
+
displayName: `${root.name} / ${child.name}`
|
|
3452
|
+
});
|
|
3453
|
+
seen.add(child.id);
|
|
3454
|
+
}
|
|
3455
|
+
}
|
|
3456
|
+
for (const category of categories) {
|
|
3457
|
+
if (seen.has(category.id)) continue;
|
|
3458
|
+
items.push({
|
|
3459
|
+
category,
|
|
3460
|
+
depth: 0,
|
|
3461
|
+
parent: null,
|
|
3462
|
+
displayName: category.name
|
|
3463
|
+
});
|
|
3464
|
+
}
|
|
3465
|
+
return {
|
|
3466
|
+
items,
|
|
3467
|
+
roots: categories.filter((category) => category.parentId === null),
|
|
3468
|
+
hasHierarchy: true
|
|
3469
|
+
};
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3472
|
+
// src/react/components/CategorySelect.tsx
|
|
3473
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3474
|
+
var NONE = "__none__";
|
|
3475
|
+
var ROOT_PARENT = "__root__";
|
|
3476
|
+
function plural(noun) {
|
|
3477
|
+
return /[^aeiou]y$/i.test(noun) ? `${noun.slice(0, -1)}ies` : `${noun}s`;
|
|
3478
|
+
}
|
|
3479
|
+
function CategorySelect({
|
|
3480
|
+
dimension,
|
|
3481
|
+
value,
|
|
3482
|
+
onChange,
|
|
3483
|
+
placeholder,
|
|
3484
|
+
allowNone = true,
|
|
3485
|
+
disabled,
|
|
3486
|
+
allowCreate = true,
|
|
3487
|
+
orgId,
|
|
3488
|
+
noun = "category"
|
|
3489
|
+
}) {
|
|
3490
|
+
const store = useAssociationsStore();
|
|
3491
|
+
const notifier = useNotifier();
|
|
3492
|
+
const {
|
|
3493
|
+
categories,
|
|
3494
|
+
status,
|
|
3495
|
+
error,
|
|
3496
|
+
create: createCategory,
|
|
3497
|
+
reload
|
|
3498
|
+
} = useCategories({ dimension });
|
|
3499
|
+
const hierarchy = buildCategoryHierarchy(categories);
|
|
3500
|
+
const [createParentId, setCreateParentId] = useState13(ROOT_PARENT);
|
|
3501
|
+
const options = [
|
|
3502
|
+
...allowNone ? [{ value: NONE, label: "None", keywords: "none clear empty" }] : [],
|
|
3503
|
+
...hierarchy.hasHierarchy ? hierarchy.items.map(({ category, depth, parent }) => ({
|
|
3504
|
+
value: category.id,
|
|
3505
|
+
label: category.name,
|
|
3506
|
+
// The type-ahead matches the parent's name too, so someone who knows
|
|
3507
|
+
// the branch but not the leaf still finds it.
|
|
3508
|
+
keywords: parent ? parent.name : "",
|
|
3509
|
+
render: depth === 0 ? /* @__PURE__ */ jsx14("span", { className: "font-medium", children: category.name }) : /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-1.5 pl-3 text-muted-foreground", children: [
|
|
3510
|
+
/* @__PURE__ */ jsx14(CornerDownRightIcon, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
3511
|
+
/* @__PURE__ */ jsx14("span", { className: "text-foreground", children: category.name })
|
|
3512
|
+
] })
|
|
3513
|
+
})) : categories.map((category) => ({
|
|
3514
|
+
value: category.id,
|
|
3515
|
+
label: category.name
|
|
3516
|
+
}))
|
|
3517
|
+
];
|
|
3518
|
+
const selected = value ? hierarchy.items.find((item) => item.category.id === value)?.displayName ?? categories.find((category) => category.id === value)?.name ?? null : null;
|
|
3519
|
+
const create = async (typed) => {
|
|
3520
|
+
const name = typed.trim();
|
|
3521
|
+
if (!name) return null;
|
|
3522
|
+
const existing = categories.find(
|
|
3523
|
+
(category) => category.name.toLowerCase() === name.toLowerCase()
|
|
3524
|
+
);
|
|
3525
|
+
if (existing) return existing.id;
|
|
3526
|
+
let resolvedOrgId = orgId ?? null;
|
|
3527
|
+
if (!resolvedOrgId && store.identity.ensureOrgId) {
|
|
3528
|
+
try {
|
|
3529
|
+
resolvedOrgId = await store.identity.ensureOrgId();
|
|
3530
|
+
} catch (e) {
|
|
3531
|
+
store.errorSink({
|
|
3532
|
+
code: "ensure_org_failed",
|
|
3533
|
+
message: "[CategorySelect] identity.ensureOrgId threw",
|
|
3534
|
+
context: { error: e instanceof Error ? e.message : String(e) }
|
|
3535
|
+
});
|
|
3536
|
+
}
|
|
3537
|
+
}
|
|
3538
|
+
if (!resolvedOrgId) {
|
|
3539
|
+
notifier.error(`Select an organization before creating a ${noun}.`);
|
|
3540
|
+
return null;
|
|
3541
|
+
}
|
|
3542
|
+
const parentId = hierarchy.hasHierarchy && createParentId !== ROOT_PARENT ? createParentId : null;
|
|
3543
|
+
const result = await createCategory({ name, orgId: resolvedOrgId, parentId });
|
|
3544
|
+
if (!result.ok || !result.id) {
|
|
3545
|
+
notifier.error(`Couldn't create that ${noun}`, {
|
|
3546
|
+
...result.error != null ? { description: result.error } : {}
|
|
3547
|
+
});
|
|
3548
|
+
return null;
|
|
3549
|
+
}
|
|
3550
|
+
await reload();
|
|
3551
|
+
setCreateParentId(ROOT_PARENT);
|
|
3552
|
+
const under = parentId ? categories.find((category) => category.id === parentId)?.name : null;
|
|
3553
|
+
notifier.success(
|
|
3554
|
+
`\u201C${name}\u201D is now one of your ${plural(noun)}${under ? ` \u2014 it sits under ${under}, and every screen that offers ${plural(noun)} offers it.` : ` \u2014 every screen that offers ${plural(noun)} offers it from now on.`}`
|
|
3555
|
+
);
|
|
3556
|
+
return result.id;
|
|
3557
|
+
};
|
|
3558
|
+
return /* @__PURE__ */ jsxs12("div", { children: [
|
|
3559
|
+
/* @__PURE__ */ jsx14(
|
|
3560
|
+
CreatablePicker,
|
|
3561
|
+
{
|
|
3562
|
+
value: value ?? (allowNone ? NONE : null),
|
|
3563
|
+
onSelect: (next) => onChange(next === NONE ? null : next),
|
|
3564
|
+
options,
|
|
3565
|
+
placeholder,
|
|
3566
|
+
searchPlaceholder: allowCreate ? `Search or add a ${noun}\u2026` : `Search ${plural(noun)}\u2026`,
|
|
3567
|
+
noun,
|
|
3568
|
+
ariaLabel: placeholder,
|
|
3569
|
+
className: "text-sm",
|
|
3570
|
+
...disabled !== void 0 ? { disabled } : {},
|
|
3571
|
+
loading: status === "loading",
|
|
3572
|
+
emptyLabel: `No ${noun} matches that.`,
|
|
3573
|
+
...allowCreate ? { onCreate: create } : {},
|
|
3574
|
+
...allowCreate && hierarchy.hasHierarchy ? {
|
|
3575
|
+
createExtra: /* @__PURE__ */ jsxs12(Select, { value: createParentId, onValueChange: setCreateParentId, children: [
|
|
3576
|
+
/* @__PURE__ */ jsx14(
|
|
3577
|
+
SelectTrigger,
|
|
3578
|
+
{
|
|
3579
|
+
className: "h-7 text-xs",
|
|
3580
|
+
"aria-label": `Put the new ${noun} under`,
|
|
3581
|
+
children: /* @__PURE__ */ jsx14(SelectValue, {})
|
|
3582
|
+
}
|
|
3583
|
+
),
|
|
3584
|
+
/* @__PURE__ */ jsxs12(SelectContent, { children: [
|
|
3585
|
+
/* @__PURE__ */ jsx14(SelectItem, { value: ROOT_PARENT, className: "text-xs", children: "Top level" }),
|
|
3586
|
+
hierarchy.items.filter((item) => item.depth === 0).map((item) => /* @__PURE__ */ jsxs12(
|
|
3587
|
+
SelectItem,
|
|
3588
|
+
{
|
|
3589
|
+
value: item.category.id,
|
|
3590
|
+
className: "text-xs",
|
|
3591
|
+
children: [
|
|
3592
|
+
"Under ",
|
|
3593
|
+
item.category.name
|
|
3594
|
+
]
|
|
3595
|
+
},
|
|
3596
|
+
item.category.id
|
|
3597
|
+
))
|
|
3598
|
+
] })
|
|
3599
|
+
] })
|
|
3600
|
+
} : {}
|
|
3601
|
+
}
|
|
3602
|
+
),
|
|
3603
|
+
selected === null && value !== null ? (
|
|
3604
|
+
// A stored id whose row this reader cannot see is not "nothing chosen":
|
|
3605
|
+
// saying so beats a blank box that looks like an unsaved field.
|
|
3606
|
+
/* @__PURE__ */ jsxs12("p", { className: "mt-1 text-xs text-muted-foreground", children: [
|
|
3607
|
+
"This ",
|
|
3608
|
+
noun,
|
|
3609
|
+
" is no longer available to you."
|
|
3610
|
+
] })
|
|
3611
|
+
) : null,
|
|
3612
|
+
error ? /* @__PURE__ */ jsx14("p", { className: "mt-1 text-xs text-destructive", children: error }) : null
|
|
3613
|
+
] });
|
|
3614
|
+
}
|
|
3615
|
+
|
|
3616
|
+
// src/react/components/CategoryTagPicker.tsx
|
|
3617
|
+
import { useState as useState14 } from "react";
|
|
3618
|
+
import {
|
|
3619
|
+
Badge,
|
|
3620
|
+
Button as Button2,
|
|
3621
|
+
cn as cn11,
|
|
3622
|
+
Command as Command2,
|
|
3623
|
+
CommandEmpty as CommandEmpty2,
|
|
3624
|
+
CommandGroup as CommandGroup2,
|
|
3625
|
+
CommandInput as CommandInput2,
|
|
3626
|
+
CommandItem as CommandItem2,
|
|
3627
|
+
CommandList as CommandList2,
|
|
3628
|
+
Popover as Popover2,
|
|
3629
|
+
PopoverContent as PopoverContent2,
|
|
3630
|
+
PopoverTrigger as PopoverTrigger2,
|
|
3631
|
+
Select as Select2,
|
|
3632
|
+
SelectContent as SelectContent2,
|
|
3633
|
+
SelectItem as SelectItem2,
|
|
3634
|
+
SelectTrigger as SelectTrigger2,
|
|
3635
|
+
SelectValue as SelectValue2
|
|
3636
|
+
} from "@ai-matrx/design-system";
|
|
3637
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3638
|
+
var ROOT_PARENT2 = "__root__";
|
|
3639
|
+
function CategoryTagPicker({
|
|
3640
|
+
entityType,
|
|
3641
|
+
entityId,
|
|
3642
|
+
dimension,
|
|
3643
|
+
edgeRole,
|
|
3644
|
+
orgId,
|
|
3645
|
+
addLabel = "Add tag",
|
|
3646
|
+
icon: Icon = TagIcon,
|
|
3647
|
+
allowCreate = true,
|
|
3648
|
+
hierarchical,
|
|
3649
|
+
emptyText = "No categories yet."
|
|
3650
|
+
}) {
|
|
3651
|
+
const store = useAssociationsStore();
|
|
3652
|
+
const notifier = useNotifier();
|
|
3653
|
+
const [open, setOpen] = useState14(false);
|
|
3654
|
+
const [creating, setCreating] = useState14(false);
|
|
3655
|
+
const [writing, setWriting] = useState14(false);
|
|
3656
|
+
const [search, setSearch] = useState14("");
|
|
3657
|
+
const [createParentId, setCreateParentId] = useState14(ROOT_PARENT2);
|
|
3658
|
+
const {
|
|
3659
|
+
categories,
|
|
3660
|
+
create: createCategory,
|
|
3661
|
+
reload: reloadCategories
|
|
3662
|
+
} = useCategories({ dimension });
|
|
3663
|
+
const { edges, setTargets } = useAssociations({
|
|
3664
|
+
type: entityType,
|
|
3665
|
+
id: entityId
|
|
3666
|
+
});
|
|
3667
|
+
const hierarchy = buildCategoryHierarchy(categories);
|
|
3668
|
+
const showHierarchy = hierarchical ?? hierarchy.hasHierarchy;
|
|
3669
|
+
const hierarchyById = new Map(
|
|
3670
|
+
hierarchy.items.map((item) => [item.category.id, item])
|
|
3671
|
+
);
|
|
3672
|
+
const selectedIds = new Set(
|
|
3673
|
+
edges.filter(
|
|
3674
|
+
(e) => e.direction === "outgoing" && e.otherType === "category" && e.role === edgeRole
|
|
3675
|
+
).map((e) => e.otherId)
|
|
3676
|
+
);
|
|
3677
|
+
const selected = categories.filter((c) => selectedIds.has(c.id));
|
|
3678
|
+
const toggle = async (categoryId) => {
|
|
3679
|
+
if (writing) return;
|
|
3680
|
+
setWriting(true);
|
|
3681
|
+
try {
|
|
3682
|
+
const next = selectedIds.has(categoryId) ? [...selectedIds].filter((id) => id !== categoryId) : [...selectedIds, categoryId];
|
|
3683
|
+
const res = await setTargets({
|
|
3684
|
+
targetType: "category",
|
|
3685
|
+
targetIds: next,
|
|
3686
|
+
...orgId != null ? { orgId } : {},
|
|
3687
|
+
role: edgeRole
|
|
3688
|
+
});
|
|
3689
|
+
if (!res.ok) {
|
|
3690
|
+
store.errorSink({
|
|
3691
|
+
code: "category_tag_set_targets_failed",
|
|
3692
|
+
message: "[CategoryTagPicker] setTargets failed",
|
|
3693
|
+
context: { entityType, entityId, edgeRole, error: res.error }
|
|
3694
|
+
});
|
|
3695
|
+
notifier.error(res.error ?? "Could not update categories");
|
|
3696
|
+
}
|
|
3697
|
+
} finally {
|
|
3698
|
+
setWriting(false);
|
|
3699
|
+
}
|
|
3700
|
+
};
|
|
3701
|
+
const createAndAttach = async () => {
|
|
3702
|
+
const name = search.trim();
|
|
3703
|
+
if (!name) return;
|
|
3704
|
+
setCreating(true);
|
|
3705
|
+
try {
|
|
3706
|
+
let resolvedOrgId = orgId ?? null;
|
|
3707
|
+
if (!resolvedOrgId && store.identity.ensureOrgId) {
|
|
3708
|
+
try {
|
|
3709
|
+
resolvedOrgId = await store.identity.ensureOrgId();
|
|
3710
|
+
} catch (e) {
|
|
3711
|
+
store.errorSink({
|
|
3712
|
+
code: "ensure_org_failed",
|
|
3713
|
+
message: "[CategoryTagPicker] identity.ensureOrgId threw",
|
|
3714
|
+
context: { error: e instanceof Error ? e.message : String(e) }
|
|
3715
|
+
});
|
|
3716
|
+
}
|
|
3717
|
+
}
|
|
3718
|
+
if (!resolvedOrgId) {
|
|
3719
|
+
store.errorSink({
|
|
3720
|
+
code: "ensure_org_missing",
|
|
3721
|
+
message: "[CategoryTagPicker] no org for the created category \u2014 pass `orgId` or bind `identity.ensureOrgId` on the store config",
|
|
3722
|
+
context: { entityType, entityId, dimension }
|
|
3723
|
+
});
|
|
3724
|
+
notifier.error(
|
|
3725
|
+
"Could not create the category \u2014 no organization is selected"
|
|
3726
|
+
);
|
|
3727
|
+
return;
|
|
3728
|
+
}
|
|
3729
|
+
const parentId = showHierarchy && createParentId !== ROOT_PARENT2 ? createParentId : null;
|
|
3730
|
+
const createRes = await createCategory({
|
|
3731
|
+
name,
|
|
3732
|
+
orgId: resolvedOrgId,
|
|
3733
|
+
parentId
|
|
3734
|
+
});
|
|
3735
|
+
if (!createRes.ok || !createRes.id) {
|
|
3736
|
+
store.errorSink({
|
|
3737
|
+
code: "category_tag_create_failed",
|
|
3738
|
+
message: "[CategoryTagPicker] create failed",
|
|
3739
|
+
context: { dimension, error: createRes.error }
|
|
3740
|
+
});
|
|
3741
|
+
notifier.error(createRes.error ?? "Could not create the category");
|
|
3742
|
+
return;
|
|
3743
|
+
}
|
|
3744
|
+
await reloadCategories();
|
|
3745
|
+
await toggle(createRes.id);
|
|
3746
|
+
setSearch("");
|
|
3747
|
+
setCreateParentId(ROOT_PARENT2);
|
|
3748
|
+
} finally {
|
|
3749
|
+
setCreating(false);
|
|
3750
|
+
}
|
|
3751
|
+
};
|
|
3752
|
+
const filtered = categories.filter(
|
|
3753
|
+
(c) => c.name.toLowerCase().includes(search.trim().toLowerCase())
|
|
3754
|
+
);
|
|
3755
|
+
const filteredHierarchy = hierarchy.items.filter(
|
|
3756
|
+
(item) => item.displayName.toLowerCase().includes(search.trim().toLowerCase())
|
|
3757
|
+
);
|
|
3758
|
+
const exactMatch = categories.some(
|
|
3759
|
+
(c) => c.name.toLowerCase() === search.trim().toLowerCase()
|
|
3760
|
+
);
|
|
3761
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex flex-wrap items-center gap-1.5", children: [
|
|
3762
|
+
selected.map((c) => /* @__PURE__ */ jsxs13(
|
|
3763
|
+
Badge,
|
|
3764
|
+
{
|
|
3765
|
+
variant: "secondary",
|
|
3766
|
+
className: "gap-1 pr-1 text-xs font-medium",
|
|
3767
|
+
children: [
|
|
3768
|
+
showHierarchy ? hierarchyById.get(c.id)?.displayName ?? c.name : c.name,
|
|
3769
|
+
/* @__PURE__ */ jsx15(
|
|
3770
|
+
"button",
|
|
3771
|
+
{
|
|
3772
|
+
type: "button",
|
|
3773
|
+
onClick: () => void toggle(c.id),
|
|
3774
|
+
className: "ml-0.5 rounded-full p-0.5 hover:bg-muted-foreground/20",
|
|
3775
|
+
"aria-label": `Remove ${c.name}`,
|
|
3776
|
+
children: /* @__PURE__ */ jsx15(XIcon, { className: "h-2.5 w-2.5" })
|
|
3777
|
+
}
|
|
3778
|
+
)
|
|
3779
|
+
]
|
|
3780
|
+
},
|
|
3781
|
+
c.id
|
|
3782
|
+
)),
|
|
3783
|
+
/* @__PURE__ */ jsxs13(Popover2, { open, onOpenChange: setOpen, children: [
|
|
3784
|
+
/* @__PURE__ */ jsx15(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs13(
|
|
3785
|
+
Button2,
|
|
3786
|
+
{
|
|
3787
|
+
variant: "outline",
|
|
3788
|
+
size: "sm",
|
|
3789
|
+
className: "h-7 gap-1 px-2 text-xs",
|
|
3790
|
+
children: [
|
|
3791
|
+
/* @__PURE__ */ jsx15(Icon, { className: "h-3.5 w-3.5" }),
|
|
3792
|
+
selected.length === 0 ? addLabel : "Edit",
|
|
3793
|
+
/* @__PURE__ */ jsx15(ChevronsUpDownIcon, { className: "h-3 w-3 opacity-50" })
|
|
3794
|
+
]
|
|
3795
|
+
}
|
|
3796
|
+
) }),
|
|
3797
|
+
/* @__PURE__ */ jsx15(PopoverContent2, { className: "w-56 p-0", align: "start", children: /* @__PURE__ */ jsxs13(Command2, { shouldFilter: false, children: [
|
|
3798
|
+
/* @__PURE__ */ jsx15(
|
|
3799
|
+
CommandInput2,
|
|
3800
|
+
{
|
|
3801
|
+
placeholder: allowCreate ? "Search or create..." : "Search...",
|
|
3802
|
+
value: search,
|
|
3803
|
+
onValueChange: setSearch
|
|
3804
|
+
}
|
|
3805
|
+
),
|
|
3806
|
+
/* @__PURE__ */ jsxs13(CommandList2, { children: [
|
|
3807
|
+
/* @__PURE__ */ jsx15(CommandEmpty2, { className: "px-2 py-3 text-xs text-muted-foreground", children: search.trim() ? "No match." : emptyText }),
|
|
3808
|
+
/* @__PURE__ */ jsx15(CommandGroup2, { children: showHierarchy ? filteredHierarchy.map(({ category, depth, parent }) => /* @__PURE__ */ jsxs13(
|
|
3809
|
+
CommandItem2,
|
|
3810
|
+
{
|
|
3811
|
+
value: category.id,
|
|
3812
|
+
keywords: parent ? [parent.name, category.name] : [],
|
|
3813
|
+
onSelect: () => void toggle(category.id),
|
|
3814
|
+
className: cn11("text-xs", depth === 1 && "pl-6"),
|
|
3815
|
+
children: [
|
|
3816
|
+
/* @__PURE__ */ jsx15(
|
|
3817
|
+
CheckIcon,
|
|
3818
|
+
{
|
|
3819
|
+
className: cn11(
|
|
3820
|
+
"mr-2 h-3.5 w-3.5",
|
|
3821
|
+
selectedIds.has(category.id) ? "opacity-100" : "opacity-0"
|
|
3822
|
+
)
|
|
3823
|
+
}
|
|
3824
|
+
),
|
|
3825
|
+
depth === 1 ? /* @__PURE__ */ jsx15(CornerDownRightIcon, { className: "mr-1.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }) : null,
|
|
3826
|
+
/* @__PURE__ */ jsx15("span", { className: cn11(depth === 0 && "font-medium"), children: category.name })
|
|
3827
|
+
]
|
|
3828
|
+
},
|
|
3829
|
+
category.id
|
|
3830
|
+
)) : filtered.map((c) => /* @__PURE__ */ jsxs13(
|
|
3831
|
+
CommandItem2,
|
|
3832
|
+
{
|
|
3833
|
+
value: c.id,
|
|
3834
|
+
onSelect: () => void toggle(c.id),
|
|
3835
|
+
className: "text-xs",
|
|
3836
|
+
children: [
|
|
3837
|
+
/* @__PURE__ */ jsx15(
|
|
3838
|
+
CheckIcon,
|
|
3839
|
+
{
|
|
3840
|
+
className: cn11(
|
|
3841
|
+
"mr-2 h-3.5 w-3.5",
|
|
3842
|
+
selectedIds.has(c.id) ? "opacity-100" : "opacity-0"
|
|
3843
|
+
)
|
|
3844
|
+
}
|
|
3845
|
+
),
|
|
3846
|
+
c.name
|
|
3847
|
+
]
|
|
3848
|
+
},
|
|
3849
|
+
c.id
|
|
3850
|
+
)) }),
|
|
3851
|
+
allowCreate && search.trim() && !exactMatch ? /* @__PURE__ */ jsxs13(CommandGroup2, { children: [
|
|
3852
|
+
showHierarchy ? /* @__PURE__ */ jsxs13("div", { className: "space-y-1.5 px-2 pb-2", children: [
|
|
3853
|
+
/* @__PURE__ */ jsx15("p", { className: "text-[11px] font-medium text-muted-foreground", children: "Place in" }),
|
|
3854
|
+
/* @__PURE__ */ jsxs13(
|
|
3855
|
+
Select2,
|
|
3856
|
+
{
|
|
3857
|
+
value: createParentId,
|
|
3858
|
+
onValueChange: setCreateParentId,
|
|
3859
|
+
children: [
|
|
3860
|
+
/* @__PURE__ */ jsx15(SelectTrigger2, { size: "sm", className: "bg-background", children: /* @__PURE__ */ jsx15(SelectValue2, {}) }),
|
|
3861
|
+
/* @__PURE__ */ jsxs13(SelectContent2, { children: [
|
|
3862
|
+
/* @__PURE__ */ jsx15(SelectItem2, { value: ROOT_PARENT2, children: "Top level" }),
|
|
3863
|
+
hierarchy.roots.map((root) => /* @__PURE__ */ jsx15(SelectItem2, { value: root.id, children: root.name }, root.id))
|
|
3864
|
+
] })
|
|
3865
|
+
]
|
|
3866
|
+
}
|
|
3867
|
+
)
|
|
3868
|
+
] }) : null,
|
|
3869
|
+
/* @__PURE__ */ jsxs13(
|
|
3870
|
+
CommandItem2,
|
|
3871
|
+
{
|
|
3872
|
+
value: `__create__${search}`,
|
|
3873
|
+
onSelect: () => void createAndAttach(),
|
|
3874
|
+
disabled: creating,
|
|
3875
|
+
className: "text-xs text-primary",
|
|
3876
|
+
children: [
|
|
3877
|
+
creating ? /* @__PURE__ */ jsx15(SpinnerIcon, { className: "mr-2 h-3.5 w-3.5 animate-spin" }) : /* @__PURE__ */ jsx15(Icon, { className: "mr-2 h-3.5 w-3.5" }),
|
|
3878
|
+
"Create \u201C",
|
|
3879
|
+
search.trim(),
|
|
3880
|
+
"\u201D"
|
|
3881
|
+
]
|
|
3882
|
+
}
|
|
3883
|
+
)
|
|
3884
|
+
] }) : null
|
|
3885
|
+
] })
|
|
3886
|
+
] }) })
|
|
3887
|
+
] })
|
|
3888
|
+
] });
|
|
3889
|
+
}
|
|
3109
3890
|
export {
|
|
3110
3891
|
AssociationCandidateBody,
|
|
3111
3892
|
AssociationCaptureToolbar,
|
|
3112
3893
|
AssociationCard,
|
|
3113
3894
|
AssociationCardGrid,
|
|
3895
|
+
AssociationEntitySelect,
|
|
3114
3896
|
AssociationList,
|
|
3115
3897
|
AssociationPicker,
|
|
3116
3898
|
AssociationWindow,
|
|
@@ -3118,6 +3900,8 @@ export {
|
|
|
3118
3900
|
AttachedItemsSheet,
|
|
3119
3901
|
CONTENT_ROLES,
|
|
3120
3902
|
CaptureToolbarAction,
|
|
3903
|
+
CategorySelect,
|
|
3904
|
+
CategoryTagPicker,
|
|
3121
3905
|
DefaultEntityIcon,
|
|
3122
3906
|
DoorRef,
|
|
3123
3907
|
PrimaryEntityProvider,
|