Extracted promise-logic and created AutocompleteAddEntryToTableField

This commit is contained in:
Philipp Czora
2018-11-15 16:58:40 +01:00
parent 639b483d92
commit 921448145a
4 changed files with 122 additions and 44 deletions

View File

@@ -1,6 +1,7 @@
// @flow
import React from "react";
import AsyncSelect from "react-select/lib/Async";
import {LabelWithHelpIcon} from "@scm-manager/ui-components";
type SelectionResult = {
id: string,
@@ -13,42 +14,39 @@ type SelectValue = {
};
type Props = {
url: string,
loadOptions: string => Promise<SelectionResult>,
valueSelected: SelectionResult => void
loadSuggestions: string => Promise<SelectionResult>,
valueSelected: SelectionResult => void,
label: string,
helpText?: string,
value?: any
};
type State = {
value: SelectionResult
};
const URL_QUERY_SUFFIX: string = "?q=";
class AsyncAutocomplete extends React.Component<Props, State> {
getOptions = (inputValue: string) => {
const { url } = this.props;
return fetch(url + URL_QUERY_SUFFIX + inputValue)
.then(response => response.json())
.then(json => {
return json.map(element => {
return { value: element, label: element.displayName };
});
});
};
handleInputChange = (newValue: SelectValue) => {
this.setState({ value: newValue.value });
return newValue.value;
this.props.valueSelected(newValue.value);
};
render() {
const { label, helpText, value } = this.props;
const stringValue = value ? value.id : "";
return (
<div className="field">
<LabelWithHelpIcon label={label} helpText={helpText} />
<div className="control">
<AsyncSelect
cacheOptions
defaultOptions
loadOptions={this.getOptions}
loadOptions={this.props.loadSuggestions}
onChange={this.handleInputChange}
value={stringValue}
/>
</div>
</div>
);
}
}

View File

@@ -0,0 +1,71 @@
//@flow
import React from "react";
import { AddButton } from "@scm-manager/ui-components";
import AsyncAutocomplete from "../../containers/AsyncAutocomplete";
type Props = {
addEntry: string => void,
disabled: boolean,
buttonLabel: string,
fieldLabel: string,
helpText?: string,
loadSuggestions: string => any //TODO: type
};
type State = {
entryToAdd: any // TODO: type
};
class AutocompleteAddEntryToTableField extends React.Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
entryToAdd: undefined
};
}
render() {
const { disabled, buttonLabel, fieldLabel, helpText } = this.props;
const { entryToAdd } = this.state;
return (
<div className="field">
<AsyncAutocomplete
label={fieldLabel}
loadSuggestions={this.props.loadSuggestions}
valueSelected={this.handleAddEntryChange}
helpText={helpText}
value={entryToAdd ? entryToAdd.id : ""}
/>
<AddButton
label={buttonLabel}
action={this.addButtonClicked}
disabled={disabled}
/>
</div>
);
}
addButtonClicked = (event: Event) => {
event.preventDefault();
this.appendEntry();
};
appendEntry = () => {
const { entryToAdd } = this.state;
this.props.addEntry(entryToAdd.id);
this.setState({ ...this.state, entryToAdd: undefined });
};
handleAddEntryChange = (selection: any) => {
this.setState({
...this.state,
entryToAdd: selection
});
};
}
export default AutocompleteAddEntryToTableField;

View File

@@ -1,22 +1,19 @@
//@flow
import React from "react";
import {translate} from "react-i18next";
import {
InputField,
SubmitButton,
Textarea,
AddEntryToTableField
} from "@scm-manager/ui-components";
import {InputField, SubmitButton, Textarea} from "@scm-manager/ui-components";
import type {Group} from "@scm-manager/ui-types";
import * as validator from "./groupValidation";
import MemberNameTable from "./MemberNameTable";
import AutocompleteAddEntryToTableField from "./AutocompleteAddEntryToTableField";
type Props = {
t: string => string,
submitForm: Group => void,
loading?: boolean,
group?: Group
group?: Group,
loadUserSuggestions: string => any
};
type State = {
@@ -100,12 +97,14 @@ class GroupForm extends React.Component<Props, State> {
members={this.state.group.members}
memberListChanged={this.memberListChanged}
/>
<AddEntryToTableField
<AutocompleteAddEntryToTableField
addEntry={this.addMember}
disabled={false}
buttonLabel={t("add-member-button.label")}
fieldLabel={t("add-member-textfield.label")}
errorMessage={t("add-member-textfield.error")}
loadSuggestions={this.props.loadUserSuggestions}
/>
<SubmitButton
disabled={!this.isValid()}

View File

@@ -2,12 +2,7 @@
import React from "react";
import {connect} from "react-redux";
import GroupForm from "../components/GroupForm";
import {
modifyGroup,
modifyGroupReset,
isModifyGroupPending,
getModifyGroupFailure
} from "../modules/groups";
import {getModifyGroupFailure, isModifyGroupPending, modifyGroup, modifyGroupReset} from "../modules/groups";
import type {History} from "history";
import {withRouter} from "react-router-dom";
import type {Group} from "@scm-manager/ui-types";
@@ -37,6 +32,20 @@ class EditGroup extends React.Component<Props> {
this.props.modifyGroup(group, this.groupModified(group));
};
loadUserAutocompletion = (inputValue: string) => {
const url = "http://localhost:8081/scm/api/v2/autocomplete/users?q=";
return fetch(url + inputValue)
.then(response => response.json())
.then(json => {
return json.map(element => {
return {
value: element,
label: `${element.displayName} (${element.id})`
};
});
});
};
render() {
const { group, loading, error } = this.props;
return (
@@ -48,6 +57,7 @@ class EditGroup extends React.Component<Props> {
this.modifyGroup(group);
}}
loading={loading}
loadUserSuggestions={this.loadUserAutocompletion}
/>
</div>
);