Added option for grouping by year (for handling events that span multiple years)
This commit is contained in:
parent
1d848131a3
commit
a936de4285
@ -4,7 +4,7 @@ This is a plugin for the [Joplin](https://joplinapp.org/) note-taking app.
|
|||||||
|
|
||||||
It creates a calendar view of events that have been specified using the [YAML](https://yaml.org/) syntax within a fenced block.
|
It creates a calendar view of events that have been specified using the [YAML](https://yaml.org/) syntax within a fenced block.
|
||||||
|
|
||||||
- Organises events into "groupings"; you can group events by **day**, **week** or by **month**
|
- Organises events into "groupings"; you can group events by **day**, **week**, **month** or **year**
|
||||||
- Focus is on readability and simplicity of content, which is why the **YAML** is simple in structure
|
- Focus is on readability and simplicity of content, which is why the **YAML** is simple in structure
|
||||||
|
|
||||||
###### Example Day view
|
###### Example Day view
|
||||||
@ -13,10 +13,11 @@ It creates a calendar view of events that have been specified using the [YAML](h
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- A grouping that contains no events will show the **date** (day grouping), **week number** (week grouping), or **month** (month grouping)
|
- A grouping that contains no events will show the **date** (day grouping), **week number** (week grouping), **month** (month grouping), or **year** (year grouping)
|
||||||
- If a grouping falls under the **current date**, it is highlighted in yellow
|
- If a grouping falls under the **current date**, it is highlighted in yellow
|
||||||
- Events can be specified in **any order**
|
- Events can be specified in **any order**
|
||||||
- Events can be assigned an **icon** 🎁 such as an emoji
|
- Events can be assigned an **icon** 🎁 such as an emoji
|
||||||
|
- Events without an icon will use the first 2 characters from the title
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ Events are specified using the YAML syntax, with the following keys:
|
|||||||
> Sets the grouping for the view
|
> Sets the grouping for the view
|
||||||
> - _**optional**_
|
> - _**optional**_
|
||||||
> - **default** `day`
|
> - **default** `day`
|
||||||
> - **accepts** : `day`, `week`, `month`, `d`, `w`, `m`
|
> - **accepts** : `day`, `week`, `month`, `year`, `d`, `w`, `m`, `y`
|
||||||
|
|
||||||
### events:
|
### events:
|
||||||
> Each individual event is a list with its own properties
|
> Each individual event is a list with its own properties
|
||||||
|
|||||||
@ -1,7 +1,17 @@
|
|||||||
import { GroupTypes } from "../types";
|
import { GroupTypes } from "../types";
|
||||||
import Events from "../Events/";
|
import Events from "../Events/";
|
||||||
import { DayGrouping, WeekGrouping, MonthGrouping } from "../EventGrouping";
|
import {
|
||||||
import { DayRenderer, WeekRenderer, MonthRenderer } from "../HtmlRenderer";
|
DayGrouping,
|
||||||
|
MonthGrouping,
|
||||||
|
WeekGrouping,
|
||||||
|
YearGrouping,
|
||||||
|
} from "../EventGrouping";
|
||||||
|
import {
|
||||||
|
DayRenderer,
|
||||||
|
MonthRenderer,
|
||||||
|
WeekRenderer,
|
||||||
|
YearRenderer,
|
||||||
|
} from "../HtmlRenderer";
|
||||||
|
|
||||||
export default class Calendar {
|
export default class Calendar {
|
||||||
public readonly jsonContent: object;
|
public readonly jsonContent: object;
|
||||||
@ -30,6 +40,10 @@ export default class Calendar {
|
|||||||
return new MonthRenderer(
|
return new MonthRenderer(
|
||||||
new MonthGrouping(this.events.sortedEvents)
|
new MonthGrouping(this.events.sortedEvents)
|
||||||
).render();
|
).render();
|
||||||
|
case GroupTypes.Year:
|
||||||
|
return new YearRenderer(
|
||||||
|
new YearGrouping(this.events.sortedEvents)
|
||||||
|
).render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
42
src/EventGrouping/YearGrouping.ts
Normal file
42
src/EventGrouping/YearGrouping.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import EventGrouping from "./EventGrouping";
|
||||||
|
import { Event, Groups } from "../types";
|
||||||
|
import {
|
||||||
|
add,
|
||||||
|
differenceInCalendarYears,
|
||||||
|
isThisYear as dateFnsIsThisYear,
|
||||||
|
} from "date-fns";
|
||||||
|
|
||||||
|
export default class YearGrouping extends EventGrouping {
|
||||||
|
static isThisYear(date: Date): boolean {
|
||||||
|
return dateFnsIsThisYear(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(sortedEvents: Event[]) {
|
||||||
|
super(sortedEvents);
|
||||||
|
this.groups = this.group();
|
||||||
|
}
|
||||||
|
|
||||||
|
group(): Groups {
|
||||||
|
const numberOfGroups = differenceInCalendarYears(
|
||||||
|
this.lastEvent.date,
|
||||||
|
this.firstEvent.date
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.sortedEvents.reduce((prev, event) => {
|
||||||
|
const groupNumber = differenceInCalendarYears(
|
||||||
|
event.date,
|
||||||
|
this.firstEvent.date
|
||||||
|
);
|
||||||
|
|
||||||
|
prev[groupNumber].push(event);
|
||||||
|
|
||||||
|
return prev;
|
||||||
|
}, this.generateEmptyGroups(numberOfGroups));
|
||||||
|
}
|
||||||
|
|
||||||
|
public getDateFromGroupIndex(index: number): Date {
|
||||||
|
const startDate = this.firstEvent.date;
|
||||||
|
|
||||||
|
return add(startDate, { years: index });
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import DayGrouping from "./DayGrouping";
|
import DayGrouping from "./DayGrouping";
|
||||||
import WeekGrouping from "./WeekGrouping";
|
import WeekGrouping from "./WeekGrouping";
|
||||||
import MonthGrouping from "./MonthGrouping";
|
import MonthGrouping from "./MonthGrouping";
|
||||||
|
import YearGrouping from "./YearGrouping";
|
||||||
|
|
||||||
export { DayGrouping, WeekGrouping, MonthGrouping };
|
export { DayGrouping, WeekGrouping, MonthGrouping, YearGrouping };
|
||||||
|
|||||||
30
src/HtmlRenderer/Year/GroupYearRenderer.ts
Normal file
30
src/HtmlRenderer/Year/GroupYearRenderer.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Event } from "../../types";
|
||||||
|
import { YearGrouping } from "../../EventGrouping";
|
||||||
|
|
||||||
|
import GroupRenderer from "../Abstract/GroupRenderer";
|
||||||
|
|
||||||
|
export default class GroupYearRenderer extends GroupRenderer {
|
||||||
|
constructor(group: Event[], groupDate: Date, groupIndex: number) {
|
||||||
|
super(group, groupDate, groupIndex);
|
||||||
|
|
||||||
|
if (YearGrouping.isThisYear(groupDate)) {
|
||||||
|
this.highlightGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected renderDateAsIcon(eventDate, groupIndex): HTMLSpanElement {
|
||||||
|
const html = document.createElement("span");
|
||||||
|
html.className = "icon";
|
||||||
|
|
||||||
|
html.textContent = eventDate.toLocaleDateString(undefined, {
|
||||||
|
year: "numeric",
|
||||||
|
});
|
||||||
|
html.className += " primary";
|
||||||
|
|
||||||
|
if (YearGrouping.isThisYear(eventDate)) {
|
||||||
|
html.className += " highlighted";
|
||||||
|
}
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/HtmlRenderer/Year/index.ts
Normal file
19
src/HtmlRenderer/Year/index.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Event } from "../../types";
|
||||||
|
import { YearGrouping } from "../../EventGrouping";
|
||||||
|
import Renderer from "../Abstract/Renderer";
|
||||||
|
import GroupYearRenderer from "./GroupYearRenderer";
|
||||||
|
|
||||||
|
export default class YearRenderer extends Renderer {
|
||||||
|
constructor(eventGrouping: YearGrouping) {
|
||||||
|
super(eventGrouping);
|
||||||
|
this.container.className += " scale-year";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected renderGroups(
|
||||||
|
group: Event[],
|
||||||
|
groupDate: Date,
|
||||||
|
groupIndex: number
|
||||||
|
): HTMLDivElement {
|
||||||
|
return new GroupYearRenderer(group, groupDate, groupIndex).render();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
import DayRenderer from "./Day/";
|
import DayRenderer from "./Day";
|
||||||
import WeekRenderer from "./Week/";
|
import WeekRenderer from "./Week";
|
||||||
import MonthRenderer from "./Month/";
|
import MonthRenderer from "./Month";
|
||||||
|
import YearRenderer from "./Year";
|
||||||
|
|
||||||
export { DayRenderer, WeekRenderer, MonthRenderer };
|
export { DayRenderer, WeekRenderer, MonthRenderer, YearRenderer };
|
||||||
|
|||||||
@ -2,6 +2,7 @@ export enum GroupTypes {
|
|||||||
Day = "D",
|
Day = "D",
|
||||||
Week = "W",
|
Week = "W",
|
||||||
Month = "M",
|
Month = "M",
|
||||||
|
Year = "Y",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Event {
|
export interface Event {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user