@sanity/assist 1.1.4 → 1.2.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/dist/index.esm.js CHANGED
@@ -1,13 +1,14 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useClient, typed, useSchema, useDocumentStore, useDocumentPresence, createPatchChannel, FormBuilder, fromMutationPatches, pathToString, isObjectSchemaType, useEditState, useCurrentUser, useValidationStatus, StatusButton, FormFieldHeaderText, PatchEvent, unset, PresenceOverlay, VirtualizerScrollInstanceProvider, stringToPath, isKeySegment, useColorSchemeValue, isArraySchemaType, useFormCallbacks, set, FormCallbacksProvider, FormInput, setIfMissing, insert, ObjectInputMember, defineType, defineField, defineArrayMember, getPublishedId, definePlugin } from 'sanity';
3
- import { Card, Stack, Box, Button, Spinner, Flex, Label, focusFirstDescendant, Text, useClickOutside, Popover, useLayer, useGlobalKeyDown, useToast, Dialog, Tooltip, TextArea, Container, Badge, useTheme, rgba, ThemeProvider, ErrorBoundary, Switch, MenuButton, Menu, MenuItem, Breadcrumbs, Autocomplete } from '@sanity/ui';
2
+ import { useClient, typed, useSchema, useDocumentStore, useDocumentPresence, createPatchChannel, FormBuilder, fromMutationPatches, pathToString, isObjectSchemaType, stringToPath, isKeySegment, useEditState, useCurrentUser, useValidationStatus, StatusButton, FormFieldHeaderText, PatchEvent, unset, set, useFormCallbacks, FormCallbacksProvider, FormInput, setIfMissing, insert, PresenceOverlay, VirtualizerScrollInstanceProvider, useColorSchemeValue, isArraySchemaType, ObjectInputMember, defineType, defineField, defineArrayMember, getPublishedId, definePlugin } from 'sanity';
3
+ import { Card, Stack, Box, Button, Spinner, Flex, Label, focusFirstDescendant, Text, useClickOutside, Popover, useLayer, useGlobalKeyDown, useToast, Dialog, Tooltip, TextArea, Container, Autocomplete, Breadcrumbs, Badge, useTheme, rgba, ThemeProvider, ErrorBoundary, Switch, MenuButton, Menu, MenuItem } from '@sanity/ui';
4
4
  import { useState, useRef, useEffect, useMemo, useCallback, createContext, useReducer, forwardRef, createElement, useContext, useId } from 'react';
5
- import { SyncIcon, DocumentIcon, LinkIcon, ImageIcon, BlockContentIcon, OlistIcon, BlockquoteIcon, StringIcon, ErrorOutlineIcon, CheckmarkCircleIcon, CloseCircleIcon, ClockIcon, PlayIcon, SparklesIcon, RetryIcon, ArrowRightIcon, CloseIcon, CheckmarkIcon, ArrowLeftIcon, icons, SearchIcon, TokenIcon, DocumentTextIcon, ThListIcon, CodeIcon, ComposeIcon, LockIcon, ControlsIcon } from '@sanity/icons';
5
+ import { SyncIcon, DocumentIcon, LinkIcon, ImageIcon, BlockContentIcon, OlistIcon, BlockquoteIcon, StringIcon, ErrorOutlineIcon, CheckmarkCircleIcon, CloseCircleIcon, ClockIcon, PlayIcon, SparklesIcon, ArrowLeftIcon, SearchIcon, RetryIcon, ArrowRightIcon, CloseIcon, CheckmarkIcon, icons, TokenIcon, DocumentTextIcon, ThListIcon, CodeIcon, ComposeIcon, LockIcon, ControlsIcon } from '@sanity/icons';
6
6
  import { mergeMap, share, take, filter, distinctUntilChanged, catchError, tap } from 'rxjs/operators';
7
7
  import isEqual from 'react-fast-compare';
8
8
  import { throwError, of, partition, merge, switchMap, delay, defer } from 'rxjs';
9
9
  import { exhaustMapToWithTrailing } from 'rxjs-exhaustmap-with-trailing';
10
10
  import { useDocumentPane, usePaneRouter, DocumentInspectorHeader, DocumentPaneProvider } from 'sanity/desk';
11
+ import { extractWithPath } from '@sanity/mutator';
11
12
  import styled, { keyframes } from 'styled-components';
12
13
  import { minutesToMilliseconds, isAfter, addSeconds } from 'date-fns';
13
14
  import formatDistanceToNow from 'date-fns/formatDistanceToNow';
@@ -506,7 +507,7 @@ function prepareRebaseEvent(event) {
506
507
  }
507
508
  const SelectedFieldContext = createContext(void 0);
508
509
  const SelectedFieldContextProvider = SelectedFieldContext.Provider;
509
- const maxDepth = 4;
510
+ const maxDepth = 6;
510
511
  function getTypeIcon(schemaType) {
511
512
  let t = schemaType;
512
513
  while (t) {
@@ -542,19 +543,76 @@ function getFieldRefs(schemaType, parent) {
542
543
  const path = parent ? [...parent.path, field.name] : [field.name];
543
544
  const title = (_a = field.type.title) != null ? _a : field.name;
544
545
  const fieldRef = {
545
- key: pathToString(path),
546
+ key: patchableKey(pathToString(path)),
546
547
  path,
547
548
  title: parent ? [parent.title, title].join(" / ") : title,
548
549
  schemaType: field.type,
549
550
  icon: getTypeIcon(field.type)
550
551
  };
551
552
  const fields = field.type.jsonType === "object" ? getFieldRefs(field.type, fieldRef, depth + 1) : [];
553
+ const syntheticFields = field.type.jsonType === "array" ? getSyntheticFields(field.type, fieldRef, depth + 1) : [];
552
554
  if (!isAssistSupported(field.type, true)) {
555
+ return [...fields, ...syntheticFields];
556
+ }
557
+ return [fieldRef, ...fields, ...syntheticFields];
558
+ });
559
+ }
560
+ function getSyntheticFields(schemaType, parent) {
561
+ let depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
562
+ if (depth >= maxDepth) {
563
+ return [];
564
+ }
565
+ return schemaType.of.filter(itemType => !isType(itemType, "block")).flatMap(itemType => {
566
+ var _a;
567
+ const segment = {
568
+ _key: itemType.name
569
+ };
570
+ const title = (_a = itemType.title) != null ? _a : itemType.name;
571
+ const path = parent ? [...parent.path, segment] : [segment];
572
+ const fieldRef = {
573
+ key: patchableKey(pathToString(path)),
574
+ path,
575
+ title: parent ? [parent.title, title].join(" / ") : title,
576
+ schemaType: itemType,
577
+ icon: getTypeIcon(itemType),
578
+ synthetic: true
579
+ };
580
+ const fields = itemType.jsonType === "object" ? getFieldRefs(itemType, fieldRef, depth + 1) : [];
581
+ if (!isAssistSupported(itemType, true)) {
553
582
  return fields;
554
583
  }
555
584
  return [fieldRef, ...fields];
556
585
  });
557
586
  }
