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
Этот коммит содержится в:
@@ -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}
|
||||
|
||||
Ссылка в новой задаче
Block a user