Accepts command with no parameter

This commit is contained in:
Cássio Zen 2016-07-07 12:04:19 -03:00
parent 238e671f4f
commit 923678d74f
4 changed files with 49 additions and 28 deletions

View File

@ -1,7 +1,7 @@
import { configure } from '@kadira/storybook';
import '../src/index.css';
function loadStories() {
require('../src/index.css');
require('../src/containers/stories/');
require('../src/components/stories/');
}

View File

@ -1,5 +1,5 @@
export const RUN_COMMAND = 'RUN_COMMAND';
export function runCommand(commandName, paramName, paramValue) {
return { type: RUN_COMMAND, command: commandName, payload: { [paramName]: paramValue } };
export function runCommand(commandName, payload) {
return { type: RUN_COMMAND, command: commandName, payload };
}

View File

@ -49,20 +49,29 @@ class FindBar extends Component {
return result.charAt(0).toUpperCase() + result.slice(1);
}
// Generates a regexp and splits a token and param details for a command
compileCommand(command) {
let regexp = '';
let param;
let param = null;
const matcher = /\(:([a-zA-Z_$][a-zA-Z0-9_$]*)(?:(?: as )(.*))?\)/g;
const match = matcher.exec(command.pattern);
const token = command.pattern.slice(0, match.index) || command.token;
regexp += this._escapeRegExp(command.pattern.slice(0, match.index));
const matchIndex = match ? match.index : command.pattern.length;
if (match[1]) {
const token = command.pattern.slice(0, matchIndex) || command.token;
regexp += this._escapeRegExp(command.pattern.slice(0, matchIndex));
if (match && match[1]) {
regexp += '(.*)';
param = { name:match[1], display:match[2] || this._camelCaseToSpace(match[1]) };
}
console.log(Object.assign({}, command, {
regexp,
token,
param
}));
return Object.assign({}, command, {
regexp,
token,
@ -70,6 +79,8 @@ class FindBar extends Component {
});
}
// Check if the entered string matches any command.
// adds a scope (so user can type param value) and dispatches action for fully matched commands
matchCommand() {
const string = this.state.activeScope ? this.state.activeScope + this.state.value : this.state.value;
let match;
@ -78,18 +89,27 @@ class FindBar extends Component {
return match;
});
const param = match[1] && match[1].trim();
const paramName = command.param ? command.param.name : null;
const enteredParamValue = command.param && match[1] ? match[1].trim() : null;
if (!command) {
// No matched command
return null;
} else if (command && !param) {
} else if (command.param && !enteredParamValue) {
// Partial Match
// Command was partially matched: It requires a param, but param wasn't entered
// Set a scope so user can fill the param
this.setState({
value: '',
activeScope: command.token,
placeholder: command.param.display
});
} else {
this.props.dispatch(runCommand(command.token, command.param.name, param));
// Match
// Command was matched and either it doesn't require a param or it's required param was entered
// Dispatch action
const payload = paramName ? { [paramName]: enteredParamValue } : null;
this.props.dispatch(runCommand(command.token, payload));
}
}
@ -102,10 +122,18 @@ class FindBar extends Component {
}
}
handleChange(event) {
this.setState({
value: event.target.value,
getSuggestions() {
return this._getSuggestions(this.state.value, this.state.activeScope, this._compiledCommands);
}
// Memoized version
_getSuggestions(value, scope, commands) {
if (scope) return []; // No autocomplete for scoped input
const results = fuzzy.filter(value, commands, {
//pre: '<strong>',
//post: '</strong>',
extract: el => el.token
});
return results.slice(0, 5).map(result => result.original);
}
handleKeyDown(event) {
@ -171,6 +199,12 @@ class FindBar extends Component {
}
}
handleChange(event) {
this.setState({
value: event.target.value,
});
}
handleInputBlur() {
if (this._ignoreBlur) return;
this.setState({
@ -189,20 +223,6 @@ class FindBar extends Component {
this.setState({ isOpen: true });
}
_getSuggestions(value, scope, commands) {
if (scope) return []; // TODO: Prepare for multiple params & search suggestions
const results = fuzzy.filter(value, commands, {
//pre: '<strong>',
//post: '</strong>',
extract: el => el.token
});
return results.slice(0, 5).map(result => result.original);
}
getSuggestions() {
return this._getSuggestions(this.state.value, this.state.activeScope, this._compiledCommands);
}
highlightCommandFromMouse(index) {
this.setState({ highlightedIndex: index });
}

View File

@ -10,7 +10,8 @@ const commands = [
{ pattern: 'Create new FAQ item(:faqName as FAQ item name)' },
{ pattern: 'Add news item(:headline)' },
{ pattern: 'Add new User(:userName as User name)' },
{ pattern: 'Search(:seachTerm as what?)' },
{ pattern: 'Search(:searchTerm as what?)' },
{ pattern: 'Go to Settings' },
{ pattern: 'Find(:seachTerm as what?)' },
{ pattern: '(:searchTerm as Find...)', token:'Find' }
];