Skip to content

Commit

Permalink
All panels autocomplete (#250)
Browse files Browse the repository at this point in the history
  • Loading branch information
eatonphil committed May 22, 2022
1 parent 1f3a63a commit 192d701
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 45 deletions.
5 changes: 4 additions & 1 deletion ui/Updates.tsx
Expand Up @@ -2,9 +2,12 @@ import * as React from 'react';
import { SITE_ROOT, VERSION } from '../shared/constants';
import { request } from '../shared/http';
import log from '../shared/log';
import { newId } from '../shared/object';
import { ContentTypeInfo } from '../shared/state';
import { SettingsContext } from './Settings';

const s = newId();

export function Updates() {
const { state: settings } = React.useContext(SettingsContext);
const [updates, setUpdates] = React.useState(null);
Expand All @@ -15,7 +18,7 @@ export function Updates() {
const updates = await request(
window.fetch,
'GET',
`${SITE_ROOT}/api/updates?version=${VERSION}&i=${settings.id}`,
`${SITE_ROOT}/api/updates?version=${VERSION}&i=${settings.id}&s=${s}`,
new ContentTypeInfo(),
[],
'',
Expand Down
21 changes: 14 additions & 7 deletions ui/components/CodeEditor.tsx
Expand Up @@ -44,6 +44,14 @@ export function skipWhitespaceForward(it: Ace.TokenIterator) {
}
}

const AUTOCOMPLETE_MAP: Record<
string,
(
tokenIteratorFactory: () => Ace.TokenIterator,
prefix: string
) => Array<Ace.Completion>
> = {};

export function CodeEditor({
value,
onChange,
Expand Down Expand Up @@ -78,6 +86,10 @@ export function CodeEditor({
state: { theme, autocompleteDisabled },
} = React.useContext(SettingsContext);

if (autocomplete) {
AUTOCOMPLETE_MAP[id] = autocomplete;
}

const [editorRef, setEditorRef] = React.useState<AceEditor>(null);
const debounced = useDebouncedCallback(onChange, INPUT_SYNC_PERIOD);
// Flush on unmount
Expand Down Expand Up @@ -136,15 +148,10 @@ export function CodeEditor({
prefix: string,
callback: Ace.CompleterCallback
) => {
// This gets registered globally which is kind of weird. //
// So it needs to check again that the currently editing editor
// is the one attached to this callback.
if (!autocomplete || (editorRef.editor as unknown) !== editor) {
return callback(null, []);
}

// This gets set/called in a global context so we need to figure out which panel is actually calling it.
try {
const factory = () => new TokenIterator(session, pos.row, pos.column);
const autocomplete = AUTOCOMPLETE_MAP[(editor as any).container.id];
return callback(null, autocomplete(factory, prefix));
} catch (e) {
log.error(e);
Expand Down
37 changes: 13 additions & 24 deletions ui/panels/DatabasePanel.tsx
@@ -1,4 +1,3 @@
import { Ace } from 'ace-builds';
import * as React from 'react';
import { DOCS_ROOT } from '../../shared/constants';
import { NoConnectorError } from '../../shared/errors';
Expand All @@ -7,7 +6,6 @@ import {
ConnectorInfo,
DatabaseConnectorInfo,
DatabasePanelInfo,
PanelInfo,
TimeSeriesRange as TimeSeriesRangeT,
} from '../../shared/state';
import { panelRPC } from '../asyncRPC';
Expand All @@ -20,12 +18,7 @@ import { TimeSeriesRange } from '../components/TimeSeriesRange';
import { Toggle } from '../components/Toggle';
import { VENDORS } from '../connectors';
import { ProjectContext } from '../state';
import {
builtinCompletions,
dotAccessPanelShapeCompletions,
panelNameCompletions,
stringPanelShapeCompletions,
} from './ProgramPanel';
import { BUILTINS, makeAutocomplete } from './ProgramPanel';
import { PanelBodyProps, PanelDetailsProps, PanelUIDetails } from './types';

export async function evalDatabasePanel(
Expand Down Expand Up @@ -270,9 +263,20 @@ export function DatabasePanelBody({
panels,
keyboardShortcuts,
}: PanelBodyProps<DatabasePanelInfo>) {
const { connectors } = React.useContext(ProjectContext).state;
const connector = connectors.find(
(c) => c.id === panel.database.connectorId
) as DatabaseConnectorInfo;

const vendor = VENDORS[connector?.database.type]?.id;

return (
<CodeEditor
autocomplete={makeAutocomplete(panels.filter((p) => p.id !== panel.id))}
autocomplete={makeAutocomplete(
panels.filter((p) => p.id !== panel.id),
vendor === 'sqlite' ? BUILTINS.sql : [],
'sql'
)}
id={'editor-' + panel.id}
onKeyDown={keyboardShortcuts}
value={panel.content}
Expand All @@ -286,21 +290,6 @@ export function DatabasePanelBody({
);
}

export function makeAutocomplete(panels: Array<PanelInfo>) {
return (tokenIteratorFactory: () => Ace.TokenIterator, prefix: string) => {
return [
...builtinCompletions(tokenIteratorFactory).filter(
(c) => !c.value.startsWith('DM_setPanel')
),
...panelNameCompletions(tokenIteratorFactory, panels),
...dotAccessPanelShapeCompletions(tokenIteratorFactory, panels),
...stringPanelShapeCompletions(tokenIteratorFactory, panels),
]
.flat()
.filter((c) => c && c.value.startsWith(prefix));
};
}

export function DatabaseInfo({ panel }: { panel: DatabasePanelInfo }) {
const { connectors } = React.useContext(ProjectContext).state;
const connector = connectors.find(
Expand Down
33 changes: 20 additions & 13 deletions ui/panels/ProgramPanel.tsx
Expand Up @@ -110,7 +110,7 @@ export function ProgramPanelDetails({
);
}

const builtins: Record<
export const BUILTINS: Record<
ProgramPanelInfo['program']['type'],
Array<{ value: string; meta: string; score: number }>
> = {
Expand Down Expand Up @@ -636,7 +636,8 @@ const builtins: Record<

export function builtinCompletions(
tokenIteratorFactory: () => Ace.TokenIterator,
builtins: Array<{ value: string; score: number; meta: string }> = []
builtins: Array<{ value: string; meta: string; score: number }>,
language: ProgramPanelInfo['program']['type']
) {
const ti = tokenIteratorFactory();
const token = ti.getCurrentToken();
Expand All @@ -649,14 +650,18 @@ export function builtinCompletions(
...builtins,
{
value: 'DM_getPanel("panelName")',
meta: 'DataStation Panels',
score: 1000,
},
{
value: 'DM_setPanel(result)',
meta: 'DataStation Panels',
score: 1000,
},
meta: 'Fetch results of this DataStation panel',
score: 1000,
},
...(language === 'sql'
? []
: [
{
value: 'DM_setPanel(result)',
meta: 'Set results of this DataStation panel',
score: 1000,
},
]),
];
}

Expand Down Expand Up @@ -753,11 +758,12 @@ export function stringPanelShapeCompletions(

export function makeAutocomplete(
panels: Array<PanelInfo>,
builtins: Array<{ value: string; score: number; meta: string }> = []
builtins: Array<{ value: string; meta: string; score: number }>,
language: ProgramPanelInfo['program']['type']
) {
return (tokenIteratorFactory: () => Ace.TokenIterator, prefix: string) => {
return [
...builtinCompletions(tokenIteratorFactory, builtins),
...builtinCompletions(tokenIteratorFactory, builtins, language),
...panelNameCompletions(tokenIteratorFactory, panels),
...dotAccessPanelShapeCompletions(tokenIteratorFactory, panels),
...stringPanelShapeCompletions(tokenIteratorFactory, panels),
Expand All @@ -779,7 +785,8 @@ export function ProgramPanelBody({
<CodeEditor
autocomplete={makeAutocomplete(
panels.filter((p) => p.id !== panel.id),
builtins[language] || []
BUILTINS[language] || [],
language
)}
id={'editor-' + panel.id}
onKeyDown={keyboardShortcuts}
Expand Down

0 comments on commit 192d701

Please sign in to comment.