hanbiro-react16-sdk 1.0.25 → 1.0.27

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.
Files changed (40) hide show
  1. package/dist/components/ChatAIDraft/ChatInput.d.ts +27 -0
  2. package/dist/components/ChatAIDraft/ChatInput.js +190 -0
  3. package/dist/components/ChatAIDraft/ChatList/AIAvatar.d.ts +3 -0
  4. package/dist/components/ChatAIDraft/ChatList/AIAvatar.js +24 -0
  5. package/dist/components/ChatAIDraft/ChatList/LoadingDots.d.ts +6 -0
  6. package/dist/components/ChatAIDraft/ChatList/LoadingDots.js +24 -0
  7. package/dist/components/ChatAIDraft/ChatList/MessageItem.d.ts +11 -0
  8. package/dist/components/ChatAIDraft/ChatList/MessageItem.js +124 -0
  9. package/dist/components/ChatAIDraft/ChatList/helpers.d.ts +1 -0
  10. package/dist/components/ChatAIDraft/ChatList/helpers.js +35 -0
  11. package/dist/components/ChatAIDraft/ChatList/index.d.ts +11 -0
  12. package/dist/components/ChatAIDraft/ChatList/index.js +36 -0
  13. package/dist/components/ChatAIDraft/{EmptyState.js → CreatePanel/EmptyState.js} +4 -4
  14. package/dist/components/ChatAIDraft/CreatePanel/index.d.ts +30 -0
  15. package/dist/components/ChatAIDraft/CreatePanel/index.js +173 -0
  16. package/dist/components/ChatAIDraft/ReplyPanel/EmptyState.d.ts +10 -0
  17. package/dist/components/ChatAIDraft/ReplyPanel/EmptyState.js +365 -0
  18. package/dist/components/ChatAIDraft/ReplyPanel/MailListSelect.d.ts +26 -0
  19. package/dist/components/ChatAIDraft/ReplyPanel/MailListSelect.js +480 -0
  20. package/dist/components/ChatAIDraft/ReplyPanel/helper.d.ts +13 -0
  21. package/dist/components/ChatAIDraft/ReplyPanel/helper.js +100 -0
  22. package/dist/components/ChatAIDraft/ReplyPanel/index.d.ts +46 -0
  23. package/dist/components/ChatAIDraft/ReplyPanel/index.js +465 -0
  24. package/dist/components/ChatAIDraft/helper.d.ts +1 -0
  25. package/dist/components/ChatAIDraft/helper.js +12 -1
  26. package/dist/components/ChatAIDraft/index.d.ts +4 -32
  27. package/dist/components/ChatAIDraft/index.js +19 -307
  28. package/dist/components/ChatAIDraft/types.d.ts +36 -0
  29. package/dist/hanbiro-react16-sdk.style.css +41 -1
  30. package/dist/hanbiro-react16-sdk.umd.js +5143 -3379
  31. package/dist/index.js +1 -1
  32. package/dist/node_modules/react-feather/dist/icons/arrow-left.js +73 -0
  33. package/dist/node_modules/react-feather/dist/icons/lock.js +75 -0
  34. package/dist/node_modules/react-feather/dist/icons/mail.js +70 -0
  35. package/dist/node_modules/react-feather/dist/icons/paperclip.js +68 -0
  36. package/dist/node_modules/react-feather/dist/icons/plus.js +76 -0
  37. package/package.json +1 -1
  38. package/dist/components/ChatAIDraft/List.d.ts +0 -10
  39. package/dist/components/ChatAIDraft/List.js +0 -188
  40. /package/dist/components/ChatAIDraft/{EmptyState.d.ts → CreatePanel/EmptyState.d.ts} +0 -0
