@@ -4,17 +4,15 @@ import { ISelectedEntries } from '../selectedEntries/selectedEntries.interface';
44import { getParentEntryUuid , getUdpatedAssociatedEntries } from '@common/helpers/schema.helper' ;
55import { generateEmptyValueUuid } from '@common/helpers/complexLookup.helper' ;
66import { IEntryPropertiesGeneratorService } from './entryPropertiesGenerator.interface' ;
7+ import { MIN_AMT_OF_SIBLING_ENTRIES_TO_BE_DELETABLE } from '@common/constants/bibframe.constants' ;
78
89export class SchemaWithDuplicatesService implements ISchemaWithDuplicatesService {
9- private isManualDuplication : boolean ;
10-
1110 constructor (
1211 private schema : Map < string , SchemaEntry > ,
1312 private readonly selectedEntriesService : ISelectedEntries ,
1413 private readonly entryPropertiesGeneratorService ?: IEntryPropertiesGeneratorService ,
1514 ) {
1615 this . set ( schema ) ;
17- this . isManualDuplication = true ;
1816 }
1917
2018 get ( ) {
@@ -25,14 +23,13 @@ export class SchemaWithDuplicatesService implements ISchemaWithDuplicatesService
2523 this . schema = cloneDeep ( schema ) ;
2624 }
2725
28- duplicateEntry ( entry : SchemaEntry , isManualDuplication = true ) {
29- this . isManualDuplication = isManualDuplication ;
30- const { uuid, path, children, constraints, clonedBy, cloneOf } = entry ;
26+ duplicateEntry ( entry : SchemaEntry ) {
27+ const { uuid, path, children, constraints, uri = '' } = entry ;
3128
3229 if ( ! constraints ?. repeatable ) return ;
3330
3431 const updatedEntryUuid = uuidv4 ( ) ;
35- const updatedEntry = this . getCopiedEntry ( entry , updatedEntryUuid , undefined , true ) ;
32+ const updatedEntry = this . getCopiedEntry ( entry , updatedEntryUuid ) ;
3633 updatedEntry . children = this . getUpdatedChildren ( children , updatedEntry ) ;
3734
3835 const parentEntryUuid = getParentEntryUuid ( path ) ;
@@ -41,56 +38,82 @@ export class SchemaWithDuplicatesService implements ISchemaWithDuplicatesService
4138 parentEntry,
4239 originalEntryUuid : uuid ,
4340 updatedEntryUuid : updatedEntryUuid ,
41+ childEntryId : uri ,
4442 } ) ;
4543
4644 if ( updatedParentEntry ) {
4745 this . schema . set ( parentEntryUuid , updatedParentEntry ) ;
4846 this . schema . set ( updatedEntryUuid , updatedEntry ) ;
4947
50- if ( this . isManualDuplication && cloneOf ) {
51- // dupicating the field that's a clone
52- // got to set the initial prototype's properties
53- const initialPrototype = this . schema . get ( cloneOf ) ! ;
54-
55- this . schema . set ( initialPrototype . uuid , {
56- ...initialPrototype ,
57- clonedBy : [ ...( initialPrototype . clonedBy ?? [ ] ) , updatedEntryUuid ] ,
58- } ) ;
59- } else {
60- this . schema . set ( uuid , {
61- ...entry ,
62- clonedBy : this . isManualDuplication ? [ ...( clonedBy ?? [ ] ) , updatedEntryUuid ] : undefined ,
63- } ) ;
64- }
65-
48+ this . updateDeletabilityAndPositioning ( updatedParentEntry ?. twinChildren ?. [ uri ] ) ;
6649 this . entryPropertiesGeneratorService ?. applyHtmlIdToEntries ( this . schema ) ;
6750 }
6851
69- this . isManualDuplication = true ;
7052 return updatedEntryUuid ;
7153 }
7254
73- private getCopiedEntry ( entry : SchemaEntry , updatedUuid : string , parentElemPath ?: string [ ] , includeCloneInfo = false ) {
74- const { path, uuid, cloneIndex = 0 , htmlId } = entry ;
75- const copiedEntry = cloneDeep ( entry ) ;
55+ deleteEntry ( entry : SchemaEntry ) {
56+ const { deletable, uuid, path, uri = '' } = entry ;
7657
77- copiedEntry . uuid = updatedUuid ;
78- copiedEntry . path = this . getUpdatedPath ( path , updatedUuid , parentElemPath ) ;
58+ if ( ! deletable ) return ;
7959
80- if ( includeCloneInfo ) {
81- copiedEntry . cloneIndex = cloneIndex + 1 ;
82- }
60+ const parent = this . schema . get ( getParentEntryUuid ( path ) ) ;
61+ const twinSiblings = parent ?. twinChildren ?. [ uri ] ;
8362
84- if ( htmlId ) {
85- this . entryPropertiesGeneratorService ?. addEntryWithHtmlId ( updatedUuid ) ;
63+ if ( twinSiblings ) {
64+ const updatedTwinSiblings = twinSiblings ?. filter ( twinUuid => twinUuid !== uuid ) ;
65+
66+ this . schema . set ( parent . uuid , {
67+ ...parent ,
68+ twinChildren : {
69+ ...parent . twinChildren ,
70+ [ uri ] : updatedTwinSiblings ,
71+ } ,
72+ children : parent . children ?. filter ( child => child !== uuid ) ,
73+ } ) ;
74+
75+ this . updateDeletabilityAndPositioning ( updatedTwinSiblings ) ;
8676 }
8777
88- if ( this . isManualDuplication && includeCloneInfo ) {
89- if ( ! copiedEntry . cloneOf ) {
90- copiedEntry . cloneOf = uuid ;
78+ const deletedUuids : string [ ] = [ ] ;
79+
80+ this . deleteEntryAndChildren ( entry , deletedUuids ) ;
81+
82+ return deletedUuids ;
83+ }
84+
85+ private deleteEntryAndChildren ( entry ?: SchemaEntry , deletedUuids ?: string [ ] ) {
86+ if ( ! entry ) return ;
87+
88+ const { children, uuid } = entry ;
89+
90+ if ( children ) {
91+ for ( const child of children ) {
92+ this . deleteEntryAndChildren ( this . schema . get ( child ) , deletedUuids ) ;
9193 }
94+ }
95+
96+ deletedUuids ?. push ( uuid ) ;
97+ this . schema . delete ( uuid ) ;
98+ }
9299
93- copiedEntry . clonedBy = undefined ;
100+ private updateDeletabilityAndPositioning ( uuids : string [ ] = [ ] ) {
101+ const deletable = uuids . length >= MIN_AMT_OF_SIBLING_ENTRIES_TO_BE_DELETABLE ;
102+
103+ uuids . forEach ( ( uuid , cloneIndex ) =>
104+ this . schema . set ( uuid , { ...( this . schema . get ( uuid ) ?? { } ) , deletable, cloneIndex } as SchemaEntry ) ,
105+ ) ;
106+ }
107+
108+ private getCopiedEntry ( entry : SchemaEntry , updatedUuid : string , parentElemPath ?: string [ ] ) {
109+ const { path, htmlId } = entry ;
110+ const copiedEntry = cloneDeep ( entry ) ;
111+
112+ copiedEntry . uuid = updatedUuid ;
113+ copiedEntry . path = this . getUpdatedPath ( path , updatedUuid , parentElemPath ) ;
114+
115+ if ( htmlId ) {
116+ this . entryPropertiesGeneratorService ?. addEntryWithHtmlId ( updatedUuid ) ;
94117 }
95118
96119 return copiedEntry ;
@@ -104,7 +127,7 @@ export class SchemaWithDuplicatesService implements ISchemaWithDuplicatesService
104127 children ?. forEach ( ( entryUuid : string , index : number ) => {
105128 const entry = this . schema . get ( entryUuid ) ;
106129
107- if ( ! entry || entry . cloneOf ) return ;
130+ if ( ! entry ) return ;
108131
109132 const { children } = entry ;
110133 let updatedEntryUuid = newUuids ?. [ index ] ?? uuidv4 ( ) ;
@@ -119,7 +142,6 @@ export class SchemaWithDuplicatesService implements ISchemaWithDuplicatesService
119142 this . schema . set ( updatedEntryUuid , copiedEntry ) ;
120143
121144 copiedEntry . children = this . getUpdatedChildren ( children , copiedEntry ) ;
122- copiedEntry . clonedBy = [ ] ;
123145
124146 const { updatedEntry, controlledByEntry } = this . getUpdatedAssociatedEntries ( {
125147 initialEntry : copiedEntry ,
@@ -148,17 +170,29 @@ export class SchemaWithDuplicatesService implements ISchemaWithDuplicatesService
148170 parentEntry,
149171 originalEntryUuid,
150172 updatedEntryUuid,
173+ childEntryId,
151174 } : {
152175 parentEntry ?: SchemaEntry ;
153176 originalEntryUuid : string ;
154177 updatedEntryUuid : string ;
178+ childEntryId ?: string ;
155179 } ) {
156180 if ( ! parentEntry ) return ;
157181
158182 const updatedParentEntry = cloneDeep ( parentEntry ) ;
159183 const { children } = updatedParentEntry ;
160184 const originalEntryIndex = children ?. indexOf ( originalEntryUuid ) ;
161185
186+ if ( childEntryId ) {
187+ if ( ! updatedParentEntry . twinChildren ) {
188+ updatedParentEntry . twinChildren = { } ;
189+ }
190+
191+ updatedParentEntry . twinChildren [ childEntryId ] = [
192+ ...new Set ( [ ...( updatedParentEntry . twinChildren [ childEntryId ] ?? [ ] ) , originalEntryUuid , updatedEntryUuid ] ) ,
193+ ] ;
194+ }
195+
162196 if ( originalEntryIndex !== undefined && originalEntryIndex >= 0 ) {
163197 // Add the UUID of the copied entry to the parent element's array of children,
164198 // saving the order of the elements
0 commit comments