df-ae-forms-package 1.0.0 → 1.0.1
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/INTEGRATION-GUIDE.md +783 -0
- package/QUICK-START.md +205 -0
- package/README.md +29 -37
- package/TROUBLESHOOTING.md +398 -0
- 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/package.json +15 -5
package/QUICK-START.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Quick Start Guide - Ionic/Angular Integration
|
|
2
|
+
|
|
3
|
+
This is a condensed quick start guide. For detailed documentation, see [INTEGRATION-GUIDE.md](./INTEGRATION-GUIDE.md).
|
|
4
|
+
|
|
5
|
+
## 1. Install Dependencies
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install df-ae-forms-package react react-dom react-i18next lucide-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
|
|
9
|
+
npm install --save-dev @types/react @types/react-dom
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## 2. Add Styles
|
|
13
|
+
|
|
14
|
+
In `src/global.scss`:
|
|
15
|
+
|
|
16
|
+
```scss
|
|
17
|
+
@import '~df-ae-forms-package/dist/index.css';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 3. Create React Wrapper Service
|
|
21
|
+
|
|
22
|
+
Create `src/app/services/react-wrapper.service.ts`:
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { Injectable, ApplicationRef } from '@angular/core';
|
|
26
|
+
import { createElement } from 'react';
|
|
27
|
+
import { createRoot, Root } from 'react-dom/client';
|
|
28
|
+
|
|
29
|
+
@Injectable({ providedIn: 'root' })
|
|
30
|
+
export class ReactWrapperService {
|
|
31
|
+
private reactRoots: Map<string, Root> = new Map();
|
|
32
|
+
|
|
33
|
+
renderReactComponent(containerId: string, component: any, props: any): void {
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
try {
|
|
36
|
+
const container = document.getElementById(containerId);
|
|
37
|
+
if (!container) return;
|
|
38
|
+
|
|
39
|
+
container.innerHTML = '';
|
|
40
|
+
let root = this.reactRoots.get(containerId);
|
|
41
|
+
if (root) {
|
|
42
|
+
root.unmount();
|
|
43
|
+
}
|
|
44
|
+
root = createRoot(container);
|
|
45
|
+
this.reactRoots.set(containerId, root);
|
|
46
|
+
root.render(createElement(component, props));
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error('Error rendering React component:', error);
|
|
49
|
+
}
|
|
50
|
+
}, 0);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
unmountReactComponent(containerId: string): void {
|
|
54
|
+
const root = this.reactRoots.get(containerId);
|
|
55
|
+
if (root) {
|
|
56
|
+
root.unmount();
|
|
57
|
+
this.reactRoots.delete(containerId);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## 4. Setup i18n
|
|
64
|
+
|
|
65
|
+
Create `src/app/services/react-i18n.service.ts`:
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { Injectable } from '@angular/core';
|
|
69
|
+
import i18n from 'i18next';
|
|
70
|
+
import { initReactI18next } from 'react-i18next';
|
|
71
|
+
|
|
72
|
+
@Injectable({ providedIn: 'root' })
|
|
73
|
+
export class ReactI18nService {
|
|
74
|
+
async initialize(): Promise<void> {
|
|
75
|
+
await i18n.use(initReactI18next).init({
|
|
76
|
+
resources: {
|
|
77
|
+
en: { translation: { 'formBuilder.submit': 'Submit' } }
|
|
78
|
+
},
|
|
79
|
+
lng: 'en',
|
|
80
|
+
fallbackLng: 'en'
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 5. Create Form Component
|
|
87
|
+
|
|
88
|
+
Create `src/app/components/form-preview/form-preview.component.ts`:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { Component, OnInit, OnDestroy, Input, ViewChild, ElementRef, AfterViewInit, ChangeDetectorRef } from '@angular/core';
|
|
92
|
+
import { ReactWrapperService } from '../../services/react-wrapper.service';
|
|
93
|
+
import { ReactI18nService } from '../../services/react-i18n.service';
|
|
94
|
+
import type { FormComponentType, DfFormPreviewProps } from 'df-ae-forms-package';
|
|
95
|
+
|
|
96
|
+
@Component({
|
|
97
|
+
selector: 'app-form-preview',
|
|
98
|
+
template: `
|
|
99
|
+
<div *ngIf="loading">Loading...</div>
|
|
100
|
+
<div #reactContainer [id]="containerId" [style.display]="loading ? 'none' : 'block'"></div>
|
|
101
|
+
`,
|
|
102
|
+
styles: [`[id^="df-form-container"] { width: 100%; }`]
|
|
103
|
+
})
|
|
104
|
+
export class FormPreviewComponent implements OnInit, AfterViewInit, OnDestroy {
|
|
105
|
+
@Input() formComponents: FormComponentType[] = [];
|
|
106
|
+
@Input() formData: Record<string, any> = {};
|
|
107
|
+
@Input() mode: 'edit' | 'preview' | 'test' = 'test';
|
|
108
|
+
|
|
109
|
+
@ViewChild('reactContainer') container!: ElementRef;
|
|
110
|
+
loading = true;
|
|
111
|
+
containerId = `df-form-container-${Math.random().toString(36).substr(2, 9)}`;
|
|
112
|
+
private DfFormPreview: any = null;
|
|
113
|
+
|
|
114
|
+
constructor(
|
|
115
|
+
private reactWrapper: ReactWrapperService,
|
|
116
|
+
private reactI18n: ReactI18nService,
|
|
117
|
+
private cdr: ChangeDetectorRef
|
|
118
|
+
) {}
|
|
119
|
+
|
|
120
|
+
async ngOnInit(): Promise<void> {
|
|
121
|
+
await this.reactI18n.initialize();
|
|
122
|
+
// Dynamically import to avoid initialization issues
|
|
123
|
+
const module = await import('df-ae-forms-package');
|
|
124
|
+
this.DfFormPreview = module.DfFormPreview;
|
|
125
|
+
this.loading = false;
|
|
126
|
+
this.cdr.detectChanges();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
ngAfterViewInit(): void {
|
|
130
|
+
setTimeout(() => this.renderForm(), 0);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
ngOnDestroy(): void {
|
|
134
|
+
this.reactWrapper.unmountReactComponent(this.containerId);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private renderForm(): void {
|
|
138
|
+
if (!this.container || !this.DfFormPreview) return;
|
|
139
|
+
|
|
140
|
+
const props: DfFormPreviewProps = {
|
|
141
|
+
formComponents: this.formComponents,
|
|
142
|
+
initialFormData: this.formData,
|
|
143
|
+
mode: this.mode,
|
|
144
|
+
currentDevice: 'desktop',
|
|
145
|
+
onSubmit: (data) => console.log('Submitted:', data),
|
|
146
|
+
onFormDataChange: (data) => console.log('Changed:', data)
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
this.reactWrapper.renderReactComponent(this.containerId, this.DfFormPreview, props);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## 6. Use in Your Page
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { Component, OnInit } from '@angular/core';
|
|
158
|
+
import { HttpClient } from '@angular/common/http';
|
|
159
|
+
import type { FormComponentType } from 'df-ae-forms-package';
|
|
160
|
+
|
|
161
|
+
@Component({
|
|
162
|
+
template: `
|
|
163
|
+
<ion-content>
|
|
164
|
+
<app-form-preview
|
|
165
|
+
[formComponents]="formComponents"
|
|
166
|
+
[formData]="formData"
|
|
167
|
+
[mode]="'test'"
|
|
168
|
+
></app-form-preview>
|
|
169
|
+
</ion-content>
|
|
170
|
+
`
|
|
171
|
+
})
|
|
172
|
+
export class MyPage implements OnInit {
|
|
173
|
+
formComponents: FormComponentType[] = [];
|
|
174
|
+
formData: Record<string, any> = {};
|
|
175
|
+
|
|
176
|
+
constructor(private http: HttpClient) {}
|
|
177
|
+
|
|
178
|
+
ngOnInit(): void {
|
|
179
|
+
// Load form from API
|
|
180
|
+
this.http.get<{ components: FormComponentType[] }>('YOUR_API_URL')
|
|
181
|
+
.subscribe(data => {
|
|
182
|
+
this.formComponents = data.components;
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## 7. Register in Module
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
import { FormPreviewComponent } from './components/form-preview/form-preview.component';
|
|
192
|
+
import { ReactWrapperService } from './services/react-wrapper.service';
|
|
193
|
+
import { ReactI18nService } from './services/react-i18n.service';
|
|
194
|
+
|
|
195
|
+
@NgModule({
|
|
196
|
+
declarations: [FormPreviewComponent],
|
|
197
|
+
providers: [ReactWrapperService, ReactI18nService]
|
|
198
|
+
})
|
|
199
|
+
export class AppModule {}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
That's it! Your form should now render with all styles and functionality.
|
|
203
|
+
|
|
204
|
+
For complete documentation, see [INTEGRATION-GUIDE.md](./INTEGRATION-GUIDE.md).
|
|
205
|
+
|
package/README.md
CHANGED
|
@@ -10,7 +10,6 @@ A comprehensive React form preview component library with form controls, validat
|
|
|
10
10
|
- 🎯 **Conditional Logic**: Show/hide fields based on other field values
|
|
11
11
|
- 📊 **Threshold Alerts**: Visual alerts when threshold conditions are met
|
|
12
12
|
- 📝 **Component Actions**: Add notes, attachments, send emails, and raise issues for form components
|
|
13
|
-
- 🌐 **Internationalization**: Built-in i18n support via react-i18next
|
|
14
13
|
- 📱 **Device Preview**: Preview forms in different device sizes
|
|
15
14
|
- 🎨 **Customizable Styling**: CSS variables for easy theming
|
|
16
15
|
- 📦 **TypeScript**: Full TypeScript support with comprehensive type definitions
|
|
@@ -27,9 +26,11 @@ npm install df-ae-forms-package
|
|
|
27
26
|
This package requires the following peer dependencies to be installed in your project:
|
|
28
27
|
|
|
29
28
|
```bash
|
|
30
|
-
npm install react react-dom
|
|
29
|
+
npm install react react-dom lucide-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
|
|
31
30
|
```
|
|
32
31
|
|
|
32
|
+
**Note**: Translation dependencies have been removed. The package no longer requires `react-i18next` or `i18next`.
|
|
33
|
+
|
|
33
34
|
## Quick Start
|
|
34
35
|
|
|
35
36
|
### 1. Import CSS
|
|
@@ -40,30 +41,7 @@ First, import the package styles in your application:
|
|
|
40
41
|
import 'df-ae-forms-package/dist/index.css';
|
|
41
42
|
```
|
|
42
43
|
|
|
43
|
-
### 2.
|
|
44
|
-
|
|
45
|
-
The package uses `react-i18next` for internationalization. You must set up i18n in your application:
|
|
46
|
-
|
|
47
|
-
```tsx
|
|
48
|
-
import i18n from 'i18next';
|
|
49
|
-
import { initReactI18next } from 'react-i18next';
|
|
50
|
-
|
|
51
|
-
i18n
|
|
52
|
-
.use(initReactI18next)
|
|
53
|
-
.init({
|
|
54
|
-
resources: {
|
|
55
|
-
en: {
|
|
56
|
-
translation: {
|
|
57
|
-
'formBuilder.submit': 'Submit'
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
lng: 'en',
|
|
62
|
-
fallbackLng: 'en'
|
|
63
|
-
});
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 3. Use the Component
|
|
44
|
+
### 2. Use the Component
|
|
67
45
|
|
|
68
46
|
```tsx
|
|
69
47
|
import React from 'react';
|
|
@@ -394,12 +372,32 @@ npm publish
|
|
|
394
372
|
|
|
395
373
|
## Integration with Angular/Ionic
|
|
396
374
|
|
|
397
|
-
This package is designed to work with Angular/Ionic applications.
|
|
375
|
+
This package is designed to work with Angular/Ionic applications.
|
|
376
|
+
|
|
377
|
+
### Documentation
|
|
378
|
+
|
|
379
|
+
- **[Quick Start Guide](./QUICK-START.md)** - Get up and running in 5 minutes
|
|
380
|
+
- **[Complete Integration Guide](./INTEGRATION-GUIDE.md)** - Detailed step-by-step instructions with examples
|
|
398
381
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
382
|
+
### Quick Overview
|
|
383
|
+
|
|
384
|
+
1. **Install dependencies:**
|
|
385
|
+
```bash
|
|
386
|
+
npm install df-ae-forms-package react react-dom lucide-react @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
2. **Import styles** in `src/global.scss`:
|
|
390
|
+
```scss
|
|
391
|
+
@import '~df-ae-forms-package/dist/index.css';
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
3. **Set up React bridge** (see [Integration Guide](./INTEGRATION-GUIDE.md))
|
|
395
|
+
|
|
396
|
+
4. **Load form data from API** and pass to the component
|
|
397
|
+
|
|
398
|
+
For complete instructions, code examples, API integration, styling, and troubleshooting, see:
|
|
399
|
+
- **[Quick Start Guide](./QUICK-START.md)** - For a condensed setup guide
|
|
400
|
+
- **[Integration Guide](./INTEGRATION-GUIDE.md)** - For comprehensive documentation
|
|
403
401
|
|
|
404
402
|
## Troubleshooting
|
|
405
403
|
|
|
@@ -415,11 +413,6 @@ This package is designed to work with Angular/Ionic applications. To use it:
|
|
|
415
413
|
- Verify that conditional logic is not hiding components
|
|
416
414
|
- Ensure that component IDs are unique
|
|
417
415
|
|
|
418
|
-
### i18n Issues
|
|
419
|
-
|
|
420
|
-
- Make sure `react-i18next` is properly configured
|
|
421
|
-
- Verify that translation keys exist in your i18n resources
|
|
422
|
-
- Check that the i18n provider wraps your application
|
|
423
416
|
|
|
424
417
|
## Contributing
|
|
425
418
|
|
|
@@ -453,6 +446,5 @@ For issues and questions:
|
|
|
453
446
|
- Component actions (notes, attachments, email, raise issue)
|
|
454
447
|
- Responsive design
|
|
455
448
|
- TypeScript support
|
|
456
|
-
- i18n support
|
|
457
449
|
- Drag and drop support (edit mode)
|
|
458
450
|
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
# Troubleshooting Guide
|
|
2
|
+
|
|
3
|
+
## Common Issues and Solutions
|
|
4
|
+
|
|
5
|
+
### Issue: "Cannot access 'qi' before initialization" Error
|
|
6
|
+
|
|
7
|
+
**Error Message:**
|
|
8
|
+
```
|
|
9
|
+
ReferenceError: Cannot access 'qi' before initialization
|
|
10
|
+
at Module.DfFormPreview
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**Cause:**
|
|
14
|
+
This error occurs due to circular dependencies or timing issues when importing the React component in Angular.
|
|
15
|
+
|
|
16
|
+
**Solution:**
|
|
17
|
+
|
|
18
|
+
1. **Use Dynamic Imports** - Import the component asynchronously:
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// In your component
|
|
22
|
+
async ngOnInit(): Promise<void> {
|
|
23
|
+
await this.reactI18n.initialize();
|
|
24
|
+
|
|
25
|
+
// Dynamically import to avoid initialization issues
|
|
26
|
+
const module = await import('df-ae-forms-package');
|
|
27
|
+
this.DfFormPreview = module.DfFormPreview;
|
|
28
|
+
this.loading = false;
|
|
29
|
+
this.cdr.detectChanges();
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
2. **Use setTimeout in renderForm**:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
ngAfterViewInit(): void {
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
this.renderForm();
|
|
39
|
+
}, 0);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
3. **Update ReactWrapperService** to use setTimeout:
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
renderReactComponent(containerId: string, component: any, props: any): void {
|
|
47
|
+
setTimeout(() => {
|
|
48
|
+
// ... rendering code
|
|
49
|
+
}, 0);
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
4. **Ensure proper initialization order**:
|
|
54
|
+
- Initialize i18n first
|
|
55
|
+
- Then dynamically import the component
|
|
56
|
+
- Then render after view is initialized
|
|
57
|
+
|
|
58
|
+
### Issue: Styles Not Applying
|
|
59
|
+
|
|
60
|
+
**Symptoms:**
|
|
61
|
+
- Form components render but without styles
|
|
62
|
+
- CSS variables not working
|
|
63
|
+
- Components look unstyled
|
|
64
|
+
|
|
65
|
+
**Solutions:**
|
|
66
|
+
|
|
67
|
+
1. **Check CSS Import:**
|
|
68
|
+
```scss
|
|
69
|
+
// In src/global.scss or src/styles.scss
|
|
70
|
+
@import '~df-ae-forms-package/dist/index.css';
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
2. **Verify Build Configuration:**
|
|
74
|
+
- Ensure Angular is configured to include node_modules CSS
|
|
75
|
+
- Check `angular.json`:
|
|
76
|
+
```json
|
|
77
|
+
"styles": [
|
|
78
|
+
"node_modules/df-ae-forms-package/dist/index.css",
|
|
79
|
+
"src/styles.scss"
|
|
80
|
+
]
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
3. **Check CSS Variables:**
|
|
84
|
+
```scss
|
|
85
|
+
:root {
|
|
86
|
+
--df-color-primary: #3880ff;
|
|
87
|
+
// ... other variables
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
4. **Clear Build Cache:**
|
|
92
|
+
```bash
|
|
93
|
+
rm -rf .angular
|
|
94
|
+
npm run build
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Issue: React Components Not Rendering
|
|
98
|
+
|
|
99
|
+
**Symptoms:**
|
|
100
|
+
- Container div is empty
|
|
101
|
+
- No errors in console
|
|
102
|
+
- Component doesn't appear
|
|
103
|
+
|
|
104
|
+
**Solutions:**
|
|
105
|
+
|
|
106
|
+
1. **Check Container Element:**
|
|
107
|
+
```typescript
|
|
108
|
+
ngAfterViewInit(): void {
|
|
109
|
+
// Ensure container exists
|
|
110
|
+
if (!this.container?.nativeElement) {
|
|
111
|
+
console.error('Container not found');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.renderForm();
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
2. **Verify React Root Creation:**
|
|
119
|
+
```typescript
|
|
120
|
+
// Check if React root is created
|
|
121
|
+
console.log('Container:', document.getElementById(containerId));
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
3. **Check for JavaScript Errors:**
|
|
125
|
+
- Open browser console
|
|
126
|
+
- Look for any React or module errors
|
|
127
|
+
- Check network tab for failed module loads
|
|
128
|
+
|
|
129
|
+
4. **Ensure i18n is Initialized:**
|
|
130
|
+
```typescript
|
|
131
|
+
async ngOnInit(): Promise<void> {
|
|
132
|
+
await this.reactI18n.initialize(); // Must complete first
|
|
133
|
+
// Then load component
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Issue: Form Data Not Loading from API
|
|
138
|
+
|
|
139
|
+
**Symptoms:**
|
|
140
|
+
- Form renders but is empty
|
|
141
|
+
- API call succeeds but form doesn't update
|
|
142
|
+
|
|
143
|
+
**Solutions:**
|
|
144
|
+
|
|
145
|
+
1. **Check API Response Format:**
|
|
146
|
+
```typescript
|
|
147
|
+
// Ensure API returns correct format
|
|
148
|
+
{
|
|
149
|
+
components: FormComponentType[] // Array of form components
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
2. **Verify Component Update:**
|
|
154
|
+
```typescript
|
|
155
|
+
this.formService.getFormTemplate(id).subscribe({
|
|
156
|
+
next: (components) => {
|
|
157
|
+
this.formComponents = components;
|
|
158
|
+
this.cdr.detectChanges(); // Trigger change detection
|
|
159
|
+
// Re-render form if needed
|
|
160
|
+
setTimeout(() => this.renderForm(), 100);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
3. **Check Input Binding:**
|
|
166
|
+
```html
|
|
167
|
+
<app-form-preview
|
|
168
|
+
[formComponents]="formComponents"
|
|
169
|
+
[formData]="formData"
|
|
170
|
+
></app-form-preview>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Issue: Type Errors
|
|
174
|
+
|
|
175
|
+
**Symptoms:**
|
|
176
|
+
- TypeScript compilation errors
|
|
177
|
+
- Type mismatches
|
|
178
|
+
|
|
179
|
+
**Solutions:**
|
|
180
|
+
|
|
181
|
+
1. **Install Type Definitions:**
|
|
182
|
+
```bash
|
|
183
|
+
npm install --save-dev @types/react @types/react-dom
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
2. **Use Type Imports:**
|
|
187
|
+
```typescript
|
|
188
|
+
import type { FormComponentType, DfFormPreviewProps } from 'df-ae-forms-package';
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
3. **Check TypeScript Configuration:**
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"compilerOptions": {
|
|
195
|
+
"skipLibCheck": true,
|
|
196
|
+
"esModuleInterop": true
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Issue: i18n Not Working
|
|
202
|
+
|
|
203
|
+
**Symptoms:**
|
|
204
|
+
- Translation keys show as-is
|
|
205
|
+
- "formBuilder.submit" instead of "Submit"
|
|
206
|
+
|
|
207
|
+
**Solutions:**
|
|
208
|
+
|
|
209
|
+
1. **Verify i18n Initialization:**
|
|
210
|
+
```typescript
|
|
211
|
+
async ngOnInit(): Promise<void> {
|
|
212
|
+
await this.reactI18n.initialize(); // Must be awaited
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
2. **Check Translation Resources:**
|
|
217
|
+
```typescript
|
|
218
|
+
resources: {
|
|
219
|
+
en: {
|
|
220
|
+
translation: {
|
|
221
|
+
'formBuilder.submit': 'Submit'
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
3. **Ensure react-i18next is Installed:**
|
|
228
|
+
```bash
|
|
229
|
+
npm install react-i18next i18next
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Issue: Memory Leaks
|
|
233
|
+
|
|
234
|
+
**Symptoms:**
|
|
235
|
+
- Performance degrades over time
|
|
236
|
+
- Multiple form instances in memory
|
|
237
|
+
|
|
238
|
+
**Solutions:**
|
|
239
|
+
|
|
240
|
+
1. **Always Unmount in ngOnDestroy:**
|
|
241
|
+
```typescript
|
|
242
|
+
ngOnDestroy(): void {
|
|
243
|
+
this.reactWrapper.unmountReactComponent(this.containerId);
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
2. **Clean Up Subscriptions:**
|
|
248
|
+
```typescript
|
|
249
|
+
private destroy$ = new Subject<void>();
|
|
250
|
+
|
|
251
|
+
ngOnInit(): void {
|
|
252
|
+
this.formService.getFormTemplate(id)
|
|
253
|
+
.pipe(takeUntil(this.destroy$))
|
|
254
|
+
.subscribe(/* ... */);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
ngOnDestroy(): void {
|
|
258
|
+
this.destroy$.next();
|
|
259
|
+
this.destroy$.complete();
|
|
260
|
+
this.reactWrapper.unmountReactComponent(this.containerId);
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Issue: Form Submission Not Working
|
|
265
|
+
|
|
266
|
+
**Symptoms:**
|
|
267
|
+
- Submit button doesn't trigger
|
|
268
|
+
- onSubmit callback not called
|
|
269
|
+
|
|
270
|
+
**Solutions:**
|
|
271
|
+
|
|
272
|
+
1. **Check onSubmit Prop:**
|
|
273
|
+
```typescript
|
|
274
|
+
const props: DfFormPreviewProps = {
|
|
275
|
+
// ... other props
|
|
276
|
+
onSubmit: (formData: Record<string, any>) => {
|
|
277
|
+
console.log('Form submitted:', formData);
|
|
278
|
+
// Handle submission
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
2. **Verify Form Validation:**
|
|
284
|
+
- Check if validation errors are preventing submission
|
|
285
|
+
- Ensure all required fields are filled
|
|
286
|
+
|
|
287
|
+
3. **Check Mode:**
|
|
288
|
+
```typescript
|
|
289
|
+
mode: 'test' // Must be 'test' for interactive forms
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Issue: Conditional Logic Not Working
|
|
293
|
+
|
|
294
|
+
**Symptoms:**
|
|
295
|
+
- Fields don't show/hide based on conditions
|
|
296
|
+
- Conditional logic seems ignored
|
|
297
|
+
|
|
298
|
+
**Solutions:**
|
|
299
|
+
|
|
300
|
+
1. **Verify Conditional Structure:**
|
|
301
|
+
```typescript
|
|
302
|
+
conditional: {
|
|
303
|
+
action: 'show', // or 'hide'
|
|
304
|
+
when: 'all', // or 'any'
|
|
305
|
+
conditions: [{
|
|
306
|
+
fieldId: 'other-field-id',
|
|
307
|
+
operator: 'equals', // or other operators
|
|
308
|
+
value: 'expected-value'
|
|
309
|
+
}]
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
2. **Check Field IDs:**
|
|
314
|
+
- Ensure fieldId in conditions matches actual component IDs
|
|
315
|
+
- IDs must be unique
|
|
316
|
+
|
|
317
|
+
3. **Verify Form Values:**
|
|
318
|
+
- Conditional logic uses current form values
|
|
319
|
+
- Ensure values are being tracked correctly
|
|
320
|
+
|
|
321
|
+
### Issue: Performance Issues
|
|
322
|
+
|
|
323
|
+
**Symptoms:**
|
|
324
|
+
- Slow rendering
|
|
325
|
+
- Laggy interactions
|
|
326
|
+
|
|
327
|
+
**Solutions:**
|
|
328
|
+
|
|
329
|
+
1. **Use OnPush Change Detection:**
|
|
330
|
+
```typescript
|
|
331
|
+
@Component({
|
|
332
|
+
changeDetection: ChangeDetectionStrategy.OnPush
|
|
333
|
+
})
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
2. **Debounce Form Updates:**
|
|
337
|
+
```typescript
|
|
338
|
+
import { debounceTime } from 'rxjs/operators';
|
|
339
|
+
|
|
340
|
+
onFormDataChange(formData: Record<string, any>): void {
|
|
341
|
+
// Debounce updates
|
|
342
|
+
this.updateSubject.next(formData);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
private updateSubject = new Subject<Record<string, any>>();
|
|
346
|
+
|
|
347
|
+
ngOnInit(): void {
|
|
348
|
+
this.updateSubject.pipe(
|
|
349
|
+
debounceTime(300)
|
|
350
|
+
).subscribe(data => {
|
|
351
|
+
// Handle updates
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
3. **Lazy Load Forms:**
|
|
357
|
+
- Only load form when needed
|
|
358
|
+
- Unmount when not visible
|
|
359
|
+
|
|
360
|
+
## Getting Help
|
|
361
|
+
|
|
362
|
+
If you're still experiencing issues:
|
|
363
|
+
|
|
364
|
+
1. Check the browser console for detailed error messages
|
|
365
|
+
2. Verify all dependencies are installed correctly
|
|
366
|
+
3. Ensure you're using the latest version of the package
|
|
367
|
+
4. Review the [Integration Guide](./INTEGRATION-GUIDE.md) for complete setup
|
|
368
|
+
5. Check the [README](./README.md) for package-specific documentation
|
|
369
|
+
|
|
370
|
+
## Debugging Tips
|
|
371
|
+
|
|
372
|
+
1. **Enable React DevTools:**
|
|
373
|
+
```bash
|
|
374
|
+
npm install --save-dev @types/react-dom
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
2. **Add Console Logs:**
|
|
378
|
+
```typescript
|
|
379
|
+
private renderForm(): void {
|
|
380
|
+
console.log('Rendering form with:', {
|
|
381
|
+
components: this.formComponents.length,
|
|
382
|
+
data: this.formData,
|
|
383
|
+
container: this.container?.nativeElement
|
|
384
|
+
});
|
|
385
|
+
// ... rendering code
|
|
386
|
+
}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
3. **Check Network Tab:**
|
|
390
|
+
- Verify module loads
|
|
391
|
+
- Check for failed requests
|
|
392
|
+
- Ensure CSS files load
|
|
393
|
+
|
|
394
|
+
4. **Inspect DOM:**
|
|
395
|
+
- Check if React root is created
|
|
396
|
+
- Verify container element exists
|
|
397
|
+
- Look for React error boundaries
|
|
398
|
+
|