mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
Fix search date suggestion crash (#26476)
* Fix search date suggestion crash * Fix tests * Improve snapshots * Fix snapshot
This commit is contained in:
parent
1383d51436
commit
8e43d45b3f
@ -24,4 +24,4 @@ function mapStateToProps(state: GlobalState) {
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(SearchDateSuggestion);
|
||||
export default connect(mapStateToProps, null, null, {forwardRef: true})(SearchDateSuggestion);
|
||||
|
@ -15,9 +15,9 @@ import 'react-day-picker/dist/style.css';
|
||||
|
||||
type Props = SuggestionProps<never> & {
|
||||
currentDate?: Date;
|
||||
handleEscape: () => void;
|
||||
handleEscape?: () => void;
|
||||
locale: string;
|
||||
preventClose: () => void;
|
||||
preventClose?: () => void;
|
||||
}
|
||||
|
||||
export default class SearchDateSuggestion extends React.PureComponent<Props> {
|
||||
@ -36,7 +36,7 @@ export default class SearchDateSuggestion extends React.PureComponent<Props> {
|
||||
if (Keyboard.isKeyPressed(e, Constants.KeyCodes.DOWN) && document.activeElement?.id === 'searchBox') {
|
||||
this.setState({datePickerFocused: true});
|
||||
} else if (Keyboard.isKeyPressed(e, Constants.KeyCodes.ESCAPE)) {
|
||||
this.props.handleEscape();
|
||||
this.props.handleEscape?.();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -10,6 +10,7 @@ import Popover from 'components/widgets/popover';
|
||||
import Constants from 'utils/constants';
|
||||
|
||||
import type {UserProfile} from './command_provider/app_command_parser/app_command_parser_dependencies';
|
||||
import type {Props} from './suggestion_list';
|
||||
import SuggestionList from './suggestion_list';
|
||||
|
||||
interface Item extends UserProfile {
|
||||
@ -18,34 +19,6 @@ interface Item extends UserProfile {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
ariaLiveRef?: React.RefObject<HTMLDivElement>;
|
||||
inputRef?: React.RefObject<HTMLInputElement>;
|
||||
open: boolean;
|
||||
position?: 'top' | 'bottom';
|
||||
renderDividers?: string[];
|
||||
renderNoResults?: boolean;
|
||||
onCompleteWord: (term: string, matchedPretext: string, e?: React.KeyboardEventHandler<HTMLDivElement>) => boolean;
|
||||
preventClose?: () => void;
|
||||
onItemHover: (term: string) => void;
|
||||
pretext: string;
|
||||
cleared: boolean;
|
||||
matchedPretext: string[];
|
||||
items: any[];
|
||||
terms: string[];
|
||||
selection: string;
|
||||
components: Array<React.FunctionComponent<any>>;
|
||||
wrapperHeight?: number;
|
||||
|
||||
// suggestionBoxAlgn is an optional object that can be passed to align the SuggestionList with the keyboard caret
|
||||
// as the user is typing.
|
||||
suggestionBoxAlgn?: {
|
||||
lineHeight: number;
|
||||
pixelsToMoveX: number;
|
||||
pixelsToMoveY: number;
|
||||
};
|
||||
}
|
||||
|
||||
export default class SearchSuggestionList extends SuggestionList {
|
||||
popoverRef: React.RefObject<BSPopover>;
|
||||
itemsContainerRef: React.RefObject<HTMLDivElement>;
|
||||
|
@ -6,8 +6,12 @@ import React, {memo} from 'react';
|
||||
import Popover from 'components/widgets/popover';
|
||||
|
||||
type SuggestionItem = {
|
||||
date: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
type SuggestionItemProps = {
|
||||
key: string;
|
||||
ref: string;
|
||||
item: SuggestionItem;
|
||||
term: string;
|
||||
matchedPretext: string;
|
||||
@ -24,7 +28,7 @@ type Props = {
|
||||
terms: string[];
|
||||
preventClose: () => void;
|
||||
handleEscape: () => void;
|
||||
components: Array<React.ComponentType<SuggestionItem>>;
|
||||
components: Array<React.ComponentType<SuggestionItemProps>>;
|
||||
}
|
||||
|
||||
const SuggestionDate = ({
|
||||
@ -54,7 +58,6 @@ const SuggestionDate = ({
|
||||
>
|
||||
<Component
|
||||
key={term}
|
||||
ref={term}
|
||||
item={item}
|
||||
term={term}
|
||||
matchedPretext={matchedPretext[0]}
|
||||
|
@ -12,7 +12,7 @@ import LoadingSpinner from 'components/widgets/loading/loading_spinner';
|
||||
import {Constants} from 'utils/constants';
|
||||
import {isEmptyObject} from 'utils/utils';
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
ariaLiveRef?: React.RefObject<HTMLDivElement>;
|
||||
inputRef?: React.RefObject<HTMLDivElement>;
|
||||
open: boolean;
|
||||
@ -28,7 +28,7 @@ interface Props {
|
||||
items: any[];
|
||||
terms: string[];
|
||||
selection: string;
|
||||
components: Array<React.FunctionComponent<any>>;
|
||||
components: Array<React.ComponentType<any>>;
|
||||
wrapperHeight?: number;
|
||||
|
||||
// suggestionBoxAlgn is an optional object that can be passed to align the SuggestionList with the keyboard caret
|
||||
|
@ -56,7 +56,6 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
},
|
||||
}
|
||||
}
|
||||
canManageGroup={true}
|
||||
group={
|
||||
Object {
|
||||
"allow_reference": true,
|
||||
@ -79,49 +78,8 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
searchTerm=""
|
||||
showUserOverlay={[MockFunction]}
|
||||
>
|
||||
<Memo(Popover)
|
||||
actions={
|
||||
Object {
|
||||
"openModal": [MockFunction],
|
||||
"searchProfiles": [MockFunction],
|
||||
"setPopoverSearchTerm": [MockFunction] {
|
||||
"calls": Array [
|
||||
Array [
|
||||
"",
|
||||
],
|
||||
],
|
||||
"results": Array [
|
||||
Object {
|
||||
"type": "return",
|
||||
"value": undefined,
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
}
|
||||
canManageGroup={true}
|
||||
group={
|
||||
Object {
|
||||
"allow_reference": true,
|
||||
"create_at": 1,
|
||||
"delete_at": 0,
|
||||
"description": "",
|
||||
"display_name": "group_display_name",
|
||||
"has_syncables": false,
|
||||
"id": "group1",
|
||||
"member_count": 15,
|
||||
"name": "group_name",
|
||||
"remote_id": "",
|
||||
"scheme_admin": false,
|
||||
"source": "",
|
||||
"update_at": 1,
|
||||
}
|
||||
}
|
||||
hide={[MockFunction]}
|
||||
<Popover
|
||||
id="user-group-popover"
|
||||
returnFocus={[MockFunction]}
|
||||
searchTerm=""
|
||||
showUserOverlay={[MockFunction]}
|
||||
>
|
||||
<Popover
|
||||
bsClass="popover"
|
||||
@ -2126,7 +2084,7 @@ exports[`component/user_group_popover should match snapshot 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
</Popover>
|
||||
</Memo(Popover)>
|
||||
</Popover>
|
||||
</Memo(UserGroupPopover)>
|
||||
</Router>
|
||||
</BrowserRouter>
|
||||
|
@ -2,6 +2,7 @@
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import type {ReactWrapper} from 'enzyme';
|
||||
import type {ComponentProps} from 'react';
|
||||
import React from 'react';
|
||||
import {Provider} from 'react-redux';
|
||||
import {BrowserRouter} from 'react-router-dom';
|
||||
@ -100,10 +101,9 @@ describe('component/user_group_popover', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const baseProps = {
|
||||
const baseProps: ComponentProps<typeof UserGroupPopover> = {
|
||||
searchTerm: '',
|
||||
group: group1,
|
||||
canManageGroup: true,
|
||||
showUserOverlay: jest.fn(),
|
||||
hide: jest.fn(),
|
||||
returnFocus: jest.fn(),
|
||||
|
@ -64,16 +64,14 @@ export type Props = {
|
||||
};
|
||||
}
|
||||
|
||||
const UserGroupPopover = (props: Props) => {
|
||||
const {
|
||||
group,
|
||||
actions,
|
||||
hide,
|
||||
returnFocus,
|
||||
searchTerm,
|
||||
showUserOverlay,
|
||||
} = props;
|
||||
|
||||
const UserGroupPopover = ({
|
||||
actions,
|
||||
group,
|
||||
hide,
|
||||
returnFocus,
|
||||
searchTerm,
|
||||
showUserOverlay,
|
||||
}: Props) => {
|
||||
const {formatMessage} = useIntl();
|
||||
|
||||
const closeRef = useRef<HTMLButtonElement>(null);
|
||||
@ -183,7 +181,6 @@ const UserGroupPopover = (props: Props) => {
|
||||
|
||||
return (
|
||||
<Popover
|
||||
{...props}
|
||||
id='user-group-popover'
|
||||
>
|
||||
{tabCatcher}
|
||||
|
@ -19,10 +19,9 @@ interface Props {
|
||||
style?: React.CSSProperties;
|
||||
onMouseOut?: React.MouseEventHandler<BSPopover>; // didn't find a better way to satisfy typing, so for now we have a slight 'bootstrap leakage'
|
||||
onMouseOver?: React.MouseEventHandler<BSPopover>;
|
||||
ref?: React.Ref<BSPopover>;
|
||||
}
|
||||
|
||||
const Popover = ({
|
||||
const Popover = React.forwardRef<BSPopover, Props>(({
|
||||
placement = 'right',
|
||||
popoverSize = 'sm',
|
||||
children,
|
||||
@ -33,8 +32,7 @@ const Popover = ({
|
||||
onMouseOver,
|
||||
className,
|
||||
style,
|
||||
ref,
|
||||
}: Props) => {
|
||||
}, ref?) => {
|
||||
return (
|
||||
<BSPopover
|
||||
id={id}
|
||||
@ -45,13 +43,15 @@ const Popover = ({
|
||||
bsClass='popover'
|
||||
title={title}
|
||||
bsSize={popoverSize && SizeMap[popoverSize] as BSSizes} // map our sizes to bootstrap
|
||||
onMouseOut={onMouseOut!}
|
||||
onMouseOut={onMouseOut}
|
||||
onMouseOver={onMouseOver}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</BSPopover>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
Popover.displayName = 'Popover';
|
||||
|
||||
export default React.memo(Popover);
|
||||
|
Loading…
Reference in New Issue
Block a user