Skip to content

Commit

Permalink
Merge pull request #198 from metalshub/includeCalendarWeeks
Browse files Browse the repository at this point in the history
introduce calendar weeks
  • Loading branch information
danielmoncada authored Aug 12, 2024
2 parents 21b26a8 + 78753f3 commit f252bb8
Show file tree
Hide file tree
Showing 10 changed files with 144 additions and 5 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ Properties for `owl-date-time`
|`pickerMode`|`popup`, `dialog`|Optional|`popup`| The style the picker would open as. |
|`startView`|`month`, `year`, `multi-year`|Optional|`month`| The view that the calendar should start in. |
|`yearOnly`|boolean|Optional|`false`| Restricts the calendar to only show the year and multi-year views for month selection. |
|`showCalendarWeeks`|boolean|Optional|`false`| Whether to show calendar weeks in the calendar. |
|`multiyearOnly`|boolean|Optional|`false`| Restricts the calendar to only show the multi-year view for year selection. |
|`startAt`| T/null |Optional|`null`| The moment to open the picker to initially. |
|`endAt`| T/null |Optional|`null`| The the default selected time for range calendar end time |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
<table class="owl-dt-calendar-table owl-dt-calendar-month-table"
<ul class="week-number" *ngIf="showCalendarWeeks">
<li *ngFor="let week of weekNumbers;">
<span>{{ week }}</span>
</li>
</ul>
<table class="owl-dt-calendar-table owl-dt-calendar-month-table" [ngClass]="{'owl-calendar-weeks': showCalendarWeeks}"
[class.owl-dt-calendar-only-current-month]="hideOtherMonths">
<thead class="owl-dt-calendar-header">
<tr class="owl-dt-weekdays">
Expand All @@ -9,7 +14,7 @@
</th>
</tr>
<tr>
<th class="owl-dt-calendar-table-divider" aria-hidden="true" colspan="7"></th>
<th class="owl-dt-calendar-table-divider" [ngClass]="{'owl-calendar-weeks': showCalendarWeeks}" aria-hidden="true" colspan="7"></th>
</tr>
</thead>
<tbody owl-date-time-calendar-body role="grid"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.week-number {
display: flex;
flex-direction: column;
justify-content: space-between;
margin: 0;
padding: 0;
list-style: none;
margin-bottom: 14px;
margin-top: 46px;
border-right: 1px solid rgba(0, 0, 0, .12);
width: 8%;
font-weight: bold;
li {
font-size: .8em;
}
}
29 changes: 27 additions & 2 deletions projects/picker/src/lib/date-time/calendar-month-view.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ export class OwlMonthViewComponent<T>
* */
@Input()
hideOtherMonths = false;

/**
* Whether to show calendar weeks in the calendar
* */
@Input()
showCalendarWeeks = false;

private isDefaultFirstDayOfWeek = true;

Expand Down Expand Up @@ -257,6 +263,11 @@ export class OwlMonthViewComponent<T>
* */
public todayDate: number | null;

/**
* Week day numbers
* */
public weekNumbers: number[];

