react-visual-feedback 1.4.8 → 2.2.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/README.md +144 -9
- package/dist/index.esm.js +2 -2
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/config.js +664 -0
- package/dist/integrations/config.js.map +1 -0
- package/dist/integrations/index.js +4 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/server/index.js +2907 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/jira.js +1565 -0
- package/dist/server/jira.js.map +1 -0
- package/dist/server/sheets.js +1448 -0
- package/dist/server/sheets.js.map +1 -0
- package/package.json +30 -3
package/README.md
CHANGED
|
@@ -8,22 +8,39 @@ A powerful, visual feedback collection tool for React applications with screen r
|
|
|
8
8
|
- **Visual Element Selection** - Click any element with hover highlighting
|
|
9
9
|
- **Screenshot Capture** - Automatic pixel-perfect screenshot with CSS rendering
|
|
10
10
|
- **Screen Recording** - Record screen with audio and capture console/network logs
|
|
11
|
+
- **Manual Feedback** - `Alt+A` to open form directly without selection
|
|
12
|
+
- **File Attachments** - Drag & drop support for Images, Videos, PDFs, and other files
|
|
11
13
|
- **Canvas Drawing** - Annotate screenshots with drawings and highlights
|
|
12
14
|
- **React Component Detection** - Automatically detects React component names and source files
|
|
13
|
-
- **Keyboard Shortcuts** - `Alt+Q`
|
|
15
|
+
- **Keyboard Shortcuts** - `Alt+Q` (Selection), `Alt+A` (Manual), `Alt+W` (Record), `Esc` (Cancel)
|
|
14
16
|
|
|
15
17
|
### Session Replay
|
|
16
|
-
- **Video Playback** - Watch recorded user sessions
|
|
17
|
-
- **Console Logs** - See console.log, errors, warnings synced with video
|
|
18
|
+
- **Video Playback** - Watch recorded user sessions with fullscreen support
|
|
19
|
+
- **Console Logs** - See console.log, errors, warnings synced with video timeline
|
|
18
20
|
- **Network Requests** - Track API calls and responses
|
|
21
|
+
- **Video Mode** - Fullscreen playback with synced logs panel (scrollable even when paused)
|
|
19
22
|
- **Expandable Logs Panel** - Slide-out panel on the right side (customizable)
|
|
20
23
|
|
|
24
|
+
### Screen Recording
|
|
25
|
+
- **Draggable Indicator** - Recording overlay can be moved around the screen
|
|
26
|
+
- **Audio Capture** - Record microphone and system audio (mixed)
|
|
27
|
+
- **IndexedDB Storage** - Large videos stored locally to prevent quota errors
|
|
28
|
+
- **Download Videos** - Export recordings as WebM files
|
|
29
|
+
|
|
21
30
|
### Dashboard
|
|
22
31
|
- **Professional UI** - Clean 700px slide-out panel
|
|
23
32
|
- **Developer Mode** - Full technical details (source file, component stack, viewport)
|
|
24
33
|
- **User Mode** - Simplified view for end users
|
|
25
34
|
- **8 Status Options** - New, Open, In Progress, Under Review, On Hold, Resolved, Closed, Won't Fix
|
|
26
35
|
- **Status Callbacks** - Sync with your database on status changes
|
|
36
|
+
- **Search** - Search through feedback by title, description, or user
|
|
37
|
+
|
|
38
|
+
### Updates Modal
|
|
39
|
+
- **What's New** - Display product updates, bug fixes, and new features to users
|
|
40
|
+
- **Filter Tabs** - Filter by Fixed or New Feature
|
|
41
|
+
- **Smooth Animations** - Beautiful fade-in animations with staggered item entry
|
|
42
|
+
- **Mobile Responsive** - Works as a centered popup on all screen sizes
|
|
43
|
+
- **Dark/Light Mode** - Full theme support
|
|
27
44
|
|
|
28
45
|
### Theming
|
|
29
46
|
- **Light/Dark Mode** - Full theme support
|
|
@@ -51,6 +68,7 @@ import { FeedbackProvider } from 'react-visual-feedback';
|
|
|
51
68
|
function App() {
|
|
52
69
|
const handleFeedbackSubmit = async (feedbackData) => {
|
|
53
70
|
console.log('Feedback received:', feedbackData);
|
|
71
|
+
// feedbackData.attachment contains any manually uploaded file
|
|
54
72
|
await fetch('/api/feedback', {
|
|
55
73
|
method: 'POST',
|
|
56
74
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -88,7 +106,7 @@ function FeedbackButtons() {
|
|
|
88
106
|
|
|
89
107
|
function App() {
|
|
90
108
|
const handleFeedbackSubmit = async (feedbackData) => {
|
|
91
|
-
// feedbackData contains: feedback, screenshot, video, eventLogs, elementInfo, etc.
|
|
109
|
+
// feedbackData contains: feedback, screenshot, video, attachment, eventLogs, elementInfo, etc.
|
|
92
110
|
await fetch('/api/feedback', {
|
|
93
111
|
method: 'POST',
|
|
94
112
|
headers: { 'Content-Type': 'application/json' },
|
|
@@ -113,6 +131,7 @@ function App() {
|
|
|
113
131
|
userName="John Doe"
|
|
114
132
|
userEmail="john@example.com"
|
|
115
133
|
mode="light"
|
|
134
|
+
defaultOpen={false} // Set to true to open feedback form on mount
|
|
116
135
|
>
|
|
117
136
|
<YourApp />
|
|
118
137
|
<FeedbackButtons />
|
|
@@ -138,6 +157,7 @@ function App() {
|
|
|
138
157
|
| `mode` | `'light' \| 'dark'` | `'light'` | Theme mode |
|
|
139
158
|
| `isActive` | `boolean` | - | Controlled active state |
|
|
140
159
|
| `onActiveChange` | `(active) => void` | - | Callback for controlled mode |
|
|
160
|
+
| `defaultOpen` | `boolean` | `false` | Open manual feedback form immediately on mount |
|
|
141
161
|
|
|
142
162
|
### FeedbackDashboard Props
|
|
143
163
|
|
|
@@ -184,6 +204,65 @@ import { SessionReplay } from 'react-visual-feedback';
|
|
|
184
204
|
/>
|
|
185
205
|
```
|
|
186
206
|
|
|
207
|
+
### UpdatesModal Props
|
|
208
|
+
|
|
209
|
+
Display product updates, bug fixes, and new features to your users with a beautiful modal.
|
|
210
|
+
|
|
211
|
+
```jsx
|
|
212
|
+
import { UpdatesModal } from 'react-visual-feedback';
|
|
213
|
+
|
|
214
|
+
const updates = [
|
|
215
|
+
{
|
|
216
|
+
id: '1',
|
|
217
|
+
type: 'solved', // 'solved' | 'new_feature'
|
|
218
|
+
title: 'Fixed login page performance issues',
|
|
219
|
+
description: 'Optimized the authentication flow, reducing load time by 40%',
|
|
220
|
+
date: '2024-11-30',
|
|
221
|
+
version: '2.1.0',
|
|
222
|
+
category: 'Performance'
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
id: '2',
|
|
226
|
+
type: 'new_feature',
|
|
227
|
+
title: 'Dark mode support added',
|
|
228
|
+
description: 'Full dark mode support across all components with smooth transitions',
|
|
229
|
+
date: '2024-11-28',
|
|
230
|
+
version: '2.1.0',
|
|
231
|
+
category: 'Feature'
|
|
232
|
+
}
|
|
233
|
+
];
|
|
234
|
+
|
|
235
|
+
<UpdatesModal
|
|
236
|
+
isOpen={showUpdates} // Control visibility
|
|
237
|
+
onClose={() => setShowUpdates(false)}
|
|
238
|
+
updates={updates} // Array of update objects
|
|
239
|
+
title="What's New" // Modal title (default: "What's New")
|
|
240
|
+
mode="light" // Theme mode: 'light' | 'dark'
|
|
241
|
+
/>
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
| Prop | Type | Default | Description |
|
|
245
|
+
|------|------|---------|-------------|
|
|
246
|
+
| `isOpen` | `boolean` | required | Control modal visibility |
|
|
247
|
+
| `onClose` | `() => void` | required | Callback when modal closes |
|
|
248
|
+
| `updates` | `Update[]` | `[]` | Array of update objects |
|
|
249
|
+
| `title` | `string` | `"What's New"` | Modal header title |
|
|
250
|
+
| `mode` | `'light' \| 'dark'` | `'light'` | Theme mode |
|
|
251
|
+
|
|
252
|
+
#### Update Object Structure
|
|
253
|
+
|
|
254
|
+
```typescript
|
|
255
|
+
interface Update {
|
|
256
|
+
id: string; // Unique identifier
|
|
257
|
+
type: 'solved' | 'new_feature'; // Update type
|
|
258
|
+
title: string; // Update title
|
|
259
|
+
description?: string; // Optional description
|
|
260
|
+
date?: string; // Date string (displayed as "Mon DD")
|
|
261
|
+
version?: string; // Version number (displayed as "vX.X.X")
|
|
262
|
+
category?: string; // Category tag
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
187
266
|
## Data Structures
|
|
188
267
|
|
|
189
268
|
### Feedback Data (submitted via onSubmit)
|
|
@@ -204,11 +283,11 @@ interface FeedbackData {
|
|
|
204
283
|
height: number;
|
|
205
284
|
};
|
|
206
285
|
|
|
207
|
-
//
|
|
208
|
-
screenshot?: string; // Base64 PNG data URL
|
|
286
|
+
// Attachments
|
|
287
|
+
screenshot?: string; // Base64 PNG data URL (Automatic)
|
|
288
|
+
video?: string; // Base64 webm data URL (Recording)
|
|
289
|
+
attachment?: File; // Generic file (Manual Upload)
|
|
209
290
|
|
|
210
|
-
// Video (for screen recording)
|
|
211
|
-
video?: string; // Base64 webm data URL
|
|
212
291
|
eventLogs?: EventLog[]; // Console/network logs
|
|
213
292
|
|
|
214
293
|
// Element info (for element selection)
|
|
@@ -284,6 +363,17 @@ CREATE TABLE feedback_videos (
|
|
|
284
363
|
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
285
364
|
);
|
|
286
365
|
|
|
366
|
+
-- Generic attachments table
|
|
367
|
+
CREATE TABLE feedback_attachments (
|
|
368
|
+
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
369
|
+
feedback_id UUID NOT NULL REFERENCES feedback(id) ON DELETE CASCADE,
|
|
370
|
+
file_name VARCHAR(255),
|
|
371
|
+
file_type VARCHAR(100),
|
|
372
|
+
file_size_bytes BIGINT,
|
|
373
|
+
file_data TEXT, -- Base64 or URL
|
|
374
|
+
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
|
375
|
+
);
|
|
376
|
+
|
|
287
377
|
-- Event logs table (console logs, network requests)
|
|
288
378
|
CREATE TABLE feedback_event_logs (
|
|
289
379
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
@@ -409,6 +499,19 @@ CREATE TABLE feedback_videos (
|
|
|
409
499
|
FOREIGN KEY (feedback_id) REFERENCES feedback(id) ON DELETE CASCADE
|
|
410
500
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
411
501
|
|
|
502
|
+
-- Attachments table
|
|
503
|
+
CREATE TABLE feedback_attachments (
|
|
504
|
+
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
|
505
|
+
feedback_id CHAR(36) NOT NULL,
|
|
506
|
+
file_name VARCHAR(255),
|
|
507
|
+
file_type VARCHAR(100),
|
|
508
|
+
file_size_bytes BIGINT,
|
|
509
|
+
file_data LONGTEXT,
|
|
510
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
511
|
+
|
|
512
|
+
FOREIGN KEY (feedback_id) REFERENCES feedback(id) ON DELETE CASCADE
|
|
513
|
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
514
|
+
|
|
412
515
|
-- Event logs table
|
|
413
516
|
CREATE TABLE feedback_event_logs (
|
|
414
517
|
id CHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
|
@@ -470,7 +573,7 @@ CREATE TABLE feedback_status_history (
|
|
|
470
573
|
// POST /api/feedback - Submit new feedback
|
|
471
574
|
app.post('/api/feedback', async (req, res) => {
|
|
472
575
|
const { feedback, type, userName, userEmail, url, userAgent,
|
|
473
|
-
viewport, screenshot, video, eventLogs, elementInfo } = req.body;
|
|
576
|
+
viewport, screenshot, video, attachment, eventLogs, elementInfo } = req.body;
|
|
474
577
|
|
|
475
578
|
// Start transaction
|
|
476
579
|
const client = await pool.connect();
|
|
@@ -501,6 +604,16 @@ app.post('/api/feedback', async (req, res) => {
|
|
|
501
604
|
VALUES ($1, $2)
|
|
502
605
|
`, [feedbackId, video]);
|
|
503
606
|
}
|
|
607
|
+
|
|
608
|
+
// Insert manual attachment (generic file)
|
|
609
|
+
if (attachment) {
|
|
610
|
+
// Note: 'attachment' here is assumed to be pre-processed/uploaded file metadata + content
|
|
611
|
+
// In a real app, you might handle file upload separately (multipart/form-data)
|
|
612
|
+
await client.query(`
|
|
613
|
+
INSERT INTO feedback_attachments (feedback_id, file_name, file_data)
|
|
614
|
+
VALUES ($1, $2, $3)
|
|
615
|
+
`, [feedbackId, attachment.name, attachment.data]);
|
|
616
|
+
}
|
|
504
617
|
|
|
505
618
|
// Insert event logs if exist
|
|
506
619
|
if (eventLogs?.length) {
|
|
@@ -573,6 +686,7 @@ app.patch('/api/feedback/:id/status', async (req, res) => {
|
|
|
573
686
|
| Shortcut | Action |
|
|
574
687
|
|----------|--------|
|
|
575
688
|
| `Alt+Q` | Activate feedback mode (element selection) |
|
|
689
|
+
| `Alt+A` | Open Manual Feedback form |
|
|
576
690
|
| `Alt+W` | Start screen recording |
|
|
577
691
|
| `Alt+Shift+Q` | Open dashboard |
|
|
578
692
|
| `Esc` | Cancel/close |
|
|
@@ -813,6 +927,7 @@ import {
|
|
|
813
927
|
FeedbackDashboard,
|
|
814
928
|
FeedbackTrigger,
|
|
815
929
|
CanvasOverlay,
|
|
930
|
+
UpdatesModal, // What's New modal for updates
|
|
816
931
|
|
|
817
932
|
// Hooks
|
|
818
933
|
useFeedback,
|
|
@@ -845,6 +960,26 @@ import {
|
|
|
845
960
|
|
|
846
961
|
## Changelog
|
|
847
962
|
|
|
963
|
+
### v2.2.0
|
|
964
|
+
- **Added**: `UpdatesModal` component - Display product updates, bug fixes, and new features
|
|
965
|
+
- **Added**: Draggable recording indicator - Move the recording overlay anywhere on screen
|
|
966
|
+
- **Added**: Video Mode with fullscreen playback and synced logs panel
|
|
967
|
+
- **Added**: Search functionality in feedback dashboard
|
|
968
|
+
- **Added**: IndexedDB storage for large video recordings (prevents quota errors)
|
|
969
|
+
- **Added**: Video download/export functionality
|
|
970
|
+
- **Improved**: Logs panel now scrollable when video is paused
|
|
971
|
+
- **Improved**: Audio mixing for microphone and system audio in recordings
|
|
972
|
+
- **Fixed**: Mobile responsive UpdatesModal - displays as centered popup
|
|
973
|
+
|
|
974
|
+
### v2.1.0
|
|
975
|
+
- **Added**: Manual feedback mode (`Alt+A`) - open form without selecting an element
|
|
976
|
+
- **Added**: `defaultOpen` prop to automatically open form on mount
|
|
977
|
+
- **Added**: Drag & Drop file upload support
|
|
978
|
+
- **Added**: Support for generic file attachments (PDF, etc.)
|
|
979
|
+
- **Improved**: Dark mode colors for better contrast and readability
|
|
980
|
+
- **Improved**: Dashboard status badges now have solid backgrounds for better visibility
|
|
981
|
+
- **Improved**: Screenshot preview in dashboard with zoom overlay
|
|
982
|
+
|
|
848
983
|
### v1.4.2
|
|
849
984
|
- **Fixed**: Modal state not resetting after submission (was showing "Sending..." on reopen)
|
|
850
985
|
- **Added**: `Alt+W` keyboard shortcut for video recording
|