587
+ function getTypePath(doc, pathString) {
588
+ if (!pathString) {
589
+ return void 0;
590
+ }
591
+ const path = stringToPath(pathString);
592
+ const currentPath = [];
593
+ let valid = true;
594
+ const syntheticPath = path.map(segment => {
595
+ currentPath.push(segment);
596
+ if (isKeySegment(segment)) {
597
+ const match = extractWithPath(pathToString(currentPath), doc)[0];
598
+ const value = match == null ? void 0 : match.value;
599
+ if (match && value && typeof value === "object" && "_type" in value) {
600
+ return {
601
+ _key: value._type
602
+ };
603
+ }
604
+ valid = false;
605
+ }
606
+ return segment;
607
+ });
608
+ return valid ? patchableKey(pathToString(syntheticPath)) : void 0;
609
+ }
610
+ function patchableKey(pathKey) {
611
+ return pathKey.replace(/[=]=/g, ":").replace(/[[\]]/g, "|").replace(/"/g, "");
612
+ }
613
+ function useTypePath(doc, pathString) {
614
+ return useMemo(() => getTypePath(doc, pathString), [doc, pathString]);
615
+ }
558
616
  function useSelectedField(documentSchemaType, path) {
559
617
  const selectableFields = useMemo(() => documentSchemaType && isObjectSchemaType(documentSchemaType) ? getFieldRefsWithDocument(documentSchemaType) : [], [documentSchemaType]);
560
618
  return useMemo(() => {
@@ -562,9 +620,9 @@ function useSelectedField(documentSchemaType, path) {
562
620
  }, [selectableFields, path]);
563
621
  }
564
622
  function getFieldTitle(field) {
565
- var _a, _b;
623
+ var _a, _b, _c;
566
624
  const schemaType = field == null ? void 0 : field.schemaType;
567
- return (_b = (_a = schemaType == null ? void 0 : schemaType.title) != null ? _a : schemaType == null ? void 0 : schemaType.name) != null ? _b : "Untitled";
625
+ return (_c = (_b = (_a = field == null ? void 0 : field.title) != null ? _a : schemaType == null ? void 0 : schemaType.title) != null ? _b : schemaType == null ? void 0 : schemaType.name) != null ? _c : "Untitled";
568
626
  }
569
627
  function useAiPaneRouter() {
570
628
  const paneRouter = usePaneRouter();
@@ -1351,32 +1409,338 @@ function InspectorOnboarding(props) {
1351
1409
  })
1352
1410
  });
1353
1411
  }
