@crownpeak/dqm-react-component 1.0.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/AUTHENTICATION.md +281 -0
- package/BACKEND-API.md +1829 -0
- package/CHANGELOG.md +28 -0
- package/DEVELOPMENT.md +339 -0
- package/EXAMPLES.md +194 -0
- package/LICENSE +22 -0
- package/QUICKSTART.md +200 -0
- package/README.md +213 -0
- package/dist/DQMSidebar.d.ts +5 -0
- package/dist/DQMSidebar.d.ts.map +1 -0
- package/dist/ErrorBoundary.d.ts +34 -0
- package/dist/ErrorBoundary.d.ts.map +1 -0
- package/dist/auth-ui/assets/index-CehNKFGj.js +158 -0
- package/dist/auth-ui/index.html +30 -0
- package/dist/components/auth/DQMLogin.d.ts +16 -0
- package/dist/components/auth/DQMLogin.d.ts.map +1 -0
- package/dist/components/auth/OAuth2CallbackHandler.d.ts +15 -0
- package/dist/components/auth/OAuth2CallbackHandler.d.ts.map +1 -0
- package/dist/components/auth/index.d.ts +3 -0
- package/dist/components/auth/index.d.ts.map +1 -0
- package/dist/components/cards/CategoryCard.d.ts +2 -0
- package/dist/components/cards/CategoryCard.d.ts.map +1 -0
- package/dist/components/cards/FailedCheckpointsCard.d.ts +2 -0
- package/dist/components/cards/FailedCheckpointsCard.d.ts.map +1 -0
- package/dist/components/cards/QualityOverviewCard.d.ts +2 -0
- package/dist/components/cards/QualityOverviewCard.d.ts.map +1 -0
- package/dist/components/cards/index.d.ts +4 -0
- package/dist/components/cards/index.d.ts.map +1 -0
- package/dist/components/common/CircularProgressWithLabel.d.ts +5 -0
- package/dist/components/common/CircularProgressWithLabel.d.ts.map +1 -0
- package/dist/components/common/index.d.ts +2 -0
- package/dist/components/common/index.d.ts.map +1 -0
- package/dist/components/renderers/BrowserViewRenderer.d.ts +9 -0
- package/dist/components/renderers/BrowserViewRenderer.d.ts.map +1 -0
- package/dist/components/renderers/SafeParsedHtml.d.ts +4 -0
- package/dist/components/renderers/SafeParsedHtml.d.ts.map +1 -0
- package/dist/components/renderers/ShadowDOMRenderer.d.ts +11 -0
- package/dist/components/renderers/ShadowDOMRenderer.d.ts.map +1 -0
- package/dist/components/renderers/index.d.ts +4 -0
- package/dist/components/renderers/index.d.ts.map +1 -0
- package/dist/components/sidebar/SidebarContent.d.ts +2 -0
- package/dist/components/sidebar/SidebarContent.d.ts.map +1 -0
- package/dist/components/sidebar/SidebarFooter.d.ts +5 -0
- package/dist/components/sidebar/SidebarFooter.d.ts.map +1 -0
- package/dist/components/sidebar/SidebarHeader.d.ts +2 -0
- package/dist/components/sidebar/SidebarHeader.d.ts.map +1 -0
- package/dist/components/sidebar/SidebarSkeleton.d.ts +5 -0
- package/dist/components/sidebar/SidebarSkeleton.d.ts.map +1 -0
- package/dist/components/sidebar/StyledDrawer.d.ts +2 -0
- package/dist/components/sidebar/StyledDrawer.d.ts.map +1 -0
- package/dist/components/sidebar/StyledFab.d.ts +4 -0
- package/dist/components/sidebar/StyledFab.d.ts.map +1 -0
- package/dist/components/sidebar/index.d.ts +7 -0
- package/dist/components/sidebar/index.d.ts.map +1 -0
- package/dist/index.cjs +113 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13712 -0
- package/dist/index.js.map +1 -0
- package/dist/server/config.js +21 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/index.js +74 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/middleware/authenticate.js +31 -0
- package/dist/server/middleware/authenticate.js.map +1 -0
- package/dist/server/middleware/errorHandler.js +8 -0
- package/dist/server/middleware/errorHandler.js.map +1 -0
- package/dist/server/routes/auth.js +142 -0
- package/dist/server/routes/auth.js.map +1 -0
- package/dist/server/routes/dqm.js +138 -0
- package/dist/server/routes/dqm.js.map +1 -0
- package/dist/server/services/dqmClient.js +127 -0
- package/dist/server/services/dqmClient.js.map +1 -0
- package/dist/server/services/sessionStore.js +250 -0
- package/dist/server/services/sessionStore.js.map +1 -0
- package/dist/server/types.js +2 -0
- package/dist/server/types.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/colors/GenerateCategoryColors.d.ts +12 -0
- package/dist/utils/colors/GenerateCategoryColors.d.ts.map +1 -0
- package/dist/utils/localStorage.d.ts +4 -0
- package/dist/utils/localStorage.d.ts.map +1 -0
- package/dist/utils/storage.d.ts +28 -0
- package/dist/utils/storage.d.ts.map +1 -0
- package/package.json +124 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Crownpeak DQM React Component - Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2025-10-30
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Initial release of @crownpeak/dqm-react-component
|
|
12
|
+
- DQMSidebar component for quality analysis
|
|
13
|
+
- ErrorBoundary component for error handling
|
|
14
|
+
- Full TypeScript support with type definitions
|
|
15
|
+
- Material-UI integration
|
|
16
|
+
- Real-time quality analysis dashboard
|
|
17
|
+
- Browser and source view for error highlighting
|
|
18
|
+
- Category-based filtering
|
|
19
|
+
- Accessibility compliance checking
|
|
20
|
+
- Comprehensive documentation
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
- Quality scoring and checkpoint validation
|
|
24
|
+
- WCAG 2.1 compliance checking
|
|
25
|
+
- Visual error highlighting
|
|
26
|
+
- Mobile responsive design
|
|
27
|
+
- Export functionality for highlighted errors
|
|
28
|
+
|
package/DEVELOPMENT.md
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
## Running the Complete Stack
|
|
4
|
+
|
|
5
|
+
### Start Development (Frontend + Backend)
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This runs both servers concurrently:
|
|
12
|
+
- **Frontend (Vite)**: http://localhost:5173
|
|
13
|
+
- **Backend (Express)**: http://localhost:3001
|
|
14
|
+
|
|
15
|
+
### Start Individual Servers
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Frontend only
|
|
19
|
+
npm run dev:client
|
|
20
|
+
|
|
21
|
+
# Backend only
|
|
22
|
+
npm run dev:server
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Project Structure
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
crownpeak-dqm-react-component/
|
|
29
|
+
├── src/ # React component source
|
|
30
|
+
│ ├── components/
|
|
31
|
+
│ │ ├── auth/ # Authentication components
|
|
32
|
+
│ │ ├── sidebar/ # Sidebar UI components
|
|
33
|
+
│ │ ├── cards/ # Analysis result cards
|
|
34
|
+
│ │ ├── renderers/ # HTML rendering
|
|
35
|
+
│ │ └── common/ # Shared components
|
|
36
|
+
│ ├── utils/ # Utilities
|
|
37
|
+
│ ├── types.ts # TypeScript types
|
|
38
|
+
│ ├── DQMSidebar.tsx # Main component
|
|
39
|
+
│ ├── index.ts # Library entry point
|
|
40
|
+
│ ├── App.tsx # Dev test harness
|
|
41
|
+
│ └── main.tsx # Dev app entry
|
|
42
|
+
│
|
|
43
|
+
├── server/ # Backend API
|
|
44
|
+
│ ├── routes/ # API endpoints
|
|
45
|
+
│ │ ├── auth.ts # Authentication
|
|
46
|
+
│ │ └── dqm.ts # DQM proxy
|
|
47
|
+
│ ├── services/ # Business logic
|
|
48
|
+
│ │ ├── sessionStore.ts # Session management
|
|
49
|
+
│ │ └── dqmClient.ts # DQM API client
|
|
50
|
+
│ ├── middleware/ # Express middleware
|
|
51
|
+
│ ├── config.ts # Configuration
|
|
52
|
+
│ ├── types.ts # TypeScript types
|
|
53
|
+
│ └── index.ts # Express app
|
|
54
|
+
│
|
|
55
|
+
├── dist/ # Build output
|
|
56
|
+
│ ├── index.js # Library ESM
|
|
57
|
+
│ ├── index.cjs # Library CommonJS
|
|
58
|
+
│ ├── index.d.ts # Type declarations
|
|
59
|
+
│ └── server/ # Compiled server code
|
|
60
|
+
│
|
|
61
|
+
├── vite.config.ts # Vite configuration
|
|
62
|
+
├── tsconfig.json # TypeScript base config
|
|
63
|
+
├── tsconfig.lib.json # Library build config
|
|
64
|
+
├── tsconfig.server.json # Server build config
|
|
65
|
+
└── package.json # Dependencies & scripts
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Authentication Modes
|
|
69
|
+
|
|
70
|
+
The component supports two modes:
|
|
71
|
+
|
|
72
|
+
### 1. Backend Mode (Recommended for Production)
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
<DQMSidebar
|
|
76
|
+
config={{
|
|
77
|
+
authBackendUrl: 'http://localhost:3001',
|
|
78
|
+
useLocalStorage: true,
|
|
79
|
+
}}
|
|
80
|
+
/>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- All API calls proxied through backend
|
|
84
|
+
- Session token stored in localStorage
|
|
85
|
+
- Real credentials never exposed to client
|
|
86
|
+
|
|
87
|
+
### 2. Direct Mode (Development/Staging)
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
<DQMSidebar
|
|
91
|
+
config={{
|
|
92
|
+
apiKey: 'YOUR_API_KEY',
|
|
93
|
+
websiteId: 'YOUR_WEBSITE_ID',
|
|
94
|
+
}}
|
|
95
|
+
/>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- Direct communication with Crownpeak DQM API
|
|
99
|
+
- Credentials in props or localStorage
|
|
100
|
+
- No backend required
|
|
101
|
+
|
|
102
|
+
## Testing Both Modes
|
|
103
|
+
|
|
104
|
+
### Test Backend Mode
|
|
105
|
+
|
|
106
|
+
1. Start both servers: `npm run dev`
|
|
107
|
+
2. Open http://localhost:5173
|
|
108
|
+
3. Click "Login" and enter credentials
|
|
109
|
+
4. Backend validates and issues session token
|
|
110
|
+
5. All API calls go through http://localhost:3001
|
|
111
|
+
|
|
112
|
+
### Test Direct Mode
|
|
113
|
+
|
|
114
|
+
1. Update `src/App.tsx`:
|
|
115
|
+
```tsx
|
|
116
|
+
<DQMSidebar
|
|
117
|
+
config={{
|
|
118
|
+
apiKey: 'YOUR_API_KEY',
|
|
119
|
+
websiteId: 'YOUR_WEBSITE_ID',
|
|
120
|
+
}}
|
|
121
|
+
/>
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
2. Start frontend only: `npm run dev:client`
|
|
125
|
+
3. No backend needed, direct API calls
|
|
126
|
+
|
|
127
|
+
## Building for Production
|
|
128
|
+
|
|
129
|
+
### Build Library
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
npm run build:lib
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Output: `dist/index.{js,cjs,d.ts}`
|
|
136
|
+
|
|
137
|
+
### Build Server
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npm run build:server
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Output: `dist/server/`
|
|
144
|
+
|
|
145
|
+
### Test Library Build
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
npm pack
|
|
149
|
+
# Creates: crownpeak-dqm-react-component-1.0.0.tgz
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Environment Configuration
|
|
153
|
+
|
|
154
|
+
### Frontend (.env)
|
|
155
|
+
|
|
156
|
+
```env
|
|
157
|
+
VITE_BACKEND_URL=http://localhost:3001
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Backend (.env)
|
|
161
|
+
|
|
162
|
+
```env
|
|
163
|
+
PORT=3001
|
|
164
|
+
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
|
|
165
|
+
DQM_API_BASE_URL=https://api.crownpeak.net/dqm-cms/v1
|
|
166
|
+
JWT_SECRET=your-secret-key
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## API Testing with cURL
|
|
170
|
+
|
|
171
|
+
### Login
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
curl -X POST http://localhost:3001/auth/login \
|
|
175
|
+
-H "Content-Type: application/json" \
|
|
176
|
+
-d '{
|
|
177
|
+
"apiKey": "YOUR_API_KEY",
|
|
178
|
+
"websiteId": "YOUR_WEBSITE_ID"
|
|
179
|
+
}'
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Response:
|
|
183
|
+
```json
|
|
184
|
+
{
|
|
185
|
+
"sessionToken": "abc123...",
|
|
186
|
+
"websiteId": "YOUR_WEBSITE_ID"
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Start Analysis
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
curl -X POST http://localhost:3001/dqm/assets \
|
|
194
|
+
-H "Authorization: Bearer YOUR_SESSION_TOKEN" \
|
|
195
|
+
-H "Content-Type: application/json" \
|
|
196
|
+
-d '{
|
|
197
|
+
"html": "<html><body><h1>Test</h1></body></html>",
|
|
198
|
+
"url": "https://example.com"
|
|
199
|
+
}'
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Get Results
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
curl -X GET http://localhost:3001/dqm/assets/ASSET_ID \
|
|
206
|
+
-H "Authorization: Bearer YOUR_SESSION_TOKEN"
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Debugging
|
|
210
|
+
|
|
211
|
+
### Enable Verbose Logging
|
|
212
|
+
|
|
213
|
+
Backend logs all requests automatically. Check terminal output:
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
[2025-10-31T10:00:00.000Z] POST /auth/login
|
|
217
|
+
[Auth] User logged in successfully (websiteId: test_id)
|
|
218
|
+
[SessionStore] Created session: abc12345... (expires in 1440 minutes)
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Check Session Status
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
curl -X GET http://localhost:3001/auth/session \
|
|
225
|
+
-H "Authorization: Bearer YOUR_SESSION_TOKEN"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### View Active Sessions (Dev Only)
|
|
229
|
+
|
|
230
|
+
Add to `server/routes/auth.ts`:
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
authRouter.get('/sessions/count', (req, res) => {
|
|
234
|
+
res.json({ count: sessionStore.count() });
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Common Issues
|
|
239
|
+
|
|
240
|
+
### CORS Errors
|
|
241
|
+
|
|
242
|
+
**Problem:** Frontend can't reach backend
|
|
243
|
+
|
|
244
|
+
**Solution:** Add frontend URL to `CORS_ORIGINS` in `.env`:
|
|
245
|
+
```env
|
|
246
|
+
CORS_ORIGINS=http://localhost:5173,http://localhost:3000
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Port Already in Use
|
|
250
|
+
|
|
251
|
+
**Problem:** `Error: listen EADDRINUSE: address already in use :::3001`
|
|
252
|
+
|
|
253
|
+
**Solution:** Kill process or change port:
|
|
254
|
+
```bash
|
|
255
|
+
lsof -ti:3001 | xargs kill -9
|
|
256
|
+
# or change PORT in .env
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Session Expired
|
|
260
|
+
|
|
261
|
+
**Problem:** 401 Unauthorized after some time
|
|
262
|
+
|
|
263
|
+
**Solution:** Session TTL is 24 hours. Login again or extend TTL in `server/config.ts`:
|
|
264
|
+
```typescript
|
|
265
|
+
session: {
|
|
266
|
+
ttl: 48 * 60 * 60 * 1000, // 48 hours
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### TypeScript Errors
|
|
271
|
+
|
|
272
|
+
**Problem:** Type errors in server code
|
|
273
|
+
|
|
274
|
+
**Solution:** Ensure @types packages installed:
|
|
275
|
+
```bash
|
|
276
|
+
npm install --save-dev @types/express @types/cors @types/node
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## Production Deployment
|
|
280
|
+
|
|
281
|
+
### Deploy Backend
|
|
282
|
+
|
|
283
|
+
1. Build server: `npm run build:server`
|
|
284
|
+
2. Copy `dist/server/` to production
|
|
285
|
+
3. Set environment variables
|
|
286
|
+
4. Install production dependencies only
|
|
287
|
+
5. Start: `node dist/server/index.js`
|
|
288
|
+
|
|
289
|
+
### Use Redis for Sessions
|
|
290
|
+
|
|
291
|
+
Replace `server/services/sessionStore.ts` with Redis:
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
import { createClient } from 'redis';
|
|
295
|
+
|
|
296
|
+
const redis = createClient({
|
|
297
|
+
url: process.env.REDIS_URL
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
await redis.connect();
|
|
301
|
+
|
|
302
|
+
export const sessionStore = {
|
|
303
|
+
create: async (apiKey, websiteId) => {
|
|
304
|
+
const token = generateToken();
|
|
305
|
+
await redis.setEx(`session:${token}`, 86400, JSON.stringify({
|
|
306
|
+
apiKey, websiteId, createdAt: Date.now()
|
|
307
|
+
}));
|
|
308
|
+
return token;
|
|
309
|
+
},
|
|
310
|
+
get: async (token) => {
|
|
311
|
+
const data = await redis.get(`session:${token}`);
|
|
312
|
+
return data ? JSON.parse(data) : null;
|
|
313
|
+
},
|
|
314
|
+
delete: async (token) => {
|
|
315
|
+
await redis.del(`session:${token}`);
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Add Rate Limiting
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
npm install express-rate-limit
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
```typescript
|
|
327
|
+
import rateLimit from 'express-rate-limit';
|
|
328
|
+
|
|
329
|
+
const limiter = rateLimit({
|
|
330
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
|
331
|
+
max: 100 // limit each IP to 100 requests per windowMs
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
app.use('/auth/login', limiter);
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## License
|
|
338
|
+
|
|
339
|
+
MIT
|
package/EXAMPLES.md
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Example Usage
|
|
2
|
+
|
|
3
|
+
This directory contains example implementations of the `@crownpeak/dqm-react-component`.
|
|
4
|
+
|
|
5
|
+
## Basic React App Example
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import React, {useState} from 'react';
|
|
9
|
+
import {DQMSidebar} from '@crownpeak/dqm-react-component';
|
|
10
|
+
|
|
11
|
+
function App() {
|
|
12
|
+
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
13
|
+
|
|
14
|
+
// Set DQM credentials (e.g., from environment variables)
|
|
15
|
+
React.useEffect(() => {
|
|
16
|
+
localStorage.setItem('dqm_apiKey', process.env.REACT_APP_DQM_API_KEY);
|
|
17
|
+
localStorage.setItem('dqm_websiteID', process.env.REACT_APP_DQM_WEBSITE_ID);
|
|
18
|
+
}, []);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div>
|
|
22
|
+
<h1>My Application with DQM</h1>
|
|
23
|
+
<p>This page is monitored by Crownpeak DQM for quality assurance.</p>
|
|
24
|
+
|
|
25
|
+
<DQMSidebar
|
|
26
|
+
open={sidebarOpen}
|
|
27
|
+
onClose={() => setSidebarOpen(false)}
|
|
28
|
+
onOpen={() => setSidebarOpen(true)}
|
|
29
|
+
/>
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default App;
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Next.js Example
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
// pages/_app.tsx
|
|
41
|
+
import type {AppProps} from 'next/app';
|
|
42
|
+
import {useEffect, useState} from 'react';
|
|
43
|
+
import {DQMSidebar} from '@crownpeak/dqm-react-component';
|
|
44
|
+
import {createTheme} from '@mui/material/styles';
|
|
45
|
+
|
|
46
|
+
const theme = createTheme();
|
|
47
|
+
|
|
48
|
+
function MyApp({Component, pageProps}: AppProps) {
|
|
49
|
+
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
50
|
+
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (typeof window !== 'undefined') {
|
|
53
|
+
localStorage.setItem('dqm_apiKey', process.env.NEXT_PUBLIC_DQM_API_KEY!);
|
|
54
|
+
localStorage.setItem('dqm_websiteID', process.env.NEXT_PUBLIC_DQM_WEBSITE_ID!);
|
|
55
|
+
}
|
|
56
|
+
}, []);
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<>
|
|
60
|
+
<Component {...pageProps} />
|
|
61
|
+
<DQMSidebar
|
|
62
|
+
open={sidebarOpen}
|
|
63
|
+
onClose={() => setSidebarOpen(false)}
|
|
64
|
+
onOpen={() => setSidebarOpen(true)}
|
|
65
|
+
/>
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default MyApp;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## TypeScript Example with Custom Configuration
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import React, { useState, useCallback } from 'react';
|
|
77
|
+
import { DQMSidebar, ErrorBoundary } from '@crownpeak/dqm-react-component';
|
|
78
|
+
import type { DQMSidebarProps } from '@crownpeak/dqm-react-component';
|
|
79
|
+
|
|
80
|
+
interface DQMConfig {
|
|
81
|
+
apiKey: string;
|
|
82
|
+
websiteId: string;
|
|
83
|
+
enabled: boolean;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const config: DQMConfig = {
|
|
87
|
+
apiKey: process.env.REACT_APP_DQM_API_KEY!,
|
|
88
|
+
websiteId: process.env.REACT_APP_DQM_WEBSITE_ID!,
|
|
89
|
+
enabled: process.env.NODE_ENV === 'production'
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
function App() {
|
|
93
|
+
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
94
|
+
|
|
95
|
+
React.useEffect(() => {
|
|
96
|
+
if (config.enabled) {
|
|
97
|
+
localStorage.setItem('dqm_apiKey', config.apiKey);
|
|
98
|
+
localStorage.setItem('dqm_websiteID', config.websiteId);
|
|
99
|
+
}
|
|
100
|
+
}, []);
|
|
101
|
+
|
|
102
|
+
const handleOpen = useCallback(() => {
|
|
103
|
+
setSidebarOpen(true);
|
|
104
|
+
}, []);
|
|
105
|
+
|
|
106
|
+
const handleClose = useCallback(() => {
|
|
107
|
+
setSidebarOpen(false);
|
|
108
|
+
}, []);
|
|
109
|
+
|
|
110
|
+
if (!config.enabled) {
|
|
111
|
+
return <div>DQM is disabled in this environment</div>;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<ErrorBoundary>
|
|
116
|
+
<div>
|
|
117
|
+
<h1>App with DQM Quality Monitoring</h1>
|
|
118
|
+
<DQMSidebar
|
|
119
|
+
open={sidebarOpen}
|
|
120
|
+
onClose={handleClose}
|
|
121
|
+
onOpen={handleOpen}
|
|
122
|
+
/>
|
|
123
|
+
</div>
|
|
124
|
+
</ErrorBoundary>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export default App;
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Conditional Rendering (Development Only)
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
import React from 'react';
|
|
135
|
+
import { DQMSidebar } from '@crownpeak/dqm-react-component';
|
|
136
|
+
|
|
137
|
+
function App() {
|
|
138
|
+
const [sidebarOpen, setSidebarOpen] = React.useState(false);
|
|
139
|
+
const isDevelopment = process.env.NODE_ENV === 'development';
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<div>
|
|
143
|
+
<h1>My App</h1>
|
|
144
|
+
|
|
145
|
+
{/* Only show DQM in development */}
|
|
146
|
+
{isDevelopment && (
|
|
147
|
+
<DQMSidebar
|
|
148
|
+
open={sidebarOpen}
|
|
149
|
+
onClose={() => setSidebarOpen(false)}
|
|
150
|
+
onOpen={() => setSidebarOpen(true)}
|
|
151
|
+
/>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## With Custom Button Trigger
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
import React, { useState } from 'react';
|
|
162
|
+
import { DQMSidebar } from '@crownpeak/dqm-react-component';
|
|
163
|
+
import { Button } from '@mui/material';
|
|
164
|
+
import { Assessment } from '@mui/icons-material';
|
|
165
|
+
|
|
166
|
+
function App() {
|
|
167
|
+
const [sidebarOpen, setSidebarOpen] = useState(false);
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<div>
|
|
171
|
+
<header>
|
|
172
|
+
<Button
|
|
173
|
+
variant="outlined"
|
|
174
|
+
startIcon={<Assessment />}
|
|
175
|
+
onClick={() => setSidebarOpen(true)}
|
|
176
|
+
>
|
|
177
|
+
Quality Check
|
|
178
|
+
</Button>
|
|
179
|
+
</header>
|
|
180
|
+
|
|
181
|
+
<main>
|
|
182
|
+
<h1>Content</h1>
|
|
183
|
+
</main>
|
|
184
|
+
|
|
185
|
+
<DQMSidebar
|
|
186
|
+
open={sidebarOpen}
|
|
187
|
+
onClose={() => setSidebarOpen(false)}
|
|
188
|
+
onOpen={() => setSidebarOpen(true)}
|
|
189
|
+
/>
|
|
190
|
+
</div>
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Crownpeak Technology GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|