@dxos/plugin-search 0.7.4-staging.f7e8224 → 0.7.5-labs.071a3e2
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/lib/browser/app-graph-builder-4C2ZPCED.mjs +41 -0
- package/dist/lib/browser/app-graph-builder-4C2ZPCED.mjs.map +7 -0
- package/dist/lib/browser/{chunk-4L4PWJYC.mjs → chunk-B532NWHM.mjs} +3 -3
- package/dist/lib/browser/chunk-B532NWHM.mjs.map +7 -0
- package/dist/lib/browser/chunk-GGOOQO2C.mjs +133 -0
- package/dist/lib/browser/chunk-GGOOQO2C.mjs.map +7 -0
- package/dist/lib/browser/chunk-Z745WIBH.mjs +21 -0
- package/dist/lib/browser/chunk-Z745WIBH.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +61 -577
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/intent-resolver-MKBD2LPH.mjs +22 -0
- package/dist/lib/browser/intent-resolver-MKBD2LPH.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/react-surface-H2PAVIXZ.mjs +357 -0
- package/dist/lib/browser/react-surface-H2PAVIXZ.mjs.map +7 -0
- package/dist/types/src/SearchPlugin.d.ts +1 -3
- package/dist/types/src/SearchPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +181 -0
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +180 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface.d.ts +4 -0
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
- package/dist/types/src/components/SearchDialog.d.ts +5 -8
- package/dist/types/src/components/SearchDialog.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +1 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +11 -4
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +20 -27
- package/src/SearchPlugin.tsx +35 -101
- package/src/capabilities/app-graph-builder.ts +36 -0
- package/src/capabilities/index.ts +9 -0
- package/src/capabilities/intent-resolver.ts +18 -0
- package/src/capabilities/react-surface.tsx +39 -0
- package/src/components/SearchDialog.tsx +28 -44
- package/src/index.ts +1 -4
- package/src/meta.ts +1 -1
- package/src/search-sync.ts +1 -1
- package/src/search.ts +1 -1
- package/src/types.tsx +7 -16
- package/dist/lib/browser/chunk-4L4PWJYC.mjs.map +0 -7
- package/dist/lib/browser/meta.mjs +0 -11
- package/dist/lib/browser/meta.mjs.map +0 -7
|
@@ -1,476 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SearchContextProvider,
|
|
3
|
+
filterObjectsSync,
|
|
4
|
+
mapObjectToTextFields,
|
|
5
|
+
queryStringToMatch,
|
|
6
|
+
useGlobalFilteredObjects,
|
|
7
|
+
useGlobalSearch,
|
|
8
|
+
useGlobalSearchResults
|
|
9
|
+
} from "./chunk-GGOOQO2C.mjs";
|
|
1
10
|
import {
|
|
2
11
|
SEARCH_PLUGIN,
|
|
3
12
|
SEARCH_RESULT,
|
|
4
|
-
|
|
5
|
-
} from "./chunk-
|
|
13
|
+
meta
|
|
14
|
+
} from "./chunk-B532NWHM.mjs";
|
|
6
15
|
|
|
7
16
|
// packages/plugins/experimental/plugin-search/src/SearchPlugin.tsx
|
|
8
|
-
import
|
|
9
|
-
import { resolvePlugin, parseIntentPlugin, parseGraphPlugin as parseGraphPlugin2, parseNavigationPlugin as parseNavigationPlugin2, LayoutAction as LayoutAction2, firstIdInPart } from "@dxos/app-framework";
|
|
10
|
-
import { createExtension } from "@dxos/plugin-graph";
|
|
11
|
-
import { getActiveSpace } from "@dxos/plugin-space";
|
|
12
|
-
|
|
13
|
-
// packages/plugins/experimental/plugin-search/src/components/Searchbar/Searchbar.tsx
|
|
14
|
-
import { MagnifyingGlass } from "@phosphor-icons/react";
|
|
15
|
-
import React, { useEffect, useRef, useState } from "react";
|
|
16
|
-
import { Input } from "@dxos/react-ui";
|
|
17
|
-
import { getSize, mx } from "@dxos/react-ui-theme";
|
|
18
|
-
var Searchbar = ({ classes, variant, placeholder, value, onChange }) => {
|
|
19
|
-
const inputRef = useRef(null);
|
|
20
|
-
const [text, setText] = useState(value);
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
setText(value);
|
|
23
|
-
}, [
|
|
24
|
-
value
|
|
25
|
-
]);
|
|
26
|
-
const handleChange = (text2) => {
|
|
27
|
-
setText(text2);
|
|
28
|
-
onChange?.(text2);
|
|
29
|
-
};
|
|
30
|
-
const handleReset = () => {
|
|
31
|
-
handleChange(void 0);
|
|
32
|
-
inputRef.current?.focus();
|
|
33
|
-
};
|
|
34
|
-
return /* @__PURE__ */ React.createElement("div", {
|
|
35
|
-
className: "flex w-full items-center pli-1 pbs-1"
|
|
36
|
-
}, /* @__PURE__ */ React.createElement(Input.Root, null, /* @__PURE__ */ React.createElement(Input.TextInput, {
|
|
37
|
-
ref: inputRef,
|
|
38
|
-
placeholder,
|
|
39
|
-
variant,
|
|
40
|
-
value: text ?? "",
|
|
41
|
-
classNames: mx("pl-3 pr-10", classes?.input),
|
|
42
|
-
onChange: ({ target }) => handleChange(target.value),
|
|
43
|
-
onKeyDown: ({ key }) => key === "Escape" && handleReset()
|
|
44
|
-
}), /* @__PURE__ */ React.createElement("div", {
|
|
45
|
-
role: "button",
|
|
46
|
-
className: "-ml-7 p-0 cursor-pointer",
|
|
47
|
-
onClick: handleReset
|
|
48
|
-
}, /* @__PURE__ */ React.createElement(MagnifyingGlass, {
|
|
49
|
-
className: getSize(5)
|
|
50
|
-
}))));
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// packages/plugins/experimental/plugin-search/src/components/SearchMain.tsx
|
|
54
|
-
import React4, { useState as useState3 } from "react";
|
|
55
|
-
import { useClient } from "@dxos/react-client";
|
|
56
|
-
import { Filter, useQuery } from "@dxos/react-client/echo";
|
|
57
|
-
import { useTranslation } from "@dxos/react-ui";
|
|
58
|
-
import { groupSurface, mx as mx3 } from "@dxos/react-ui-theme";
|
|
59
|
-
|
|
60
|
-
// packages/plugins/experimental/plugin-search/src/components/SearchResults/SearchResults.tsx
|
|
61
|
-
import { Buildings, Folders, User } from "@phosphor-icons/react";
|
|
62
|
-
import React2, { forwardRef } from "react";
|
|
63
|
-
import { ScrollArea } from "@dxos/react-ui";
|
|
64
|
-
import { Card } from "@dxos/react-ui-card";
|
|
65
|
-
import { Mosaic } from "@dxos/react-ui-mosaic";
|
|
66
|
-
import { ghostHover, mx as mx2 } from "@dxos/react-ui-theme";
|
|
67
|
-
var styles = {
|
|
68
|
-
selected: "!bg-primary-100 !dark:bg-primary-900"
|
|
69
|
-
};
|
|
70
|
-
var getIcon = (type) => {
|
|
71
|
-
const iconMap = {
|
|
72
|
-
user: User,
|
|
73
|
-
organization: Buildings,
|
|
74
|
-
project: Folders
|
|
75
|
-
};
|
|
76
|
-
return iconMap[type];
|
|
77
|
-
};
|
|
78
|
-
var Snippet = ({ text, match }) => {
|
|
79
|
-
let content = /* @__PURE__ */ React2.createElement(React2.Fragment, null, text);
|
|
80
|
-
if (match) {
|
|
81
|
-
const result = text.match(match);
|
|
82
|
-
if (result?.index !== void 0) {
|
|
83
|
-
const maxOffset = 16;
|
|
84
|
-
let before = text.slice(0, result.index);
|
|
85
|
-
if (before.length > maxOffset) {
|
|
86
|
-
const idx = before.indexOf(" ", result.index - maxOffset);
|
|
87
|
-
before = "\u2026 " + before.slice(idx);
|
|
88
|
-
}
|
|
89
|
-
const after = text.slice(result.index + result[0].length);
|
|
90
|
-
content = /* @__PURE__ */ React2.createElement(React2.Fragment, null, before, /* @__PURE__ */ React2.createElement("span", {
|
|
91
|
-
className: "text-blue-500"
|
|
92
|
-
}, result[0]), after);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return /* @__PURE__ */ React2.createElement("span", {
|
|
96
|
-
className: "text-xs mb-1 line-clamp-3 text-neutral-300"
|
|
97
|
-
}, content);
|
|
98
|
-
};
|
|
99
|
-
var SearchItem = /* @__PURE__ */ forwardRef(({ draggableStyle, draggableProps, item, debug = false }, forwardRef3) => {
|
|
100
|
-
const { id, type, label, snippet, match, selected, onSelect } = item;
|
|
101
|
-
const Icon2 = type ? getIcon(type) : void 0;
|
|
102
|
-
return /* @__PURE__ */ React2.createElement(Card.Root, {
|
|
103
|
-
ref: forwardRef3,
|
|
104
|
-
style: draggableStyle,
|
|
105
|
-
classNames: mx2("mx-2 mt-2 cursor-pointer", ghostHover, selected && styles.selected),
|
|
106
|
-
onClick: () => onSelect?.(id)
|
|
107
|
-
}, /* @__PURE__ */ React2.createElement(Card.Header, null, /* @__PURE__ */ React2.createElement(Card.DragHandle, draggableProps), /* @__PURE__ */ React2.createElement(Card.Title, {
|
|
108
|
-
title: label ?? "Untitled"
|
|
109
|
-
}), Icon2 && /* @__PURE__ */ React2.createElement(Card.Endcap, {
|
|
110
|
-
Icon: Icon2
|
|
111
|
-
})), snippet && /* @__PURE__ */ React2.createElement(Card.Body, {
|
|
112
|
-
gutter: true
|
|
113
|
-
}, /* @__PURE__ */ React2.createElement(Snippet, {
|
|
114
|
-
text: snippet,
|
|
115
|
-
match
|
|
116
|
-
})), debug && /* @__PURE__ */ React2.createElement(Card.Body, {
|
|
117
|
-
gutter: true
|
|
118
|
-
}, /* @__PURE__ */ React2.createElement("pre", {
|
|
119
|
-
className: "text-xs whitespace-pre-line"
|
|
120
|
-
}, JSON.stringify(item))));
|
|
121
|
-
});
|
|
122
|
-
var SearchResults = ({ items, selected, onSelect }) => {
|
|
123
|
-
const path = "search";
|
|
124
|
-
return /* @__PURE__ */ React2.createElement(ScrollArea.Root, {
|
|
125
|
-
classNames: "grow"
|
|
126
|
-
}, /* @__PURE__ */ React2.createElement(ScrollArea.Viewport, null, /* @__PURE__ */ React2.createElement(Mosaic.Container, {
|
|
127
|
-
id: path,
|
|
128
|
-
Component: SearchItem
|
|
129
|
-
}, items.map((item) => /* @__PURE__ */ React2.createElement(Mosaic.DraggableTile, {
|
|
130
|
-
key: item.id,
|
|
131
|
-
path,
|
|
132
|
-
type: SEARCH_RESULT,
|
|
133
|
-
item: {
|
|
134
|
-
...item,
|
|
135
|
-
selected: selected === item.id,
|
|
136
|
-
onSelect
|
|
137
|
-
},
|
|
138
|
-
Component: SearchItem
|
|
139
|
-
})))), /* @__PURE__ */ React2.createElement(ScrollArea.Scrollbar, {
|
|
140
|
-
orientation: "vertical"
|
|
141
|
-
}, /* @__PURE__ */ React2.createElement(ScrollArea.Thumb, null)), /* @__PURE__ */ React2.createElement(ScrollArea.Corner, null));
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
// packages/plugins/experimental/plugin-search/src/context.tsx
|
|
145
|
-
import React3, { createContext, useContext, useMemo, useState as useState2 } from "react";
|
|
146
|
-
import { raise } from "@dxos/debug";
|
|
147
|
-
|
|
148
|
-
// packages/plugins/experimental/plugin-search/src/search-sync.ts
|
|
149
|
-
import { AST } from "@dxos/echo-schema";
|
|
150
|
-
import { getSchema } from "@dxos/live-object";
|
|
151
|
-
import { TextType } from "@dxos/plugin-markdown/types";
|
|
152
|
-
var queryStringToMatch = (queryString) => {
|
|
153
|
-
const trimmed = queryString?.trim();
|
|
154
|
-
return trimmed ? new RegExp(trimmed, "i") : void 0;
|
|
155
|
-
};
|
|
156
|
-
var getIcon2 = (schema) => {
|
|
157
|
-
if (!(schema && AST.isTypeLiteral(schema.ast))) {
|
|
158
|
-
return void 0;
|
|
159
|
-
}
|
|
160
|
-
const keys = schema.ast.propertySignatures.map((p) => p.name);
|
|
161
|
-
if (keys.indexOf("email") !== -1) {
|
|
162
|
-
return "user";
|
|
163
|
-
}
|
|
164
|
-
if (keys.indexOf("website") !== -1) {
|
|
165
|
-
return "organization";
|
|
166
|
-
}
|
|
167
|
-
if (keys.indexOf("repo") !== -1) {
|
|
168
|
-
return "project";
|
|
169
|
-
}
|
|
170
|
-
return void 0;
|
|
171
|
-
};
|
|
172
|
-
var filterObjectsSync = (objects, match) => {
|
|
173
|
-
if (!match) {
|
|
174
|
-
return [];
|
|
175
|
-
}
|
|
176
|
-
return objects.reduce((results, object) => {
|
|
177
|
-
if (object instanceof TextType) {
|
|
178
|
-
return results;
|
|
179
|
-
}
|
|
180
|
-
const fields = mapObjectToTextFields(object);
|
|
181
|
-
Object.entries(fields).some(([, value]) => {
|
|
182
|
-
const result = value.match(match);
|
|
183
|
-
if (result) {
|
|
184
|
-
const label = getStringProperty(object, [
|
|
185
|
-
"label",
|
|
186
|
-
"name",
|
|
187
|
-
"title"
|
|
188
|
-
]);
|
|
189
|
-
results.push({
|
|
190
|
-
id: object.id,
|
|
191
|
-
type: getIcon2(getSchema(object)),
|
|
192
|
-
label,
|
|
193
|
-
match,
|
|
194
|
-
// TODO(burdon): Truncate.
|
|
195
|
-
// TODO(burdon): Issue with sketch documents.
|
|
196
|
-
snippet: value !== label ? value : fields.content ?? fields.description ?? void 0,
|
|
197
|
-
object
|
|
198
|
-
});
|
|
199
|
-
return true;
|
|
200
|
-
}
|
|
201
|
-
return false;
|
|
202
|
-
});
|
|
203
|
-
return results;
|
|
204
|
-
}, []);
|
|
205
|
-
};
|
|
206
|
-
var getStringProperty = (object, keys) => {
|
|
207
|
-
let label;
|
|
208
|
-
keys.some((key) => {
|
|
209
|
-
const value = object[key];
|
|
210
|
-
if (typeof value === "string") {
|
|
211
|
-
label = value;
|
|
212
|
-
return true;
|
|
213
|
-
}
|
|
214
|
-
return false;
|
|
215
|
-
});
|
|
216
|
-
return label;
|
|
217
|
-
};
|
|
218
|
-
var getKeys = (object) => {
|
|
219
|
-
try {
|
|
220
|
-
const obj = JSON.parse(JSON.stringify(object));
|
|
221
|
-
return Object.keys(obj).filter((key) => key !== "id" && key !== "identityKey" && key[0] !== "_" && key[0] !== "@");
|
|
222
|
-
} catch (err) {
|
|
223
|
-
return [];
|
|
224
|
-
}
|
|
225
|
-
};
|
|
226
|
-
var mapObjectToTextFields = (object) => {
|
|
227
|
-
return getKeys(object).reduce((fields, key) => {
|
|
228
|
-
const value = object[key];
|
|
229
|
-
if (typeof value === "string" || value instanceof TextType) {
|
|
230
|
-
try {
|
|
231
|
-
fields[key] = String(value);
|
|
232
|
-
} catch (err) {
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
return fields;
|
|
236
|
-
}, {});
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
// packages/plugins/experimental/plugin-search/src/context.tsx
|
|
240
|
-
var SearchContext = /* @__PURE__ */ createContext({});
|
|
241
|
-
var SearchContextProvider = ({ children }) => {
|
|
242
|
-
const [match, setMatch] = useState2();
|
|
243
|
-
const handleMatch = (text) => setMatch(queryStringToMatch(text));
|
|
244
|
-
return /* @__PURE__ */ React3.createElement(SearchContext.Provider, {
|
|
245
|
-
value: {
|
|
246
|
-
match,
|
|
247
|
-
setMatch: handleMatch
|
|
248
|
-
}
|
|
249
|
-
}, children);
|
|
250
|
-
};
|
|
251
|
-
var useGlobalSearch = () => {
|
|
252
|
-
return useContext(SearchContext) ?? raise(new Error("Missing SearchContext."));
|
|
253
|
-
};
|
|
254
|
-
var useGlobalSearchResults = (objects) => {
|
|
255
|
-
const { match } = useGlobalSearch();
|
|
256
|
-
return objects && match ? filterObjectsSync(objects, match) : [];
|
|
257
|
-
};
|
|
258
|
-
var useGlobalFilteredObjects = (objects) => {
|
|
259
|
-
const { match } = useGlobalSearch();
|
|
260
|
-
if (!match || !objects) {
|
|
261
|
-
return objects ?? [];
|
|
262
|
-
}
|
|
263
|
-
return useMemo(() => filterObjectsSync(objects, match).map((result) => result.object), [
|
|
264
|
-
objects,
|
|
265
|
-
match
|
|
266
|
-
]);
|
|
267
|
-
};
|
|
17
|
+
import { contributes, Events, defineModule, definePlugin, Capabilities } from "@dxos/app-framework";
|
|
268
18
|
|
|
269
|
-
// packages/plugins/experimental/plugin-search/src/
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
const allSpaces = false;
|
|
275
|
-
const objects = useQuery(allSpaces ? client.spaces : space, Filter.all());
|
|
276
|
-
const results = useGlobalSearchResults(objects);
|
|
277
|
-
const [selected, setSelected] = useState3();
|
|
278
|
-
const handleSelect = (id) => {
|
|
279
|
-
setSelected((selected2) => selected2 === id ? void 0 : id);
|
|
280
|
-
};
|
|
281
|
-
return /* @__PURE__ */ React4.createElement("div", {
|
|
282
|
-
className: "flex flex-col grow h-full"
|
|
283
|
-
}, /* @__PURE__ */ React4.createElement(Searchbar, {
|
|
284
|
-
placeholder: t("search placeholder"),
|
|
285
|
-
onChange: setMatch
|
|
286
|
-
}), results.length > 0 && /* @__PURE__ */ React4.createElement("div", {
|
|
287
|
-
className: "absolute top-[--topbar-size] bottom-0 z-[1]"
|
|
288
|
-
}, /* @__PURE__ */ React4.createElement("div", {
|
|
289
|
-
className: mx3("flex flex-col h-full overflow-hidden", groupSurface)
|
|
290
|
-
}, /* @__PURE__ */ React4.createElement(SearchResults, {
|
|
291
|
-
items: results,
|
|
292
|
-
selected,
|
|
293
|
-
onSelect: handleSelect
|
|
294
|
-
}))));
|
|
295
|
-
};
|
|
296
|
-
|
|
297
|
-
// packages/plugins/experimental/plugin-search/src/components/SearchDialog.tsx
|
|
298
|
-
import React5, { forwardRef as forwardRef2, useCallback, useState as useState5 } from "react";
|
|
299
|
-
import { useResolvePlugin, parseNavigationPlugin, parseGraphPlugin, NavigationAction, LayoutAction, isLayoutParts, useIntentDispatcher } from "@dxos/app-framework";
|
|
300
|
-
import { useClient as useClient2 } from "@dxos/react-client";
|
|
301
|
-
import { Filter as Filter2, fullyQualifiedId, useQuery as useQuery2 } from "@dxos/react-client/echo";
|
|
302
|
-
import { Button, Dialog, Icon, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
303
|
-
import { SearchList } from "@dxos/react-ui-searchlist";
|
|
304
|
-
import { descriptionText, mx as mx4 } from "@dxos/react-ui-theme";
|
|
305
|
-
|
|
306
|
-
// packages/plugins/experimental/plugin-search/src/search.ts
|
|
307
|
-
import { yieldOrContinue } from "main-thread-scheduling";
|
|
308
|
-
import { useEffect as useEffect2, useState as useState4 } from "react";
|
|
309
|
-
import { TextType as TextType2 } from "@dxos/plugin-markdown/types";
|
|
310
|
-
var filterObjects = async (objects, match) => {
|
|
311
|
-
const result = /* @__PURE__ */ new Map();
|
|
312
|
-
if (!match) {
|
|
313
|
-
return result;
|
|
314
|
-
}
|
|
315
|
-
await Promise.all(objects.filter((object) => !(object instanceof TextType2)).map(async (object) => {
|
|
316
|
-
await yieldOrContinue("interactive");
|
|
317
|
-
const fields = mapObjectToTextFields(object);
|
|
318
|
-
Object.entries(fields).filter(([_, value]) => value.match(match)).forEach(([key, value]) => {
|
|
319
|
-
if (!result.has(object)) {
|
|
320
|
-
result.set(object, []);
|
|
321
|
-
}
|
|
322
|
-
result.set(object, [
|
|
323
|
-
...result.get(object),
|
|
324
|
-
[
|
|
325
|
-
key,
|
|
326
|
-
value
|
|
327
|
-
]
|
|
328
|
-
]);
|
|
329
|
-
});
|
|
330
|
-
}));
|
|
331
|
-
return result;
|
|
332
|
-
};
|
|
333
|
-
var useSearchResults = (queryString, objects, delay = 400) => {
|
|
334
|
-
const [results, setResults] = useState4(/* @__PURE__ */ new Map());
|
|
335
|
-
const [pending, setPending] = useState4(false);
|
|
336
|
-
useEffect2(() => {
|
|
337
|
-
setPending(!!(objects && queryString));
|
|
338
|
-
const timeoutId = setTimeout(async () => {
|
|
339
|
-
const nextResults = objects && queryString ? await filterObjects(objects, queryStringToMatch(queryString)) : /* @__PURE__ */ new Map();
|
|
340
|
-
setResults(nextResults);
|
|
341
|
-
setPending(false);
|
|
342
|
-
}, delay);
|
|
343
|
-
return () => clearTimeout(timeoutId);
|
|
344
|
-
}, [
|
|
345
|
-
queryString,
|
|
346
|
-
objects
|
|
347
|
-
]);
|
|
348
|
-
return [
|
|
349
|
-
pending,
|
|
350
|
-
results
|
|
351
|
-
];
|
|
352
|
-
};
|
|
353
|
-
|
|
354
|
-
// packages/plugins/experimental/plugin-search/src/components/SearchDialog.tsx
|
|
355
|
-
var SearchListResult = /* @__PURE__ */ forwardRef2(({ node, onSelect }, forwardedRef) => {
|
|
356
|
-
const { t } = useTranslation2(SEARCH_PLUGIN);
|
|
357
|
-
const label = toLocalizedString(node?.properties.label ?? "never", t);
|
|
358
|
-
return /* @__PURE__ */ React5.createElement(SearchList.Item, {
|
|
359
|
-
value: label,
|
|
360
|
-
key: node.id,
|
|
361
|
-
classNames: "flex gap-2 items-center pli-2",
|
|
362
|
-
onSelect: () => onSelect?.(node.id),
|
|
363
|
-
ref: forwardedRef
|
|
364
|
-
}, /* @__PURE__ */ React5.createElement(Icon, {
|
|
365
|
-
size: 5,
|
|
366
|
-
icon: node?.properties.icon
|
|
367
|
-
}), /* @__PURE__ */ React5.createElement("span", {
|
|
368
|
-
className: "is-0 grow truncate"
|
|
369
|
-
}, label));
|
|
370
|
-
});
|
|
371
|
-
var SearchDialog = ({ subject }) => {
|
|
372
|
-
const { t } = useTranslation2(SEARCH_PLUGIN);
|
|
373
|
-
const graphPlugin = useResolvePlugin(parseGraphPlugin);
|
|
374
|
-
const graph = graphPlugin?.provides.graph;
|
|
375
|
-
const navigationPlugin = useResolvePlugin(parseNavigationPlugin);
|
|
376
|
-
const providedClosed = navigationPlugin?.provides.location.closed ?? [];
|
|
377
|
-
const closed = (Array.isArray(providedClosed) ? providedClosed : [
|
|
378
|
-
providedClosed
|
|
379
|
-
]).map((id) => graph?.findNode(id)).filter(Boolean);
|
|
380
|
-
const active = navigationPlugin?.provides.location.active;
|
|
381
|
-
const [queryString, setQueryString] = useState5("");
|
|
382
|
-
const client = useClient2();
|
|
383
|
-
const dangerouslyLoadAllObjects = useQuery2(client.spaces, Filter2.all());
|
|
384
|
-
const [pending, results] = useSearchResults(queryString, dangerouslyLoadAllObjects);
|
|
385
|
-
const resultObjects = Array.from(results.keys());
|
|
386
|
-
const dispatch = useIntentDispatcher();
|
|
387
|
-
const handleSelect = useCallback((nodeId) => {
|
|
388
|
-
if (active && isLayoutParts(active)) {
|
|
389
|
-
const index = active?.main?.findIndex((entry) => entry.id === nodeId);
|
|
390
|
-
if (index !== -1) {
|
|
391
|
-
return dispatch([
|
|
392
|
-
{
|
|
393
|
-
action: LayoutAction.SET_LAYOUT,
|
|
394
|
-
data: {
|
|
395
|
-
element: "dialog",
|
|
396
|
-
state: false
|
|
397
|
-
}
|
|
398
|
-
},
|
|
399
|
-
{
|
|
400
|
-
action: LayoutAction.SCROLL_INTO_VIEW,
|
|
401
|
-
data: {
|
|
402
|
-
id: nodeId
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
]);
|
|
406
|
-
}
|
|
407
|
-
return dispatch([
|
|
408
|
-
{
|
|
409
|
-
action: NavigationAction.ADD_TO_ACTIVE,
|
|
410
|
-
data: {
|
|
411
|
-
part: subject.layoutCoordinate.part,
|
|
412
|
-
id: nodeId,
|
|
413
|
-
pivotId: subject.layoutCoordinate.entryId,
|
|
414
|
-
positioning: "end"
|
|
415
|
-
}
|
|
416
|
-
},
|
|
417
|
-
{
|
|
418
|
-
action: LayoutAction.SET_LAYOUT,
|
|
419
|
-
data: {
|
|
420
|
-
element: "dialog",
|
|
421
|
-
state: false
|
|
422
|
-
}
|
|
423
|
-
},
|
|
424
|
-
{
|
|
425
|
-
action: LayoutAction.SCROLL_INTO_VIEW,
|
|
426
|
-
data: {
|
|
427
|
-
id: nodeId
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
]);
|
|
431
|
-
}
|
|
432
|
-
}, [
|
|
433
|
-
subject,
|
|
434
|
-
dispatch,
|
|
435
|
-
active
|
|
436
|
-
]);
|
|
437
|
-
return /* @__PURE__ */ React5.createElement(Dialog.Content, {
|
|
438
|
-
classNames: [
|
|
439
|
-
"md:max-is-[24rem] overflow-hidden mbs-12"
|
|
440
|
-
]
|
|
441
|
-
}, /* @__PURE__ */ React5.createElement(Dialog.Title, null, t("search dialog title")), /* @__PURE__ */ React5.createElement(SearchList.Root, {
|
|
442
|
-
label: t("search placeholder"),
|
|
443
|
-
classNames: "flex flex-col grow overflow-hidden my-2"
|
|
444
|
-
}, /* @__PURE__ */ React5.createElement(SearchList.Input, {
|
|
445
|
-
value: queryString,
|
|
446
|
-
onValueChange: (nextValue) => {
|
|
447
|
-
setQueryString(nextValue);
|
|
448
|
-
},
|
|
449
|
-
placeholder: t("search placeholder"),
|
|
450
|
-
classNames: "px-1 my-2"
|
|
451
|
-
}), /* @__PURE__ */ React5.createElement(SearchList.Content, {
|
|
452
|
-
classNames: "max-bs-[24rem] overflow-auto"
|
|
453
|
-
}, queryString.length > 0 ? resultObjects.length > 0 ? resultObjects.map((object) => graph?.findNode(fullyQualifiedId(object))).filter(Boolean).map((node) => /* @__PURE__ */ React5.createElement(SearchListResult, {
|
|
454
|
-
key: node.id,
|
|
455
|
-
node,
|
|
456
|
-
onSelect: handleSelect
|
|
457
|
-
})) : /* @__PURE__ */ React5.createElement("p", {
|
|
458
|
-
className: "pli-1"
|
|
459
|
-
}, t(pending ? "pending results message" : "empty results message")) : /* @__PURE__ */ React5.createElement(React5.Fragment, null, closed.length > 0 && /* @__PURE__ */ React5.createElement("h2", {
|
|
460
|
-
className: mx4("mlb-1", descriptionText)
|
|
461
|
-
}, t("recently closed heading")), closed.map((node) => /* @__PURE__ */ React5.createElement(SearchListResult, {
|
|
462
|
-
key: node.id,
|
|
463
|
-
node,
|
|
464
|
-
onSelect: handleSelect
|
|
465
|
-
}))))), /* @__PURE__ */ React5.createElement(Dialog.Close, {
|
|
466
|
-
asChild: true
|
|
467
|
-
}, /* @__PURE__ */ React5.createElement(Button, {
|
|
468
|
-
variant: "primary",
|
|
469
|
-
classNames: "mbs-2"
|
|
470
|
-
}, t("close label", {
|
|
471
|
-
ns: "os"
|
|
472
|
-
}))));
|
|
473
|
-
};
|
|
19
|
+
// packages/plugins/experimental/plugin-search/src/capabilities/index.ts
|
|
20
|
+
import { lazy } from "@dxos/app-framework";
|
|
21
|
+
var AppGraphBuilder = lazy(() => import("./app-graph-builder-4C2ZPCED.mjs"));
|
|
22
|
+
var IntentResolver = lazy(() => import("./intent-resolver-MKBD2LPH.mjs"));
|
|
23
|
+
var ReactSurface = lazy(() => import("./react-surface-H2PAVIXZ.mjs"));
|
|
474
24
|
|
|
475
25
|
// packages/plugins/experimental/plugin-search/src/translations.ts
|
|
476
26
|
var translations_default = [
|
|
@@ -489,126 +39,60 @@ var translations_default = [
|
|
|
489
39
|
}
|
|
490
40
|
];
|
|
491
41
|
|
|
492
|
-
// packages/plugins/experimental/plugin-search/src/types.tsx
|
|
493
|
-
var SEARCH_ACTION = `${SEARCH_PLUGIN}/action`;
|
|
494
|
-
var SearchAction;
|
|
495
|
-
(function(SearchAction2) {
|
|
496
|
-
SearchAction2[SearchAction2["SEARCH"] = `${SEARCH_ACTION}/search`] = "SEARCH";
|
|
497
|
-
})(SearchAction || (SearchAction = {}));
|
|
498
|
-
|
|
499
42
|
// packages/plugins/experimental/plugin-search/src/SearchPlugin.tsx
|
|
500
|
-
var SearchPlugin = () =>
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
43
|
+
var SearchPlugin = () => definePlugin(meta, [
|
|
44
|
+
defineModule({
|
|
45
|
+
id: `${meta.id}/module/translations`,
|
|
46
|
+
activatesOn: Events.SetupTranslations,
|
|
47
|
+
activate: () => contributes(Capabilities.Translations, translations_default)
|
|
48
|
+
}),
|
|
49
|
+
defineModule({
|
|
50
|
+
id: `${meta.id}/module/metadata`,
|
|
51
|
+
activatesOn: Events.SetupMetadata,
|
|
52
|
+
activate: () => contributes(Capabilities.Metadata, {
|
|
53
|
+
id: SEARCH_RESULT,
|
|
511
54
|
metadata: {
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
case "view-object":
|
|
525
|
-
return item;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
},
|
|
531
|
-
graph: {
|
|
532
|
-
builder: (plugins) => {
|
|
533
|
-
const intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
|
|
534
|
-
return createExtension({
|
|
535
|
-
id: SEARCH_PLUGIN,
|
|
536
|
-
filter: (node) => node.id === "root",
|
|
537
|
-
actions: () => [
|
|
538
|
-
{
|
|
539
|
-
id: SearchAction.SEARCH,
|
|
540
|
-
data: async () => {
|
|
541
|
-
await intentPlugin?.provides.intent.dispatch({
|
|
542
|
-
plugin: SEARCH_PLUGIN,
|
|
543
|
-
action: SearchAction.SEARCH
|
|
544
|
-
});
|
|
545
|
-
},
|
|
546
|
-
properties: {
|
|
547
|
-
label: [
|
|
548
|
-
"search action label",
|
|
549
|
-
{
|
|
550
|
-
ns: SEARCH_PLUGIN
|
|
551
|
-
}
|
|
552
|
-
],
|
|
553
|
-
icon: "ph--magnifying-glass--regular",
|
|
554
|
-
keyBinding: {
|
|
555
|
-
macos: "shift+meta+f",
|
|
556
|
-
windows: "shift+alt+f"
|
|
557
|
-
},
|
|
558
|
-
testId: "searchPlugin.search"
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
]
|
|
562
|
-
});
|
|
563
|
-
}
|
|
564
|
-
},
|
|
565
|
-
context: ({ children }) => /* @__PURE__ */ React6.createElement(SearchContextProvider, null, children),
|
|
566
|
-
surface: {
|
|
567
|
-
component: ({ data, role }) => {
|
|
568
|
-
const location = navigationPlugin?.provides.location;
|
|
569
|
-
const graph = graphPlugin?.provides.graph;
|
|
570
|
-
const space = graph && location ? getActiveSpace(graph, firstIdInPart(location.active, "main")) : void 0;
|
|
571
|
-
switch (role) {
|
|
572
|
-
case "dialog":
|
|
573
|
-
return data.component === `${SEARCH_PLUGIN}/Dialog` ? /* @__PURE__ */ React6.createElement(SearchDialog, {
|
|
574
|
-
subject: data.subject
|
|
575
|
-
}) : null;
|
|
576
|
-
case "search-input":
|
|
577
|
-
return space ? /* @__PURE__ */ React6.createElement(SearchMain, {
|
|
578
|
-
space
|
|
579
|
-
}) : null;
|
|
580
|
-
}
|
|
581
|
-
return null;
|
|
582
|
-
}
|
|
583
|
-
},
|
|
584
|
-
intent: {
|
|
585
|
-
resolver: (intent, plugins) => {
|
|
586
|
-
switch (intent.action) {
|
|
587
|
-
case SearchAction.SEARCH: {
|
|
588
|
-
const intentPlugin = resolvePlugin(plugins, parseIntentPlugin);
|
|
589
|
-
return intentPlugin?.provides.intent.dispatch({
|
|
590
|
-
action: LayoutAction2.SET_LAYOUT,
|
|
591
|
-
data: {
|
|
592
|
-
element: "complementary",
|
|
593
|
-
state: true
|
|
594
|
-
}
|
|
595
|
-
});
|
|
596
|
-
}
|
|
55
|
+
parse: (item, type) => {
|
|
56
|
+
switch (type) {
|
|
57
|
+
case "node":
|
|
58
|
+
return {
|
|
59
|
+
id: item.id,
|
|
60
|
+
label: item.label,
|
|
61
|
+
data: item.object
|
|
62
|
+
};
|
|
63
|
+
case "object":
|
|
64
|
+
return item.object;
|
|
65
|
+
case "view-object":
|
|
66
|
+
return item;
|
|
597
67
|
}
|
|
598
68
|
}
|
|
599
69
|
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
70
|
+
})
|
|
71
|
+
}),
|
|
72
|
+
defineModule({
|
|
73
|
+
id: `${meta.id}/module/react-surface`,
|
|
74
|
+
activatesOn: Events.SetupSurfaces,
|
|
75
|
+
activate: ReactSurface
|
|
76
|
+
}),
|
|
77
|
+
defineModule({
|
|
78
|
+
id: `${meta.id}/module/intent-resolver`,
|
|
79
|
+
activatesOn: Events.SetupIntents,
|
|
80
|
+
activate: IntentResolver
|
|
81
|
+
}),
|
|
82
|
+
defineModule({
|
|
83
|
+
id: `${meta.id}/module/app-graph-builder`,
|
|
84
|
+
activatesOn: Events.SetupAppGraph,
|
|
85
|
+
activate: AppGraphBuilder
|
|
86
|
+
})
|
|
87
|
+
]);
|
|
606
88
|
export {
|
|
89
|
+
SEARCH_PLUGIN,
|
|
90
|
+
SEARCH_RESULT,
|
|
607
91
|
SearchContextProvider,
|
|
608
92
|
SearchPlugin,
|
|
609
|
-
src_default as default,
|
|
610
93
|
filterObjectsSync,
|
|
611
94
|
mapObjectToTextFields,
|
|
95
|
+
meta,
|
|
612
96
|
queryStringToMatch,
|
|
613
97
|
useGlobalFilteredObjects,
|
|
614
98
|
useGlobalSearch,
|