@sanity/embeddings-index-ui 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -1
- package/dist/index.d.ts +21 -14
- package/dist/index.esm.js +295 -221
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +291 -217
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/isEnabled.tsx +53 -0
- package/src/embeddingsIndexDashboard/EmbeddingsIndexTool.tsx +11 -1
- package/src/embeddingsIndexDashboard/IndexEditor.tsx +8 -6
- package/src/embeddingsIndexDashboard/IndexFormInput.tsx +13 -3
- package/src/embeddingsIndexDashboard/IndexList.tsx +6 -3
- package/src/embeddingsIndexDashboard/QueryIndex.tsx +8 -103
- package/src/referenceInput/SemanticSearchAutocomplete.tsx +205 -0
- package/src/referenceInput/SemanticSearchReferenceInput.tsx +78 -133
- package/src/referenceInput/referencePlugin.tsx +37 -15
- package/src/schemas/typeDefExtensions.ts +21 -13
package/dist/index.js
CHANGED
|
@@ -8,14 +8,61 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
8
8
|
var ui = require('@sanity/ui');
|
|
9
9
|
var icons = require('@sanity/icons');
|
|
10
10
|
var require$$0 = require('react');
|
|
11
|
-
var router = require('sanity/router');
|
|
12
11
|
var desk = require('sanity/desk');
|
|
12
|
+
var router = require('sanity/router');
|
|
13
13
|
function _interopDefaultCompat(e) {
|
|
14
14
|
return e && typeof e === 'object' && 'default' in e ? e : {
|
|
15
15
|
default: e
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
var require$$0__default = /*#__PURE__*/_interopDefaultCompat(require$$0);
|
|
19
|
+
function publicId(id) {
|
|
20
|
+
return id.replace("drafts.", "");
|
|
21
|
+
}
|
|
22
|
+
const featureName = "embeddingsIndexApi";
|
|
23
|
+
const FeatureEnabledContext = require$$0.createContext("loading");
|
|
24
|
+
function useIsFeatureEnabled() {
|
|
25
|
+
const client = sanity.useClient({
|
|
26
|
+
apiVersion: "2023-09-01"
|
|
27
|
+
});
|
|
28
|
+
const [status, setStatus] = require$$0.useState("loading");
|
|
29
|
+
require$$0.useEffect(() => {
|
|
30
|
+
client.request({
|
|
31
|
+
method: "GET",
|
|
32
|
+
url: "/projects/".concat(client.config().projectId, "/features/").concat(featureName)
|
|
33
|
+
}).then(isEnabled => {
|
|
34
|
+
setStatus(isEnabled === "true" || isEnabled === true ? "enabled" : "disabled");
|
|
35
|
+
}).catch(err => {
|
|
36
|
+
console.error(err);
|
|
37
|
+
setStatus("disabled");
|
|
38
|
+
});
|
|
39
|
+
}, [client]);
|
|
40
|
+
return status;
|
|
41
|
+
}
|
|
42
|
+
function FeatureEnabledProvider(props) {
|
|
43
|
+
const status = useIsFeatureEnabled();
|
|
44
|
+
return /* @__PURE__ */jsxRuntime.jsx(FeatureEnabledContext.Provider, {
|
|
45
|
+
value: status,
|
|
46
|
+
children: props.children
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function useIsFeatureEnabledContext() {
|
|
50
|
+
return require$$0.useContext(FeatureEnabledContext);
|
|
51
|
+
}
|
|
52
|
+
function FeatureDisabledNotice() {
|
|
53
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
54
|
+
tone: "primary",
|
|
55
|
+
border: true,
|
|
56
|
+
padding: 2,
|
|
57
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
58
|
+
size: 1,
|
|
59
|
+
children: ["Embeddings index APIs are only available on the", " ", /* @__PURE__ */jsxRuntime.jsx("a", {
|
|
60
|
+
href: "https://sanity.io/pricing",
|
|
61
|
+
children: "Team tier and above"
|
|
62
|
+
}), ". Please upgrade to enable access."]
|
|
63
|
+
})
|
|
64
|
+
});
|
|
65
|
+
}
|
|
19
66
|
|
|
20
67
|
/******************************************************************************
|
|
21
68
|
Copyright (c) Microsoft Corporation.
|
|
@@ -1887,9 +1934,6 @@ function deleteIndex(indexName, client) {
|
|
|
1887
1934
|
url: "/embeddings-index/".concat(dataset, "/").concat(indexName, "?projectId=").concat(projectId)
|
|
1888
1935
|
});
|
|
1889
1936
|
}
|
|
1890
|
-
function publicId(id) {
|
|
1891
|
-
return id.replace("drafts.", "");
|
|
1892
|
-
}
|
|
1893
1937
|
function useApiClient() {
|
|
1894
1938
|
const client = sanity.useClient({
|
|
1895
1939
|
apiVersion: "vX"
|
|
@@ -1906,59 +1950,20 @@ function useApiClient() {
|
|
|
1906
1950
|
return client;
|
|
1907
1951
|
}, [client]);
|
|
1908
1952
|
}
|
|
1953
|
+
const NO_RESULTS_VALUE = "";
|
|
1909
1954
|
const NO_OPTIONS = [];
|
|
1910
1955
|
const NO_FILTER = () => true;
|
|
1911
|
-
function
|
|
1912
|
-
var _a, _b, _c;
|
|
1913
|
-
const defaultEnabled = ((_c = (_b = (_a = props.schemaType) == null ? void 0 : _a.options) == null ? void 0 : _b.embeddingsIndex) == null ? void 0 : _c.searchMode) === "embeddings";
|
|
1914
|
-
const [semantic, setSemantic] = require$$0.useState(defaultEnabled);
|
|
1915
|
-
const toggleSemantic = require$$0.useCallback(() => setSemantic(current => !current), []);
|
|
1916
|
-
return /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
1917
|
-
gap: 2,
|
|
1918
|
-
flex: 1,
|
|
1919
|
-
style: {
|
|
1920
|
-
width: "100%"
|
|
1921
|
-
},
|
|
1922
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
1923
|
-
flex: 1,
|
|
1924
|
-
style: {
|
|
1925
|
-
maxHeight: 36,
|
|
1926
|
-
overflow: "hidden"
|
|
1927
|
-
},
|
|
1928
|
-
children: semantic ? /* @__PURE__ */jsxRuntime.jsx(SemanticSearchInput, {
|
|
1929
|
-
...props
|
|
1930
|
-
}) : props.renderDefault(props)
|
|
1931
|
-
}), /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
1932
|
-
icon: semantic ? icons.EarthGlobeIcon : icons.LinkIcon,
|
|
1933
|
-
onClick: toggleSemantic,
|
|
1934
|
-
mode: "bleed",
|
|
1935
|
-
title: semantic ? "Switch to standard reference search" : "Switch to semantic reference search"
|
|
1936
|
-
})]
|
|
1937
|
-
});
|
|
1938
|
-
}
|
|
1939
|
-
function useDebouncedValue(value, ms) {
|
|
1940
|
-
const [debouncedValue, setDebouncedValue] = require$$0.useState(value);
|
|
1941
|
-
require$$0.useEffect(() => {
|
|
1942
|
-
const timeoutId = setTimeout(() => {
|
|
1943
|
-
setDebouncedValue(value);
|
|
1944
|
-
}, ms);
|
|
1945
|
-
return () => clearTimeout(timeoutId);
|
|
1946
|
-
}, [value, ms]);
|
|
1947
|
-
return debouncedValue;
|
|
1948
|
-
}
|
|
1949
|
-
function SemanticSearchInput(props) {
|
|
1956
|
+
const SemanticSearchAutocomplete = require$$0.forwardRef(function SemanticSearchAutocomplete2(props, ref) {
|
|
1950
1957
|
const {
|
|
1951
|
-
|
|
1952
|
-
|
|
1958
|
+
indexConfig,
|
|
1959
|
+
filterResult,
|
|
1960
|
+
getEmptySearchValue,
|
|
1953
1961
|
readOnly,
|
|
1954
|
-
|
|
1955
|
-
|
|
1962
|
+
onFocus,
|
|
1963
|
+
onBlur,
|
|
1964
|
+
onChange,
|
|
1965
|
+
typeFilter
|
|
1956
1966
|
} = props;
|
|
1957
|
-
const {
|
|
1958
|
-
value: currentDocument
|
|
1959
|
-
} = desk.useDocumentPane();
|
|
1960
|
-
const docRef = require$$0.useRef(currentDocument);
|
|
1961
|
-
const autocompleteRef = require$$0.useRef(null);
|
|
1962
1967
|
const id = require$$0.useId();
|
|
1963
1968
|
const [query, setQuery] = require$$0.useState("");
|
|
1964
1969
|
const queryRef = require$$0.useRef(query);
|
|
@@ -1967,29 +1972,16 @@ function SemanticSearchInput(props) {
|
|
|
1967
1972
|
const [searching, setSearching] = require$$0.useState(false);
|
|
1968
1973
|
const [options, setOptions] = require$$0.useState(NO_OPTIONS);
|
|
1969
1974
|
const client = useApiClient();
|
|
1970
|
-
require$$0.useEffect(() => {
|
|
1971
|
-
docRef.current = currentDocument;
|
|
1972
|
-
}, [currentDocument]);
|
|
1973
|
-
require$$0.useEffect(() => {
|
|
1974
|
-
var _a;
|
|
1975
|
-
if (value == null ? void 0 : value._ref) {
|
|
1976
|
-
(_a = autocompleteRef.current) == null ? void 0 : _a.focus();
|
|
1977
|
-
}
|
|
1978
|
-
}, []);
|
|
1979
|
-
const handleFocus = require$$0.useCallback(() => onPathFocus(["_ref"]), [onPathFocus]);
|
|
1980
|
-
const handleBlur = require$$0.useCallback(() => onPathFocus([]), [onPathFocus]);
|
|
1981
1975
|
const runIndexQuery = require$$0.useCallback(queryString => {
|
|
1982
|
-
var _a
|
|
1976
|
+
var _a;
|
|
1983
1977
|
setSearching(true);
|
|
1984
|
-
const
|
|
1985
|
-
const
|
|
1986
|
-
const maxResults = (_d = (_c = refSchema.options) == null ? void 0 : _c.embeddingsIndex) == null ? void 0 : _d.maxResults;
|
|
1987
|
-
const typeFilter = refSchema.to.map(ref => ref.name);
|
|
1978
|
+
const indexName = indexConfig == null ? void 0 : indexConfig.indexName;
|
|
1979
|
+
const maxResults = indexConfig == null ? void 0 : indexConfig.maxResults;
|
|
1988
1980
|
if (!indexName) {
|
|
1989
|
-
throw new Error("Reference option embeddingsIndex.indexName is required, but was missing
|
|
1981
|
+
throw new Error("Reference option embeddingsIndex.indexName is required, but was missing");
|
|
1990
1982
|
}
|
|
1991
1983
|
queryIndex({
|
|
1992
|
-
query: queryString.trim().length ? queryString : (
|
|
1984
|
+
query: queryString.trim().length ? queryString : (_a = getEmptySearchValue()) != null ? _a : "",
|
|
1993
1985
|
indexName,
|
|
1994
1986
|
maxResults,
|
|
1995
1987
|
filter: {
|
|
@@ -1998,10 +1990,18 @@ function SemanticSearchInput(props) {
|
|
|
1998
1990
|
}, client).then(result => {
|
|
1999
1991
|
if (queryRef.current === queryString) {
|
|
2000
1992
|
setSearching(false);
|
|
2001
|
-
setOptions(
|
|
1993
|
+
setOptions([]);
|
|
1994
|
+
const resultOptions = result.filter(hit => filterResult ? filterResult(hit) : true).map(r => sanity.typed({
|
|
2002
1995
|
result: r,
|
|
2003
1996
|
value: r.value.documentId
|
|
2004
|
-
}))
|
|
1997
|
+
}));
|
|
1998
|
+
if (resultOptions.length) {
|
|
1999
|
+
setOptions(resultOptions);
|
|
2000
|
+
} else {
|
|
2001
|
+
setOptions([{
|
|
2002
|
+
value: NO_RESULTS_VALUE
|
|
2003
|
+
}]);
|
|
2004
|
+
}
|
|
2005
2005
|
}
|
|
2006
2006
|
}).catch(e => {
|
|
2007
2007
|
if (queryRef.current === queryString) {
|
|
@@ -2009,23 +2009,13 @@ function SemanticSearchInput(props) {
|
|
|
2009
2009
|
}
|
|
2010
2010
|
throw e;
|
|
2011
2011
|
});
|
|
2012
|
-
}, [client,
|
|
2012
|
+
}, [client, indexConfig, getEmptySearchValue, filterResult, typeFilter]);
|
|
2013
2013
|
require$$0.useEffect(() => {
|
|
2014
2014
|
if (prevDebouncedQuery.current !== debouncedQuery) {
|
|
2015
2015
|
runIndexQuery(debouncedQuery);
|
|
2016
2016
|
}
|
|
2017
2017
|
prevDebouncedQuery.current = debouncedQuery;
|
|
2018
2018
|
}, [debouncedQuery, runIndexQuery]);
|
|
2019
|
-
const handleChange = require$$0.useCallback(nextId => {
|
|
2020
|
-
if (!nextId) {
|
|
2021
|
-
onChange(sanity.unset());
|
|
2022
|
-
onPathFocus([]);
|
|
2023
|
-
return;
|
|
2024
|
-
}
|
|
2025
|
-
const patches = [sanity.setIfMissing({}), sanity.set(schemaType.name, ["_type"]), sanity.set(publicId(nextId), ["_ref"]), sanity.unset(["_weak"]), sanity.unset(["_strengthenOnPublish"])];
|
|
2026
|
-
onChange(patches);
|
|
2027
|
-
onPathFocus([]);
|
|
2028
|
-
}, [onChange, onPathFocus, schemaType.name]);
|
|
2029
2019
|
const openButtonConfig = require$$0.useMemo(() => ({
|
|
2030
2020
|
onClick: () => runIndexQuery(queryRef.current)
|
|
2031
2021
|
}), [runIndexQuery, queryRef]);
|
|
@@ -2034,52 +2024,187 @@ function SemanticSearchInput(props) {
|
|
|
2034
2024
|
queryRef.current = newQuery;
|
|
2035
2025
|
setQuery(newQuery);
|
|
2036
2026
|
}, [setQuery]);
|
|
2027
|
+
const handleChange = require$$0.useCallback(value => {
|
|
2028
|
+
if (value === NO_RESULTS_VALUE) {
|
|
2029
|
+
setOptions(NO_OPTIONS);
|
|
2030
|
+
return;
|
|
2031
|
+
}
|
|
2032
|
+
onChange == null ? void 0 : onChange(value);
|
|
2033
|
+
}, [onChange]);
|
|
2037
2034
|
return /* @__PURE__ */jsxRuntime.jsx(ui.Autocomplete, {
|
|
2038
2035
|
id,
|
|
2039
|
-
ref
|
|
2036
|
+
ref,
|
|
2040
2037
|
"data-testid": "semantic-autocomplete",
|
|
2041
2038
|
placeholder: "Type to search...",
|
|
2042
2039
|
openButton: openButtonConfig,
|
|
2043
|
-
onFocus
|
|
2040
|
+
onFocus,
|
|
2044
2041
|
onChange: handleChange,
|
|
2045
2042
|
loading: searching,
|
|
2046
|
-
onBlur
|
|
2043
|
+
onBlur,
|
|
2047
2044
|
readOnly,
|
|
2048
2045
|
filterOption: NO_FILTER,
|
|
2049
2046
|
onQueryChange: handleQueryChange,
|
|
2050
2047
|
options,
|
|
2051
2048
|
renderOption: AutocompleteOption
|
|
2052
2049
|
});
|
|
2053
|
-
}
|
|
2050
|
+
});
|
|
2054
2051
|
function AutocompleteOption(props) {
|
|
2055
|
-
|
|
2052
|
+
if ("result" in props) {
|
|
2053
|
+
const value = props.result.value;
|
|
2054
|
+
return /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
2055
|
+
mode: "bleed",
|
|
2056
|
+
padding: 1,
|
|
2057
|
+
style: {
|
|
2058
|
+
width: "100%"
|
|
2059
|
+
},
|
|
2060
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
2061
|
+
gap: 2,
|
|
2062
|
+
align: "center",
|
|
2063
|
+
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2064
|
+
flex: 1,
|
|
2065
|
+
children: /* @__PURE__ */jsxRuntime.jsx(DocumentPreview, {
|
|
2066
|
+
documentId: value.documentId,
|
|
2067
|
+
schemaTypeName: value.type
|
|
2068
|
+
})
|
|
2069
|
+
}), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2070
|
+
padding: 2,
|
|
2071
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
2072
|
+
size: 1,
|
|
2073
|
+
muted: true,
|
|
2074
|
+
title: "Relevance",
|
|
2075
|
+
children: [Math.floor(props.result.score * 100), "%"]
|
|
2076
|
+
})
|
|
2077
|
+
})]
|
|
2078
|
+
})
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2056
2081
|
return /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
2057
2082
|
mode: "bleed",
|
|
2058
2083
|
padding: 1,
|
|
2059
2084
|
style: {
|
|
2060
2085
|
width: "100%"
|
|
2061
2086
|
},
|
|
2062
|
-
|
|
2087
|
+
disabled: true,
|
|
2088
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
|
|
2063
2089
|
gap: 2,
|
|
2064
2090
|
align: "center",
|
|
2065
|
-
children:
|
|
2066
|
-
flex: 1,
|
|
2067
|
-
children: /* @__PURE__ */jsxRuntime.jsx(DocumentPreview, {
|
|
2068
|
-
documentId: value.documentId,
|
|
2069
|
-
schemaTypeName: value.type
|
|
2070
|
-
})
|
|
2071
|
-
}), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2072
|
-
padding: 2,
|
|
2073
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
2074
|
-
size: 1,
|
|
2075
|
-
muted: true,
|
|
2076
|
-
title: "Relevance",
|
|
2077
|
-
children: [Math.floor(props.result.score * 100), "%"]
|
|
2078
|
-
})
|
|
2079
|
-
})]
|
|
2091
|
+
children: "No results."
|
|
2080
2092
|
})
|
|
2081
2093
|
});
|
|
2082
2094
|
}
|
|
2095
|
+
function useDebouncedValue(value, ms) {
|
|
2096
|
+
const [debouncedValue, setDebouncedValue] = require$$0.useState(value);
|
|
2097
|
+
require$$0.useEffect(() => {
|
|
2098
|
+
const timeoutId = setTimeout(() => {
|
|
2099
|
+
setDebouncedValue(value);
|
|
2100
|
+
}, ms);
|
|
2101
|
+
return () => clearTimeout(timeoutId);
|
|
2102
|
+
}, [value, ms]);
|
|
2103
|
+
return debouncedValue;
|
|
2104
|
+
}
|
|
2105
|
+
function useEmeddingsConfig(embeddingsIndexConfig, defaultConfig) {
|
|
2106
|
+
return require$$0.useMemo(() => {
|
|
2107
|
+
if (embeddingsIndexConfig === true || !embeddingsIndexConfig) {
|
|
2108
|
+
if (!(defaultConfig == null ? void 0 : defaultConfig.indexName)) {
|
|
2109
|
+
throw new Error("Default embeddingsIndex config is missing. When options.embeddingsIndex: true, embeddingsIndexReferenceInput plugin config is required.");
|
|
2110
|
+
}
|
|
2111
|
+
return defaultConfig;
|
|
2112
|
+
}
|
|
2113
|
+
const finalConfig = {
|
|
2114
|
+
...defaultConfig,
|
|
2115
|
+
...embeddingsIndexConfig
|
|
2116
|
+
};
|
|
2117
|
+
if (!(finalConfig == null ? void 0 : finalConfig.indexName)) {
|
|
2118
|
+
throw new Error("indexName is missing. Either set it in options.embeddingsIndex or configure defaults using plugin config.");
|
|
2119
|
+
}
|
|
2120
|
+
return finalConfig;
|
|
2121
|
+
}, [defaultConfig, embeddingsIndexConfig]);
|
|
2122
|
+
}
|
|
2123
|
+
function SemanticSearchReferenceInput(props) {
|
|
2124
|
+
var _a, _b;
|
|
2125
|
+
const embeddingsIndexConfig = (_b = (_a = props.schemaType) == null ? void 0 : _a.options) == null ? void 0 : _b.embeddingsIndex;
|
|
2126
|
+
const config = useEmeddingsConfig(embeddingsIndexConfig, props.defaultConfig);
|
|
2127
|
+
const defaultEnabled = config.searchMode === "embeddings";
|
|
2128
|
+
const featureState = useIsFeatureEnabledContext();
|
|
2129
|
+
const [semantic, setSemantic] = require$$0.useState(defaultEnabled);
|
|
2130
|
+
const toggleSemantic = require$$0.useCallback(() => setSemantic(current => !current), []);
|
|
2131
|
+
return /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
2132
|
+
gap: 2,
|
|
2133
|
+
flex: 1,
|
|
2134
|
+
style: {
|
|
2135
|
+
width: "100%"
|
|
2136
|
+
},
|
|
2137
|
+
children: [semantic && featureState == "loading" ? /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2138
|
+
padding: 2,
|
|
2139
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {})
|
|
2140
|
+
}) : null, semantic && featureState == "disabled" ? /* @__PURE__ */jsxRuntime.jsx(FeatureDisabledNotice, {}) : null, /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2141
|
+
flex: 1,
|
|
2142
|
+
style: {
|
|
2143
|
+
maxHeight: 36,
|
|
2144
|
+
overflow: "hidden"
|
|
2145
|
+
},
|
|
2146
|
+
children: semantic && featureState == "enabled" ? /* @__PURE__ */jsxRuntime.jsx(SemanticSearchInput, {
|
|
2147
|
+
...props,
|
|
2148
|
+
indexConfig: config
|
|
2149
|
+
}) : props.renderDefault(props)
|
|
2150
|
+
}), /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
2151
|
+
icon: semantic ? icons.EarthGlobeIcon : icons.LinkIcon,
|
|
2152
|
+
onClick: toggleSemantic,
|
|
2153
|
+
mode: "bleed",
|
|
2154
|
+
title: semantic ? "Switch to standard reference search" : "Switch to semantic reference search"
|
|
2155
|
+
})]
|
|
2156
|
+
});
|
|
2157
|
+
}
|
|
2158
|
+
function SemanticSearchInput(props) {
|
|
2159
|
+
const {
|
|
2160
|
+
indexConfig,
|
|
2161
|
+
onPathFocus,
|
|
2162
|
+
onChange,
|
|
2163
|
+
readOnly,
|
|
2164
|
+
schemaType,
|
|
2165
|
+
value
|
|
2166
|
+
} = props;
|
|
2167
|
+
const {
|
|
2168
|
+
value: currentDocument
|
|
2169
|
+
} = desk.useDocumentPane();
|
|
2170
|
+
const docRef = require$$0.useRef(currentDocument);
|
|
2171
|
+
const autocompleteRef = require$$0.useRef(null);
|
|
2172
|
+
require$$0.useEffect(() => {
|
|
2173
|
+
docRef.current = currentDocument;
|
|
2174
|
+
}, [currentDocument]);
|
|
2175
|
+
require$$0.useEffect(() => {
|
|
2176
|
+
var _a;
|
|
2177
|
+
if (value == null ? void 0 : value._ref) {
|
|
2178
|
+
(_a = autocompleteRef.current) == null ? void 0 : _a.focus();
|
|
2179
|
+
}
|
|
2180
|
+
}, []);
|
|
2181
|
+
const handleFocus = require$$0.useCallback(() => onPathFocus(["_ref"]), [onPathFocus]);
|
|
2182
|
+
const handleBlur = require$$0.useCallback(() => onPathFocus([]), [onPathFocus]);
|
|
2183
|
+
const handleChange = require$$0.useCallback(nextId => {
|
|
2184
|
+
if (!nextId) {
|
|
2185
|
+
onChange(sanity.unset());
|
|
2186
|
+
onPathFocus([]);
|
|
2187
|
+
return;
|
|
2188
|
+
}
|
|
2189
|
+
const patches = [sanity.setIfMissing({}), sanity.set(schemaType.name, ["_type"]), sanity.set(publicId(nextId), ["_ref"]), sanity.unset(["_weak"]), sanity.unset(["_strengthenOnPublish"])];
|
|
2190
|
+
onChange(patches);
|
|
2191
|
+
onPathFocus([]);
|
|
2192
|
+
}, [onChange, onPathFocus, schemaType.name]);
|
|
2193
|
+
const filterResult = require$$0.useCallback(r => r.value.documentId !== publicId(docRef.current._id), [docRef]);
|
|
2194
|
+
const getEmptySearchValue = require$$0.useCallback(() => JSON.stringify(docRef.current), [docRef]);
|
|
2195
|
+
const typeFilter = require$$0.useMemo(() => schemaType.to.map(refType => refType.name), [schemaType]);
|
|
2196
|
+
return /* @__PURE__ */jsxRuntime.jsx(SemanticSearchAutocomplete, {
|
|
2197
|
+
ref: autocompleteRef,
|
|
2198
|
+
typeFilter,
|
|
2199
|
+
indexConfig,
|
|
2200
|
+
onChange: handleChange,
|
|
2201
|
+
onFocus: handleFocus,
|
|
2202
|
+
onBlur: handleBlur,
|
|
2203
|
+
getEmptySearchValue,
|
|
2204
|
+
filterResult,
|
|
2205
|
+
readOnly
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
2083
2208
|
function isType(schemaType, typeName) {
|
|
2084
2209
|
if (schemaType.name === typeName) {
|
|
2085
2210
|
return true;
|
|
@@ -2089,21 +2214,35 @@ function isType(schemaType, typeName) {
|
|
|
2089
2214
|
}
|
|
2090
2215
|
return isType(schemaType.type, typeName);
|
|
2091
2216
|
}
|
|
2092
|
-
const embeddingsIndexReferenceInput = sanity.definePlugin({
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
return /* @__PURE__ */jsxRuntime.jsx(
|
|
2100
|
-
|
|
2217
|
+
const embeddingsIndexReferenceInput = sanity.definePlugin(defaultConfig => {
|
|
2218
|
+
const config = typeof defaultConfig === "object" ? defaultConfig : void 0;
|
|
2219
|
+
return {
|
|
2220
|
+
name: "@sanity/embeddings-index-reference-input",
|
|
2221
|
+
studio: {
|
|
2222
|
+
components: {
|
|
2223
|
+
layout: props => {
|
|
2224
|
+
return /* @__PURE__ */jsxRuntime.jsx(FeatureEnabledProvider, {
|
|
2225
|
+
children: props.renderDefault(props)
|
|
2101
2226
|
});
|
|
2102
2227
|
}
|
|
2103
|
-
|
|
2228
|
+
}
|
|
2229
|
+
},
|
|
2230
|
+
form: {
|
|
2231
|
+
components: {
|
|
2232
|
+
input: props => {
|
|
2233
|
+
var _a, _b;
|
|
2234
|
+
const embeddingsIndexConfig = (_b = (_a = props.schemaType) == null ? void 0 : _a.options) == null ? void 0 : _b.embeddingsIndex;
|
|
2235
|
+
if (sanity.isObjectInputProps(props) && isType(props.schemaType, "reference") && (embeddingsIndexConfig === true || (embeddingsIndexConfig == null ? void 0 : embeddingsIndexConfig.indexName))) {
|
|
2236
|
+
return /* @__PURE__ */jsxRuntime.jsx(SemanticSearchReferenceInput, {
|
|
2237
|
+
...props,
|
|
2238
|
+
defaultConfig: config
|
|
2239
|
+
});
|
|
2240
|
+
}
|
|
2241
|
+
return props.renderDefault(props);
|
|
2242
|
+
}
|
|
2104
2243
|
}
|
|
2105
2244
|
}
|
|
2106
|
-
}
|
|
2245
|
+
};
|
|
2107
2246
|
});
|
|
2108
2247
|
const defaultProjection = "{...}";
|
|
2109
2248
|
function useDefaultIndex(schema, dataset) {
|
|
@@ -2118,6 +2257,7 @@ function IndexFormInput(props) {
|
|
|
2118
2257
|
var _a;
|
|
2119
2258
|
const {
|
|
2120
2259
|
label,
|
|
2260
|
+
description,
|
|
2121
2261
|
index,
|
|
2122
2262
|
prop,
|
|
2123
2263
|
onChange,
|
|
@@ -2131,6 +2271,7 @@ function IndexFormInput(props) {
|
|
|
2131
2271
|
})), [onChange, prop]);
|
|
2132
2272
|
return /* @__PURE__ */jsxRuntime.jsx(FormInput, {
|
|
2133
2273
|
label,
|
|
2274
|
+
description,
|
|
2134
2275
|
onChange: handleChange,
|
|
2135
2276
|
value: (_a = index[prop]) != null ? _a : "",
|
|
2136
2277
|
readOnly,
|
|
@@ -2141,6 +2282,7 @@ function IndexFormInput(props) {
|
|
|
2141
2282
|
function FormInput(props) {
|
|
2142
2283
|
const {
|
|
2143
2284
|
label,
|
|
2285
|
+
description,
|
|
2144
2286
|
onChange,
|
|
2145
2287
|
value,
|
|
2146
2288
|
readOnly,
|
|
@@ -2158,6 +2300,12 @@ function FormInput(props) {
|
|
|
2158
2300
|
htmlFor: id,
|
|
2159
2301
|
children: label
|
|
2160
2302
|
})
|
|
2303
|
+
}), description && /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2304
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
|
|
2305
|
+
size: 1,
|
|
2306
|
+
muted: true,
|
|
2307
|
+
children: description
|
|
2308
|
+
})
|
|
2161
2309
|
}), type === "text" ? /* @__PURE__ */jsxRuntime.jsx(ui.TextInput, {
|
|
2162
2310
|
id,
|
|
2163
2311
|
value,
|
|
@@ -2312,18 +2460,20 @@ function IndexEditor(props) {
|
|
|
2312
2460
|
onChange: setIndex,
|
|
2313
2461
|
readOnly: true
|
|
2314
2462
|
}), /* @__PURE__ */jsxRuntime.jsx(IndexFormInput, {
|
|
2315
|
-
label: "
|
|
2316
|
-
|
|
2463
|
+
label: "Filter",
|
|
2464
|
+
description: "Must be a valid GROQ filter",
|
|
2465
|
+
placeholder: defaultIndex.filter,
|
|
2317
2466
|
index,
|
|
2318
|
-
prop: "
|
|
2467
|
+
prop: "filter",
|
|
2319
2468
|
onChange: setIndex,
|
|
2320
2469
|
readOnly,
|
|
2321
2470
|
type: "textarea"
|
|
2322
2471
|
}), /* @__PURE__ */jsxRuntime.jsx(IndexFormInput, {
|
|
2323
|
-
label: "
|
|
2324
|
-
|
|
2472
|
+
label: "Projection",
|
|
2473
|
+
description: "Must be a valid GROQ projection, starting { and ending with }",
|
|
2474
|
+
placeholder: defaultIndex.projection,
|
|
2325
2475
|
index,
|
|
2326
|
-
prop: "
|
|
2476
|
+
prop: "projection",
|
|
2327
2477
|
onChange: setIndex,
|
|
2328
2478
|
readOnly,
|
|
2329
2479
|
type: "textarea"
|
|
@@ -2360,6 +2510,7 @@ function IndexList(props) {
|
|
|
2360
2510
|
borderBottom: true,
|
|
2361
2511
|
flex: 1,
|
|
2362
2512
|
paddingBottom: 2,
|
|
2513
|
+
padding: 3,
|
|
2363
2514
|
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
2364
2515
|
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2365
2516
|
flex: 1,
|
|
@@ -2414,12 +2565,15 @@ function IndexRow(props) {
|
|
|
2414
2565
|
const onSelect = require$$0.useCallback(() => onIndexSelected(index), [onIndexSelected, index]);
|
|
2415
2566
|
return /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
|
|
2416
2567
|
tone: (selectedIndex == null ? void 0 : selectedIndex.indexName) === index.indexName ? "primary" : "default",
|
|
2417
|
-
mode: (selectedIndex == null ? void 0 : selectedIndex.indexName) === index.indexName ? "default" : "
|
|
2568
|
+
mode: (selectedIndex == null ? void 0 : selectedIndex.indexName) === index.indexName ? "default" : "ghost",
|
|
2418
2569
|
onClick: onSelect,
|
|
2570
|
+
padding: 3,
|
|
2419
2571
|
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
2420
2572
|
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2421
2573
|
flex: 1,
|
|
2422
|
-
children:
|
|
2574
|
+
children: /* @__PURE__ */jsxRuntime.jsx("strong", {
|
|
2575
|
+
children: index.indexName
|
|
2576
|
+
})
|
|
2423
2577
|
}), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2424
2578
|
flex: 1,
|
|
2425
2579
|
children: index.dataset
|
|
@@ -2433,102 +2587,18 @@ function IndexRow(props) {
|
|
|
2433
2587
|
})
|
|
2434
2588
|
}, index.indexName);
|
|
2435
2589
|
}
|
|
2436
|
-
const NO_RESULTS = [];
|
|
2437
2590
|
function QueryIndex(props) {
|
|
2438
2591
|
const {
|
|
2439
2592
|
indexName
|
|
2440
2593
|
} = props;
|
|
2441
|
-
const
|
|
2442
|
-
const
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
indexName,
|
|
2450
|
-
maxResults: 5
|
|
2451
|
-
}, client).then(setResults).finally(() => setSearching(false));
|
|
2452
|
-
}, [client, indexName]);
|
|
2453
|
-
const onInputChange = require$$0.useCallback(e => {
|
|
2454
|
-
setQuery(e.currentTarget.value);
|
|
2455
|
-
}, []);
|
|
2456
|
-
const onKeyDown = require$$0.useCallback(e => {
|
|
2457
|
-
if (e.key === "Enter") {
|
|
2458
|
-
search(query).catch(console.error);
|
|
2459
|
-
}
|
|
2460
|
-
}, [search, query]);
|
|
2461
|
-
return /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
2462
|
-
space: 3,
|
|
2463
|
-
flex: 1,
|
|
2464
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
|
|
2465
|
-
flex: 1,
|
|
2466
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
2467
|
-
flex: 1,
|
|
2468
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.TextInput, {
|
|
2469
|
-
iconRight: searching ? /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2470
|
-
style: {
|
|
2471
|
-
marginTop: 5
|
|
2472
|
-
},
|
|
2473
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {})
|
|
2474
|
-
}) : icons.SearchIcon,
|
|
2475
|
-
placeholder: "Find documents",
|
|
2476
|
-
value: query,
|
|
2477
|
-
disabled: searching,
|
|
2478
|
-
onChange: onInputChange,
|
|
2479
|
-
onKeyDown
|
|
2480
|
-
})
|
|
2481
|
-
})
|
|
2482
|
-
}), /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
|
|
2483
|
-
gap: 4,
|
|
2484
|
-
style: {
|
|
2485
|
-
opacity: searching ? 0.5 : 1
|
|
2486
|
-
},
|
|
2487
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2488
|
-
flex: 1,
|
|
2489
|
-
children: /* @__PURE__ */jsxRuntime.jsx(ResultList, {
|
|
2490
|
-
results,
|
|
2491
|
-
query
|
|
2492
|
-
})
|
|
2493
|
-
})
|
|
2494
|
-
})]
|
|
2495
|
-
});
|
|
2496
|
-
}
|
|
2497
|
-
function ResultList(props) {
|
|
2498
|
-
const {
|
|
2499
|
-
results,
|
|
2500
|
-
query
|
|
2501
|
-
} = props;
|
|
2502
|
-
return /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
|
|
2503
|
-
space: 4,
|
|
2504
|
-
height: "fill",
|
|
2505
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
|
|
2506
|
-
space: 2,
|
|
2507
|
-
children: [results.map(r => /* @__PURE__ */jsxRuntime.jsx(ResultEntry, {
|
|
2508
|
-
result: r
|
|
2509
|
-
}, r.value.documentId)), !results.length && query ? "No results." : null]
|
|
2510
|
-
})
|
|
2511
|
-
});
|
|
2512
|
-
}
|
|
2513
|
-
function ResultEntry(props) {
|
|
2514
|
-
const value = props.result.value;
|
|
2515
|
-
return /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
|
|
2516
|
-
gap: 4,
|
|
2517
|
-
align: "center",
|
|
2518
|
-
children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2519
|
-
flex: 1,
|
|
2520
|
-
children: /* @__PURE__ */jsxRuntime.jsx(DocumentPreview, {
|
|
2521
|
-
documentId: value.documentId,
|
|
2522
|
-
schemaTypeName: value.type,
|
|
2523
|
-
button: true
|
|
2524
|
-
})
|
|
2525
|
-
}), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2526
|
-
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
|
|
2527
|
-
muted: true,
|
|
2528
|
-
size: 1,
|
|
2529
|
-
children: [Math.floor(props.result.score * 100), " %"]
|
|
2530
|
-
})
|
|
2531
|
-
})]
|
|
2594
|
+
const getEmpty = require$$0.useCallback(() => "anything", []);
|
|
2595
|
+
const indexConfig = require$$0.useMemo(() => ({
|
|
2596
|
+
indexName,
|
|
2597
|
+
maxResults: 8
|
|
2598
|
+
}), [indexName]);
|
|
2599
|
+
return /* @__PURE__ */jsxRuntime.jsx(SemanticSearchAutocomplete, {
|
|
2600
|
+
getEmptySearchValue: getEmpty,
|
|
2601
|
+
indexConfig
|
|
2532
2602
|
});
|
|
2533
2603
|
}
|
|
2534
2604
|
function IndexInfo(_ref3) {
|
|
@@ -2660,17 +2730,21 @@ function IndexStatus(_ref4) {
|
|
|
2660
2730
|
});
|
|
2661
2731
|
}
|
|
2662
2732
|
function EmbeddingsIndexTool() {
|
|
2733
|
+
const featureState = useIsFeatureEnabled();
|
|
2663
2734
|
return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
|
|
2664
2735
|
children: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
|
|
2665
2736
|
justify: "center",
|
|
2666
2737
|
flex: 1,
|
|
2667
|
-
children: /* @__PURE__ */jsxRuntime.
|
|
2738
|
+
children: /* @__PURE__ */jsxRuntime.jsxs(ui.Card, {
|
|
2668
2739
|
flex: 1,
|
|
2669
2740
|
style: {
|
|
2670
2741
|
maxWidth: 1200
|
|
2671
2742
|
},
|
|
2672
2743
|
padding: 5,
|
|
2673
|
-
children: /* @__PURE__ */jsxRuntime.jsx(
|
|
2744
|
+
children: [featureState == "loading" ? /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
|
|
2745
|
+
padding: 2,
|
|
2746
|
+
children: /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {})
|
|
2747
|
+
}) : null, featureState == "disabled" ? /* @__PURE__ */jsxRuntime.jsx(FeatureDisabledNotice, {}) : null, featureState == "enabled" ? /* @__PURE__ */jsxRuntime.jsx(Indexes, {}) : null]
|
|
2674
2748
|
})
|
|
2675
2749
|
})
|
|
2676
2750
|
});
|