diff --git a/app/assets/javascripts/discourse/components/auto-update-input.js.es6 b/app/assets/javascripts/discourse/components/auto-update-input.js.es6 index 7541d4988e4..1d441197782 100644 --- a/app/assets/javascripts/discourse/components/auto-update-input.js.es6 +++ b/app/assets/javascripts/discourse/components/auto-update-input.js.es6 @@ -1,9 +1,12 @@ -import computed from "ember-addons/ember-computed-decorators"; -import { observes } from "ember-addons/ember-computed-decorators"; +import { default as computed, observes } from "ember-addons/ember-computed-decorators"; export default Ember.Component.extend({ limited: false, - inputValid: false, + + didInsertElement() { + this._super(); + this._updateInputValid(); + }, @computed("limited") inputUnitsKey(limited) { diff --git a/app/assets/javascripts/discourse/components/category-chooser.js.es6 b/app/assets/javascripts/discourse/components/category-chooser.js.es6 index ab0c704b59b..7b031e354f6 100644 --- a/app/assets/javascripts/discourse/components/category-chooser.js.es6 +++ b/app/assets/javascripts/discourse/components/category-chooser.js.es6 @@ -3,6 +3,7 @@ import { categoryBadgeHTML } from 'discourse/helpers/category-link'; import computed from 'ember-addons/ember-computed-decorators'; import { observes, on } from 'ember-addons/ember-computed-decorators'; import PermissionType from 'discourse/models/permission-type'; +import Category from 'discourse/models/category'; export default ComboboxView.extend({ classNames: ['combobox category-combobox'], @@ -14,13 +15,16 @@ export default ComboboxView.extend({ content(scopedCategoryId, categories) { // Always scope to the parent of a category, if present if (scopedCategoryId) { - const scopedCat = Discourse.Category.findById(scopedCategoryId); + const scopedCat = Category.findById(scopedCategoryId); scopedCategoryId = scopedCat.get('parent_category_id') || scopedCat.get('id'); } + const excludeCategoryId = this.get('excludeCategoryId'); + return categories.filter(c => { - if (scopedCategoryId && c.get('id') !== scopedCategoryId && c.get('parent_category_id') !== scopedCategoryId) { return false; } - if (c.get('isUncategorizedCategory')) { return false; } + const categoryId = c.get('id'); + if (scopedCategoryId && categoryId !== scopedCategoryId && c.get('parent_category_id') !== scopedCategoryId) { return false; } + if (c.get('isUncategorizedCategory') || excludeCategoryId === categoryId) { return false; } return c.get('permission') === PermissionType.FULL; }); }, @@ -30,8 +34,8 @@ export default ComboboxView.extend({ _updateCategories() { if (!this.get('categories')) { const categories = Discourse.SiteSettings.fixed_category_positions_on_create ? - Discourse.Category.list() : - Discourse.Category.listByActivity(); + Category.list() : + Category.listByActivity(); this.set('categories', categories); } }, @@ -42,7 +46,7 @@ export default ComboboxView.extend({ if (rootNone) { return "category.none"; } else { - return Discourse.Category.findUncategorized(); + return Category.findUncategorized(); } } else { return 'category.choose'; @@ -54,12 +58,12 @@ export default ComboboxView.extend({ // If we have no id, but text with the uncategorized name, we can use that badge. if (Ember.isEmpty(item.id)) { - const uncat = Discourse.Category.findUncategorized(); + const uncat = Category.findUncategorized(); if (uncat && uncat.get('name') === item.text) { category = uncat; } } else { - category = Discourse.Category.findById(parseInt(item.id,10)); + category = Category.findById(parseInt(item.id,10)); } if (!category) return item.text; @@ -67,7 +71,7 @@ export default ComboboxView.extend({ const parentCategoryId = category.get('parent_category_id'); if (parentCategoryId) { - result = categoryBadgeHTML(Discourse.Category.findById(parentCategoryId), {link: false}) + " " + result; + result = categoryBadgeHTML(Category.findById(parentCategoryId), {link: false}) + " " + result; } result += ` × ${category.get('topic_count')}`; diff --git a/app/assets/javascripts/discourse/components/topic-status-info.js.es6 b/app/assets/javascripts/discourse/components/topic-status-info.js.es6 index e204db09a7c..a7b5d784b04 100644 --- a/app/assets/javascripts/discourse/components/topic-status-info.js.es6 +++ b/app/assets/javascripts/discourse/components/topic-status-info.js.es6 @@ -1,4 +1,5 @@ import { bufferedRender } from 'discourse-common/lib/buffered-render'; +import Category from 'discourse/models/category'; export default Ember.Component.extend(bufferedRender({ elementId: 'topic-status-info', @@ -8,7 +9,8 @@ export default Ember.Component.extend(bufferedRender({ 'topic.topic_status_update', 'topic.topic_status_update.execute_at', 'topic.topic_status_update.based_on_last_post', - 'topic.topic_status_update.duration' + 'topic.topic_status_update.duration', + 'topic.topic_status_update.category_id', ], buildBuffer(buffer) { @@ -35,11 +37,23 @@ export default Ember.Component.extend(bufferedRender({ buffer.push('

'); - buffer.push(I18n.t(this._noticeKey(), { + let options = { timeLeft: duration.humanize(true), - duration: moment.duration(autoCloseHours, "hours").humanize() - })); + duration: moment.duration(autoCloseHours, "hours").humanize(), + }; + const categoryId = this.get('topic.topic_status_update.category_id'); + + if (categoryId) { + const category = Category.findById(categoryId); + + options = _.assign({ + categoryName: category.get('slug'), + categoryUrl: category.get('url') + }, options); + } + + buffer.push(I18n.t(this._noticeKey(), options)); buffer.push('

'); // TODO Sam: concerned this can cause a heavy rerender loop diff --git a/app/assets/javascripts/discourse/controllers/edit-topic-status-update.js.es6 b/app/assets/javascripts/discourse/controllers/edit-topic-status-update.js.es6 index 27c3a13c164..de3b147324e 100644 --- a/app/assets/javascripts/discourse/controllers/edit-topic-status-update.js.es6 +++ b/app/assets/javascripts/discourse/controllers/edit-topic-status-update.js.es6 @@ -5,18 +5,36 @@ import { popupAjaxError } from 'discourse/lib/ajax-error'; const CLOSE_STATUS_TYPE = 'close'; const OPEN_STATUS_TYPE = 'open'; +const PUBLISH_TO_CATEGORY_STATUS_TYPE = 'publish_to_category'; export default Ember.Controller.extend(ModalFunctionality, { + closeStatusType: CLOSE_STATUS_TYPE, + openStatusType: OPEN_STATUS_TYPE, + publishToCategoryStatusType: PUBLISH_TO_CATEGORY_STATUS_TYPE, updateTimeValid: null, updateTimeInvalid: Em.computed.not('updateTimeValid'), loading: false, updateTime: null, topicStatusUpdate: Ember.computed.alias("model.topic_status_update"), selection: Ember.computed.alias('model.topic_status_update.status_type'), - autoReopen: Ember.computed.equal('selection', OPEN_STATUS_TYPE), + autoOpen: Ember.computed.equal('selection', OPEN_STATUS_TYPE), autoClose: Ember.computed.equal('selection', CLOSE_STATUS_TYPE), - disableAutoReopen: Ember.computed.and('autoClose', 'updateTime'), - disableAutoClose: Ember.computed.and('autoReopen', 'updateTime'), + publishToCategory: Ember.computed.equal('selection', PUBLISH_TO_CATEGORY_STATUS_TYPE), + + @computed('autoClose', 'updateTime') + disableAutoClose(autoClose, updateTime) { + return updateTime && !autoClose; + }, + + @computed('autoOpen', 'updateTime') + disableAutoOpen(autoOpen, updateTime) { + return updateTime && !autoOpen; + }, + + @computed('publishToCatgory', 'updateTime') + disablePublishToCategory(publishToCatgory, updateTime) { + return updateTime && !publishToCatgory; + }, @computed('topicStatusUpdate.based_on_last_post', 'updateTime', 'model.last_posted_at') willCloseImmediately(basedOnLastPost, updateTime, lastPostedAt) { @@ -42,7 +60,7 @@ export default Ember.Controller.extend(ModalFunctionality, { }, @observes("topicStatusUpdate.execute_at", "topicStatusUpdate.duration") - setAutoCloseTime() { + _setUpdateTime() { let time = null; if (this.get("topicStatusUpdate.based_on_last_post")) { @@ -65,12 +83,18 @@ export default Ember.Controller.extend(ModalFunctionality, { this.get('model.id'), time, this.get('topicStatusUpdate.based_on_last_post'), - status_type + status_type, + this.get('categoryId') ).then(result => { if (time) { this.send('closeModal'); - this.set('topicStatusUpdate.execute_at', result.execute_at); - this.set('topicStatusUpdate.duration', result.duration); + + this.get("topicStatusUpdate").setProperties({ + execute_at: result.execute_at, + duration: result.duration, + category_id: result.category_id + }); + this.set('model.closed', result.closed); } else { this.set('topicStatusUpdate', Ember.Object.create({})); diff --git a/app/assets/javascripts/discourse/models/topic-status-update.js.es6 b/app/assets/javascripts/discourse/models/topic-status-update.js.es6 index cec7eb91a02..fae76de94b9 100644 --- a/app/assets/javascripts/discourse/models/topic-status-update.js.es6 +++ b/app/assets/javascripts/discourse/models/topic-status-update.js.es6 @@ -4,7 +4,7 @@ import RestModel from 'discourse/models/rest'; const TopicStatusUpdate = RestModel.extend({}); TopicStatusUpdate.reopenClass({ - updateStatus(topicId, time, basedOnLastPost, statusType) { + updateStatus(topicId, time, basedOnLastPost, statusType, categoryId) { let data = { time: time, timezone_offset: (new Date().getTimezoneOffset()), @@ -12,6 +12,7 @@ TopicStatusUpdate.reopenClass({ }; if (basedOnLastPost) data.based_on_last_post = basedOnLastPost; + if (categoryId) data.category_id = categoryId; return ajax({ url: `/t/${topicId}/status_update`, diff --git a/app/assets/javascripts/discourse/routes/topic.js.es6 b/app/assets/javascripts/discourse/routes/topic.js.es6 index edcbaba332c..3fcb115fbf4 100644 --- a/app/assets/javascripts/discourse/routes/topic.js.es6 +++ b/app/assets/javascripts/discourse/routes/topic.js.es6 @@ -52,7 +52,7 @@ const TopicRoute = Discourse.Route.extend({ showTopicStatusUpdate() { const model = this.modelFor('topic'); - if (!model.get('topic_status_update')) model.set('topic_status_update', Ember.Object.create()); + model.set('topic_status_update', Ember.Object.create(model.get('topic_status_update'))); showModal('edit-topic-status-update', { model }); this.controllerFor('modal').set('modalClass', 'topic-close-modal'); }, diff --git a/app/assets/javascripts/discourse/templates/components/auto-update-input.hbs b/app/assets/javascripts/discourse/templates/components/auto-update-input.hbs index d9b9cec0e91..455f17eea36 100644 --- a/app/assets/javascripts/discourse/templates/components/auto-update-input.hbs +++ b/app/assets/javascripts/discourse/templates/components/auto-update-input.hbs @@ -1,21 +1,20 @@
-
+
+ + {{#if inputExamplesKey}} +
+ {{i18n inputExamplesKey}} +
+ {{/if}}
- {{#if inputExamplesKey}} -
- {{i18n inputExamplesKey}} -
- {{/if}} - - {{#unless hideBasedOnLastPost}} -
+
- {{#if autoReopen}} - {{auto-update-input - inputLabelKey='topic.topic_status_update.time' - input=updateTime - inputValid=updateTimeValid - hideBasedOnLastPost=true - basedOnLastPost=false}} - {{else if autoClose}} - {{auto-update-input - inputLabelKey='topic.topic_status_update.time' - input=updateTime - inputValid=updateTimeValid - limited=topicStatusUpdate.based_on_last_post - basedOnLastPost=topicStatusUpdate.based_on_last_post}} - - {{#if willCloseImmediately}} -
- {{fa-icon "warning"}} - {{willCloseI18n}} +
+ {{#if autoOpen}} + {{auto-update-input + inputLabelKey='topic.topic_status_update.time' + input=updateTime + inputValid=updateTimeValid + hideBasedOnLastPost=true + basedOnLastPost=false}} + {{else if publishToCategory}} +
+ + {{category-chooser valueAttribute="id" value=categoryId excludeCategoryId=model.category_id}}
+ + {{auto-update-input + inputLabelKey='topic.topic_status_update.time' + input=updateTime + inputValid=updateTimeValid + hideBasedOnLastPost=true + basedOnLastPost=false}} + {{else if autoClose}} + {{auto-update-input + inputLabelKey='topic.topic_status_update.time' + input=updateTime + inputValid=updateTimeValid + limited=topicStatusUpdate.based_on_last_post + basedOnLastPost=topicStatusUpdate.based_on_last_post}} + + {{#if willCloseImmediately}} +
+ {{fa-icon "warning"}} + {{willCloseI18n}} +
+ {{/if}} {{/if}} - {{/if}} +
{{/d-modal-body}}