| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import React, { useEffect, useState } from 'react'; |
| import { useDispatch } from 'react-redux'; |
| import uuid from 'react-uuid'; |
| import PropTypes from 'prop-types'; |
| import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
| import { faTimesCircle, faToggleOff, faToggleOn } from '@fortawesome/free-solid-svg-icons'; |
| import store from '../../../app/store'; |
| import AlertContainers from '../../alert/containers/AlertContainers'; |
| import CodeMirror from '../../editor/containers/CodeMirrorWapperContainer'; |
| import SideBarToggle from '../../editor/containers/SideBarMenuToggleContainer'; |
| import { setting } from '../../../conf/config'; |
| import IconPlay from '../../../icons/IconPlay'; |
| import { getMetaData } from '../../../features/database/MetadataSlice'; |
| |
| const Editor = ({ |
| setCommand, |
| activeRequests, |
| command, |
| update, |
| addFrame, |
| trimFrame, |
| addAlert, |
| alertList, |
| isActive, |
| database, |
| executeCypherQuery, |
| addCommandHistory, |
| toggleMenu, |
| setLabel, |
| isLabel, |
| // addCommandFavorites, |
| }) => { |
| const dispatch = useDispatch(); |
| const [alerts, setAlerts] = useState([]); |
| const [activePromises, setPromises] = useState({}); |
| |
| // const favoritesCommand = () => { |
| // dispatch(() => addCommandFavorites(command)); |
| // }; |
| |
| const clearCommand = () => { |
| setCommand(''); |
| }; |
| |
| const onClick = () => { |
| const refKey = uuid(); |
| if (command.toUpperCase().startsWith(':PLAY')) { |
| dispatch(() => addFrame(command, 'Contents', refKey)); |
| } else if (command.toUpperCase().startsWith(':CSV')) { |
| dispatch(() => addFrame(command, 'CSV', refKey)); |
| } else if (command.toUpperCase() === ':SERVER STATUS') { |
| dispatch(() => trimFrame('ServerStatus')); |
| dispatch(() => addFrame(command, 'ServerStatus', refKey)); |
| } else if (database.status === 'disconnected' && command.toUpperCase() === ':SERVER DISCONNECT') { |
| dispatch(() => trimFrame('ServerDisconnect')); |
| dispatch(() => trimFrame('ServerConnect')); |
| dispatch(() => addAlert('ErrorNoDatabaseConnected')); |
| dispatch(() => addFrame(command, 'ServerDisconnect', refKey)); |
| } else if (database.status === 'disconnected' && command.toUpperCase() === ':SERVER CONNECT') { |
| if (!setting.closeWhenDisconnect) { |
| dispatch(() => trimFrame('ServerConnect')); |
| dispatch(() => addFrame(':server connect', 'ServerConnect')); |
| } |
| } else if (database.status === 'disconnected') { |
| dispatch(() => trimFrame('ServerConnect')); |
| dispatch(() => addAlert('ErrorNoDatabaseConnected')); |
| dispatch(() => addFrame(command, 'ServerConnect', refKey)); |
| } else if (database.status === 'connected' && command.toUpperCase() === ':SERVER DISCONNECT') { |
| dispatch(() => trimFrame('ServerDisconnect')); |
| dispatch(() => addAlert('NoticeServerDisconnected')); |
| dispatch(() => addFrame(command, 'ServerDisconnect', refKey)); |
| } else if (database.status === 'connected' && command.toUpperCase() === ':SERVER CONNECT') { |
| if (!setting.connectionStatusSkip) { |
| dispatch(() => trimFrame('ServerStatus')); |
| dispatch(() => addAlert('NoticeAlreadyConnected')); |
| dispatch(() => addFrame(command, 'ServerStatus', refKey)); |
| } |
| } else if (database.status === 'connected') { |
| addFrame(command, 'CypherResultFrame', refKey); |
| const req = dispatch(() => executeCypherQuery([refKey, command])); |
| req.then((response) => { |
| if (response.type === 'cypher/executeCypherQuery/rejected') { |
| if (response.error.name !== 'AbortError') { |
| dispatch(() => addAlert('ErrorCypherQuery')); |
| const currentCommand = store.getState().editor.command; |
| if (currentCommand === '') { |
| setCommand(command); |
| } |
| } |
| return; |
| } |
| if (update) dispatch(getMetaData()); |
| }); |
| activePromises[refKey] = req; |
| setPromises({ ...activePromises }); |
| } |
| dispatch(() => addCommandHistory(command)); |
| clearCommand(); |
| }; |
| |
| useEffect(() => { |
| const reqCancel = Object.keys(activePromises).filter((ref) => !activeRequests.includes(ref)); |
| reqCancel.forEach((ref) => { |
| activePromises[ref].abort(); |
| delete activePromises[ref]; |
| }); |
| setPromises({ ...activePromises }); |
| }, [activeRequests]); |
| |
| useEffect(() => { |
| setAlerts( |
| alertList.map((alert) => ( |
| <AlertContainers |
| key={alert.alertProps.key} |
| alertKey={alert.alertProps.key} |
| alertName={alert.alertName} |
| errorMessage={alert.alertProps.errorMessage} |
| /> |
| )), |
| ); |
| }, [alertList]); |
| |
| return ( |
| <div className="container-fluid"> |
| <div className="editor"> |
| <div className="container-fluid editor-area card-header"> |
| <div className="input-group input-style"> |
| |
| <div id="codeMirrorEditor" className="form-control col-11 editor-code-wrapper"> |
| <CodeMirror |
| onClick={onClick} |
| value={command} |
| onChange={setCommand} |
| /> |
| </div> |
| <div className="input-group-append ml-auto editor-button-wrapper" id="editor-buttons"> |
| {/* <button className="frame-head-button btn btn-link" |
| type="button" onClick={() => favoritesCommand()}> |
| <FontAwesomeIcon |
| icon={faStar} |
| size="lg" |
| /> |
| </button> */} |
| <button className={command ? 'btn show-eraser' : 'btn hide-eraser'} type="button" id="eraser" onDoubleClick={() => clearCommand()} aria-label="Clear Command"> |
| <FontAwesomeIcon |
| icon={faTimesCircle} |
| size="1x" |
| /> |
| </button> |
| <button |
| className="frame-head-button btn btn-link" |
| type="button" |
| onClick={() => onClick()} |
| title="Run Query" |
| aria-label="Run Query" |
| > |
| <IconPlay /> |
| </button> |
| <button |
| className="frame-head-button btn btn-link" |
| type="button" |
| onClick={() => { |
| toggleMenu('home'); |
| /* |
| if (!isActive) { |
| document.getElementById('wrapper')?.classList?.remove('wrapper'); |
| document.getElementById('wrapper')?.classList?.add('wrapper-extension-padding'); |
| } else { |
| document.getElementById('wrapper')? |
| .classList?.remove('wrapper-extension-padding'); |
| document.getElementById('wrapper')?.classList?.add('wrapper'); |
| } */ |
| }} |
| title={(isActive) ? 'Hide' : 'Show'} |
| aria-label="toggleMenu" |
| > |
| <SideBarToggle isActive={isActive} /> |
| </button> |
| <button |
| className="frame-head-button btn btn-link" |
| type="button" |
| onClick={() => setLabel()} |
| title="Run Query" |
| aria-label="Run Query" |
| > |
| <FontAwesomeIcon |
| icon={isLabel ? faToggleOn : faToggleOff} |
| size="2x" |
| /> |
| </button> |
| </div> |
| </div> |
| </div> |
| </div> |
| {alerts} |
| </div> |
| ); |
| }; |
| |
| Editor.propTypes = { |
| setCommand: PropTypes.func.isRequired, |
| activeRequests: PropTypes.arrayOf(PropTypes.string).isRequired, |
| command: PropTypes.string.isRequired, |
| addFrame: PropTypes.func.isRequired, |
| trimFrame: PropTypes.func.isRequired, |
| addAlert: PropTypes.func.isRequired, |
| alertList: PropTypes.arrayOf(PropTypes.shape({ |
| alertName: PropTypes.string.isRequired, |
| alertProps: PropTypes.shape({ |
| key: PropTypes.string.isRequired, |
| alertType: PropTypes.string.isRequired, |
| errorMessage: PropTypes.string.isRequired, |
| }), |
| })).isRequired, |
| isActive: PropTypes.bool.isRequired, |
| database: PropTypes.shape({ |
| status: PropTypes.string.isRequired, |
| host: PropTypes.string.isRequired, |
| }).isRequired, |
| executeCypherQuery: PropTypes.func.isRequired, |
| addCommandHistory: PropTypes.func.isRequired, |
| toggleMenu: PropTypes.func.isRequired, |
| update: PropTypes.bool.isRequired, |
| setLabel: PropTypes.func.isRequired, |
| isLabel: PropTypes.bool.isRequired, |
| // addCommandFavorites: PropTypes.func.isRequired, |
| }; |
| |
| export default Editor; |