@fieldia/chatter 0.10.0 → 0.12.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fieldia/chatter",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "A record's conversation and to-dos beside its Fieldia form: messages, notes, attachments, activities and followers, through an interface your app implements.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://fieldia.dev",
@@ -21,8 +21,8 @@
21
21
  "./package.json": "./package.json"
22
22
  },
23
23
  "dependencies": {
24
- "@fieldia/core": "0.10.0",
25
- "@fieldia/widgets": "0.10.0",
24
+ "@fieldia/core": "0.12.0",
25
+ "@fieldia/widgets": "0.12.0",
26
26
  "tslib": "^2.8.1"
27
27
  },
28
28
  "sideEffects": false,
@@ -1,5 +1,6 @@
1
- import type { Form } from '@fieldia/core';
1
+ import type { FileValue, Form, RecordRequest } from '@fieldia/core';
2
2
  import { type ChatterOptions } from './chatter.mjs';
3
+ import type { ChatterSource } from './source.mjs';
3
4
  export interface ChatterSlotOptions extends Omit<ChatterOptions, 'record'> {
4
5
  /** The model the conversation is about; the page's own by default. */
5
6
  model?: string;
@@ -7,11 +8,19 @@ export interface ChatterSlotOptions extends Omit<ChatterOptions, 'record'> {
7
8
  /**
8
9
  * What fills a sheet's chatter slot: the conversation of the record the form
9
10
  * shows. It waits while the record is new, starts once it is saved, follows
10
- * the form to another record, and fetches again after each save, when a
11
- * backend posts what changed.
11
+ * the form to another record, and fetches again after each save and each
12
+ * time the record is loaded again — when a backend posts what changed. What
13
+ * a `post` step or the app's answer posts, it posts.
12
14
  *
13
15
  * mountViewer(host, { page, dataSource, slots: { chatter: chatterSlot({ source }) } })
14
16
  */
15
17
  export declare function chatterSlot(options: ChatterSlotOptions): (element: HTMLElement, context: {
16
18
  form: Form;
17
19
  }) => () => void;
20
+ /**
21
+ * A record's attachments from its conversation, newest first — the pictures
22
+ * and PDFs sent with its messages — as a data source's `attachments`, for a
23
+ * sheet's attachment preview: `{ ...dataSource, attachments: chatterAttachments(source) }`.
24
+ * Only those with an address are given.
25
+ */
26
+ export declare function chatterAttachments(source: ChatterSource): (request: RecordRequest) => Promise<FileValue[]>;
package/src/lib/slot.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import type { Form } from '@fieldia/core';
1
+ import type { FileValue, Form, RecordRequest } from '@fieldia/core';
2
2
  import { type ChatterOptions } from './chatter';
3
+ import type { ChatterSource } from './source';
3
4
  export interface ChatterSlotOptions extends Omit<ChatterOptions, 'record'> {
4
5
  /** The model the conversation is about; the page's own by default. */
5
6
  model?: string;
@@ -7,11 +8,19 @@ export interface ChatterSlotOptions extends Omit<ChatterOptions, 'record'> {
7
8
  /**
8
9
  * What fills a sheet's chatter slot: the conversation of the record the form
9
10
  * shows. It waits while the record is new, starts once it is saved, follows
10
- * the form to another record, and fetches again after each save, when a
11
- * backend posts what changed.
11
+ * the form to another record, and fetches again after each save and each
12
+ * time the record is loaded again — when a backend posts what changed. What
13
+ * a `post` step or the app's answer posts, it posts.
12
14
  *
13
15
  * mountViewer(host, { page, dataSource, slots: { chatter: chatterSlot({ source }) } })
14
16
  */
15
17
  export declare function chatterSlot(options: ChatterSlotOptions): (element: HTMLElement, context: {
16
18
  form: Form;
17
19
  }) => () => void;
20
+ /**
21
+ * A record's attachments from its conversation, newest first — the pictures
22
+ * and PDFs sent with its messages — as a data source's `attachments`, for a
23
+ * sheet's attachment preview: `{ ...dataSource, attachments: chatterAttachments(source) }`.
24
+ * Only those with an address are given.
25
+ */
26
+ export declare function chatterAttachments(source: ChatterSource): (request: RecordRequest) => Promise<FileValue[]>;
package/src/lib/slot.js CHANGED
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.chatterSlot = chatterSlot;
4
+ exports.chatterAttachments = chatterAttachments;
4
5
  const chatter_1 = require("./chatter");
5
6
  /**
6
7
  * What fills a sheet's chatter slot: the conversation of the record the form
7
8
  * shows. It waits while the record is new, starts once it is saved, follows
8
- * the form to another record, and fetches again after each save, when a
9
- * backend posts what changed.
9
+ * the form to another record, and fetches again after each save and each
10
+ * time the record is loaded again — when a backend posts what changed. What
11
+ * a `post` step or the app's answer posts, it posts.
10
12
  *
11
13
  * mountViewer(host, { page, dataSource, slots: { chatter: chatterSlot({ source }) } })
12
14
  */
@@ -23,15 +25,34 @@ function chatterSlot(options) {
23
25
  shown = next;
24
26
  void chatter.setRecord(next);
25
27
  }
26
- else if (state.status === 'saved' && status !== 'saved') {
28
+ else if ((state.status === 'saved' && status !== 'saved') || (state.status === 'ready' && status === 'loading')) {
27
29
  void chatter.refresh();
28
30
  }
29
31
  status = state.status;
30
32
  });
33
+ // Words a step or the app posts go in the conversation as a message or a note.
34
+ const unpost = form.on('post', ({ message }) => {
35
+ const record = recordOf(form.getState());
36
+ if (record)
37
+ void options.source.post(record, { kind: message.kind, body: message.body }).then(() => chatter.refresh());
38
+ });
31
39
  return () => {
32
40
  unsubscribe();
41
+ unpost();
33
42
  chatter.destroy();
34
43
  };
35
44
  };
36
45
  }
46
+ /**
47
+ * A record's attachments from its conversation, newest first — the pictures
48
+ * and PDFs sent with its messages — as a data source's `attachments`, for a
49
+ * sheet's attachment preview: `{ ...dataSource, attachments: chatterAttachments(source) }`.
50
+ * Only those with an address are given.
51
+ */
52
+ function chatterAttachments(source) {
53
+ return async ({ model, id }) => {
54
+ const messages = await source.messages({ model, id });
55
+ return messages.flatMap((message) => message.attachments ?? []).flatMap((file) => (file.url ? [{ name: file.name, type: file.type, size: file.size, url: file.url }] : []));
56
+ };
57
+ }
37
58
  //# sourceMappingURL=slot.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"slot.js","sourceRoot":"","sources":["../../../../../libs/chatter/src/lib/slot.ts"],"names":[],"mappings":";;AAiBA,kCAsBC;AAtCD,uCAA8D;AAQ9D;;;;;;;GAOG;AACH,SAAgB,WAAW,CAAC,OAA2B;IACrD,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChG,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAoB,EAAE,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClI,IAAI,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtC,IAAI,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC;QACpC,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,IAAI,EAAE,EAAE,KAAK,KAAK,EAAE,EAAE,EAAE,CAAC;gBAC3B,KAAK,GAAG,IAAI,CAAC;gBACb,KAAK,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC1D,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;YACzB,CAAC;YACD,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACxB,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,WAAW,EAAE,CAAC;YACd,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"slot.js","sourceRoot":"","sources":["../../../../../libs/chatter/src/lib/slot.ts"],"names":[],"mappings":"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"}
package/src/lib/slot.mjs CHANGED
@@ -2,8 +2,9 @@ import { mountChatter } from './chatter.mjs';
2
2
  /**
3
3
  * What fills a sheet's chatter slot: the conversation of the record the form
4
4
  * shows. It waits while the record is new, starts once it is saved, follows
5
- * the form to another record, and fetches again after each save, when a
6
- * backend posts what changed.
5
+ * the form to another record, and fetches again after each save and each
6
+ * time the record is loaded again — when a backend posts what changed. What
7
+ * a `post` step or the app's answer posts, it posts.
7
8
  *
8
9
  * mountViewer(host, { page, dataSource, slots: { chatter: chatterSlot({ source }) } })
9
10
  */
@@ -20,15 +21,34 @@ export function chatterSlot(options) {
20
21
  shown = next;
21
22
  void chatter.setRecord(next);
22
23
  }
23
- else if (state.status === 'saved' && status !== 'saved') {
24
+ else if ((state.status === 'saved' && status !== 'saved') || (state.status === 'ready' && status === 'loading')) {
24
25
  void chatter.refresh();
25
26
  }
26
27
  status = state.status;
27
28
  });