/**
* An array to hold all selectedDates' value
* the value is the day number in current month
Expand Down Expand Up @@ -485,6 +496,7 @@ export class OwlMonthViewComponent<T>
}

this.todayDate = null;
this.weekNumbers = [];

// the first weekday of the month
const startWeekdayOfMonth = this.dateTimeAdapter.getDay(
Expand All @@ -511,7 +523,6 @@ export class OwlMonthViewComponent<T>
daysDiff
);
const dateCell = this.createDateCell(date, daysDiff);

// check if the date is today
if (
this.dateTimeAdapter.isSameDay(
Expand All @@ -526,11 +537,25 @@ export class OwlMonthViewComponent<T>
daysDiff += 1;
}
this._days.push(week);
if (this.showCalendarWeeks) {
const weekNumber = this.getISOWeek(new Date(week[0].ariaLabel));
this.weekNumbers.push(weekNumber);
}
}

this.setSelectedDates();
}

public getISOWeek(d: Date): number {
const clonedDate = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
// Make Sunday's day number 7
clonedDate.setUTCDate(clonedDate.getUTCDate() + 4 - (clonedDate.getUTCDay()||7));
// Get first day of year
const yearStart = new Date(Date.UTC(clonedDate.getUTCFullYear(),0,1));
// Calculate full weeks to nearest Thursday
const weekNo = Math.ceil(( ( (+clonedDate - +yearStart) / 86400000) + 1)/7);
return weekNo;
}

private updateFirstDayOfWeek(locale: string): void {
if (this.isDefaultFirstDayOfWeek) {
try {
Expand Down
1 change: 1 addition & 0 deletions projects/picker/src/lib/date-time/calendar.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
[selecteds]="selecteds"
[selectMode]="selectMode"
[minDate]="minDate"
[showCalendarWeeks]="showCalendarWeeks"
[maxDate]="maxDate"
[dateFilter]="dateFilter"
[hideOtherMonths]="hideOtherMonths"
Expand Down
69 changes: 69 additions & 0 deletions projects/picker/src/lib/date-time/calendar.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ describe('OwlCalendarComponent', () => {
imports: [OwlNativeDateTimeModule, OwlDateTimeModule],
declarations: [
StandardCalendarComponent,
CalendarWithCalendarWeeks,
CalendarWithMinMaxComponent,
CalendarWithDateFilterComponent
],
Expand Down Expand Up @@ -294,6 +295,60 @@ describe('OwlCalendarComponent', () => {
});
});

describe('calendar with Calendar Weeks', () => {
let fixture: ComponentFixture<CalendarWithCalendarWeeks>;
let testComponent: CalendarWithCalendarWeeks;
let calendarElement: HTMLElement;
let calendarInstance: OwlCalendarComponent<Date>;

beforeEach(() => {
fixture = TestBed.createComponent(CalendarWithCalendarWeeks);
fixture.detectChanges();

const calendarDebugElement = fixture.debugElement.query(
By.directive(OwlCalendarComponent)
);
calendarElement = calendarDebugElement.nativeElement;

calendarInstance = calendarDebugElement.componentInstance;
testComponent = fixture.componentInstance;
});

it('should show calendar weeks when attribute showCalendarWeeks in true', () => {
// Check the initial value is false
expect(calendarInstance.showCalendarWeeks).toBe(false);
testComponent.showCalendarWeeks = true;
fixture.detectChanges(); // Trigger change detection to apply the new value
// Now check if the calendarInstance reflects this change
expect(calendarInstance.showCalendarWeeks).toBe(true);
});

it('should show calendar weeks classes only when attribute showCalendarWeeks in true', () => {
// Check the initial value is false
expect(calendarInstance.showCalendarWeeks).toBe(false);

// Verify classes are not present initially
let weekNumberElement = fixture.debugElement.nativeElement.querySelector('.week-number');
let owlCalendarWeeksElement = fixture.debugElement.nativeElement.querySelector('.owl-calendar-weeks');
expect(weekNumberElement).toBeNull();
expect(owlCalendarWeeksElement).toBeNull();

// Set showCalendarWeeks to true
testComponent.showCalendarWeeks = true;
fixture.detectChanges(); // Trigger change detection to apply the new value

// Now check if the calendarInstance reflects this change
expect(calendarInstance.showCalendarWeeks).toBe(true);

// Verify classes are present after the change
weekNumberElement = fixture.debugElement.nativeElement.querySelector('.week-number');
owlCalendarWeeksElement = fixture.debugElement.nativeElement.querySelector('.owl-calendar-weeks');
expect(weekNumberElement).toBeTruthy();
expect(owlCalendarWeeksElement).toBeTruthy();
});
});


describe('calendar with min and max', () => {
let fixture: ComponentFixture<CalendarWithMinMaxComponent>;
let testComponent: CalendarWithMinMaxComponent;
Expand Down Expand Up @@ -502,6 +557,20 @@ class CalendarWithMinMaxComponent {
pickerMoment = new Date(2018, JAN, 31);
}

@Component({
template: `
<owl-date-time-calendar [selectMode]="selectMode"
[pickerMoment]="pickerMoment"
[showCalendarWeeks]="showCalendarWeeks"></owl-date-time-calendar>
`
})
class CalendarWithCalendarWeeks {
selectMode = 'single';
startAt: Date;
showCalendarWeeks = false;
pickerMoment = new Date(2018, JAN, 31);
}

@Component({
template: `
<owl-date-time-calendar [(selected)]="selected"
Expand Down
6 changes: 6 additions & 0 deletions projects/picker/src/lib/date-time/calendar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,12 @@ export class OwlCalendarComponent<T>
*/
@Input()
yearOnly = false;

/**
* Whether to show calendar weeks in the calendar
* */
@Input()
showCalendarWeeks = false;

/**
* Whether to should only the multi-year view.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
[dateFilter]="picker.dateTimeFilter"
[startView]="picker.startView"
[yearOnly]="picker.yearOnly"
[showCalendarWeeks]="picker.showCalendarWeeks"
[multiyearOnly]="picker.multiyearOnly"
[hideOtherMonths]="picker.hideOtherMonths"
(yearSelected)="picker.selectYear($event)"
Expand Down
5 changes: 5 additions & 0 deletions projects/picker/src/lib/date-time/date-time.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ export abstract class OwlDateTime<T> {
@Input()
startView: DateViewType = DateView.MONTH;

/**
* Whether to show calendar weeks in the calendar
* */
@Input()
showCalendarWeeks = false;

/**
* Whether to should only the year and multi-year views.
Expand Down
12 changes: 11 additions & 1 deletion projects/picker/src/sass/picker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ $theme-color: #3f51b5;
}

.owl-dt-calendar-view {
display: block;
display: flex;
-webkit-box-flex: 1;
flex: 1 1 auto;
}
Expand Down Expand Up @@ -287,6 +287,11 @@ $theme-color: #3f51b5;
height: 1px;
background: rgba(0, 0, 0, .12);
}
&.owl-calendar-weeks {
&:after {
left: -1.8em;
}
}
}
}

Expand Down Expand Up @@ -374,6 +379,11 @@ $theme-color: #3f51b5;
border-bottom-right-radius: 999px;
}
}
&.owl-calendar-weeks {
.owl-dt-calendar-cell-content {
height: 86%; // adjust for the additional space taked for calendar weeks
}
}
}

.owl-dt-timer {
Expand Down

0 comments on commit f252bb8

Please sign in to comment.