@anker-in/campaign-ui 0.0.33-alpha4 → 0.0.33-alpha5

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 (35) hide show
  1. package/dist/cjs/components/chat/action.d.ts +4 -2
  2. package/dist/cjs/components/chat/action.js +1 -1
  3. package/dist/cjs/components/chat/action.js.map +3 -3
  4. package/dist/cjs/components/chat/button.d.ts +1 -1
  5. package/dist/cjs/components/chat/button.js +1 -1
  6. package/dist/cjs/components/chat/button.js.map +3 -3
  7. package/dist/cjs/components/chat/index.d.ts +13 -7
  8. package/dist/cjs/components/chat/index.js +1 -1
  9. package/dist/cjs/components/chat/index.js.map +3 -3
  10. package/dist/cjs/components/chat/props.d.ts +1 -2
  11. package/dist/cjs/components/chat/props.js +1 -1
  12. package/dist/cjs/components/chat/props.js.map +1 -1
  13. package/dist/cjs/stories/chat.stories.js +1 -1
  14. package/dist/cjs/stories/chat.stories.js.map +2 -2
  15. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  16. package/dist/esm/components/chat/action.d.ts +4 -2
  17. package/dist/esm/components/chat/action.js +1 -1
  18. package/dist/esm/components/chat/action.js.map +3 -3
  19. package/dist/esm/components/chat/button.d.ts +1 -1
  20. package/dist/esm/components/chat/button.js +1 -1
  21. package/dist/esm/components/chat/button.js.map +3 -3
  22. package/dist/esm/components/chat/index.d.ts +13 -7
  23. package/dist/esm/components/chat/index.js +1 -1
  24. package/dist/esm/components/chat/index.js.map +3 -3
  25. package/dist/esm/components/chat/props.d.ts +1 -2
  26. package/dist/esm/components/chat/props.js.map +1 -1
  27. package/dist/esm/stories/chat.stories.js +1 -1
  28. package/dist/esm/stories/chat.stories.js.map +2 -2
  29. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +1 -1
  31. package/src/components/chat/action.tsx +19 -7
  32. package/src/components/chat/button.tsx +2 -9
  33. package/src/components/chat/index.tsx +46 -37
  34. package/src/components/chat/props.ts +1 -2
  35. package/src/stories/chat.stories.tsx +5 -5
@@ -14,17 +14,20 @@ interface Message {
14
14
  export interface ActionProps {
15
15
  start?: string
16
16
  history: Message[]
17
+ addtocartHandler?: (_args: any) => Promise<any>
17
18
  gotocheckoutRender?: string | ((_props: any) => React.ReactElement)
18
19
  gotocartRender?: string | ((_props: any) => React.ReactElement)
19
20
  addtocartRender?: string | ((_props: any) => React.ReactElement)
20
- productRender?: string | ((_props: any) => React.ReactElement)
21
21
  signupRender?: string | ((_props: any) => React.ReactElement)
22
+ productRender?: string | ((_props: any) => React.ReactElement)
23
+ productRenderTipMessage?: string
22
24
  children?: React.ReactNode
23
25
  }
24
26
 
25
27
  export const CopilotAction = ({
26
28
  start,
27
29
  history,
30
+ addtocartHandler,
28
31
  gotocheckoutRender,
29
32
  gotocartRender,
30
33
  addtocartRender,
@@ -32,16 +35,17 @@ export const CopilotAction = ({
32
35
  signupRender,
33
36
  children,
34
37
  }: ActionProps) => {
35
- const { setMessages } = useCopilotChat()
38
+ const { setMessages, appendMessage, isLoading } = useCopilotChat()
36
39
 
37
40
  useEffect(() => {
38
41
  const originhistory = history?.filter(value => value?.content || value?.arguments)
39
42
  if (originhistory?.length > 0) {
40
43
  const content = originhistory?.map(value => {
41
44
  if (value?.name && value?.arguments) {
45
+ const args = value?.arguments?.map((item: any) => (item ? { ...item, ishistory: true } : {}))
42
46
  return new ActionExecutionMessage({
43
47
  name: value?.name,
44
- arguments: value?.arguments,
48
+ arguments: args,
45
49
  scope: value?.scope,
46
50
  })
47
51
  }
@@ -79,8 +83,8 @@ export const CopilotAction = ({
79
83
  description: 'add to cart',
80
84
  parameters: [{ sku: '', handle: '' }] as any,
81
85
  render: addtocartRender || (props => <div className="hidden">{JSON.stringify(props)}</div>),
82
- handler: function () {
83
- // console.log('buynow-props', props)
86
+ handler: function (props) {
87
+ addtocartHandler && addtocartHandler(props)
84
88
  },
85
89
  })
86
90
 
@@ -89,8 +93,16 @@ export const CopilotAction = ({
89
93
  description: 'product card',
90
94
  parameters: [{ sku: '', handle: '' }] as any,
91
95
  render: productRender || (props => <div className="hidden">{JSON.stringify(props)}</div>),
92
- handler: function () {
93
- // console.log('buynow-props', props)
96
+ handler: function (props) {
97
+ console.log('show_product_card-props', props)
98
+ // const ishistory = props?.find((item: { ishistory: any }) => item?.ishistory)
99
+ // if (!ishistory) {
100
+ // const content = new TextMessage({
101
+ // content: 'show product card',
102
+ // role: Role.Assistant,
103
+ // })
104
+ // appendMessage(content)
105
+ // }
94
106
  },
95
107
  })
96
108
 
@@ -2,18 +2,11 @@ import { useChatContext } from '@copilotkit/react-ui'
2
2
 
3
3
  import type { ButtonProps } from './props.js'
4
4
 
5
- const DefaultButton = ({ setOpen, setOpenTip }: ButtonProps) => {
5
+ const DefaultButton = ({ setOpen }: ButtonProps) => {
6
6
  const context = useChatContext()
7
7
 
8
8
  return (
9
- <button
10
- onClick={() => {
11
- setOpen(true)
12
- setOpenTip(false)
13
- }}
14
- className="copilotKitButton "
15
- aria-label="Open Chat"
16
- >
9
+ <button onClick={() => setOpen()} className="copilotKitButton " aria-label="Open Chat">
17
10
  <div className="copilotKitButtonIcon copilotKitButtonIconOpen">{context.icons.openIcon}</div>
18
11
  <div className="copilotKitButtonIcon copilotKitButtonIconClose">{context.icons.closeIcon}</div>
19
12
  </button>
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable react-hooks/exhaustive-deps */
2
- import React from 'react'
2
+ import React, { useMemo } from 'react'
3
3
  import { useCallback, useState, useEffect } from 'react'
4
4
  import { CopilotKit } from '@copilotkit/react-core'
5
5
  import { CopilotPopup } from '@copilotkit/react-ui'
@@ -13,16 +13,19 @@ import fetcher from '../../helpers/fetcher.js'
13
13
  export interface ChatProps {
14
14
  title: string
15
15
  runtimeUrl: string
16
- shopify_domain: string
16
+ shopifyDomain: string
17
17
  /** GA 的 client id
18
18
  */
19
- user_id: string
19
+ userId: string
20
20
  /** 是否登陆用户 0 or 1
21
21
  */
22
22
  account?: string
23
23
  /** 用户浏览器语言
24
24
  */
25
25
  locale?: string
26
+ /** 开场白
27
+ */
28
+ prologue?: string
26
29
  /** ?a=1&b=2
27
30
  */
28
31
  query?: string
@@ -39,21 +42,24 @@ export interface ChatProps {
39
42
  * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
40
43
  */
41
44
  gotocartRender?: string | ((_props: any) => React.ReactElement)
45
+ /** 打开购物车 action 的触发事件
46
+ */
47
+ addtocartHandler?: (_args: any) => Promise<any>
42
48
  /** 加购卡片,接受参数: {"status":"complete","args":[{"sku":["A3936031"],"handle":"space-a40-a3936031"}],"result":""}
43
49
  * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
44
50
  */
45
51
  addtocartRender?: string | ((_props: any) => React.ReactElement)
46
- /** 产品卡片,接受参数: {"status":"complete","args":[{"sku":["A3936031"],"handle":"space-a40-a3936031"}],"result":""}
47
- * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
48
- */
49
- productRender?: string | ((_props: any) => React.ReactElement)
50
52
  /** 订阅卡片,接受参数: {"status":"complete","args":[{"sku":["A3936031"],"handle":"space-a40-a3936031"}],"result":""}
51
53
  * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
52
54
  */
53
55
  signupRender?: string | ((_props: any) => React.ReactElement)
56
+ /** 产品卡片,接受参数: {"status":"complete","args":[{"sku":["A3936031"],"handle":"space-a40-a3936031"}],"result":""}
57
+ * 后端接口文档:https://anker-in.feishu.cn/wiki/DOYJwE9oxipWmYk072ncnJNznBb
58
+ */
59
+ productRender?: string | ((_props: any) => React.ReactElement)
54
60
  /** CopilotPopup 自定义参数,参考:https://docs.copilotkit.ai/reference/components/CopilotPopup */
55
61
  popup?: any
56
- /** 文案,{"popupTip": "Hi ! Welcome to soundcore Innovations live chat!", "popupTipTimeout": [3000, 6000]} */
62
+ /** 文案,{"productRenderTipMessage": "","popupTip": "Hi ! Welcome to soundcore Innovations live chat!", "popupTipTimeout": [3000, 6000]} */
57
63
  lang?: any
58
64
  /** 参考此文档:https://docs.copilotkit.ai/concepts/customize-look-and-feel */
59
65
  style?: any
@@ -65,9 +71,10 @@ const Chat = (props: ChatProps) => {
65
71
  title,
66
72
  runtimeUrl,
67
73
  popup,
68
- shopify_domain,
69
- user_id = '',
74
+ shopifyDomain,
75
+ userId = '',
70
76
  account = '',
77
+ prologue = '',
71
78
  locale = '',
72
79
  query = '',
73
80
  showResponseButton,
@@ -84,33 +91,43 @@ const Chat = (props: ChatProps) => {
84
91
 
85
92
  const [openTip, setOpenTip] = useState(false)
86
93
  const [openPopup, setOpenPopup] = useState(false)
87
- const [start, setstart] = useState('')
94
+ const [start, setstart] = useState(prologue)
88
95
  const [currentSuggestions, setCurrentSuggestions] = useState([])
89
96
  const [history, sethistory] = useState<[{ content: string; role: string }] | []>([])
90
97
 
98
+ const headers = useMemo(
99
+ () => ({
100
+ 'x-user-id': userId || '',
101
+ 'x-shopify-domain': shopifyDomain,
102
+ 'x-member-ship': account,
103
+ 'x-user-locale': locale,
104
+ }),
105
+ [userId, shopifyDomain, account, locale]
106
+ )
107
+
91
108
  const getStart = useCallback(async () => {
92
109
  const result = await fetcher({
93
110
  url: `${runtimeUrl}/copilotkit/start${query}`,
94
111
  method: 'GET',
95
- headers: { user_id: user_id || '', shopify_domain, account, locale },
112
+ headers,
96
113
  })
97
114
 
98
115
  setCurrentSuggestions(result?.suggested_questions?.map((item: string) => ({ message: item, title: item })) || [])
99
116
  setstart(result?.opening_statement || '')
100
117
  sethistory(result?.history || [])
101
- }, [user_id, shopify_domain, account, locale])
118
+ }, [userId, shopifyDomain, account, locale])
102
119
 
103
120
  const getSuggestions = useCallback(async () => {
104
121
  const result = await fetcher({
105
122
  url: `${runtimeUrl}/copilotkit/suggested_questions${query}`,
106
123
  method: 'GET',
107
- headers: { user_id: user_id || '', shopify_domain, account, locale },
124
+ headers,
108
125
  })
109
126
 
110
127
  setCurrentSuggestions(
111
128
  result?.suggested_questions?.data?.map((item: string) => ({ message: item, title: item })) || []
112
129
  )
113
- }, [user_id, shopify_domain, account, locale])
130
+ }, [userId, shopifyDomain, account, locale])
114
131
 
115
132
  const setOpenTipFn = () => {
116
133
  if (!openTip) setOpenTip(true)
@@ -129,20 +146,10 @@ const Chat = (props: ChatProps) => {
129
146
  }
130
147
  }, [])
131
148
 
132
- useEffect(() => {
133
- if (!start) {
134
- getStart()
135
- }
136
- }, [])
137
-
138
149
  return (
139
150
  <div className={className} style={style || {}}>
140
- {user_id && runtimeUrl && (
141
- <CopilotKit
142
- runtimeUrl={`${runtimeUrl}/copilotkit/chat${query}`}
143
- showDevConsole={false}
144
- headers={{ user_id: user_id || '', shopify_domain: shopify_domain, account, locale }}
145
- >
151
+ {userId && runtimeUrl && (
152
+ <CopilotKit runtimeUrl={`${runtimeUrl}/copilotkit/chat${query}`} showDevConsole={false} headers={headers}>
146
153
  <CopilotPopup
147
154
  {...popup}
148
155
  showResponseButton={showResponseButton !== 'follow'}
@@ -164,29 +171,30 @@ const Chat = (props: ChatProps) => {
164
171
  <Suggestions currentSuggestions={currentSuggestions} />
165
172
  </Messages>
166
173
  )}
167
- Button={({ open, setOpen }) => {
174
+ Button={({ open, setOpen: setOpenDefault }) => {
168
175
  const Button = popup?.Button || DefaultButton
169
176
  // eslint-disable-next-line react-hooks/rules-of-hooks
170
177
  useEffect(() => {
171
178
  setOpenPopup(open)
172
179
  }, [open])
180
+
181
+ // eslint-disable-next-line react-hooks/rules-of-hooks
182
+ const setOpen = useCallback(() => {
183
+ setOpenDefault(!open)
184
+ setOpenTip(false)
185
+ if (!start || !history?.length) getStart()
186
+ }, [start])
187
+
173
188
  return (
174
189
  <>
175
190
  {lang?.popupTip && openTip && !openPopup && (
176
191
  <div className="copilotKitPopup copilotKitPopupTip">
177
- <button
178
- onClick={() => {
179
- setOpen(true)
180
- setOpenTip(false)
181
- }}
182
- aria-label="Open Chat"
183
- className="copilotKitPopupTipContent"
184
- >
192
+ <button onClick={setOpen} aria-label="Open Chat" className="copilotKitPopupTipContent">
185
193
  {lang?.popupTip}
186
194
  </button>
187
195
  </div>
188
196
  )}
189
- <Button open={open} setOpen={setOpen} setOpenTip={setOpenTip} />
197
+ <Button open={open} setOpen={setOpen} />
190
198
  </>
191
199
  )
192
200
  }}
@@ -199,6 +207,7 @@ const Chat = (props: ChatProps) => {
199
207
  addtocartRender={addtocartRender}
200
208
  productRender={productRender}
201
209
  signupRender={signupRender}
210
+ productRenderTipMessage={lang?.productRenderTipMessage}
202
211
  />
203
212
  </CopilotPopup>
204
213
  </CopilotKit>
@@ -3,8 +3,7 @@ import { Message } from '@copilotkit/runtime-client-gql'
3
3
 
4
4
  export interface ButtonProps {
5
5
  open: boolean
6
- setOpen: (open: boolean) => void
7
- setOpenTip: (open: boolean) => void
6
+ setOpen: () => void
8
7
  }
9
8
 
10
9
  export interface WindowProps {
@@ -12,8 +12,8 @@ const meta: Meta<typeof Chat> = {
12
12
  component: Chat,
13
13
  args: {
14
14
  title: 'DTC Live Chat',
15
- runtimeUrl: 'https://beta-dtcapi.anker.com',
16
- shopify_domain: 'soundcoreusa.myshopify.com',
15
+ runtimeUrl: 'https://beta-api-livechat.anker.com',
16
+ shopifyDomain: 'soundcoreusa.myshopify.com',
17
17
  },
18
18
  // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
19
19
  tags: ['autodocs'],
@@ -32,9 +32,9 @@ export default meta
32
32
  export const Default: Story = {
33
33
  args: {
34
34
  title: 'DTC Live Chat',
35
- runtimeUrl: 'https://beta-dtcapi.anker.com',
36
- shopify_domain: 'soundcoreusa.myshopify.com',
37
- user_id: 'arno6',
35
+ runtimeUrl: 'https://beta-api-livechat.anker.com',
36
+ shopifyDomain: 'soundcoreusa.myshopify.com',
37
+ userId: 'arno7',
38
38
  showResponseButton: 'follow',
39
39
  lang: { popupTip: 'Hi ! Welcome to soundcore Innovations live chat!', popupTipTimeout: [3000, 6000] },
40
40
  },