From 65817e13c7900ea81947e40e177459cfea8acee4 Mon Sep 17 00:00:00 2001 From: Chris Date: Wed, 2 Aug 2017 01:36:54 -0700 Subject: PLT-6965 jira integration (plus plugin scaffolding) (#6918) * plugin scaffolding / jira integration * add vendored testify packages * webhook fix * don't change i18n ids * support configuration watching * add basic jira plugin configuration to admin console * fix eslint errors * fix another eslint warning * polish * undo unintentional config.json commit >:( * test fix * add jira plugin diagnostics, remove dm support, add bot tag, generate web-safe secrets * rebase, implement requested changes * requested changes * remove tests and minimize makefile change * add missing license headers * add missing comma * remove bad line from Makefile --- webapp/components/suggestion/suggestion_box.jsx | 49 ++++++++++++++++++++----- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'webapp/components/suggestion') diff --git a/webapp/components/suggestion/suggestion_box.jsx b/webapp/components/suggestion/suggestion_box.jsx index e9dc698aa..008fc2ffb 100644 --- a/webapp/components/suggestion/suggestion_box.jsx +++ b/webapp/components/suggestion/suggestion_box.jsx @@ -80,7 +80,12 @@ export default class SuggestionBox extends React.Component { /** * Function called when @mention is clicked */ - popoverMentionKeyClick: PropTypes.bool + popoverMentionKeyClick: PropTypes.bool, + + /** + * The number of characters required to show the suggestion list, defaults to 1 + */ + requiredCharacters: PropTypes.number } static defaultProps = { @@ -88,13 +93,15 @@ export default class SuggestionBox extends React.Component { listStyle: 'top', renderDividers: false, completeOnTab: true, - isRHS: false + isRHS: false, + requiredCharacters: 1 } constructor(props) { super(props); this.handleBlur = this.handleBlur.bind(this); + this.handleFocus = this.handleFocus.bind(this); this.handlePopoverMentionKeyClick = this.handlePopoverMentionKeyClick.bind(this); this.handleCompleteWord = this.handleCompleteWord.bind(this); @@ -163,11 +170,22 @@ export default class SuggestionBox extends React.Component { } } + handleFocus() { + setTimeout(() => { + const textbox = this.getTextbox(); + const pretext = textbox.value.substring(0, textbox.selectionEnd); + + if (pretext.length >= this.props.requiredCharacters) { + GlobalActions.emitSuggestionPretextChanged(this.suggestionId, pretext); + } + }); + } + handleChange(e) { const textbox = this.getTextbox(); const pretext = textbox.value.substring(0, textbox.selectionEnd); - if (!this.composing && SuggestionStore.getPretext(this.suggestionId) !== pretext) { + if (!this.composing && SuggestionStore.getPretext(this.suggestionId) !== pretext && pretext.length >= this.props.requiredCharacters) { GlobalActions.emitSuggestionPretextChanged(this.suggestionId, pretext); } @@ -228,7 +246,8 @@ export default class SuggestionBox extends React.Component { const suffix = text.substring(caret); - this.refs.textbox.value = prefix + term + ' ' + suffix; + const newValue = prefix + term + ' ' + suffix; + this.refs.textbox.value = newValue; if (this.props.onChange) { // fake an input event to send back to parent components @@ -242,9 +261,10 @@ export default class SuggestionBox extends React.Component { if (this.props.onItemSelected) { const items = SuggestionStore.getItems(this.suggestionId); - for (const i of items) { - if (i.name === term) { - this.props.onItemSelected(i); + const terms = SuggestionStore.getTerms(this.suggestionId); + for (let i = 0; i < terms.length; i++) { + if (terms[i] === term) { + this.props.onItemSelected(items[i]); break; } } @@ -254,7 +274,9 @@ export default class SuggestionBox extends React.Component { // set the caret position after the next rendering window.requestAnimationFrame(() => { - Utils.setCaretPosition(textbox, prefix.length + term.length + 1); + if (textbox.value === newValue) { + Utils.setCaretPosition(textbox, newValue.length); + } }); for (const provider of this.props.providers) { @@ -277,7 +299,9 @@ export default class SuggestionBox extends React.Component { e.preventDefault(); } else if (e.which === KeyCodes.ENTER || (this.props.completeOnTab && e.which === KeyCodes.TAB)) { this.handleCompleteWord(SuggestionStore.getSelection(this.suggestionId), SuggestionStore.getSelectedMatchedPretext(this.suggestionId)); - this.props.onKeyDown(e); + if (this.props.onKeyDown) { + this.props.onKeyDown(e); + } e.preventDefault(); } else if (e.which === KeyCodes.ESCAPE) { GlobalActions.emitClearSuggestions(this.suggestionId); @@ -321,11 +345,14 @@ export default class SuggestionBox extends React.Component { Reflect.deleteProperty(props, 'completeOnTab'); Reflect.deleteProperty(props, 'isRHS'); Reflect.deleteProperty(props, 'popoverMentionKeyClick'); + Reflect.deleteProperty(props, 'requiredCharacters'); const childProps = { ref: 'textbox', onBlur: this.handleBlur, + onFocus: this.handleFocus, onInput: this.handleChange, + onChange() { /* this is only here to suppress warnings about onChange not being implemented for read-write inputs */ }, onCompositionStart: this.handleCompositionStart, onCompositionUpdate: this.handleCompositionUpdate, onCompositionEnd: this.handleCompositionEnd, @@ -337,6 +364,7 @@ export default class SuggestionBox extends React.Component { textbox = ( @@ -345,6 +373,7 @@ export default class SuggestionBox extends React.Component { textbox = ( @@ -364,7 +393,7 @@ export default class SuggestionBox extends React.Component { return (
{textbox} - {this.props.value && + {this.props.value.length >= this.props.requiredCharacters &&