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:
+
+
+ + +
+ March 2017 +
+ + +
+ +
+ Mon TueWed Thu Fri Sat Sun +
+
+
`; 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