@asgard-js/react 0.0.43-canary.2 → 0.0.43-canary.21
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/dist/components/chatbot/api-key-input/api-key-input.d.ts +2 -1
- package/dist/components/chatbot/api-key-input/api-key-input.d.ts.map +1 -1
- package/dist/components/chatbot/chatbot.d.ts +1 -1
- package/dist/components/chatbot/chatbot.d.ts.map +1 -1
- package/dist/context/asgard-theme-context.d.ts +2 -0
- package/dist/context/asgard-theme-context.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20859 -19002
- package/dist/style.css +1 -1
- package/dist/types/auth.d.ts +2 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/.DS_Store +0 -0
- package/src/components/chatbot/api-key-input/api-key-input.module.scss +35 -44
- package/src/components/chatbot/api-key-input/api-key-input.tsx +32 -34
- package/src/components/chatbot/chatbot.tsx +21 -3
- package/src/context/asgard-theme-context.tsx +7 -0
- package/src/icons/eye-off.svg +4 -0
- package/src/icons/eye.svg +4 -0
- package/src/index.ts +1 -0
- package/src/types/auth.ts +1 -0
- package/src/types/index.ts +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/types/auth.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,eAAe,GAAG,OAAO,GAAG,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC"}
|
package/package.json
CHANGED
package/src/components/.DS_Store
CHANGED
|
Binary file
|
|
@@ -1,52 +1,51 @@
|
|
|
1
|
-
.
|
|
1
|
+
.api_key_input {
|
|
2
2
|
width: 220px;
|
|
3
3
|
background-color: var(--asg-color-bg);
|
|
4
4
|
border-radius: 12px;
|
|
5
|
-
padding: 20px;
|
|
5
|
+
padding: 12px 20px;
|
|
6
6
|
border: 0.5px solid var(--asg-color-border);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.form {
|
|
9
|
+
.api_key_input__header {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
gap: 4px;
|
|
13
|
+
align-items: center;
|
|
14
|
+
margin-bottom: 12px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.api_key_input__icon {
|
|
18
|
+
width: 24px;
|
|
19
|
+
height: 24px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.api_key_input__title {
|
|
23
|
+
margin: 0;
|
|
24
|
+
font-size: 18px;
|
|
25
|
+
font-weight: 500;
|
|
26
|
+
color: white;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.api_key_input__form {
|
|
31
30
|
width: 100%;
|
|
32
31
|
display: flex;
|
|
33
32
|
flex-direction: column;
|
|
34
33
|
gap: 20px;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
|
-
.
|
|
36
|
+
.api_key_input__label {
|
|
38
37
|
display: block;
|
|
39
38
|
font-size: 14px;
|
|
40
39
|
color: rgba(255, 255, 255, 0.7);
|
|
41
40
|
margin-bottom: 8px;
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
.
|
|
43
|
+
.api_key_input__input_wrapper {
|
|
45
44
|
position: relative;
|
|
46
45
|
width: 100%;
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
.
|
|
48
|
+
.api_key_input__input {
|
|
50
49
|
width: 100%;
|
|
51
50
|
height: 42px;
|
|
52
51
|
padding: 0 40px 0 12px;
|
|
@@ -69,18 +68,18 @@
|
|
|
69
68
|
background: rgba(255, 255, 255, 0.08);
|
|
70
69
|
}
|
|
71
70
|
|
|
72
|
-
|
|
71
|
+
&--error {
|
|
73
72
|
border-color: rgba(255, 69, 58, 0.6);
|
|
74
73
|
background: rgba(255, 69, 58, 0.05);
|
|
75
74
|
}
|
|
76
75
|
|
|
77
|
-
|
|
76
|
+
&--disabled {
|
|
78
77
|
opacity: 0.5;
|
|
79
78
|
cursor: not-allowed;
|
|
80
79
|
}
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
.
|
|
82
|
+
.api_key_input__toggle_button {
|
|
84
83
|
position: absolute;
|
|
85
84
|
right: 8px;
|
|
86
85
|
top: 50%;
|
|
@@ -107,23 +106,23 @@
|
|
|
107
106
|
}
|
|
108
107
|
}
|
|
109
108
|
|
|
110
|
-
.
|
|
109
|
+
.api_key_input__toggle_icon {
|
|
111
110
|
width: 16px;
|
|
112
111
|
height: 16px;
|
|
113
112
|
}
|
|
114
113
|
|
|
115
|
-
.
|
|
114
|
+
.api_key_input__error_message {
|
|
116
115
|
margin-top: 6px;
|
|
117
116
|
font-size: 12px;
|
|
118
117
|
color: rgba(255, 69, 58, 0.8);
|
|
119
118
|
}
|
|
120
119
|
|
|
121
|
-
.
|
|
120
|
+
.api_key_input__submit_button {
|
|
122
121
|
width: 100%;
|
|
123
122
|
height: 42px;
|
|
124
|
-
background: #5856d6;
|
|
125
123
|
border: none;
|
|
126
124
|
border-radius: 6px;
|
|
125
|
+
background-color: #5856d6;
|
|
127
126
|
color: white;
|
|
128
127
|
font-size: 14px;
|
|
129
128
|
font-weight: 500;
|
|
@@ -131,14 +130,6 @@
|
|
|
131
130
|
transition: all 0.2s ease;
|
|
132
131
|
outline: none;
|
|
133
132
|
|
|
134
|
-
&:hover:not(:disabled) {
|
|
135
|
-
background: #4845c7;
|
|
136
|
-
transform: translateY(-1px);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
&:active:not(:disabled) {
|
|
140
|
-
transform: translateY(0);
|
|
141
|
-
}
|
|
142
133
|
|
|
143
134
|
&:disabled {
|
|
144
135
|
opacity: 0.5;
|
|
@@ -146,7 +137,7 @@
|
|
|
146
137
|
transform: none;
|
|
147
138
|
}
|
|
148
139
|
|
|
149
|
-
|
|
140
|
+
&--loading {
|
|
150
141
|
position: relative;
|
|
151
142
|
color: transparent;
|
|
152
143
|
|
|
@@ -178,7 +169,7 @@
|
|
|
178
169
|
|
|
179
170
|
// 響應式設計
|
|
180
171
|
@media (max-width: 280px) {
|
|
181
|
-
.
|
|
172
|
+
.api_key_input {
|
|
182
173
|
width: 100%;
|
|
183
174
|
min-width: 200px;
|
|
184
175
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { useState, FormEvent, ChangeEvent } from 'react';
|
|
2
2
|
import clsx from 'clsx';
|
|
3
3
|
import { useAsgardThemeContext } from '../../../context/asgard-theme-context';
|
|
4
|
+
import { useAsgardContext } from '../../../context/asgard-service-context';
|
|
5
|
+
import { ProfileIcon } from '../profile-icon';
|
|
6
|
+
import EyeSvg from '../../../icons/eye.svg?react';
|
|
7
|
+
import EyeOffSvg from '../../../icons/eye-off.svg?react';
|
|
4
8
|
import styles from './api-key-input.module.scss';
|
|
5
9
|
|
|
6
10
|
export interface ApiKeyInputProps {
|
|
@@ -8,6 +12,7 @@ export interface ApiKeyInputProps {
|
|
|
8
12
|
loading?: boolean;
|
|
9
13
|
error?: string;
|
|
10
14
|
placeholder?: string;
|
|
15
|
+
title?: string;
|
|
11
16
|
showToggle?: boolean;
|
|
12
17
|
className?: string;
|
|
13
18
|
}
|
|
@@ -17,12 +22,14 @@ export function ApiKeyInput({
|
|
|
17
22
|
loading = false,
|
|
18
23
|
error,
|
|
19
24
|
placeholder = 'Enter your key',
|
|
25
|
+
title = 'Preview',
|
|
20
26
|
showToggle = true,
|
|
21
27
|
className,
|
|
22
28
|
}: ApiKeyInputProps): JSX.Element {
|
|
23
29
|
const [apiKey, setApiKey] = useState('');
|
|
24
30
|
const [showPassword, setShowPassword] = useState(false);
|
|
25
31
|
const { chatbot } = useAsgardThemeContext();
|
|
32
|
+
const { avatar } = useAsgardContext();
|
|
26
33
|
|
|
27
34
|
const handleSubmit = (e: FormEvent): void => {
|
|
28
35
|
e.preventDefault();
|
|
@@ -41,24 +48,29 @@ export function ApiKeyInput({
|
|
|
41
48
|
|
|
42
49
|
return (
|
|
43
50
|
<div
|
|
44
|
-
className={clsx(styles.
|
|
51
|
+
className={clsx(styles.api_key_input, className)}
|
|
45
52
|
style={{
|
|
46
53
|
backgroundColor: chatbot.backgroundColor,
|
|
47
54
|
borderColor: chatbot.borderColor,
|
|
48
55
|
}}
|
|
49
56
|
>
|
|
50
|
-
<
|
|
57
|
+
<div className={styles.api_key_input__header}>
|
|
58
|
+
<ProfileIcon avatar={avatar} />
|
|
59
|
+
<h2 className={styles.api_key_input__title} style={chatbot?.header?.title?.style}>{title}</h2>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<form onSubmit={handleSubmit} className={styles.api_key_input__form}>
|
|
51
63
|
<div className={styles.inputGroup}>
|
|
52
|
-
<label className={styles.
|
|
53
|
-
<div className={styles.
|
|
64
|
+
<label className={styles.api_key_input__label}>Key</label>
|
|
65
|
+
<div className={styles.api_key_input__input_wrapper}>
|
|
54
66
|
<input
|
|
55
67
|
type={showPassword ? 'text' : 'password'}
|
|
56
68
|
value={apiKey}
|
|
57
69
|
onChange={handleInputChange}
|
|
58
70
|
placeholder={placeholder}
|
|
59
|
-
className={clsx(styles.
|
|
60
|
-
[styles
|
|
61
|
-
[styles
|
|
71
|
+
className={clsx(styles.api_key_input__input, {
|
|
72
|
+
[styles['api_key_input__input--error']]: error,
|
|
73
|
+
[styles['api_key_input__input--disabled']]: loading,
|
|
62
74
|
})}
|
|
63
75
|
disabled={loading}
|
|
64
76
|
autoComplete="off"
|
|
@@ -67,45 +79,31 @@ export function ApiKeyInput({
|
|
|
67
79
|
<button
|
|
68
80
|
type="button"
|
|
69
81
|
onClick={togglePasswordVisibility}
|
|
70
|
-
className={styles.
|
|
82
|
+
className={styles.api_key_input__toggle_button}
|
|
71
83
|
disabled={loading}
|
|
72
84
|
aria-label={showPassword ? 'Hide password' : 'Show password'}
|
|
73
85
|
>
|
|
74
|
-
|
|
75
|
-
className={styles.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
fill="none"
|
|
80
|
-
stroke="currentColor"
|
|
81
|
-
strokeWidth="2"
|
|
82
|
-
strokeLinecap="round"
|
|
83
|
-
strokeLinejoin="round"
|
|
84
|
-
>
|
|
85
|
-
{showPassword ? (
|
|
86
|
-
<>
|
|
87
|
-
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" />
|
|
88
|
-
<line x1="1" y1="1" x2="23" y2="23" />
|
|
89
|
-
</>
|
|
90
|
-
) : (
|
|
91
|
-
<>
|
|
92
|
-
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
|
|
93
|
-
<circle cx="12" cy="12" r="3" />
|
|
94
|
-
</>
|
|
95
|
-
)}
|
|
96
|
-
</svg>
|
|
86
|
+
{showPassword ? (
|
|
87
|
+
<EyeOffSvg className={styles.api_key_input__toggle_icon} />
|
|
88
|
+
) : (
|
|
89
|
+
<EyeSvg className={styles.api_key_input__toggle_icon} />
|
|
90
|
+
)}
|
|
97
91
|
</button>
|
|
98
92
|
)}
|
|
99
93
|
</div>
|
|
100
|
-
{error && <div className={styles.
|
|
94
|
+
{error && <div className={styles.api_key_input__error_message}>{error}</div>}
|
|
101
95
|
</div>
|
|
102
96
|
|
|
103
97
|
<button
|
|
104
98
|
type="submit"
|
|
105
99
|
disabled={!apiKey.trim() || loading}
|
|
106
|
-
className={clsx(styles.
|
|
107
|
-
[styles
|
|
100
|
+
className={clsx(styles.api_key_input__submit_button, {
|
|
101
|
+
[styles['api_key_input__submit_button--loading']]: loading,
|
|
108
102
|
})}
|
|
103
|
+
style={{
|
|
104
|
+
backgroundColor: chatbot?.mainColor,
|
|
105
|
+
color: chatbot?.secondaryColor,
|
|
106
|
+
}}
|
|
109
107
|
>
|
|
110
108
|
{loading ? 'Loading...' : 'Continue'}
|
|
111
109
|
</button>
|
|
@@ -17,14 +17,13 @@ import {
|
|
|
17
17
|
AsgardAppInitializationContextProvider,
|
|
18
18
|
AsgardServiceContextProviderProps,
|
|
19
19
|
} from '../../context';
|
|
20
|
+
import { AuthState } from '../../types';
|
|
20
21
|
import { ApiKeyInput } from './api-key-input';
|
|
21
22
|
import { ChatbotHeader } from './chatbot-header';
|
|
22
23
|
import { ChatbotBody } from './chatbot-body';
|
|
23
24
|
import { ChatbotFooter } from './chatbot-footer';
|
|
24
25
|
import { ChatbotContainer } from './chatbot-container/chatbot-container';
|
|
25
26
|
|
|
26
|
-
type AuthState = 'loading' | 'needApiKey' | 'authenticated' | 'error';
|
|
27
|
-
|
|
28
27
|
interface ChatbotProps extends AsgardTemplateContextValue {
|
|
29
28
|
className?: string;
|
|
30
29
|
style?: CSSProperties;
|
|
@@ -116,8 +115,27 @@ export const Chatbot = forwardRef(function Chatbot(
|
|
|
116
115
|
padding: '20px'
|
|
117
116
|
}}>
|
|
118
117
|
<ApiKeyInput
|
|
118
|
+
title={title}
|
|
119
|
+
onSubmit={onApiKeySubmit || (() => {})}
|
|
120
|
+
placeholder="Enter your key"
|
|
121
|
+
/>
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
case 'invalidApiKey':
|
|
126
|
+
return (
|
|
127
|
+
<div style={{
|
|
128
|
+
display: 'flex',
|
|
129
|
+
alignItems: 'center',
|
|
130
|
+
justifyContent: 'center',
|
|
131
|
+
flex: 1,
|
|
132
|
+
padding: '20px'
|
|
133
|
+
}}>
|
|
134
|
+
<ApiKeyInput
|
|
135
|
+
title={title}
|
|
119
136
|
onSubmit={onApiKeySubmit || (() => {})}
|
|
120
137
|
placeholder="Enter your key"
|
|
138
|
+
error="Please check if the key is correct."
|
|
121
139
|
/>
|
|
122
140
|
</div>
|
|
123
141
|
);
|
|
@@ -158,7 +176,7 @@ export const Chatbot = forwardRef(function Chatbot(
|
|
|
158
176
|
};
|
|
159
177
|
|
|
160
178
|
// Don't initialize SSE connection when explicitly needing API key or in error state
|
|
161
|
-
if (authState !== 'needApiKey' && authState !== 'error') {
|
|
179
|
+
if (authState !== 'needApiKey' && authState !== 'error' && authState !== 'invalidApiKey') {
|
|
162
180
|
return (
|
|
163
181
|
<AsgardAppInitializationContextProvider
|
|
164
182
|
enabled={enableLoadConfigFromService}
|
|
@@ -31,6 +31,8 @@ export interface AsgardThemeContextValue {
|
|
|
31
31
|
backgroundColor?: CSSProperties['backgroundColor'];
|
|
32
32
|
borderColor?: CSSProperties['borderColor'];
|
|
33
33
|
inactiveColor?: CSSProperties['color'];
|
|
34
|
+
mainColor?: CSSProperties['color'];
|
|
35
|
+
secondaryColor?: CSSProperties['color'];
|
|
34
36
|
primaryComponent?: {
|
|
35
37
|
mainColor?: CSSProperties['color'];
|
|
36
38
|
secondaryColor?: CSSProperties['color'];
|
|
@@ -267,6 +269,9 @@ export function AsgardThemeContextProvider(
|
|
|
267
269
|
chatbot: {
|
|
268
270
|
backgroundColor: themeFromAnnotations.chatbot?.backgroundColor,
|
|
269
271
|
borderColor: themeFromAnnotations.chatbot?.borderColor,
|
|
272
|
+
mainColor: themeFromAnnotations.chatbot?.primaryComponent?.mainColor,
|
|
273
|
+
secondaryColor: themeFromAnnotations.chatbot?.primaryComponent?.secondaryColor,
|
|
274
|
+
|
|
270
275
|
header: {
|
|
271
276
|
style: {
|
|
272
277
|
borderBottomColor: themeFromAnnotations.chatbot?.borderColor,
|
|
@@ -407,6 +412,8 @@ export function AsgardThemeContextProvider(
|
|
|
407
412
|
chatbot: {
|
|
408
413
|
backgroundColor: propsTheme.chatbot?.backgroundColor,
|
|
409
414
|
borderColor: propsTheme.chatbot?.borderColor,
|
|
415
|
+
mainColor: propsTheme.chatbot?.primaryComponent?.mainColor,
|
|
416
|
+
secondaryColor: propsTheme.chatbot?.primaryComponent?.secondaryColor,
|
|
410
417
|
header: {
|
|
411
418
|
style: {
|
|
412
419
|
borderBottomColor: propsTheme.chatbot?.borderColor,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
2
|
+
<path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"/>
|
|
3
|
+
<line x1="1" y1="1" x2="23" y2="23"/>
|
|
4
|
+
</svg>
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type AuthState = 'loading' | 'needApiKey' | 'authenticated' | 'error' | 'invalidApiKey';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './auth';
|