Skip to content

Commit

Permalink
feat(calendars): add ethiopian calendar module
Browse files Browse the repository at this point in the history
  • Loading branch information
trik committed Jan 27, 2020
1 parent 0454e6e commit 55064f6
Show file tree
Hide file tree
Showing 36 changed files with 1,091 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
/src/monaco/lib/* @trik
/src/monaco/src/* @trik

# Ajf calendars
/src/calendars/* @trik
/src/calendars/ethiopian/* @trik

# Docs examples & guides
/guides/** @trik
/src/material-examples/** @trik
Expand All @@ -59,6 +63,7 @@
/src/dev-app-mat/* @trik
/src/dev-app-mat/barcode/** @peppedeka
/src/dev-app-mat/calendar/** @trik
/src/dev-app-mat/calendar-ethiopian/** @trik
/src/dev-app-mat/checkbox-group/** @trik
/src/dev-app-mat/dev-app/** @trik
/src/dev-app-mat/example/** @trik
Expand Down
6 changes: 6 additions & 0 deletions packages.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ IONIC_PACKAGES = [

IONIC_TARGETS = ["//src/ionic"] + ["//src/ionic/%s" % p for p in IONIC_PACKAGES]

CALENDARS_PACKAGES = [
"ethiopian",
]

CALENDARS_TARGETS = ["//src/calendars"] + ["//src/calendars/%s" % p for p in CALENDARS_PACKAGES]

# Each individual package uses a placeholder for the version of Angular to ensure they're
# all in-sync. This map is passed to each ng_package rule to stamp out the appropriate
# version for the placeholders.
Expand Down
35 changes: 35 additions & 0 deletions src/calendars/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package(default_visibility = ["//visibility:public"])

load("//:packages.bzl", "CALENDARS_PACKAGES", "CALENDARS_TARGETS", "ROLLUP_GLOBALS")
load("//tools:defaults.bzl", "ng_module", "ng_package")

# Root "@ajf/calendars" entry-point that does not re-export individual entry-points.
ng_module(
name = "calendars",
srcs = glob(
["*.ts"],
exclude = ["**/*.spec.ts"],
),
module_name = "@ajf/calendars",
deps = [
"@npm//@angular/core",
],
)

filegroup(
name = "overviews",
srcs = ["//src/calendars/%s:overview" % name for name in CALENDARS_PACKAGES],
)

# Creates the @ajf/calendars package published to npm.
ng_package(
name = "npm_package",
srcs = ["package.json"],
entry_point = ":public-api.ts",
globals = ROLLUP_GLOBALS,
# TODO(devversion): Use the npm package for publishing. Right now this is disabled because
# we build using AOT for serving & testing, but the `ng_package` rule should not include factory
# files.
tags = ["manual"],
deps = CALENDARS_TARGETS,
)
33 changes: 33 additions & 0 deletions src/calendars/ethiopian/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])

load(
"//tools:defaults.bzl",
"markdown_to_html",
"ng_module",
"ng_test_library",
"ng_web_test_suite",
)

ng_module(
name = "ethiopian",
srcs = glob(
["**/*.ts"],
exclude = ["**/*.spec.ts"],
),
assets = [],
module_name = "@ajf/calendars/ethiopian",
deps = [
"//src/core/calendar",
"@npm//@angular/core",
],
)

markdown_to_html(
name = "overview",
srcs = ["ethiopian.md"],
)

filegroup(
name = "source-files",
srcs = glob(["**/*.ts"]),
)
33 changes: 33 additions & 0 deletions src/calendars/ethiopian/calendar-module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* @license
* Copyright (C) 2018 Gnucoop soc. coop.
*
* This file is part of the Advanced JSON forms (ajf).
*
* Advanced JSON forms (ajf) is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* Advanced JSON forms (ajf) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Advanced JSON forms (ajf).
* If not, see http://www.gnu.org/licenses/.
*
*/

import {AjfCalendarService} from '@ajf/core/calendar';
import {NgModule} from '@angular/core';

import {AjfEthiopianCalendarService} from './calendar-service';

@NgModule({
providers: [
{provide: AjfCalendarService, useClass: AjfEthiopianCalendarService},
],
})
export class AjfEthiopianCalendarModule { }
192 changes: 192 additions & 0 deletions src/calendars/ethiopian/calendar-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/**
* @license
* Copyright (C) 2018 Gnucoop soc. coop.
*
* This file is part of the Advanced JSON forms (ajf).
*
* Advanced JSON forms (ajf) is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* Advanced JSON forms (ajf) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Advanced JSON forms (ajf).
* If not, see http://www.gnu.org/licenses/.
*
*/

import {AjfCalendarEntry, AjfCalendarService, AjfCalendarParams,
AjfCalendarView, AjfCalendarViewMode} from '@ajf/core/calendar';
import {Injectable} from '@angular/core';
import {addDays, addYears, setISODay, startOfWeek} from 'date-fns';

import {EthiopianDate} from './ethiopian-date';

