FEATURE: Bookmark reminder type changes and bugfixes (#9329)
New Reminder Types ------------------------------------- * Add a "later this week" reminder which is today + 2 days, will not show if we are on the days Thu-Sun * Add a "start of next business week" reminder which is 8am Monday Bugfixes and Tweaks -------------------------------------- * Move dates out of translation for reminder types and yield HTML for tap-tile for more customizable content and styling * Make sure double clicking the bookmark icon in quick access takes users to the new bookmarks-with-reminders page * Sane default to 8am (start of day) for custom reminder with no time
This commit is contained in:
parent
393215266f
commit
d261a809e2
|
@ -3,7 +3,6 @@ import { Promise } from "rsvp";
|
|||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
|
||||
const START_OF_DAY_HOUR = 8;
|
||||
|
@ -17,7 +16,9 @@ const REMINDER_TYPES = {
|
|||
NEXT_MONTH: "next_month",
|
||||
CUSTOM: "custom",
|
||||
LAST_CUSTOM: "last_custom",
|
||||
NONE: "none"
|
||||
NONE: "none",
|
||||
START_OF_NEXT_BUSINESS_WEEK: "start_of_next_business_week",
|
||||
LATER_THIS_WEEK: "later_this_week"
|
||||
};
|
||||
|
||||
export default Controller.extend(ModalFunctionality, {
|
||||
|
@ -115,60 +116,48 @@ export default Controller.extend(ModalFunctionality, {
|
|||
);
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
showLaterThisWeek() {
|
||||
return this.now().day() < 4; // 4 is Thursday
|
||||
},
|
||||
|
||||
@discourseComputed("parsedLastCustomReminderDatetime")
|
||||
lastCustomFormatted(parsedLastCustomReminderDatetime) {
|
||||
return htmlSafe(
|
||||
I18n.t("bookmarks.reminders.last_custom", {
|
||||
date: parsedLastCustomReminderDatetime.format(
|
||||
I18n.t("dates.long_no_year")
|
||||
)
|
||||
})
|
||||
return parsedLastCustomReminderDatetime.format(
|
||||
I18n.t("dates.long_no_year")
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
startNextBusinessWeekFormatted() {
|
||||
return this.nextWeek()
|
||||
.day("Monday")
|
||||
.format(I18n.t("dates.long_no_year"));
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
laterTodayFormatted() {
|
||||
return htmlSafe(
|
||||
I18n.t("bookmarks.reminders.later_today", {
|
||||
date: this.laterToday().format(I18n.t("dates.time"))
|
||||
})
|
||||
);
|
||||
return this.laterToday().format(I18n.t("dates.time"));
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
tomorrowFormatted() {
|
||||
return htmlSafe(
|
||||
I18n.t("bookmarks.reminders.tomorrow", {
|
||||
date: this.tomorrow().format(I18n.t("dates.time_short_day"))
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
nextBusinessDayFormatted() {
|
||||
return htmlSafe(
|
||||
I18n.t("bookmarks.reminders.next_business_day", {
|
||||
date: this.nextBusinessDay().format(I18n.t("dates.time_short_day"))
|
||||
})
|
||||
);
|
||||
return this.tomorrow().format(I18n.t("dates.time_short_day"));
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
nextWeekFormatted() {
|
||||
return htmlSafe(
|
||||
I18n.t("bookmarks.reminders.next_week", {
|
||||
date: this.nextWeek().format(I18n.t("dates.long_no_year"))
|
||||
})
|
||||
);
|
||||
return this.nextWeek().format(I18n.t("dates.long_no_year"));
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
laterThisWeekFormatted() {
|
||||
return this.laterThisWeek().format(I18n.t("dates.time_short_day"));
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
nextMonthFormatted() {
|
||||
return htmlSafe(
|
||||
I18n.t("bookmarks.reminders.next_month", {
|
||||
date: this.nextMonth().format(I18n.t("dates.long_no_year"))
|
||||
})
|
||||
);
|
||||
return this.nextMonth().format(I18n.t("dates.long_no_year"));
|
||||
},
|
||||
|
||||
@discourseComputed()
|
||||
|
@ -237,9 +226,17 @@ export default Controller.extend(ModalFunctionality, {
|
|||
return this.tomorrow();
|
||||
case REMINDER_TYPES.NEXT_WEEK:
|
||||
return this.nextWeek();
|
||||
case REMINDER_TYPES.START_OF_NEXT_BUSINESS_WEEK:
|
||||
return this.nextWeek().day("Monday");
|
||||
case REMINDER_TYPES.LATER_THIS_WEEK:
|
||||
return this.laterThisWeek();
|
||||
case REMINDER_TYPES.NEXT_MONTH:
|
||||
return this.nextMonth();
|
||||
case REMINDER_TYPES.CUSTOM:
|
||||
this.set(
|
||||
"customReminderTime",
|
||||
this.customReminderTime || `0${START_OF_DAY_HOUR}:00`
|
||||
);
|
||||
const customDateTime = this.parseCustomDateTime(
|
||||
this.customReminderDate,
|
||||
this.customReminderTime
|
||||
|
@ -265,23 +262,6 @@ export default Controller.extend(ModalFunctionality, {
|
|||
return this.startOfDay(this.now().add(1, "month"));
|
||||
},
|
||||
|
||||
nextBusinessDay() {
|
||||
const currentDay = this.now().isoWeekday(); // 1=Mon, 7=Sun
|
||||
let next = null;
|
||||
|
||||
// friday
|
||||
if (currentDay === 5) {
|
||||
next = this.now().add(3, "days");
|
||||
// saturday
|
||||
} else if (currentDay === 6) {
|
||||
next = this.now().add(2, "days");
|
||||
} else {
|
||||
next = this.now().add(1, "day");
|
||||
}
|
||||
|
||||
return this.startOfDay(next);
|
||||
},
|
||||
|
||||
tomorrow() {
|
||||
return this.startOfDay(this.now().add(1, "day"));
|
||||
},
|
||||
|
@ -301,6 +281,13 @@ export default Controller.extend(ModalFunctionality, {
|
|||
: later.add(30, "minutes").startOf("hour");
|
||||
},
|
||||
|
||||
laterThisWeek() {
|
||||
if (!this.showLaterThisWeek) {
|
||||
return;
|
||||
}
|
||||
return this.startOfDay(this.now().add(2, "days"));
|
||||
},
|
||||
|
||||
handleSaveError(e) {
|
||||
this.isSavingBookmarkManually = false;
|
||||
if (typeof e === "string") {
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
{{d-icon icon}}
|
||||
{{text}}
|
||||
{{ yield }}
|
||||
|
|
|
@ -21,21 +21,51 @@
|
|||
{{#if userHasTimezoneSet}}
|
||||
{{#tap-tile-grid activeTile=selectedReminderType as |grid|}}
|
||||
{{#if showAtDesktop}}
|
||||
{{tap-tile icon="desktop" text=(i18n "bookmarks.reminders.at_desktop") tileId=reminderTypes.AT_DESKTOP activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{#tap-tile icon="desktop" tileId=reminderTypes.AT_DESKTOP activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.at_desktop"}}
|
||||
{{/tap-tile}}
|
||||
{{/if}}
|
||||
|
||||
{{#if showLaterToday}}
|
||||
{{tap-tile icon="far-moon" text=laterTodayFormatted tileId=reminderTypes.LATER_TODAY activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{#tap-tile icon="far-moon" tileId=reminderTypes.LATER_TODAY activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.later_today"}}<br>
|
||||
{{laterTodayFormatted}}
|
||||
{{/tap-tile}}
|
||||
{{/if}}
|
||||
{{tap-tile icon="briefcase" text=nextBusinessDayFormatted tileId=reminderTypes.NEXT_BUSINESS_DAY activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-sun" text=tomorrowFormatted tileId=reminderTypes.TOMORROW activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-clock" text=nextWeekFormatted tileId=reminderTypes.NEXT_WEEK activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{tap-tile icon="far-calendar-plus" text=nextMonthFormatted tileId=reminderTypes.NEXT_MONTH activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{tap-tile icon="calendar-alt" text=(I18n "bookmarks.reminders.custom") tileId=reminderTypes.CUSTOM activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{#tap-tile icon="far-sun" tileId=reminderTypes.TOMORROW activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.tomorrow"}}<br>
|
||||
{{tomorrowFormatted}}
|
||||
{{/tap-tile}}
|
||||
{{#if showLaterThisWeek}}
|
||||
{{#tap-tile icon="angle-double-right" tileId=reminderTypes.LATER_THIS_WEEK activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.later_this_week"}}<br>
|
||||
{{laterThisWeekFormatted}}
|
||||
{{/tap-tile}}
|
||||
{{/if}}
|
||||
{{#tap-tile icon="briefcase" tileId=reminderTypes.START_OF_NEXT_BUSINESS_WEEK activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.start_of_next_business_week"}}<br>
|
||||
{{startNextBusinessWeekFormatted}}
|
||||
{{/tap-tile}}
|
||||
{{#tap-tile icon="far-clock" tileId=reminderTypes.NEXT_WEEK activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.next_week"}}<br>
|
||||
{{nextWeekFormatted}}
|
||||
{{/tap-tile}}
|
||||
{{#tap-tile icon="far-calendar-plus" tileId=reminderTypes.NEXT_MONTH activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.next_month"}}<br>
|
||||
{{nextMonthFormatted}}
|
||||
{{/tap-tile}}
|
||||
{{#tap-tile icon="calendar-alt" tileId=reminderTypes.CUSTOM activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.custom"}}
|
||||
{{/tap-tile}}
|
||||
{{#if showLastCustom}}
|
||||
{{tap-tile icon="undo" text=lastCustomFormatted tileId=reminderTypes.LAST_CUSTOM activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{#tap-tile icon="undo" tileId=reminderTypes.LAST_CUSTOM activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.last_custom"}}<br>
|
||||
{{lastCustomFormatted}}
|
||||
{{/tap-tile}}
|
||||
{{/if}}
|
||||
{{tap-tile icon="ban" text=(I18n "bookmarks.reminders.none") tileId=reminderTypes.NONE activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{#tap-tile icon="ban" tileId=reminderTypes.NONE activeTile=grid.activeTile onChange=(action "selectReminderType")}}
|
||||
{{i18n "bookmarks.reminders.none"}}
|
||||
{{/tap-tile}}
|
||||
{{/tap-tile-grid}}
|
||||
{{#if customDateTimeSelected}}
|
||||
<div class="control-group custom-date-time-wrap">
|
||||
|
|
|
@ -56,13 +56,16 @@ createWidget("user-menu-links", {
|
|||
},
|
||||
|
||||
bookmarksGlyph() {
|
||||
let path = this.siteSettings.enable_bookmarks_with_reminders
|
||||
? "bookmarks-with-reminders"
|
||||
: "bookmarks";
|
||||
return {
|
||||
action: UserMenuAction.QUICK_ACCESS,
|
||||
actionParam: QuickAccess.BOOKMARKS,
|
||||
label: "user.bookmarks",
|
||||
className: "user-bookmarks-link",
|
||||
icon: "bookmark",
|
||||
href: `${this.attrs.path}/activity/bookmarks`
|
||||
href: `${this.attrs.path}/activity/${path}`
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -67,7 +67,9 @@ class Bookmark < ActiveRecord::Base
|
|||
tomorrow: 3,
|
||||
next_week: 4,
|
||||
next_month: 5,
|
||||
custom: 6
|
||||
custom: 6,
|
||||
start_of_next_business_week: 7,
|
||||
later_this_week: 8
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -316,13 +316,15 @@ en:
|
|||
list_permission_denied: "You do not have permission to view this user's bookmarks."
|
||||
reminders:
|
||||
at_desktop: "Next time I'm at my desktop"
|
||||
later_today: "Later today <br/>{{date}}"
|
||||
next_business_day: "Next business day <br/>{{date}}"
|
||||
tomorrow: "Tomorrow <br/>{{date}}"
|
||||
next_week: "Next week <br/>{{date}}"
|
||||
next_month: "Next month <br/>{{date}}"
|
||||
later_today: "Later today"
|
||||
next_business_day: "Next business day"
|
||||
tomorrow: "Tomorrow"
|
||||
next_week: "Next week"
|
||||
later_this_week: "Later this week"
|
||||
start_of_next_business_week: "Next Monday"
|
||||
next_month: "Next month"
|
||||
custom: "Custom date and time"
|
||||
last_custom: "Last <br/>{{date}}"
|
||||
last_custom: "Last"
|
||||
none: "No reminder needed"
|
||||
|
||||
drafts:
|
||||
|
|
|
@ -6,6 +6,7 @@ moduleFor("controller:bookmark", {
|
|||
beforeEach() {
|
||||
logIn();
|
||||
BookmarkController = this.subject({ currentUser: User.current() });
|
||||
BookmarkController.onShow();
|
||||
},
|
||||
|
||||
afterEach() {
|
||||
|
@ -58,54 +59,34 @@ QUnit.test("nextMonth gets next month correctly", function(assert) {
|
|||
);
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"nextBusinessDay gets next business day of monday correctly if today is friday",
|
||||
function(assert) {
|
||||
mockMomentTz("2019-12-13T08:00:00");
|
||||
QUnit.test("laterThisWeek gets 2 days from now", function(assert) {
|
||||
mockMomentTz("2019-12-10T08:00:00");
|
||||
|
||||
assert.equal(
|
||||
BookmarkController.nextBusinessDay().format("YYYY-MM-DD"),
|
||||
"2019-12-16"
|
||||
);
|
||||
}
|
||||
);
|
||||
assert.equal(
|
||||
BookmarkController.laterThisWeek().format("YYYY-MM-DD"),
|
||||
"2019-12-12"
|
||||
);
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"nextBusinessDay gets next business day of monday correctly if today is saturday",
|
||||
function(assert) {
|
||||
mockMomentTz("2019-12-14T08:00:00");
|
||||
QUnit.test("laterThisWeek returns null if we are at Thursday already", function(
|
||||
assert
|
||||
) {
|
||||
mockMomentTz("2019-12-12T08:00:00");
|
||||
|
||||
assert.equal(
|
||||
BookmarkController.nextBusinessDay().format("YYYY-MM-DD"),
|
||||
"2019-12-16"
|
||||
);
|
||||
}
|
||||
);
|
||||
assert.equal(BookmarkController.laterThisWeek(), null);
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"nextBusinessDay gets next business day of monday correctly if today is sunday",
|
||||
function(assert) {
|
||||
mockMomentTz("2019-12-15T08:00:00");
|
||||
QUnit.test("showLaterThisWeek returns true if < Thursday", function(assert) {
|
||||
mockMomentTz("2019-12-10T08:00:00");
|
||||
|
||||
assert.equal(
|
||||
BookmarkController.nextBusinessDay().format("YYYY-MM-DD"),
|
||||
"2019-12-16"
|
||||
);
|
||||
}
|
||||
);
|
||||
assert.equal(BookmarkController.showLaterThisWeek, true);
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
"nextBusinessDay gets next business day of thursday correctly if today is wednesday",
|
||||
function(assert) {
|
||||
mockMomentTz("2019-12-11T08:00:00");
|
||||
|
||||
assert.equal(
|
||||
BookmarkController.nextBusinessDay().format("YYYY-MM-DD"),
|
||||
"2019-12-12"
|
||||
);
|
||||
}
|
||||
);
|
||||
QUnit.test("showLaterThisWeek returns false if > Thursday", function(assert) {
|
||||
mockMomentTz("2019-12-12T08:00:00");
|
||||
|
||||
assert.equal(BookmarkController.showLaterThisWeek, false);
|
||||
});
|
||||
QUnit.test("tomorrow gets tomorrow correctly", function(assert) {
|
||||
mockMomentTz("2019-12-11T08:00:00");
|
||||
|
||||
|
@ -154,6 +135,27 @@ QUnit.test(
|
|||
}
|
||||
);
|
||||
|
||||
QUnit.test(
|
||||
"reminderAt - custom - defaults to 8:00am if the time is not selected",
|
||||
function(assert) {
|
||||
BookmarkController.customReminderDate = "2028-12-12";
|
||||
BookmarkController.selectedReminderType =
|
||||
BookmarkController.reminderTypes.CUSTOM;
|
||||
const reminderAt = BookmarkController.reminderAt();
|
||||
assert.equal(BookmarkController.customReminderTime, "08:00");
|
||||
assert.equal(
|
||||
reminderAt.toString(),
|
||||
moment
|
||||
.tz(
|
||||
"2028-12-12 08:00",
|
||||
BookmarkController.currentUser.resolvedTimezone()
|
||||
)
|
||||
.toString(),
|
||||
"the custom date and time are parsed correctly with default time"
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
QUnit.test(
|
||||
"loadLastUsedCustomReminderDatetime fills the custom reminder date + time if present in localStorage",
|
||||
function(assert) {
|
||||
|
|
Loading…
Reference in New Issue