mirror of
https://github.com/discourse/discourse.git
synced 2025-05-26 11:42:14 +08:00
FEATURE: when uncategorized topics are not allowed, disable the post input until a category is chosen
This commit is contained in:
@ -37,10 +37,19 @@ export default Ember.Component.extend({
|
|||||||
return `[${I18n.t('uploading')}]() `;
|
return `[${I18n.t('uploading')}]() `;
|
||||||
},
|
},
|
||||||
|
|
||||||
@computed()
|
@computed('composer.requiredCategoryMissing')
|
||||||
replyPlaceholder() {
|
replyPlaceholder(requiredCategoryMissing) {
|
||||||
|
if (requiredCategoryMissing) {
|
||||||
|
return 'composer.reply_placeholder_choose_category';
|
||||||
|
} else {
|
||||||
const key = authorizesOneOrMoreImageExtensions() ? "reply_placeholder" : "reply_placeholder_no_images";
|
const key = authorizesOneOrMoreImageExtensions() ? "reply_placeholder" : "reply_placeholder_no_images";
|
||||||
return `composer.${key}`;
|
return `composer.${key}`;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@computed('composer.requiredCategoryMissing', 'composer.replyLength')
|
||||||
|
disableTextarea(requiredCategoryMissing, replyLength) {
|
||||||
|
return requiredCategoryMissing && replyLength === 0;
|
||||||
},
|
},
|
||||||
|
|
||||||
@observes('composer.uploadCancelled')
|
@observes('composer.uploadCancelled')
|
||||||
|
@ -750,6 +750,8 @@ export default Ember.Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
toolbarButton(button) {
|
toolbarButton(button) {
|
||||||
|
if (this.get('disabled')) { return; }
|
||||||
|
|
||||||
const selected = this._getSelected(button.trimLeading);
|
const selected = this._getSelected(button.trimLeading);
|
||||||
const toolbarEvent = {
|
const toolbarEvent = {
|
||||||
selected,
|
selected,
|
||||||
@ -770,6 +772,8 @@ export default Ember.Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
showLinkModal() {
|
showLinkModal() {
|
||||||
|
if (this.get('disabled')) { return; }
|
||||||
|
|
||||||
this._lastSel = this._getSelected();
|
this._lastSel = this._getSelected();
|
||||||
|
|
||||||
if (this._lastSel) {
|
if (this._lastSel) {
|
||||||
@ -780,6 +784,8 @@ export default Ember.Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
formatCode() {
|
formatCode() {
|
||||||
|
if (this.get('disabled')) { return; }
|
||||||
|
|
||||||
const sel = this._getSelected('', { lineVal: true });
|
const sel = this._getSelected('', { lineVal: true });
|
||||||
const selValue = sel.value;
|
const selValue = sel.value;
|
||||||
const hasNewLine = selValue.indexOf("\n") !== -1;
|
const hasNewLine = selValue.indexOf("\n") !== -1;
|
||||||
@ -833,6 +839,7 @@ export default Ember.Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
emoji() {
|
emoji() {
|
||||||
|
if (this.get('disabled')) { return; }
|
||||||
this.set('emojiPickerIsActive', !this.get('emojiPickerIsActive'));
|
this.set('emojiPickerIsActive', !this.get('emojiPickerIsActive'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,13 +265,17 @@ const Composer = RestModel.extend({
|
|||||||
return this.get('targetUsernames') && (this.get('targetUsernames').trim() + ',').indexOf(',') === 0;
|
return this.get('targetUsernames') && (this.get('targetUsernames').trim() + ',').indexOf(',') === 0;
|
||||||
} else {
|
} else {
|
||||||
// has a category? (when needed)
|
// has a category? (when needed)
|
||||||
return this.get('canCategorize') &&
|
return this.get('requiredCategoryMissing');
|
||||||
!this.siteSettings.allow_uncategorized_topics &&
|
|
||||||
!this.get('categoryId') &&
|
|
||||||
!this.user.get('admin');
|
|
||||||
}
|
}
|
||||||
}.property('loading', 'canEditTitle', 'titleLength', 'targetUsernames', 'replyLength', 'categoryId', 'missingReplyCharacters'),
|
}.property('loading', 'canEditTitle', 'titleLength', 'targetUsernames', 'replyLength', 'categoryId', 'missingReplyCharacters'),
|
||||||
|
|
||||||
|
@computed('canCategorize', 'categoryId')
|
||||||
|
requiredCategoryMissing(canCategorize, categoryId) {
|
||||||
|
return canCategorize && !categoryId &&
|
||||||
|
!this.siteSettings.allow_uncategorized_topics &&
|
||||||
|
!this.user.get('admin');
|
||||||
|
},
|
||||||
|
|
||||||
titleLengthValid: function() {
|
titleLengthValid: function() {
|
||||||
if (this.user.get('admin') && this.get('post.static_doc') && this.get('titleLength') > 0) return true;
|
if (this.user.get('admin') && this.get('post.static_doc') && this.get('titleLength') > 0) return true;
|
||||||
if (this.get('titleLength') < this.get('minimumTitleLength')) return false;
|
if (this.get('titleLength') < this.get('minimumTitleLength')) return false;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
onExpandPopupMenuOptions="onExpandPopupMenuOptions"
|
onExpandPopupMenuOptions="onExpandPopupMenuOptions"
|
||||||
onPopupMenuAction=onPopupMenuAction
|
onPopupMenuAction=onPopupMenuAction
|
||||||
popupMenuOptions=popupMenuOptions
|
popupMenuOptions=popupMenuOptions
|
||||||
|
disabled=disableTextarea
|
||||||
outletArgs=(hash composer=composer editorType="composer")}}
|
outletArgs=(hash composer=composer editorType="composer")}}
|
||||||
|
|
||||||
{{#if site.mobileView}}
|
{{#if site.mobileView}}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<div class='d-editor-container'>
|
<div class='d-editor-container'>
|
||||||
<div class="d-editor-textarea-wrapper">
|
<div class="d-editor-textarea-wrapper">
|
||||||
<div class='d-editor-button-bar'>
|
<div class='d-editor-button-bar {{if disabled "disabled"}}'>
|
||||||
{{#each toolbar.groups as |group|}}
|
{{#each toolbar.groups as |group|}}
|
||||||
{{#each group.buttons as |b|}}
|
{{#each group.buttons as |b|}}
|
||||||
{{#if b.popupMenu}}
|
{{#if b.popupMenu}}
|
||||||
@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{conditional-loading-spinner condition=loading}}
|
{{conditional-loading-spinner condition=loading}}
|
||||||
{{textarea tabindex=tabindex value=value class="d-editor-input" placeholder=placeholderTranslated}}
|
{{textarea tabindex=tabindex value=value class="d-editor-input" placeholder=placeholderTranslated disabled=disabled}}
|
||||||
{{popup-input-tip validation=validation}}
|
{{popup-input-tip validation=validation}}
|
||||||
{{plugin-outlet name="after-d-editor" tagName="" args=outletArgs}}
|
{{plugin-outlet name="after-d-editor" tagName="" args=outletArgs}}
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,6 +90,11 @@
|
|||||||
.btn.italic {
|
.btn.italic {
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
visibility: hidden;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.d-editor-spacer {
|
.d-editor-spacer {
|
||||||
|
@ -1325,6 +1325,7 @@ en:
|
|||||||
remove_featured_link: "Remove link from topic."
|
remove_featured_link: "Remove link from topic."
|
||||||
reply_placeholder: "Type here. Use Markdown, BBCode, or HTML to format. Drag or paste images."
|
reply_placeholder: "Type here. Use Markdown, BBCode, or HTML to format. Drag or paste images."
|
||||||
reply_placeholder_no_images: "Type here. Use Markdown, BBCode, or HTML to format."
|
reply_placeholder_no_images: "Type here. Use Markdown, BBCode, or HTML to format."
|
||||||
|
reply_placeholder_choose_category: "Please select a category."
|
||||||
view_new_post: "View your new post."
|
view_new_post: "View your new post."
|
||||||
saving: "Saving"
|
saving: "Saving"
|
||||||
saved: "Saved!"
|
saved: "Saved!"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { acceptance } from "helpers/qunit-helpers";
|
import { acceptance, replaceCurrentUser } from "helpers/qunit-helpers";
|
||||||
|
|
||||||
acceptance("Composer", {
|
acceptance("Composer", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
@ -335,3 +335,42 @@ QUnit.test("Composer draft with dirty reply can toggle to edit", assert => {
|
|||||||
assert.equal(find('.d-editor-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text');
|
assert.equal(find('.d-editor-input').val().indexOf('This is the first post.'), 0, 'it populates the input with the post text');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
acceptance("Composer and uncategorized is not allowed", {
|
||||||
|
loggedIn: true,
|
||||||
|
settings: {
|
||||||
|
enable_whispers: true,
|
||||||
|
allow_uncategorized_topics: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("Disable body until category is selected", assert => {
|
||||||
|
replaceCurrentUser({ admin: false, staff: false, trust_level: 1 });
|
||||||
|
|
||||||
|
visit("/");
|
||||||
|
click('#create-topic');
|
||||||
|
andThen(() => {
|
||||||
|
assert.ok(exists('.d-editor-input'), 'the composer input is visible');
|
||||||
|
assert.ok(exists('.title-input .popup-tip.bad.hide'), 'title errors are hidden by default');
|
||||||
|
assert.ok(exists('.d-editor-textarea-wrapper .popup-tip.bad.hide'), 'body errors are hidden by default');
|
||||||
|
assert.ok(exists('.d-editor-container .d-editor-button-bar.disabled'), 'toolbar is disabled');
|
||||||
|
assert.ok(find('.d-editor-container .d-editor-input:disabled').length, 'textarea is disabled');
|
||||||
|
});
|
||||||
|
|
||||||
|
const categoryChooser = selectKit('.category-chooser');
|
||||||
|
|
||||||
|
categoryChooser.expand().selectRowByValue(2);
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.ok(!exists('.d-editor-container .d-editor-button-bar.disabled'), 'toolbar is enabled');
|
||||||
|
assert.ok(find('.d-editor-container .d-editor-input:disabled').length === 0, 'textarea is enabled');
|
||||||
|
});
|
||||||
|
|
||||||
|
fillIn('.d-editor-input', 'Now I can type stuff');
|
||||||
|
categoryChooser.expand().selectRowByValue('__none__');
|
||||||
|
|
||||||
|
andThen(() => {
|
||||||
|
assert.ok(!exists('.d-editor-container .d-editor-button-bar.disabled'), 'toolbar is still enabled');
|
||||||
|
assert.ok(find('.d-editor-container .d-editor-input:disabled').length === 0, 'textarea is still enabled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { acceptance } from "helpers/qunit-helpers";
|
import { acceptance, replaceCurrentUser } from "helpers/qunit-helpers";
|
||||||
|
|
||||||
acceptance("Composer topic featured links", {
|
acceptance("Composer topic featured links", {
|
||||||
loggedIn: true,
|
loggedIn: true,
|
||||||
@ -76,3 +76,32 @@ QUnit.test("onebox with title but extra words in title field", assert => {
|
|||||||
assert.equal(find('.title-input input').val(), "http://www.example.com/has-title.html test", "title is unchanged");
|
assert.equal(find('.title-input input').val(), "http://www.example.com/has-title.html test", "title is unchanged");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
acceptance("Composer topic featured links when uncategorized is not allowed", {
|
||||||
|
loggedIn: true,
|
||||||
|
settings: {
|
||||||
|
topic_featured_link_enabled: true,
|
||||||
|
max_topic_title_length: 80,
|
||||||
|
enable_markdown_linkify: true,
|
||||||
|
allow_uncategorized_topics: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test("Pasting a link enables the text input area", assert => {
|
||||||
|
replaceCurrentUser({ admin: false, staff: false, trust_level: 1 });
|
||||||
|
|
||||||
|
visit("/");
|
||||||
|
click('#create-topic');
|
||||||
|
andThen(() => {
|
||||||
|
assert.ok(exists('.d-editor-container .d-editor-button-bar.disabled'), 'toolbar is disabled');
|
||||||
|
assert.ok(find('.d-editor-container .d-editor-input:disabled').length, 'textarea is disabled');
|
||||||
|
});
|
||||||
|
fillIn('#reply-title', "http://www.example.com/has-title.html");
|
||||||
|
andThen(() => {
|
||||||
|
assert.ok(find('.d-editor-preview').html().trim().indexOf('onebox') > 0, "it pastes the link into the body and previews it");
|
||||||
|
assert.ok(exists('.d-editor-textarea-wrapper .popup-tip.good'), 'the body is now good');
|
||||||
|
assert.equal(find('.title-input input').val(), "An interesting article", "title is from the oneboxed article");
|
||||||
|
assert.ok(!exists('.d-editor-container .d-editor-button-bar.disabled'), 'toolbar is enabled');
|
||||||
|
assert.ok(find('.d-editor-container .d-editor-input:disabled').length === 0, 'textarea is enabled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Reference in New Issue
Block a user