@Injectable()
export class AjfEthiopianCalendarService extends AjfCalendarService {
buildView(params: AjfCalendarParams): AjfCalendarView {
const {viewMode} = params;
const viewDate = EthiopianDate.gregorianToEthiopian(params.viewDate);
switch (viewMode) {
case 'decade':
let curYear: number = viewDate.getFullYear();
let firstYear = curYear - (curYear % 10) + 1;
let lastYear = firstYear + 11;
return {
header: `${firstYear} - ${lastYear}`,
headerRow: [],
rows: this._ecDecadeCalendarRows(params),
};
case 'year':
return {
header: `${viewDate.getFullYear()}`,
headerRow: [],
rows: this._ecYearCalendarRows(params),
};
case 'month':
const view = super.buildView(params);
return {
header: `${viewDate.getShortMonthName()} ${viewDate.getFullYear()}`,
headerRow: this._ecMonthHeaderRow(params),
rows: view.rows,
};
}
return super.buildView(params);
}

entryLabel(entry: AjfCalendarEntry): string {
const ecDate = EthiopianDate.gregorianToEthiopian(entry.date);
if (entry.type === 'day') {
return `${ecDate.getDate()}`;
}
if (entry.type === 'month') {
return `${ecDate.getMonthName()}`;
}
return `${ecDate.getFullYear()}`;
}

monthBounds(date: Date, isoMode: boolean): {start: Date, end: Date} {
if (!isoMode) {
const ecDate = EthiopianDate.gregorianToEthiopian(date);
const year = ecDate.getFullYear();
const month = ecDate.getMonth();
const start = new EthiopianDate(year, month, 1);
const endDay = month < 12 ? 30 : (year % 4 === 3 ? 6 : 5);
const end = new EthiopianDate(year, month, endDay);
return {
start: EthiopianDate.ethiopianToGregorian(start),
end: EthiopianDate.ethiopianToGregorian(end),
};
}
return super.monthBounds(date, isoMode);
}

nextView(viewDate: Date, viewMode: AjfCalendarViewMode): Date {
if (viewMode === 'month') {
const ecDate = EthiopianDate.gregorianToEthiopian(viewDate);
let year = ecDate.getFullYear();
let month = ecDate.getMonth();
if (month === 12) {
month = 0;
year += 1;
} else {
month += 1;
}
return EthiopianDate.ethiopianToGregorian(new EthiopianDate(year, month, 1));
}
return super.nextView(viewDate, viewMode);
}

previousView(viewDate: Date, viewMode: AjfCalendarViewMode): Date {
if (viewMode === 'month') {
const ecDate = EthiopianDate.gregorianToEthiopian(viewDate);
let year = ecDate.getFullYear();
let month = ecDate.getMonth();
if (month === 0) {
month = 12;
year -= 1;
} else {
month -= 1;
}
return EthiopianDate.ethiopianToGregorian(new EthiopianDate(year, month, 1));
}
return super.previousView(viewDate, viewMode);
}

private _ecMonthHeaderRow(params: AjfCalendarParams): string[] {
const {isoMode, viewDate} = params;
let curDate: Date;
if (isoMode) {
curDate = setISODay(startOfWeek(viewDate), 1);
} else {
curDate = startOfWeek(viewDate);
}
let weekDayNames: string[] = [];
for (let i = 0; i < 7; i++) {
const ecDate = EthiopianDate.gregorianToEthiopian(curDate);
weekDayNames.push(ecDate.getDayOfWeek());
curDate = addDays(curDate, 1);
}
return weekDayNames;
}

private _ecYearCalendarRows(params: AjfCalendarParams): AjfCalendarEntry[][] {
const {viewDate, selection} = params;
const year = EthiopianDate.gregorianToEthiopian(viewDate).getFullYear();
let curDate: EthiopianDate;

let rows: AjfCalendarEntry[][] = [];
for (let i = 0; i <= 4; i++) {
let row: AjfCalendarEntry[] = [];
for (let j = 0; j < 3; j++) {
const curMonth = i * 4 + j;
if (curMonth < 13) {
curDate = new EthiopianDate(year, curMonth, 1);
let date = EthiopianDate.ethiopianToGregorian(curDate);
let newEntry: AjfCalendarEntry = {
type: 'month',
date,
selected: 'none'
};
newEntry.selected = this.isEntrySelected(newEntry, selection);
row.push(newEntry);
}
}
rows.push(row);
}

return rows;
}

private _ecDecadeCalendarRows(params: AjfCalendarParams): AjfCalendarEntry[][] {
const {viewDate, selection} = params;
const ecDate = EthiopianDate.gregorianToEthiopian(viewDate);
let curYear: number = ecDate.getFullYear();
let firstYear = curYear - (curYear % 10) + 1;
let curDate: Date = EthiopianDate.ethiopianToGregorian(firstYear, 1, 1);

let rows: AjfCalendarEntry[][] = [];
for (let i = 0; i < 4; i++) {
let row: AjfCalendarEntry[] = [];
for (let j = 0; j < 3; j++) {
let date = new Date(curDate);
let newEntry: AjfCalendarEntry = {
type: 'year',
date: date,
selected: 'none'
};
newEntry.selected = this.isEntrySelected(newEntry, selection);
row.push(newEntry);
curDate = addYears(curDate, 1);
}
rows.push(row);
}

return rows;
}
}

0 comments on commit 55064f6

Please sign in to comment.