@@ -17,7 +17,7 @@ struct FieldEditState {
1717 let isLongText : Bool
1818
1919 /// Original values from all selected rows (nil if multiple different values)
20- let originalValue : String ?
20+ var originalValue : String ?
2121
2222 /// Flag indicating if selected rows have different values for this field
2323 let hasMultipleValues : Bool
@@ -31,6 +31,12 @@ struct FieldEditState {
3131 /// Whether user has explicitly set this field to DEFAULT
3232 var isPendingDefault : Bool
3333
34+ /// Whether this field's value was truncated by column exclusion policy
35+ var isTruncated : Bool = false
36+
37+ /// Whether full value is currently being lazy-loaded
38+ var isLoadingFullValue : Bool = false
39+
3440 var hasEdit : Bool {
3541 pendingValue != nil || isPendingNull || isPendingDefault
3642 }
@@ -67,8 +73,9 @@ final class MultiRowEditState {
6773 selectedRowIndices: Set < Int > ,
6874 allRows: [ [ String ? ] ] ,
6975 columns: [ String ] ,
70- columnTypes: [ ColumnType ] , // Changed from [String] to [ColumnType]
71- externallyModifiedColumns: Set < Int > = [ ]
76+ columnTypes: [ ColumnType ] ,
77+ externallyModifiedColumns: Set < Int > = [ ] ,
78+ excludedColumnNames: Set < String > = [ ]
7279 ) {
7380 // Check if the underlying data has changed (not just edits)
7481 let columnsChanged = self . columns != columns
@@ -110,13 +117,25 @@ final class MultiRowEditState {
110117 var isPendingNull = false
111118 var isPendingDefault = false
112119
120+ let isExcluded = excludedColumnNames. contains ( columnName)
121+ var preservedOriginalValue : String ? = originalValue
122+ var preservedIsTruncated = isExcluded
123+ var preservedIsLoadingFullValue = isExcluded
124+
113125 if !columnsChanged, !selectionChanged, colIndex < fields. count {
114126 let oldField = fields [ colIndex]
127+ // Preserve pending edits when original data matches
115128 if oldField. originalValue == originalValue && oldField. hasMultipleValues == hasMultipleValues {
116129 pendingValue = oldField. pendingValue
117130 isPendingNull = oldField. isPendingNull
118131 isPendingDefault = oldField. isPendingDefault
119132 }
133+ // Preserve resolved truncation state — don't reset already-fetched full values
134+ if isExcluded && !oldField. isTruncated && oldField. columnName == columnName {
135+ preservedOriginalValue = oldField. originalValue
136+ preservedIsTruncated = false
137+ preservedIsLoadingFullValue = false
138+ }
120139 }
121140
122141 // Mark externally modified columns (e.g., edited in data grid)
@@ -129,11 +148,13 @@ final class MultiRowEditState {
129148 columnName: columnName,
130149 columnTypeEnum: columnTypeEnum,
131150 isLongText: isLongText,
132- originalValue: originalValue ,
151+ originalValue: preservedOriginalValue ,
133152 hasMultipleValues: hasMultipleValues,
134153 pendingValue: pendingValue,
135154 isPendingNull: isPendingNull,
136- isPendingDefault: isPendingDefault
155+ isPendingDefault: isPendingDefault,
156+ isTruncated: preservedIsTruncated,
157+ isLoadingFullValue: preservedIsLoadingFullValue
137158 ) )
138159 }
139160
@@ -200,6 +221,26 @@ final class MultiRowEditState {
200221 }
201222 }
202223
224+ /// Apply lazy-loaded full values for previously truncated columns
225+ func applyFullValues( _ fullValues: [ String : String ? ] ) {
226+ for i in 0 ..< fields. count {
227+ guard let fullValue = fullValues [ fields [ i] . columnName] else { continue }
228+ fields [ i] = FieldEditState (
229+ columnIndex: fields [ i] . columnIndex,
230+ columnName: fields [ i] . columnName,
231+ columnTypeEnum: fields [ i] . columnTypeEnum,
232+ isLongText: fields [ i] . isLongText,
233+ originalValue: fullValue,
234+ hasMultipleValues: fields [ i] . hasMultipleValues,
235+ pendingValue: fields [ i] . pendingValue,
236+ isPendingNull: fields [ i] . isPendingNull,
237+ isPendingDefault: fields [ i] . isPendingDefault,
238+ isTruncated: false ,
239+ isLoadingFullValue: false
240+ )
241+ }
242+ }
243+
203244 /// Clear all pending edits
204245 func clearEdits( ) {
205246 for i in 0 ..< fields. count {
@@ -222,7 +263,7 @@ final class MultiRowEditState {
222263 /// Get all edited fields with their new values
223264 func getEditedFields( ) -> [ ( columnIndex: Int , columnName: String , newValue: String ? ) ] {
224265 fields. compactMap { field in
225- guard field. hasEdit else { return nil }
266+ guard field. hasEdit, !field . isTruncated else { return nil }
226267 return ( field. columnIndex, field. columnName, field. effectiveValue)
227268 }
228269 }
0 commit comments