@@ -0,0 +1,465 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
+ var __async = (__this, __arguments, generator) => {
22
+ return new Promise((resolve, reject) => {
23
+ var fulfilled = (value) => {
24
+ try {
25
+ step(generator.next(value));
26
+ } catch (e) {
27
+ reject(e);
28
+ }
29
+ };
30
+ var rejected = (value) => {
31
+ try {
32
+ step(generator.throw(value));
33
+ } catch (e) {
34
+ reject(e);
35
+ }
36
+ };
37
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
38
+ step((generator = generator.apply(__this, __arguments)).next());
39
+ });
40
+ };
41
+ import * as React from "react";
42
+ import { callAI } from "../helper.js";
43
+ import ChatList from "../ChatList/index.js";
44
+ import ChatInput from "../ChatInput.js";
45
+ import EmptyState from "./EmptyState.js";
46
+ import MailListSelect from "./MailListSelect.js";
47
+ import { fetchMailView, fetchMailAiContext } from "./helper.js";
48
+ import { LENGTH_OPTIONS, TONE_OPTIONS } from "../constants.js";
49
+ import { AI_LANG_FLAGS } from "../../../constants/index.js";
50
+ import v4 from "../../../node_modules/uuid/dist/esm-browser/v4.js";
51
+ import Lock from "../../../node_modules/react-feather/dist/icons/lock.js";
52
+ import Plus from "../../../node_modules/react-feather/dist/icons/plus.js";
53
+ class ReplyPanel extends React.Component {
54
+ constructor(props) {
55
+ var _a;
56
+ super(props);
57
+ __publicField(this, "rootRef");
58
+ __publicField(this, "loadSourceMail", () => __async(this, null, function* () {
59
+ const { sourceMid } = this.props;
60
+ if (!sourceMid) return;
61
+ this.setState({ isLoadingSource: true });
62
+ const view = yield fetchMailView(sourceMid);
63
+ if (view) {
64
+ this.setState({
65
+ sourceMail: {
66
+ mid: view.mid,
67
+ subject: view.subject,
68
+ from_name: view.from_name,
69
+ from_addr: view.from_addr,
70
+ date: view.date,
71
+ ai_contents: view.ai_contents,
72
+ contents: view.contents
73
+ },
74
+ accountEmail: view.from_addr,
75
+ isLoadingSource: false
76
+ });
77
+ } else {
78
+ this.setState({ isLoadingSource: false });
79
+ }
80
+ }));
81
+ __publicField(this, "handleAddClick", () => {
82
+ this.setState({ view: "list" });
83
+ });
84
+ __publicField(this, "handleListCancel", () => {
85
+ this.setState({ view: this.state.messages.length > 0 ? "chat" : "empty" });
86
+ });
87
+ __publicField(this, "handleListConfirm", (mids) => __async(this, null, function* () {
88
+ this.setState({ isLoadingSelected: true });
89
+ const selectedMails = yield fetchMailAiContext(mids);
90
+ this.setState({
91
+ selectedMails,
92
+ isLoadingSelected: false,
93
+ view: this.state.messages.length > 0 ? "chat" : "empty"
94
+ });
95
+ }));
96
+ __publicField(this, "handleRemoveSelected", (mid) => {
97
+ this.setState({
98
+ selectedMails: this.state.selectedMails.filter((m) => m.mid !== mid)
99
+ });
100
+ });
101
+ __publicField(this, "handleMessageChange", (value) => {
102
+ this.setState({ message: value });
103
+ });
104
+ __publicField(this, "handleSubmit", () => __async(this, null, function* () {
105
+ const { type } = this.props;
106
+ const {
107
+ message,
108
+ messages,
109
+ lang,
110
+ tone,
111
+ length,
112
+ conversationId,
113
+ sourceMail,
114
+ selectedMails
115
+ } = this.state;
116
+ if (!message.trim()) return;
117
+ const newId = v4();
118
+ const newMessage = {
119
+ id: newId,
120
+ question: message,
121
+ subject: "",
122
+ body: "",
123
+ created_at: (/* @__PURE__ */ new Date()).getTime(),
124
+ isLoading: true
125
+ };
126
+ this.setState({
127
+ messages: [...messages, newMessage],
128
+ message: "",
129
+ isSending: true,
130
+ view: "chat"
131
+ });
132
+ const params = {
133
+ query: message,
134
+ default_language: lang ? lang.value : "KR",
135
+ debug_grpc: true,
136
+ action: type,
137
+ original_email: (sourceMail == null ? void 0 : sourceMail.contents) || "",
138
+ emailhistorys: selectedMails.filter((m) => m.ai_contents).map((m) => ({ date: m.date, contents: m.ai_contents }))
139
+ };
140
+ if (tone) params.tone = tone.value;
141
+ if (length) params.length = length.value;
142
+ if (conversationId) params.conversation_id = conversationId;
143
+ const setContent = (nContent) => {
144
+ this.setState((prevState) => ({
145
+ messages: prevState.messages.map(
146
+ (m) => m.id === newId ? __spreadProps(__spreadValues({}, m), {
147
+ subject: "Some thing not used",
148
+ body: nContent,
149
+ isLoading: false,
150
+ created_at: (/* @__PURE__ */ new Date()).getTime()
151
+ }) : m
152
+ )
153
+ }));
154
+ };
155
+ const setIsLoading = (loading) => {
156
+ this.setState((prevState) => ({
157
+ messages: prevState.messages.map(
158
+ (m) => m.id === newId ? __spreadProps(__spreadValues({}, m), { isLoading: loading }) : m
159
+ )
160
+ }));
161
+ };
162
+ const setConversationId = (id) => {
163
+ this.setState({ conversationId: id });
164
+ };
165
+ yield callAI(params, { setContent, setIsLoading, setConversationId });
166
+ this.setState({ isSending: false });
167
+ }));
168
+ __publicField(this, "setLang", (lang) => this.setState({ lang }));
169
+ __publicField(this, "setTone", (tone) => this.setState({ tone }));
170
+ __publicField(this, "setLength", (length) => this.setState({ length }));
171
+ this.rootRef = React.createRef();
172
+ const lang = ((_a = AI_LANG_FLAGS) == null ? void 0 : _a.find((_item) => (_item == null ? void 0 : _item.value) === (props == null ? void 0 : props.defaultLang))) || AI_LANG_FLAGS[0];
173
+ this.state = {
174
+ view: "empty",
175
+ sourceMail: null,
176
+ accountEmail: "",
177
+ selectedMails: [],
178
+ isLoadingSource: false,
179
+ isLoadingSelected: false,
180
+ message: "",
181
+ messages: [],
182
+ isSending: false,
183
+ lang,
184
+ tone: TONE_OPTIONS[2],
185
+ length: LENGTH_OPTIONS[2],
186
+ conversationId: ""
187
+ };
188
+ }
189
+ componentDidMount() {
190
+ this.loadSourceMail();
191
+ }
192
+ renderContextHeader() {
193
+ const { sourceMail, selectedMails } = this.state;
194
+ return /* @__PURE__ */ React.createElement(
195
+ "div",
196
+ {
197
+ style: {
198
+ display: "flex",
199
+ flexDirection: "column",
200
+ gap: 8,
201
+ paddingBottom: 12,
202
+ borderBottom: "1px solid var(--border-light)",
203
+ marginBottom: 12
204
+ }
205
+ },
206
+ sourceMail && /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 4 } }, /* @__PURE__ */ React.createElement(
207
+ "div",
208
+ {
209
+ style: {
210
+ display: "flex",
211
+ alignItems: "center",
212
+ gap: 6,
213
+ fontSize: 12,
214
+ fontWeight: 600,
215
+ color: "var(--text-primary)"
216
+ }
217
+ },
218
+ /* @__PURE__ */ React.createElement("span", null, "Source context"),
219
+ /* @__PURE__ */ React.createElement(
220
+ "span",
221
+ {
222
+ style: {
223
+ background: "var(--primary-main)",
224
+ color: "var(--primary-contrasttext)",
225
+ fontSize: 10,
226
+ padding: "1px 6px",
227
+ borderRadius: 999
228
+ }
229
+ },
230
+ "1"
231
+ ),
232
+ /* @__PURE__ */ React.createElement(
233
+ "span",
234
+ {
235
+ style: {
236
+ display: "inline-flex",
237
+ alignItems: "center",
238
+ gap: 2,
239
+ fontSize: 11,
240
+ color: "var(--text-secondary)"
241
+ }
242
+ },
243
+ /* @__PURE__ */ React.createElement(Lock, { size: 11 }),
244
+ " Auto"
245
+ )
246
+ ), /* @__PURE__ */ React.createElement(
247
+ "div",
248
+ {
249
+ style: {
250
+ fontSize: 12,
251
+ color: "var(--text-secondary)",
252
+ whiteSpace: "nowrap",
253
+ overflow: "hidden",
254
+ textOverflow: "ellipsis"
255
+ }
256
+ },
257
+ sourceMail.subject,
258
+ " ·",
259
+ " ",
260
+ /* @__PURE__ */ React.createElement("span", { style: { color: "var(--text-primary)" } }, sourceMail.from_name)
261
+ )),
262
+ /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 6 } }, /* @__PURE__ */ React.createElement(
263
+ "div",
264
+ {
265
+ style: {
266
+ display: "flex",
267
+ alignItems: "center",
268
+ justifyContent: "space-between"
269
+ }
270
+ },
271
+ /* @__PURE__ */ React.createElement(
272
+ "div",
273
+ {
274
+ style: {
275
+ display: "flex",
276
+ alignItems: "center",
277
+ gap: 6,
278
+ fontSize: 12,
279
+ fontWeight: 600,
280
+ color: "var(--text-primary)"
281
+ }
282
+ },
283
+ /* @__PURE__ */ React.createElement("span", null, "Selected context"),
284
+ /* @__PURE__ */ React.createElement(
285
+ "span",
286
+ {
287
+ style: {
288
+ background: "var(--background-softGrey)",
289
+ color: "var(--text-primary)",
290
+ fontSize: 10,
291
+ padding: "1px 6px",
292
+ borderRadius: 999
293
+ }
294
+ },
295
+ selectedMails.length
296
+ )
297
+ ),
298
+ /* @__PURE__ */ React.createElement(
299
+ "button",
300
+ {
301
+ type: "button",
302
+ onClick: this.handleAddClick,
303
+ className: "text-button primary"
304
+ },
305
+ /* @__PURE__ */ React.createElement(Plus, { size: 12 }),
306
+ " Add"
307
+ )
308
+ ), selectedMails.length > 0 && /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 } }, selectedMails.map((m, i) => /* @__PURE__ */ React.createElement(
309
+ "div",
310
+ {
311
+ key: m.mid,
312
+ style: {
313
+ display: "inline-flex",
314
+ alignItems: "center",
315
+ gap: 6,
316
+ padding: "4px 8px",
317
+ borderRadius: 8,
318
+ border: "1px solid var(--border-light)",
319
+ background: "var(--primary-lighter)",
320
+ fontSize: 11,
321
+ maxWidth: 160
322
+ }
323
+ },
324
+ /* @__PURE__ */ React.createElement(
325
+ "span",
326
+ {
327
+ style: {
328
+ width: 14,
329
+ height: 14,
330
+ borderRadius: "50%",
331
+ background: "var(--primary-main)",
332
+ color: "var(--primary-contrasttext)",
333
+ fontSize: 9,
334
+ fontWeight: 700,
335
+ display: "inline-flex",
336
+ alignItems: "center",
337
+ justifyContent: "center",
338
+ flexShrink: 0
339
+ }
340
+ },
341
+ i + 1
342
+ ),
343
+ /* @__PURE__ */ React.createElement(
344
+ "span",
345
+ {
346
+ style: {
347
+ whiteSpace: "nowrap",
348
+ overflow: "hidden",
349
+ textOverflow: "ellipsis"
350
+ }
351
+ },
352
+ m.subject || "(no subject)"
353
+ ),
354
+ /* @__PURE__ */ React.createElement(
355
+ "button",
356
+ {
357
+ type: "button",
358
+ onClick: () => this.handleRemoveSelected(m.mid),
359
+ style: {
360
+ border: "none",
361
+ background: "transparent",
362
+ cursor: "pointer",
363
+ padding: 0,
364
+ color: "var(--text-secondary)",
365
+ display: "inline-flex",
366
+ alignItems: "center",
367
+ flexShrink: 0
368
+ }
369
+ },
370
+ "×"
371
+ )
372
+ ))))
373
+ );
374
+ }
375
+ render() {
376
+ const { onApply, getEditorContent } = this.props;
377
+ const {
378
+ view,
379
+ sourceMail,
380
+ accountEmail,
381
+ selectedMails,
382
+ message,
383
+ messages,
384
+ isSending,
385
+ lang,
386
+ tone,
387
+ length,
388
+ isLoadingSelected
389
+ } = this.state;
390
+ if (view === "list") {
391
+ return /* @__PURE__ */ React.createElement(
392
+ MailListSelect,
393
+ {
394
+ accountEmail,
395
+ initialSelected: selectedMails.map((m) => m.mid),
396
+ onCancel: this.handleListCancel,
397
+ onConfirm: this.handleListConfirm
398
+ }
399
+ );
400
+ }
401
+ return /* @__PURE__ */ React.createElement(
402
+ "div",
403
+ {
404
+ ref: this.rootRef,
405
+ style: {
406
+ display: "flex",
407
+ height: "100%",
408
+ padding: 16,
409
+ flexDirection: "column",
410
+ background: "#fff",
411
+ fontFamily: "inherit",
412
+ boxSizing: "border-box"
413
+ }
414
+ },
415
+ view === "chat" ? /* @__PURE__ */ React.createElement(React.Fragment, null, this.renderContextHeader(), /* @__PURE__ */ React.createElement(
416
+ ChatList,
417
+ {
418
+ items: messages,
419
+ onApply,
420
+ getEditorContent
421
+ }
422
+ )) : /* @__PURE__ */ React.createElement(
423
+ EmptyState,
424
+ {
425
+ sourceMail,
426
+ selectedMails,
427
+ onAddClick: this.handleAddClick,
428
+ onRemoveSelected: this.handleRemoveSelected
429
+ }
430
+ ),
431
+ isLoadingSelected && /* @__PURE__ */ React.createElement(
432
+ "div",
433
+ {
434
+ style: {
435
+ fontSize: 12,
436
+ color: "var(--text-secondary)",
437
+ padding: 8,
438
+ textAlign: "center"
439
+ }
440
+ },
441
+ "Loading context..."
442
+ ),
443
+ /* @__PURE__ */ React.createElement(
444
+ ChatInput,
445
+ {
446
+ message,
447
+ onMessageChange: this.handleMessageChange,
448
+ onSubmit: this.handleSubmit,
449
+ isSending,
450
+ lang,
451
+ setLang: this.setLang,
452
+ tone,
453
+ setTone: this.setTone,
454
+ length,
455
+ setLength: this.setLength,
456
+ parentRef: this.rootRef,
457
+ placeholder: "Type a message..."
458
+ }
459
+ )
460
+ );
461
+ }
462
+ }
463
+ export {
464
+ ReplyPanel as default
465
+ };
@@ -4,4 +4,5 @@ interface Options {
4
4
  setConversationId: (nVal: string) => void;
5
5
  }
