angular-data-mapper 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.
Files changed (64) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/LICENSE +190 -0
  3. package/PUBLISHING.md +75 -0
  4. package/README.md +214 -0
  5. package/angular.json +121 -0
  6. package/package.json +67 -0
  7. package/projects/demo-app/public/favicon.ico +0 -0
  8. package/projects/demo-app/src/app/app.config.ts +12 -0
  9. package/projects/demo-app/src/app/app.html +36 -0
  10. package/projects/demo-app/src/app/app.routes.ts +62 -0
  11. package/projects/demo-app/src/app/app.scss +65 -0
  12. package/projects/demo-app/src/app/app.ts +11 -0
  13. package/projects/demo-app/src/app/layout/app-layout.component.ts +294 -0
  14. package/projects/demo-app/src/app/pages/mapper-page/mapper-page.component.html +87 -0
  15. package/projects/demo-app/src/app/pages/mapper-page/mapper-page.component.scss +202 -0
  16. package/projects/demo-app/src/app/pages/mapper-page/mapper-page.component.ts +192 -0
  17. package/projects/demo-app/src/app/pages/mappings-page/add-mapping-dialog.component.ts +163 -0
  18. package/projects/demo-app/src/app/pages/mappings-page/mappings-page.component.ts +306 -0
  19. package/projects/demo-app/src/app/pages/schema-creator-page/schema-creator-page.component.ts +88 -0
  20. package/projects/demo-app/src/app/pages/schema-editor-page/schema-editor-page.component.html +108 -0
  21. package/projects/demo-app/src/app/pages/schema-editor-page/schema-editor-page.component.scss +317 -0
  22. package/projects/demo-app/src/app/pages/schema-editor-page/schema-editor-page.component.ts +129 -0
  23. package/projects/demo-app/src/app/services/app-state.service.ts +233 -0
  24. package/projects/demo-app/src/app/services/sample-data.service.ts +228 -0
  25. package/projects/demo-app/src/index.html +15 -0
  26. package/projects/demo-app/src/main.ts +6 -0
  27. package/projects/demo-app/src/styles.scss +54 -0
  28. package/projects/demo-app/tsconfig.app.json +13 -0
  29. package/projects/ngx-data-mapper/ng-package.json +7 -0
  30. package/projects/ngx-data-mapper/package.json +40 -0
  31. package/projects/ngx-data-mapper/src/lib/components/array-filter-modal/array-filter-modal.component.html +183 -0
  32. package/projects/ngx-data-mapper/src/lib/components/array-filter-modal/array-filter-modal.component.scss +352 -0
  33. package/projects/ngx-data-mapper/src/lib/components/array-filter-modal/array-filter-modal.component.ts +277 -0
  34. package/projects/ngx-data-mapper/src/lib/components/array-selector-modal/array-selector-modal.component.html +174 -0
  35. package/projects/ngx-data-mapper/src/lib/components/array-selector-modal/array-selector-modal.component.scss +357 -0
  36. package/projects/ngx-data-mapper/src/lib/components/array-selector-modal/array-selector-modal.component.ts +258 -0
  37. package/projects/ngx-data-mapper/src/lib/components/condition-builder/condition-builder.component.html +139 -0
  38. package/projects/ngx-data-mapper/src/lib/components/condition-builder/condition-builder.component.scss +213 -0
  39. package/projects/ngx-data-mapper/src/lib/components/condition-builder/condition-builder.component.ts +261 -0
  40. package/projects/ngx-data-mapper/src/lib/components/data-mapper/data-mapper.component.html +199 -0
  41. package/projects/ngx-data-mapper/src/lib/components/data-mapper/data-mapper.component.scss +321 -0
  42. package/projects/ngx-data-mapper/src/lib/components/data-mapper/data-mapper.component.ts +618 -0
  43. package/projects/ngx-data-mapper/src/lib/components/default-value-popover/default-value-popover.component.html +67 -0
  44. package/projects/ngx-data-mapper/src/lib/components/default-value-popover/default-value-popover.component.scss +97 -0
  45. package/projects/ngx-data-mapper/src/lib/components/default-value-popover/default-value-popover.component.ts +105 -0
  46. package/projects/ngx-data-mapper/src/lib/components/schema-editor/schema-editor.component.html +552 -0
  47. package/projects/ngx-data-mapper/src/lib/components/schema-editor/schema-editor.component.scss +824 -0
  48. package/projects/ngx-data-mapper/src/lib/components/schema-editor/schema-editor.component.ts +730 -0
  49. package/projects/ngx-data-mapper/src/lib/components/schema-tree/schema-tree.component.html +82 -0
  50. package/projects/ngx-data-mapper/src/lib/components/schema-tree/schema-tree.component.scss +352 -0
  51. package/projects/ngx-data-mapper/src/lib/components/schema-tree/schema-tree.component.ts +225 -0
  52. package/projects/ngx-data-mapper/src/lib/components/transformation-popover/transformation-popover.component.html +346 -0
  53. package/projects/ngx-data-mapper/src/lib/components/transformation-popover/transformation-popover.component.scss +511 -0
  54. package/projects/ngx-data-mapper/src/lib/components/transformation-popover/transformation-popover.component.ts +368 -0
  55. package/projects/ngx-data-mapper/src/lib/models/json-schema.model.ts +164 -0
  56. package/projects/ngx-data-mapper/src/lib/models/schema.model.ts +173 -0
  57. package/projects/ngx-data-mapper/src/lib/services/mapping.service.ts +615 -0
  58. package/projects/ngx-data-mapper/src/lib/services/schema-parser.service.ts +270 -0
  59. package/projects/ngx-data-mapper/src/lib/services/svg-connector.service.ts +135 -0
  60. package/projects/ngx-data-mapper/src/lib/services/transformation.service.ts +453 -0
  61. package/projects/ngx-data-mapper/src/public-api.ts +22 -0
  62. package/projects/ngx-data-mapper/tsconfig.lib.json +13 -0
  63. package/projects/ngx-data-mapper/tsconfig.lib.prod.json +9 -0
  64. package/tsconfig.json +28 -0
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Mapper Page Styles
3
+ *
4
+ * Theme Examples:
5
+ *
6
+ * DARK THEME (currently applied below):
7
+ * data-mapper {
8
+ * --data-mapper-bg: #1e293b;
9
+ * --data-mapper-panel-bg: #334155;
10
+ * --data-mapper-text-primary: #f1f5f9;
11
+ * --data-mapper-accent-primary: #818cf8;
12
+ * --data-mapper-connector-color: #818cf8;
13
+ * }
14
+ *
15
+ * LIGHT THEME:
16
+ * data-mapper {
17
+ * --data-mapper-bg: #f8fafc;
18
+ * --data-mapper-panel-bg: #ffffff;
19
+ * --data-mapper-panel-header-bg: #f1f5f9;
20
+ * --data-mapper-text-primary: #1e293b;
21
+ * --data-mapper-text-secondary: #64748b;
22
+ * --data-mapper-text-muted: #94a3b8;
23
+ * --data-mapper-accent-primary: #6366f1;
24
+ * --data-mapper-connector-color: #6366f1;
25
+ * --data-mapper-border-color: #e2e8f0;
26
+ * --data-mapper-toolbar-bg: #ffffff;
27
+ * --data-mapper-toolbar-border: #e2e8f0;
28
+ * }
29
+ *
30
+ * GREEN ACCENT THEME:
31
+ * data-mapper {
32
+ * --data-mapper-bg: #f0fdf4;
33
+ * --data-mapper-panel-bg: #ffffff;
34
+ * --data-mapper-accent-primary: #10b981;
35
+ * --data-mapper-connector-color: #10b981;
36
+ * }
37
+ */
38
+
39
+ .page-container {
40
+ height: 100%;
41
+ display: flex;
42
+ flex-direction: column;
43
+ background: #f8fafc;
44
+ box-sizing: border-box;
45
+ overflow: hidden;
46
+ }
47
+
48
+ .page-header {
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: space-between;
52
+ padding: 20px 32px;
53
+ background: white;
54
+ border-bottom: 1px solid #e2e8f0;
55
+ color: #1e293b;
56
+ flex-shrink: 0;
57
+
58
+ .header-title {
59
+ display: flex;
60
+ align-items: flex-start;
61
+ gap: 12px;
62
+
63
+ button {
64
+ color: #64748b;
65
+ margin-top: 4px;
66
+ }
67
+ }
68
+
69
+ .title-text {
70
+ .name-display {
71
+ display: flex;
72
+ align-items: center;
73
+ gap: 4px;
74
+
75
+ h1 {
76
+ font-size: 20px;
77
+ font-weight: 600;
78
+ margin: 0;
79
+ color: #0f172a;
80
+ letter-spacing: -0.3px;
81
+ }
82
+
83
+ .edit-btn {
84
+ opacity: 0;
85
+ transition: opacity 0.15s;
86
+ width: 28px;
87
+ height: 28px;
88
+ color: #94a3b8;
89
+ display: flex;
90
+ align-items: center;
91
+ justify-content: center;
92
+
93
+ mat-icon {
94
+ font-size: 16px;
95
+ width: 16px;
96
+ height: 16px;
97
+ display: flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ }
101
+
102
+ &:hover {
103
+ color: #64748b;
104
+ }
105
+ }
106
+
107
+ &:hover .edit-btn {
108
+ opacity: 1;
109
+ }
110
+ }
111
+
112
+ .name-edit {
113
+ .name-input {
114
+ font-size: 20px;
115
+ font-weight: 600;
116
+ color: #0f172a;
117
+ letter-spacing: -0.3px;
118
+ border: 1px solid #6366f1;
119
+ border-radius: 6px;
120
+ padding: 4px 8px;
121
+ outline: none;
122
+ background: white;
123
+
124
+ &:focus {
125
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
126
+ }
127
+ }
128
+ }
129
+
130
+ h1 {
131
+ font-size: 20px;
132
+ font-weight: 600;
133
+ margin: 0;
134
+ color: #0f172a;
135
+ letter-spacing: -0.3px;
136
+ }
137
+
138
+ .subtitle {
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 6px;
142
+ font-size: 13px;
143
+ color: #64748b;
144
+ margin: 2px 0 0;
145
+
146
+ .flow-icon {
147
+ font-size: 14px;
148
+ width: 14px;
149
+ height: 14px;
150
+ color: #cbd5e1;
151
+ }
152
+ }
153
+ }
154
+
155
+ .header-actions {
156
+ display: flex;
157
+ gap: 12px;
158
+ flex-wrap: wrap;
159
+
160
+ button {
161
+ display: flex;
162
+ align-items: center;
163
+ gap: 8px;
164
+ }
165
+ }
166
+ }
167
+
168
+ .page-main {
169
+ flex: 1;
170
+ display: flex;
171
+ flex-direction: column;
172
+ min-height: 0;
173
+ overflow: hidden;
174
+ padding: 24px;
175
+
176
+ data-mapper {
177
+ flex: 1;
178
+ display: flex;
179
+ flex-direction: column;
180
+ min-height: 0;
181
+ background: white;
182
+ border-radius: 12px;
183
+ border: 1px solid #e2e8f0;
184
+ overflow: hidden;
185
+
186
+ // Light theme customization
187
+ --data-mapper-bg: white;
188
+ --data-mapper-panel-bg: white;
189
+ --data-mapper-panel-header-bg: #f8fafc;
190
+ --data-mapper-panel-border: 1px solid #e2e8f0;
191
+ --data-mapper-panel-border-radius: 10px;
192
+ --data-mapper-panel-shadow: none;
193
+ --data-mapper-text-primary: #1e293b;
194
+ --data-mapper-text-secondary: #64748b;
195
+ --data-mapper-text-muted: #94a3b8;
196
+ --data-mapper-accent-primary: #6366f1;
197
+ --data-mapper-connector-color: #6366f1;
198
+ --data-mapper-border-color: #e2e8f0;
199
+ --data-mapper-toolbar-bg: white;
200
+ --data-mapper-toolbar-border: #e2e8f0;
201
+ }
202
+ }
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Mapper Page - Example usage of the DataMapperComponent
3
+ *
4
+ * This page demonstrates how to:
5
+ * 1. Use the data-mapper component
6
+ * 2. Provide source and target schemas
7
+ * 3. Handle mapping changes
8
+ * 4. Export/import mappings
9
+ * 5. Apply custom styling via CSS variables
10
+ */
11
+ import { Component, inject, OnInit, signal, computed, ViewChild, ElementRef } from '@angular/core';
12
+ import { Router, ActivatedRoute } from '@angular/router';
13
+ import { MatButtonModule } from '@angular/material/button';
14
+ import { MatIconModule } from '@angular/material/icon';
15
+ import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
16
+ import { MatTooltipModule } from '@angular/material/tooltip';
17
+ import { DataMapperComponent, SchemaDocument, FieldMapping } from '@expeed/ngx-data-mapper';
18
+ import { AppStateService } from '../../services/app-state.service';
19
+ import { SampleDataService } from '../../services/sample-data.service';
20
+
21
+ @Component({
22
+ selector: 'mapper-page',
23
+ standalone: true,
24
+ imports: [
25
+ DataMapperComponent, // Import the reusable component
26
+ MatButtonModule,
27
+ MatIconModule,
28
+ MatSnackBarModule,
29
+ MatTooltipModule,
30
+ ],
31
+ templateUrl: './mapper-page.component.html',
32
+ styleUrl: './mapper-page.component.scss',
33
+ })
34
+ export class MapperPageComponent implements OnInit {
35
+ private sampleDataService = inject(SampleDataService);
36
+ private snackBar = inject(MatSnackBar);
37
+ private router = inject(Router);
38
+ private route = inject(ActivatedRoute);
39
+ appState = inject(AppStateService);
40
+
41
+ @ViewChild('fileInput') fileInput!: ElementRef<HTMLInputElement>;
42
+ @ViewChild(DataMapperComponent) dataMapper!: DataMapperComponent;
43
+
44
+ // Current mapping ID from route
45
+ mappingId = signal<string | null>(null);
46
+
47
+ // Computed: current mapping
48
+ currentMapping = computed(() => {
49
+ const id = this.mappingId();
50
+ return this.appState.mappings().find(m => m.id === id) || null;
51
+ });
52
+
53
+ // State: schemas and mappings
54
+ sourceSchema = signal<SchemaDocument>({ type: 'object', title: '', properties: {} });
55
+ targetSchema = signal<SchemaDocument>({ type: 'object', title: '', properties: {} });
56
+ sampleData = signal<Record<string, unknown>>({});
57
+ mappings = signal<FieldMapping[]>([]);
58
+
59
+ // Name editing
60
+ isEditingName = signal(false);
61
+
62
+ startEditName(): void {
63
+ this.isEditingName.set(true);
64
+ }
65
+
66
+ cancelEditName(): void {
67
+ this.isEditingName.set(false);
68
+ }
69
+
70
+ saveName(newName: string): void {
71
+ const trimmed = newName.trim();
72
+ const id = this.mappingId();
73
+ if (id && trimmed) {
74
+ this.appState.updateMapping(id, { name: trimmed });
75
+ }
76
+ this.isEditingName.set(false);
77
+ }
78
+
79
+ ngOnInit(): void {
80
+ // Get mapping ID from route
81
+ const id = this.route.snapshot.paramMap.get('id');
82
+ this.mappingId.set(id);
83
+
84
+ if (id) {
85
+ // Load schemas based on the mapping's source and target schema IDs
86
+ const mapping = this.appState.mappings().find(m => m.id === id);
87
+ if (mapping) {
88
+ const sourceSchema = this.appState.schemas().find(s => s.id === mapping.sourceSchemaId);
89
+ const targetSchema = this.appState.schemas().find(s => s.id === mapping.targetSchemaId);
90
+
91
+ if (sourceSchema) {
92
+ const { id: _, ...schema } = sourceSchema;
93
+ this.sourceSchema.set(schema as SchemaDocument);
94
+ }
95
+ if (targetSchema) {
96
+ const { id: _, ...schema } = targetSchema;
97
+ this.targetSchema.set(schema as SchemaDocument);
98
+ }
99
+
100
+ // Load existing mapping data if available
101
+ if (mapping.mappingData) {
102
+ this.mappings.set(mapping.mappingData as FieldMapping[]);
103
+ }
104
+ }
105
+ } else {
106
+ // Fallback to sample data for demo
107
+ this.sourceSchema.set(this.sampleDataService.getSourceSchema());
108
+ this.targetSchema.set(this.sampleDataService.getTargetSchema());
109
+ }
110
+
111
+ this.sampleData.set(this.sampleDataService.getSampleData());
112
+ }
113
+
114
+ /**
115
+ * Handle mapping changes from the data mapper component
116
+ * This is called whenever the user creates, modifies, or deletes a mapping
117
+ */
118
+ onMappingsChange(mappings: FieldMapping[]): void {
119
+ this.mappings.set(mappings);
120
+
121
+ // Save mapping data to AppStateService
122
+ const id = this.mappingId();
123
+ if (id) {
124
+ this.appState.updateMappingData(id, mappings);
125
+ }
126
+ }
127
+
128
+ // --- Navigation ---
129
+
130
+ goBack(): void {
131
+ this.router.navigate(['/mappings']);
132
+ }
133
+
134
+ // --- Export/Import ---
135
+
136
+ /** Export mappings to JSON file */
137
+ exportMappings(): void {
138
+ const json = this.dataMapper.exportMappings();
139
+ const blob = new Blob([json], { type: 'application/json' });
140
+ const url = URL.createObjectURL(blob);
141
+
142
+ const link = document.createElement('a');
143
+ link.href = url;
144
+ link.download = 'mappings.json';
145
+ link.click();
146
+
147
+ URL.revokeObjectURL(url);
148
+
149
+ this.snackBar.open('Mappings exported to file', 'Close', {
150
+ duration: 3000,
151
+ });
152
+ }
153
+
154
+ /** Open file dialog for import */
155
+ importMappings(): void {
156
+ this.fileInput.nativeElement.click();
157
+ }
158
+
159
+ /** Handle file selection for import */
160
+ onFileSelected(event: Event): void {
161
+ const input = event.target as HTMLInputElement;
162
+ if (!input.files?.length) return;
163
+
164
+ const file = input.files[0];
165
+ const reader = new FileReader();
166
+
167
+ reader.onload = () => {
168
+ try {
169
+ const json = reader.result as string;
170
+ this.dataMapper.importMappings(json);
171
+ this.snackBar.open('Mappings imported successfully', 'Close', {
172
+ duration: 3000,
173
+ });
174
+ } catch (error) {
175
+ this.snackBar.open('Failed to import mappings: invalid file', 'Close', {
176
+ duration: 3000,
177
+ });
178
+ }
179
+ };
180
+
181
+ reader.readAsText(file);
182
+ input.value = '';
183
+ }
184
+
185
+ /** Clear all mappings */
186
+ clearMappings(): void {
187
+ this.dataMapper.clearAllMappings();
188
+ this.snackBar.open('All mappings cleared', 'Close', {
189
+ duration: 2000,
190
+ });
191
+ }
192
+ }
@@ -0,0 +1,163 @@
1
+ import { Component, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
5
+ import { MatButtonModule } from '@angular/material/button';
6
+ import { MatFormFieldModule } from '@angular/material/form-field';
7
+ import { MatInputModule } from '@angular/material/input';
8
+ import { MatSelectModule } from '@angular/material/select';
9
+ import { MatIconModule } from '@angular/material/icon';
10
+ import { StoredSchema } from '../../services/app-state.service';
11
+
12
+ export interface AddMappingDialogData {
13
+ schemas: StoredSchema[];
14
+ }
15
+
16
+ export interface AddMappingResult {
17
+ name: string;
18
+ sourceSchemaId: string;
19
+ targetSchemaId: string;
20
+ }
21
+
22
+ @Component({
23
+ selector: 'add-mapping-dialog',
24
+ standalone: true,
25
+ imports: [
26
+ CommonModule,
27
+ FormsModule,
28
+ MatDialogModule,
29
+ MatButtonModule,
30
+ MatFormFieldModule,
31
+ MatInputModule,
32
+ MatSelectModule,
33
+ MatIconModule,
34
+ ],
35
+ template: `
36
+ <h2 mat-dialog-title>Create New Mapping</h2>
37
+
38
+ <mat-dialog-content>
39
+ <div class="form-fields">
40
+ <mat-form-field appearance="outline" class="full-width">
41
+ <mat-label>Mapping Name</mat-label>
42
+ <input matInput [(ngModel)]="name" placeholder="e.g., Contact to Salesforce Lead">
43
+ </mat-form-field>
44
+
45
+ <mat-form-field appearance="outline" class="full-width">
46
+ <mat-label>Source Schema</mat-label>
47
+ <mat-select [(ngModel)]="sourceSchemaId">
48
+ @for (schema of data.schemas; track schema.id) {
49
+ <mat-option [value]="schema.id">
50
+ <mat-icon>schema</mat-icon>
51
+ {{ schema.title }}
52
+ </mat-option>
53
+ }
54
+ </mat-select>
55
+ <mat-hint>The schema to map from</mat-hint>
56
+ </mat-form-field>
57
+
58
+ <div class="arrow-divider">
59
+ <mat-icon>arrow_downward</mat-icon>
60
+ </div>
61
+
62
+ <mat-form-field appearance="outline" class="full-width">
63
+ <mat-label>Target Schema</mat-label>
64
+ <mat-select [(ngModel)]="targetSchemaId">
65
+ @for (schema of data.schemas; track schema.id) {
66
+ <mat-option [value]="schema.id">
67
+ <mat-icon>schema</mat-icon>
68
+ {{ schema.title }}
69
+ </mat-option>
70
+ }
71
+ </mat-select>
72
+ <mat-hint>The schema to map to</mat-hint>
73
+ </mat-form-field>
74
+
75
+ @if (data.schemas.length === 0) {
76
+ <div class="no-schemas-warning">
77
+ <mat-icon>warning</mat-icon>
78
+ <span>No schemas available. Please create schemas first.</span>
79
+ </div>
80
+ }
81
+ </div>
82
+ </mat-dialog-content>
83
+
84
+ <mat-dialog-actions align="end">
85
+ <button mat-button mat-dialog-close>Cancel</button>
86
+ <button
87
+ mat-flat-button
88
+ color="primary"
89
+ [disabled]="!isValid()"
90
+ (click)="create()"
91
+ >
92
+ Create Mapping
93
+ </button>
94
+ </mat-dialog-actions>
95
+ `,
96
+ styles: [`
97
+ .form-fields {
98
+ display: flex;
99
+ flex-direction: column;
100
+ gap: 8px;
101
+ min-width: 380px;
102
+ padding-top: 8px;
103
+ }
104
+
105
+ .full-width {
106
+ width: 100%;
107
+ }
108
+
109
+ .arrow-divider {
110
+ display: flex;
111
+ justify-content: center;
112
+ padding: 8px 0;
113
+ color: #94a3b8;
114
+
115
+ mat-icon {
116
+ font-size: 24px;
117
+ width: 24px;
118
+ height: 24px;
119
+ }
120
+ }
121
+
122
+ .no-schemas-warning {
123
+ display: flex;
124
+ align-items: center;
125
+ gap: 8px;
126
+ padding: 12px 16px;
127
+ background: #fef3c7;
128
+ border-radius: 8px;
129
+ color: #92400e;
130
+ font-size: 14px;
131
+
132
+ mat-icon {
133
+ color: #f59e0b;
134
+ }
135
+ }
136
+
137
+ mat-dialog-actions {
138
+ padding: 16px 24px;
139
+ }
140
+ `],
141
+ })
142
+ export class AddMappingDialogComponent {
143
+ private dialogRef = inject(MatDialogRef<AddMappingDialogComponent>);
144
+ data = inject<AddMappingDialogData>(MAT_DIALOG_DATA);
145
+
146
+ name = '';
147
+ sourceSchemaId = '';
148
+ targetSchemaId = '';
149
+
150
+ isValid(): boolean {
151
+ return !!(this.name.trim() && this.sourceSchemaId && this.targetSchemaId);
152
+ }
153
+
154
+ create(): void {
155
+ if (this.isValid()) {
156
+ this.dialogRef.close({
157
+ name: this.name.trim(),
158
+ sourceSchemaId: this.sourceSchemaId,
159
+ targetSchemaId: this.targetSchemaId,
160
+ } as AddMappingResult);
161
+ }
162
+ }
163
+ }