mindoodb-app-sdk 0.0.59 → 0.0.61
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 +68 -0
- package/dist/{chunk-SKPP4T6S.js → chunk-U4NXI7EH.js} +932 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +23 -510
- package/dist/testing/index.d.ts +44 -2
- package/dist/testing/index.js +307 -6
- package/dist/{types-DkzIJKBw.d.ts → types-BKN_Zh_l.d.ts} +223 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -391,6 +391,74 @@ session.onIncomingContent(async (content) => {
|
|
|
391
391
|
|
|
392
392
|
Register the handler once, early. Haven waits for it before delivering, so a launch started for a delivery receives it as soon as the handler exists. `item.path` is relative (`assets/logo.png` inside a shared folder) and never absolute. What the app does with the content is up to the app. The returned `status` and `message` are shown to the user; a throwing handler counts as `rejected`. In tests, `createMockMindooDBAppSession().emitIncomingContent({ acceptId, items })` plays Haven's part.
|
|
393
393
|
|
|
394
|
+
### Components: embedding another app's editor
|
|
395
|
+
|
|
396
|
+
An app can offer an editor to other apps, and an app can show such an editor inside
|
|
397
|
+
its own page — like an embedded control. TeamGrid offers its spreadsheet this way; a
|
|
398
|
+
CRM shows it next to its own folder tree without knowing about TeamGrid beforehand.
|
|
399
|
+
|
|
400
|
+
**Offering a component** (in `haven-app.json`):
|
|
401
|
+
|
|
402
|
+
```json
|
|
403
|
+
"components": [
|
|
404
|
+
{
|
|
405
|
+
"id": "sheet",
|
|
406
|
+
"label": { "en": "Spreadsheet", "de": "Tabelle" },
|
|
407
|
+
"icon": "icons/sheet.svg",
|
|
408
|
+
"intents": ["create", "edit", "view"],
|
|
409
|
+
"match": { "form": "teamgrid" },
|
|
410
|
+
"create": { "title": "" },
|
|
411
|
+
"children": { "linkField": "parentId", "match": { "type": "sheetChunk" } }
|
|
412
|
+
}
|
|
413
|
+
]
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
`match` names the fields a root document carries; `children` (optional) says which
|
|
417
|
+
documents belong to a root. When a host opens the component, Haven copies the root and
|
|
418
|
+
its children into an in-memory sandbox and launches the app with that sandbox as its
|
|
419
|
+
only database. The launch context then carries `embed` (`docId`, `databaseId`,
|
|
420
|
+
`intent`, `hostAppLabel`): open that document, hide "New"/"Open", and finish with
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
await session.embedding.complete({ title }); // or session.embedding.cancel()
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Haven writes every change back to the host's database as it happens and only lets the
|
|
427
|
+
component create documents that are children of the root.
|
|
428
|
+
|
|
429
|
+
**Embedding a component** (host app):
|
|
430
|
+
|
|
431
|
+
```ts
|
|
432
|
+
const [sheet] = await session.components.list({ intent: "create" });
|
|
433
|
+
const doc = await db.documents.create({ set: { ...sheet.createFields, crm: { folders: ["Offers"] } } });
|
|
434
|
+
const embed = await session.embeds.open({
|
|
435
|
+
componentKey: sheet.key,
|
|
436
|
+
databaseId: "crm",
|
|
437
|
+
docId: doc.id,
|
|
438
|
+
container: panel, // a positioned element; the component fills it
|
|
439
|
+
});
|
|
440
|
+
const closed = await embed.closed; // { reason: "completed" | "cancelled" | "closed" | "error", result? }
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
The SDK puts a frame into `container`, so the component is part of the host's page: it
|
|
444
|
+
scrolls, clips and resizes with it, and the host's menus and dialogs cover it like any
|
|
445
|
+
other element. The frame holds a page from Haven's origin that loads the component and
|
|
446
|
+
hands its connection to Haven, so the host cannot reach into the component or its data
|
|
447
|
+
channel. Haven tells the SDK where the container is (for the component's own menus);
|
|
448
|
+
the SDK follows the container's size and position by itself.
|
|
449
|
+
|
|
450
|
+
Havens that predate this lay the component over the container instead, above the host's
|
|
451
|
+
frame (`embed.placement === "overlay"`). The host then cannot draw on top of it: hide it
|
|
452
|
+
with `embed.setVisible(false)` while a menu or dialog of the host should be visible.
|
|
453
|
+
Without a `container`, pass `rect` (in this app's viewport) and keep it current with
|
|
454
|
+
`embed.setRect` to get that overlay explicitly.
|
|
455
|
+
|
|
456
|
+
The first time a host embeds a component, Haven asks the user.
|
|
457
|
+
In tests, `createMockMindooDBAppSession({ components })` records embeds
|
|
458
|
+
(`listEmbeds`, `closeEmbed`), and the `/__haven-test/` page draws a stand-in with
|
|
459
|
+
Done/Cancel buttons over the container. `createFakeBridgeHost({ embedFrameUrl })`
|
|
460
|
+
answers like a current Haven, so the SDK frames that URL in the container.
|
|
461
|
+
|
|
394
462
|
### Databases and capabilities
|
|
395
463
|
|
|
396
464
|
Each database mapped to your app carries a set of **capabilities** that Haven controls. Your app should check capabilities before attempting operations and adapt its UI accordingly.
|