6
6
  export declare function callAI(params: any, { setContent, setIsLoading, setConversationId }: Options): Promise<string>;
7
+ export declare const extractEmail: (raw?: string) => string;
7
8
  export {};
@@ -116,6 +116,17 @@ function callAI(_0, _1) {
116
116
  return "";
117
117
  });
118
118
  }
119
+ const extractEmail = (raw = "") => {
120
+ var _a;
121
+ if (!raw) return "";
122
+ const decoded = String(raw).replace(/&lt;/g, "<").replace(/&gt;/g, ">").trim();
123
+ const match = decoded.match(/<([^>]+)>/);
124
+ if (match) return match[1].trim();
125
+ const first = (_a = decoded.split(",")[0]) == null ? void 0 : _a.trim();
126
+ const inner = first == null ? void 0 : first.match(/([^\s<>"]+@[^\s<>"]+)/);
127
+ return inner ? inner[1] : first || "";
128
+ };
119
129
  export {
120
- callAI
130
+ callAI,
131
+ extractEmail
121
132
  };
@@ -1,41 +1,13 @@
1
- import { LabelValue } from '../../types';
1
+ import { ChatType } from './types';
2
2
  import * as React from "react";
3
3
  export interface ChatAIDraftProps {
4
+ type?: ChatType;
5
+ sourceMid?: string;
4
6
  defaultLang?: string;
5
7
  getEditorContent?: () => string;
6
8
  onApply: (params: {
7
9
  html: string;
8
10
  }) => void;
9
11
  }
