Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EPMRPP-87316 || Implement functionality to add Assignee and Milestone… #3644

Merged
merged 5 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
top: 100%;
display: none;
width: 100%;
max-width: 405px;
Vadim73i marked this conversation as resolved.
Show resolved Hide resolved
border-radius: 3px;
margin-top: 4px;
font-family: $FONT-ROBOTO-MEDIUM;
Expand All @@ -32,4 +33,8 @@
&.opened {
display: block;
}

@media (max-width: $SCREEN_XS_MAX) {
max-width: 100%;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,43 @@ export const AutocompleteOption = ({
isNew,
disabled,
variant,
hideSelected,
...props
}) => {
return isNew ? (
<>
<div className={cx('divider')} />
let option;
if (isNew) {
option = (
<>
<div className={cx('divider')} />
<li
className={cx('new-item', variant, { active: isActive, selected: isSelected, disabled })}
{...props}
>
<span className={cx('value')}>{children}</span>
<Button
{...(!disabled ? props : {})}
customClassName={cx({ 'button-active': isActive })}
startIcon={PlusIcon}
variant={'text'}
>
{variant === 'key-variant' ? 'New key' : 'New value'}
</Button>
</li>
</>
);
} else if (isSelected && hideSelected) {
option = null;
} else {
option = (
<li
className={cx('new-item', variant, { active: isActive, selected: isSelected, disabled })}
{...props}
className={cx('item', variant, { active: isActive, selected: isSelected, disabled })}
{...(!disabled ? props : {})}
>
<span className={cx('value')}>{children}</span>
<Button
{...(!disabled ? props : {})}
customClassName={cx({ 'button-active': isActive })}
startIcon={PlusIcon}
variant={'text'}
>
{variant === 'key-variant' ? 'New key' : 'New value'}
</Button>
<span className={cx('label', 'tag')}>{children}</span>
</li>
</>
) : (
<li
className={cx('item', variant, { active: isActive, selected: isSelected, disabled })}
{...(!disabled ? props : {})}
>
<span className={cx('label', 'tag')}>{children}</span>
</li>
);
);
}
return option;
};

AutocompleteOption.propTypes = {
Expand All @@ -67,6 +76,7 @@ AutocompleteOption.propTypes = {
children: PropTypes.node,
disabled: PropTypes.bool,
variant: PropTypes.string,
hideSelected: PropTypes.bool,
};

AutocompleteOption.defaultProps = {
Expand All @@ -76,4 +86,5 @@ AutocompleteOption.defaultProps = {
children: null,
disabled: false,
variant: '',
hideSelected: false,
};
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const MultipleAutocomplete = ({
handleUnStoredItemCb,
dataAutomationId,
existingItemsMap,
hideSelected,
Vadim73i marked this conversation as resolved.
Show resolved Hide resolved
...props
}) => {
let updatePosition;
Expand All @@ -72,6 +73,7 @@ export const MultipleAutocomplete = ({
index,
isActive: highlightedIndex === index,
isSelected: selectedItems.some((selectedItem) => isEqual(selectedItem, item)),
hideSelected,
...rest,
});
const removeItemByBackspace = ({ event, removeItem, inputValue }) => {
Expand Down Expand Up @@ -266,6 +268,7 @@ MultipleAutocomplete.propTypes = {
existingItemsMap: PropTypes.shape({
value: PropTypes.bool,
}),
hideSelected: PropTypes.bool,
};

MultipleAutocomplete.defaultProps = {
Expand Down Expand Up @@ -297,4 +300,5 @@ MultipleAutocomplete.defaultProps = {
handleUnStoredItemCb: null,
dataAutomationId: '',
existingItemsMap: {},
hideSelected: false,
};
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@
@include hover-state($COLOR--e-300);
@include focus-state($COLOR--topaz-focused);

&.disabled {
background-color: $COLOR--bg-100;
}

&.error.touched {
@include error-state($COLOR--red-failed-2);
}
Expand Down Expand Up @@ -88,6 +92,7 @@
color: $COLOR--almost-black;
box-sizing: border-box;
outline: none;
background-color: transparent;

&::placeholder {
font-family: inherit;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export class SingleAutocomplete extends Component {
icon: PropTypes.string,
isOptionUnique: PropTypes.func,
refFunction: PropTypes.func,
creatable: PropTypes.bool,
};

static defaultProps = {
Expand Down Expand Up @@ -78,6 +79,7 @@ export class SingleAutocomplete extends Component {
icon: null,
isOptionUnique: null,
refFunction: () => {},
creatable: false,
};

getOptionProps = (getItemProps, highlightedIndex, selectedItem) => ({ item, index, ...rest }) =>
Expand Down Expand Up @@ -119,6 +121,7 @@ export class SingleAutocomplete extends Component {
options,
isOptionUnique,
refFunction,
creatable,
...props
} = this.props;
return (
Expand Down Expand Up @@ -167,10 +170,12 @@ export class SingleAutocomplete extends Component {
selectItem(newValue);
}

if (createWithoutConfirmation) {
if (createWithoutConfirmation && (creatable || newValue === '')) {
Vadim73i marked this conversation as resolved.
Show resolved Hide resolved
selectItem(newValue);
}
onBlur(e);

(creatable || newValue === '') && onBlur(e);
Vadim73i marked this conversation as resolved.
Show resolved Hide resolved

isOptionUnique &&
isOptionUnique(newValue ? !options.find((v) => v === newValue) : null);
setTouch(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ export const WithAsyncLoading = (AutocompleteComponent) =>
class WrappedAutocomplete extends Component {
static propTypes = {
getURI: PropTypes.func,
getRequestParams: PropTypes.func,
makeOptions: PropTypes.func,
filterOption: PropTypes.func,
minLength: PropTypes.number,
};

static defaultProps = {
getURI: () => '',
getRequestParams: () => {},
makeOptions: (values) => values,
filterOption: () => true,
minLength: 1,
Expand All @@ -47,16 +49,21 @@ export const WithAsyncLoading = (AutocompleteComponent) =>
}

debouncedFetch = debounce((inputValue) => {
const { getURI, makeOptions, filterOption } = this.props;
const { getURI, getRequestParams, makeOptions, filterOption } = this.props;

if (this.cancelToken) {
this.cancelToken();
}

const value = (inputValue || '').trim();
const uri = getURI(value);
const requestParams = getRequestParams(value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I can see, If getRequestParams is not provided, the result of this function invocation will be undefined.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the scope of #3670


fetch(uri, {
abort: (cancelToken) => {
this.cancelToken = cancelToken;
},
...requestParams,
AmsterGet marked this conversation as resolved.
Show resolved Hide resolved
})
.then((response) => {
this.cancelToken = null;
Expand Down
2 changes: 2 additions & 0 deletions app/src/components/fields/dynamicFieldsSection/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const TEXT_TYPE = 'text';
export const ARRAY_TYPE = 'array';
export const DROPDOWN_TYPE = 'dropdown';
export const DATE_TYPE = 'date';
export const AUTOCOMPLETE_TYPE = 'autocomplete';
export const MULTIPLE_AUTOCOMPLETE_TYPE = 'multiAutocomplete';

export const VALUE_NAME_KEY = 'valueName';
export const VALUE_ID_KEY = 'valueId';
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,28 @@
* limitations under the License.
*/

import { ArrayField, DateField, DropdownField, TextField } from './fields';
import { ARRAY_TYPE, DATE_TYPE, DROPDOWN_TYPE, TEXT_TYPE } from './constants';
import {
ArrayField,
AutocompleteField,
DateField,
DropdownField,
MultipleAutocompleteField,
TextField,
} from './fields';
import {
ARRAY_TYPE,
AUTOCOMPLETE_TYPE,
DATE_TYPE,
DROPDOWN_TYPE,
MULTIPLE_AUTOCOMPLETE_TYPE,
TEXT_TYPE,
} from './constants';

export const FIELDS_MAP = {
[TEXT_TYPE]: TextField,
[DROPDOWN_TYPE]: DropdownField,
[DATE_TYPE]: DateField,
[ARRAY_TYPE]: ArrayField,
[AUTOCOMPLETE_TYPE]: AutocompleteField,
[MULTIPLE_AUTOCOMPLETE_TYPE]: MultipleAutocompleteField,
};
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export class DynamicFieldsSection extends Component {
darkView: PropTypes.bool,
children: PropTypes.node,
modalView: PropTypes.bool,
pluginName: PropTypes.string,
integrationId: PropTypes.number,
};

static defaultProps = {
Expand All @@ -49,6 +51,8 @@ export class DynamicFieldsSection extends Component {
darkView: false,
children: null,
modalView: false,
pluginName: '',
integrationId: undefined,
};

getCustomBlockConfig = (field) => {
Expand All @@ -67,6 +71,8 @@ export class DynamicFieldsSection extends Component {
defaultOptionValueKey,
darkView,
modalView,
pluginName,
integrationId,
} = this.props;

return fields.map((field) => {
Expand All @@ -82,6 +88,8 @@ export class DynamicFieldsSection extends Component {
defaultOptionValueKey={defaultOptionValueKey}
modalView={modalView}
darkView={darkView}
pluginName={pluginName}
integrationId={integrationId}
/>
);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React from 'react';
import PropTypes from 'prop-types';
import { AsyncAutocomplete } from 'componentLibrary/autocompletes/asyncAutocomplete';
import { connect } from 'react-redux';
import { projectInfoSelector } from 'controllers/project';
import { URLS } from 'common/urls';
import { DynamicField } from '../dynamicField';

const AutocompleteFieldComponent = ({
field,
darkView,
modalView,
integrationId,
projectName,
...rest
}) => {
const getUri = () =>
URLS.projectIntegrationByIdCommand(projectName, integrationId, field.commandName);

const getRequestParams = (term) => ({ method: 'PUT', data: { term } });

const parseValueToString = (user) => (user ? user.name : '');

return (
<DynamicField field={field} darkView={darkView} modalView={modalView} {...rest}>
<AsyncAutocomplete
getURI={getUri}
getRequestParams={getRequestParams}
parseValueToString={parseValueToString}
createWithoutConfirmation
onBlur={() => {}}
Vadim73i marked this conversation as resolved.
Show resolved Hide resolved
/>
</DynamicField>
);
};
AutocompleteFieldComponent.propTypes = {
field: PropTypes.object.isRequired,
defaultOptionValueKey: PropTypes.string.isRequired,
darkView: PropTypes.bool,
modalView: PropTypes.bool,
projectName: PropTypes.number,
integrationId: PropTypes.number,
};
AutocompleteFieldComponent.defaultProps = {
darkView: false,
modalView: false,
integrationId: undefined,
};
export const AutocompleteField = connect((state) => ({
projectName: projectInfoSelector(state).projectName,
}))(AutocompleteFieldComponent);
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ export { TextField } from './textField';
export { DateField } from './dateField';
export { DropdownField } from './dropdownField';
export { ArrayField } from './arrayField';
export { AutocompleteField } from './autocompleteField';
export { MultipleAutocompleteField } from './multipleAutocompleteField';
Loading
Loading