add client side validation for category minimum_required_tags

This commit is contained in:
Arpit Jalan 2018-04-06 23:15:33 +05:30
parent 9ca6ebe8fe
commit 48d43b33cc
6 changed files with 45 additions and 10 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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}}

View File

@ -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"

View File

@ -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

View File

@ -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