"Fossies" - the Fresh Open Source Software Archive

Member "graylog2-server-4.0.6/graylog2-web-interface/src/views/components/common/ActionDropdown.jsx" (7 Apr 2021, 3975 Bytes) of package /linux/misc/graylog2-server-4.0.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) JSX source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "ActionDropdown.jsx": 3.3.8_vs_4.0.0.

    1 /*
    2  * Copyright (C) 2020 Graylog, Inc.
    3  *
    4  * This program is free software: you can redistribute it and/or modify
    5  * it under the terms of the Server Side Public License, version 1,
    6  * as published by MongoDB, Inc.
    7  *
    8  * This program is distributed in the hope that it will be useful,
    9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   11  * Server Side Public License for more details.
   12  *
   13  * You should have received a copy of the Server Side Public License
   14  * along with this program. If not, see
   15  * <http://www.mongodb.com/licensing/server-side-public-license>.
   16  */
   17 // @flow strict
   18 import * as React from 'react';
   19 import PropTypes from 'prop-types';
   20 import { Overlay } from 'react-overlays';
   21 
   22 import { DropdownMenu, MenuItem } from 'components/graylog';
   23 
   24 import StopPropagation from './StopPropagation';
   25 
   26 /**
   27  * This implements a custom toggle for a dropdown menu.
   28  * See: "Custom Dropdown Components" in react-bootstrap documentation.
   29  */
   30 
   31 type ActionToggleProps = {
   32   children: React.Node,
   33   onClick: (SyntheticInputEvent<HTMLButtonElement>) => void,
   34 };
   35 
   36 type ActionDropdownState = {
   37   show: boolean,
   38 };
   39 
   40 type FilterPropsProps = {
   41   children: React.Node,
   42   style?: { [string]: any },
   43 };
   44 
   45 type ActionDropdownProps = {
   46   children: React.Node,
   47   container?: HTMLElement,
   48   element: React.Node,
   49 };
   50 
   51 const ActionToggle = ({ children, onClick }: ActionToggleProps) => {
   52   const handleClick = (e) => {
   53     e.preventDefault();
   54     e.stopPropagation();
   55 
   56     onClick(e);
   57   };
   58 
   59   const handleKeyDown = (e) => {
   60     if (e.keyCode === 32) {
   61       e.preventDefault();
   62       e.stopPropagation();
   63 
   64       onClick(e);
   65     }
   66   };
   67 
   68   return (
   69     <span onClick={handleClick} onKeyDown={handleKeyDown} role="presentation">
   70       {children}
   71     </span>
   72   );
   73 };
   74 
   75 ActionToggle.propTypes = {
   76   children: PropTypes.node.isRequired,
   77   onClick: PropTypes.func,
   78 };
   79 
   80 ActionToggle.defaultProps = {
   81   onClick: () => {},
   82 };
   83 
   84 const FilterProps = ({ children, style }: FilterPropsProps) => React.Children.map(
   85   children,
   86   (child) => React.cloneElement(child, { style: { ...style, ...child.props.style } }),
   87 );
   88 
   89 class ActionDropdown extends React.Component<ActionDropdownProps, ActionDropdownState> {
   90   target: ?HTMLElement;
   91 
   92   static defaultProps = {
   93     container: undefined,
   94   };
   95 
   96   constructor(props: ActionDropdownProps) {
   97     super(props);
   98 
   99     this.state = {
  100       show: false,
  101     };
  102   }
  103 
  104   _onToggle = (e: SyntheticInputEvent<HTMLButtonElement>) => {
  105     e.preventDefault();
  106     e.stopPropagation();
  107     this.setState(({ show }) => ({ show: !show }));
  108   };
  109 
  110   render() {
  111     const { children, container, element } = this.props;
  112     const { show } = this.state;
  113 
  114     const mappedChildren = React.Children.map(
  115       children,
  116       (child) => child && React.cloneElement(child, {
  117         ...child.props,
  118         ...(child.props.onSelect ? {
  119           onSelect: (eventKey, event) => {
  120             child.props.onSelect();
  121             this._onToggle(event);
  122           },
  123         } : {}),
  124       }),
  125     );
  126 
  127     return (
  128       <StopPropagation>
  129         <ActionToggle bsRole="toggle" onClick={this._onToggle}>
  130           <span ref={(elem) => { this.target = elem; }}>{element}</span>
  131         </ActionToggle>
  132         <Overlay show={show}
  133                  container={container}
  134                  placement="bottom"
  135                  shouldUpdatePosition
  136                  rootClose
  137                  onHide={this._onToggle}
  138                  target={() => this.target}>
  139           <FilterProps>
  140             <DropdownMenu show={show}>
  141               <MenuItem header>Actions</MenuItem>
  142               {mappedChildren}
  143             </DropdownMenu>
  144           </FilterProps>
  145         </Overlay>
  146       </StopPropagation>
  147     );
  148   }
  149 }
  150 
  151 ActionDropdown.propTypes = {
  152   children: PropTypes.node.isRequired,
  153   container: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
  154   element: PropTypes.node.isRequired,
  155 };
  156 
  157 export default ActionDropdown;