<commit_before>import { MenuItem } from '@reach/menu-button';
import CopyIcon from 'mdi-react/ContentCopyIcon';
import UnsavedIcon from 'mdi-react/ContentSaveEditIcon';
import SaveIcon from 'mdi-react/ContentSaveIcon';
import DatabaseIcon from 'mdi-react/DatabaseIcon';
import DotsVerticalIcon from 'mdi-react/DotsVerticalIcon';
import FormatIcon from 'mdi-react/FormatAlignLeftIcon';
import NewIcon from 'mdi-react/PlusIcon';
import TagsIcon from 'mdi-react/TagMultipleIcon';
import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { Redirect } from 'react-router-dom';
import { connect } from 'unistore/react';
import Button from '../../common/Button';
import Drawer from '../../common/Drawer';
import IconButton from '../../common/IconButton';
import IconMenu from '../../common/IconMenu';
import Input from '../../common/Input';
import ConfigurationForm from '../../configuration/ConfigurationForm';
import ConnectionListDrawer from '../../connections/ConnectionListDrawer';
import {
  formatQuery,
  handleCloneClick,
  resetNewQuery,
  runQuery,
  saveQuery,
  setQueryState
} from '../../stores/queries';
import { toggleSchema } from '../../stores/schema';
import UserList from '../../users/UserList';
import fetchJson from '../../utilities/fetch-json.js';
import ConnectionDropDown from '../ConnectionDropdown';
import AboutModal from './AboutModal';
import ChartButton from './ChartButton';
import QueryListButton from './QueryListButton';
import QueryTagsModal from './QueryTagsModal';

const growSpacerStyle = { flexShrink: 0, flexGrow: 1, width: 8 };
const spacerStyle = { flexShrink: 0, width: 8 };

function Spacer({ grow }) {
  if (grow) {
    return <div style={growSpacerStyle} />;
  }
  return <div style={spacerStyle} />;
}

function mapStateToProps(state) {
  return {
    currentUser: state.currentUser,
    isRunning: state.isRunning,
    isSaving: state.isSaving,
    queryId: state.query && state.query._id,
    queryName: state.query && state.query.name,
    showValidation: state.showValidation,
    unsavedChanges: state.unsavedChanges
  };
}

const ConnectedEditorNavBar = connect(
  mapStateToProps,
  store => ({
    toggleSchema,
    formatQuery,
    runQuery: runQuery(store),
    saveQuery: saveQuery(store),
    handleCloneClick,
    resetNewQuery,
    setQueryState
  })
)(React.memo(Toolbar));

