@@ -15,7 +15,7 @@ import timeGridPlugin from "@fullcalendar/timegrid";
1515import interactionPlugin , { EventResizeDoneArg } from "@fullcalendar/interaction" ;
1616import listPlugin from "@fullcalendar/list" ;
1717import allLocales from "@fullcalendar/core/locales-all" ;
18- import { EventContentArg , DateSelectArg , EventDropArg } from "@fullcalendar/core" ;
18+ import { EventContentArg , DateSelectArg , EventDropArg , EventInput } from "@fullcalendar/core" ;
1919import momentPlugin from "@fullcalendar/moment" ;
2020
2121import ErrorBoundary from "./errorBoundary" ;
@@ -58,6 +58,8 @@ import {
5858depsConfig ,
5959stateComp ,
6060JSONObject ,
61+ isDynamicSegment ,
62+ Theme ,
6163} from 'lowcoder-sdk' ;
6264
6365import {
@@ -81,11 +83,14 @@ import {
8183resourcesDefaultData ,
8284resourceTimeLineHeaderToolbar ,
8385resourceTimeGridHeaderToolbar ,
86+ formattedEvents ,
8487} from "./calendarConstants" ;
8588import { EventOptionControl } from "./eventOptionsControl" ;
8689import { EventImpl } from "@fullcalendar/core/internal" ;
8790import DatePicker from "antd/es/date-picker" ;
8891
92+ type Theme = typeof Theme ;
93+
8994const DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss" ;
9095
9196function fixOldData ( oldData :any ) {
@@ -206,6 +211,7 @@ let childrenMap: any = {
206211showVerticalScrollbar :withDefault ( BoolControl , false ) ,
207212showResourceEventsInFreeView :withDefault ( BoolControl , false ) ,
208213initialData :stateComp < JSONObject > ( { } ) ,
214+ updatedEventsData :stateComp < JSONObject > ( defaultEvents ) ,
209215updatedEvents :stateComp < JSONObject > ( { } ) ,
210216insertedEvents :stateComp < JSONObject > ( { } ) ,
211217deletedEvents :stateComp < JSONObject > ( { } ) ,
@@ -251,15 +257,16 @@ let CalendarBasicComp = (function () {
251257showVerticalScrollbar ?:boolean ;
252258showResourceEventsInFreeView ?:boolean ;
253259initialData :Array < EventType > ;
260+ updatedEventsData :Array < EventType > ;
254261inputFormat :string ;
255262} , dispatch :any ) => {
256263const comp = useContext ( EditorContext ) ?. getUICompByName (
257264useContext ( CompNameContext )
258265) ;
259266
260- const theme = useContext ( ThemeContext ) ;
267+ const theme : Theme | undefined = useContext ( ThemeContext ) ;
261268const ref = createRef < HTMLDivElement > ( ) ;
262- const editEvent = useRef < EventType > ( ) ;
269+ const editEvent = useRef < EventInput > ( ) ;
263270const initData = useRef < boolean > ( false ) ;
264271const [ form ] = Form . useForm ( ) ;
265272const [ left , setLeft ] = useState < number | undefined > ( undefined ) ;
@@ -294,63 +301,75 @@ let CalendarBasicComp = (function () {
294301
295302const currentEvents = useMemo ( ( ) => {
296303if ( props . showResourceEventsInFreeView && Boolean ( props . licenseKey ) ) {
297- return props . events . filter ( ( event :{ resourceId :any ; } ) => Boolean ( event . resourceId ) )
304+ return props . updatedEventsData . filter ( ( event :{ resourceId ? :any ; } ) => Boolean ( event . resourceId ) )
298305}
299306return currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay"
300- ?props . events . filter ( ( event :{ resourceId :any ; } ) => Boolean ( event . resourceId ) )
301- :props . events . filter ( ( event :{ resourceId :any ; } ) => ! Boolean ( event . resourceId ) ) ;
307+ ?props . updatedEventsData . filter ( ( event :{ resourceId ? :any ; } ) => Boolean ( event . resourceId ) )
308+ :props . updatedEventsData . filter ( ( event :{ resourceId ? :any ; } ) => ! Boolean ( event . resourceId ) ) ;
302309} , [
303310currentView ,
304- props . events ,
311+ props . updatedEventsData ,
305312props . showResourceEventsInFreeView ,
306313] )
307314
308315// we use one central stack of events for all views
309- const events = useMemo ( ( ) => {
310- return Array . isArray ( currentEvents ) ?currentEvents . map ( ( item :EventType ) => {
311- return {
312- title :item . label ,
313- id :item . id ,
314- start :dayjs ( item . start , DateParser ) . format ( ) ,
315- end :dayjs ( item . end , DateParser ) . format ( ) ,
316- allDay :item . allDay ,
317- ...( item . resourceId ?{ resourceId :item . resourceId } :{ } ) ,
318- ...( item . groupId ?{ groupId :item . groupId } :{ } ) ,
319- backgroundColor :item . backgroundColor ,
320- extendedProps :{ // Ensure color is in extendedProps
321- color :isValidColor ( item . color || "" ) ?item . color :theme ?. theme ?. primary ,
322- detail :item . detail ,
323- titleColor :item . titleColor ,
324- detailColor :item . detailColor ,
325- titleFontWeight :item . titleFontWeight ,
326- titleFontStyle :item . titleFontStyle ,
327- detailFontWeight :item . detailFontWeight ,
328- detailFontStyle :item . detailFontStyle ,
329- animation :item ?. animation ,
330- animationDelay :item ?. animationDelay ,
331- animationDuration :item ?. animationDuration ,
332- animationIterationCount :item ?. animationIterationCount
333- }
334- }
335- } ) :[ currentEvents ] ;
316+ const events :EventInput = useMemo ( ( ) => {
317+ return formattedEvents ( currentEvents , theme ) ;
336318} , [ currentEvents , theme ] )
337319
320+ const initialEvents = useMemo ( ( ) => {
321+ let eventsList :EventType [ ] = [ ] ;
322+ if ( props . showResourceEventsInFreeView && Boolean ( props . licenseKey ) ) {
323+ eventsList = props . events . filter ( ( event :{ resourceId ?:any ; } ) => Boolean ( event . resourceId ) )
324+ }
325+ else {
326+ if ( currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay" ) {
327+ eventsList = props . events . filter ( ( event :{ resourceId ?:any ; } ) => Boolean ( event . resourceId ) )
328+ } else {
329+ eventsList = props . events . filter ( ( event :{ resourceId ?:any ; } ) => ! Boolean ( event . resourceId ) ) ;
330+ }
331+ }
332+
333+ return eventsList . map ( event => ( {
334+ ...event ,
335+ start :dayjs ( event . start , DateParser ) . format ( ) ,
336+ end :dayjs ( event . end , DateParser ) . format ( ) ,
337+ } ) ) ;
338+ } , [
339+ JSON . stringify ( props . events ) ,
340+ ] )
341+
342+ useEffect ( ( ) => {
343+ initData . current = false ;
344+ } , [ JSON . stringify ( props . events ) ] ) ;
345+
338346useEffect ( ( ) => {
339347if ( initData . current ) return ;
340348
341349const mapData :Record < string , number > = { } ;
342- events ?. forEach ( ( item :any , index :number ) => {
350+ initialEvents ?. forEach ( ( item :any , index :number ) => {
343351mapData [ `${ item . id } ` ] = index ;
344352} )
345353
346- if ( ! initData . current && events ?. length && comp ?. children ?. comp ?. children ?. initialData ) {
354+ if ( ! initData . current && initialEvents ?. length && comp ?. children ?. comp ?. children ?. initialData ) {
347355setInitDataMap ( mapData ) ;
348356comp ?. children ?. comp ?. children ?. initialData ?. dispatch ?.(
349- comp ?. children ?. comp ?. children ?. initialData ?. changeValueAction ?.( [ ...events ] )
357+ comp ?. children ?. comp ?. children ?. initialData ?. changeValueAction ?.( [ ...initialEvents ] )
358+ ) ;
359+
360+ const eventsList = props . events . map ( ( event :EventType ) => ( {
361+ ...event ,
362+ start :dayjs ( event . start , DateParser ) . format ( ) ,
363+ end :dayjs ( event . end , DateParser ) . format ( ) ,
364+ } ) ) ;
365+
366+ comp ?. children ?. comp ?. children ?. updatedEventsData ?. dispatch ?.(
367+ comp ?. children ?. comp ?. children ?. updatedEventsData ?. changeValueAction ?.( eventsList )
350368) ;
369+
351370initData . current = true ;
352371}
353- } , [ JSON . stringify ( events ) , comp ?. children ?. comp ?. children ?. initialData ] ) ;
372+ } , [ JSON . stringify ( initialEvents ) , comp ?. children ?. comp ?. children ?. initialData ] ) ;
354373
355374const resources = useMemo ( ( ) => props . resources . value , [ props . resources . value ] ) ;
356375
@@ -413,35 +432,10 @@ let CalendarBasicComp = (function () {
413432const findUpdatedInsertedDeletedEvents = useCallback ( ( data :Array < EventType > ) => {
414433if ( ! initData . current ) return ;
415434
416- let eventsData :Array < Record < string , any > > = currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay"
435+ const eventsData :Array < EventType > = currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay"
417436 ?data . filter ( ( event :{ resourceId ?:string ; } ) => Boolean ( event . resourceId ) )
418437 :data . filter ( ( event :{ resourceId ?:string ; } ) => ! Boolean ( event . resourceId ) ) ;
419438
420- eventsData = eventsData . map ( ( item ) => ( {
421- title :item . label ,
422- id :item . id ,
423- start :dayjs ( item . start , DateParser ) . format ( ) ,
424- end :dayjs ( item . end , DateParser ) . format ( ) ,
425- allDay :item . allDay ,
426- ...( item . resourceId ?{ resourceId :item . resourceId } :{ } ) ,
427- ...( item . groupId ?{ groupId :item . groupId } :{ } ) ,
428- backgroundColor :item . backgroundColor ,
429- extendedProps :{ // Ensure color is in extendedProps
430- color :isValidColor ( item . color || "" ) ?item . color :theme ?. theme ?. primary ,
431- detail :item . detail ,
432- titleColor :item . titleColor ,
433- detailColor :item . detailColor ,
434- titleFontWeight :item . titleFontWeight ,
435- titleFontStyle :item . titleFontStyle ,
436- detailFontWeight :item . detailFontWeight ,
437- detailFontStyle :item . detailFontStyle ,
438- animation :item ?. animation ,
439- animationDelay :item ?. animationDelay ,
440- animationDuration :item ?. animationDuration ,
441- animationIterationCount :item ?. animationIterationCount
442- }
443- } ) ) ;
444-
445439const mapData :Record < string , number > = { } ;
446440eventsData ?. forEach ( ( item :any , index :number ) => {
447441mapData [ `${ item . id } ` ] = index ;
@@ -458,13 +452,8 @@ let CalendarBasicComp = (function () {
458452} , [ initDataMap , currentView , props . initialData , initData . current ] ) ;
459453
460454const handleEventDataChange = useCallback ( ( data :Array < EventType > ) => {
461- comp ?. children ?. comp . children . events . children . manual . children . manual . dispatch (
462- comp ?. children ?. comp . children . events . children . manual . children . manual . setChildrensAction (
463- data
464- )
465- ) ;
466- comp ?. children ?. comp . children . events . children . mapData . children . data . dispatchChangeValueAction (
467- JSON . stringify ( data )
455+ comp ?. children ?. comp ?. children ?. updatedEventsData ?. dispatch ?.(
456+ comp ?. children ?. comp ?. children ?. updatedEventsData ?. changeValueAction ?.( data )
468457) ;
469458
470459findUpdatedInsertedDeletedEvents ( data ) ;
@@ -522,7 +511,7 @@ let CalendarBasicComp = (function () {
522511className = "event-remove"
523512onClick = { ( e ) => {
524513e . stopPropagation ( ) ;
525- const events = props . events . filter (
514+ const events = props . updatedEventsData . filter (
526515( item :EventType ) => item . id !== eventInfo . event . id
527516) ;
528517handleEventDataChange ( events ) ;
@@ -541,7 +530,7 @@ let CalendarBasicComp = (function () {
541530} , [
542531theme ,
543532props . style ,
544- props . events ,
533+ props . updatedEventsData ,
545534props . showAllDay ,
546535handleEventDataChange ,
547536] ) ;
@@ -780,7 +769,7 @@ let CalendarBasicComp = (function () {
780769 end,
781770 allDay,
782771} = form . getFieldsValue ( ) ;
783- const idExist = props . events . findIndex (
772+ const idExist = props . updatedEventsData . findIndex (
784773( item :EventType ) => item . id === id
785774) ;
786775if ( idExist > - 1 && id !== eventId ) {
@@ -790,7 +779,7 @@ let CalendarBasicComp = (function () {
790779throw new Error ( ) ;
791780}
792781if ( ifEdit ) {
793- const changeEvents = props . events . map ( ( item :EventType ) => {
782+ const changeEvents = props . updatedEventsData . map ( ( item :EventType ) => {
794783if ( item . id === eventId ) {
795784return {
796785 ...item ,
@@ -843,7 +832,7 @@ let CalendarBasicComp = (function () {
843832 ...( titleColor !== undefined ?{ titleColor} :null ) ,
844833 ...( detailColor !== undefined ?{ detailColor} :null ) ,
845834} ;
846- handleEventDataChange ( [ ...props . events , createInfo ] ) ;
835+ handleEventDataChange ( [ ...props . updatedEventsData , createInfo ] ) ;
847836}
848837form . resetFields ( ) ;
849838} ) ; //small change
@@ -855,14 +844,14 @@ let CalendarBasicComp = (function () {
855844} , [
856845form ,
857846editEvent ,
858- props . events ,
847+ props . updatedEventsData ,
859848props ?. modalStyle ,
860849props ?. animationStyle ,
861850handleEventDataChange ,
862851] ) ;
863852
864853const handleDbClick = useCallback ( ( ) => {
865- const event = props . events . find (
854+ const event = props . updatedEventsData . find (
866855( item :EventType ) => item . id === editEvent . current ?. id
867856) as EventType ;
868857if ( ! props . editable || ! editEvent . current ) {
@@ -880,7 +869,7 @@ let CalendarBasicComp = (function () {
880869}
881870} , [
882871editEvent ,
883- props . events ,
872+ props . updatedEventsData ,
884873props . editable ,
885874onEventVal ,
886875showModal ,
@@ -911,7 +900,7 @@ let CalendarBasicComp = (function () {
911900const updateEventsOnDragOrResize = useCallback ( ( eventInfo :EventImpl ) => {
912901const { extendedProps, title, ...event } = eventInfo . toJSON ( ) ;
913902
914- let eventsList = [ ...props . events ] ;
903+ let eventsList = [ ...props . updatedEventsData ] ;
915904const eventIdx = eventsList . findIndex (
916905( item :EventType ) => item . id === event . id
917906) ;
@@ -923,7 +912,7 @@ let CalendarBasicComp = (function () {
923912} ;
924913handleEventDataChange ( eventsList ) ;
925914}
926- } , [ props . events , handleEventDataChange ] ) ;
915+ } , [ props . updatedEventsData , handleEventDataChange ] ) ;
927916
928917const handleDrop = useCallback ( ( eventInfo :EventDropArg ) => {
929918updateEventsOnDragOrResize ( eventInfo . event ) ;
@@ -987,7 +976,7 @@ let CalendarBasicComp = (function () {
987976select = { ( info ) => handleCreate ( info ) }
988977eventClick = { ( info ) => {
989978const event = events . find (
990- ( item :EventType ) => item . id === info . event . id
979+ ( item :EventInput ) => item . id === info . event . id
991980) ;
992981editEvent . current = event ;
993982setTimeout ( ( ) => {
@@ -1018,9 +1007,9 @@ let CalendarBasicComp = (function () {
10181007} }
10191008eventsSet = { ( info ) => {
10201009let needChange = false ;
1021- let changeEvents :EventType [ ] = [ ] ;
1010+ let changeEvents :EventInput [ ] = [ ] ;
10221011info . forEach ( ( item ) => {
1023- const event = events . find ( ( i :EventType ) => i . id === item . id ) ;
1012+ const event = events . find ( ( i :EventInput ) => i . id === item . id ) ;
10241013const start = dayjs ( item . start , DateParser ) . format ( ) ;
10251014const end = dayjs ( item . end , DateParser ) . format ( ) ;
10261015if (
@@ -1076,7 +1065,7 @@ let CalendarBasicComp = (function () {
10761065style :{ getPropertyView :( ) => any ; } ;
10771066animationStyle :{ getPropertyView :( ) => any ; } ;
10781067modalStyle :{ getPropertyView :( ) => any ; } ;
1079- licenseKey :{ getView :( ) => any ; propertyView :( arg0 :{ label :string ; } ) => any ; } ;
1068+ licenseKey :{ getView :( ) => any ; propertyView :( arg0 :{ label :string ; tooltip : string } ) => any ; } ;
10801069showVerticalScrollbar :{ propertyView :( arg0 :{ label :string ; } ) => any ; } ;
10811070showResourceEventsInFreeView :{ propertyView :( arg0 :{ label :string ; } ) => any ; } ;
10821071inputFormat :{ propertyView :( arg0 :{ } ) => any ; } ;
@@ -1172,25 +1161,25 @@ const TmpCalendarComp = withExposingConfigs(CalendarBasicComp, [
11721161depsConfig ( {
11731162name :"allEvents" ,
11741163desc :trans ( "calendar.events" ) ,
1175- depKeys :[ "events " ] ,
1176- func :( input :{ events :any [ ] ; } ) => {
1177- return input . events ;
1164+ depKeys :[ "updatedEventsData " ] ,
1165+ func :( input :{ updatedEventsData :any [ ] ; } ) => {
1166+ return input . updatedEventsData ;
11781167} ,
11791168} ) ,
11801169depsConfig ( {
11811170name :"events" ,
11821171desc :trans ( "calendar.events" ) ,
1183- depKeys :[ "events " ] ,
1184- func :( input :{ events :any [ ] ; } ) => {
1185- return input . events . filter ( event => ! Boolean ( event . resourceId ) ) ;
1172+ depKeys :[ "updatedEventsData " ] ,
1173+ func :( input :{ updatedEventsData :any [ ] ; } ) => {
1174+ return input . updatedEventsData . filter ( event => ! Boolean ( event . resourceId ) ) ;
11861175} ,
11871176} ) ,
11881177depsConfig ( {
11891178name :"resourcesEvents" ,
11901179desc :trans ( "calendar.resourcesEvents" ) ,
1191- depKeys :[ "events " ] ,
1192- func :( input :{ events :any [ ] ; } ) => {
1193- return input . events . filter ( event => Boolean ( event . resourceId ) ) ;
1180+ depKeys :[ "updatedEventsData " ] ,
1181+ func :( input :{ updatedEventsData :any [ ] ; } ) => {
1182+ return input . updatedEventsData . filter ( event => Boolean ( event . resourceId ) ) ;
11941183} ,
11951184} ) ,
11961185depsConfig ( {