Auto-close time can be entered in 3 ways, so a topic can close at any time
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
Discourse.AutoCloseFormComponent = Ember.Component.extend({
|
||||
|
||||
autoCloseValid: false,
|
||||
|
||||
label: function() {
|
||||
return I18n.t( this.get('labelKey') || 'composer.auto_close_label' );
|
||||
}.property('labelKey'),
|
||||
|
||||
autoCloseChanged: function() {
|
||||
if( this.get('autoCloseTime') && this.get('autoCloseTime').length > 0 ) {
|
||||
this.set('autoCloseTime', this.get('autoCloseTime').replace(/[^\d:-\s]/g, '') );
|
||||
}
|
||||
this.set('autoCloseValid', this.isAutoCloseValid());
|
||||
}.observes('autoCloseTime'),
|
||||
|
||||
isAutoCloseValid: function() {
|
||||
if (this.get('autoCloseTime')) {
|
||||
var t = this.get('autoCloseTime').trim();
|
||||
if (t.match(/^[\d]{4}-[\d]{1,2}-[\d]{1,2} [\d]{1,2}:[\d]{2}/)) {
|
||||
return moment(t).isAfter(); // In the future
|
||||
} else {
|
||||
return (t.match(/^[\d]+$/) || t.match(/^[\d]{1,2}:[\d]{2}$/)) !== null;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -9,20 +9,23 @@
|
||||
**/
|
||||
Discourse.EditTopicAutoCloseController = Discourse.ObjectController.extend(Discourse.ModalFunctionality, {
|
||||
|
||||
setDays: function() {
|
||||
auto_close_valid: true,
|
||||
auto_close_invalid: Em.computed.not('auto_close_valid'),
|
||||
|
||||
setAutoCloseTime: function() {
|
||||
if( this.get('details.auto_close_at') ) {
|
||||
var closeTime = new Date( this.get('details.auto_close_at') );
|
||||
if (closeTime > new Date()) {
|
||||
this.set('auto_close_days', Math.round(moment(closeTime).diff(new Date(), 'days', true)));
|
||||
this.set('auto_close_time', moment(closeTime).format("YYYY-MM-DD HH:mm"));
|
||||
}
|
||||
} else {
|
||||
this.set('details.auto_close_days', '');
|
||||
this.set('details.auto_close_time', '');
|
||||
}
|
||||
}.observes('details.auto_close_at'),
|
||||
|
||||
actions: {
|
||||
saveAutoClose: function() {
|
||||
this.setAutoClose( parseFloat(this.get('auto_close_days')) );
|
||||
this.setAutoClose( this.get('auto_close_time') );
|
||||
},
|
||||
|
||||
removeAutoClose: function() {
|
||||
@@ -30,19 +33,23 @@ Discourse.EditTopicAutoCloseController = Discourse.ObjectController.extend(Disco
|
||||
}
|
||||
},
|
||||
|
||||
setAutoClose: function(days) {
|
||||
setAutoClose: function(time) {
|
||||
var self = this;
|
||||
this.send('hideModal');
|
||||
Discourse.ajax({
|
||||
url: '/t/' + this.get('id') + '/autoclose',
|
||||
type: 'PUT',
|
||||
dataType: 'html', // no custom errors, jquery 1.9 enforces json
|
||||
data: { auto_close_days: days > 0 ? days : null }
|
||||
}).then(function(){
|
||||
self.send('closeModal');
|
||||
self.set('details.auto_close_at', moment().add('days', days).format());
|
||||
dataType: 'json',
|
||||
data: { auto_close_time: Discourse.Utilities.timestampFromAutocloseString(time) }
|
||||
}).then(function(result){
|
||||
if (result.success) {
|
||||
self.send('closeModal');
|
||||
self.set('details.auto_close_at', result.auto_close_at);
|
||||
} else {
|
||||
bootbox.alert(I18n.t('composer.auto_close_error'), function() { self.send('showModal'); } );
|
||||
}
|
||||
}, function (error) {
|
||||
bootbox.alert(I18n.t('generic_error'), function() { self.send('showModal'); } );
|
||||
bootbox.alert(I18n.t('composer.auto_close_error'), function() { self.send('showModal'); } );
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -322,6 +322,26 @@ Discourse.Utilities = {
|
||||
image.src = url;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
timestampFromAutocloseString: function(arg) {
|
||||
if (!arg) return null;
|
||||
if (arg.match(/^[\d]{4}-[\d]{1,2}-[\d]{1,2} [\d]{1,2}:[\d]{2}/)) {
|
||||
return moment(arg).toJSON(); // moment will add the timezone
|
||||
} else {
|
||||
var matches = arg.match(/^([\d]{1,2}):([\d]{2})$/); // just the time HH:MM
|
||||
if (matches) {
|
||||
var now = moment(),
|
||||
t = moment(new Date(now.year(), now.month(), now.date(), matches[1], matches[2]));
|
||||
if (t.isAfter()) {
|
||||
return t.toJSON();
|
||||
} else {
|
||||
return t.add('days', 1).toJSON();
|
||||
}
|
||||
} else {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -465,7 +465,7 @@ Discourse.Composer = Discourse.Model.extend({
|
||||
moderator: currentUser.get('moderator'),
|
||||
yours: true,
|
||||
newPost: true,
|
||||
auto_close_days: this.get('auto_close_days')
|
||||
auto_close_time: Discourse.Utilities.timestampFromAutocloseString(this.get('auto_close_time'))
|
||||
});
|
||||
|
||||
// If we're in a topic, we can append the post instantly.
|
||||
|
||||
@@ -180,7 +180,7 @@ Discourse.Post = Discourse.Model.extend({
|
||||
title: this.get('title'),
|
||||
image_sizes: this.get('imageSizes'),
|
||||
target_usernames: this.get('target_usernames'),
|
||||
auto_close_days: this.get('auto_close_days')
|
||||
auto_close_time: Discourse.Utilities.timestampFromAutocloseString(this.get('auto_close_time'))
|
||||
};
|
||||
|
||||
var metaData = this.get('metaData');
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<div class="auto-close-fields">
|
||||
<i class="icon icon-time"></i>
|
||||
{{view.label}}
|
||||
{{textField value=view.autoCloseDays maxlength="3"}}
|
||||
{{i18n composer.auto_close_units}}
|
||||
</div>
|
||||
@@ -0,0 +1,11 @@
|
||||
<div class="auto-close-fields">
|
||||
<div>
|
||||
<i class="icon icon-time"></i>
|
||||
{{label}}
|
||||
{{textField value=autoCloseTime}}
|
||||
{{i18n composer.auto_close_units}}
|
||||
</div>
|
||||
<div class="examples">
|
||||
{{i18n composer.auto_close_examples}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -48,13 +48,13 @@
|
||||
<button class='btn' {{action showOptions}}>{{i18n topic.options}}</button>
|
||||
{{/if}}
|
||||
{{#if model.showAdminOptions}}
|
||||
<button {{action toggleAdminOptions target="view"}} class="btn no-text" title='{{i18n composer.admin_options_title}}'><i class="icon icon-wrench"></i></button>
|
||||
<button {{action toggleAdminOptions target="view"}} class="btn no-text show-admin-options" title='{{i18n composer.admin_options_title}}'><i class="icon icon-wrench"></i></button>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
|
||||
<div class="admin-options-form">
|
||||
{{autoCloseForm autoCloseDays=model.auto_close_days}}
|
||||
{{auto-close-form autoCloseTime=model.auto_close_time}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
{{autoCloseForm autoCloseDays=auto_close_days}}
|
||||
{{auto-close-form autoCloseTime=auto_close_time autoCloseValid=auto_close_valid}}
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class='btn btn-primary' {{action saveAutoClose}}>{{i18n topic.auto_close_save}}</button>
|
||||
<button class='btn btn-primary' {{action saveAutoClose}} {{bindAttr disabled="auto_close_invalid"}}>{{i18n topic.auto_close_save}}</button>
|
||||
<a {{action closeModal}}>{{i18n cancel}}</a>
|
||||
<button class='btn pull-right' {{action removeAutoClose}}>{{i18n topic.auto_close_remove}}</button>
|
||||
</div>
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/**
|
||||
This view renders the form to set or change a topic or category's auto-close setting.
|
||||
|
||||
@class AutoCloseFormView
|
||||
@extends Ember.View
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.AutoCloseFormView = Ember.View.extend({
|
||||
templateName: 'auto_close_form',
|
||||
|
||||
label: function() {
|
||||
return I18n.t( this.get('labelKey') || 'composer.auto_close_label' );
|
||||
}.property('labelKey'),
|
||||
|
||||
autoCloseChanged: function() {
|
||||
if( this.get('autoCloseDays') && this.get('autoCloseDays').length > 0 ) {
|
||||
this.set('autoCloseDays', this.get('autoCloseDays').replace(/[^\d]/g, '') );
|
||||
}
|
||||
}.observes('autoCloseDays')
|
||||
});
|
||||
|
||||
Discourse.View.registerHelper('autoCloseForm', Discourse.AutoCloseFormView);
|
||||
Reference in New Issue
Block a user