diff --git a/src/public/javascripts/services/library_loader.js b/src/public/javascripts/services/library_loader.js
index 4aba9765b..5d0b81aef 100644
--- a/src/public/javascripts/services/library_loader.js
+++ b/src/public/javascripts/services/library_loader.js
@@ -51,6 +51,8 @@ const SORTABLE = {js: ["libraries/sortable.min.js"]};
const KNOCKOUT = {js: ["libraries/knockout.min.js"]};
+const CALENDAR_WIDGET = {css: ["stylesheets/calendar.css"]};
+
async function requireLibrary(library) {
if (library.css) {
library.css.map(cssUrl => cssLoader.requireCss(cssUrl));
@@ -88,5 +90,6 @@ export default {
LINK_MAP,
PRINT_THIS,
SORTABLE,
- KNOCKOUT
+ KNOCKOUT,
+ CALENDAR_WIDGET
}
\ No newline at end of file
diff --git a/src/public/javascripts/services/sidebar.js b/src/public/javascripts/services/sidebar.js
index 85be94fe7..faa800b1c 100644
--- a/src/public/javascripts/services/sidebar.js
+++ b/src/public/javascripts/services/sidebar.js
@@ -60,6 +60,7 @@ class Sidebar {
import("../widgets/what_links_here.js"),
import("../widgets/similar_notes.js"),
import("../widgets/edited_notes.js"),
+ import("../widgets/calendar.js")
])).map(m => m.default);
const options = await optionsService.waitForOptions();
diff --git a/src/public/javascripts/widgets/calendar.js b/src/public/javascripts/widgets/calendar.js
index 8438a8817..f455b1d81 100644
--- a/src/public/javascripts/widgets/calendar.js
+++ b/src/public/javascripts/widgets/calendar.js
@@ -1,27 +1,34 @@
import StandardWidget from "./standard_widget.js";
+import libraryLoader from "../services/library_loader.js";
+import utils from "../services/utils.js";
+import dateNoteService from "../services/date_notes.js";
+import treeService from "../services/tree.js";
const TPL = `
-
-
- Note ID: |
- |
-
-
- Created: |
- |
-
-
- Modified: |
- |
-
-
- Type: |
- |
-
- MIME: |
- |
-
-
+
`;
class CalendarWidget extends StandardWidget {
@@ -33,21 +40,122 @@ class CalendarWidget extends StandardWidget {
}
async doRenderBody() {
+ await libraryLoader.requireLibrary(libraryLoader.CALENDAR_WIDGET);
+
this.$body.html(TPL);
- const $noteId = this.$body.find(".note-info-note-id");
- const $dateCreated = this.$body.find(".note-info-date-created");
- const $dateModified = this.$body.find(".note-info-date-modified");
- const $type = this.$body.find(".note-info-type");
- const $mime = this.$body.find(".note-info-mime");
+ this.init(this.$body, await this.ctx.note.getLabelValue("dateNote"));
+ }
- const note = this.ctx.note;
+ init($el, activeDate) {
+ this.date = new Date();
+ this.todaysDate = new Date();
+ this.activeDate = new Date(Date.parse(activeDate));
- $noteId.text(note.noteId);
- $dateCreated.text(note.dateCreated);
- $dateModified.text(note.dateModified);
- $type.text(note.type);
- $mime.text(note.mime).attr("title", note.mime);
+ this.$month = $el.find('[data-calendar-area="month"]');
+ this.$next = $el.find('[data-calendar-toggle="next"]');
+ this.$previous = $el.find('[data-calendar-toggle="previous"]');
+
+ this.$next.click(() => {
+ this.clearCalendar();
+ this.date.setMonth(this.date.getMonth() + 1);
+ this.createMonth();
+ });
+
+ this.$previous.click(() => {
+ this.clearCalendar();
+ this.date.setMonth(this.date.getMonth() - 1);
+ this.createMonth();
+ });
+
+ this.$label = $el.find('[data-calendar-label="month"]');
+
+ this.date.setDate(1);
+ this.createMonth();
+
+ this.$body.on('click', '.calendar-date', async ev => {
+ const date = $(ev.target).closest('.calendar-date').attr('data-calendar-date');
+
+ const note = await dateNoteService.getDateNote(date);
+
+ if (note) {
+ treeService.activateNote(note.noteId);
+ }
+ else {
+ alert("Cannot find day note");
+ }
+ });
+ }
+
+ createDay(num, day) {
+ const $newDay = $('')
+ .addClass("calendar-date")
+ .attr('data-calendar-date', utils.formatDateISO(this.date));
+ const $date = $('').html(num);
+
+ // if it's the first day of the month
+ if (num === 1) {
+ if (day === 0) {
+ $newDay.css("marginLeft", (6 * 14.28) + '%');
+ } else {
+ $newDay.css("marginLeft", ((day - 1) * 14.28) + '%');
+ }
+ }
+
+ if (this.isEqual(this.date, this.activeDate)) {
+ $newDay.addClass('calendar-date-active');
+ }
+
+ if (this.isEqual(this.date, this.todaysDate)) {
+ $newDay.addClass('calendar-date-today');
+ }
+
+ $newDay.append($date);
+ this.$month.append($newDay);
+ }
+
+ isEqual(a, b) {
+ return a.getFullYear() === b.getFullYear()
+ && a.getMonth() === b.getMonth()
+ && a.getDate() === b.getDate();
+ }
+
+ createMonth() {
+ const currentMonth = this.date.getMonth();
+ while (this.date.getMonth() === currentMonth) {
+ this.createDay(
+ this.date.getDate(),
+ this.date.getDay(),
+ this.date.getFullYear()
+ );
+ this.date.setDate(this.date.getDate() + 1);
+ }
+ // while loop trips over and day is at 30/31, bring it back
+ this.date.setDate(1);
+ this.date.setMonth(this.date.getMonth() - 1);
+
+ this.$label.html(this.monthsAsString(this.date.getMonth()) + ' ' + this.date.getFullYear());
+ }
+
+ monthsAsString(monthIndex) {
+ return [
+ 'January',
+ 'Febuary',
+ 'March',
+ 'April',
+ 'May',
+ 'June',
+ 'July',
+ 'August',
+ 'September',
+ 'October',
+ 'November',
+ 'December'
+ ][monthIndex];
+ }
+
+ clearCalendar() {
+ this.$month.html('');
}
}
diff --git a/src/public/stylesheets/calendar.css b/src/public/stylesheets/calendar.css
new file mode 100755
index 000000000..286fc5ce5
--- /dev/null
+++ b/src/public/stylesheets/calendar.css
@@ -0,0 +1,88 @@
+.calendar-widget *, .calendar-widget *:before, .calendar-widget *:after {
+ box-sizing: border-box;
+}
+
+.calendar-widget {
+ margin: 0 auto;
+ overflow: hidden;
+ width: 100%;
+}
+
+.calendar-widget .calendar-btn {
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -webkit-appearance: button;
+ background: none;
+ border: 0;
+ color: inherit;
+ cursor: pointer;
+ font: inherit;
+ line-height: normal;
+ min-width: 27px;
+ outline: none;
+ overflow: visible;
+ padding: 0;
+ text-align: center;
+}
+
+.calendar-widget .calendar-header {
+ align-items: center;
+ display: flex;
+ padding: 0 0.5rem 0.5rem 0.5rem;
+}
+
+.calendar-widget .calendar-header__label {
+ font-weight: bold;
+ text-align: center;
+ width: 100%;
+}
+
+.calendar-widget .calendar-week {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.calendar-widget .calendar-week span {
+ flex-direction: column;
+ flex: 0 0 14.28%;
+ font-size: 1rem;
+ font-weight: bold;
+ max-width: 14.28%;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ text-align: center;
+ text-transform: uppercase;
+}
+
+.calendar-widget .calendar-body {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.calendar-widget .calendar-date {
+ align-items: center;
+ background-color: #fff;
+ display: flex;
+ flex-direction: column;
+ flex: 0 0 14.28%;
+ max-width: 14.28%;
+ padding: 0.6rem 0;
+}
+
+.calendar-widget .calendar-date:hover {
+ color: var(--hover-item-text-color);
+ background-color: var(--hover-item-background-color);
+}
+
+.calendar-widget .calendar-date-active {
+ background-color: var(--active-item-background-color);
+ color: var(--active-item-text-color);
+}
+
+.calendar-widget .calendar-date-today {
+ font-weight: bold;
+}
+
+.calendar-widget .calendar-date:not(.calendar-date-active) {
+ cursor: pointer;
+}
\ No newline at end of file