@forcecalendar/interface 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -349,11 +349,147 @@ export class ForceCalendar extends BaseComponent {
|
|
|
349
349
|
justify-content: space-between;
|
|
350
350
|
width: 100%;
|
|
351
351
|
}
|
|
352
|
-
|
|
352
|
+
|
|
353
353
|
#create-event-btn {
|
|
354
354
|
flex: 1;
|
|
355
355
|
}
|
|
356
356
|
}
|
|
357
|
+
|
|
358
|
+
/* Month View Styles (inline rendering for Locker Service compatibility) */
|
|
359
|
+
.fc-month-view {
|
|
360
|
+
display: flex;
|
|
361
|
+
flex-direction: column;
|
|
362
|
+
height: 100%;
|
|
363
|
+
background: var(--fc-background);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.fc-month-header {
|
|
367
|
+
display: grid;
|
|
368
|
+
grid-template-columns: repeat(7, 1fr);
|
|
369
|
+
border-bottom: 1px solid var(--fc-border-color);
|
|
370
|
+
background: var(--fc-background-alt);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.fc-month-header-cell {
|
|
374
|
+
padding: 12px 8px;
|
|
375
|
+
text-align: center;
|
|
376
|
+
font-size: 11px;
|
|
377
|
+
font-weight: 600;
|
|
378
|
+
color: var(--fc-text-light);
|
|
379
|
+
text-transform: uppercase;
|
|
380
|
+
letter-spacing: 0.05em;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
.fc-month-body {
|
|
384
|
+
display: flex;
|
|
385
|
+
flex-direction: column;
|
|
386
|
+
flex: 1;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
.fc-month-week {
|
|
390
|
+
display: grid;
|
|
391
|
+
grid-template-columns: repeat(7, 1fr);
|
|
392
|
+
flex: 1;
|
|
393
|
+
min-height: 100px;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.fc-month-day {
|
|
397
|
+
background: var(--fc-background);
|
|
398
|
+
border-right: 1px solid var(--fc-border-color);
|
|
399
|
+
border-bottom: 1px solid var(--fc-border-color);
|
|
400
|
+
padding: 4px;
|
|
401
|
+
min-height: 80px;
|
|
402
|
+
cursor: pointer;
|
|
403
|
+
transition: background-color 0.15s ease;
|
|
404
|
+
display: flex;
|
|
405
|
+
flex-direction: column;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
.fc-month-day:hover {
|
|
409
|
+
background: var(--fc-background-hover);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
.fc-month-day:last-child {
|
|
413
|
+
border-right: none;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
.fc-month-day.other-month {
|
|
417
|
+
background: var(--fc-background-alt);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.fc-month-day.other-month .fc-day-number {
|
|
421
|
+
color: var(--fc-text-light);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.fc-month-day.today {
|
|
425
|
+
background: rgba(37, 99, 235, 0.05);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.fc-month-day.today .fc-day-number {
|
|
429
|
+
background: var(--fc-primary-color);
|
|
430
|
+
color: white;
|
|
431
|
+
border-radius: 50%;
|
|
432
|
+
width: 24px;
|
|
433
|
+
height: 24px;
|
|
434
|
+
display: flex;
|
|
435
|
+
align-items: center;
|
|
436
|
+
justify-content: center;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
.fc-day-number {
|
|
440
|
+
font-size: 13px;
|
|
441
|
+
font-weight: 500;
|
|
442
|
+
color: var(--fc-text-color);
|
|
443
|
+
padding: 2px 4px;
|
|
444
|
+
margin-bottom: 4px;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
.fc-day-events {
|
|
448
|
+
display: flex;
|
|
449
|
+
flex-direction: column;
|
|
450
|
+
gap: 2px;
|
|
451
|
+
flex: 1;
|
|
452
|
+
overflow: hidden;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.fc-event {
|
|
456
|
+
font-size: 11px;
|
|
457
|
+
padding: 2px 6px;
|
|
458
|
+
border-radius: 3px;
|
|
459
|
+
color: white;
|
|
460
|
+
white-space: nowrap;
|
|
461
|
+
overflow: hidden;
|
|
462
|
+
text-overflow: ellipsis;
|
|
463
|
+
cursor: pointer;
|
|
464
|
+
transition: transform 0.1s ease;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.fc-event:hover {
|
|
468
|
+
transform: scale(1.02);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.fc-more-events {
|
|
472
|
+
font-size: 10px;
|
|
473
|
+
color: var(--fc-text-light);
|
|
474
|
+
padding: 2px 4px;
|
|
475
|
+
font-weight: 500;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/* Week View Styles (inline rendering for Locker Service compatibility) */
|
|
479
|
+
.fc-week-view {
|
|
480
|
+
display: flex;
|
|
481
|
+
flex-direction: column;
|
|
482
|
+
height: 100%;
|
|
483
|
+
background: var(--fc-background);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/* Day View Styles (inline rendering for Locker Service compatibility) */
|
|
487
|
+
.fc-day-view {
|
|
488
|
+
display: flex;
|
|
489
|
+
flex-direction: column;
|
|
490
|
+
height: 100%;
|
|
491
|
+
background: var(--fc-background);
|
|
492
|
+
}
|
|
357
493
|
`;
|
|
358
494
|
}
|
|
359
495
|
|
|
@@ -436,30 +572,53 @@ export class ForceCalendar extends BaseComponent {
|
|
|
436
572
|
const container = this.$('#calendar-view-container');
|
|
437
573
|
console.log('[ForceCalendar] afterRender - container:', !!container, 'stateManager:', !!this.stateManager, 'currentView:', this.currentView);
|
|
438
574
|
|
|
575
|
+
// Only create view once per view type change
|
|
439
576
|
if (container && this.stateManager && this.currentView) {
|
|
577
|
+
// Check if container actually has content (render() clears shadow DOM)
|
|
578
|
+
if (this._currentViewInstance && this._currentViewInstance._viewType === this.currentView && container.children.length > 0) {
|
|
579
|
+
console.log('[ForceCalendar] View already exists with content, skipping creation');
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
|
|
440
583
|
// Clean up previous view if exists
|
|
441
584
|
if (this._currentViewInstance) {
|
|
442
585
|
if (this._currentViewInstance.cleanup) {
|
|
443
586
|
this._currentViewInstance.cleanup();
|
|
444
587
|
}
|
|
588
|
+
if (this._viewUnsubscribe) {
|
|
589
|
+
this._viewUnsubscribe();
|
|
590
|
+
this._viewUnsubscribe = null;
|
|
591
|
+
}
|
|
445
592
|
}
|
|
446
593
|
|
|
447
594
|
console.log('[ForceCalendar] Creating view for:', this.currentView);
|
|
448
595
|
|
|
449
596
|
// Create a simple view renderer that doesn't use custom elements
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
597
|
+
try {
|
|
598
|
+
const viewRenderer = this._createViewRenderer(this.currentView);
|
|
599
|
+
if (viewRenderer) {
|
|
600
|
+
viewRenderer._viewType = this.currentView;
|
|
601
|
+
this._currentViewInstance = viewRenderer;
|
|
602
|
+
viewRenderer.stateManager = this.stateManager;
|
|
603
|
+
viewRenderer.container = container;
|
|
604
|
+
|
|
605
|
+
console.log('[ForceCalendar] Calling viewRenderer.render()');
|
|
606
|
+
viewRenderer.render();
|
|
607
|
+
console.log('[ForceCalendar] viewRenderer.render() completed');
|
|
608
|
+
|
|
609
|
+
// Subscribe to state changes (store unsubscribe function)
|
|
610
|
+
this._viewUnsubscribe = this.stateManager.subscribe((newState, oldState) => {
|
|
611
|
+
// Only re-render on data changes, not view changes
|
|
612
|
+
if (newState.events !== oldState?.events ||
|
|
613
|
+
newState.currentDate !== oldState?.currentDate) {
|
|
614
|
+
if (viewRenderer && viewRenderer.render) {
|
|
615
|
+
viewRenderer.render();
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
} catch (err) {
|
|
621
|
+
console.error('[ForceCalendar] Error creating/rendering view:', err);
|
|
463
622
|
}
|
|
464
623
|
}
|
|
465
624
|
|
|
@@ -529,18 +688,25 @@ export class ForceCalendar extends BaseComponent {
|
|
|
529
688
|
},
|
|
530
689
|
|
|
531
690
|
render() {
|
|
691
|
+
console.log('[ViewRenderer] render called, container:', !!this.container, 'stateManager:', !!this.stateManager);
|
|
532
692
|
if (!this.container || !this.stateManager) return;
|
|
533
693
|
|
|
534
694
|
const viewData = this.stateManager.getViewData();
|
|
695
|
+
console.log('[ViewRenderer] viewData:', viewData);
|
|
696
|
+
console.log('[ViewRenderer] viewData.weeks:', viewData?.weeks);
|
|
697
|
+
|
|
535
698
|
if (!viewData || !viewData.weeks) {
|
|
536
|
-
this.container.innerHTML = '<div style="padding: 20px; text-align: center;">
|
|
699
|
+
this.container.innerHTML = '<div style="padding: 20px; text-align: center; background: #fee; color: #c00;">No viewData.weeks available. viewData keys: ' + (viewData ? Object.keys(viewData).join(', ') : 'null') + '</div>';
|
|
537
700
|
return;
|
|
538
701
|
}
|
|
539
702
|
|
|
540
703
|
this.cleanup();
|
|
541
704
|
const config = this.stateManager.getState().config;
|
|
705
|
+
console.log('[ViewRenderer] Rendering month view with', viewData.weeks.length, 'weeks');
|
|
542
706
|
const html = this._renderMonthView(viewData, config);
|
|
707
|
+
console.log('[ViewRenderer] HTML length:', html.length);
|
|
543
708
|
this.container.innerHTML = html;
|
|
709
|
+
console.log('[ViewRenderer] innerHTML set, container children:', this.container.children.length);
|
|
544
710
|
this._attachEventHandlers();
|
|
545
711
|
},
|
|
546
712
|
|
|
@@ -552,55 +718,39 @@ export class ForceCalendar extends BaseComponent {
|
|
|
552
718
|
dayNames.push(['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][dayIndex]);
|
|
553
719
|
}
|
|
554
720
|
|
|
721
|
+
// Using inline styles for Locker Service compatibility
|
|
555
722
|
let html = `
|
|
556
|
-
<style>
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
.fc-month-header-cell { padding: 8px; text-align: left; font-weight: 600; font-size: 10px; color: #9ca3af; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
560
|
-
.fc-month-body { flex: 1; display: flex; flex-direction: column; }
|
|
561
|
-
.fc-month-week { flex: 1; display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; }
|
|
562
|
-
.fc-month-week:last-child { border-bottom: none; }
|
|
563
|
-
.fc-month-day { background: #fff; padding: 4px; position: relative; border-right: 1px solid #e5e7eb; min-height: 80px; cursor: pointer; }
|
|
564
|
-
.fc-month-day:last-child { border-right: none; }
|
|
565
|
-
.fc-month-day:hover { background: #f9fafb; }
|
|
566
|
-
.fc-month-day.other-month { background: #f9fafb; }
|
|
567
|
-
.fc-month-day.other-month .fc-day-number { color: #d1d5db; }
|
|
568
|
-
.fc-month-day.today .fc-day-number { background: #ef4444; color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }
|
|
569
|
-
.fc-day-number { font-size: 12px; font-weight: 500; color: #111827; padding: 4px; }
|
|
570
|
-
.fc-day-events { display: flex; flex-direction: column; gap: 2px; margin-top: 2px; }
|
|
571
|
-
.fc-event { font-size: 11px; padding: 2px 6px; border-radius: 2px; background: #2563eb; color: white; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; cursor: pointer; }
|
|
572
|
-
.fc-event:hover { opacity: 0.9; }
|
|
573
|
-
.fc-more-events { font-size: 10px; color: #6b7280; padding: 2px 4px; cursor: pointer; }
|
|
574
|
-
.fc-more-events:hover { color: #111827; text-decoration: underline; }
|
|
575
|
-
</style>
|
|
576
|
-
<div class="fc-month-view">
|
|
577
|
-
<div class="fc-month-header">
|
|
578
|
-
${dayNames.map(d => `<div class="fc-month-header-cell">${d}</div>`).join('')}
|
|
723
|
+
<div class="fc-month-view" style="display: flex; flex-direction: column; height: 100%; min-height: 400px; background: #fff; border: 1px solid #e5e7eb;">
|
|
724
|
+
<div class="fc-month-header" style="display: grid; grid-template-columns: repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb;">
|
|
725
|
+
${dayNames.map(d => `<div class="fc-month-header-cell" style="padding: 12px 8px; text-align: center; font-size: 11px; font-weight: 600; color: #6b7280; text-transform: uppercase;">${d}</div>`).join('')}
|
|
579
726
|
</div>
|
|
580
|
-
<div class="fc-month-body">
|
|
727
|
+
<div class="fc-month-body" style="display: flex; flex-direction: column; flex: 1;">
|
|
581
728
|
`;
|
|
582
729
|
|
|
583
730
|
viewData.weeks.forEach(week => {
|
|
584
|
-
html += '<div class="fc-month-week">';
|
|
731
|
+
html += '<div class="fc-month-week" style="display: grid; grid-template-columns: repeat(7, 1fr); flex: 1; min-height: 80px;">';
|
|
585
732
|
week.days.forEach(day => {
|
|
586
|
-
const
|
|
587
|
-
|
|
588
|
-
|
|
733
|
+
const isOtherMonth = !day.isCurrentMonth;
|
|
734
|
+
const isToday = day.isToday;
|
|
735
|
+
|
|
736
|
+
const dayBg = isOtherMonth ? '#f3f4f6' : '#fff';
|
|
737
|
+
const dayNumColor = isOtherMonth ? '#9ca3af' : '#111827';
|
|
738
|
+
const todayStyle = isToday ? 'background: #2563eb; color: white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;' : '';
|
|
589
739
|
|
|
590
740
|
const events = day.events || [];
|
|
591
741
|
const visibleEvents = events.slice(0, 3);
|
|
592
742
|
const moreCount = events.length - 3;
|
|
593
743
|
|
|
594
744
|
html += `
|
|
595
|
-
<div class="
|
|
596
|
-
<div class="fc-day-number">${day.dayOfMonth}</div>
|
|
597
|
-
<div class="fc-day-events">
|
|
745
|
+
<div class="fc-month-day" data-date="${day.date}" style="background: ${dayBg}; border-right: 1px solid #e5e7eb; border-bottom: 1px solid #e5e7eb; padding: 4px; min-height: 80px; cursor: pointer;">
|
|
746
|
+
<div class="fc-day-number" style="font-size: 13px; font-weight: 500; color: ${dayNumColor}; padding: 2px 4px; margin-bottom: 4px; ${todayStyle}">${day.dayOfMonth}</div>
|
|
747
|
+
<div class="fc-day-events" style="display: flex; flex-direction: column; gap: 2px;">
|
|
598
748
|
${visibleEvents.map(evt => `
|
|
599
|
-
<div class="fc-event" data-event-id="${evt.id}" style="background-color: ${evt.backgroundColor || '#2563eb'}">
|
|
749
|
+
<div class="fc-event" data-event-id="${evt.id}" style="background-color: ${evt.backgroundColor || '#2563eb'}; font-size: 11px; padding: 2px 6px; border-radius: 3px; color: white; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;">
|
|
600
750
|
${evt.title}
|
|
601
751
|
</div>
|
|
602
752
|
`).join('')}
|
|
603
|
-
${moreCount > 0 ? `<div class="fc-more-events">+${moreCount} more</div>` : ''}
|
|
753
|
+
${moreCount > 0 ? `<div class="fc-more-events" style="font-size: 10px; color: #6b7280; padding: 2px 4px; font-weight: 500;">+${moreCount} more</div>` : ''}
|
|
604
754
|
</div>
|
|
605
755
|
</div>
|
|
606
756
|
`;
|