1354
- const inspectorOnboardingKey = "sanityStudio:assist:inspector:onboarding:dismissed";
1355
- const fieldOnboardingKey = "sanityStudio:assist:field:onboarding:dismissed";
1356
- function isFeatureOnboardingDismissed(featureKey) {
1357
- if (typeof localStorage === "undefined") {
1358
- return false;
1359
- }
1360
- const value = localStorage.getItem(featureKey);
1361
- return value === "true";
1362
- }
1363
- function dismissFeatureOnboarding(featureKey) {
1364
- if (typeof localStorage === "undefined") {
1365
- return;
1366
- }
1367
- localStorage.setItem(featureKey, "true");
1368
- }
1369
- function useOnboardingFeature(featureKey) {
1370
- const [showOnboarding, setShowOnboarding] = useState(() => !isFeatureOnboardingDismissed(featureKey));
1371
- const dismissOnboarding = useCallback(() => {
1372
- setShowOnboarding(false);
1373
- dismissFeatureOnboarding(featureKey);
1374
- }, [setShowOnboarding, featureKey]);
1375
- return {
1376
- showOnboarding,
1377
- dismissOnboarding
1378
- };
1379
- }
1412
+ const inspectorOnboardingKey = "sanityStudio:assist:inspector:onboarding:dismissed";
1413
+ const fieldOnboardingKey = "sanityStudio:assist:field:onboarding:dismissed";
1414
+ function isFeatureOnboardingDismissed(featureKey) {
1415
+ if (typeof localStorage === "undefined") {
1416
+ return false;
1417
+ }
1418
+ const value = localStorage.getItem(featureKey);
1419
+ return value === "true";
1420
+ }
1421
+ function dismissFeatureOnboarding(featureKey) {
1422
+ if (typeof localStorage === "undefined") {
1423
+ return;
1424
+ }
1425
+ localStorage.setItem(featureKey, "true");
1426
+ }
1427
+ function useOnboardingFeature(featureKey) {
1428
+ const [showOnboarding, setShowOnboarding] = useState(() => !isFeatureOnboardingDismissed(featureKey));
1429
+ const dismissOnboarding = useCallback(() => {
1430
+ setShowOnboarding(false);
1431
+ dismissFeatureOnboarding(featureKey);
1432
+ }, [setShowOnboarding, featureKey]);
1433
+ return {
1434
+ showOnboarding,
1435
+ dismissOnboarding
1436
+ };
1437
+ }
1438
+ function BackToInstructionListLink() {
1439
+ const {
1440
+ openInspector
1441
+ } = useDocumentPane();
1442
+ const goBack = useCallback(() => openInspector(aiInspectorId, {
1443
+ [instructionParam]: void 0
1444
+ }), [openInspector]);
1445
+ return /* @__PURE__ */jsx("div", {
1446
+ children: /* @__PURE__ */jsx(Button, {
1447
+ as: "a",
1448
+ fontSize: 1,
1449
+ icon: ArrowLeftIcon,
1450
+ mode: "bleed",
1451
+ padding: 1,
1452
+ space: 2,
1453
+ onClick: goBack,
1454
+ text: " Instructions",
1455
+ textAlign: "left"
1456
+ })
1457
+ });
1458
+ }
1459
+ const EMPTY_FIELDS = [];
1460
+ const TypePathContext = createContext(void 0);
1461
+ function AssistDocumentForm(props) {
1462
+ const {
1463
+ onChange
1464
+ } = props;
1465
+ const value = props.value;
1466
+ const id = value == null ? void 0 : value._id;
1467
+ const fields = value == null ? void 0 : value.fields;
1468
+ const targetDocumentType = useMemo(() => {
1469
+ if (!id) {
1470
+ return void 0;
1471
+ }
1472
+ return documentTypeFromAiDocumentId(id);
1473
+ }, [id]);
1474
+ const {
1475
+ params,
1476
+ setParams
1477
+ } = useAiPaneRouter();
1478
+ const pathKey = params[fieldPathParam];
1479
+ const typePath = useContext(TypePathContext);
1480
+ const instruction = params[instructionParam];
1481
+ const activeKey = useMemo(() => {
1482
+ var _a;
1483
+ if (!typePath) {
1484
+ return void 0;
1485
+ }
1486
+ return (_a = (fields != null ? fields : EMPTY_FIELDS).find(f => f.path === typePath)) == null ? void 0 : _a._key;
1487
+ }, [fields, typePath]);
1488
+ const activePath = useMemo(() => {
1489
+ if (!activeKey) {
1490
+ return void 0;
1491
+ }
1492
+ const base = ["fields", {
1493
+ _key: activeKey
1494
+ }];
1495
+ return instruction ? [...base, "instructions", {
1496
+ _key: instruction
1497
+ }] : base;
1498
+ }, [activeKey, instruction]);
1499
+ const schema = useSchema();
1500
+ const documentSchema = useMemo(() => {
1501
+ if (!targetDocumentType) {
1502
+ return void 0;
1503
+ }
1504
+ return schema.get(targetDocumentType);
1505
+ }, [schema, targetDocumentType]);
1506
+ const fieldSchema = useSelectedSchema(pathKey, documentSchema);
1507
+ const context = useMemo(() => ({
1508
+ documentSchema,
1509
+ fieldSchema: fieldSchema != null ? fieldSchema : documentSchema
1510
+ }), [fieldSchema, documentSchema]);
1511
+ const title = value == null ? void 0 : value.title;
1512
+ useEffect(() => {
1513
+ var _a;
1514
+ if (!title && documentSchema && !(id == null ? void 0 : id.startsWith("drafts."))) {
1515
+ onChange(set((_a = documentSchema.title) != null ? _a : documentSchema.name, ["title"]));
1516
+ }
1517
+ }, [title, documentSchema, onChange, id]);
1518
+ const fieldExists = !!(fields == null ? void 0 : fields.some(f => f._key === typePath));
1519
+ const {
1520
+ onPathOpen,
1521
+ ...formCallbacks
1522
+ } = useFormCallbacks();
1523
+ const newCallbacks = useMemo(() => ({
1524
+ ...formCallbacks,
1525
+ onPathOpen: path => {
1526
+ var _a;
1527
+ if (!instruction && path.length === 4 && path[2] === "instructions") {
1528
+ setParams(typed({
1529
+ ...params,
1530
+ [instructionParam]: (_a = path[3]) == null ? void 0 : _a._key
1531
+ }));
1532
+ onPathOpen([]);
1533
+ } else {
1534
+ setTimeout(() => onPathOpen(path), 0);
1535
+ }
1536
+ }
1537
+ }), [formCallbacks, onPathOpen, params, setParams, instruction]);
1538
+ useEffect(() => {
1539
+ if (activePath && !instruction) {
1540
+ onPathOpen([]);
1541
+ }
1542
+ }, [activePath, instruction, onPathOpen]);
1543
+ return /* @__PURE__ */jsx(SelectedFieldContextProvider, {
1544
+ value: context,
1545
+ children: /* @__PURE__ */jsxs(Stack, {
1546
+ space: 5,
1547
+ children: [/* @__PURE__ */jsx(FieldsInitializer, {
1548
+ pathKey: typePath,
1549
+ activePath,
1550
+ fieldExists,
1551
+ onChange
1552
+ }, typePath), instruction && /* @__PURE__ */jsx(BackToInstructionListLink, {}), activePath && /* @__PURE__ */jsx(FormCallbacksProvider, {
1553
+ ...newCallbacks,
1554
+ children: /* @__PURE__ */jsx("div", {
1555
+ style: {
1556
+ lineHeight: "1.25em"
1557
+ },
1558
+ children: /* @__PURE__ */jsx(FormInput, {
1559
+ ...props,
1560
+ absolutePath: activePath
1561
+ })
1562
+ })
1563
+ }), !activePath && props.renderDefault(props)]
1564
+ })
1565
+ });
1566
+ }
1567
+ function useSelectedSchema(fieldPath, documentSchema) {
1568
+ return useMemo(() => {
1569
+ if (!fieldPath) {
1570
+ return void 0;
1571
+ }
1572
+ if (fieldPath === documentRootKey) {
1573
+ return documentSchema;
1574
+ }
1575
+ const path = stringToPath(fieldPath);
1576
+ let currentSchema = documentSchema;
1577
+ for (let i = 0; i < path.length; i++) {
1578
+ const segment = path[i];
1579
+ const field = currentSchema == null ? void 0 : currentSchema.fields.find(f => f.name === segment);
1580
+ if (!field) {
1581
+ return void 0;
1582
+ }
1583
+ if (i === path.length - 1) {
1584
+ return field.type;
1585
+ }
1586
+ if (field.type.jsonType !== "object") {
1587
+ return void 0;
1588
+ }
1589
+ currentSchema = field.type;
1590
+ }
1591
+ return currentSchema;
1592
+ }, [documentSchema, fieldPath]);
1593
+ }
1594
+ function FieldsInitializer(_ref7) {
1595
+ let {
1596
+ pathKey,
1597
+ activePath,
1598
+ fieldExists,
1599
+ onChange
1600
+ } = _ref7;
1601
+ const initialized = useRef(false);
1602
+ useEffect(() => {
1603
+ if (initialized.current || fieldExists || activePath || !pathKey) {
1604
+ return;
1605
+ }
1606
+ onChange([setIfMissing([], ["fields"]), insert([typed({
1607
+ _key: pathKey,
1608
+ _type: assistFieldTypeName,
1609
+ path: pathKey
1610
+ })], "after", ["fields", -1])]);
1611
+ initialized.current = true;
1612
+ }, [activePath, onChange, pathKey, fieldExists]);
1613
+ return null;
1614
+ }
1615
+ function FieldAutocomplete(props) {
1616
+ const {
1617
+ id,
1618
+ schemaType,
1619
+ fieldPath,
1620
+ onSelect,
1621
+ includeDocument,
1622
+ filter
1623
+ } = props;
1624
+ const fieldRefs = useMemo(() => {
1625
+ if (includeDocument) {
1626
+ return getFieldRefsWithDocument(schemaType);
1627
+ }
1628
+ return getFieldRefs(schemaType);
1629
+ }, [schemaType, includeDocument]);
1630
+ const currentField = useMemo(() => fieldRefs.find(f => f.key === fieldPath), [fieldPath, fieldRefs]);
1631
+ const autocompleteOptions = useMemo(() => fieldRefs.filter(field => filter ? filter(field) : true).map(field => ({
1632
+ value: field.key,
1633
+ field
1634
+ })), [fieldRefs, filter]);
1635
+ const renderOption = useCallback(option => {
1636
+ const {
1637
+ value,
1638
+ field
1639
+ } = option;
1640
+ if (!value) {
1641
+ return /* @__PURE__ */jsx(Card, {
1642
+ as: "button",
1643
+ padding: 3,
1644
+ radius: 1,
1645
+ children: /* @__PURE__ */jsx(Text, {
1646
+ accent: true,
1647
+ size: 1,
1648
+ children: option.value
1649
+ })
1650
+ });
1651
+ }
1652
+ if (isType(field.schemaType, "document")) {
1653
+ return /* @__PURE__ */jsx(Card, {
1654
+ as: "button",
1655
+ padding: 3,
1656
+ radius: 1,
1657
+ children: /* @__PURE__ */jsx(Text, {
1658
+ size: 1,
1659
+ weight: "semibold",
1660
+ children: "The entire document"
1661
+ })
1662
+ });
1663
+ }
1664
+ return /* @__PURE__ */jsx(Card, {
1665
+ as: "button",
1666
+ padding: 3,
1667
+ radius: 1,
1668
+ children: /* @__PURE__ */jsxs(Flex, {
1669
+ gap: 3,
1670
+ children: [/* @__PURE__ */jsx(Text, {
1671
+ size: 1,
1672
+ children: createElement(field.icon)
1673
+ }), /* @__PURE__ */jsx(FieldTitle, {
1674
+ field
1675
+ })]
1676
+ })
1677
+ });
1678
+ }, []);
1679
+ const renderValue = useCallback((value, option) => {
1680
+ var _a;
1681
+ return (_a = option == null ? void 0 : option.field.title) != null ? _a : value;
1682
+ }, []);
1683
+ const filterOption = useCallback((query, option) => {
1684
+ var _a, _b, _c;
1685
+ const lQuery = query.toLowerCase();
1686
+ return ((_a = option == null ? void 0 : option.value) == null ? void 0 : _a.toLowerCase().includes(lQuery)) || ((_c = (_b = option == null ? void 0 : option.field) == null ? void 0 : _b.title) == null ? void 0 : _c.toLowerCase().includes(lQuery));
1687
+ }, []);
1688
+ return /* @__PURE__ */jsx(Autocomplete, {
1689
+ fontSize: 1,
1690
+ icon: currentField ? currentField.icon : SearchIcon,
1691
+ onChange: onSelect,
1692
+ openButton: true,
1693
+ id,
1694
+ options: autocompleteOptions,
1695
+ placeholder: "Search for a field",
1696
+ radius: 2,
1697
+ renderOption,
1698
+ renderValue,
1699
+ value: currentField == null ? void 0 : currentField.key,
1700
+ filterOption
1701
+ });
1702
+ }
1703
+ function FieldTitle(props) {
1704
+ const splitTitle = props.field.title.split("/");
1705
+ return /* @__PURE__ */jsx(Box, {
1706
+ flex: "none",
1707
+ children: /* @__PURE__ */jsxs(Breadcrumbs, {
1708
+ style: {
1709
+ display: "flex",
1710
+ flexWrap: "wrap",
1711
+ alignItems: "center",
1712
+ marginTop: "-4px"
1713
+ },
1714
+ separator: /* @__PURE__ */jsx(Box, {
1715
+ marginTop: 1,
1716
+ children: /* @__PURE__ */jsx(Text, {
1717
+ muted: true,
1718
+ size: 1,
1719
+ children: "/"
1720
+ })
1721
+ }),
1722
+ space: 1,
1723
+ children: [splitTitle.slice(0, splitTitle.length - 1).map((pt, i) =>
1724
+ // eslint-disable-next-line react/no-array-index-key
1725
+ /* @__PURE__ */
1726
+ jsx(Box, {
1727
+ marginTop: 1,
1728
+ children: /* @__PURE__ */jsx(Text, {
1729
+ muted: true,
1730
+ size: 1,
1731
+ children: pt.trim()
1732
+ })
1733
+ }, i)), /* @__PURE__ */jsx(Box, {
1734
+ marginTop: 1,
1735
+ children: /* @__PURE__ */jsx(Text, {
1736
+ size: 1,
1737
+ weight: "medium",
1738
+ children: splitTitle[splitTitle.length - 1]
1739
+ })
1740
+ })]
1741
+ })
1742
+ });
1743
+ }
1380
1744
  var __freeze$4 = Object.freeze;
