Skip to content

Commit

Permalink
Merge pull request #1514 from BlueBrain/migration/fix/line-editing
Browse files Browse the repository at this point in the history
Migration/fix Query Editor line jumping
  • Loading branch information
danburonline authored Mar 7, 2024
2 parents 9e13658 + c21f3ab commit fc55b66
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 66 deletions.
13 changes: 11 additions & 2 deletions src/shared/components/ResourceEditor/ResourceEditor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,21 @@ button.cancel {
}
}

.ant-card.ant-card-bordered.results {
margin-top: 2rem !important;
}

.ant-form-item {
margin-bottom: 0;
}

.control-panel {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #f0efef;
padding: 1rem;
height: 52px;
padding: 0.75rem;
height: 56px;
}

._positive {
Expand Down
21 changes: 11 additions & 10 deletions src/subapps/admin/components/Projects/QueryEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
import { useEffect, useState } from 'react';
import { Tabs } from 'antd';
import { useHistory, useRouteMatch } from 'react-router';
import {
DEFAULT_ELASTIC_SEARCH_VIEW_ID,
DEFAULT_SPARQL_VIEW_ID,
} from '@bbp/nexus-sdk/es';
import { useNexusContext } from '@bbp/react-nexus';
import SparqlQueryView from '../../views/SparqlQueryView';
import ElasticSearchQueryView from '../../views/ElasticSearchQueryView';
import useNotification from '../../../../shared/hooks/useNotification';
import { Tabs } from 'antd';
import { FC, useEffect, useState } from 'react';
import { useHistory, useRouteMatch } from 'react-router';
import { useOrganisationsSubappContext } from '../..';
import useNotification from '../../../../shared/hooks/useNotification';
import ElasticSearchQueryView from '../../views/ElasticSearchQueryView';
import SparqlQueryView from '../../views/SparqlQueryView';
import './QueryEditor.scss';

const QueryEditor: React.FC<{
const QueryEditor: FC<{
orgLabel: string;
projectLabel: string;
onUpdate: () => void;
}> = ({ orgLabel, projectLabel }) => {
const subapp = useOrganisationsSubappContext();
const subApp = useOrganisationsSubappContext();
const history = useHistory();
const match = useRouteMatch<{
orgLabel: string;
Expand Down Expand Up @@ -52,7 +52,7 @@ const QueryEditor: React.FC<{
setLoading(false);
history.replace(
`/${
subapp.namespace
subApp.namespace
}/${orgLabel}/${projectLabel}/query/${encodeURIComponent(
DEFAULT_SPARQL_VIEW_ID
)}`
Expand All @@ -63,6 +63,7 @@ const QueryEditor: React.FC<{
if (loading) {
return null;
}

return (
<div className="query-editor">
<div className="query-editor__header">
Expand All @@ -78,7 +79,7 @@ const QueryEditor: React.FC<{
setActiveKey(tab);
history.replace(
`/${
subapp.namespace
subApp.namespace
}/${orgLabel}/${projectLabel}/query/${encodeURIComponent(
tab === 'sparql'
? DEFAULT_SPARQL_VIEW_ID
Expand Down
79 changes: 35 additions & 44 deletions src/subapps/admin/components/ViewForm/ElasticSearchQueryForm.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,30 @@
import { useEffect, useRef, useState } from 'react';
import { Form, Button, Card, List, Empty } from 'antd';
import {
CheckCircleOutlined,
ExclamationCircleOutlined,
} from '@ant-design/icons';
import ReactJson from 'react-json-view';
import { ElasticSearchViewQueryResponse } from '@bbp/nexus-sdk/es';
import { Button, Card, Empty, Form, List } from 'antd';
import * as codemirror from 'codemirror';
import { UnControlled as CodeMirror } from 'react-codemirror2';
import 'codemirror/addon/display/placeholder';
import 'codemirror/mode/javascript/javascript';
import { FC, MutableRefObject, useEffect, useRef, useState } from 'react';
import { UnControlled as CodeMirror } from 'react-codemirror2';
import ReactJson from 'react-json-view';

import './view-form.scss';

const FormItem = Form.Item;
const ListItem = List.Item;
/**
* This is tricky because error can be KG error OR an ElasticSearch Error.
*
* In the case of ES, the reason message is nested within an error object
*/
// Can be KG error or an ElasticSearch Error
// In the case of ES, the reason message is nested within an error object
export type NexusESError = {
reason?: string;
error?: {
reason?: string;
};
};

// TODO this needs to be broken into Input, Result, and Form components.
const ElasticSearchQueryForm: React.FunctionComponent<{
const ElasticSearchQueryForm: FC<{
query: object;
response?: ElasticSearchViewQueryResponse<any> | null;
busy: boolean;
Expand All @@ -39,28 +35,23 @@ const ElasticSearchQueryForm: React.FunctionComponent<{
onQueryChange: (query: object) => void;
onChangePageSize: (size: number) => void;
}> = ({
query,
response,
busy,
error,
from,
size,
onPaginationChange,
query,
error,
response,
onQueryChange,
onChangePageSize,
onPaginationChange,
}): JSX.Element => {
const [initialQuery, setInitialQuery] = useState('');
const [_initialQuery, setInitialQuery] = useState('');
const [editorValue, setEditorValue] = useState('');
const [valid, setValid] = useState(true);
const [value, setValue] = useState<string>();
const [pageSize, setPageSize] = useState<number>(size);
const editor = useRef<codemirror.Editor>();
const wrapper = useRef(null);

useEffect(() => {
// only on first render!
const formattedInitialQuery = JSON.stringify(query, null, 2);
setInitialQuery(formattedInitialQuery);
}, []);
const wrapper = useRef(null);
const editor = useRef<codemirror.Editor>();

const data =
response && response.hits.hits.map(result => result._source || []);
Expand All @@ -69,10 +60,15 @@ const ElasticSearchQueryForm: React.FunctionComponent<{
const totalPages = Math.ceil(total / size);
const current = Math.floor((totalPages / total) * from + 1);

useEffect(() => {
const formattedInitialQuery = JSON.stringify(query, null, 2);
setEditorValue(formattedInitialQuery);
}, [query]);

const handleChange = (_: any, __: any, value: string) => {
setEditorValue(value);
try {
JSON.parse(value);
setValue(value);
setValid(true);
} catch (error) {
setValid(false);
Expand All @@ -88,25 +84,25 @@ const ElasticSearchQueryForm: React.FunctionComponent<{
<div className="view-form">
<Form
onFinish={() => {
value && onQueryChange(JSON.parse(value));
editorValue && onQueryChange(JSON.parse(editorValue));
}}
layout="vertical"
>
<>
<div className="control-panel">
<div>
<div className={`feedback ${valid ? '_positive' : '_negative'}`}>
{valid ? (
<CheckCircleOutlined />
) : (
<ExclamationCircleOutlined />
)}{' '}
{valid ? 'Valid JSON' : 'Invalid JSON'}
</div>
<div className={`feedback ${valid ? '_positive' : '_negative'}`}>
{valid ? <CheckCircleOutlined /> : <ExclamationCircleOutlined />}{' '}
{valid ? 'Valid JSON' : 'Invalid JSON'}
</div>
<FormItem>
<Button type="primary" htmlType="submit" disabled={!valid}>
Execute ElasticSearch query
</Button>
</FormItem>
</div>
<CodeMirror
value={initialQuery}
autoCursor={false}
value={editorValue}
options={{
mode: { name: 'javascript', json: true },
theme: 'base16-light',
Expand All @@ -115,12 +111,12 @@ const ElasticSearchQueryForm: React.FunctionComponent<{
}}
onChange={handleChange}
editorDidMount={editorElement => {
(editor as React.MutableRefObject<
(editor as MutableRefObject<
codemirror.Editor
>).current = editorElement;
}}
editorWillUnmount={() => {
const editorWrapper = (editor as React.MutableRefObject<
const editorWrapper = (editor as MutableRefObject<
CodeMirror.Editor
>).current.getWrapperElement();
if (editor) editorWrapper.remove();
Expand All @@ -130,11 +126,6 @@ const ElasticSearchQueryForm: React.FunctionComponent<{
}}
/>
</>
<FormItem>
<Button type="primary" htmlType="submit" disabled={!valid}>
Execute ElasticSearch query
</Button>
</FormItem>
</Form>
<Card bordered className="results">
{error && (
Expand Down Expand Up @@ -169,8 +160,8 @@ const ElasticSearchQueryForm: React.FunctionComponent<{
<ListItem>
{(result && (
<ReactJson
collapsed
src={result}
collapsed
name={null}
enableClipboard={false}
displayObjectSize={false}
Expand Down
12 changes: 6 additions & 6 deletions src/subapps/admin/components/ViewForm/SparqlQueryInput.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, { useRef } from 'react';
import * as codemirror from 'codemirror';
import { UnControlled as UnControlledCodeMirror } from 'react-codemirror2';
import 'codemirror/mode/javascript/javascript';
import 'codemirror/addon/display/autorefresh';
import 'codemirror/addon/display/placeholder';
import 'codemirror/lib/codemirror.css';
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/sparql/sparql';
import 'codemirror/theme/base16-light.css';
import 'codemirror/lib/codemirror.css';
import { FC, useRef } from 'react';
import { UnControlled as UnControlledCodeMirror } from 'react-codemirror2';
import './SparqlQueryInput.scss';

const SparqlQueryInput: React.FunctionComponent<{
const SparqlQueryInput: FC<{
value?: string;
onChange?: (query: string) => void;
}> = ({ value = '', onChange }) => {
Expand All @@ -25,8 +25,8 @@ const SparqlQueryInput: React.FunctionComponent<{
<div className="code">
<UnControlledCodeMirror
ref={wrapper}
autoCursor={false}
value={value}
autoCursor={true}
autoScroll={true}
options={{
mode: { name: 'sparql' },
Expand Down
2 changes: 1 addition & 1 deletion src/subapps/admin/components/ViewForm/view-form.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
margin: 0 auto;
}
.code {
margin-bottom: $default-pad;
max-height: 600;
overflow: 'scroll';
margin-bottom: $default-pad;
}
.ant-card-body {
overflow: scroll;
Expand Down
6 changes: 3 additions & 3 deletions src/subapps/admin/containers/ElasticSearchQuery.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { useState, FC } from 'react';
import { useNexusContext } from '@bbp/react-nexus';
import {
DEFAULT_ELASTIC_SEARCH_VIEW_ID,
ElasticSearchViewQueryResponse,
} from '@bbp/nexus-sdk/es';
import { useNexusContext } from '@bbp/react-nexus';
import { FC, useState } from 'react';

import { useQuery } from 'react-query';
import ElasticSearchQueryForm, {
NexusESError,
} from '../components/ViewForm/ElasticSearchQueryForm';
import { useQuery } from 'react-query';

const DEFAULT_PAGE_SIZE = 5;
const DEFAULT_QUERY = {
Expand Down

0 comments on commit fc55b66

Please sign in to comment.