@bagelink/vue 1.4.14 → 1.4.16

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.
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts" generic="T">
2
2
  import type { BglFormSchemaT, Option } from '@bagelink/vue'
3
+ import type { MaybeRefOrGetter } from 'vue'
3
4
  import type { Field } from '../types/BagelForm'
4
5
  import {
5
6
  Btn,
@@ -13,13 +14,12 @@ import {
13
14
  useExcel,
14
15
  DragOver,
15
16
  } from '@bagelink/vue'
16
- import { computed, reactive, ref, watch, watchEffect } from 'vue'
17
+ import { computed, reactive, ref, watch, watchEffect, toValue } from 'vue'
17
18
 
18
19
  import { useSchemaField } from '../composables/useSchemaField'
19
20
  import { formatString } from '../utils/strings'
20
21
  import TextInput from './form/inputs/TextInput.vue'
21
22
 
22
- // Add interface for schema items
23
23
  interface SchemaItem {
24
24
  id: string
25
25
  label: string
@@ -56,7 +56,7 @@ interface Transformation {
56
56
  }
57
57
 
58
58
  const props = defineProps<{
59
- schema?: BglFormSchemaT<T>
59
+ schema?: MaybeRefOrGetter<BglFormSchemaT<T>>
60
60
  title?: string
61
61
  }>()
62
62
 
@@ -91,57 +91,40 @@ const dataTypeOptions = [
91
91
  { value: DATA_TYPES.BOOLEAN, label: 'Boolean' }
92
92
  ]
93
93
 
94
- // Component state
95
94
  const file = ref<File | null>(null)
96
95
  const fileData = ref<any[]>([])
97
96
  const sheetNames = ref<string[]>([])
98
97
  const selectedSheet = ref<string>('')
99
98
  const hasHeaders = ref(true)
100
- const fieldMapping = reactive<Record<string, string>>({})
101
99
  const isLoading = ref(false)
102
100
  const showPreviewModal = ref(false)
103
101
  const previewData = ref<any[]>([])
104
102
  const mappingComplete = ref(false)
105
103
  const fileHeaders = ref<string[]>([])
106
-
107
- // New state for constant values and transformations
108
- const defaultValues = reactive<Record<string, any>>({})
109
-
110
- // State for transformations
111
- const transformations = reactive<Record<string, Transformation[]>>({})
112
104
  const showTransformDialog = ref(false)
113
105
  const selectedTransformField = ref<SchemaItem | null>(null)
106
+ const showRelatedDialog = ref(false)
107
+ const selectedRelationField = ref<SchemaItem | null>(null)
108
+ const selectedSourceValue = ref('')
109
+ const selectedTargetValue = ref('')
110
+ const showRelatedTransformDialog = ref(false)
111
+ const selectedRelatedTransformField = ref<{ parentId: string, field: SchemaItem } | null>(null)
112
+ const selectedRelatedSourceValue = ref('')
113
+ const selectedRelatedTargetValue = ref('')
114
114
 
115
- // State for data types
115
+ const fieldMapping = reactive<Record<string, string>>({})
116
+ const defaultValues = reactive<Record<string, any>>({})
117
+ const transformations = reactive<Record<string, Transformation[]>>({})
116
118
  const fieldDataTypes = reactive<Record<string, string>>({})
117
-
118
- // State for related data
119
119
  const relatedFiles = reactive<Record<string, File | null>>({})
120
120
  const relatedFileData = reactive<Record<string, any[]>>({})
121
121
  const relatedFileMappings = reactive<Record<string, Record<string, string>>>({})
122
- const showRelatedDialog = ref(false)
123
- const selectedRelationField = ref<SchemaItem | null>(null)
124
122
  const relatedKeyField = reactive<Record<string, string>>({})
125
123
  const parentKeyField = reactive<Record<string, string>>({})
126
-
127
- // Improve the transformations management
128
- const selectedSourceValue = ref('')
129
- const selectedTargetValue = ref('')
130
-
131
- // State for related field data types
132
124
  const relatedFieldDataTypes = reactive<Record<string, string>>({})
133
-
134
- // State for related default values
135
125
  const relatedDefaultValues = reactive<Record<string, Record<string, any>>>({})
136
-
137
- // State for related transformations
138
126
  const relatedTransformations = reactive<Record<string, Record<string, Transformation[]>>>({})
139
- const showRelatedTransformDialog = ref(false)
140
- const selectedRelatedTransformField = ref<{ parentId: string, field: SchemaItem } | null>(null)
141
- const selectedRelatedSourceValue = ref('')
142
- const selectedRelatedTargetValue = ref('')
143
127
 
144
- // Set up schema field rendering
145
128
  const formData = ref<any>({})
146
129
  const { renderField } = useSchemaField<any, any>({
147
130
  mode: 'form',
@@ -149,7 +132,6 @@ const { renderField } = useSchemaField<any, any>({
149
132
  onUpdateModelValue: (field: Field<any>, value: any) => {
150
133
  if (!field.id) return
151
134
 
152
- // Check if this is a related field (id contains a dot)
153
135
  if (field.id.includes('.')) {
154
136
  const [parentId, childId] = field.id.split('.')
155
137
  if (!relatedDefaultValues[parentId]) {
@@ -157,19 +139,15 @@ const { renderField } = useSchemaField<any, any>({
157
139
  }
158
140
  relatedDefaultValues[parentId][childId] = value
159
141
  } else {
160
- // Regular field
161
142
  defaultValues[field.id] = value
162
143
  }
163
144
  }
164
145
  })
165
146
 
166
- // Add function to get unique source values for a field
167
147
  function getUniqueSourceValues(fieldId: string): any[] {
168
148
  if (!fieldMapping[fieldId] || !fileData.value || fileData.value.length === 0) {
169
149
  return []
170
150
  }
171
-
172
- // Get all values from the mapped column
173
151
  const allValues = fileData.value
174
152
  .map(row => row[fieldMapping[fieldId]])
175
153
  .filter(value => value !== undefined && value !== null && value !== '')
@@ -191,7 +169,6 @@ const availableSourceValues = computed(() => {
191
169
  return getUniqueSourceValues(selectedTransformField.value.id)
192
170
  })
193
171
 
194
- // Create options array from unique values
195
172
  const sourceValueOptions = computed(() => {
196
173
  return availableSourceValues.value.map(value => ({
197
174
  value: String(value),
@@ -199,17 +176,11 @@ const sourceValueOptions = computed(() => {
199
176
  }))
200
177
  })
201
178
 
202
- // Fix the findMatchingTargetValue function to handle Option types correctly
203
179
  function findMatchingTargetValue(sourceValue: string, options: Option[]): string | null {
204
180
  if (!sourceValue || !options || !Array.isArray(options) || options.length === 0) return null
205
-
206
- // Convert sourceValue to string and lowercase for comparison
207
181
  const lowerSourceValue = String(sourceValue).toLowerCase().trim()
208
-
209
- // First try exact match
210
182
  const exactMatch = options.find((option) => {
211
183
  const optionObj = typeof option === 'object' && option !== null ? option : { value: String(option), label: String(option) }
212
- // Make sure option and label exist and is a string
213
184
  if (!optionObj) return false
214
185
  const optionLabel = `${optionObj.label}`.toLowerCase().trim()
215
186
  return optionLabel === lowerSourceValue
@@ -229,7 +200,6 @@ function findMatchingTargetValue(sourceValue: string, options: Option[]): string
229
200
 
230
201
  const optionLabel = `${optionObj.label}`.toLowerCase().trim()
231
202
 
232
- // Try contains match
233
203
  return lowerSourceValue.includes(optionLabel) || optionLabel.includes(lowerSourceValue)
234
204
  })
235
205
 
@@ -243,7 +213,6 @@ function findMatchingTargetValue(sourceValue: string, options: Option[]): string
243
213
  return null
244
214
  }
245
215
 
246
- // Watch for changes in selected source value and auto-match if enabled
247
216
  watch(selectedSourceValue, (newValue) => {
248
217
  if (selectedTransformField.value?.options) {
249
218
  const matchedValue = findMatchingTargetValue(newValue, selectedTransformField.value.options)
@@ -253,22 +222,18 @@ watch(selectedSourceValue, (newValue) => {
253
222
  }
254
223
  })
255
224
 
256
- // Add a transformation
257
225
  function addTransformation(fieldId: string) {
258
226
  if (!transformations[fieldId]) {
259
227
  transformations[fieldId] = []
260
228
  }
261
229
 
262
230
  if (selectedSourceValue.value && selectedTargetValue.value) {
263
- // Check if this source value already has a transformation
264
231
  const existingIndex = transformations[fieldId].findIndex(t => t.sourceValue === selectedSourceValue.value
265
232
  )
266
233
 
267
234
  if (existingIndex >= 0) {
268
- // Update existing transformation
269
235
  transformations[fieldId][existingIndex].targetValue = selectedTargetValue.value
270
236
  } else {
271
- // Add new transformation
272
237
  transformations[fieldId].push({
273
238
  fieldId,
274
239
  sourceValue: selectedSourceValue.value,
@@ -280,7 +245,6 @@ function addTransformation(fieldId: string) {
280
245
  }
281
246
  }
282
247
 
283
- // Create a revised function to extract fields from the schema structure without duplicates
284
248
  function getAllFields(schema: any[]): any[] {
285
249
  if (!schema || !Array.isArray(schema)) return []
286
250
 
@@ -312,18 +276,11 @@ function getAllFields(schema: any[]): any[] {
312
276
  if (item && item.id && item.label) {
313
277
  addFieldIfNew(item)
314
278
  }
315
-
316
- // Containers with children (like flex divs)
317
279
  if (item && item.children && Array.isArray(item.children)) {
318
- // Process each child
319
280
  item.children.forEach((child: any) => {
320
- // Regular fields
321
281
  if (child && child.id && child.label) {
322
- // Check if it's an array field
323
282
  if (child.$el === 'array' && child.attrs && child.attrs.schema) {
324
- // Add the array field itself (phones, emails)
325
283
  addFieldIfNew(child)
326
-
327
284
  if (Array.isArray(child.attrs.schema)) {
328
285
  child.attrs.schema.forEach((schemaItem: SchemaItem) => {
329
286
  if (schemaItem && schemaItem.id && schemaItem.label) {
@@ -339,7 +296,6 @@ function getAllFields(schema: any[]): any[] {
339
296
  } else if (schemaItem.attrs && schemaItem.attrs.options) {
340
297
  qualifiedField.options = schemaItem.attrs.options
341
298
  }
342
-
343
299
  addFieldIfNew(qualifiedField)
344
300
  }
345
301
  })
@@ -355,26 +311,19 @@ function getAllFields(schema: any[]): any[] {
355
311
  return allFields
356
312
  }
357
313
 
358
- // Get extracted fields from schema
359
- const schemaFields = computed(() => {
360
- return getAllFields(props.schema || [])
361
- })
314
+ const schemaFields = computed(() => getAllFields(toValue(props.schema) || []))
362
315
 
363
- // Update the isFieldRequired function to handle the special case for array fields
364
316
  function isFieldRequired(field: any): boolean {
365
317
  if (field.isArrayField && field.parentField) {
366
318
  return false
367
319
  }
368
320
 
369
- // For regular fields, check the standard required attributes
370
321
  return (field.attrs && field.attrs.required === true)
371
322
  || (field.required === true)
372
323
  || (field.attrs && field.attrs.attrs && field.attrs.attrs.required === true)
373
324
  }
374
325
 
375
- // Add a function to get field display information including conditional requirements
376
326
  function getFieldDescription(field: any): { description: string, isConditional: boolean } {
377
- // For array child fields, show they're conditionally required
378
327
  if (field.isArrayField && field.parentField) {
379
328
  const parentLabel = schemaFields.value.find(f => f.id === field.parentField)?.label || field.parentField
380
329
  return {
@@ -382,8 +331,6 @@ function getFieldDescription(field: any): { description: string, isConditional:
382
331
  isConditional: true
383
332
  }
384
333
  }
385
-
386
- // No special handling needed
387
334
  return {
388
335
  description: '',
389
336
  isConditional: false
@@ -405,12 +352,10 @@ async function parseFile(file: File) {
405
352
  }
406
353
  }
407
354
 
408
- // Replace loadSheetData function with simplified version
409
355
  async function loadSheetData() {
410
356
  if (!file.value || !selectedSheet.value) return
411
357
  isLoading.value = true
412
358
  try {
413
- // Use the readSheetData utility from our composable
414
359
  const { headers, data } = await readSheetData(file.value, selectedSheet.value, hasHeaders.value)
415
360
 
416
361
  fileHeaders.value = headers
@@ -424,21 +369,16 @@ async function loadSheetData() {
424
369
  }
425
370
  }
426
371
 
427
- // Add a function to check if a field is related to an array parent that's already mapped
428
372
  function checkArrayFieldConflicts() {
429
- // Get all array parent fields that are currently mapped
430
373
  const mappedArrayParents = new Set()
431
- const mappedArrayChildren = new Map() // Map from parent ID to child IDs
374
+ const mappedArrayChildren = new Map()
432
375
 
433
- // Identify which array parents and children are mapped
434
376
  Object.keys(fieldMapping).forEach((fieldId: string) => {
435
377
  const field = schemaFields.value.find(f => f.id === fieldId)
436
378
  if (field) {
437
379
  if (field.$el === 'array') {
438
- // This is an array parent
439
380
  mappedArrayParents.add(field.id)
440
381
  } else if (field.isArrayField && field.parentField) {
441
- // This is an array child
442
382
  if (!mappedArrayChildren.has(field.parentField)) {
443
383
  mappedArrayChildren.set(field.parentField, new Set())
444
384
  }
@@ -447,7 +387,6 @@ function checkArrayFieldConflicts() {
447
387
  }
448
388
  })
449
389
 
450
- // For each array parent that's mapped, disable its children
451
390
  for (const parentId of mappedArrayParents) {
452
391
  const childFields = schemaFields.value.filter(f => f.parentField === parentId)
453
392
  childFields.forEach((child: any) => {
@@ -456,7 +395,6 @@ function checkArrayFieldConflicts() {
456
395
  })
457
396
  }
458
397
 
459
- // For each array child that's mapped, disable its parent
460
398
  for (const [parentId, childIds] of mappedArrayChildren.entries()) {
461
399
  if (childIds.size > 0) {
462
400
  const parentField = schemaFields.value.find(f => f.id === parentId)
@@ -468,14 +406,11 @@ function checkArrayFieldConflicts() {
468
406
  }
469
407
  }
470
408
 
471
- // Modify the resetMapping function to call checkArrayFieldConflicts
472
409
  function resetMapping() {
473
- // Reset field mapping
474
410
  Object.keys(fieldMapping).forEach((key: string) => {
475
411
  delete fieldMapping[key]
476
412
  })
477
413
 
478
- // Reset disabled state on all fields
479
414
  schemaFields.value.forEach((field: any) => {
480
415
  field.disabled = false
481
416
  field.disabledReason = ''
@@ -522,38 +457,29 @@ function resetMapping() {
522
457
  })
523
458
  }
524
459
 
525
- // Check for array field conflicts
526
460
  checkArrayFieldConflicts()
527
461
  checkMappingComplete()
528
462
  }
529
463
 
530
- // Simplify the checkMappingComplete function to match canProcessData
531
464
  function checkMappingComplete() {
532
- // Use the same logic as canProcessData for consistency
533
465
  if (!file.value || (Object.keys(fieldMapping).length === 0 && Object.keys(defaultValues).length === 0)) {
534
466
  mappingComplete.value = false
535
467
  return
536
468
  }
537
469
 
538
- // Get strictly required fields (non-conditional)
539
470
  const requiredFields = schemaFields.value.filter((field) => {
540
- // Exclude array children which are conditionally required
541
471
  if (field.isArrayField && field.parentField) return false
542
472
 
543
- // Check various ways a field might be marked as required
544
473
  return (field.attrs && field.attrs.required === true)
545
474
  || (field.required === true)
546
475
  || (field.attrs && field.attrs.attrs && field.attrs.attrs.required === true)
547
476
  })
548
477
 
549
- // If no strictly required fields, we just need at least one mapping or default value
550
478
  if (requiredFields.length === 0) {
551
479
  mappingComplete.value = Object.keys(fieldMapping).some(key => !!fieldMapping[key])
552
480
  || Object.keys(defaultValues).length > 0
553
481
  return
554
482
  }
555
-
556
- // Check that all required fields are mapped or have default values
557
483
  mappingComplete.value = requiredFields.every(field => !!fieldMapping[field.id] || hasDefaultValue(field.id))
558
484
  }
559
485
 
@@ -566,34 +492,24 @@ function showPreview() {
566
492
  const mappedRow: MappedRow = {}
567
493
 
568
494
  schemaFields.value.forEach((field) => {
569
- // Skip array fields as they're handled separately
570
495
  if (field.isArrayField || field.$el === 'array') return
571
-
572
- // Get value from mapping or use default
573
496
  let value: any = null
574
497
  let useDefault = false
575
498
 
576
499
  if (fieldMapping[field.id] && sourceRow[fieldMapping[field.id]] !== undefined) {
577
500
  value = sourceRow[fieldMapping[field.id]]
578
- // Use default value as fallback if the mapped value is empty
579
501
  if (value === '' && defaultValues[field.id] !== undefined) {
580
502
  value = defaultValues[field.id]
581
503
  useDefault = true
582
504
  }
583
505
  } else if (defaultValues[field.id] !== undefined) {
584
- // Use default value if no direct mapping or mapping is empty
585
506
  value = defaultValues[field.id]
586
507
  useDefault = true
587
508
  }
588
509
 
589
- // Skip if no value
590
- if (value === null) {
591
- return
592
- }
510
+ if (value === null) return
593
511
 
594
- // Apply transformations if any exist and not using default value
595
512
  if (!useDefault && transformations[field.id] && transformations[field.id].length > 0) {
596
- // Find matching transformation
597
513
  const transform = transformations[field.id].find(t => t.sourceValue == value || t.sourceValue === String(value)
598
514
  )
599
515
  if (transform) {
@@ -601,21 +517,17 @@ function showPreview() {
601
517
  }
602
518
  }
603
519
 
604
- // Apply data type conversion
605
520
  const dataType = fieldDataTypes[field.id] || DATA_TYPES.STRING
606
521
  value = convertValueByType(value, dataType)
607
522
 
608
523
  if (field.id.includes('.')) {
609
- // Handle dot notation for nested objects
610
524
  const parts = field.id.split('.')
611
525
  const rootField = parts[0]
612
526
 
613
- // Create nested structure
614
527
  if (!mappedRow[rootField]) {
615
528
  mappedRow[rootField] = {}
616
529
  }
617
530
 
618
- // Handle multi-level nesting
619
531
  let current = mappedRow[rootField]
620
532
  for (let i = 1; i < parts.length - 1; i++) {
621
533
  if (!current[parts[i]]) {
@@ -624,51 +536,41 @@ function showPreview() {
624
536
  current = current[parts[i]]
625
537
  }
626
538
 
627
- // Set the value at the final level
628
539
  current[parts[parts.length - 1]] = value
629
540
  } else {
630
541
  mappedRow[field.id] = value
631
542
  }
632
543
  })
633
544
 
634
- // Process array child fields
635
545
  const arrayChildFields = schemaFields.value.filter(field => field.isArrayField && field.parentField)
636
546
 
637
- // Process each array field
638
547
  arrayChildFields.forEach((childField) => {
639
548
  const [parentId, childId] = childField.id.split('.')
640
549
  if (!parentId || !childId) return
641
550
 
642
- // Get value from mapping or use default
643
551
  let value: any = null
644
552
  let useDefault = false
645
553
 
646
554
  if (fieldMapping[childField.id] && sourceRow[fieldMapping[childField.id]] !== undefined) {
647
555
  value = sourceRow[fieldMapping[childField.id]]
648
- // Use default value as fallback if the mapped value is empty
649
556
  if (value === '' && defaultValues[childField.id] !== undefined) {
650
557
  value = defaultValues[childField.id]
651
558
  useDefault = true
652
559
  }
653
560
  } else if (defaultValues[childField.id] !== undefined) {
654
- // Use default value if no direct mapping
655
561
  value = defaultValues[childField.id]
656
562
  useDefault = true
657
563
  }
658
564
 
659
- // Skip if no value
660
565
  if (value === null) {
661
566
  return
662
567
  }
663
568
 
664
- // Create the array structure if it doesn't exist
665
569
  if (!mappedRow[parentId]) {
666
570
  mappedRow[parentId] = []
667
571
  }
668
572
 
669
- // Apply transformations if any exist and not using default
670
573
  if (!useDefault && transformations[childField.id] && transformations[childField.id].length > 0) {
671
- // Find matching transformation
672
574
  const transform = transformations[childField.id].find(t => t.sourceValue == value || t.sourceValue === String(value)
673
575
  )
674
576
  if (transform) {
@@ -676,71 +578,57 @@ function showPreview() {
676
578
  }
677
579
  }
678
580
 
679
- // Apply data type conversion for array fields
680
581
  const dataType = fieldDataTypes[childField.id] || DATA_TYPES.STRING
681
582
  value = convertValueByType(value, dataType)
682
583
 
683
- // Add the array item with the proper structure
684
584
  mappedRow[parentId].push({
685
585
  [childId]: value
686
586
  })
687
587
  })
688
588
 
689
- // Handle related file data
690
589
  Object.keys(relatedFiles).forEach((fieldId) => {
691
590
  if (!relatedFiles[fieldId] || !relatedKeyField[fieldId] || !parentKeyField[fieldId]) {
692
591
  return
693
592
  }
694
593
 
695
- // Get parent key value from this row
696
594
  const parentKeyValue = sourceRow[parentKeyField[fieldId]]
697
595
  if (!parentKeyValue) return
698
596
 
699
- // Create the array structure if it doesn't exist
700
597
  if (!mappedRow[fieldId]) {
701
598
  mappedRow[fieldId] = []
702
599
  }
703
600
 
704
- // Find matching rows in related data
705
601
  const matchingRows = relatedFileData[fieldId].filter(relatedRow => relatedRow[relatedKeyField[fieldId]] == parentKeyValue
706
602
  || relatedRow[relatedKeyField[fieldId]] === parentKeyValue.toString()
707
603
  )
708
604
 
709
- // Add each matching row as an item in the array
710
605
  matchingRows.forEach((matchingRow) => {
711
606
  const mappedItem: Record<string, any> = {}
712
607
 
713
- // Apply mappings from related file
714
608
  if (selectedRelationField.value?.attrs?.schema) {
715
609
  selectedRelationField.value.attrs.schema.forEach((schemaItem: SchemaItem) => {
716
610
  if (!schemaItem.id) return
717
611
 
718
- // Get value from related mapping or use default
719
612
  let value: any = null
720
613
  let useDefault = false
721
614
 
722
615
  if (relatedFileMappings[fieldId][schemaItem.id]
723
616
  && matchingRow[relatedFileMappings[fieldId][schemaItem.id]] !== undefined) {
724
617
  value = matchingRow[relatedFileMappings[fieldId][schemaItem.id]]
725
- // Use default as fallback for empty values
726
618
  if (value === '' && relatedDefaultValues[fieldId][schemaItem.id] !== undefined) {
727
619
  value = relatedDefaultValues[fieldId][schemaItem.id]
728
620
  useDefault = true
729
621
  }
730
622
  } else if (relatedDefaultValues[fieldId][schemaItem.id] !== undefined) {
731
- // Use default value if no mapping
732
623
  value = relatedDefaultValues[fieldId][schemaItem.id]
733
624
  useDefault = true
734
625
  }
735
626
 
736
- // Skip if no value
737
627
  if (value === null) return
738
628
 
739
- // Apply transformations if any exist and not using default
740
629
  if (!useDefault
741
630
  && relatedTransformations[fieldId][schemaItem.id]
742
631
  && relatedTransformations[fieldId][schemaItem.id].length > 0) {
743
- // Find matching transformation
744
632
  const transform = relatedTransformations[fieldId][schemaItem.id].find(t => t.sourceValue == value || t.sourceValue === String(value)
745
633
  )
746
634
  if (transform) {
@@ -748,24 +636,20 @@ function showPreview() {
748
636
  }
749
637
  }
750
638
 
751
- // Apply data type conversion
752
639
  const fullChildId = `${fieldId}.${schemaItem.id}`
753
640
  const dataType = relatedFieldDataTypes[fullChildId] || DATA_TYPES.STRING
754
641
  value = convertValueByType(value, dataType)
755
642
 
756
- // Add to mapped item
757
643
  mappedItem[schemaItem.id] = value
758
644
  })
759
645
  }
760
646
 
761
- // Only add item if it has at least one value
762
647
  if (Object.keys(mappedItem).length > 0) {
763
648
  mappedRow[fieldId].push(mappedItem)
764
649
  }
765
650
  })
766
651
  })
767
652
 
768
- // Check if this row has any data (not empty)
769
653
  const hasData = Object.values(mappedRow).some((value) => {
770
654
  if (value === null || value === undefined) return false
771
655
  if (value === '') return false
@@ -773,39 +657,30 @@ function showPreview() {
773
657
  return true
774
658
  })
775
659
 
776
- // Only add rows that have data
777
660
  if (hasData) {
778
661
  mappedData.push(mappedRow)
779
662
  }
780
663
  }
781
664
 
782
- // Update the preview data with all non-empty rows
783
665
  previewData.value = mappedData
784
-
785
- // Show the modal
786
666
  showPreviewModal.value = true
787
667
  }
788
668
 
789
- // Create a function to convert our schema fields to Spreadsheet column config
790
669
  function createSpreadsheetColumns() {
791
670
  return schemaFields.value
792
671
  .filter((field) => {
793
672
  return field.$el !== 'array'
794
673
  })
795
674
  .map((field) => {
796
- // Create a column config for each field
797
675
  return {
798
676
  key: field.id,
799
677
  title: field.label,
800
- // Special formatting for array child fields
801
678
  formatter: field.isArrayField ? formatArrayChildValue : undefined
802
679
  }
803
680
  })
804
681
  }
805
682
 
806
- // Helper function to format array child values for display
807
683
  function formatArrayChildValue(value: any, row: any, fieldId: string): string {
808
- // For array child fields, we need to check if it's in the parent array
809
684
  const field = schemaFields.value.find(f => f.id === fieldId)
810
685
  if (!field || !field.isArrayField || !field.parentField) return value
811
686
 
@@ -813,7 +688,6 @@ function formatArrayChildValue(value: any, row: any, fieldId: string): string {
813
688
  const parentArray = row[parentId]
814
689
 
815
690
  if (Array.isArray(parentArray) && parentArray.length > 0) {
816
- // Extract values from the parent array
817
691
  return parentArray
818
692
  .map(item => item[childId])
819
693
  .filter(val => val !== undefined)
@@ -823,7 +697,6 @@ function formatArrayChildValue(value: any, row: any, fieldId: string): string {
823
697
  return ''
824
698
  }
825
699
 
826
- // Add computed for spreadsheet columns
827
700
  const spreadsheetColumns = computed(() => createSpreadsheetColumns())
828
701
 
829
702
  function processData() {
@@ -885,21 +758,19 @@ async function handleFilesUploaded(files: FileList) {
885
758
  isLoading.value = false
886
759
  }
887
760
  }
888
- // Watch for changes in the selected sheet
761
+
889
762
  watchEffect(() => {
890
763
  if (selectedSheet.value) {
891
764
  loadSheetData()
892
765
  }
893
766
  })
894
767
 
895
- // Function to check if field has default value
896
768
  function hasDefaultValue(fieldId: string): boolean {
897
769
  return defaultValues[fieldId] !== undefined
898
770
  && defaultValues[fieldId] !== null
899
771
  && defaultValues[fieldId] !== ''
900
772
  }
901
773
 
902
- // Function to open transformation dialog
903
774
  function openTransformDialog(field: SchemaItem) {
904
775
  try {
905
776
  if (!field.options) {
@@ -920,20 +791,17 @@ function openTransformDialog(field: SchemaItem) {
920
791
  }
921
792
  }
922
793
 
923
- // Function to remove a transformation
924
794
  function removeTransformation(fieldId: string, index: number) {
925
795
  if (transformations[fieldId] && transformations[fieldId].length > index) {
926
796
  transformations[fieldId].splice(index, 1)
927
797
  }
928
798
  }
929
799
 
930
- // Function to open related file dialog
931
800
  function openRelatedDialog(field: SchemaItem) {
932
801
  selectedRelationField.value = field
933
802
  showRelatedDialog.value = true
934
803
  }
935
804
 
936
- // Function to process related file
937
805
  async function processRelatedFile(fieldId: string, files: File[] | FileList) {
938
806
  if (!files) return
939
807
  const file = files[0]
@@ -941,15 +809,12 @@ async function processRelatedFile(fieldId: string, files: File[] | FileList) {
941
809
  relatedFiles[fieldId] = file
942
810
 
943
811
  try {
944
- // First get sheet names
945
812
  const sheets = await getSheetNames(file)
946
813
  const selectedSheet = sheets.length > 0 ? sheets[0] : ''
947
814
 
948
- // Use the first sheet instead of an empty string
949
815
  const { data } = await readSheetData(file, selectedSheet, true)
950
816
  relatedFileData[fieldId] = data
951
817
 
952
- // Initialize mapping if not exists
953
818
  if (!relatedFileMappings[fieldId]) {
954
819
  relatedFileMappings[fieldId] = {}
955
820
  }
@@ -958,7 +823,6 @@ async function processRelatedFile(fieldId: string, files: File[] | FileList) {
958
823
  }
959
824
  }
960
825
 
961
- // Add function to auto-populate transformations for a field
962
826
  function autoPopulateTransformations(fieldId: string) {
963
827
  try {
964
828
  const field = schemaFields.value.find(f => f.id === fieldId)
@@ -967,7 +831,6 @@ function autoPopulateTransformations(fieldId: string) {
967
831
  return
968
832
  }
969
833
 
970
- // Ensure options are available either directly or from attrs
971
834
  let fieldOptions = field.options || (field.attrs && field.attrs.options)
972
835
 
973
836
  if (!fieldMapping[fieldId] || !fileData.value || fileData.value.length === 0) {
@@ -980,7 +843,6 @@ function autoPopulateTransformations(fieldId: string) {
980
843
  return
981
844
  }
982
845
 
983
- // Ensure options is an array
984
846
  if (!Array.isArray(fieldOptions)) {
985
847
  console.warn('Options is not an array for field:', fieldId)
986
848
  fieldOptions = []
@@ -988,7 +850,6 @@ function autoPopulateTransformations(fieldId: string) {
988
850
 
989
851
  const uniqueValues = getUniqueSourceValues(fieldId)
990
852
 
991
- // Initialize transformations array if needed
992
853
  if (!transformations[fieldId]) {
993
854
  transformations[fieldId] = []
994
855
  }
@@ -996,21 +857,17 @@ function autoPopulateTransformations(fieldId: string) {
996
857
  let matchCount = 0
997
858
  const unmatchedValues: string[] = []
998
859
 
999
- // For each unique value, try to find a matching target
1000
860
  uniqueValues.forEach((sourceValue) => {
1001
861
  const strSourceValue = String(sourceValue)
1002
862
  const matchedValue = findMatchingTargetValue(strSourceValue, fieldOptions)
1003
863
 
1004
864
  if (matchedValue) {
1005
- // Check if this source value already has a transformation
1006
865
  const existingIndex = transformations[fieldId].findIndex(t => t.sourceValue === strSourceValue
1007
866
  )
1008
867
 
1009
868
  if (existingIndex >= 0) {
1010
- // Update existing transformation
1011
869
  transformations[fieldId][existingIndex].targetValue = matchedValue
1012
870
  } else {
1013
- // Add new transformation
1014
871
  transformations[fieldId].push({
1015
872
  fieldId,
1016
873
  sourceValue: strSourceValue,
@@ -1024,7 +881,6 @@ function autoPopulateTransformations(fieldId: string) {
1024
881
  }
1025
882
  })
1026
883
 
1027
- // Provide some feedback about how many matches were found
1028
884
  if (matchCount === 0) {
1029
885
  alert(`No automatic matches found. Try creating transformations manually.`)
1030
886
  } else {
@@ -1036,9 +892,7 @@ function autoPopulateTransformations(fieldId: string) {
1036
892
  }
1037
893
  }
1038
894
 
1039
- // Function to detect date format from string
1040
895
  function detectDateFormat(value: string): RegExp | null {
1041
- // Common date formats
1042
896
  const formats = [
1043
897
  /^\d{4}-\d{2}-\d{2}$/, // YYYY-MM-DD
1044
898
  /^\d{2}\/\d{2}\/\d{4}$/, // MM/DD/YYYY
@@ -1055,30 +909,22 @@ function detectDateFormat(value: string): RegExp | null {
1055
909
  return null
1056
910
  }
1057
911
 
1058
- // Function to parse date string based on detected format
1059
912
  function parseDate(value: string): Date | null {
1060
913
  if (!value) return null
1061
914
 
1062
- // Try parsing ISO format first
1063
915
  const isoDate = new Date(value)
1064
916
  if (!Number.isNaN(isoDate.getTime())) {
1065
917
  return isoDate
1066
918
  }
1067
-
1068
- // Try parsing other formats
1069
919
  const format = detectDateFormat(value)
1070
920
  if (format) {
1071
- // Handle specific formats
1072
921
  if (/^\d{2}\/\d{2}\/\d{4}$/.test(value)) {
1073
- // MM/DD/YYYY
1074
922
  const [month, day, year] = value.split('/').map(Number)
1075
923
  return new Date(year, month - 1, day)
1076
924
  } else if (/^\d{2}\.\d{2}\.\d{4}$/.test(value)) {
1077
- // DD.MM.YYYY
1078
925
  const [day, month, year] = value.split('.').map(Number)
1079
926
  return new Date(year, month - 1, day)
1080
927
  } else if (/^\d{1,2}\s[a-z]{3,9}\s\d{4}$/i.test(value)) {
1081
- // D MMM YYYY or D MMMM YYYY
1082
928
  return new Date(value)
1083
929
  }
1084
930
  }
@@ -1086,12 +932,10 @@ function parseDate(value: string): Date | null {
1086
932
  return null
1087
933
  }
1088
934
 
1089
- // Replace convertValueByType function with simplified version using composable utilities
1090
935
  function convertValueByType(value: any, dataType: string): any {
1091
936
  if (value === null || value === undefined || value === '') {
1092
937
  return null
1093
938
  }
1094
-
1095
939
  try {
1096
940
  switch (dataType) {
1097
941
  case DATA_TYPES.STRING:
@@ -1110,24 +954,18 @@ function convertValueByType(value: any, dataType: string): any {
1110
954
  if (['false', 'no', '0', 'off'].includes(lowercased)) return false
1111
955
  }
1112
956
  return Boolean(value)
1113
-
1114
957
  case DATA_TYPES.DATE:
1115
958
  case DATA_TYPES.DATETIME:
1116
- // Handle Excel serial dates
1117
959
  if (isExcelSerialDate(value)) {
1118
960
  const date = excelSerialDateToJSDate(value)
1119
961
  return formatDate(date, dataType === DATA_TYPES.DATETIME)
1120
962
  }
1121
-
1122
- // Handle string dates
1123
963
  if (typeof value === 'string') {
1124
964
  const dateObj = parseDate(value)
1125
965
  if (dateObj) {
1126
966
  return formatDate(dateObj, dataType === DATA_TYPES.DATETIME)
1127
967
  }
1128
968
  }
1129
-
1130
- // Handle Date objects
1131
969
  if (value instanceof Date) {
1132
970
  return formatDate(value, dataType === DATA_TYPES.DATETIME)
1133
971
  }
@@ -1161,28 +999,22 @@ function detectDataType(value: any): string {
1161
999
  }
1162
1000
 
1163
1001
  if (typeof value === 'string') {
1164
- // Check if it's a date string
1165
1002
  if (detectDateFormat(value) || !Number.isNaN(new Date(value).getTime())) {
1166
1003
  return DATA_TYPES.DATE
1167
1004
  }
1168
1005
  }
1169
-
1170
- // Default to string
1171
1006
  return DATA_TYPES.STRING
1172
1007
  }
1173
1008
 
1174
- // Function to guess data types for all mapped fields
1175
1009
  function guessDataTypes(): void {
1176
1010
  schemaFields.value.forEach((field) => {
1177
1011
  if (!fieldDataTypes[field.id] && fieldMapping[field.id]) {
1178
- // Get sample values from the first few rows
1179
1012
  const sampleValues = fileData.value
1180
1013
  .slice(0, 5)
1181
1014
  .map(row => row[fieldMapping[field.id]])
1182
1015
  .filter(value => value !== undefined && value !== null && value !== '')
1183
1016
 
1184
1017
  if (sampleValues.length > 0) {
1185
- // Detect most common type
1186
1018
  const types = sampleValues.map(detectDataType)
1187
1019
  const typeCount: Record<string, number> = {}
1188
1020
 
@@ -1190,7 +1022,6 @@ function guessDataTypes(): void {
1190
1022
  typeCount[type] = (typeCount[type] || 0) + 1
1191
1023
  })
1192
1024
 
1193
- // Get the most common type
1194
1025
  let maxCount = 0
1195
1026
  let mostCommonType = DATA_TYPES.STRING
1196
1027
 
@@ -1209,12 +1040,9 @@ function guessDataTypes(): void {
1209
1040
  })
1210
1041
  }
1211
1042
 
1212
- // Function to open transformation dialog for related fields
1213
1043
  function openRelatedTransformDialog(parentId: string, field: SchemaItem) {
1214
1044
  try {
1215
1045
  console.log('Opening related transform dialog for field:', field.id, 'in parent:', parentId)
1216
-
1217
- // Make sure to set options property from attrs if needed
1218
1046
  if (!field.options) {
1219
1047
  field.options = []
1220
1048
  }
@@ -1228,7 +1056,6 @@ function openRelatedTransformDialog(parentId: string, field: SchemaItem) {
1228
1056
 
1229
1057
  selectedRelatedTransformField.value = { parentId, field }
1230
1058
 
1231
- // Initialize transformations structure if needed
1232
1059
  if (!relatedTransformations[parentId]) {
1233
1060
  relatedTransformations[parentId] = {}
1234
1061
  }
@@ -1239,7 +1066,6 @@ function openRelatedTransformDialog(parentId: string, field: SchemaItem) {
1239
1066
 
1240
1067
  showRelatedTransformDialog.value = true
1241
1068
 
1242
- // Reset selected values
1243
1069
  selectedRelatedSourceValue.value = ''
1244
1070
  selectedRelatedTargetValue.value = ''
1245
1071
  } catch (error) {
@@ -1248,7 +1074,6 @@ function openRelatedTransformDialog(parentId: string, field: SchemaItem) {
1248
1074
  }
1249
1075
  }
1250
1076
 
1251
- // Function to get unique source values for a related field
1252
1077
  function getRelatedUniqueSourceValues(parentId: string, fieldId: string): any[] {
1253
1078
  if (!relatedFileMappings[parentId][fieldId]
1254
1079
  || !relatedFileData[parentId]
@@ -1256,28 +1081,22 @@ function getRelatedUniqueSourceValues(parentId: string, fieldId: string): any[]
1256
1081
  return []
1257
1082
  }
1258
1083
 
1259
- // Get all values from the mapped column in the related file
1260
1084
  const allValues = relatedFileData[parentId]
1261
1085
  .map(row => row[relatedFileMappings[parentId][fieldId]])
1262
1086
  .filter(value => value !== undefined && value !== null && value !== '')
1263
1087
 
1264
- // Create a unique set of values
1265
1088
  const uniqueValues = [...new Set(allValues)]
1266
1089
 
1267
- // Filter out values that already have transformations
1268
1090
  return uniqueValues.filter((value) => {
1269
1091
  if (!relatedTransformations[parentId][fieldId]
1270
1092
  || relatedTransformations[parentId][fieldId].length === 0) {
1271
1093
  return true
1272
1094
  }
1273
-
1274
- // Return false if this value already has a transformation
1275
1095
  return !relatedTransformations[parentId][fieldId].some(t => t.sourceValue == value || t.sourceValue === value.toString()
1276
1096
  )
1277
1097
  })
1278
1098
  }
1279
1099
 
1280
- // Computed for available related source values
1281
1100
  const availableRelatedSourceValues = computed(() => {
1282
1101
  if (!selectedRelatedTransformField.value) {
1283
1102
  return []
@@ -1287,7 +1106,6 @@ const availableRelatedSourceValues = computed(() => {
1287
1106
  return getRelatedUniqueSourceValues(parentId, field.id)
1288
1107
  })
1289
1108
 
1290
- // Create options array from unique related values
1291
1109
  const relatedSourceValueOptions = computed(() => {
1292
1110
  return availableRelatedSourceValues.value.map(value => ({
1293
1111
  value: String(value),
@@ -1295,7 +1113,6 @@ const relatedSourceValueOptions = computed(() => {
1295
1113
  }))
1296
1114
  })
1297
1115
 
1298
- // Function to add a related transformation
1299
1116
  function addRelatedTransformation(parentId: string, fieldId: string) {
1300
1117
  if (!relatedTransformations[parentId]) {
1301
1118
  relatedTransformations[parentId] = {}
@@ -1306,30 +1123,24 @@ function addRelatedTransformation(parentId: string, fieldId: string) {
1306
1123
  }
1307
1124
 
1308
1125
  if (selectedRelatedSourceValue.value && selectedRelatedTargetValue.value) {
1309
- // Check if this source value already has a transformation
1310
1126
  const existingIndex = relatedTransformations[parentId][fieldId].findIndex(
1311
1127
  t => t.sourceValue === selectedRelatedSourceValue.value
1312
1128
  )
1313
1129
 
1314
1130
  if (existingIndex >= 0) {
1315
- // Update existing transformation
1316
1131
  relatedTransformations[parentId][fieldId][existingIndex].targetValue = selectedRelatedTargetValue.value
1317
1132
  } else {
1318
- // Add new transformation
1319
1133
  relatedTransformations[parentId][fieldId].push({
1320
1134
  fieldId,
1321
1135
  sourceValue: selectedRelatedSourceValue.value,
1322
1136
  targetValue: selectedRelatedTargetValue.value
1323
1137
  })
1324
1138
  }
1325
-
1326
- // Reset selection
1327
1139
  selectedRelatedSourceValue.value = ''
1328
1140
  selectedRelatedTargetValue.value = ''
1329
1141
  }
1330
1142
  }
1331
1143
 
1332
- // Function to remove a related transformation
1333
1144
  function removeRelatedTransformation(parentId: string, fieldId: string, index: number) {
1334
1145
  if (relatedTransformations[parentId][fieldId]
1335
1146
  && relatedTransformations[parentId][fieldId].length > index) {
@@ -1337,7 +1148,6 @@ function removeRelatedTransformation(parentId: string, fieldId: string, index: n
1337
1148
  }
1338
1149
  }
1339
1150
 
1340
- // Function to auto-populate transformations for a related field
1341
1151
  function autoPopulateRelatedTransformations(parentId: string, fieldId: string) {
1342
1152
  try {
1343
1153
  const field = selectedRelatedTransformField.value?.field
@@ -1346,7 +1156,6 @@ function autoPopulateRelatedTransformations(parentId: string, fieldId: string) {
1346
1156
  return
1347
1157
  }
1348
1158
 
1349
- // Ensure options are available either directly or from attrs
1350
1159
  let fieldOptions = field.options || (field.attrs && field.attrs.options)
1351
1160
 
1352
1161
  if (!relatedFileMappings[parentId][fieldId]
@@ -1361,7 +1170,6 @@ function autoPopulateRelatedTransformations(parentId: string, fieldId: string) {
1361
1170
  return
1362
1171
  }
1363
1172
 
1364
- // Ensure options is an array
1365
1173
  if (!Array.isArray(fieldOptions)) {
1366
1174
  console.warn('Options is not an array for related field:', fieldId)
1367
1175
  fieldOptions = []
@@ -1369,7 +1177,6 @@ function autoPopulateRelatedTransformations(parentId: string, fieldId: string) {
1369
1177
 
1370
1178
  const uniqueValues = getRelatedUniqueSourceValues(parentId, fieldId)
1371
1179
 
1372
- // Initialize transformations array if needed
1373
1180
  if (!relatedTransformations[parentId]) {
1374
1181
  relatedTransformations[parentId] = {}
1375
1182
  }
@@ -1381,14 +1188,12 @@ function autoPopulateRelatedTransformations(parentId: string, fieldId: string) {
1381
1188
  let matchCount = 0
1382
1189
  const unmatchedValues: string[] = []
1383
1190
 
1384
- // For each unique value, try to find a matching target
1385
1191
  uniqueValues.forEach((sourceValue) => {
1386
1192
  const strSourceValue = String(sourceValue)
1387
1193
 
1388
1194
  const matchedValue = findMatchingTargetValue(strSourceValue, fieldOptions)
1389
1195
 
1390
1196
  if (matchedValue) {
1391
- // Check if this source value already has a transformation
1392
1197
  const existingIndex = relatedTransformations[parentId][fieldId].findIndex(
1393
1198
  t => t.sourceValue === strSourceValue
1394
1199
  )
@@ -1410,8 +1215,6 @@ function autoPopulateRelatedTransformations(parentId: string, fieldId: string) {
1410
1215
  unmatchedValues.push(strSourceValue)
1411
1216
  }
1412
1217
  })
1413
-
1414
- // Provide feedback about matches
1415
1218
  if (matchCount === 0) {
1416
1219
  alert(`No automatic matches found. Try creating transformations manually.`)
1417
1220
  } else {
@@ -1423,15 +1226,12 @@ function autoPopulateRelatedTransformations(parentId: string, fieldId: string) {
1423
1226
  }
1424
1227
  }
1425
1228
 
1426
- // Initialize default value structure for a field
1427
1229
  function initDefaultValue(fieldId: string) {
1428
- // Make sure the field has an entry in defaultValues
1429
1230
  if (defaultValues[fieldId] === undefined) {
1430
1231
  defaultValues[fieldId] = null
1431
1232
  }
1432
1233
  }
1433
1234
 
1434
- // Initialize related default value structure
1435
1235
  function initRelatedDefaultValue(parentId: string, fieldId: string) {
1436
1236
  if (!relatedDefaultValues[parentId]) {
1437
1237
  relatedDefaultValues[parentId] = {}
@@ -1441,12 +1241,9 @@ function initRelatedDefaultValue(parentId: string, fieldId: string) {
1441
1241
  }
1442
1242
  }
1443
1243
 
1444
- // Helper function to prepare a field with default values for rendering
1445
1244
  function getFieldWithDefaults(field: any) {
1446
- // Get the current field type to render proper input
1447
1245
  let fieldType = field.$el || 'text'
1448
1246
 
1449
- // If datatype is set, adjust the field type accordingly
1450
1247
  if (fieldDataTypes[field.id]) {
1451
1248
  switch (fieldDataTypes[field.id]) {
1452
1249
  case DATA_TYPES.NUMBER:
@@ -1461,7 +1258,6 @@ function getFieldWithDefaults(field: any) {
1461
1258
  }
1462
1259
  }
1463
1260
 
1464
- // Update formData with current value to support the renderField function
1465
1261
  if (field.id) {
1466
1262
  formData.value[field.id] = defaultValues[field.id]
1467
1263
  }
@@ -1473,12 +1269,8 @@ function getFieldWithDefaults(field: any) {
1473
1269
  }
1474
1270
  }
1475
1271
 
1476
- // Add a helper function for related fields too
1477
1272
  function getRelatedFieldWithDefaults(parentId: string, field: any) {
1478
- // Get the current field type to render proper input
1479
1273
  let fieldType = field.$el || 'text'
1480
-
1481
- // If datatype is set, adjust the field type accordingly
1482
1274
  const fullFieldId = `${parentId}.${field.id}`
1483
1275
  if (relatedFieldDataTypes[fullFieldId]) {
1484
1276
  switch (relatedFieldDataTypes[fullFieldId]) {
@@ -1529,22 +1321,16 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1529
1321
  </Card>
1530
1322
  </DragOver>
1531
1323
  </div>
1532
-
1533
- <!-- Loading indicator -->
1534
1324
  <div v-if="isLoading" class="loading-container">
1535
1325
  <div class="spinner" />
1536
1326
  <p>Processing your file...</p>
1537
1327
  </div>
1538
1328
 
1539
- <!-- Step 2: Sheet selection and configuration -->
1540
1329
  <div class="overflow h-100p">
1541
1330
  <div v-if="file && !isLoading && sheetNames.length > 0" class="config-section flex gap-05 pb-2 m_flex-wrap">
1542
1331
  <Btn v-tooltip="'Change File'" class="px-1" color="gray" @click="file = null">
1543
1332
  <Icon icon="draft" size="1.5" weight="300" />
1544
- <p>
1545
- {{ file.name }}
1546
- </p>
1547
- <!-- <Icon icon="edit" size="0.75" /> -->
1333
+ <p v-text="file.name" />
1548
1334
  </Btn>
1549
1335
  <SelectInput v-if="sheetNames.length > 1" v-model="selectedSheet" :options="sheetNames" label="Select Sheet" />
1550
1336
  <CheckInput
@@ -1552,12 +1338,7 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1552
1338
  style="--bgl-accent-color: var(--bgl-black); --bgl-primary: var(--bgl-black);"
1553
1339
  />
1554
1340
  </div>
1555
-
1556
- <!-- Step 3: Field Mapping -->
1557
1341
  <div v-if="file && !isLoading && fileHeaders.length > 0">
1558
- <!-- <h3 class="mt-0">
1559
- Map Fields
1560
- </h3> -->
1561
1342
  <p class="label pb-1 border-bottom mb-1">
1562
1343
  Match each required field to a column from your file, set default values, or configure transformations
1563
1344
  </p>
@@ -1644,8 +1425,6 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1644
1425
  </div>
1645
1426
  </div>
1646
1427
  </div>
1647
-
1648
- <!-- Transformation Modal -->
1649
1428
  <Modal v-model:visible="showTransformDialog" title="Configure Transformations" width="800">
1650
1429
  <div v-if="selectedTransformField">
1651
1430
  <div class="flex space-between gap-1 mb-1 border-bottom pb-05 m_flex-wrap">
@@ -1718,8 +1497,6 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1718
1497
  </div>
1719
1498
  </div>
1720
1499
  </Modal>
1721
-
1722
- <!-- Related File Modal -->
1723
1500
  <Modal v-model:visible="showRelatedDialog" title="Configure Related Data" width="900">
1724
1501
  <div v-if="selectedRelationField">
1725
1502
  <p class="pb-05">
@@ -1819,7 +1596,6 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1819
1596
  </div>
1820
1597
  </Modal>
1821
1598
 
1822
- <!-- Preview Modal -->
1823
1599
  <Modal v-model:visible="showPreviewModal" title="Data Preview & Edit" width="90vw">
1824
1600
  <div>
1825
1601
  <Spreadsheet
@@ -1840,7 +1616,6 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1840
1616
  </div>
1841
1617
  </Modal>
1842
1618
 
1843
- <!-- Related Transformation Modal -->
1844
1619
  <Modal v-model:visible="showRelatedTransformDialog" title="Configure Related Transformations" width="800">
1845
1620
  <div v-if="selectedRelatedTransformField">
1846
1621
  <p>Create transformations for <strong>{{ selectedRelatedTransformField.field.label }}</strong> in {{ selectedRelationField?.label }}</p>
@@ -1929,9 +1704,7 @@ function getRelatedFieldWithDefaults(parentId: string, field: any) {
1929
1704
  </div>
1930
1705
 
1931
1706
  <div>
1932
- <Btn @click="showRelatedTransformDialog = false">
1933
- Close
1934
- </Btn>
1707
+ <Btn value="Close" @click="showRelatedTransformDialog = false" />
1935
1708
  </div>
1936
1709
  </div>
1937
1710
  </Modal>