fix(popovers): Refactor popover to controlled component (#18524)

* fix(popovers): Refactor popover to controlled component

* fix(labels): Test popover closing
pull/18561/head
Deniz Kusefoglu 2020-06-16 19:41:12 -07:00 committed by GitHub
parent 5c4f5cacdc
commit cdcba3566b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 79 additions and 16 deletions

View File

@ -296,7 +296,7 @@ describe('Dashboards', () => {
})
})
it('typing a new label name and pressing ENTER starts label creation flow', () => {
it('typing a new label name and pressing ENTER starts label creation flow, closes popover', () => {
const labelName = 'choco'
cy.get('@org').then(() => {
@ -304,10 +304,39 @@ describe('Dashboards', () => {
.first()
.click()
cy.getByTestID('inline-labels--popover--contents').should(
'be.visible'
)
cy.getByTestID(`inline-labels--popover-field`)
.type(labelName)
.type('{enter}')
cy.getByTestID('overlay--body').should('be.visible')
cy.getByTestID('inline-labels--popover--contents').should(
'not.be.visible'
)
})
})
it('typing a new label name and clicking name starts label creation flow, closes popover', () => {
// https://github.com/influxdata/influxdb/issues/17964
const labelName = 'the new new'
cy.get('@org').then(() => {
cy.getByTestID(`inline-labels--add`)
.first()
.click()
cy.getByTestID('inline-labels--popover--contents').should(
'be.visible'
)
cy.getByTestID(`inline-labels--popover-field`).type(labelName)
cy.getByTestID(`inline-labels--create-new`).click()
cy.getByTestID('overlay--body').should('be.visible')
cy.getByTestID('inline-labels--popover--contents').should(
'not.be.visible'
)
})
})

View File

@ -42,6 +42,7 @@ interface Props {
onInputChange: (e: ChangeEvent<HTMLInputElement>) => void
filteredLabels: Label[]
onAddLabel: (labelID: string) => void
visible: boolean
}
@ErrorHandling
@ -57,6 +58,7 @@ export default class InlineLabelPopover extends PureComponent<Props> {
onUpdateSelectedItemID,
onInputChange,
filteredLabels,
visible,
} = this.props
return (
@ -65,8 +67,9 @@ export default class InlineLabelPopover extends PureComponent<Props> {
position={PopoverPosition.Below}
triggerRef={triggerRef}
distanceFromTrigger={8}
showEvent={PopoverInteraction.Click}
hideEvent={PopoverInteraction.Click}
visible={visible}
showEvent={PopoverInteraction.None}
hideEvent={PopoverInteraction.None}
testID="inline-labels--popover"
className="inline-labels--popover"
contents={() => (

View File

@ -9,6 +9,7 @@ import {
ButtonShape,
ButtonBaseRef,
ComponentColor,
ClickOutside,
} from '@influxdata/clockface'
import InlineLabelPopover from 'src/shared/components/inlineLabels/InlineLabelPopover'
import CreateLabelOverlay from 'src/labels/components/CreateLabelOverlay'
@ -53,6 +54,7 @@ interface State {
searchTerm: string
selectedItemID: string
isCreatingLabel: OverlayState
isPopoverVisible: boolean
}
@ErrorHandling
@ -66,9 +68,14 @@ class InlineLabelsEditor extends Component<Props, State> {
selectedItemID: null,
searchTerm: '',
isCreatingLabel: OverlayState.Closed,
isPopoverVisible: false,
}
}
public componentDidMount() {
this.handleAddPopoverEventListener()
}
public render() {
const {isCreatingLabel, searchTerm} = this.state
@ -101,23 +108,26 @@ class InlineLabelsEditor extends Component<Props, State> {
private get popover(): JSX.Element {
const {labels, selectedLabels} = this.props
const {searchTerm, selectedItemID} = this.state
const {searchTerm, selectedItemID, isPopoverVisible} = this.state
const labelsUsed =
labels.length > 0 && labels.length === selectedLabels.length
return (
<InlineLabelPopover
searchTerm={searchTerm}
triggerRef={this.popoverTrigger}
selectedItemID={selectedItemID}
onUpdateSelectedItemID={this.handleUpdateSelectedItemID}
allLabelsUsed={labelsUsed}
onStartCreatingLabel={this.handleStartCreatingLabel}
onInputChange={this.handleInputChange}
filteredLabels={this.filterLabels(searchTerm)}
onAddLabel={this.handleAddLabel}
/>
<ClickOutside onClickOutside={this.onClickOutside}>
<InlineLabelPopover
searchTerm={searchTerm}
triggerRef={this.popoverTrigger}
selectedItemID={selectedItemID}
onUpdateSelectedItemID={this.handleUpdateSelectedItemID}
allLabelsUsed={labelsUsed}
onStartCreatingLabel={this.handleStartCreatingLabel}
onInputChange={this.handleInputChange}
filteredLabels={this.filterLabels(searchTerm)}
onAddLabel={this.handleAddLabel}
visible={isPopoverVisible}
/>
</ClickOutside>
)
}
@ -145,6 +155,27 @@ class InlineLabelsEditor extends Component<Props, State> {
)
}
private handleAddPopoverEventListener = (): void => {
if (!this.popoverTrigger.current) {
return
}
this.popoverTrigger.current.addEventListener('click', () => {
this.setState({
isPopoverVisible: true,
})
})
}
private onClickOutside = (e: MouseEvent): void => {
if (e.target === this.popoverTrigger.current) {
return
}
this.setState({
isPopoverVisible: false,
})
}
private handleAddLabel = async (labelID: string) => {
const {onAddLabel, labels} = this.props
@ -243,7 +274,7 @@ class InlineLabelsEditor extends Component<Props, State> {
}
private handleStartCreatingLabel = (): void => {
this.setState({isCreatingLabel: OverlayState.Open})
this.setState({isCreatingLabel: OverlayState.Open, isPopoverVisible: false})
}
private handleStopCreatingLabel = (): void => {