Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion licenses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5094,7 +5094,7 @@ license_category: binary
module: web-console
license_name: Apache License version 2.0
copyright: Imply Data
version: 0.22.15
version: 0.22.20

---

Expand Down
3 changes: 3 additions & 0 deletions web-console/lib/keywords.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ exports.SQL_KEYWORDS = [
'FULL',
'CROSS',
'USING',
'NATURAL',
'FETCH',
'FIRST',
'NEXT',
Expand All @@ -67,6 +68,8 @@ exports.SQL_KEYWORDS = [
'RANGE',
'PRECEDING',
'FOLLOWING',
'CURRENT',
'UNBOUNDED',
'EXTEND',
'PIVOT',
'UNPIVOT',
Expand Down
14 changes: 7 additions & 7 deletions web-console/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web-console/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"@blueprintjs/icons": "^4.16.0",
"@blueprintjs/popover2": "^1.14.9",
"@blueprintjs/select": "^4.9.24",
"@druid-toolkit/query": "^0.22.15",
"@druid-toolkit/query": "^0.22.20",
"@druid-toolkit/visuals-core": "^0.3.3",
"@druid-toolkit/visuals-react": "^0.3.3",
"ace-builds": "~1.4.14",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,9 @@ export const RecordTablePane = React.memo(function RecordTablePane(props: Record
})}
/>
)}
{showValue && <ShowValueDialog onClose={() => setShowValue(undefined)} str={showValue} />}
{showValue && (
<ShowValueDialog onClose={() => setShowValue(undefined)} str={showValue} size="large" />
)}
</div>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,102 @@ exports[`EditContextDialog matches snapshot 1`] = `
</span>
</button>
</div>
<textarea
class="bp4-input"
<div
class=" ace_editor ace_hidpi ace-solarized-dark ace_dark query-string"
id="ace-editor"
style="width: 100%; height: 100%; font-size: 12px;"
>
{

}
</textarea>
<textarea
autocapitalize="off"
autocorrect="off"
class="ace_text-input"
spellcheck="false"
style="opacity: 0; font-size: 1px;"
wrap="off"
/>
<div
aria-hidden="true"
class="ace_gutter"
>
<div
class="ace_layer ace_gutter-layer ace_folding-enabled"
style="height: 1000000px;"
/>
</div>
<div
class="ace_scroller"
style="line-height: 0px;"
>
<div
class="ace_content"
>
<div
class="ace_layer ace_print-margin-layer"
>
<div
class="ace_print-margin"
style="left: 4px; visibility: hidden;"
/>
</div>
<div
class="ace_layer ace_marker-layer"
/>
<div
class="ace_layer ace_text-layer"
style="height: 1000000px; margin: 0px 4px;"
/>
<div
class="ace_layer ace_marker-layer"
/>
<div
class="ace_layer ace_cursor-layer ace_hidden-cursors"
>
<div
class="ace_cursor"
/>
</div>
</div>
</div>
<div
class="ace_scrollbar ace_scrollbar-v"
style="display: none; width: 20px;"
>
<div
class="ace_scrollbar-inner"
style="width: 20px;"
>

</div>
</div>
<div
class="ace_scrollbar ace_scrollbar-h"
style="display: none; height: 20px;"
>
<div
class="ace_scrollbar-inner"
style="height: 20px;"
>

</div>
</div>
<div
style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: hidden;"
>
<div
style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
/>
<div
style="height: auto; width: auto; top: 0px; left: 0px; visibility: hidden; position: absolute; white-space: pre; overflow: visible;"
>
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
</div>
</div>
</div>
<div
class="bp4-dialog-footer-actions"
class="bp4-dialog-footer"
>
<div
class="edit-context-dialog-buttons"
class="bp4-dialog-footer-actions"
>
<button
class="bp4-button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,6 @@

.edit-context-dialog {
&.#{$bp-ns}-dialog {
padding-bottom: 10px;
}

.#{$bp-ns}-input {
margin: 10px;
height: 400px;
}

.#{$bp-ns}-dialog-footer-actions {
padding: 0px 10px 0px 10px;
display: grid;
grid-template-columns: 340px 1fr;
grid-template-areas: 'error buttons';
}

.edit-context-dialog-error {
grid-area: error;
}
.edit-context-dialog-buttons {
grid-area: buttons;
height: 60vh;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ import { EditContextDialog } from './edit-context-dialog';
describe('EditContextDialog', () => {
it('matches snapshot', () => {
const compactionDialog = (
<EditContextDialog queryContext={{}} onQueryContextChange={() => null} onClose={() => {}} />
<EditContextDialog
initQueryContext={{}}
onQueryContextChange={() => null}
onClose={() => {}}
/>
);
render(compactionDialog);
expect(document.body.lastChild).toMatchSnapshot();
Expand Down
102 changes: 44 additions & 58 deletions web-console/src/dialogs/edit-context-dialog/edit-context-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,86 +16,72 @@
* limitations under the License.
*/

import { Button, Callout, Classes, Dialog, Intent, TextArea } from '@blueprintjs/core';
import { Button, Classes, Dialog, Intent } from '@blueprintjs/core';
import Hjson from 'hjson';
import * as JSONBig from 'json-bigint-native';
import React, { useState } from 'react';
import AceEditor from 'react-ace';

import type { QueryContext } from '../../druid-models';
import { AppToaster } from '../../singletons';

import './edit-context-dialog.scss';

export interface EditContextDialogProps {
queryContext: QueryContext;
onQueryContextChange: (queryContext: QueryContext) => void;
onClose: () => void;
function formatContext(context: QueryContext | undefined): string {
const str = JSONBig.stringify(context || {}, undefined, 2);
return str === '{}' ? '{\n\n}' : str;
}

export interface EditContextDialogState {
queryContextString: string;
queryContext?: QueryContext;
error?: string;
export interface EditContextDialogProps {
initQueryContext: QueryContext | undefined;
onQueryContextChange(queryContext: QueryContext): void;
onClose(): void;
}

export const EditContextDialog = React.memo(function EditContextDialog(
props: EditContextDialogProps,
) {
const { onQueryContextChange, onClose } = props;
const [state, setState] = useState<EditContextDialogState>(() => ({
queryContext: props.queryContext,
queryContextString: Object.keys(props.queryContext).length
? JSONBig.stringify(props.queryContext, undefined, 2)
: '{\n\n}',
}));

const { queryContext, queryContextString, error } = state;

function handleTextChange(e: any) {
const queryContextString = (e.target as HTMLInputElement).value;

let error: string | undefined;
let queryContext: QueryContext | undefined;
try {
queryContext = Hjson.parse(queryContextString);
} catch (e) {
error = e.message;
}

if (!error && (!queryContext || typeof queryContext !== 'object')) {
error = 'Input is not a valid object';
queryContext = undefined;
}

setState({
queryContextString,
queryContext,
error,
});
}
const { initQueryContext, onQueryContextChange, onClose } = props;
const [queryContextString, setQueryContextString] = useState<string>(
formatContext(initQueryContext),
);

return (
<Dialog className="edit-context-dialog" isOpen onClose={onClose} title="Edit query context">
<TextArea value={queryContextString} onChange={handleTextChange} autoFocus />
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
{error && (
<Callout intent={Intent.DANGER} className="edit-context-dialog-error">
{error}
</Callout>
)}
<div className="edit-context-dialog-buttons">
<AceEditor
mode="hjson"
theme="solarized_dark"
className="query-string"
name="ace-editor"
fontSize={12}
width="100%"
height="100%"
showGutter
showPrintMargin={false}
value={queryContextString}
onChange={v => setQueryContextString(v)}
/>
<div className={Classes.DIALOG_FOOTER}>
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button text="Close" onClick={onClose} />
<Button
text="Save"
intent={Intent.PRIMARY}
disabled={Boolean(error)}
onClick={
queryContext
? () => {
onQueryContextChange(queryContext);
onClose();
}
: undefined
}
onClick={() => {
let queryContext: QueryContext;
try {
queryContext = Hjson.parse(queryContextString);
} catch (e) {
AppToaster.show({
message: e.message,
intent: Intent.DANGER,
});
return;
}

onQueryContextChange(queryContext);
onClose();
}}
/>
</div>
</div>
Expand Down
Loading