29
+ // Words a step or the app posts go in the conversation as a message or a note.
30
+ const unpost = form.on('post', ({ message }) => {
31
+ const record = recordOf(form.getState());
32
+ if (record)
33
+ void options.source.post(record, { kind: message.kind, body: message.body }).then(() => chatter.refresh());
34
+ });
28
35
  return () => {
29
36
  unsubscribe();
37
+ unpost();
30
38
  chatter.destroy();
31
39
  };
32
40
  };
33
41
  }
42
+ /**
43
+ * A record's attachments from its conversation, newest first — the pictures
44
+ * and PDFs sent with its messages — as a data source's `attachments`, for a
45
+ * sheet's attachment preview: `{ ...dataSource, attachments: chatterAttachments(source) }`.
46
+ * Only those with an address are given.
47
+ */
48
+ export function chatterAttachments(source) {
49
+ return async ({ model, id }) => {
50
+ const messages = await source.messages({ model, id });
51
+ return messages.flatMap((message) => message.attachments ?? []).flatMap((file) => (file.url ? [{ name: file.name, type: file.type, size: file.size, url: file.url }] : []));
52
+ };
53
+ }
34
54
  //# sourceMappingURL=slot.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"slot.mjs","sourceRoot":"","sources":["../../../../../libs/chatter/src/lib/slot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAuB,MAAM,WAAW,CAAC;AAQ9D;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,OAA2B;IACrD,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChG,MAAM,QAAQ,GAAG,CAAC,KAAgB,EAAoB,EAAE,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClI,IAAI,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtC,IAAI,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC;QACpC,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE;YAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC7B,IAAI,IAAI,EAAE,EAAE,KAAK,KAAK,EAAE,EAAE,EAAE,CAAC;gBAC3B,KAAK,GAAG,IAAI,CAAC;gBACb,KAAK,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBAC1D,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC;YACzB,CAAC;YACD,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QACxB,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,WAAW,EAAE,CAAC;YACd,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"slot.mjs","sourceRoot":"","sources":["../../../../../libs/chatter/src/lib/slot.ts"],"names":[],"mappings":"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"}