From 764cf7e3a58d06396bef5712508179391e881391 Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Thu, 26 Oct 2017 13:50:31 -0400 Subject: [PATCH] FEATURE: Add longer suspension defaults Also refactors and DRYs up the future input date data a lot --- .../templates/modal/admin-suspend-user.hbs | 2 +- .../components/future-date-input.js.es6 | 10 +- .../components/future-date-input.hbs | 2 +- .../future-date-input-selector.js.es6 | 198 +++++++++++------- .../future-date-input-selector/mixin.js.es6 | 87 ++------ config/locales/client.en.yml | 3 + 6 files changed, 144 insertions(+), 158 deletions(-) diff --git a/app/assets/javascripts/admin/templates/modal/admin-suspend-user.hbs b/app/assets/javascripts/admin/templates/modal/admin-suspend-user.hbs index cfbd21d4b9b..a701cf50458 100644 --- a/app/assets/javascripts/admin/templates/modal/admin-suspend-user.hbs +++ b/app/assets/javascripts/admin/templates/modal/admin-suspend-user.hbs @@ -7,7 +7,7 @@ {{future-date-input class="suspend-until" label="admin.user.suspend_duration" - includeForever=true + includeFarFuture=true input=suspendUntil}} diff --git a/app/assets/javascripts/discourse/components/future-date-input.js.es6 b/app/assets/javascripts/discourse/components/future-date-input.js.es6 index ae0a14cfb0a..97b87387872 100644 --- a/app/assets/javascripts/discourse/components/future-date-input.js.es6 +++ b/app/assets/javascripts/discourse/components/future-date-input.js.es6 @@ -1,8 +1,6 @@ import { default as computed, observes } from "ember-addons/ember-computed-decorators"; import { FORMAT, - PICK_DATE_AND_TIME, - SET_BASED_ON_LAST_POST } from "select-box-kit/components/future-date-input-selector"; import { PUBLISH_TO_CATEGORY_STATUS_TYPE } from 'discourse/controllers/edit-topic-timer'; @@ -11,8 +9,8 @@ export default Ember.Component.extend({ selection: null, date: null, time: null, - isCustom: Ember.computed.equal('selection', PICK_DATE_AND_TIME), - isBasedOnLastPost: Ember.computed.equal('selection', SET_BASED_ON_LAST_POST), + isCustom: Ember.computed.equal('selection', 'pick_date_and_time'), + isBasedOnLastPost: Ember.computed.equal('selection', 'set_based_on_last_post'), displayLabel: null, init() { @@ -22,9 +20,9 @@ export default Ember.Component.extend({ if (input) { if (this.get('basedOnLastPost')) { - this.set('selection', SET_BASED_ON_LAST_POST); + this.set('selection', 'set_based_on_last_post'); } else { - this.set('selection', PICK_DATE_AND_TIME); + this.set('selection', 'pick_date_and_time'); const datetime = moment(input); this.set('date', datetime.toDate()); this.set('time', datetime.format("HH:mm")); diff --git a/app/assets/javascripts/discourse/templates/components/future-date-input.hbs b/app/assets/javascripts/discourse/templates/components/future-date-input.hbs index 2bf53bee820..b509f19d76a 100644 --- a/app/assets/javascripts/discourse/templates/components/future-date-input.hbs +++ b/app/assets/javascripts/discourse/templates/components/future-date-input.hbs @@ -7,7 +7,7 @@ value=selection input=input includeWeekend=includeWeekend - includeForever=includeForever + includeFarFuture=includeFarFuture none="topic.auto_update_input.none"}} diff --git a/app/assets/javascripts/select-box-kit/components/future-date-input-selector.js.es6 b/app/assets/javascripts/select-box-kit/components/future-date-input-selector.js.es6 index 8c291abc099..b344f2080e6 100644 --- a/app/assets/javascripts/select-box-kit/components/future-date-input-selector.js.es6 +++ b/app/assets/javascripts/select-box-kit/components/future-date-input-selector.js.es6 @@ -3,99 +3,139 @@ import ComboBoxComponent from "select-box-kit/components/combo-box"; import { CLOSE_STATUS_TYPE } from "discourse/controllers/edit-topic-timer"; import DatetimeMixin from "select-box-kit/components/future-date-input-selector/mixin"; -export const LATER_TODAY = "later_today"; -export const TOMORROW = "tomorrow"; -export const LATER_THIS_WEEK = "later_this_week"; -export const THIS_WEEKEND = "this_weekend"; -export const NEXT_WEEK = "next_week"; -export const TWO_WEEKS = "two_weeks"; -export const NEXT_MONTH = "next_month"; -export const FOREVER = "forever"; +const TIMEFRAME_BASE = { + enabled: () => true, + when: () => null, + icon: 'briefcase', + displayWhen: true, +}; -export const PICK_DATE_AND_TIME = "pick_date_and_time"; -export const SET_BASED_ON_LAST_POST = "set_based_on_last_post"; +function buildTimeframe(opts) { + return jQuery.extend({}, TIMEFRAME_BASE, opts); +} + +export const TIMEFRAMES = [ + buildTimeframe({ + id: 'later_today', + format: "h a", + enabled: opts => opts.canScheduleToday, + when: (time) => time.hour(18).minute(0), + icon: 'moon-o' + }), + buildTimeframe({ + id: "tomorrow", + format: "ddd, h a", + when: (time, timeOfDay) => time.add(1, 'day').hour(timeOfDay).minute(0), + icon: 'sun-o' + }), + buildTimeframe({ + id: "later_this_week", + format: "ddd, h a", + enabled: opts => !opts.canScheduleToday && opts.day < 4, + when: (time, timeOfDay) => time.add(2, 'day').hour(timeOfDay).minute(0), + }), + buildTimeframe({ + id: "this_weekend", + format: "ddd, h a", + enabled: opts => opts.day < 5 && opts.includeWeekend, + when: (time, timeOfDay) => time.day(6).hour(timeOfDay).minute(0), + icon: 'bed' + }), + buildTimeframe({ + id: "next_week", + format: "ddd, h a", + enabled: opts => opts.day !== 7, + when: (time, timeOfDay) => time.add(1, 'week').day(1).hour(timeOfDay).minute(0), + icon: 'briefcase' + }), + buildTimeframe({ + id: "two_weeks", + format: "MMM D", + when: (time, timeOfDay) => time.add(2, 'week').hour(timeOfDay).minute(0), + icon: 'briefcase' + }), + buildTimeframe({ + id: "next_month", + format: "MMM D", + enabled: opts => opts.now.date() !== moment().endOf("month").date(), + when: (time, timeOfDay) => time.add(1, 'month').startOf('month').hour(timeOfDay).minute(0), + icon: 'briefcase' + }), + buildTimeframe({ + id: "three_months", + format: "MMM D", + enabled: opts => opts.includeFarFuture, + when: (time, timeOfDay) => time.add(3, 'month').startOf('month').hour(timeOfDay).minute(0), + icon: 'briefcase' + }), + buildTimeframe({ + id: "six_months", + format: "MMM D", + enabled: opts => opts.includeFarFuture, + when: (time, timeOfDay) => time.add(6, 'month').startOf('month').hour(timeOfDay).minute(0), + icon: 'briefcase' + }), + buildTimeframe({ + id: "one_year", + format: "MMM D", + enabled: opts => opts.includeFarFuture, + when: (time, timeOfDay) => time.add(1, 'year').startOf('day').hour(timeOfDay).minute(0), + icon: 'briefcase' + }), + buildTimeframe({ + id: "forever", + enabled: opts => opts.includeFarFuture, + when: (time, timeOfDay) => time.add(1000, 'year').hour(timeOfDay).minute(0), + icon: 'gavel', + displayWhen: false + }), + buildTimeframe({ + id: "pick_date_and_time", + icon: 'calendar-plus-o' + }), + buildTimeframe({ + id: "set_based_on_last_post", + enabled: opts => opts.includeBasedOnLastPost, + icon: 'clock-o' + }), +]; + +let _timeframeById = null; +export function timeframeDetails(id) { + if (!_timeframeById) { + _timeframeById = {}; + TIMEFRAMES.forEach(t => _timeframeById[t.id] = t); + } + return _timeframeById[id]; +} export const FORMAT = "YYYY-MM-DD HH:mm"; export default ComboBoxComponent.extend(DatetimeMixin, { classNames: ["future-date-input-selector"], - isCustom: Ember.computed.equal("value", PICK_DATE_AND_TIME), + isCustom: Ember.computed.equal("value", "pick_date_and_time"), clearable: true, rowComponent: "future-date-input-selector/future-date-input-selector-row", headerComponent: "future-date-input-selector/future-date-input-selector-header", @computed content() { - const selections = []; - const now = moment(); - const canScheduleToday = (24 - now.hour()) > 6; - const day = now.day(); + let now = moment(); + let opts = { + now, + day: now.day(), + includeWeekend: this.get('includeWeekend'), + includeFarFuture: this.get('includeFarFuture'), + includeBasedOnLastPost: this.get("statusType") === CLOSE_STATUS_TYPE, + canScheduleToday: (24 - now.hour()) > 6, + }; - if (canScheduleToday) { - selections.push({ - id: LATER_TODAY, - name: I18n.t("topic.auto_update_input.later_today") - }); - } - - selections.push({ - id: TOMORROW, - name: I18n.t("topic.auto_update_input.tomorrow") + return TIMEFRAMES.filter(tf => tf.enabled(opts)).map(tf => { + return { + id: tf.id, + name: I18n.t(`topic.auto_update_input.${tf.id}`) + }; }); - - if (!canScheduleToday && day < 4) { - selections.push({ - id: LATER_THIS_WEEK, - name: I18n.t("topic.auto_update_input.later_this_week") - }); - } - - if (day < 5 && this.get("includeWeekend")) { - selections.push({ - id: THIS_WEEKEND, - name: I18n.t("topic.auto_update_input.this_weekend") - }); - } - - if (day !== 7) { - selections.push({ - id: NEXT_WEEK, - name: I18n.t("topic.auto_update_input.next_week") - }); - } - - selections.push({ - id: TWO_WEEKS, - name: I18n.t("topic.auto_update_input.two_weeks") - }); - - if (moment().endOf("month").date() !== now.date()) { - selections.push({ - id: NEXT_MONTH, - name: I18n.t("topic.auto_update_input.next_month") - }); - } - - if (this.get("includeForever")) { - selections.push({ - id: FOREVER, - name: I18n.t("topic.auto_update_input.forever") - }); - } - - selections.push({ - id: PICK_DATE_AND_TIME, - name: I18n.t("topic.auto_update_input.pick_date_and_time") - }); - - if (this.get("statusType") === CLOSE_STATUS_TYPE) { - selections.push({ - id: SET_BASED_ON_LAST_POST, - name: I18n.t("topic.auto_update_input.set_based_on_last_post") - }); - } - - return selections; }, @observes("value") diff --git a/app/assets/javascripts/select-box-kit/components/future-date-input-selector/mixin.js.es6 b/app/assets/javascripts/select-box-kit/components/future-date-input-selector/mixin.js.es6 index 2046b0c4cfd..d69b38a5666 100644 --- a/app/assets/javascripts/select-box-kit/components/future-date-input-selector/mixin.js.es6 +++ b/app/assets/javascripts/select-box-kit/components/future-date-input-selector/mixin.js.es6 @@ -1,17 +1,6 @@ import { iconHTML } from 'discourse-common/lib/icon-library'; import { CLOSE_STATUS_TYPE } from 'discourse/controllers/edit-topic-timer'; -import { - LATER_TODAY, - TOMORROW, - LATER_THIS_WEEK, - THIS_WEEKEND, - NEXT_WEEK, - TWO_WEEKS, - NEXT_MONTH, - FOREVER, - PICK_DATE_AND_TIME, - SET_BASED_ON_LAST_POST, -} from "select-box-kit/components/future-date-input-selector"; +import { timeframeDetails } from 'select-box-kit/components/future-date-input-selector'; export default Ember.Mixin.create({ _computeIconForValue(value) { @@ -30,72 +19,28 @@ export default Ember.Mixin.create({ } let {time} = this._updateAt(value); - if (time) { - if (value === LATER_TODAY) { - time = time.format("h a"); - } else if (value === NEXT_MONTH || value === TWO_WEEKS) { - time = time.format("MMM D"); - } else { - time = time.format("ddd, h a"); + + let details = timeframeDetails(value); + if (!details.displayWhen) { + time = null; + } + if (time && details.format) { + return time.format(details.format); } } - - if (time && value !== FOREVER) { - return time; - } - - return null; + return time; }, _updateAt(selection) { - let time = moment(); - let icon; - const timeOfDay = this.get('statusType') !== CLOSE_STATUS_TYPE ? 8 : 18; - - switch(selection) { - case LATER_TODAY: - time = time.hour(18).minute(0); - icon = 'moon-o'; - break; - case TOMORROW: - time = time.add(1, 'day').hour(timeOfDay).minute(0); - icon = 'sun-o'; - break; - case LATER_THIS_WEEK: - time = time.add(2, 'day').hour(timeOfDay).minute(0); - icon = 'briefcase'; - break; - case THIS_WEEKEND: - time = time.day(6).hour(timeOfDay).minute(0); - icon = 'bed'; - break; - case NEXT_WEEK: - time = time.add(1, 'week').day(1).hour(timeOfDay).minute(0); - icon = 'briefcase'; - break; - case TWO_WEEKS: - time = time.add(2, 'week').hour(timeOfDay).minute(0); - icon = 'briefcase'; - break; - case NEXT_MONTH: - time = time.add(1, 'month').startOf('month').hour(timeOfDay).minute(0); - icon = 'briefcase'; - break; - case FOREVER: - time = time.add(1000, 'year').hour(timeOfDay).minute(0); - icon = 'gavel'; - break; - case PICK_DATE_AND_TIME: - time = null; - icon = 'calendar-plus-o'; - break; - case SET_BASED_ON_LAST_POST: - time = null; - icon = 'clock-o'; - break; + let details = timeframeDetails(selection); + if (details) { + return { + time: details.when(moment(), this.get('statusType') !== CLOSE_STATUS_TYPE ? 8 : 18), + icon: details.icon + }; } - return { time, icon }; + return { time: moment() }; }, }); diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index eadad8b0e40..b00423b5dbf 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -1572,6 +1572,9 @@ en: next_week: "Next week" two_weeks: "Two Weeks" next_month: "Next month" + three_months: "Three Months" + six_months: "Six Months" + one_year: "One Year" forever: "Forever" pick_date_and_time: "Pick date and time" set_based_on_last_post: "Close based on last post"