@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 +567 -452
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +564 -449
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/assistDocument/components/AssistDocumentForm.tsx +16 -10
- package/src/assistDocument/components/InstructionsArrayField.tsx +1 -1
- package/src/assistDocument/components/instruction/FieldRefInput.tsx +16 -1
- package/src/assistInspector/AssistInspector.tsx +50 -27
- package/src/assistInspector/FieldAutocomplete.tsx +49 -29
- package/src/assistInspector/helpers.ts +84 -4
- package/src/fieldActions/assistFieldActions.tsx +16 -5
- package/src/helpers/useAssistSupported.ts +1 -4
- package/src/schemas/assistDocumentSchema.tsx +1 -1
- package/src/useApiClient.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ var isEqual = require('react-fast-compare');
|
|
|
13
13
|
var rxjs = require('rxjs');
|
|
14
14
|
var rxjsExhaustmapWithTrailing = require('rxjs-exhaustmap-with-trailing');
|
|
15
15
|
var desk = require('sanity/desk');
|
|
16
|
+
var mutator = require('@sanity/mutator');
|
|
16
17
|
var styled = require('styled-components');
|
|
17
18
|
var dateFns = require('date-fns');
|
|
18
19
|
var formatDistanceToNow = require('date-fns/formatDistanceToNow');
|
|
@@ -519,7 +520,7 @@ function prepareRebaseEvent(event) {
|
|
|
519
520
|
}
|
|
520
521
|
const SelectedFieldContext = react.createContext(void 0);
|
|
521
522
|
const SelectedFieldContextProvider = SelectedFieldContext.Provider;
|
|
522
|
-
const maxDepth =
|
|
523
|
+
const maxDepth = 6;
|
|
523
524
|
function getTypeIcon(schemaType) {
|
|
524
525
|
let t = schemaType;
|
|
525
526
|
while (t) {
|
|
@@ -555,19 +556,76 @@ function getFieldRefs(schemaType, parent) {
|
|
|
555
556
|
const path = parent ? [...parent.path, field.name] : [field.name];
|
|
556
557
|
const title = (_a = field.type.title) != null ? _a : field.name;
|
|
557
558
|
const fieldRef = {
|
|
558
|
-
key: sanity.pathToString(path),
|
|
559
|
+
key: patchableKey(sanity.pathToString(path)),
|
|
559
560
|
path,
|
|
560
561
|
title: parent ? [parent.title, title].join(" / ") : title,
|
|
561
562
|
schemaType: field.type,
|
|
562
563
|
icon: getTypeIcon(field.type)
|
|
563
564
|
};
|
|
564
565
|
const fields = field.type.jsonType === "object" ? getFieldRefs(field.type, fieldRef, depth + 1) : [];
|
|
566
|
+
const syntheticFields = field.type.jsonType === "array" ? getSyntheticFields(field.type, fieldRef, depth + 1) : [];
|
|
565
567
|
if (!isAssistSupported(field.type, true)) {
|
|
568
|
+
return [...fields, ...syntheticFields];
|
|
569
|
+
}
|
|
570
|
+
return [fieldRef, ...fields, ...syntheticFields];
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
function getSyntheticFields(schemaType, parent) {
|
|
574
|
+
let depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
575
|
+
if (depth >= maxDepth) {
|
|
576
|
+
return [];
|
|
577
|
+
}
|
|
578
|
+
return schemaType.of.filter(itemType => !isType(itemType, "block")).flatMap(itemType => {
|
|
579
|
+
var _a;
|
|
580
|
+
const segment = {
|
|
581
|
+
_key: itemType.name
|
|
582
|
+
};
|
|
583
|
+
const title = (_a = itemType.title) != null ? _a : itemType.name;
|
|
584
|
+
const path = parent ? [...parent.path, segment] : [segment];
|
|
585
|
+
const fieldRef = {
|
|
586
|
+
key: patchableKey(sanity.pathToString(path)),
|
|
587
|
+
path,
|
|
588
|
+
title: parent ? [parent.title, title].join(" / ") : title,
|
|
589
|
+
schemaType: itemType,
|
|
590
|
+
icon: getTypeIcon(itemType),
|
|
591
|
+
synthetic: true
|
|
592
|
+
};
|
|
593
|
+
const fields = itemType.jsonType === "object" ? getFieldRefs(itemType, fieldRef, depth + 1) : [];
|
|
594
|
+
if (!isAssistSupported(itemType, true)) {
|
|
566
595
|
return fields;
|
|
567
596
|
}
|
|
568
597
|
return [fieldRef, ...fields];
|
|
569
598
|
});
|
|
570
599
|
}
|
|
600
|
+
function getTypePath(doc, pathString) {
|
|
601
|
+
if (!pathString) {
|
|
602
|
+
return void 0;
|
|
603
|
+
}
|
|
604
|
+
const path = sanity.stringToPath(pathString);
|
|
605
|
+
const currentPath = [];
|
|
606
|
+
let valid = true;
|
|
607
|
+
const syntheticPath = path.map(segment => {
|
|
608
|
+
currentPath.push(segment);
|
|
609
|
+
if (sanity.isKeySegment(segment)) {
|
|
610
|
+
const match = mutator.extractWithPath(sanity.pathToString(currentPath), doc)[0];
|
|
611
|
+
const value = match == null ? void 0 : match.value;
|
|
612
|
+
if (match && value && typeof value === "object" && "_type" in value) {
|
|
613
|
+
return {
|
|
614
|
+
_key: value._type
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
valid = false;
|
|
618
|
+
}
|
|
619
|
+
return segment;
|
|
620
|
+
});
|
|
621
|
+
return valid ? patchableKey(sanity.pathToString(syntheticPath)) : void 0;
|
|
622
|
+
}
|
|
623
|
+
function patchableKey(pathKey) {
|
|
624
|
+
return pathKey.replace(/[=]=/g, ":").replace(/[[\]]/g, "|").replace(/"/g, "");
|
|
625
|
+
}
|
|
626
|
+
function useTypePath(doc, pathString) {
|
|
627
|
+
return react.useMemo(() => getTypePath(doc, pathString), [doc, pathString]);
|
|
628
|
+
}
|
|
571
629
|
function useSelectedField(documentSchemaType, path) {
|
|
572
630
|
const selectableFields = react.useMemo(() => documentSchemaType && sanity.isObjectSchemaType(documentSchemaType) ? getFieldRefsWithDocument(documentSchemaType) : [], [documentSchemaType]);
|
|
573
631
|
return react.useMemo(() => {
|
|
@@ -575,9 +633,9 @@ function useSelectedField(documentSchemaType, path) {
|
|
|
575
633
|
}, [selectableFields, path]);
|
|
576
634
|
}
|
|
577
635
|
function getFieldTitle(field) {
|
|
578
|
-
var _a, _b;
|
|
636
|
+
var _a, _b, _c;
|
|
579
637
|
const schemaType = field == null ? void 0 : field.schemaType;
|
|
580
|
-
return (_b = (_a = schemaType == null ? void 0 : schemaType.title) != null ?
|
|
638
|
+
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";
|
|
581
639
|
}
|
|
582
640
|
function useAiPaneRouter() {
|
|
583
641
|
const paneRouter = desk.usePaneRouter();
|
|
@@ -1364,32 +1422,338 @@ function InspectorOnboarding(props) {
|
|
|
1364
1422
|
})
|
|
1365
1423
|
});
|
|
1366
1424
|
}
|
|
1367
|
-
const inspectorOnboardingKey = "sanityStudio:assist:inspector:onboarding:dismissed";
|
|
1368
|
-
const fieldOnboardingKey = "sanityStudio:assist:field:onboarding:dismissed";
|
|
1369
|
-
function isFeatureOnboardingDismissed(featureKey) {
|
|
1370
|
-
if (typeof localStorage === "undefined") {
|
|
1371
|
-
return false;
|
|
1372
|
-
}
|
|
1373
|
-
const value = localStorage.getItem(featureKey);
|
|
1374
|
-
return value === "true";
|
|
1375
|
-
}
|
|
1376
|
-
function dismissFeatureOnboarding(featureKey) {
|
|
1377
|
-
if (typeof localStorage === "undefined") {
|
|
1378
|
-
return;
|
|
1379
|
-
}
|
|
1380
|
-
localStorage.setItem(featureKey, "true");
|
|
1381
|
-
}
|
|
1382
|
-
function useOnboardingFeature(featureKey) {
|
|
1383
|
-
const [showOnboarding, setShowOnboarding] = react.useState(() => !isFeatureOnboardingDismissed(featureKey));
|
|
1384
|
-
const dismissOnboarding = react.useCallback(() => {
|
|
1385
|
-
setShowOnboarding(false);
|
|
1386
|
-
dismissFeatureOnboarding(featureKey);
|
|
1387
|
-
}, [setShowOnboarding, featureKey]);
|
|
1388
|
-
return {
|
|
1389
|
-
showOnboarding,
|
|
1390
|
-
dismissOnboarding
|
|
1391
|
-
};
|
|
1392
|
-
}
|
|
1425
|
+
const inspectorOnboardingKey = "sanityStudio:assist:inspector:onboarding:dismissed";
|
|
1426
|
+
const fieldOnboardingKey = "sanityStudio:assist:field:onboarding:dismissed";
|
|
1427
|
+
function isFeatureOnboardingDismissed(featureKey) {
|
|
1428
|
+
if (typeof localStorage === "undefined") {
|
|
1429
|
+
return false;
|
|
1430
|
+
}
|
|
1431
|
+
const value = localStorage.getItem(featureKey);
|
|
1432
|
+
return value === "true";
|
|
1433
|
+
}
|
|
1434
|
+
function dismissFeatureOnboarding(featureKey) {
|
|
1435
|
+
if (typeof localStorage === "undefined") {
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
localStorage.setItem(featureKey, "true");
|
|
1439
|
+
}
|
|
1440
|
+
function useOnboardingFeature(featureKey) {
|
|
1441
|
+
const [showOnboarding, setShowOnboarding] = react.useState(() => !isFeatureOnboardingDismissed(featureKey));
|
|
1442
|
+
const dismissOnboarding = react.useCallback(() => {
|
|
1443
|
+
setShowOnboarding(false);
|
|
1444
|
+
dismissFeatureOnboarding(featureKey);
|
|
1445
|
+
}, [setShowOnboarding, featureKey]);
|
|
1446
|
+
return {
|
|
1447
|
+
showOnboarding,
|
|
1448
|
+
dismissOnboarding
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1451
|
+
function BackToInstructionListLink() {
|
|
1452
|
+
const {
|
|
1453
|
+
openInspector
|
|
1454
|
+
} = desk.useDocumentPane();
|
|
1455
|
+
const goBack = react.useCallback(() => openInspector(aiInspectorId, {
|
|
1456
|
+
[instructionParam]: void 0
|
|
1457
|
+
}), [openInspector]);
|
|
1458
|
+
return /* @__PURE__ */jsxRuntime.jsx("div", {
|
|
1459
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
1460
|
+
as: "a",
|
|
1461
|
+
fontSize: 1,
|
|
1462
|
+
icon: icons.ArrowLeftIcon,
|
|
1463
|
+
mode: "bleed",
|
|
1464
|
+
padding: 1,
|
|
1465
|
+
space: 2,
|
|
1466
|
+
onClick: goBack,
|
|
1467
|
+
text: " Instructions",
|
|
1468
|
+
textAlign: "left"
|
|
1469
|
+
})
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1472
|
+
const EMPTY_FIELDS = [];
|
|
1473
|
+
const TypePathContext = react.createContext(void 0);
|
|
1474
|
+
function AssistDocumentForm(props) {
|
|
1475
|
+
const {
|
|
1476
|
+
onChange
|
|
1477
|
+
} = props;
|
|
1478
|
+
const value = props.value;
|
|
1479
|
+
const id = value == null ? void 0 : value._id;
|
|
1480
|
+
const fields = value == null ? void 0 : value.fields;
|
|
1481
|
+
const targetDocumentType = react.useMemo(() => {
|
|
1482
|
+
if (!id) {
|
|
1483
|
+
return void 0;
|
|
1484
|
+
}
|
|
1485
|
+
return documentTypeFromAiDocumentId(id);
|
|
1486
|
+
}, [id]);
|
|
1487
|
+
const {
|
|
1488
|
+
params,
|
|
1489
|
+
setParams
|
|
1490
|
+
} = useAiPaneRouter();
|
|
1491
|
+
const pathKey = params[fieldPathParam];
|
|
1492
|
+
const typePath = react.useContext(TypePathContext);
|
|
1493
|
+
const instruction = params[instructionParam];
|
|
1494
|
+
const activeKey = react.useMemo(() => {
|
|
1495
|
+
var _a;
|
|
1496
|
+
if (!typePath) {
|
|
1497
|
+
return void 0;
|
|
1498
|
+
}
|
|
1499
|
+
return (_a = (fields != null ? fields : EMPTY_FIELDS).find(f => f.path === typePath)) == null ? void 0 : _a._key;
|
|
1500
|
+
}, [fields, typePath]);
|
|
1501
|
+
const activePath = react.useMemo(() => {
|
|
1502
|
+
if (!activeKey) {
|
|
1503
|
+
return void 0;
|
|
1504
|
+
}
|
|
1505
|
+
const base = ["fields", {
|
|
1506
|
+
_key: activeKey
|
|
1507
|
+
}];
|
|
1508
|
+
return instruction ? [...base, "instructions", {
|
|
1509
|
+
_key: instruction
|
|
1510
|
+
}] : base;
|
|
1511
|
+
}, [activeKey, instruction]);
|
|
1512
|
+
const schema = sanity.useSchema();
|
|
1513
|
+
const documentSchema = react.useMemo(() => {
|
|
1514
|
+
if (!targetDocumentType) {
|
|
1515
|
+
return void 0;
|
|
1516
|
+
}
|
|
1517
|
+
return schema.get(targetDocumentType);
|
|
1518
|
+
}, [schema, targetDocumentType]);
|
|
1519
|
+
const fieldSchema = useSelectedSchema(pathKey, documentSchema);
|
|
1520
|
+
const context = react.useMemo(() => ({
|
|
1521
|
+
documentSchema,
|
|
1522
|
+
fieldSchema: fieldSchema != null ? fieldSchema : documentSchema
|
|
1523
|
+
}), [fieldSchema, documentSchema]);
|
|
1524
|
+
const title = value == null ? void 0 : value.title;
|
|
1525
|
+
react.useEffect(() => {
|
|
1526
|
+
var _a;
|
|
1527
|
+
if (!title && documentSchema && !(id == null ? void 0 : id.startsWith("drafts."))) {
|
|
1528
|
+
onChange(sanity.set((_a = documentSchema.title) != null ? _a : documentSchema.name, ["title"]));
|
|
1529
|
+
}
|
|
1530
|
+
}, [title, documentSchema, onChange, id]);
|
|
1531
|
+
const fieldExists = !!(fields == null ? void 0 : fields.some(f => f._key === typePath));
|
|
1532
|
+
const {
|
|
1533
|
+
onPathOpen,
|
|
1534
|
+
...formCallbacks
|
|
1535
|
+
} = sanity.useFormCallbacks();
|
|
1536
|
+
const newCallbacks = react.useMemo(() => ({
|
|
1537
|
+
...formCallbacks,
|
|
1538
|
+
onPathOpen: path => {
|
|
1539
|
+
var _a;
|
|
1540
|
+
if (!instruction && path.length === 4 && path[2] === "instructions") {
|
|
1541
|
+
setParams(sanity.typed({
|
|
1542
|
+
...params,
|
|
1543
|
+
[instructionParam]: (_a = path[3]) == null ? void 0 : _a._key
|
|
1544
|
+
}));
|
|
1545
|
+
onPathOpen([]);
|
|
1546
|
+
} else {
|
|
1547
|
+
setTimeout(() => onPathOpen(path), 0);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}), [formCallbacks, onPathOpen, params, setParams, instruction]);
|
|
1551
|
+
react.useEffect(() => {
|
|
1552
|
+
if (activePath && !instruction) {
|
|
1553
|
+
onPathOpen([]);
|
|
1554
|
+
}
|
|
1555
|
+
}, [activePath, instruction, onPathOpen]);
|
|
1556
|
+
return /* @__PURE__ */jsxRuntime.jsx(SelectedFieldContextProvider, {
|
|
1557
|
+
value: context,
|
|
1558
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
1559
|
+
space: 5,
|
|
1560
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(FieldsInitializer, {
|
|
1561
|
+
pathKey: typePath,
|
|
1562
|
+
activePath,
|
|
1563
|
+
fieldExists,
|
|
1564
|
+
onChange
|
|
1565
|
+
}, typePath), instruction && /* @__PURE__ */jsxRuntime.jsx(BackToInstructionListLink, {}), activePath && /* @__PURE__ */jsxRuntime.jsx(sanity.FormCallbacksProvider, {
|
|
1566
|
+
...newCallbacks,
|
|
1567
|
+
children: /* @__PURE__ */jsxRuntime.jsx("div", {
|
|
1568
|
+
style: {
|
|
1569
|
+
lineHeight: "1.25em"
|
|
1570
|
+
},
|
|
1571
|
+
children: /* @__PURE__ */jsxRuntime.jsx(sanity.FormInput, {
|
|
1572
|
+
...props,
|
|
1573
|
+
absolutePath: activePath
|
|
1574
|
+
})
|
|
1575
|
+
})
|
|
1576
|
+
}), !activePath && props.renderDefault(props)]
|
|
1577
|
+
})
|
|
1578
|
+
});
|
|
1579
|
+
}
|
|
1580
|
+
function useSelectedSchema(fieldPath, documentSchema) {
|
|
1581
|
+
return react.useMemo(() => {
|
|
1582
|
+
if (!fieldPath) {
|
|
1583
|
+
return void 0;
|
|
1584
|
+
}
|
|
1585
|
+
if (fieldPath === documentRootKey) {
|
|
1586
|
+
return documentSchema;
|
|
1587
|
+
}
|
|
1588
|
+
const path = sanity.stringToPath(fieldPath);
|
|
1589
|
+
let currentSchema = documentSchema;
|
|
1590
|
+
for (let i = 0; i < path.length; i++) {
|
|
1591
|
+
const segment = path[i];
|
|
1592
|
+
const field = currentSchema == null ? void 0 : currentSchema.fields.find(f => f.name === segment);
|
|
1593
|
+
if (!field) {
|
|
1594
|
+
return void 0;
|
|
1595
|
+
}
|
|
1596
|
+
if (i === path.length - 1) {
|
|
1597
|
+
return field.type;
|
|
1598
|
+
}
|
|
1599
|
+
if (field.type.jsonType !== "object") {
|
|
1600
|
+
return void 0;
|
|
1601
|
+
}
|
|
1602
|
+
currentSchema = field.type;
|
|
1603
|
+
}
|
|
1604
|
+
return currentSchema;
|
|
1605
|
+
}, [documentSchema, fieldPath]);
|
|
1606
|
+
}
|
|
1607
|
+
function FieldsInitializer(_ref7) {
|
|
1608
|
+
let {
|
|
1609
|
+
pathKey,
|
|
1610
|
+
activePath,
|
|
1611
|
+
fieldExists,
|
|
1612
|
+
onChange
|
|
1613
|
+
} = _ref7;
|
|
1614
|
+
const initialized = react.useRef(false);
|
|
1615
|
+
react.useEffect(() => {
|
|
1616
|
+
if (initialized.current || fieldExists || activePath || !pathKey) {
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
onChange([sanity.setIfMissing([], ["fields"]), sanity.insert([sanity.typed({
|
|
1620
|
+
_key: pathKey,
|
|
1621
|
+
_type: assistFieldTypeName,
|
|
1622
|
+
path: pathKey
|
|
1623
|
+
})], "after", ["fields", -1])]);
|
|
1624
|
+
initialized.current = true;
|
|
1625
|
+
}, [activePath, onChange, pathKey, fieldExists]);
|
|
1626
|
+
return null;
|
|
1627
|
+
}
|
|
1628
|
+
function FieldAutocomplete(props) {
|
|
1629
|
+
const {
|
|
1630
|
+
id,
|
|
1631
|
+
schemaType,
|
|
1632
|
+
fieldPath,
|
|
1633
|
+
onSelect,
|
|
1634
|
+
includeDocument,
|
|
1635
|
+
filter
|
|
1636
|
+
} = props;
|
|
1637
|
+
const fieldRefs = react.useMemo(() => {
|
|
1638
|
+
if (includeDocument) {
|
|
1639
|
+
return getFieldRefsWithDocument(schemaType);
|
|
1640
|
+
}
|
|
1641
|
+
return getFieldRefs(schemaType);
|
|
1642
|
+
}, [schemaType, includeDocument]);
|
|
1643
|
+
const currentField = react.useMemo(() => fieldRefs.find(f => f.key === fieldPath), [fieldPath, fieldRefs]);
|
|
1644
|
+
const autocompleteOptions = react.useMemo(() => fieldRefs.filter(field => filter ? filter(field) : true).map(field => ({
|
|
1645
|
+
value: field.key,
|
|
1646
|
+
field
|
|
1647
|
+
})), [fieldRefs, filter]);
|
|
1648
|
+
const renderOption = react.useCallback(option => {
|
|
1649
|
+
const {
|
|
1650
|
+
value,
|
|
1651
|
+
field
|
|
1652
|
+
} = option;
|
|
1653
|
+
if (!value) {
|
|
1654
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
1655
|
+
as: "button",
|
|
1656
|
+
padding: 3,
|
|
1657
|
+
radius: 1,
|
|
1658
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
1659
|
+
accent: true,
|
|
1660
|
+
size: 1,
|
|
1661
|
+
children: option.value
|
|
1662
|
+
})
|
|
1663
|
+
});
|
|
1664
|
+
}
|
|
1665
|
+
if (isType(field.schemaType, "document")) {
|
|
1666
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
1667
|
+
as: "button",
|
|
1668
|
+
padding: 3,
|
|
1669
|
+
radius: 1,
|
|
1670
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
1671
|
+
size: 1,
|
|
1672
|
+
weight: "semibold",
|
|
1673
|
+
children: "The entire document"
|
|
1674
|
+
})
|
|
1675
|
+
});
|
|
1676
|
+
}
|
|
1677
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
1678
|
+
as: "button",
|
|
1679
|
+
padding: 3,
|
|
1680
|
+
radius: 1,
|
|
1681
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
1682
|
+
gap: 3,
|
|
1683
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
1684
|
+
size: 1,
|
|
1685
|
+
children: react.createElement(field.icon)
|
|
1686
|
+
}), /* @__PURE__ */jsxRuntime.jsx(FieldTitle, {
|
|
1687
|
+
field
|
|
1688
|
+
})]
|
|
1689
|
+
})
|
|
1690
|
+
});
|
|
1691
|
+
}, []);
|
|
1692
|
+
const renderValue = react.useCallback((value, option) => {
|
|
1693
|
+
var _a;
|
|
1694
|
+
return (_a = option == null ? void 0 : option.field.title) != null ? _a : value;
|
|
1695
|
+
}, []);
|
|
1696
|
+
const filterOption = react.useCallback((query, option) => {
|
|
1697
|
+
var _a, _b, _c;
|
|
1698
|
+
const lQuery = query.toLowerCase();
|
|
1699
|
+
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));
|
|
1700
|
+
}, []);
|
|
1701
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Autocomplete, {
|
|
1702
|
+
fontSize: 1,
|
|
1703
|
+
icon: currentField ? currentField.icon : icons.SearchIcon,
|
|
1704
|
+
onChange: onSelect,
|
|
1705
|
+
openButton: true,
|
|
1706
|
+
id,
|
|
1707
|
+
options: autocompleteOptions,
|
|
1708
|
+
placeholder: "Search for a field",
|
|
1709
|
+
radius: 2,
|
|
1710
|
+
renderOption,
|
|
1711
|
+
renderValue,
|
|
1712
|
+
value: currentField == null ? void 0 : currentField.key,
|
|
1713
|
+
filterOption
|
|
1714
|
+
});
|
|
1715
|
+
}
|
|
1716
|
+
function FieldTitle(props) {
|
|
1717
|
+
const splitTitle = props.field.title.split("/");
|
|
1718
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
1719
|
+
flex: "none",
|
|
1720
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Breadcrumbs, {
|
|
1721
|
+
style: {
|
|
1722
|
+
display: "flex",
|
|
1723
|
+
flexWrap: "wrap",
|
|
1724
|
+
alignItems: "center",
|
|
1725
|
+
marginTop: "-4px"
|
|
1726
|
+
},
|
|
1727
|
+
separator: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
1728
|
+
marginTop: 1,
|
|
1729
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
1730
|
+
muted: true,
|
|
1731
|
+
size: 1,
|
|
1732
|
+
children: "/"
|
|
1733
|
+
})
|
|
1734
|
+
}),
|
|
1735
|
+
space: 1,
|
|
1736
|
+
children: [splitTitle.slice(0, splitTitle.length - 1).map((pt, i) =>
|
|
1737
|
+
// eslint-disable-next-line react/no-array-index-key
|
|
1738
|
+
/* @__PURE__ */
|
|
1739
|
+
jsxRuntime.jsx(ui.Box, {
|
|
1740
|
+
marginTop: 1,
|
|
1741
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
1742
|
+
muted: true,
|
|
1743
|
+
size: 1,
|
|
1744
|
+
children: pt.trim()
|
|
1745
|
+
})
|
|
1746
|
+
}, i)), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
1747
|
+
marginTop: 1,
|
|
1748
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
1749
|
+
size: 1,
|
|
1750
|
+
weight: "medium",
|
|
1751
|
+
children: splitTitle[splitTitle.length - 1]
|
|
1752
|
+
})
|
|
1753
|
+
})]
|
|
1754
|
+
})
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1393
1757
|
var __freeze$4 = Object.freeze;
|
|
1394
1758
|
var __defProp$4 = Object.defineProperty;
|
|
1395
1759
|
var __template$4 = (cooked, raw) => __freeze$4(__defProp$4(cooked, "raw", {
|
|
@@ -1527,6 +1891,7 @@ function AssistInspector(props) {
|
|
|
1527
1891
|
const {
|
|
1528
1892
|
documentId,
|
|
1529
1893
|
documentType,
|
|
1894
|
+
value: docValue,
|
|
1530
1895
|
schemaType,
|
|
1531
1896
|
onChange: documentOnChange
|
|
1532
1897
|
} = documentPane;
|
|
@@ -1542,13 +1907,14 @@ function AssistInspector(props) {
|
|
|
1542
1907
|
documentOnChange,
|
|
1543
1908
|
isDocAssistable: isDocAssistable(schemaType, published, draft)
|
|
1544
1909
|
});
|
|
1545
|
-
const
|
|
1910
|
+
const typePath = useTypePath(docValue, pathKey != null ? pathKey : "");
|
|
1911
|
+
const selectedField = useSelectedField(schemaType, typePath);
|
|
1546
1912
|
const aiDocId = assistDocumentId(documentType);
|
|
1547
1913
|
const assistDocument = useStudioAssistDocument({
|
|
1548
1914
|
documentId,
|
|
1549
1915
|
schemaType
|
|
1550
1916
|
});
|
|
1551
|
-
const assistField = (_a2 = assistDocument == null ? void 0 : assistDocument.fields) == null ? void 0 : _a2.find(f => f.path ===
|
|
1917
|
+
const assistField = (_a2 = assistDocument == null ? void 0 : assistDocument.fields) == null ? void 0 : _a2.find(f => f.path === typePath);
|
|
1552
1918
|
const instruction = (_b2 = assistField == null ? void 0 : assistField.instructions) == null ? void 0 : _b2.find(i => i._key === instructionKey);
|
|
1553
1919
|
const tasks = react.useMemo(() => {
|
|
1554
1920
|
var _a3;
|
|
@@ -1580,12 +1946,13 @@ function AssistInspector(props) {
|
|
|
1580
1946
|
type: assistDocumentTypeName
|
|
1581
1947
|
}
|
|
1582
1948
|
}), [aiDocId]);
|
|
1583
|
-
const runCurrentInstruction = react.useCallback(() => instruction && pathKey && requestRunInstruction({
|
|
1949
|
+
const runCurrentInstruction = react.useCallback(() => instruction && pathKey && typePath && requestRunInstruction({
|
|
1584
1950
|
documentId: assistableDocId,
|
|
1585
1951
|
path: pathKey,
|
|
1952
|
+
typePath,
|
|
1586
1953
|
assistDocumentId: assistDocumentId(documentType),
|
|
1587
1954
|
instruction
|
|
1588
|
-
}), [instruction,
|
|
1955
|
+
}), [pathKey, instruction, typePath, documentType, assistableDocId, requestRunInstruction]);
|
|
1589
1956
|
const Region = react.useCallback(_props => {
|
|
1590
1957
|
return /* @__PURE__ */jsxRuntime.jsx("div", {
|
|
1591
1958
|
..._props,
|
|
@@ -1616,6 +1983,7 @@ function AssistInspector(props) {
|
|
|
1616
1983
|
},
|
|
1617
1984
|
children: [/* @__PURE__ */jsxRuntime.jsx(AiInspectorHeader, {
|
|
1618
1985
|
onClose: props.onClose,
|
|
1986
|
+
field: selectedField,
|
|
1619
1987
|
fieldTitle: getFieldTitle(selectedField)
|
|
1620
1988
|
}), /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
1621
1989
|
as: Region,
|
|
@@ -1631,15 +1999,18 @@ function AssistInspector(props) {
|
|
|
1631
1999
|
children: /* @__PURE__ */jsxRuntime.jsx(sanity.PresenceOverlay, {
|
|
1632
2000
|
children: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
1633
2001
|
padding: 4,
|
|
1634
|
-
children: selectedField && /* @__PURE__ */jsxRuntime.jsx(
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
2002
|
+
children: selectedField && /* @__PURE__ */jsxRuntime.jsx(TypePathContext.Provider, {
|
|
2003
|
+
value: typePath,
|
|
2004
|
+
children: /* @__PURE__ */jsxRuntime.jsx(sanity.VirtualizerScrollInstanceProvider, {
|
|
2005
|
+
scrollElement: boundary.current,
|
|
2006
|
+
containerElement: boundary,
|
|
2007
|
+
children: /* @__PURE__ */jsxRuntime.jsx(desk.DocumentPaneProvider, {
|
|
2008
|
+
paneKey: documentPane.paneKey,
|
|
2009
|
+
index: documentPane.index,
|
|
2010
|
+
itemId: "ai",
|
|
2011
|
+
pane: paneNode,
|
|
2012
|
+
children: /* @__PURE__ */jsxRuntime.jsx(DocumentForm, {})
|
|
2013
|
+
})
|
|
1643
2014
|
})
|
|
1644
2015
|
})
|
|
1645
2016
|
})
|
|
@@ -1697,6 +2068,7 @@ function AssistInspector(props) {
|
|
|
1697
2068
|
function AiInspectorHeader(props) {
|
|
1698
2069
|
const {
|
|
1699
2070
|
onClose,
|
|
2071
|
+
field,
|
|
1700
2072
|
fieldTitle
|
|
1701
2073
|
} = props;
|
|
1702
2074
|
const {
|
|
@@ -1717,18 +2089,25 @@ function AiInspectorHeader(props) {
|
|
|
1717
2089
|
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
1718
2090
|
gap: 1,
|
|
1719
2091
|
align: "center",
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
2092
|
+
wrap: "wrap",
|
|
2093
|
+
style: {
|
|
2094
|
+
marginTop: "-4px"
|
|
2095
|
+
},
|
|
2096
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2097
|
+
marginTop: 1,
|
|
2098
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
2099
|
+
size: 1,
|
|
2100
|
+
weight: "semibold",
|
|
2101
|
+
children: "AI instructions for"
|
|
2102
|
+
})
|
|
1724
2103
|
}), /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
1725
2104
|
radius: 2,
|
|
1726
2105
|
border: true,
|
|
1727
2106
|
padding: 1,
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
2107
|
+
marginTop: 1,
|
|
2108
|
+
children: field ? /* @__PURE__ */jsxRuntime.jsx(FieldTitle, {
|
|
2109
|
+
field
|
|
2110
|
+
}) : /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
1732
2111
|
size: 1,
|
|
1733
2112
|
weight: "semibold",
|
|
1734
2113
|
children: fieldTitle
|
|
@@ -1758,10 +2137,10 @@ const assistInspector = {
|
|
|
1758
2137
|
showAsAction: false
|
|
1759
2138
|
}),
|
|
1760
2139
|
component: AssistInspectorWrapper,
|
|
1761
|
-
onClose(
|
|
2140
|
+
onClose(_ref8) {
|
|
1762
2141
|
let {
|
|
1763
2142
|
params
|
|
1764
|
-
} =
|
|
2143
|
+
} = _ref8;
|
|
1765
2144
|
return {
|
|
1766
2145
|
params: sanity.typed({
|
|
1767
2146
|
...params,
|
|
@@ -1834,11 +2213,11 @@ var __template$3 = (cooked, raw) => __freeze$3(__defProp$3(cooked, "raw", {
|
|
|
1834
2213
|
var _a$3, _b$1;
|
|
1835
2214
|
const fadeIn = styled.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"])));
|
|
1836
2215
|
const FadeInDiv = styled__default.default.div(_b$1 || (_b$1 = __template$3(["\n animation-name: ", ";\n animation-timing-function: ease-in-out;\n"])), fadeIn);
|
|
1837
|
-
const FadeInContent = react.forwardRef(function FadeInContent2(
|
|
2216
|
+
const FadeInContent = react.forwardRef(function FadeInContent2(_ref9, ref) {
|
|
1838
2217
|
let {
|
|
1839
2218
|
children,
|
|
1840
2219
|
durationMs = 250
|
|
1841
|
-
} =
|
|
2220
|
+
} = _ref9;
|
|
1842
2221
|
return /* @__PURE__ */jsxRuntime.jsx(FadeInDiv, {
|
|
1843
2222
|
ref,
|
|
1844
2223
|
style: {
|
|
@@ -2863,291 +3242,119 @@ function SafeValueInput(props) {
|
|
|
2863
3242
|
function ErrorWrapper(props) {
|
|
2864
3243
|
const {
|
|
2865
3244
|
onChange
|
|
2866
|
-
} = props;
|
|
2867
|
-
const [error, setError] = react.useState();
|
|
2868
|
-
const catchError = react.useCallback(params => {
|
|
2869
|
-
setError(params.error);
|
|
2870
|
-
}, [setError]);
|
|
2871
|
-
const unsetValue = react.useCallback(() => onChange(sanity.PatchEvent.from(sanity.unset())), [onChange]);
|
|
2872
|
-
const dismiss = react.useCallback(() => setError(void 0), []);
|
|
2873
|
-
const catcher = /* @__PURE__ */jsxRuntime.jsx(ui.ErrorBoundary, {
|
|
2874
|
-
onCatch: catchError,
|
|
2875
|
-
children: props.children
|
|
2876
|
-
});
|
|
2877
|
-
return error ? /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
2878
|
-
border: true,
|
|
2879
|
-
tone: "critical",
|
|
2880
|
-
padding: 2,
|
|
2881
|
-
contentEditable: false,
|
|
2882
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
2883
|
-
space: 3,
|
|
2884
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
2885
|
-
muted: true,
|
|
2886
|
-
weight: "semibold",
|
|
2887
|
-
children: "An error occurred."
|
|
2888
|
-
}), /* @__PURE__ */jsxRuntime.jsx(WrapPreCard, {
|
|
2889
|
-
flex: 1,
|
|
2890
|
-
padding: 2,
|
|
2891
|
-
tone: "critical",
|
|
2892
|
-
border: true,
|
|
2893
|
-
children: catcher
|
|
2894
|
-
}), /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
2895
|
-
width: "fill",
|
|
2896
|
-
flex: 1,
|
|
2897
|
-
gap: 3,
|
|
2898
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2899
|
-
flex: 1,
|
|
2900
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
2901
|
-
text: "Dismiss",
|
|
2902
|
-
onClick: dismiss,
|
|
2903
|
-
tone: "primary"
|
|
2904
|
-
})
|
|
2905
|
-
}), /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
2906
|
-
text: "Unset value",
|
|
2907
|
-
onClick: unsetValue,
|
|
2908
|
-
tone: "critical"
|
|
2909
|
-
})]
|
|
2910
|
-
})]
|
|
2911
|
-
})
|
|
2912
|
-
}) : catcher;
|
|
2913
|
-
}
|
|
2914
|
-
function PteValueFixer(props) {
|
|
2915
|
-
const isPortableText = react.useMemo(() => sanity.isArraySchemaType(props.schemaType) && isPortableTextArray(props.schemaType), [props.schemaType]);
|
|
2916
|
-
const value = props.value;
|
|
2917
|
-
if (isPortableText && value && !value.length) {
|
|
2918
|
-
return props.renderDefault({
|
|
2919
|
-
...props,
|
|
2920
|
-
value: void 0
|
|
2921
|
-
});
|
|
2922
|
-
}
|
|
2923
|
-
return props.renderDefault(props);
|
|
2924
|
-
}
|
|
2925
|
-
function AssistFormBlock(props) {
|
|
2926
|
-
const presence = useAssistPresence(props.path, true);
|
|
2927
|
-
const {
|
|
2928
|
-
onChange
|
|
2929
|
-
} = sanity.useFormCallbacks();
|
|
2930
|
-
const key = props.value._key;
|
|
2931
|
-
const localOnChange = react.useCallback(patchEvent => {
|
|
2932
|
-
if (!key) {
|
|
2933
|
-
return;
|
|
2934
|
-
}
|
|
2935
|
-
onChange(sanity.PatchEvent.from(patchEvent).prefixAll({
|
|
2936
|
-
_key: key
|
|
2937
|
-
}));
|
|
2938
|
-
}, [onChange, key]);
|
|
2939
|
-
return /* @__PURE__ */jsxRuntime.jsx(ErrorWrapper, {
|
|
2940
|
-
onChange: localOnChange,
|
|
2941
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
2942
|
-
align: "center",
|
|
2943
|
-
justify: "space-between",
|
|
2944
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2945
|
-
flex: 1,
|
|
2946
|
-
children: props.renderDefault(props)
|
|
2947
|
-
}), presence.map(pre => /* @__PURE__ */jsxRuntime.jsx(AiFieldPresence, {
|
|
2948
|
-
presence: pre
|
|
2949
|
-
}, pre.lastActiveAt))]
|
|
2950
|
-
})
|
|
2951
|
-
});
|
|
2952
|
-
}
|
|
2953
|
-
function AssistItem(props) {
|
|
2954
|
-
const {
|
|
2955
|
-
path
|
|
2956
|
-
} = props;
|
|
2957
|
-
const presence = useAssistPresence(path, true);
|
|
2958
|
-
return /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
2959
|
-
align: "center",
|
|
2960
|
-
width: "fill",
|
|
2961
|
-
style: {
|
|
2962
|
-
position: "relative"
|
|
2963
|
-
},
|
|
2964
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2965
|
-
flex: 1,
|
|
2966
|
-
children: props.renderDefault({
|
|
2967
|
-
...props
|
|
2968
|
-
})
|
|
2969
|
-
}), presence.map(pre => /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2970
|
-
style: {
|
|
2971
|
-
position: "absolute",
|
|
2972
|
-
right: 35
|
|
2973
|
-
},
|
|
2974
|
-
children: /* @__PURE__ */jsxRuntime.jsx(AiFieldPresence, {
|
|
2975
|
-
presence: pre
|
|
2976
|
-
})
|
|
2977
|
-
}, pre.user.id))]
|
|
2978
|
-
});
|
|
2979
|
-
}
|
|
2980
|
-
function BackToInstructionListLink() {
|
|
2981
|
-
const {
|
|
2982
|
-
openInspector
|
|
2983
|
-
} = desk.useDocumentPane();
|
|
2984
|
-
const goBack = react.useCallback(() => openInspector(aiInspectorId, {
|
|
2985
|
-
[instructionParam]: void 0
|
|
2986
|
-
}), [openInspector]);
|
|
2987
|
-
return /* @__PURE__ */jsxRuntime.jsx("div", {
|
|
2988
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
2989
|
-
as: "a",
|
|
2990
|
-
fontSize: 1,
|
|
2991
|
-
icon: icons.ArrowLeftIcon,
|
|
2992
|
-
mode: "bleed",
|
|
2993
|
-
padding: 1,
|
|
2994
|
-
space: 2,
|
|
2995
|
-
onClick: goBack,
|
|
2996
|
-
text: " Instructions",
|
|
2997
|
-
textAlign: "left"
|
|
2998
|
-
})
|
|
2999
|
-
});
|
|
3000
|
-
}
|
|
3001
|
-
const EMPTY_FIELDS = [];
|
|
3002
|
-
function AssistDocumentForm(props) {
|
|
3003
|
-
const {
|
|
3004
|
-
onChange
|
|
3005
|
-
} = props;
|
|
3006
|
-
const value = props.value;
|
|
3007
|
-
const id = value == null ? void 0 : value._id;
|
|
3008
|
-
const fields = value == null ? void 0 : value.fields;
|
|
3009
|
-
const targetDocumentType = react.useMemo(() => {
|
|
3010
|
-
if (!id) {
|
|
3011
|
-
return void 0;
|
|
3012
|
-
}
|
|
3013
|
-
return documentTypeFromAiDocumentId(id);
|
|
3014
|
-
}, [id]);
|
|
3015
|
-
const {
|
|
3016
|
-
params,
|
|
3017
|
-
setParams
|
|
3018
|
-
} = useAiPaneRouter();
|
|
3019
|
-
const pathKey = params[fieldPathParam];
|
|
3020
|
-
const instruction = params[instructionParam];
|
|
3021
|
-
const activeKey = react.useMemo(() => {
|
|
3022
|
-
var _a;
|
|
3023
|
-
return (_a = (fields != null ? fields : EMPTY_FIELDS).find(f => f.path === pathKey)) == null ? void 0 : _a._key;
|
|
3024
|
-
}, [fields, pathKey]);
|
|
3025
|
-
const activePath = react.useMemo(() => {
|
|
3026
|
-
if (!activeKey) {
|
|
3027
|
-
return void 0;
|
|
3028
|
-
}
|
|
3029
|
-
const base = ["fields", {
|
|
3030
|
-
_key: activeKey
|
|
3031
|
-
}];
|
|
3032
|
-
return instruction ? [...base, "instructions", {
|
|
3033
|
-
_key: instruction
|
|
3034
|
-
}] : base;
|
|
3035
|
-
}, [activeKey, instruction]);
|
|
3036
|
-
const schema = sanity.useSchema();
|
|
3037
|
-
const documentSchema = react.useMemo(() => {
|
|
3038
|
-
if (!targetDocumentType) {
|
|
3039
|
-
return void 0;
|
|
3040
|
-
}
|
|
3041
|
-
return schema.get(targetDocumentType);
|
|
3042
|
-
}, [schema, targetDocumentType]);
|
|
3043
|
-
const fieldSchema = useSelectedSchema(pathKey, documentSchema);
|
|
3044
|
-
const context = react.useMemo(() => ({
|
|
3045
|
-
documentSchema,
|
|
3046
|
-
fieldSchema: fieldSchema != null ? fieldSchema : documentSchema
|
|
3047
|
-
}), [fieldSchema, documentSchema]);
|
|
3048
|
-
const title = value == null ? void 0 : value.title;
|
|
3049
|
-
react.useEffect(() => {
|
|
3050
|
-
var _a;
|
|
3051
|
-
if (!title && documentSchema && !(id == null ? void 0 : id.startsWith("drafts."))) {
|
|
3052
|
-
onChange(sanity.set((_a = documentSchema.title) != null ? _a : documentSchema.name, ["title"]));
|
|
3053
|
-
}
|
|
3054
|
-
}, [title, documentSchema, onChange, id]);
|
|
3055
|
-
const fieldExists = !!(fields == null ? void 0 : fields.some(f => f._key === pathKey));
|
|
3056
|
-
const {
|
|
3057
|
-
onPathOpen,
|
|
3058
|
-
...formCallbacks
|
|
3059
|
-
} = sanity.useFormCallbacks();
|
|
3060
|
-
const newCallbacks = react.useMemo(() => ({
|
|
3061
|
-
...formCallbacks,
|
|
3062
|
-
onPathOpen: path => {
|
|
3063
|
-
var _a;
|
|
3064
|
-
if (!instruction && path.length === 4 && path[2] === "instructions") {
|
|
3065
|
-
setParams(sanity.typed({
|
|
3066
|
-
...params,
|
|
3067
|
-
[instructionParam]: (_a = path[3]) == null ? void 0 : _a._key
|
|
3068
|
-
}));
|
|
3069
|
-
onPathOpen([]);
|
|
3070
|
-
} else {
|
|
3071
|
-
setTimeout(() => onPathOpen(path), 0);
|
|
3072
|
-
}
|
|
3073
|
-
}
|
|
3074
|
-
}), [formCallbacks, onPathOpen, params, setParams, instruction]);
|
|
3075
|
-
react.useEffect(() => {
|
|
3076
|
-
if (activePath && !instruction) {
|
|
3077
|
-
onPathOpen([]);
|
|
3078
|
-
}
|
|
3079
|
-
}, [activePath, instruction, onPathOpen]);
|
|
3080
|
-
return /* @__PURE__ */jsxRuntime.jsx(SelectedFieldContextProvider, {
|
|
3081
|
-
value: context,
|
|
3245
|
+
} = props;
|
|
3246
|
+
const [error, setError] = react.useState();
|
|
3247
|
+
const catchError = react.useCallback(params => {
|
|
3248
|
+
setError(params.error);
|
|
3249
|
+
}, [setError]);
|
|
3250
|
+
const unsetValue = react.useCallback(() => onChange(sanity.PatchEvent.from(sanity.unset())), [onChange]);
|
|
3251
|
+
const dismiss = react.useCallback(() => setError(void 0), []);
|
|
3252
|
+
const catcher = /* @__PURE__ */jsxRuntime.jsx(ui.ErrorBoundary, {
|
|
3253
|
+
onCatch: catchError,
|
|
3254
|
+
children: props.children
|
|
3255
|
+
});
|
|
3256
|
+
return error ? /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
3257
|
+
border: true,
|
|
3258
|
+
tone: "critical",
|
|
3259
|
+
padding: 2,
|
|
3260
|
+
contentEditable: false,
|
|
3082
3261
|
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
3083
|
-
space:
|
|
3084
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3262
|
+
space: 3,
|
|
3263
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
3264
|
+
muted: true,
|
|
3265
|
+
weight: "semibold",
|
|
3266
|
+
children: "An error occurred."
|
|
3267
|
+
}), /* @__PURE__ */jsxRuntime.jsx(WrapPreCard, {
|
|
3268
|
+
flex: 1,
|
|
3269
|
+
padding: 2,
|
|
3270
|
+
tone: "critical",
|
|
3271
|
+
border: true,
|
|
3272
|
+
children: catcher
|
|
3273
|
+
}), /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
3274
|
+
width: "fill",
|
|
3275
|
+
flex: 1,
|
|
3276
|
+
gap: 3,
|
|
3277
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
3278
|
+
flex: 1,
|
|
3279
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
3280
|
+
text: "Dismiss",
|
|
3281
|
+
onClick: dismiss,
|
|
3282
|
+
tone: "primary"
|
|
3098
3283
|
})
|
|
3099
|
-
})
|
|
3100
|
-
|
|
3284
|
+
}), /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
3285
|
+
text: "Unset value",
|
|
3286
|
+
onClick: unsetValue,
|
|
3287
|
+
tone: "critical"
|
|
3288
|
+
})]
|
|
3289
|
+
})]
|
|
3101
3290
|
})
|
|
3102
|
-
});
|
|
3291
|
+
}) : catcher;
|
|
3103
3292
|
}
|
|
3104
|
-
function
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
}
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
for (let i = 0; i < path.length; i++) {
|
|
3115
|
-
const segment = path[i];
|
|
3116
|
-
const field = currentSchema == null ? void 0 : currentSchema.fields.find(f => f.name === segment);
|
|
3117
|
-
if (!field) {
|
|
3118
|
-
return void 0;
|
|
3119
|
-
}
|
|
3120
|
-
if (i === path.length - 1) {
|
|
3121
|
-
return field.type;
|
|
3122
|
-
}
|
|
3123
|
-
if (field.type.jsonType !== "object") {
|
|
3124
|
-
return void 0;
|
|
3125
|
-
}
|
|
3126
|
-
currentSchema = field.type;
|
|
3127
|
-
}
|
|
3128
|
-
return currentSchema;
|
|
3129
|
-
}, [documentSchema, fieldPath]);
|
|
3293
|
+
function PteValueFixer(props) {
|
|
3294
|
+
const isPortableText = react.useMemo(() => sanity.isArraySchemaType(props.schemaType) && isPortableTextArray(props.schemaType), [props.schemaType]);
|
|
3295
|
+
const value = props.value;
|
|
3296
|
+
if (isPortableText && value && !value.length) {
|
|
3297
|
+
return props.renderDefault({
|
|
3298
|
+
...props,
|
|
3299
|
+
value: void 0
|
|
3300
|
+
});
|
|
3301
|
+
}
|
|
3302
|
+
return props.renderDefault(props);
|
|
3130
3303
|
}
|
|
3131
|
-
function
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
activePath,
|
|
3135
|
-
fieldExists,
|
|
3304
|
+
function AssistFormBlock(props) {
|
|
3305
|
+
const presence = useAssistPresence(props.path, true);
|
|
3306
|
+
const {
|
|
3136
3307
|
onChange
|
|
3137
|
-
} =
|
|
3138
|
-
const
|
|
3139
|
-
react.
|
|
3140
|
-
if (
|
|
3308
|
+
} = sanity.useFormCallbacks();
|
|
3309
|
+
const key = props.value._key;
|
|
3310
|
+
const localOnChange = react.useCallback(patchEvent => {
|
|
3311
|
+
if (!key) {
|
|
3141
3312
|
return;
|
|
3142
3313
|
}
|
|
3143
|
-
onChange(
|
|
3144
|
-
_key:
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3314
|
+
onChange(sanity.PatchEvent.from(patchEvent).prefixAll({
|
|
3315
|
+
_key: key
|
|
3316
|
+
}));
|
|
3317
|
+
}, [onChange, key]);
|
|
3318
|
+
return /* @__PURE__ */jsxRuntime.jsx(ErrorWrapper, {
|
|
3319
|
+
onChange: localOnChange,
|
|
3320
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
3321
|
+
align: "center",
|
|
3322
|
+
justify: "space-between",
|
|
3323
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
3324
|
+
flex: 1,
|
|
3325
|
+
children: props.renderDefault(props)
|
|
3326
|
+
}), presence.map(pre => /* @__PURE__ */jsxRuntime.jsx(AiFieldPresence, {
|
|
3327
|
+
presence: pre
|
|
3328
|
+
}, pre.lastActiveAt))]
|
|
3329
|
+
})
|
|
3330
|
+
});
|
|
3331
|
+
}
|
|
3332
|
+
function AssistItem(props) {
|
|
3333
|
+
const {
|
|
3334
|
+
path
|
|
3335
|
+
} = props;
|
|
3336
|
+
const presence = useAssistPresence(path, true);
|
|
3337
|
+
return /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
3338
|
+
align: "center",
|
|
3339
|
+
width: "fill",
|
|
3340
|
+
style: {
|
|
3341
|
+
position: "relative"
|
|
3342
|
+
},
|
|
3343
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
3344
|
+
flex: 1,
|
|
3345
|
+
children: props.renderDefault({
|
|
3346
|
+
...props
|
|
3347
|
+
})
|
|
3348
|
+
}), presence.map(pre => /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
3349
|
+
style: {
|
|
3350
|
+
position: "absolute",
|
|
3351
|
+
right: 35
|
|
3352
|
+
},
|
|
3353
|
+
children: /* @__PURE__ */jsxRuntime.jsx(AiFieldPresence, {
|
|
3354
|
+
presence: pre
|
|
3355
|
+
})
|
|
3356
|
+
}, pre.user.id))]
|
|
3357
|
+
});
|
|
3151
3358
|
}
|
|
3152
3359
|
function findFieldMember(members, fieldName) {
|
|
3153
3360
|
return members.find(m => m.kind === "field" && m.name === fieldName || m.kind === "error" && m.fieldName === fieldName);
|
|
@@ -3356,117 +3563,10 @@ function getIcon(iconName) {
|
|
|
3356
3563
|
return key === iconName;
|
|
3357
3564
|
})) == null ? void 0 : _a[1]) != null ? _b : icons.icons.sparkles;
|
|
3358
3565
|
}
|
|
3359
|
-
function FieldAutocomplete(props) {
|
|
3360
|
-
const {
|
|
3361
|
-
id,
|
|
3362
|
-
schemaType,
|
|
3363
|
-
fieldPath,
|
|
3364
|
-
onSelect,
|
|
3365
|
-
includeDocument
|
|
3366
|
-
} = props;
|
|
3367
|
-
const fieldNames = react.useMemo(() => {
|
|
3368
|
-
if (includeDocument) {
|
|
3369
|
-
return getFieldRefsWithDocument(schemaType);
|
|
3370
|
-
}
|
|
3371
|
-
return getFieldRefs(schemaType);
|
|
3372
|
-
}, [schemaType, includeDocument]);
|
|
3373
|
-
const currentField = react.useMemo(() => fieldNames.find(f => f.key === fieldPath), [fieldPath, fieldNames]);
|
|
3374
|
-
const autocompleteOptions = react.useMemo(() => fieldNames.map(field => ({
|
|
3375
|
-
value: field.key,
|
|
3376
|
-
field
|
|
3377
|
-
})), [fieldNames]);
|
|
3378
|
-
const renderOption = react.useCallback(option => {
|
|
3379
|
-
const {
|
|
3380
|
-
value,
|
|
3381
|
-
field
|
|
3382
|
-
} = option;
|
|
3383
|
-
if (!value) {
|
|
3384
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
3385
|
-
as: "button",
|
|
3386
|
-
padding: 3,
|
|
3387
|
-
radius: 1,
|
|
3388
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
3389
|
-
accent: true,
|
|
3390
|
-
size: 1,
|
|
3391
|
-
children: option.value
|
|
3392
|
-
})
|
|
3393
|
-
});
|
|
3394
|
-
}
|
|
3395
|
-
if (isType(field.schemaType, "document")) {
|
|
3396
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
3397
|
-
as: "button",
|
|
3398
|
-
padding: 3,
|
|
3399
|
-
radius: 1,
|
|
3400
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
3401
|
-
size: 1,
|
|
3402
|
-
weight: "semibold",
|
|
3403
|
-
children: "The entire document"
|
|
3404
|
-
})
|
|
3405
|
-
});
|
|
3406
|
-
}
|
|
3407
|
-
const splitTitle = field.title.split("/");
|
|
3408
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
3409
|
-
as: "button",
|
|
3410
|
-
padding: 3,
|
|
3411
|
-
radius: 1,
|
|
3412
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
3413
|
-
gap: 3,
|
|
3414
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
3415
|
-
size: 1,
|
|
3416
|
-
children: react.createElement(field.icon)
|
|
3417
|
-
}), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
3418
|
-
flex: "none",
|
|
3419
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Breadcrumbs, {
|
|
3420
|
-
separator: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
3421
|
-
muted: true,
|
|
3422
|
-
size: 1,
|
|
3423
|
-
children: "/"
|
|
3424
|
-
}),
|
|
3425
|
-
space: 1,
|
|
3426
|
-
children: [splitTitle.slice(0, splitTitle.length - 1).map((pt, i) =>
|
|
3427
|
-
// eslint-disable-next-line react/no-array-index-key
|
|
3428
|
-
/* @__PURE__ */
|
|
3429
|
-
jsxRuntime.jsx(ui.Text, {
|
|
3430
|
-
muted: true,
|
|
3431
|
-
size: 1,
|
|
3432
|
-
children: pt.trim()
|
|
3433
|
-
}, i)), /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
3434
|
-
size: 1,
|
|
3435
|
-
weight: "medium",
|
|
3436
|
-
children: splitTitle[splitTitle.length - 1]
|
|
3437
|
-
})]
|
|
3438
|
-
})
|
|
3439
|
-
})]
|
|
3440
|
-
})
|
|
3441
|
-
});
|
|
3442
|
-
}, []);
|
|
3443
|
-
const renderValue = react.useCallback((value, option) => {
|
|
3444
|
-
var _a;
|
|
3445
|
-
return (_a = option == null ? void 0 : option.field.title) != null ? _a : value;
|
|
3446
|
-
}, []);
|
|
3447
|
-
const filterOption = react.useCallback((query, option) => {
|
|
3448
|
-
var _a, _b, _c;
|
|
3449
|
-
const lQuery = query.toLowerCase();
|
|
3450
|
-
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));
|
|
3451
|
-
}, []);
|
|
3452
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Autocomplete, {
|
|
3453
|
-
fontSize: 1,
|
|
3454
|
-
icon: currentField ? currentField.icon : icons.SearchIcon,
|
|
3455
|
-
onChange: onSelect,
|
|
3456
|
-
openButton: true,
|
|
3457
|
-
id,
|
|
3458
|
-
options: autocompleteOptions,
|
|
3459
|
-
placeholder: "Search for a field",
|
|
3460
|
-
radius: 2,
|
|
3461
|
-
renderOption,
|
|
3462
|
-
renderValue,
|
|
3463
|
-
value: currentField == null ? void 0 : currentField.key,
|
|
3464
|
-
filterOption
|
|
3465
|
-
});
|
|
3466
|
-
}
|
|
3467
3566
|
function FieldRefPathInput(props) {
|
|
3468
3567
|
var _a;
|
|
3469
3568
|
const documentSchema = (_a = react.useContext(SelectedFieldContext)) == null ? void 0 : _a.documentSchema;
|
|
3569
|
+
const typePath = react.useContext(TypePathContext);
|
|
3470
3570
|
const ref = react.useRef(null);
|
|
3471
3571
|
const id = react.useId();
|
|
3472
3572
|
const {
|
|
@@ -3477,20 +3577,29 @@ function FieldRefPathInput(props) {
|
|
|
3477
3577
|
(_b = (_a2 = ref.current) == null ? void 0 : _a2.querySelector("input")) == null ? void 0 : _b.focus();
|
|
3478
3578
|
}, []);
|
|
3479
3579
|
const onSelect = react.useCallback(path => onChange(sanity.set(path)), [onChange]);
|
|
3580
|
+
const filter = react.useCallback(field => {
|
|
3581
|
+
if (!field.key.includes("|") || !typePath) {
|
|
3582
|
+
return true;
|
|
3583
|
+
}
|
|
3584
|
+
const dotSplit = typePath.split(".");
|
|
3585
|
+
const base = dotSplit.slice(0, dotSplit.length - 1).join(".");
|
|
3586
|
+
return field.key.includes(base);
|
|
3587
|
+
}, [typePath]);
|
|
3480
3588
|
if (!documentSchema) {
|
|
3481
3589
|
return props.renderDefault(props);
|
|
3482
3590
|
}
|
|
3483
3591
|
return /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
3484
3592
|
flex: 1,
|
|
3485
3593
|
style: {
|
|
3486
|
-
minWidth:
|
|
3594
|
+
minWidth: 300
|
|
3487
3595
|
},
|
|
3488
3596
|
ref,
|
|
3489
3597
|
children: /* @__PURE__ */jsxRuntime.jsx(FieldAutocomplete, {
|
|
3490
3598
|
id,
|
|
3491
3599
|
schemaType: documentSchema,
|
|
3492
3600
|
onSelect,
|
|
3493
|
-
fieldPath: props.value
|
|
3601
|
+
fieldPath: props.value,
|
|
3602
|
+
filter
|
|
3494
3603
|
})
|
|
3495
3604
|
});
|
|
3496
3605
|
}
|
|
@@ -3693,7 +3802,7 @@ function useOnlyInlineBlocks(props) {
|
|
|
3693
3802
|
function InstructionsArrayField(props) {
|
|
3694
3803
|
return props.renderDefault({
|
|
3695
3804
|
...props,
|
|
3696
|
-
title:
|
|
3805
|
+
title: " "
|
|
3697
3806
|
});
|
|
3698
3807
|
}
|
|
3699
3808
|
const fieldReference = sanity.defineType({
|
|
@@ -4033,7 +4142,7 @@ const fieldInstructions = sanity.defineType({
|
|
|
4033
4142
|
});
|
|
4034
4143
|
const assistDocumentSchema = sanity.defineType({
|
|
4035
4144
|
//NOTE: this is a document type. Using object here ensures it does not appear in structure menus
|
|
4036
|
-
type: "
|
|
4145
|
+
type: "document",
|
|
4037
4146
|
//workaround for using object and not document
|
|
4038
4147
|
...{
|
|
4039
4148
|
liveEdit: true
|
|
@@ -4113,7 +4222,7 @@ const documentInstructionStatus = sanity.defineType({
|
|
|
4113
4222
|
});
|
|
4114
4223
|
const schemaTypes = [fieldInstructions, assistDocumentSchema, prompt, fieldReference, instruction, documentInstructionStatus, instructionTask, contextDocumentSchema, userInput, promptContext];
|
|
4115
4224
|
function useAssistSupported(path, schemaType) {
|
|
4116
|
-
return react.useMemo(() =>
|
|
4225
|
+
return react.useMemo(() => isAssistSupported(schemaType), [schemaType]);
|
|
4117
4226
|
}
|
|
4118
4227
|
function useAssistDocumentContextValue(documentId, documentSchemaType) {
|
|
4119
4228
|
const {
|
|
@@ -4284,7 +4393,6 @@ const assistFieldActions = {
|
|
|
4284
4393
|
const {
|
|
4285
4394
|
schemaType
|
|
4286
4395
|
} = props;
|
|
4287
|
-
const assistSupported = useAssistSupported(props.path, schemaType);
|
|
4288
4396
|
const isDocumentLevel = props.path.length === 0;
|
|
4289
4397
|
const {
|
|
4290
4398
|
assistDocument,
|
|
@@ -4305,9 +4413,13 @@ const assistFieldActions = {
|
|
|
4305
4413
|
useAssistDocumentContextValue(props.documentId, schemaType) :
|
|
4306
4414
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
4307
4415
|
useAssistDocumentContext();
|
|
4416
|
+
const {
|
|
4417
|
+
value: docValue
|
|
4418
|
+
} = desk.useDocumentPane();
|
|
4308
4419
|
const currentUser = sanity.useCurrentUser();
|
|
4309
4420
|
const isHidden = !assistDocument;
|
|
4310
4421
|
const pathKey = usePathKey(props.path);
|
|
4422
|
+
const typePath = useTypePath(docValue, pathKey);
|
|
4311
4423
|
const assistDocumentId = assistDocument == null ? void 0 : assistDocument._id;
|
|
4312
4424
|
const assistableDocId = getAssistableDocId(documentSchemaType, documentId);
|
|
4313
4425
|
const {
|
|
@@ -4316,10 +4428,12 @@ const assistFieldActions = {
|
|
|
4316
4428
|
documentOnChange,
|
|
4317
4429
|
isDocAssistable: documentIsAssistable != null ? documentIsAssistable : false
|
|
4318
4430
|
});
|
|
4431
|
+
const isSelectable = !!useSelectedField(documentSchemaType, typePath);
|
|
4432
|
+
const assistSupported = useAssistSupported(props.path, schemaType) && isSelectable;
|
|
4319
4433
|
const fieldAssist = react.useMemo(() => {
|
|
4320
4434
|
var _a;
|
|
4321
|
-
return ((_a = assistDocument == null ? void 0 : assistDocument.fields) != null ? _a : []).find(f => f.path
|
|
4322
|
-
}, [assistDocument == null ? void 0 : assistDocument.fields, pathKey]);
|
|
4435
|
+
return ((_a = assistDocument == null ? void 0 : assistDocument.fields) != null ? _a : []).find(f => f.path === typePath || pathKey === documentRootKey && f.path === pathKey);
|
|
4436
|
+
}, [assistDocument == null ? void 0 : assistDocument.fields, pathKey, typePath]);
|
|
4323
4437
|
const fieldAssistKey = fieldAssist == null ? void 0 : fieldAssist._key;
|
|
4324
4438
|
const isInspectorOpen = (inspector == null ? void 0 : inspector.name) === aiInspectorId;
|
|
4325
4439
|
const isPathSelected = pathKey === selectedPath;
|
|
@@ -4337,9 +4451,10 @@ const assistFieldActions = {
|
|
|
4337
4451
|
documentId: assistableDocId,
|
|
4338
4452
|
assistDocumentId,
|
|
4339
4453
|
path: pathKey,
|
|
4454
|
+
typePath,
|
|
4340
4455
|
instruction
|
|
4341
4456
|
});
|
|
4342
|
-
}, [requestRunInstruction, assistableDocId, pathKey, assistDocumentId, fieldAssistKey]);
|
|
4457
|
+
}, [requestRunInstruction, assistableDocId, pathKey, typePath, assistDocumentId, fieldAssistKey]);
|
|
4343
4458
|
const privateInstructions = react.useMemo(() => {
|
|
4344
4459
|
var _a;
|
|
4345
4460
|
return ((_a = fieldAssist == null ? void 0 : fieldAssist.instructions) == null ? void 0 : _a.filter(i => i.userId && i.userId === (currentUser == null ? void 0 : currentUser.id))) || [];
|