@agrid/agrid-react-native 4.12.11
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 +691 -0
- package/dist/AgridContext.d.ts +5 -0
- package/dist/AgridContext.js +1 -0
- package/dist/AgridContext.js.map +1 -0
- package/dist/AgridProvider.d.ts +86 -0
- package/dist/AgridProvider.js +1 -0
- package/dist/AgridProvider.js.map +1 -0
- package/dist/agrid-rn.d.ts +612 -0
- package/dist/agrid-rn.js +1 -0
- package/dist/agrid-rn.js.map +1 -0
- package/dist/autocapture.d.ts +4 -0
- package/dist/autocapture.js +1 -0
- package/dist/autocapture.js.map +1 -0
- package/dist/error-tracking/index.d.ts +27 -0
- package/dist/error-tracking/index.js +1 -0
- package/dist/error-tracking/index.js.map +1 -0
- package/dist/error-tracking/utils.d.ts +5 -0
- package/dist/error-tracking/utils.js +1 -0
- package/dist/error-tracking/utils.js.map +1 -0
- package/dist/frameworks/wix-navigation.d.ts +3 -0
- package/dist/frameworks/wix-navigation.js +1 -0
- package/dist/frameworks/wix-navigation.js.map +1 -0
- package/dist/hooks/useAgrid.d.ts +2 -0
- package/dist/hooks/useAgrid.js +1 -0
- package/dist/hooks/useAgrid.js.map +1 -0
- package/dist/hooks/useFeatureFlag.d.ts +5 -0
- package/dist/hooks/useFeatureFlag.js +1 -0
- package/dist/hooks/useFeatureFlag.js.map +1 -0
- package/dist/hooks/useFeatureFlags.d.ts +3 -0
- package/dist/hooks/useFeatureFlags.js +1 -0
- package/dist/hooks/useFeatureFlags.js.map +1 -0
- package/dist/hooks/useNavigationTracker.d.ts +6 -0
- package/dist/hooks/useNavigationTracker.js +1 -0
- package/dist/hooks/useNavigationTracker.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/native-deps.d.ts +4 -0
- package/dist/native-deps.js +1 -0
- package/dist/native-deps.js.map +1 -0
- package/dist/optional/OptionalAsyncStorage.d.ts +2 -0
- package/dist/optional/OptionalAsyncStorage.js +1 -0
- package/dist/optional/OptionalAsyncStorage.js.map +1 -0
- package/dist/optional/OptionalExpoApplication.d.ts +2 -0
- package/dist/optional/OptionalExpoApplication.js +1 -0
- package/dist/optional/OptionalExpoApplication.js.map +1 -0
- package/dist/optional/OptionalExpoDevice.d.ts +2 -0
- package/dist/optional/OptionalExpoDevice.js +1 -0
- package/dist/optional/OptionalExpoDevice.js.map +1 -0
- package/dist/optional/OptionalExpoFileSystem.d.ts +2 -0
- package/dist/optional/OptionalExpoFileSystem.js +1 -0
- package/dist/optional/OptionalExpoFileSystem.js.map +1 -0
- package/dist/optional/OptionalExpoFileSystemLegacy.d.ts +2 -0
- package/dist/optional/OptionalExpoFileSystemLegacy.js +1 -0
- package/dist/optional/OptionalExpoFileSystemLegacy.js.map +1 -0
- package/dist/optional/OptionalExpoLocalization.d.ts +2 -0
- package/dist/optional/OptionalExpoLocalization.js +1 -0
- package/dist/optional/OptionalExpoLocalization.js.map +1 -0
- package/dist/optional/OptionalReactNativeDeviceInfo.d.ts +2 -0
- package/dist/optional/OptionalReactNativeDeviceInfo.js +1 -0
- package/dist/optional/OptionalReactNativeDeviceInfo.js.map +1 -0
- package/dist/optional/OptionalReactNativeLocalize.d.ts +13 -0
- package/dist/optional/OptionalReactNativeLocalize.js +1 -0
- package/dist/optional/OptionalReactNativeLocalize.js.map +1 -0
- package/dist/optional/OptionalReactNativeNavigation.d.ts +2 -0
- package/dist/optional/OptionalReactNativeNavigation.js +1 -0
- package/dist/optional/OptionalReactNativeNavigation.js.map +1 -0
- package/dist/optional/OptionalReactNativeNavigationWix.d.ts +2 -0
- package/dist/optional/OptionalReactNativeNavigationWix.js +1 -0
- package/dist/optional/OptionalReactNativeNavigationWix.js.map +1 -0
- package/dist/optional/OptionalReactNativeSafeArea.d.ts +2 -0
- package/dist/optional/OptionalReactNativeSafeArea.js +1 -0
- package/dist/optional/OptionalReactNativeSafeArea.js.map +1 -0
- package/dist/optional/OptionalSessionReplay.d.ts +2 -0
- package/dist/optional/OptionalSessionReplay.js +1 -0
- package/dist/optional/OptionalSessionReplay.js.map +1 -0
- package/dist/storage.d.ts +21 -0
- package/dist/storage.js +1 -0
- package/dist/storage.js.map +1 -0
- package/dist/surveys/AgridSurveyProvider.d.ts +16 -0
- package/dist/surveys/AgridSurveyProvider.js +1 -0
- package/dist/surveys/AgridSurveyProvider.js.map +1 -0
- package/dist/surveys/components/BottomSection.d.ts +8 -0
- package/dist/surveys/components/BottomSection.js +1 -0
- package/dist/surveys/components/BottomSection.js.map +1 -0
- package/dist/surveys/components/Cancel.d.ts +5 -0
- package/dist/surveys/components/Cancel.js +1 -0
- package/dist/surveys/components/Cancel.js.map +1 -0
- package/dist/surveys/components/ConfirmationMessage.d.ts +12 -0
- package/dist/surveys/components/ConfirmationMessage.js +1 -0
- package/dist/surveys/components/ConfirmationMessage.js.map +1 -0
- package/dist/surveys/components/QuestionHeader.d.ts +6 -0
- package/dist/surveys/components/QuestionHeader.js +1 -0
- package/dist/surveys/components/QuestionHeader.js.map +1 -0
- package/dist/surveys/components/QuestionTypes.d.ts +26 -0
- package/dist/surveys/components/QuestionTypes.js +1 -0
- package/dist/surveys/components/QuestionTypes.js.map +1 -0
- package/dist/surveys/components/SurveyModal.d.ts +9 -0
- package/dist/surveys/components/SurveyModal.js +1 -0
- package/dist/surveys/components/SurveyModal.js.map +1 -0
- package/dist/surveys/components/Surveys.d.ts +13 -0
- package/dist/surveys/components/Surveys.js +1 -0
- package/dist/surveys/components/Surveys.js.map +1 -0
- package/dist/surveys/getActiveMatchingSurveys.d.ts +2 -0
- package/dist/surveys/getActiveMatchingSurveys.js +1 -0
- package/dist/surveys/getActiveMatchingSurveys.js.map +1 -0
- package/dist/surveys/icons.d.ts +8 -0
- package/dist/surveys/icons.js +1 -0
- package/dist/surveys/icons.js.map +1 -0
- package/dist/surveys/index.d.ts +6 -0
- package/dist/surveys/index.js +1 -0
- package/dist/surveys/index.js.map +1 -0
- package/dist/surveys/surveys-utils.d.ts +30 -0
- package/dist/surveys/surveys-utils.js +1 -0
- package/dist/surveys/surveys-utils.js.map +1 -0
- package/dist/surveys/useActivatedSurveys.d.ts +3 -0
- package/dist/surveys/useActivatedSurveys.js +1 -0
- package/dist/surveys/useActivatedSurveys.js.map +1 -0
- package/dist/surveys/useSurveyStorage.d.ts +8 -0
- package/dist/surveys/useSurveyStorage.js +1 -0
- package/dist/surveys/useSurveyStorage.js.map +1 -0
- package/dist/tooling/agridMetroSerializer.d.ts +17 -0
- package/dist/tooling/agridMetroSerializer.js +1 -0
- package/dist/tooling/agridMetroSerializer.js.map +1 -0
- package/dist/tooling/metroconfig.d.ts +15 -0
- package/dist/tooling/metroconfig.js +1 -0
- package/dist/tooling/metroconfig.js.map +1 -0
- package/dist/tooling/utils.d.ts +58 -0
- package/dist/tooling/utils.js +1 -0
- package/dist/tooling/utils.js.map +1 -0
- package/dist/tooling/vendor/expo/expoconfig.d.ts +23 -0
- package/dist/tooling/vendor/expo/expoconfig.js +1 -0
- package/dist/tooling/vendor/expo/expoconfig.js.map +1 -0
- package/dist/tooling/vendor/metro/countLines.d.ts +2 -0
- package/dist/tooling/vendor/metro/countLines.js +1 -0
- package/dist/tooling/vendor/metro/countLines.js.map +1 -0
- package/dist/tooling/vendor/metro/utils.d.ts +22 -0
- package/dist/tooling/vendor/metro/utils.js +1 -0
- package/dist/tooling/vendor/metro/utils.js.map +1 -0
- package/dist/types.d.ts +150 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +20 -0
- package/dist/utils.js +1 -0
- package/dist/utils.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +1 -0
- package/dist/version.js.map +1 -0
- package/package.json +134 -0
- package/tooling/agrid-xcode.sh +111 -0
- package/tooling/agrid.gradle +312 -0
package/README.md
ADDED
|
@@ -0,0 +1,691 @@
|
|
|
1
|
+
# Hướng dẫn tích hợp thư viện Agrid React Native cho các ứng dụng React Native
|
|
2
|
+
|
|
3
|
+
Thư viện Agrid React Native cho phép bạn tích hợp analytics vào ứng dụng React Native của mình. Thư viện này được xây dựng dựa trên PostHog và hỗ trợ đầy đủ cho ứng dụng React Native.
|
|
4
|
+
|
|
5
|
+
## Mục lục
|
|
6
|
+
|
|
7
|
+
1. [Cài đặt](#1-cài-đặt)
|
|
8
|
+
2. [Thông tin mặc định](#2-thông-tin-mặc-định)
|
|
9
|
+
3. [Cấu hình](#3-cấu-hình)
|
|
10
|
+
4. [Ghi nhận sự kiện](#4-ghi-nhận-sự-kiện)
|
|
11
|
+
5. [Tự động ghi nhận (Autocapture)](#5-tự-động-ghi-nhận-autocapture)
|
|
12
|
+
6. [Nhận diện người dùng](#6-nhận-diện-người-dùng)
|
|
13
|
+
7. [Super Properties](#7-super-properties)
|
|
14
|
+
8. [Feature Flags](#8-feature-flags)
|
|
15
|
+
9. [Tùy chọn nâng cao](#9-tùy-chọn-nâng-cao)
|
|
16
|
+
10. [Session Replay](#10-session-replay)
|
|
17
|
+
11. [Error Tracking](#11-error-tracking)
|
|
18
|
+
12. [Surveys](#12-surveys)
|
|
19
|
+
13. [Ví dụ hoàn chỉnh](#13-ví-dụ-hoàn-chỉnh)
|
|
20
|
+
14. [Liên hệ & Hỗ trợ](#14-liên-hệ--hỗ-trợ)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 1. Cài đặt
|
|
25
|
+
|
|
26
|
+
### Ứng dụng React Native
|
|
27
|
+
|
|
28
|
+
Chạy lệnh sau để cài đặt các gói cần thiết:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
yarn add @agrid/agrid-react-native @react-native-async-storage/async-storage react-native-device-info react-native-localize
|
|
32
|
+
# hoặc
|
|
33
|
+
npm i -s @agrid/agrid-react-native @react-native-async-storage/async-storage react-native-device-info react-native-localize
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Đối với iOS, cần chạy thêm lệnh sau để cài đặt CocoaPods:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
bundle install
|
|
40
|
+
cd ios && pod install && cd ..
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 2. Thông tin mặc định
|
|
46
|
+
|
|
47
|
+
Để bắt đầu nhanh, bạn có thể sử dụng các giá trị mặc định sau:
|
|
48
|
+
|
|
49
|
+
- **Host mặc định**: `https://gw.track-asia.vn`
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 3. Cấu hình
|
|
54
|
+
|
|
55
|
+
### Cấu hình cơ bản
|
|
56
|
+
|
|
57
|
+
Có hai cách để khởi tạo Agrid trong ứng dụng của bạn:
|
|
58
|
+
|
|
59
|
+
#### Cách 1: Sử dụng AgridProvider (Khuyến nghị)
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
import { AgridProvider } from '@agrid/agrid-react-native'
|
|
63
|
+
|
|
64
|
+
export function App() {
|
|
65
|
+
return (
|
|
66
|
+
<AgridProvider
|
|
67
|
+
apiKey="<your_api_key>"
|
|
68
|
+
options={{
|
|
69
|
+
host: 'https://gw.track-asia.vn',
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
{/* Phần còn lại của ứng dụng */}
|
|
73
|
+
</AgridProvider>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
#### Cách 2: Khởi tạo thủ công
|
|
79
|
+
|
|
80
|
+
```tsx
|
|
81
|
+
// agrid.ts
|
|
82
|
+
import Agrid from '@agrid/agrid-react-native'
|
|
83
|
+
|
|
84
|
+
export const agrid = new Agrid('<your_api_key>', {
|
|
85
|
+
host: 'https://gw.track-asia.vn',
|
|
86
|
+
})
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Các tùy chọn cấu hình
|
|
90
|
+
|
|
91
|
+
| Tùy chọn | Mô tả | Giá trị mặc định |
|
|
92
|
+
|----------|-------|------------------|
|
|
93
|
+
| `host` | URL của Agrid instance | `https://gw.track-asia.vn` |
|
|
94
|
+
| `flushAt` | Số lượng sự kiện trước khi tự động gửi | `20` |
|
|
95
|
+
| `flushInterval` | Khoảng thời gian (ms) giữa các lần gửi | `10000` |
|
|
96
|
+
| `maxBatchSize` | Số lượng sự kiện tối đa trong một batch | `100` |
|
|
97
|
+
| `maxQueueSize` | Số lượng sự kiện tối đa trong hàng đợi | `1000` |
|
|
98
|
+
| `disabled` | Vô hiệu hóa tracking | `false` |
|
|
99
|
+
| `defaultOptIn` | Người dùng mặc định opt-in tracking | `true` |
|
|
100
|
+
| `captureAppLifecycleEvents` | Tự động ghi nhận vòng đời app | `false` |
|
|
101
|
+
| `persistence` | Loại lưu trữ: `'file'` hoặc `'memory'` | `'file'` |
|
|
102
|
+
| `customStorage` | Custom storage implementation | `null` |
|
|
103
|
+
| `enableSessionReplay` | Bật Session Replay | `false` |
|
|
104
|
+
| `sessionReplayConfig` | Cấu hình Session Replay | `null` |
|
|
105
|
+
|
|
106
|
+
### Ví dụ cấu hình đầy đủ
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
<AgridProvider
|
|
110
|
+
apiKey="<your_api_key>"
|
|
111
|
+
options={{
|
|
112
|
+
host: 'https://gw.track-asia.vn',
|
|
113
|
+
captureAppLifecycleEvents: true, // Tự động track app lifecycle
|
|
114
|
+
flushAt: 10,
|
|
115
|
+
flushInterval: 5000,
|
|
116
|
+
persistence: 'file',
|
|
117
|
+
}}
|
|
118
|
+
>
|
|
119
|
+
{/* App content */}
|
|
120
|
+
</AgridProvider>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 4. Ghi nhận sự kiện
|
|
126
|
+
|
|
127
|
+
### Ghi nhận sự kiện tùy chỉnh
|
|
128
|
+
|
|
129
|
+
Sử dụng phương thức `capture` để ghi nhận sự kiện:
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
import { useAgrid } from '@agrid/agrid-react-native'
|
|
133
|
+
|
|
134
|
+
function MyComponent() {
|
|
135
|
+
const agrid = useAgrid()
|
|
136
|
+
|
|
137
|
+
const handleButtonPress = () => {
|
|
138
|
+
agrid?.capture('button_clicked', {
|
|
139
|
+
button_name: 'sign_up',
|
|
140
|
+
screen: 'home',
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return <Button onPress={handleButtonPress} title="Sign Up" />
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
> **💡 Mẹo:** Chúng tôi khuyến nghị sử dụng định dạng `[đối tượng] [hành động]` cho tên sự kiện, ví dụ: `user_signed_up`, `project_created`, `invite_sent`.
|
|
149
|
+
|
|
150
|
+
### Thiết lập thuộc tính sự kiện
|
|
151
|
+
|
|
152
|
+
Bạn có thể thêm thuộc tính bổ sung cho sự kiện:
|
|
153
|
+
|
|
154
|
+
```tsx
|
|
155
|
+
agrid?.capture('purchase_completed', {
|
|
156
|
+
product_id: '12345',
|
|
157
|
+
price: 99.99,
|
|
158
|
+
currency: 'USD',
|
|
159
|
+
category: 'electronics',
|
|
160
|
+
})
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Ghi nhận màn hình (Screen Views)
|
|
164
|
+
|
|
165
|
+
#### Tự động với useEffect
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
import { useEffect, useState } from 'react'
|
|
169
|
+
import { useAgrid } from '@agrid/agrid-react-native'
|
|
170
|
+
|
|
171
|
+
function AppContent() {
|
|
172
|
+
const [activeScreen, setActiveScreen] = useState('HOME')
|
|
173
|
+
const agrid = useAgrid()
|
|
174
|
+
|
|
175
|
+
// Tự động track khi màn hình thay đổi
|
|
176
|
+
useEffect(() => {
|
|
177
|
+
if (agrid) {
|
|
178
|
+
agrid.screen(activeScreen)
|
|
179
|
+
}
|
|
180
|
+
}, [activeScreen, agrid])
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
// UI của bạn
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Thủ công
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
agrid?.screen('ProfileScreen', {
|
|
192
|
+
user_id: '123',
|
|
193
|
+
tab: 'settings',
|
|
194
|
+
})
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
#### Với @react-navigation/native (v6 trở xuống)
|
|
198
|
+
|
|
199
|
+
Khi sử dụng `@react-navigation/native` v6 hoặc thấp hơn, screen tracking được tự động ghi nhận nếu sử dụng thuộc tính `autocapture`:
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
import { PostHogProvider } from '@agrid/agrid-react-native'
|
|
203
|
+
import { NavigationContainer } from '@react-navigation/native'
|
|
204
|
+
|
|
205
|
+
export function App() {
|
|
206
|
+
return (
|
|
207
|
+
<NavigationContainer>
|
|
208
|
+
<AgridProvider apiKey="<your_api_key>" autocapture>
|
|
209
|
+
{/* Rest of app */}
|
|
210
|
+
</AgridProvider>
|
|
211
|
+
</NavigationContainer>
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
> **⚠️ Lưu ý:** `AgridProvider` phải là con của `NavigationContainer`.
|
|
217
|
+
|
|
218
|
+
#### Với @react-navigation/native (v7 trở lên)
|
|
219
|
+
|
|
220
|
+
Đối với v7 trở lên, bạn cần ghi nhận màn hình thủ công:
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import { useAgrid } from '@agrid/agrid-react-native'
|
|
224
|
+
import { NavigationContainer } from '@react-navigation/native'
|
|
225
|
+
|
|
226
|
+
export function App() {
|
|
227
|
+
const agrid = useAgrid()
|
|
228
|
+
|
|
229
|
+
return (
|
|
230
|
+
<NavigationContainer
|
|
231
|
+
onStateChange={(state) => {
|
|
232
|
+
const currentRouteName = getCurrentRouteName(state)
|
|
233
|
+
agrid?.screen(currentRouteName)
|
|
234
|
+
}}
|
|
235
|
+
>
|
|
236
|
+
<AgridProvider
|
|
237
|
+
apiKey="<your_api_key>"
|
|
238
|
+
autocapture={{
|
|
239
|
+
captureScreens: false, // Xử lý riêng cho v7
|
|
240
|
+
captureTouches: true,
|
|
241
|
+
}}
|
|
242
|
+
>
|
|
243
|
+
{/* Rest of app */}
|
|
244
|
+
</AgridProvider>
|
|
245
|
+
</NavigationContainer>
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## 5. Tự động ghi nhận (Autocapture)
|
|
253
|
+
|
|
254
|
+
Agrid có thể tự động ghi nhận các sự kiện sau:
|
|
255
|
+
|
|
256
|
+
- **Application Opened** - khi app được mở từ trạng thái đóng
|
|
257
|
+
- **Application Became Active** - khi app chuyển sang foreground
|
|
258
|
+
- **Application Backgrounded** - khi app chuyển sang background
|
|
259
|
+
- **Application Installed** - khi app được cài đặt lần đầu
|
|
260
|
+
- **Application Updated** - khi app được cập nhật
|
|
261
|
+
- **$screen** - khi người dùng điều hướng (nếu sử dụng navigation library)
|
|
262
|
+
- **$autocapture** - sự kiện chạm khi người dùng tương tác với màn hình
|
|
263
|
+
|
|
264
|
+
### Bật Autocapture
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
<AgridProvider
|
|
268
|
+
apiKey="<your_api_key>"
|
|
269
|
+
options={{
|
|
270
|
+
captureAppLifecycleEvents: true, // Bật app lifecycle events
|
|
271
|
+
}}
|
|
272
|
+
autocapture={{
|
|
273
|
+
captureScreens: true, // Tự động capture screen views
|
|
274
|
+
captureTouches: true, // Tự động capture touch events
|
|
275
|
+
}}
|
|
276
|
+
>
|
|
277
|
+
{/* App content */}
|
|
278
|
+
</AgridProvider>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Tùy chỉnh nhãn cho phần tử
|
|
282
|
+
|
|
283
|
+
Agrid sẽ tự động tạo tên cho phần tử được chạm dựa trên `displayName` hoặc `name` của React component. Bạn có thể tùy chỉnh bằng prop `ph-label`:
|
|
284
|
+
|
|
285
|
+
```tsx
|
|
286
|
+
<View ph-label="my-special-button">
|
|
287
|
+
<Text>Click me</Text>
|
|
288
|
+
</View>
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Ngăn chặn capture dữ liệu nhạy cảm
|
|
292
|
+
|
|
293
|
+
Sử dụng prop `ph-no-capture` để ngăn Agrid capture một phần tử cụ thể:
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
<TextInput
|
|
297
|
+
ph-no-capture
|
|
298
|
+
placeholder="Nhập mật khẩu"
|
|
299
|
+
secureTextEntry
|
|
300
|
+
/>
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## 6. Nhận diện người dùng
|
|
306
|
+
|
|
307
|
+
### Identify
|
|
308
|
+
|
|
309
|
+
Sử dụng `identify` để liên kết sự kiện với người dùng cụ thể:
|
|
310
|
+
|
|
311
|
+
```tsx
|
|
312
|
+
agrid?.identify('user_123', {
|
|
313
|
+
email: 'user@example.com',
|
|
314
|
+
name: 'Nguyễn Văn A',
|
|
315
|
+
plan: 'premium',
|
|
316
|
+
})
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
> **💡 Mẹo:** Gọi `identify` ngay sau khi người dùng đăng nhập để đảm bảo tất cả sự kiện được liên kết đúng.
|
|
320
|
+
|
|
321
|
+
### Lấy Distinct ID hiện tại
|
|
322
|
+
|
|
323
|
+
```tsx
|
|
324
|
+
const distinctId = agrid?.getDistinctId()
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Alias
|
|
328
|
+
|
|
329
|
+
Gán nhiều distinct ID cho cùng một người dùng:
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
agrid?.alias('new_distinct_id')
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Thiết lập thuộc tính người dùng
|
|
336
|
+
|
|
337
|
+
#### Sử dụng $set
|
|
338
|
+
|
|
339
|
+
```tsx
|
|
340
|
+
agrid?.identify('user_123', {
|
|
341
|
+
$set: {
|
|
342
|
+
email: 'user@example.com',
|
|
343
|
+
name: 'Nguyễn Văn A',
|
|
344
|
+
}
|
|
345
|
+
})
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
#### Sử dụng $set_once
|
|
349
|
+
|
|
350
|
+
`$set_once` chỉ thiết lập thuộc tính nếu người dùng chưa có thuộc tính đó:
|
|
351
|
+
|
|
352
|
+
```tsx
|
|
353
|
+
agrid?.identify('user_123', {
|
|
354
|
+
$set: {
|
|
355
|
+
email: 'user@example.com',
|
|
356
|
+
},
|
|
357
|
+
$set_once: {
|
|
358
|
+
first_login_date: '2024-01-01',
|
|
359
|
+
}
|
|
360
|
+
})
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### Thiết lập thuộc tính trong sự kiện
|
|
364
|
+
|
|
365
|
+
```tsx
|
|
366
|
+
agrid?.capture('purchase_completed', {
|
|
367
|
+
$set: {
|
|
368
|
+
last_purchase_date: new Date().toISOString(),
|
|
369
|
+
},
|
|
370
|
+
product_id: '12345',
|
|
371
|
+
})
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## 7. Super Properties
|
|
377
|
+
|
|
378
|
+
Super properties là các thuộc tính được gửi kèm với **mọi** sự kiện sau khi được thiết lập:
|
|
379
|
+
|
|
380
|
+
```tsx
|
|
381
|
+
agrid?.register({
|
|
382
|
+
app_version: '1.0.0',
|
|
383
|
+
environment: 'production',
|
|
384
|
+
user_tier: 'premium',
|
|
385
|
+
})
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Sau khi gọi `register`, tất cả sự kiện sẽ tự động bao gồm các thuộc tính này.
|
|
389
|
+
|
|
390
|
+
### Xóa Super Properties
|
|
391
|
+
|
|
392
|
+
```tsx
|
|
393
|
+
agrid?.unregister('app_version')
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
> **⚠️ Lưu ý:** Super properties khác với person properties. Super properties chỉ áp dụng cho sự kiện, không lưu trữ thông tin người dùng.
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## 8. Feature Flags
|
|
401
|
+
|
|
402
|
+
Feature flags cho phép bạn triển khai và rollback tính năng một cách an toàn.
|
|
403
|
+
|
|
404
|
+
### Cách 1: Sử dụng Hooks
|
|
405
|
+
|
|
406
|
+
```tsx
|
|
407
|
+
import { useFeatureFlag } from '@agrid/agrid-react-native'
|
|
408
|
+
|
|
409
|
+
function MyComponent() {
|
|
410
|
+
const showNewFeature = useFeatureFlag('new-feature')
|
|
411
|
+
|
|
412
|
+
if (showNewFeature) {
|
|
413
|
+
return <NewFeature />
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
return <OldFeature />
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Cách 2: Kiểm tra trực tiếp
|
|
421
|
+
|
|
422
|
+
```tsx
|
|
423
|
+
import { useAgrid } from '@agrid/agrid-react-native'
|
|
424
|
+
|
|
425
|
+
function MyComponent() {
|
|
426
|
+
const agrid = useAgrid()
|
|
427
|
+
const isEnabled = agrid?.isFeatureEnabled('new-feature')
|
|
428
|
+
|
|
429
|
+
return isEnabled ? <NewFeature /> : <OldFeature />
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Lấy giá trị Feature Flag
|
|
434
|
+
|
|
435
|
+
```tsx
|
|
436
|
+
const flagValue = agrid?.getFeatureFlag('feature-key')
|
|
437
|
+
// Trả về: boolean | string | undefined
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### Lấy payload của Feature Flag
|
|
441
|
+
|
|
442
|
+
```tsx
|
|
443
|
+
const payload = agrid?.getFeatureFlagPayload('feature-key')
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### Reload Feature Flags
|
|
447
|
+
|
|
448
|
+
```tsx
|
|
449
|
+
// Reload đồng bộ
|
|
450
|
+
agrid?.reloadFeatureFlags()
|
|
451
|
+
|
|
452
|
+
// Reload bất đồng bộ
|
|
453
|
+
const flags = await agrid?.reloadFeatureFlagsAsync()
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
### Thiết lập thuộc tính cho Feature Flags
|
|
457
|
+
|
|
458
|
+
Đôi khi bạn cần đánh giá feature flags dựa trên thuộc tính chưa được gửi lên server:
|
|
459
|
+
|
|
460
|
+
```tsx
|
|
461
|
+
agrid?.setPersonPropertiesForFlags({
|
|
462
|
+
is_beta_user: 'true',
|
|
463
|
+
organization_size: 'large',
|
|
464
|
+
})
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## 9. Tùy chọn nâng cao
|
|
470
|
+
|
|
471
|
+
### Flush thủ công
|
|
472
|
+
|
|
473
|
+
Gửi tất cả sự kiện trong hàng đợi ngay lập tức:
|
|
474
|
+
|
|
475
|
+
```tsx
|
|
476
|
+
await agrid?.flush()
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Reset sau khi logout
|
|
480
|
+
|
|
481
|
+
Xóa tất cả dữ liệu người dùng và bắt đầu session mới:
|
|
482
|
+
|
|
483
|
+
```tsx
|
|
484
|
+
agrid?.reset()
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
### Opt out/in
|
|
488
|
+
|
|
489
|
+
```tsx
|
|
490
|
+
// Opt out - ngừng tracking
|
|
491
|
+
await agrid?.optOut()
|
|
492
|
+
|
|
493
|
+
// Opt in - tiếp tục tracking
|
|
494
|
+
await agrid?.optIn()
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
### Group Analytics
|
|
498
|
+
|
|
499
|
+
Liên kết người dùng với một nhóm (ví dụ: công ty, team):
|
|
500
|
+
|
|
501
|
+
```tsx
|
|
502
|
+
agrid?.group('company', 'company_id_123', {
|
|
503
|
+
name: 'Acme Inc',
|
|
504
|
+
employees: 50,
|
|
505
|
+
})
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Custom Storage
|
|
509
|
+
|
|
510
|
+
Bạn có thể cung cấp custom storage implementation:
|
|
511
|
+
|
|
512
|
+
```tsx
|
|
513
|
+
import { MMKV } from 'react-native-mmkv'
|
|
514
|
+
|
|
515
|
+
const storage = new MMKV()
|
|
516
|
+
|
|
517
|
+
const customStorage = {
|
|
518
|
+
getItem: (key: string) => storage.getString(key) ?? null,
|
|
519
|
+
setItem: (key: string, value: string) => storage.set(key, value),
|
|
520
|
+
removeItem: (key: string) => storage.delete(key),
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
<AgridProvider
|
|
524
|
+
apiKey="<your_api_key>"
|
|
525
|
+
options={{
|
|
526
|
+
customStorage: customStorage,
|
|
527
|
+
}}
|
|
528
|
+
>
|
|
529
|
+
{/* App */}
|
|
530
|
+
</AgridProvider>
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
### Debug Mode
|
|
534
|
+
|
|
535
|
+
Bật logging để debug:
|
|
536
|
+
|
|
537
|
+
```tsx
|
|
538
|
+
<AgridProvider
|
|
539
|
+
apiKey="<your_api_key>"
|
|
540
|
+
options={{
|
|
541
|
+
// Bật debug logs
|
|
542
|
+
debug: true,
|
|
543
|
+
}}
|
|
544
|
+
>
|
|
545
|
+
{/* App */}
|
|
546
|
+
</AgridProvider>
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### Vô hiệu hóa cho môi trường local
|
|
550
|
+
|
|
551
|
+
```tsx
|
|
552
|
+
<AgridProvider
|
|
553
|
+
apiKey="<your_api_key>"
|
|
554
|
+
options={{
|
|
555
|
+
disabled: __DEV__, // Tắt tracking trong development
|
|
556
|
+
}}
|
|
557
|
+
>
|
|
558
|
+
{/* App */}
|
|
559
|
+
</AgridProvider>
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
## 10. Session Replay
|
|
565
|
+
|
|
566
|
+
Ghi lại và phát lại session của người dùng:
|
|
567
|
+
|
|
568
|
+
```tsx
|
|
569
|
+
<AgridProvider
|
|
570
|
+
apiKey="<your_api_key>"
|
|
571
|
+
options={{
|
|
572
|
+
enableSessionReplay: true,
|
|
573
|
+
sessionReplayConfig: {
|
|
574
|
+
maskAllTexts: true, // Che tất cả text
|
|
575
|
+
maskAllImages: true, // Che tất cả hình ảnh
|
|
576
|
+
captureNetworkTelemetry: true, // Capture network requests
|
|
577
|
+
},
|
|
578
|
+
}}
|
|
579
|
+
>
|
|
580
|
+
{/* App */}
|
|
581
|
+
</AgridProvider>
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
---
|
|
585
|
+
|
|
586
|
+
## 11. Error Tracking
|
|
587
|
+
|
|
588
|
+
Tự động ghi nhận lỗi JavaScript:
|
|
589
|
+
|
|
590
|
+
```tsx
|
|
591
|
+
<AgridProvider
|
|
592
|
+
apiKey="<your_api_key>"
|
|
593
|
+
options={{
|
|
594
|
+
errorTracking: {
|
|
595
|
+
captureErrors: true,
|
|
596
|
+
captureUnhandledRejections: true,
|
|
597
|
+
},
|
|
598
|
+
}}
|
|
599
|
+
>
|
|
600
|
+
{/* App */}
|
|
601
|
+
</AgridProvider>
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
606
|
+
## 12. Surveys
|
|
607
|
+
|
|
608
|
+
Hiển thị khảo sát cho người dùng:
|
|
609
|
+
|
|
610
|
+
```tsx
|
|
611
|
+
import { AgridSurveyProvider } from '@agrid/agrid-react-native'
|
|
612
|
+
|
|
613
|
+
<AgridProvider apiKey="<your_api_key>">
|
|
614
|
+
<AgridSurveyProvider>
|
|
615
|
+
{/* App */}
|
|
616
|
+
</AgridSurveyProvider>
|
|
617
|
+
</AgridProvider>
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
## 13. Ví dụ hoàn chỉnh
|
|
623
|
+
|
|
624
|
+
```tsx
|
|
625
|
+
import React, { useEffect, useState } from 'react'
|
|
626
|
+
import { View, Button, Text } from 'react-native'
|
|
627
|
+
import { AgridProvider, useAgrid } from '@agrid/agrid-react-native'
|
|
628
|
+
|
|
629
|
+
function App() {
|
|
630
|
+
return (
|
|
631
|
+
<AgridProvider
|
|
632
|
+
apiKey="<your_api_key>"
|
|
633
|
+
options={{
|
|
634
|
+
host: 'https://gw.track-asia.vn',
|
|
635
|
+
captureAppLifecycleEvents: true,
|
|
636
|
+
flushAt: 10,
|
|
637
|
+
}}
|
|
638
|
+
autocapture={{
|
|
639
|
+
captureTouches: true,
|
|
640
|
+
}}
|
|
641
|
+
>
|
|
642
|
+
<MyApp />
|
|
643
|
+
</AgridProvider>
|
|
644
|
+
)
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
function MyApp() {
|
|
648
|
+
const agrid = useAgrid()
|
|
649
|
+
const [user, setUser] = useState(null)
|
|
650
|
+
|
|
651
|
+
useEffect(() => {
|
|
652
|
+
// Identify user khi đăng nhập
|
|
653
|
+
if (user) {
|
|
654
|
+
agrid?.identify(user.id, {
|
|
655
|
+
email: user.email,
|
|
656
|
+
name: user.name,
|
|
657
|
+
})
|
|
658
|
+
}
|
|
659
|
+
}, [user, agrid])
|
|
660
|
+
|
|
661
|
+
const handlePurchase = () => {
|
|
662
|
+
agrid?.capture('purchase_completed', {
|
|
663
|
+
product_id: '12345',
|
|
664
|
+
price: 99.99,
|
|
665
|
+
})
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
const handleLogout = () => {
|
|
669
|
+
agrid?.reset()
|
|
670
|
+
setUser(null)
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
return (
|
|
674
|
+
<View>
|
|
675
|
+
<Text>Welcome to Agrid!</Text>
|
|
676
|
+
<Button title="Make Purchase" onPress={handlePurchase} />
|
|
677
|
+
<Button title="Logout" onPress={handleLogout} />
|
|
678
|
+
</View>
|
|
679
|
+
)
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
export default App
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
---
|
|
686
|
+
|
|
687
|
+
## 14. Liên hệ & Hỗ trợ
|
|
688
|
+
|
|
689
|
+
- Liên hệ với đội ngũ hỗ trợ Agrid qua email (info@agrid.vn) để được giúp đỡ.
|
|
690
|
+
- Project ví dụ: [example-agrid-react-native](https://github.com/agridvn/agrid-react-native/tree/main/example-agrid-react-native)
|
|
691
|
+
- Tài liệu tham khảo: [React Native Documentation](https://reactnative.dev/)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var _interopRequireDefault=require("@babel/runtime/helpers/interopRequireDefault");Object.defineProperty(exports,"__esModule",{value:true});exports.AgridContext=void 0;var _react=_interopRequireDefault(require("react"));var AgridContext=exports.AgridContext=_react["default"].createContext({client:undefined});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgridContext.js","sourceRoot":"","sources":["../src/AgridContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,CAAoB,EAAE,MAAM,EAAE,SAA6B,EAAE,CAAC,CAAA"}
|