add client side validation for category minimum_required_tags
This commit is contained in:
parent
9ca6ebe8fe
commit
48d43b33cc
|
@ -779,11 +779,19 @@ export default Ember.Controller.extend({
|
||||||
|
|
||||||
@computed('model.categoryId', 'lastValidatedAt')
|
@computed('model.categoryId', 'lastValidatedAt')
|
||||||
categoryValidation(categoryId, lastValidatedAt) {
|
categoryValidation(categoryId, lastValidatedAt) {
|
||||||
if( !this.siteSettings.allow_uncategorized_topics && !categoryId) {
|
if(!this.siteSettings.allow_uncategorized_topics && !categoryId) {
|
||||||
return InputValidation.create({ failed: true, reason: I18n.t('composer.error.category_missing'), lastShownAt: lastValidatedAt });
|
return InputValidation.create({ failed: true, reason: I18n.t('composer.error.category_missing'), lastShownAt: lastValidatedAt });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@computed('model.category', 'model.tags', 'lastValidatedAt')
|
||||||
|
tagValidation(category, tags, lastValidatedAt) {
|
||||||
|
const tagsArray = tags || [];
|
||||||
|
if (this.site.get('can_tag_topics') && category && category.get('minimum_required_tags') > tagsArray.length) {
|
||||||
|
return InputValidation.create({ failed: true, reason: I18n.t('composer.error.tags_missing', {count: category.get('minimum_required_tags')}), lastShownAt: lastValidatedAt });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
collapse() {
|
collapse() {
|
||||||
this._saveDraft();
|
this._saveDraft();
|
||||||
this.set('model.composeState', Composer.DRAFT);
|
this.set('model.composeState', Composer.DRAFT);
|
||||||
|
|
|
@ -105,6 +105,11 @@ const Composer = RestModel.extend({
|
||||||
return categoryId ? this.site.categories.findBy('id', categoryId) : null;
|
return categoryId ? this.site.categories.findBy('id', categoryId) : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@computed('category')
|
||||||
|
minimumRequiredTags(category) {
|
||||||
|
return (category && category.get('minimum_required_tags') > 0) ? category.get('minimum_required_tags') : null;
|
||||||
|
},
|
||||||
|
|
||||||
creatingTopic: Em.computed.equal('action', CREATE_TOPIC),
|
creatingTopic: Em.computed.equal('action', CREATE_TOPIC),
|
||||||
creatingSharedDraft: Em.computed.equal('action', CREATE_SHARED_DRAFT),
|
creatingSharedDraft: Em.computed.equal('action', CREATE_SHARED_DRAFT),
|
||||||
creatingPrivateMessage: Em.computed.equal('action', PRIVATE_MESSAGE),
|
creatingPrivateMessage: Em.computed.equal('action', PRIVATE_MESSAGE),
|
||||||
|
@ -246,28 +251,41 @@ const Composer = RestModel.extend({
|
||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
|
|
||||||
// whether to disable the post button
|
@computed
|
||||||
cantSubmitPost: function() {
|
isStaffUser() {
|
||||||
|
const currentUser = Discourse.User.current();
|
||||||
|
return currentUser && currentUser.get('staff');
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('loading', 'canEditTitle', 'titleLength', 'targetUsernames', 'replyLength', 'categoryId', 'missingReplyCharacters', 'tags', 'topicFirstPost', 'minimumRequiredTags', 'isStaffUser')
|
||||||
|
cantSubmitPost(loading, canEditTitle, titleLength, targetUsernames, replyLength, categoryId, missingReplyCharacters, tags, topicFirstPost, minimumRequiredTags, isStaffUser) {
|
||||||
|
|
||||||
// can't submit while loading
|
// can't submit while loading
|
||||||
if (this.get('loading')) return true;
|
if (loading) return true;
|
||||||
|
|
||||||
// title is required when
|
// title is required when
|
||||||
// - creating a new topic/private message
|
// - creating a new topic/private message
|
||||||
// - editing the 1st post
|
// - editing the 1st post
|
||||||
if (this.get('canEditTitle') && !this.get('titleLengthValid')) return true;
|
if (canEditTitle && !this.get('titleLengthValid')) return true;
|
||||||
|
|
||||||
// reply is always required
|
// reply is always required
|
||||||
if (this.get('missingReplyCharacters') > 0) return true;
|
if (missingReplyCharacters > 0) return true;
|
||||||
|
|
||||||
|
if (this.site.get('can_tag_topics') && !isStaffUser && topicFirstPost && minimumRequiredTags) {
|
||||||
|
const tagsArray = tags || [];
|
||||||
|
if (tagsArray.length < minimumRequiredTags) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.get("privateMessage")) {
|
if (this.get("privateMessage")) {
|
||||||
// need at least one user when sending a PM
|
// need at least one user when sending a PM
|
||||||
return this.get('targetUsernames') && (this.get('targetUsernames').trim() + ',').indexOf(',') === 0;
|
return targetUsernames && (targetUsernames.trim() + ',').indexOf(',') === 0;
|
||||||
} else {
|
} else {
|
||||||
// has a category? (when needed)
|
// has a category? (when needed)
|
||||||
return this.get('requiredCategoryMissing');
|
return this.get('requiredCategoryMissing');
|
||||||
}
|
}
|
||||||
}.property('loading', 'canEditTitle', 'titleLength', 'targetUsernames', 'replyLength', 'categoryId', 'missingReplyCharacters'),
|
},
|
||||||
|
|
||||||
@computed('canCategorize', 'categoryId')
|
@computed('canCategorize', 'categoryId')
|
||||||
requiredCategoryMissing(canCategorize, categoryId) {
|
requiredCategoryMissing(canCategorize, categoryId) {
|
||||||
|
|
|
@ -64,7 +64,8 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if canEditTags}}
|
{{#if canEditTags}}
|
||||||
{{mini-tag-chooser tags=model.tags tabindex="4" categoryId=model.categoryId}}
|
{{mini-tag-chooser tags=model.tags tabindex="4" categoryId=model.categoryId minimum=model.minimumRequiredTags}}
|
||||||
|
{{popup-input-tip validation=tagValidation}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1303,6 +1303,7 @@ en:
|
||||||
post_length: "Post must be at least {{min}} characters"
|
post_length: "Post must be at least {{min}} characters"
|
||||||
try_like: 'Have you tried the <i class="fa fa-heart"></i> button?'
|
try_like: 'Have you tried the <i class="fa fa-heart"></i> button?'
|
||||||
category_missing: "You must choose a category"
|
category_missing: "You must choose a category"
|
||||||
|
tags_missing: "You must choose at least {{count}} tags"
|
||||||
|
|
||||||
save_edit: "Save Edit"
|
save_edit: "Save Edit"
|
||||||
reply_original: "Reply on Original Topic"
|
reply_original: "Reply on Original Topic"
|
||||||
|
|
|
@ -155,7 +155,7 @@ class TopicCreator
|
||||||
|
|
||||||
def setup_tags(topic)
|
def setup_tags(topic)
|
||||||
if @opts[:tags].blank?
|
if @opts[:tags].blank?
|
||||||
unless @guardian.is_staff?
|
unless @guardian.is_staff? || !guardian.can_tag?(topic)
|
||||||
# Validate minimum required tags for a category
|
# Validate minimum required tags for a category
|
||||||
category = find_category
|
category = find_category
|
||||||
if category.present? && category.minimum_required_tags > 0
|
if category.present? && category.minimum_required_tags > 0
|
||||||
|
|
|
@ -116,6 +116,13 @@ describe TopicCreator do
|
||||||
expect(topic).to be_valid
|
expect(topic).to be_valid
|
||||||
expect(topic.tags.length).to eq(2)
|
expect(topic.tags.length).to eq(2)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "lets new user create a topic if they don't have sufficient trust level to tag topics" do
|
||||||
|
SiteSetting.min_trust_level_to_tag_topics = 1
|
||||||
|
new_user = Fabricate(:newuser)
|
||||||
|
topic = TopicCreator.create(new_user, Guardian.new(new_user), valid_attrs.merge(category: "beta"))
|
||||||
|
expect(topic).to be_valid
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue