1010 *
1111 * SPDX-License-Identifier: EPL-2.0 OR W3C-20150513
1212 ********************************************************************************/
13- import React , { useContext , useState } from "react" ;
14- import { Trash2 } from "react-feather" ;
13+ import React , { useContext , useState , useRef } from "react" ;
14+ import { Trash2 , Copy } from "react-feather" ;
1515import ediTDorContext from "../../../context/ediTDorContext" ;
1616import {
1717 buildAttributeListObject ,
@@ -27,12 +27,11 @@ const alreadyRenderedKeys = ["title", "forms", "description"];
2727
2828const Event : React . FC < any > = ( props ) => {
2929 const context = useContext ( ediTDorContext ) ;
30-
3130 const [ isExpanded , setIsExpanded ] = useState ( false ) ;
3231
33- const addFormDialog = React . useRef ( ) ;
32+ const addFormDialog = useRef < { openModal : ( ) => void } > ( null ) ;
3433 const handleOpenAddFormDialog = ( ) => {
35- addFormDialog . current . openModal ( ) ;
34+ addFormDialog . current ? .openModal ( ) ;
3635 } ;
3736
3837 if (
@@ -48,22 +47,47 @@ const Event: React.FC<any> = (props) => {
4847
4948 const event = props . event ;
5049 const forms = separateForms ( props . event . forms ) ;
50+
5151 const attributeListObject = buildAttributeListObject (
5252 { name : props . eventName } ,
5353 props . event ,
5454 alreadyRenderedKeys
5555 ) ;
56- const attributes = Object . keys ( attributeListObject ) . map ( ( x ) => {
57- return (
58- < li key = { x } >
59- { x } : { JSON . stringify ( attributeListObject [ x ] ) }
60- </ li >
61- ) ;
62- } ) ;
6356
57+ const attributes = Object . keys ( attributeListObject ) . map ( ( x ) => (
58+ < li key = { x } >
59+ { x } : { JSON . stringify ( attributeListObject [ x ] ) }
60+ </ li >
61+ ) ) ;
62+
6463 const handleDeleteEventClicked = ( ) => {
6564 context . removeOneOfAKindReducer ( "events" , props . eventName ) ;
6665 } ;
66+ const handleCopyEvent = ( ) => {
67+ const parsedTD = context . parsedTD ;
68+ if ( ! parsedTD || ! parsedTD . events ) {
69+ console . error ( "parsedTD or events missing" , parsedTD ) ;
70+ return ;
71+ }
72+ const originalName = props . eventName ;
73+ let newName = `${ originalName } _copy` ;
74+ let counter = 1 ;
75+ while ( parsedTD . events [ newName ] ) {
76+ newName = `${ originalName } _copy_${ counter ++ } ` ;
77+ }
78+ const copiedEvent = structuredClone ( event ) ;
79+ const baseTitle = event . title ?? props . eventName ;
80+ copiedEvent . title = `${ baseTitle } copy` ;
81+ const updatedParsedTD = {
82+ ...parsedTD ,
83+ events : {
84+ ...parsedTD . events ,
85+ [ newName ] : copiedEvent ,
86+ } ,
87+ } ;
88+
89+ context . updateOfflineTD ( JSON . stringify ( updatedParsedTD , null , 2 ) ) ;
90+ } ;
6791
6892 return (
6993 < details
@@ -72,16 +96,39 @@ const Event: React.FC<any> = (props) => {
7296 onToggle = { ( ) => setIsExpanded ( ! isExpanded ) }
7397 >
7498 < summary
75- className = { `flex cursor-pointer items-center rounded-t-lg pl-2 text-xl font-bold text-white ${ isExpanded ? "bg-gray-500" : "" } ` }
99+ className = { `flex cursor-pointer items-center rounded-t-lg pl-2 text-xl font-bold text-white ${
100+ isExpanded ? "bg-gray-500" : ""
101+ } `}
76102 >
77- < div className = "flex-grow px-2" > { event . title ?? props . eventName } </ div >
103+ < div className = "flex-grow px-2" >
104+ { event . title ?? props . eventName }
105+ </ div >
106+
78107 { isExpanded && (
79- < button
80- className = "flex h-10 w-10 items-center justify-center self-stretch rounded-bl-md rounded-tr-md bg-gray-400 text-base"
81- onClick = { handleDeleteEventClicked }
82- >
83- < Trash2 size = { 16 } color = "white" />
84- </ button >
108+ < >
109+ < button
110+ className = "flex h-10 w-10 items-center justify-center self-stretch bg-gray-400 text-base"
111+ title = "Copy event"
112+ onClick = { ( e ) => {
113+ e . preventDefault ( ) ;
114+ e . stopPropagation ( ) ;
115+ handleCopyEvent ( ) ;
116+ } }
117+ >
118+ < Copy size = { 16 } color = "white" />
119+ </ button >
120+ < button
121+ className = "flex h-10 w-10 items-center justify-center self-stretch rounded-bl-md rounded-tr-md bg-gray-400 text-base"
122+ title = "Delete event"
123+ onClick = { ( e ) => {
124+ e . preventDefault ( ) ;
125+ e . stopPropagation ( ) ;
126+ handleDeleteEventClicked ( ) ;
127+ } }
128+ >
129+ < Trash2 size = { 16 } color = "white" />
130+ </ button >
131+ </ >
85132 ) }
86133 </ summary >
87134
@@ -91,7 +138,9 @@ const Event: React.FC<any> = (props) => {
91138 { event . description }
92139 </ div >
93140 ) }
94- < ul className = "list-disc pl-6 text-base text-gray-300" > { attributes } </ ul >
141+ < ul className = "list-disc pl-6 text-base text-gray-300" >
142+ { attributes }
143+ </ ul >
95144
96145 < div className = "flex items-center justify-start pb-2 pt-2" >
97146 < InfoIconWrapper
@@ -102,10 +151,9 @@ const Event: React.FC<any> = (props) => {
102151 < h4 className = "pr-1 text-lg font-bold text-white" > Forms</ h4 >
103152 </ InfoIconWrapper >
104153 </ div >
105-
106154 < AddFormElement onClick = { handleOpenAddFormDialog } />
107155 < AddFormDialog
108- type = { "event" }
156+ type = "event"
109157 interaction = { event }
110158 interactionName = { props . eventName }
111159 ref = { addFormDialog }
@@ -115,8 +163,8 @@ const Event: React.FC<any> = (props) => {
115163 key = { `${ i } -${ form . href } ` }
116164 form = { form }
117165 propName = { props . eventName }
118- interactionType = { "event" }
119- > </ Form >
166+ interactionType = "event"
167+ / >
120168 ) ) }
121169 </ div >
122170 </ details >
0 commit comments