From 65817e13c7900ea81947e40e177459cfea8acee4 Mon Sep 17 00:00:00 2001
From: Chris <ccbrown112@gmail.com>
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/suggestion_box.jsx')

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 = (
                 <input
                     type='text'
+                    autoComplete='off'
                     {...props}
                     {...childProps}
                 />
@@ -345,6 +373,7 @@ export default class SuggestionBox extends React.Component {
             textbox = (
                 <input
                     type='search'
+                    autoComplete='off'
                     {...props}
                     {...childProps}
                 />
@@ -364,7 +393,7 @@ export default class SuggestionBox extends React.Component {
         return (
             <div ref='container'>
                 {textbox}
-                {this.props.value &&
+                {this.props.value.length >= this.props.requiredCharacters &&
                     <SuggestionListComponent
                         suggestionId={this.suggestionId}
                         location={listStyle}
-- 
cgit v1.2.3-1-g7c22

