@@ -48,6 +48,11 @@ export class DsoEditMetadataValue {
4848 */
4949 change : DsoEditMetadataChangeType ;
5050
51+ /**
52+ * A flag to keep track if the value has been reordered (place has changed)
53+ */
54+ reordered = false ;
55+
5156 /**
5257 * A type or change that can be used to undo any discarding that took place
5358 */
@@ -69,8 +74,9 @@ export class DsoEditMetadataValue {
6974 * It will also set the editing flag to false
7075 */
7176 confirmChanges ( finishEditing = false ) {
77+ this . reordered = this . originalValue . place !== this . newValue . place ;
7278 if ( hasNoValue ( this . change ) || this . change === DsoEditMetadataChangeType . UPDATE ) {
73- if ( ( this . originalValue . value !== this . newValue . value || this . originalValue . language !== this . newValue . language || this . originalValue . place !== this . newValue . place ) ) {
79+ if ( ( this . originalValue . value !== this . newValue . value || this . originalValue . language !== this . newValue . language ) ) {
7480 this . change = DsoEditMetadataChangeType . UPDATE ;
7581 } else {
7682 this . change = undefined ;
@@ -87,29 +93,33 @@ export class DsoEditMetadataValue {
8793 * return false (which is desired)
8894 */
8995 hasChanges ( ) : boolean {
90- return hasValue ( this . change ) ;
96+ return hasValue ( this . change ) || this . reordered ;
9197 }
9298
9399 /**
94100 * Discard the current changes and mark the value and change type re-instatable by storing them in their relevant
95101 * properties
96102 */
97103 discardAndMarkReinstatable ( ) : void {
98- if ( this . change === DsoEditMetadataChangeType . UPDATE ) {
104+ if ( this . change === DsoEditMetadataChangeType . UPDATE || this . reordered ) {
99105 this . reinstatableValue = this . newValue ;
100106 }
101107 this . reinstatableChange = this . change ;
102- this . discard ( ) ;
108+ this . discard ( false ) ;
103109 }
104110
105111 /**
106112 * Discard the current changes
107113 * Call discardAndMarkReinstatable() instead, if the discard should be re-instatable
108114 */
109- discard ( ) : void {
115+ discard ( keepPlace = true ) : void {
110116 this . change = undefined ;
117+ const place = this . newValue . place ;
111118 this . newValue = Object . assign ( new MetadataValue ( ) , this . originalValue ) ;
112- this . editing = false ;
119+ if ( keepPlace ) {
120+ this . newValue . place = place ;
121+ }
122+ this . confirmChanges ( true ) ;
113123 }
114124
115125 /**
@@ -124,6 +134,7 @@ export class DsoEditMetadataValue {
124134 this . change = this . reinstatableChange ;
125135 this . reinstatableChange = undefined ;
126136 }
137+ this . confirmChanges ( ) ;
127138 }
128139
129140 /**
@@ -190,6 +201,7 @@ export class DsoEditMetadataForm {
190201 this . fieldKeys . push ( mdField ) ;
191202 this . setValuesForFieldSorted ( mdField , values . map ( ( value : MetadataValue ) => new DsoEditMetadataValue ( value ) ) ) ;
192203 } ) ;
204+ this . sortFieldKeys ( ) ;
193205 }
194206
195207 /**
@@ -225,6 +237,7 @@ export class DsoEditMetadataForm {
225237 private addValueToField ( value : DsoEditMetadataValue , mdField : string ) : void {
226238 if ( isEmpty ( this . fields [ mdField ] ) ) {
227239 this . fieldKeys . push ( mdField ) ;
240+ this . sortFieldKeys ( ) ;
228241 this . fields [ mdField ] = [ ] ;
229242 }
230243 this . fields [ mdField ] . push ( value ) ;
@@ -252,6 +265,14 @@ export class DsoEditMetadataForm {
252265 return Object . values ( this . fields ) . some ( ( values : DsoEditMetadataValue [ ] ) => values . some ( ( value : DsoEditMetadataValue ) => value . hasChanges ( ) ) ) ;
253266 }
254267
268+ /**
269+ * Check if a metadata field contains changes within its order (place property of values)
270+ * @param mdField
271+ */
272+ hasOrderChanges ( mdField : string ) : boolean {
273+ return this . fields [ mdField ] . some ( ( value : DsoEditMetadataValue ) => value . originalValue . place !== value . newValue . place ) ;
274+ }
275+
255276 /**
256277 * Discard all changes within the form and store their current values within re-instatable properties so they can be
257278 * undone afterwards
@@ -285,12 +306,34 @@ export class DsoEditMetadataForm {
285306 }
286307 } ) ;
287308 this . fieldKeys = [ ...this . originalFieldKeys ] ;
309+ this . sortFieldKeys ( ) ;
288310 // Reset the order of values within their fields to match their place property
289311 this . fieldKeys . forEach ( ( field : string ) => {
290312 this . setValuesForFieldSorted ( field , this . fields [ field ] ) ;
291313 } ) ;
292314 }
293315
316+ /**
317+ * Reset the order of values within a metadata field to their original places
318+ * Update the actual array to match the place properties
319+ * @param mdField
320+ */
321+ resetOrder ( mdField : string ) {
322+ this . fields [ mdField ] . forEach ( ( value : DsoEditMetadataValue ) => {
323+ value . newValue . place = value . originalValue . place ;
324+ value . confirmChanges ( ) ;
325+ } ) ;
326+ this . setValuesForFieldSorted ( mdField , this . fields [ mdField ] ) ;
327+ }
328+
329+ /**
330+ * Sort fieldKeys alphabetically
331+ * Should be called whenever a field is added to ensure the alphabetical order is kept
332+ */
333+ sortFieldKeys ( ) {
334+ this . fieldKeys . sort ( ( a : string , b : string ) => a . localeCompare ( b ) ) ;
335+ }
336+
294337 /**
295338 * Undo any previously discarded changes
296339 */
@@ -356,10 +399,10 @@ export class DsoEditMetadataForm {
356399 const replaceOperations : MetadataPatchReplaceOperation [ ] = [ ] ;
357400 const removeOperations : MetadataPatchRemoveOperation [ ] = [ ] ;
358401 const addOperations : MetadataPatchAddOperation [ ] = [ ] ;
359- values
402+ [ ... values ]
360403 . sort ( ( a : DsoEditMetadataValue , b : DsoEditMetadataValue ) => a . originalValue . place - b . originalValue . place )
361404 . forEach ( ( value : DsoEditMetadataValue ) => {
362- if ( value . hasChanges ( ) ) {
405+ if ( hasValue ( value . change ) ) {
363406 if ( value . change === DsoEditMetadataChangeType . UPDATE ) {
364407 // Only changes to value or language are considered "replace" operations. Changes to place are considered "move", which is processed below.
365408 if ( value . originalValue . value !== value . newValue . value || value . originalValue . language !== value . newValue . language ) {
@@ -398,10 +441,10 @@ export class DsoEditMetadataForm {
398441 const moveOperations = moveAnalyser
399442 . diff (
400443 valuesWithoutRemoved
401- . map ( ( value : DsoEditMetadataValue ) => value . originalValue . place ) ,
402- valuesWithoutRemoved
403- . sort ( ( a : DsoEditMetadataValue , b : DsoEditMetadataValue ) => a . newValue . place - b . newValue . place )
404- . map ( ( value : DsoEditMetadataValue ) => value . originalValue . place ) )
444+ . map ( ( value : DsoEditMetadataValue ) => value . newValue . place ) ,
445+ [ ... valuesWithoutRemoved ]
446+ . sort ( ( a : DsoEditMetadataValue , b : DsoEditMetadataValue ) => a . originalValue . place - b . originalValue . place )
447+ . map ( ( value : DsoEditMetadataValue ) => value . newValue . place ) )
405448 . map ( ( operation : MoveOperation ) => new MetadataPatchMoveOperation ( field , + operation . from . substr ( 1 ) , + operation . path . substr ( 1 ) ) . toOperation ( ) ) ;
406449 operations . push ( ...moveOperations ) ;
407450 } ) ;
0 commit comments