mindoodb-app-sdk 0.0.58 → 0.0.60

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 CHANGED
@@ -391,6 +391,63 @@ 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
+ rect: panel.getBoundingClientRect(), // in this app's viewport
439
+ });
440
+ new ResizeObserver(() => void embed.setRect(panel.getBoundingClientRect())).observe(panel);
441
+ const closed = await embed.closed; // { reason: "completed" | "cancelled" | "closed" | "error", result? }
442
+ ```
443
+
444
+ Haven lays the component's frame over the rectangle, above the host's frame, so the
445
+ host cannot draw on top of it; hide it with `embed.setVisible(false)` while a dialog of
446
+ the host should be visible. The first time a host embeds a component, Haven asks the user.
447
+ In tests, `createMockMindooDBAppSession({ components })` records embeds
448
+ (`listEmbeds`, `closeEmbed`), and the `/__haven-test/` page draws a stand-in with
449
+ Done/Cancel buttons.
450
+
394
451
  ### Databases and capabilities
395
452
 
396
453
  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.