1381
1745
  var __defProp$4 = Object.defineProperty;
1382
1746
  var __template$4 = (cooked, raw) => __freeze$4(__defProp$4(cooked, "raw", {
@@ -1514,6 +1878,7 @@ function AssistInspector(props) {
1514
1878
  const {
1515
1879
  documentId,
1516
1880
  documentType,
1881
+ value: docValue,
1517
1882
  schemaType,
1518
1883
  onChange: documentOnChange
1519
1884
  } = documentPane;
@@ -1529,13 +1894,14 @@ function AssistInspector(props) {
1529
1894
  documentOnChange,
1530
1895
  isDocAssistable: isDocAssistable(schemaType, published, draft)
1531
1896
  });
1532
- const selectedField = useSelectedField(schemaType, params[fieldPathParam]);
1897
+ const typePath = useTypePath(docValue, pathKey != null ? pathKey : "");
1898
+ const selectedField = useSelectedField(schemaType, typePath);
1533
1899
  const aiDocId = assistDocumentId(documentType);
1534
1900
  const assistDocument = useStudioAssistDocument({
1535
1901
  documentId,
1536
1902
  schemaType
1537
1903
  });
1538
- const assistField = (_a2 = assistDocument == null ? void 0 : assistDocument.fields) == null ? void 0 : _a2.find(f => f.path === pathKey);
1904
+ const assistField = (_a2 = assistDocument == null ? void 0 : assistDocument.fields) == null ? void 0 : _a2.find(f => f.path === typePath);
1539
1905
  const instruction = (_b2 = assistField == null ? void 0 : assistField.instructions) == null ? void 0 : _b2.find(i => i._key === instructionKey);
1540
1906
  const tasks = useMemo(() => {
1541
1907
  var _a3;
@@ -1567,12 +1933,13 @@ function AssistInspector(props) {
1567
1933
  type: assistDocumentTypeName
1568
1934
  }
1569
1935
  }), [aiDocId]);
1570
- const runCurrentInstruction = useCallback(() => instruction && pathKey && requestRunInstruction({
1936
+ const runCurrentInstruction = useCallback(() => instruction && pathKey && typePath && requestRunInstruction({
1571
1937
  documentId: assistableDocId,
1572
1938
  path: pathKey,
1939
+ typePath,
1573
1940
  assistDocumentId: assistDocumentId(documentType),
1574
1941
  instruction
1575
- }), [instruction, pathKey, documentType, assistableDocId, requestRunInstruction]);
1942
+ }), [pathKey, instruction, typePath, documentType, assistableDocId, requestRunInstruction]);
1576
1943
  const Region = useCallback(_props => {
1577
1944
  return /* @__PURE__ */jsx("div", {
1578
1945
  ..._props,
@@ -1603,6 +1970,7 @@ function AssistInspector(props) {
1603
1970
  },
1604
1971
  children: [/* @__PURE__ */jsx(AiInspectorHeader, {
1605
1972
  onClose: props.onClose,
1973
+ field: selectedField,
1606
1974
  fieldTitle: getFieldTitle(selectedField)
1607
1975
  }), /* @__PURE__ */jsx(Card, {
1608
1976
  as: Region,
@@ -1618,15 +1986,18 @@ function AssistInspector(props) {
1618
1986
  children: /* @__PURE__ */jsx(PresenceOverlay, {
1619
1987
  children: /* @__PURE__ */jsx(Box, {
1620
1988
  padding: 4,
1621
- children: selectedField && /* @__PURE__ */jsx(VirtualizerScrollInstanceProvider, {
1622
- scrollElement: boundary.current,
1623
- containerElement: boundary,
1624
- children: /* @__PURE__ */jsx(DocumentPaneProvider, {
1625
- paneKey: documentPane.paneKey,
1626
- index: documentPane.index,
1627
- itemId: "ai",
1628
- pane: paneNode,
1629
- children: /* @__PURE__ */jsx(DocumentForm, {})
1989
+ children: selectedField && /* @__PURE__ */jsx(TypePathContext.Provider, {
1990
+ value: typePath,
1991
+ children: /* @__PURE__ */jsx(VirtualizerScrollInstanceProvider, {
1992
+ scrollElement: boundary.current,
1993
+ containerElement: boundary,
1994
+ children: /* @__PURE__ */jsx(DocumentPaneProvider, {
1995
+ paneKey: documentPane.paneKey,
1996
+ index: documentPane.index,
1997
+ itemId: "ai",
1998
+ pane: paneNode,
1999
+ children: /* @__PURE__ */jsx(DocumentForm, {})
2000
+ })
1630
2001
  })
1631
2002
  })
1632
2003
  })
@@ -1684,6 +2055,7 @@ function AssistInspector(props) {
1684
2055
  function AiInspectorHeader(props) {
1685
2056
  const {
1686
2057
  onClose,
2058
+ field,
1687
2059
  fieldTitle
1688
2060
  } = props;
1689
2061
  const {
@@ -1704,18 +2076,25 @@ function AiInspectorHeader(props) {
1704
2076
  children: /* @__PURE__ */jsxs(Flex, {
1705
2077
  gap: 1,
1706
2078
  align: "center",
1707
- children: [/* @__PURE__ */jsx(Text, {
1708
- size: 1,
1709
- weight: "semibold",
1710
- children: "AI instructions for"
2079
+ wrap: "wrap",
2080
+ style: {
2081
+ marginTop: "-4px"
2082
+ },
2083
+ children: [/* @__PURE__ */jsx(Box, {
2084
+ marginTop: 1,
2085
+ children: /* @__PURE__ */jsx(Text, {
2086
+ size: 1,
2087
+ weight: "semibold",
2088
+ children: "AI instructions for"
2089
+ })
1711
2090
  }), /* @__PURE__ */jsx(Card, {
1712
2091
  radius: 2,
1713
2092
  border: true,
1714
2093
  padding: 1,
1715
- style: {
1716
- margin: "-4px 0"
1717
- },
1718
- children: /* @__PURE__ */jsx(Text, {
2094
+ marginTop: 1,
2095
+ children: field ? /* @__PURE__ */jsx(FieldTitle, {
2096
+ field
2097
+ }) : /* @__PURE__ */jsx(Text, {
1719
2098
  size: 1,
1720
2099
  weight: "semibold",
1721
2100
  children: fieldTitle
@@ -1745,10 +2124,10 @@ const assistInspector = {
1745
2124
  showAsAction: false
1746
2125
  }),
1747
2126
  component: AssistInspectorWrapper,
1748
- onClose(_ref7) {
2127
+ onClose(_ref8) {
1749
2128
  let {
1750
2129
  params
1751
- } = _ref7;
2130
+ } = _ref8;
1752
2131
  return {
1753
2132
  params: typed({
1754
2133
  ...params,
@@ -1821,11 +2200,11 @@ var __template$3 = (cooked, raw) => __freeze$3(__defProp$3(cooked, "raw", {
1821
2200
  var _a$3, _b$1;
1822
2201
  const fadeIn = keyframes(_a$3 || (_a$3 = __template$3(["\n 0% {\n opacity: 0;\n transform: scale(0.75);\n }\n 40% {\n opacity: 0;\n transform: scale(0.75);\n }\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n"])));
1823
2202
  const FadeInDiv = styled.div(_b$1 || (_b$1 = __template$3(["\n animation-name: ", ";\n animation-timing-function: ease-in-out;\n"])), fadeIn);
1824
- const FadeInContent = forwardRef(function FadeInContent2(_ref8, ref) {
2203
+ const FadeInContent = forwardRef(function FadeInContent2(_ref9, ref) {
1825
2204
  let {
1826
2205
  children,
1827
2206
  durationMs = 250
1828
- } = _ref8;
2207
+ } = _ref9;
1829
2208
  return /* @__PURE__ */jsx(FadeInDiv, {
1830
2209
  ref,
1831
2210
  style: {
@@ -2850,291 +3229,119 @@ function SafeValueInput(props) {
2850
3229
  function ErrorWrapper(props) {
2851
3230
  const {
2852
3231
  onChange
2853
- } = props;
2854
- const [error, setError] = useState();
2855
- const catchError = useCallback(params => {
2856
- setError(params.error);
2857
- }, [setError]);
2858
- const unsetValue = useCallback(() => onChange(PatchEvent.from(unset())), [onChange]);
2859
- const dismiss = useCallback(() => setError(void 0), []);
2860
- const catcher = /* @__PURE__ */jsx(ErrorBoundary, {
2861
- onCatch: catchError,
2862
- children: props.children
2863
- });
2864
- return error ? /* @__PURE__ */jsx(Card, {
2865
- border: true,
2866
- tone: "critical",
2867
- padding: 2,
2868
- contentEditable: false,
2869
- children: /* @__PURE__ */jsxs(Stack, {
2870
- space: 3,
2871
- children: [/* @__PURE__ */jsx(Text, {
2872
- muted: true,
2873
- weight: "semibold",
2874
- children: "An error occurred."
2875
- }), /* @__PURE__ */jsx(WrapPreCard, {
2876
- flex: 1,
2877
- padding: 2,
2878
- tone: "critical",
2879
- border: true,
2880
- children: catcher
2881
- }), /* @__PURE__ */jsxs(Flex, {
2882
- width: "fill",
2883
- flex: 1,
2884
- gap: 3,
2885
- children: [/* @__PURE__ */jsx(Box, {
2886
- flex: 1,
2887
- children: /* @__PURE__ */jsx(Button, {
2888
- text: "Dismiss",
2889
- onClick: dismiss,
2890
- tone: "primary"
2891
- })
2892
- }), /* @__PURE__ */jsx(Button, {
2893
- text: "Unset value",
2894
- onClick: unsetValue,
2895
- tone: "critical"
2896
- })]
2897
- })]
2898
- })
2899
- }) : catcher;
2900
- }
2901
- function PteValueFixer(props) {
2902
- const isPortableText = useMemo(() => isArraySchemaType(props.schemaType) && isPortableTextArray(props.schemaType), [props.schemaType]);
2903
- const value = props.value;
2904
- if (isPortableText && value && !value.length) {
2905
- return props.renderDefault({
2906
- ...props,
2907
- value: void 0
2908
- });
2909
- }
2910
- return props.renderDefault(props);
2911
- }
2912
- function AssistFormBlock(props) {
2913
- const presence = useAssistPresence(props.path, true);
2914
- const {
2915
- onChange
2916
- } = useFormCallbacks();
2917
- const key = props.value._key;
2918
- const localOnChange = useCallback(patchEvent => {
2919
- if (!key) {
2920
- return;
2921
- }
2922
- onChange(PatchEvent.from(patchEvent).prefixAll({
2923
- _key: key
2924
- }));
2925
- }, [onChange, key]);
2926
- return /* @__PURE__ */jsx(ErrorWrapper, {
2927
- onChange: localOnChange,
2928
- children: /* @__PURE__ */jsxs(Flex, {
2929
- align: "center",
2930
- justify: "space-between",
2931
- children: [/* @__PURE__ */jsx(Box, {
2932
- flex: 1,
2933
- children: props.renderDefault(props)
2934
- }), presence.map(pre => /* @__PURE__ */jsx(AiFieldPresence, {
2935
- presence: pre
2936
- }, pre.lastActiveAt))]
2937
- })
2938
- });
2939
- }
2940
- function AssistItem(props) {
2941
- const {
2942
- path
2943
- } = props;
2944
- const presence = useAssistPresence(path, true);
2945
- return /* @__PURE__ */jsxs(Flex, {
2946
- align: "center",
2947
- width: "fill",
2948
- style: {
2949
- position: "relative"
2950
- },
2951
- children: [/* @__PURE__ */jsx(Box, {
2952
- flex: 1,
2953
- children: props.renderDefault({
2954
- ...props
2955
- })
2956
- }), presence.map(pre => /* @__PURE__ */jsx(Box, {
2957
- style: {
2958
- position: "absolute",
2959
- right: 35
2960
- },
2961
- children: /* @__PURE__ */jsx(AiFieldPresence, {
2962
- presence: pre
2963
- })
2964
- }, pre.user.id))]
2965
- });
2966
- }
2967
- function BackToInstructionListLink() {
2968
- const {
2969
- openInspector
2970
- } = useDocumentPane();
2971
- const goBack = useCallback(() => openInspector(aiInspectorId, {
2972
- [instructionParam]: void 0
2973
- }), [openInspector]);
2974
- return /* @__PURE__ */jsx("div", {
2975
- children: /* @__PURE__ */jsx(Button, {
2976
- as: "a",
2977
- fontSize: 1,
2978
- icon: ArrowLeftIcon,
2979
- mode: "bleed",
2980
- padding: 1,
2981
- space: 2,
2982
- onClick: goBack,
2983
- text: " Instructions",
2984
- textAlign: "left"
2985
- })
2986
- });
2987
- }
2988
- const EMPTY_FIELDS = [];
2989
- function AssistDocumentForm(props) {
2990
- const {
2991
- onChange
2992
- } = props;
2993
- const value = props.value;
2994
- const id = value == null ? void 0 : value._id;
2995
- const fields = value == null ? void 0 : value.fields;
2996
- const targetDocumentType = useMemo(() => {
2997
- if (!id) {
2998
- return void 0;
2999
- }
3000
- return documentTypeFromAiDocumentId(id);
3001
- }, [id]);
3002
- const {
3003
- params,
3004
- setParams
3005
- } = useAiPaneRouter();
3006
- const pathKey = params[fieldPathParam];
3007
- const instruction = params[instructionParam];
3008
- const activeKey = useMemo(() => {
3009
- var _a;
3010
- return (_a = (fields != null ? fields : EMPTY_FIELDS).find(f => f.path === pathKey)) == null ? void 0 : _a._key;
3011
- }, [fields, pathKey]);
3012
- const activePath = useMemo(() => {
3013
- if (!activeKey) {
3014
- return void 0;
3015
- }
3016
- const base = ["fields", {
3017
- _key: activeKey
3018
- }];
3019
- return instruction ? [...base, "instructions", {
3020
- _key: instruction
3021
- }] : base;
3022
- }, [activeKey, instruction]);
3023
- const schema = useSchema();
3024
- const documentSchema = useMemo(() => {
3025
- if (!targetDocumentType) {
3026
- return void 0;
3027
- }
3028
- return schema.get(targetDocumentType);
3029
- }, [schema, targetDocumentType]);
3030
- const fieldSchema = useSelectedSchema(pathKey, documentSchema);
3031
- const context = useMemo(() => ({
3032
- documentSchema,
3033
- fieldSchema: fieldSchema != null ? fieldSchema : documentSchema
3034
- }), [fieldSchema, documentSchema]);
3035
- const title = value == null ? void 0 : value.title;
3036
- useEffect(() => {
3037
- var _a;
3038
- if (!title && documentSchema && !(id == null ? void 0 : id.startsWith("drafts."))) {
3039
- onChange(set((_a = documentSchema.title) != null ? _a : documentSchema.name, ["title"]));
3040
- }
3041
- }, [title, documentSchema, onChange, id]);
3042
- const fieldExists = !!(fields == null ? void 0 : fields.some(f => f._key === pathKey));
3043
- const {
3044
- onPathOpen,
3045
- ...formCallbacks
3046
- } = useFormCallbacks();
3047
- const newCallbacks = useMemo(() => ({
3048
- ...formCallbacks,
3049
- onPathOpen: path => {
3050
- var _a;
3051
- if (!instruction && path.length === 4 && path[2] === "instructions") {
3052
- setParams(typed({
3053
- ...params,
3054
- [instructionParam]: (_a = path[3]) == null ? void 0 : _a._key
3055
- }));
3056
- onPathOpen([]);
3057
- } else {
3058
- setTimeout(() => onPathOpen(path), 0);
3059
- }
3060
- }
3061
- }), [formCallbacks, onPathOpen, params, setParams, instruction]);
3062
- useEffect(() => {
3063
- if (activePath && !instruction) {
3064
- onPathOpen([]);
3065
- }
3066
- }, [activePath, instruction, onPathOpen]);
3067
- return /* @__PURE__ */jsx(SelectedFieldContextProvider, {
3068
- value: context,
3232
+ } = props;
3233
+ const [error, setError] = useState();
3234
+ const catchError = useCallback(params => {
3235
+ setError(params.error);
3236
+ }, [setError]);
3237
+ const unsetValue = useCallback(() => onChange(PatchEvent.from(unset())), [onChange]);
3238
+ const dismiss = useCallback(() => setError(void 0), []);
3239
+ const catcher = /* @__PURE__ */jsx(ErrorBoundary, {
3240
+ onCatch: catchError,
3241
+ children: props.children
3242
+ });
3243
+ return error ? /* @__PURE__ */jsx(Card, {
3244
+ border: true,
3245
+ tone: "critical",
3246
+ padding: 2,
3247
+ contentEditable: false,
3069
3248
  children: /* @__PURE__ */jsxs(Stack, {
3070
- space: 5,
3071
- children: [/* @__PURE__ */jsx(FieldsInitializer, {
3072
- pathKey,
3073
- activePath,
3074
- fieldExists,
3075
- onChange
3076
- }, pathKey), instruction && /* @__PURE__ */jsx(BackToInstructionListLink, {}), activePath && /* @__PURE__ */jsx(FormCallbacksProvider, {
3077
- ...newCallbacks,
3078
- children: /* @__PURE__ */jsx("div", {
3079
- style: {
3080
- lineHeight: "1.25em"
3081
- },
3082
- children: /* @__PURE__ */jsx(FormInput, {
3083
- ...props,
3084
- absolutePath: activePath
3249
+ space: 3,
3250
+ children: [/* @__PURE__ */jsx(Text, {
3251
+ muted: true,
3252
+ weight: "semibold",
3253
+ children: "An error occurred."
3254
+ }), /* @__PURE__ */jsx(WrapPreCard, {
3255
+ flex: 1,
3256
+ padding: 2,
3257
+ tone: "critical",
3258
+ border: true,
3259
+ children: catcher
3260
+ }), /* @__PURE__ */jsxs(Flex, {
3261
+ width: "fill",
3262
+ flex: 1,
3263
+ gap: 3,
3264
+ children: [/* @__PURE__ */jsx(Box, {
3265
+ flex: 1,
3266
+ children: /* @__PURE__ */jsx(Button, {
3267
+ text: "Dismiss",
3268
+ onClick: dismiss,
3269
+ tone: "primary"
3085
3270
  })
3086
- })
3087
- }), !activePath && props.renderDefault(props)]
3271
+ }), /* @__PURE__ */jsx(Button, {
3272
+ text: "Unset value",
3273
+ onClick: unsetValue,
3274
+ tone: "critical"
3275
+ })]
3276
+ })]
3088
3277
  })
3089
- });
3278
+ }) : catcher;
3090
3279
  }
3091
- function useSelectedSchema(fieldPath, documentSchema) {
3092
- return useMemo(() => {
3093
- if (!fieldPath) {
3094
- return void 0;
3095
- }
3096
- if (fieldPath === documentRootKey) {
3097
- return documentSchema;
3098
- }
3099
- const path = stringToPath(fieldPath);
3100
- let currentSchema = documentSchema;
3101
- for (let i = 0; i < path.length; i++) {
3102
- const segment = path[i];
3103
- const field = currentSchema == null ? void 0 : currentSchema.fields.find(f => f.name === segment);
3104
- if (!field) {
3105
- return void 0;
3106
- }
3107
- if (i === path.length - 1) {
3108
- return field.type;
3109
- }
3110
- if (field.type.jsonType !== "object") {
3111
- return void 0;
3112
- }
3113
- currentSchema = field.type;
3114
- }
3115
- return currentSchema;
3116
- }, [documentSchema, fieldPath]);
3280
+ function PteValueFixer(props) {
3281
+ const isPortableText = useMemo(() => isArraySchemaType(props.schemaType) && isPortableTextArray(props.schemaType), [props.schemaType]);
3282
+ const value = props.value;
3283
+ if (isPortableText && value && !value.length) {
3284
+ return props.renderDefault({
3285
+ ...props,
3286
+ value: void 0
3287
+ });
3288
+ }
3289
+ return props.renderDefault(props);
3117
3290
  }
3118
- function FieldsInitializer(_ref9) {
3119
- let {
3120
- pathKey,
3121
- activePath,
3122
- fieldExists,
3291
+ function AssistFormBlock(props) {
3292
+ const presence = useAssistPresence(props.path, true);
3293
+ const {
3123
3294
  onChange
3124
- } = _ref9;
3125
- const initialized = useRef(false);
3126
- useEffect(() => {
3127
- if (initialized.current || fieldExists || activePath || !pathKey) {
3295
+ } = useFormCallbacks();
3296
+ const key = props.value._key;
3297
+ const localOnChange = useCallback(patchEvent => {
3298
+ if (!key) {
3128
3299
  return;
3129
3300
  }
3130
- onChange([setIfMissing([], ["fields"]), insert([typed({
3131
- _key: pathKey,
3132
- _type: assistFieldTypeName,
3133
- path: pathKey
3134
- })], "after", ["fields", -1])]);
3135
- initialized.current = true;
3136
- }, [activePath, onChange, pathKey, fieldExists]);
3137
- return null;
3301
+ onChange(PatchEvent.from(patchEvent).prefixAll({
3302
+ _key: key
3303
+ }));
3304
+ }, [onChange, key]);
3305
+ return /* @__PURE__ */jsx(ErrorWrapper, {
3306
+ onChange: localOnChange,
3307
+ children: /* @__PURE__ */jsxs(Flex, {
3308
+ align: "center",
3309
+ justify: "space-between",
3310
+ children: [/* @__PURE__ */jsx(Box, {
3311
+ flex: 1,
3312
+ children: props.renderDefault(props)
3313
+ }), presence.map(pre => /* @__PURE__ */jsx(AiFieldPresence, {
3314
+ presence: pre
3315
+ }, pre.lastActiveAt))]
3316
+ })
3317
+ });
3318
+ }
3319
+ function AssistItem(props) {
3320
+ const {
3321
+ path
3322
+ } = props;
3323
+ const presence = useAssistPresence(path, true);
3324
+ return /* @__PURE__ */jsxs(Flex, {
3325
+ align: "center",
3326
+ width: "fill",
3327
+ style: {
3328
+ position: "relative"
3329
+ },
3330
+ children: [/* @__PURE__ */jsx(Box, {
3331
+ flex: 1,
3332
+ children: props.renderDefault({
3333
+ ...props
3334
+ })
3335
+ }), presence.map(pre => /* @__PURE__ */jsx(Box, {
3336
+ style: {
3337
+ position: "absolute",
3338
+ right: 35
3339
+ },
3340
+ children: /* @__PURE__ */jsx(AiFieldPresence, {
3341
+ presence: pre
3342
+ })
3343
+ }, pre.user.id))]
3344
+ });
3138
3345
  }
3139
3346
  function findFieldMember(members, fieldName) {
3140
3347
  return members.find(m => m.kind === "field" && m.name === fieldName || m.kind === "error" && m.fieldName === fieldName);
@@ -3343,117 +3550,10 @@ function getIcon(iconName) {
3343
3550
  return key === iconName;
3344
3551
  })) == null ? void 0 : _a[1]) != null ? _b : icons.sparkles;
3345
3552
  }
3346
- function FieldAutocomplete(props) {
3347
- const {
3348
- id,
3349
- schemaType,
3350
- fieldPath,
3351
- onSelect,
3352
- includeDocument
3353
- } = props;
3354
- const fieldNames = useMemo(() => {
3355
- if (includeDocument) {
3356
- return getFieldRefsWithDocument(schemaType);
3357
- }
3358
- return getFieldRefs(schemaType);
3359
- }, [schemaType, includeDocument]);
3360
- const currentField = useMemo(() => fieldNames.find(f => f.key === fieldPath), [fieldPath, fieldNames]);
3361
- const autocompleteOptions = useMemo(() => fieldNames.map(field => ({
3362
- value: field.key,
3363
- field
3364
- })), [fieldNames]);
3365
- const renderOption = useCallback(option => {
3366
- const {
3367
- value,
3368
- field
3369
- } = option;
3370
- if (!value) {
3371
- return /* @__PURE__ */jsx(Card, {
3372
- as: "button",
3373
- padding: 3,
3374
- radius: 1,
3375
- children: /* @__PURE__ */jsx(Text, {
3376
- accent: true,
3377
- size: 1,
3378
- children: option.value
3379
- })
3380
- });
3381
- }
3382
- if (isType(field.schemaType, "document")) {
3383
- return /* @__PURE__ */jsx(Card, {
3384
- as: "button",
3385
- padding: 3,
3386
- radius: 1,
3387
- children: /* @__PURE__ */jsx(Text, {
3388
- size: 1,
3389
- weight: "semibold",
3390
- children: "The entire document"
3391
- })
3392
- });
3393
- }
3394
- const splitTitle = field.title.split("/");
3395
- return /* @__PURE__ */jsx(Card, {
3396
- as: "button",
3397
- padding: 3,
3398
- radius: 1,
3399
- children: /* @__PURE__ */jsxs(Flex, {
3400
- gap: 3,
3401
- children: [/* @__PURE__ */jsx(Text, {
3402
- size: 1,
3403
- children: createElement(field.icon)
3404
- }), /* @__PURE__ */jsx(Box, {
3405
- flex: "none",
3406
- children: /* @__PURE__ */jsxs(Breadcrumbs, {
3407
- separator: /* @__PURE__ */jsx(Text, {
3408
- muted: true,
3409
- size: 1,
3410
- children: "/"
3411
- }),
3412
- space: 1,
3413
- children: [splitTitle.slice(0, splitTitle.length - 1).map((pt, i) =>
3414
- // eslint-disable-next-line react/no-array-index-key
3415
- /* @__PURE__ */
3416
- jsx(Text, {
3417
- muted: true,
3418
- size: 1,
3419
- children: pt.trim()
3420
- }, i)), /* @__PURE__ */jsx(Text, {
3421
- size: 1,
3422
- weight: "medium",
3423
- children: splitTitle[splitTitle.length - 1]
3424
- })]
3425
- })
3426
- })]
3427
- })
3428
- });
3429
- }, []);
3430
- const renderValue = useCallback((value, option) => {
3431
- var _a;
3432
- return (_a = option == null ? void 0 : option.field.title) != null ? _a : value;
3433
- }, []);
3434
- const filterOption = useCallback((query, option) => {
3435
- var _a, _b, _c;
3436
- const lQuery = query.toLowerCase();
3437
- return ((_a = option == null ? void 0 : option.value) == null ? void 0 : _a.toLowerCase().includes(lQuery)) || ((_c = (_b = option == null ? void 0 : option.field) == null ? void 0 : _b.title) == null ? void 0 : _c.toLowerCase().includes(lQuery));
3438
- }, []);
3439
- return /* @__PURE__ */jsx(Autocomplete, {
3440
- fontSize: 1,
3441
- icon: currentField ? currentField.icon : SearchIcon,
3442
- onChange: onSelect,
3443
- openButton: true,
3444
- id,
3445
- options: autocompleteOptions,
3446
- placeholder: "Search for a field",
3447
- radius: 2,
3448
- renderOption,
3449
- renderValue,
3450
- value: currentField == null ? void 0 : currentField.key,
3451
- filterOption
3452
- });
3453
- }
3454
3553
  function FieldRefPathInput(props) {
3455
3554
  var _a;
3456
3555
  const documentSchema = (_a = useContext(SelectedFieldContext)) == null ? void 0 : _a.documentSchema;
3556
+ const typePath = useContext(TypePathContext);
3457
3557
  const ref = useRef(null);
3458
3558
  const id = useId();
3459
3559
  const {
@@ -3464,20 +3564,29 @@ function FieldRefPathInput(props) {
3464
3564
  (_b = (_a2 = ref.current) == null ? void 0 : _a2.querySelector("input")) == null ? void 0 : _b.focus();
3465
3565
  }, []);
3466
3566
  const onSelect = useCallback(path => onChange(set(path)), [onChange]);
3567
+ const filter = useCallback(field => {
3568
+ if (!field.key.includes("|") || !typePath) {
3569
+ return true;
3570
+ }
3571
+ const dotSplit = typePath.split(".");
3572
+ const base = dotSplit.slice(0, dotSplit.length - 1).join(".");
3573
+ return field.key.includes(base);
3574
+ }, [typePath]);
3467
3575
  if (!documentSchema) {
3468
3576
  return props.renderDefault(props);
3469
3577
  }
3470
3578
  return /* @__PURE__ */jsx(Box, {
3471
3579
  flex: 1,
3472
3580
  style: {
3473
- minWidth: 200
3581
+ minWidth: 300
3474
3582
  },
3475
3583
  ref,
3476
3584
  children: /* @__PURE__ */jsx(FieldAutocomplete, {
3477
3585
  id,
3478
3586
  schemaType: documentSchema,
3479
3587
  onSelect,
3480
- fieldPath: props.value
3588
+ fieldPath: props.value,
3589
+ filter
3481
3590
  })
3482
3591
  });
3483
3592
  }
@@ -3680,7 +3789,7 @@ function useOnlyInlineBlocks(props) {
3680
3789
  function InstructionsArrayField(props) {
3681
3790
  return props.renderDefault({
3682
3791
  ...props,
3683
- title: void 0
3792
+ title: " "
3684
3793
  });
3685
3794
  }
3686
3795
  const fieldReference = defineType({
@@ -4020,7 +4129,7 @@ const fieldInstructions = defineType({
4020
4129
  });
4021
4130
  const assistDocumentSchema = defineType({
4022
4131
  //NOTE: this is a document type. Using object here ensures it does not appear in structure menus
4023
- type: "object",
4132
+ type: "document",
4024
4133
  //workaround for using object and not document
4025
4134
  ...{
4026
4135
  liveEdit: true
@@ -4100,7 +4209,7 @@ const documentInstructionStatus = defineType({
4100
4209
  });
4101
4210
  const schemaTypes = [fieldInstructions, assistDocumentSchema, prompt, fieldReference, instruction, documentInstructionStatus, instructionTask, contextDocumentSchema, userInput, promptContext];
4102
4211
  function useAssistSupported(path, schemaType) {
4103
- return useMemo(() => path.every(p => typeof p === "string") && isAssistSupported(schemaType), [path, schemaType]);
4212
+ return useMemo(() => isAssistSupported(schemaType), [schemaType]);
4104
4213
  }
4105
4214
  function useAssistDocumentContextValue(documentId, documentSchemaType) {
4106
4215
  const {
@@ -4271,7 +4380,6 @@ const assistFieldActions = {
4271
4380
  const {
4272
4381
  schemaType
4273
4382
  } = props;
4274
- const assistSupported = useAssistSupported(props.path, schemaType);
4275
4383
  const isDocumentLevel = props.path.length === 0;
4276
4384
  const {
4277
4385
  assistDocument,
@@ -4292,9 +4400,13 @@ const assistFieldActions = {
4292
4400
  useAssistDocumentContextValue(props.documentId, schemaType) :
4293
4401
  // eslint-disable-next-line react-hooks/rules-of-hooks
4294
4402
  useAssistDocumentContext();
4403
+ const {
4404
+ value: docValue
4405
+ } = useDocumentPane();
4295
4406
  const currentUser = useCurrentUser();
4296
4407
  const isHidden = !assistDocument;
4297
4408
  const pathKey = usePathKey(props.path);
4409
+ const typePath = useTypePath(docValue, pathKey);
4298
4410
  const assistDocumentId = assistDocument == null ? void 0 : assistDocument._id;
4299
4411
  const assistableDocId = getAssistableDocId(documentSchemaType, documentId);
4300
4412
  const {
@@ -4303,10 +4415,12 @@ const assistFieldActions = {
4303
4415
  documentOnChange,
4304
4416
  isDocAssistable: documentIsAssistable != null ? documentIsAssistable : false
4305
4417
  });
4418
+ const isSelectable = !!useSelectedField(documentSchemaType, typePath);
4419
+ const assistSupported = useAssistSupported(props.path, schemaType) && isSelectable;
4306
4420
  const fieldAssist = useMemo(() => {
4307
4421
  var _a;
4308
- return ((_a = assistDocument == null ? void 0 : assistDocument.fields) != null ? _a : []).find(f => f.path == pathKey);
4309
- }, [assistDocument == null ? void 0 : assistDocument.fields, pathKey]);
4422
+ return ((_a = assistDocument == null ? void 0 : assistDocument.fields) != null ? _a : []).find(f => f.path === typePath || pathKey === documentRootKey && f.path === pathKey);
4423
+ }, [assistDocument == null ? void 0 : assistDocument.fields, pathKey, typePath]);
4310
4424
  const fieldAssistKey = fieldAssist == null ? void 0 : fieldAssist._key;
4311
4425
  const isInspectorOpen = (inspector == null ? void 0 : inspector.name) === aiInspectorId;
4312
4426
  const isPathSelected = pathKey === selectedPath;
@@ -4324,9 +4438,10 @@ const assistFieldActions = {
4324
4438
  documentId: assistableDocId,
4325
4439
  assistDocumentId,
4326
4440
  path: pathKey,
4441
+ typePath,
4327
4442
  instruction
4328
4443
  });
4329
- }, [requestRunInstruction, assistableDocId, pathKey, assistDocumentId, fieldAssistKey]);
4444
+ }, [requestRunInstruction, assistableDocId, pathKey, typePath, assistDocumentId, fieldAssistKey]);
4330
4445
  const privateInstructions = useMemo(() => {
4331
4446
  var _a;
4332
4447
  return ((_a = fieldAssist == null ? void 0 : fieldAssist.instructions) == null ? void 0 : _a.filter(i => i.userId && i.userId === (currentUser == null ? void 0 : currentUser.id))) || [];