fix autocompletion

This commit is contained in:
Florian Scholdei
2019-06-12 09:47:13 +02:00
parent bfd22aa507
commit 303e7f1e50
10 changed files with 235 additions and 130 deletions

View File

@@ -4,7 +4,6 @@ import { AsyncCreatable, Async } from "react-select";
import type { AutocompleteObject, SelectValue } from "@scm-manager/ui-types";
import LabelWithHelpIcon from "./forms/LabelWithHelpIcon";
type Props = {
loadSuggestions: string => Promise<AutocompleteObject>,
valueSelected: SelectValue => void,
@@ -17,12 +16,9 @@ type Props = {
creatable?: boolean
};
type State = {};
class Autocomplete extends React.Component<Props, State> {
static defaultProps = {
placeholder: "Type here",
loadingMessage: "Loading...",
@@ -34,7 +30,11 @@ class Autocomplete extends React.Component<Props, State> {
};
// We overwrite this to avoid running into a bug (https://github.com/JedWatson/react-select/issues/2944)
isValidNewOption = (inputValue: string, selectValue: SelectValue, selectOptions: SelectValue[]) => {
isValidNewOption = (
inputValue: string,
selectValue: SelectValue,
selectOptions: SelectValue[]
) => {
const isNotDuplicated = !selectOptions
.map(option => option.label)
.includes(inputValue);
@@ -43,12 +43,21 @@ class Autocomplete extends React.Component<Props, State> {
};
render() {
const { label, helpText, value, placeholder, loadingMessage, noOptionsMessage, loadSuggestions, creatable } = this.props;
const {
label,
helpText,
value,
placeholder,
loadingMessage,
noOptionsMessage,
loadSuggestions,
creatable
} = this.props;
return (
<div className="field">
<LabelWithHelpIcon label={label} helpText={helpText} />
<div className="control">
{creatable?
{creatable ? (
<AsyncCreatable
cacheOptions
loadOptions={loadSuggestions}
@@ -65,7 +74,7 @@ class Autocomplete extends React.Component<Props, State> {
});
}}
/>
:
) : (
<Async
cacheOptions
loadOptions={loadSuggestions}
@@ -75,13 +84,11 @@ class Autocomplete extends React.Component<Props, State> {
loadingMessage={() => loadingMessage}
noOptionsMessage={() => noOptionsMessage}
/>
}
)}
</div>
</div>
);
}
}
export default Autocomplete;

View File

@@ -0,0 +1,37 @@
// @flow
import React from "react";
import { translate } from "react-i18next";
import type { SelectValue } from "@scm-manager/ui-types";
import UserGroupAutocomplete from "./UserGroupAutocomplete";
type Props = {
groupAutocompleteLink: string,
valueSelected: SelectValue => void,
value?: SelectValue,
// Context props
t: string => string
};
class GroupAutocomplete extends React.Component<Props> {
selectName = (selection: SelectValue) => {
this.props.valueSelected(selection);
};
render() {
const { groupAutocompleteLink, t, value } = this.props;
return (
<UserGroupAutocomplete
autocompleteLink={groupAutocompleteLink}
label={t("autocomplete.group")}
noOptionsMessage={t("autocomplete.noGroupOptions")}
loadingMessage={t("autocomplete.loading")}
placeholder={t("autocomplete.groupPlaceholder")}
valueSelected={this.selectName}
value={value}
/>
);
}
}
export default translate("commons")(GroupAutocomplete);

View File

@@ -0,0 +1,37 @@
// @flow
import React from "react";
import { translate } from "react-i18next";
import type { SelectValue } from "@scm-manager/ui-types";
import UserGroupAutocomplete from "./UserGroupAutocomplete";
type Props = {
userAutocompleteLink: string,
valueSelected: SelectValue => void,
value?: SelectValue,
// Context props
t: string => string
};
class UserAutocomplete extends React.Component<Props> {
selectName = (selection: SelectValue) => {
this.props.valueSelected(selection);
};
render() {
const { userAutocompleteLink, t, value } = this.props;
return (
<UserGroupAutocomplete
autocompleteLink={userAutocompleteLink}
label={t("autocomplete.user")}
noOptionsMessage={t("autocomplete.noUserOptions")}
loadingMessage={t("autocomplete.loading")}
placeholder={t("autocomplete.userPlaceholder")}
valueSelected={this.selectName}
value={value}
/>
);
}
}
export default translate("commons")(UserAutocomplete);

View File

@@ -0,0 +1,57 @@
// @flow
import React from "react";
import type { SelectValue } from "@scm-manager/ui-types";
import Autocomplete from "./Autocomplete";
type Props = {
autocompleteLink: string,
label: string,
noOptionsMessage: string,
loadingMessage: string,
placeholder: string,
valueSelected: SelectValue => void,
value?: SelectValue
};
class UserGroupAutocomplete extends React.Component<Props> {
loadSuggestions = (inputValue: string) => {
const url = this.props.autocompleteLink;
const link = url + "?q=";
return fetch(link + inputValue)
.then(response => response.json())
.then(json => {
return json.map(element => {
const label = element.displayName
? `${element.displayName} (${element.id})`
: element.id;
return {
value: element,
label
};
});
});
};
selectName = (selection: SelectValue) => {
this.props.valueSelected(selection);
};
render() {
const { autocompleteLink, label, noOptionsMessage, loadingMessage, placeholder, value } = this.props;
return (
<Autocomplete
autocompleteLink={autocompleteLink}
label={label}
noOptionsMessage={noOptionsMessage}
loadingMessage={loadingMessage}
placeholder={placeholder}
loadSuggestions={this.loadSuggestions}
valueSelected={this.selectName}
value={value}
creatable={true}
/>
); // {...this.props}
}
}
export default UserGroupAutocomplete;