function Toolbar({
  currentUser,
  formatQuery,
  handleCloneClick,
  isRunning,
  isSaving,
  queryId,
  queryName,
  resetNewQuery,
  runQuery,
  saveQuery,
  setQueryState,
  showValidation,
  toggleSchema,
  unsavedChanges
}) {
  const [showTags, setShowTags] = useState(false);
  const [showConfig, setShowConfig] = useState(false);
  const [showUsers, setShowUsers] = useState(false);
  const [redirectToSignIn, setRedirectToSignIn] = useState(false);
  const [showAbout, setShowAbout] = useState(false);
  const [showConnections, setShowConnections] = useState(false);

  const error = showValidation && !queryName.length;
  const cloneDisabled = !queryId;

  const isAdmin = currentUser.role === 'admin';

  if (redirectToSignIn) {
    return <Redirect push to="/signin" />;
  }

  return (
    <div
      style={{
        width: '100%',
        backgroundColor: 'rgba(0, 0, 0, 0.04)',
        padding: 6,
        borderBottom: '1px solid rgb(204, 204, 204)'
      }}
    >
      <div style={{ display: 'flex' }}>
        <QueryListButton />

        <IconButton
          to="/queries/new"
          tooltip="New query"
          onClick={() => resetNewQuery()}
        >
          <NewIcon />
        </IconButton>

        <Spacer grow />

        <IconButton tooltip="Toggle schema" onClick={toggleSchema}>
          <DatabaseIcon />
        </IconButton>

        <ConnectionDropDown />

        <Spacer />

        <Input
          error={error}
          style={{ width: 260 }}
          placeholder="Query name"
          value={queryName}
          onChange={e => setQueryState('name', e.target.value)}
        />

        <Spacer />

        <IconButton tooltip="Tags" onClick={() => setShowTags(true)}>
          <TagsIcon />
        </IconButton>

        <QueryTagsModal visible={showTags} onClose={() => setShowTags(false)} />

        <IconButton
          tooltip="Clone"
          onClick={handleCloneClick}
          disabled={cloneDisabled}
        >
          <CopyIcon />
        </IconButton>

        <IconButton tooltip="Format" onClick={formatQuery}>
          <FormatIcon />
        </IconButton>

        <IconButton
          tooltip="Save"
          onClick={() => saveQuery()}
          disabled={isSaving}
        >
          {unsavedChanges ? <UnsavedIcon /> : <SaveIcon />}
        </IconButton>

        <Spacer />

        <Button type="primary" onClick={() => runQuery()} disabled={isRunning}>
          Run
        </Button>

        <Spacer />

        <ChartButton />

        <Spacer grow />

        <IconMenu icon={<DotsVerticalIcon aria-label="menu" />}>
          {isAdmin && (
            <MenuItem onSelect={() => setShowConfig(true)}>
              Configuration
            </MenuItem>
          )}
          {isAdmin && (
            <MenuItem onSelect={() => setShowConnections(true)}>
              Connections
            </MenuItem>
          )}
          {isAdmin && (
            <MenuItem onSelect={() => setShowUsers(true)}>Users</MenuItem>
          )}
          <div style={{ borderBottom: '1px solid #ddd' }} />
          <MenuItem onSelect={() => setShowAbout(true)}>About</MenuItem>
          <div style={{ borderBottom: '1px solid #ddd' }} />
          <MenuItem
            onSelect={async () => {
              await fetchJson('GET', '/api/signout');
              setRedirectToSignIn(true);
            }}
          >
            Sign out
          </MenuItem>
        </IconMenu>

        <Drawer
          title={'Configuration'}
          visible={showConfig}
          width={600}
          onClose={() => setShowConfig(false)}
          placement={'right'}<commit_msg>Fix app menu for non-admin users<commit_after>import { MenuItem } from '@reach/menu-button';
import CopyIcon from 'mdi-react/ContentCopyIcon';
import UnsavedIcon from 'mdi-react/ContentSaveEditIcon';
import SaveIcon from 'mdi-react/ContentSaveIcon';
import DatabaseIcon from 'mdi-react/DatabaseIcon';
import DotsVerticalIcon from 'mdi-react/DotsVerticalIcon';
import FormatIcon from 'mdi-react/FormatAlignLeftIcon';
import NewIcon from 'mdi-react/PlusIcon';
import TagsIcon from 'mdi-react/TagMultipleIcon';
import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { Redirect } from 'react-router-dom';
import { connect } from 'unistore/react';
import Button from '../../common/Button';
import Drawer from '../../common/Drawer';
import IconButton from '../../common/IconButton';
import IconMenu from '../../common/IconMenu';
import Input from '../../common/Input';
import ConfigurationForm from '../../configuration/ConfigurationForm';
import ConnectionListDrawer from '../../connections/ConnectionListDrawer';
import {
  formatQuery,
  handleCloneClick,
  resetNewQuery,
  runQuery,
  saveQuery,
  setQueryState
} from '../../stores/queries';
import { toggleSchema } from '../../stores/schema';
import UserList from '../../users/UserList';
import fetchJson from '../../utilities/fetch-json.js';
import ConnectionDropDown from '../ConnectionDropdown';
import AboutModal from './AboutModal';
import ChartButton from './ChartButton';
import QueryListButton from './QueryListButton';
import QueryTagsModal from './QueryTagsModal';

const growSpacerStyle = { flexShrink: 0, flexGrow: 1, width: 8 };
const spacerStyle = { flexShrink: 0, width: 8 };

function Spacer({ grow }) {
  if (grow) {
    return <div style={growSpacerStyle} />;
  }
  return <div style={spacerStyle} />;
}

function mapStateToProps(state) {
  return {
    currentUser: state.currentUser,
    isRunning: state.isRunning,
    isSaving: state.isSaving,
    queryId: state.query && state.query._id,
    queryName: state.query && state.query.name,
    showValidation: state.showValidation,
    unsavedChanges: state.unsavedChanges
  };
}

const ConnectedEditorNavBar = connect(
  mapStateToProps,
  store => ({
    toggleSchema,
    formatQuery,
    runQuery: runQuery(store),
    saveQuery: saveQuery(store),
    handleCloneClick,
    resetNewQuery,
    setQueryState
  })
)(React.memo(Toolbar));

function Toolbar({
  currentUser,
  formatQuery,
  handleCloneClick,
  isRunning,
  isSaving,
  queryId,
  queryName,
  resetNewQuery,
  runQuery,
  saveQuery,
  setQueryState,
  showValidation,
  toggleSchema,
  unsavedChanges
}) {
  const [showTags, setShowTags] = useState(false);
  const [showConfig, setShowConfig] = useState(false);
  const [showUsers, setShowUsers] = useState(false);
  const [redirectToSignIn, setRedirectToSignIn] = useState(false);
  const [showAbout, setShowAbout] = useState(false);
  const [showConnections, setShowConnections] = useState(false);

  const error = showValidation && !queryName.length;
  const cloneDisabled = !queryId;

  const isAdmin = currentUser.role === 'admin';

  if (redirectToSignIn) {
    return <Redirect push to="/signin" />;
  }

  // Reach UI menu / IconMenu does not like the {someBoolean && <element/>} patterm
  // As a workaround optional MenuItems are managed in an array
  let menuItems = [];
  if (isAdmin) {
    menuItems = [
      <MenuItem key="config" onSelect={() => setShowConfig(true)}>
        Configuration
      </MenuItem>,
      <MenuItem key="connections" onSelect={() => setShowConnections(true)}>
        Connections
      </MenuItem>,
      <MenuItem
        key="users"
        style={{ borderBottom: '1px solid #ddd' }}
        onSelect={() => setShowUsers(true)}
      >
        Users
      </MenuItem>
    ];
  }

  return (
    <div
      style={{
        width: '100%',
        backgroundColor: 'rgba(0, 0, 0, 0.04)',
        padding: 6,
        borderBottom: '1px solid rgb(204, 204, 204)'
      }}
    >
      <div style={{ display: 'flex' }}>
        <QueryListButton />

        <IconButton
          to="/queries/new"
          tooltip="New query"
          onClick={() => resetNewQuery()}
        >
          <NewIcon />
        </IconButton>

        <Spacer grow />

        <IconButton tooltip="Toggle schema" onClick={toggleSchema}>
          <DatabaseIcon />
        </IconButton>

        <ConnectionDropDown />

        <Spacer />

        <Input
          error={error}
          style={{ width: 260 }}
          placeholder="Query name"
          value={queryName}
          onChange={e => setQueryState('name', e.target.value)}
        />

        <Spacer />

        <IconButton tooltip="Tags" onClick={() => setShowTags(true)}>
          <TagsIcon />
        </IconButton>

        <QueryTagsModal visible={showTags} onClose={() => setShowTags(false)} />

        <IconButton
          tooltip="Clone"
          onClick={handleCloneClick}
          disabled={cloneDisabled}
        >
          <CopyIcon />
        </IconButton>

        <IconButton tooltip="Format" onClick={formatQuery}>
          <FormatIcon />
        </IconButton>

        <IconButton
          tooltip="Save"
          onClick={() => saveQuery()}
          disabled={isSaving}
        >
          {unsavedChanges ? <UnsavedIcon /> : <SaveIcon />}
        </IconButton>

        <Spacer />

        <Button type="primary" onClick={() => runQuery()} disabled={isRunning}>
          Run
        </Button>

        <Spacer />

        <ChartButton />

        <Spacer grow />

        <IconMenu icon={<DotsVerticalIcon aria-label="menu" />}>
          {menuItems}
          <MenuItem
            style={{ borderBottom: '1px solid #ddd' }}
            onSelect={() => setShowAbout(true)}
          >
            About
          </MenuItem>
          <MenuItem
            onSelect={async () => {
              await fetchJson('GET', '/api/signout');
              setRedirectToSignIn(true);
            }}
          >
            Sign out
          </MenuItem>
        </IconMenu>

        <Drawer
          title={'Configuration'}
          visible={showConfig}
          width={600}
          onClose={() => setShowConfig(false)}
          placement={'right'}
{'fraction_non_alphanumeric': 0.1373222167729279, 'fraction_numerical': 0.005394801373222168, 'mean_word_length': 2.5848227365953704, 'pattern_counts': {'":': 0, '<': 108, '<?xml version=': 0, '>': 132, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6634085', 'n_tokens_mistral': 3531, 'n_tokens_neox': 3516, 'n_words': 801}