10
- export interface AIMessage {
11
- id: string;
12
- question: string;
13
- subject: string;
14
- body: string;
15
- created_at: number;
16
- isLoading: boolean;
17
- }
18
- interface AIPaneState {
19
- message: string;
20
- messages: AIMessage[];
21
- isSending: boolean;
22
- lang: LabelValue | null;
23
- tone: LabelValue | null;
24
- length: LabelValue | null;
25
- conversationId: string;
26
- }
27
- declare class ChatAIDraft extends React.Component<ChatAIDraftProps, AIPaneState> {
28
- private rootRef;
29
- private textareaRef;
30
- constructor(props: ChatAIDraftProps);
31
- adjustTextareaHeight: () => void;
32
- handleMessageChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
33
- componentDidUpdate(_: ChatAIDraftProps, prevState: AIPaneState): void;
34
- handleSubmit: () => Promise<void>;
35
- handleKeyDown: (event: React.KeyboardEvent<HTMLTextAreaElement>) => void;
36
- setLang: (lang: LabelValue | null) => void;
37
- setTone: (tone: LabelValue | null) => void;
38
- setLength: (length: LabelValue | null) => void;
39
- render(): React.JSX.Element;
40
- }
12
+ declare const ChatAIDraft: React.FunctionComponent<ChatAIDraftProps>;
41
13
  export default ChatAIDraft;