You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ju...@apache.org on 2024/04/16 22:09:50 UTC
(superset) 02/05: use custom keywords
This is an automated email from the ASF dual-hosted git repository.
justinpark pushed a commit to branch justin--sqllab-plugin-test
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 6bd6ebfad18d50236da0e53a1dec607515a4b753
Author: justinpark <ju...@gmail.com>
AuthorDate: Tue Apr 16 11:44:46 2024 -0700
use custom keywords
---
.../superset-ui-core/src/ui-overrides/types.ts | 18 +++++++
.../SqlLab/components/AceEditorWrapper/index.tsx | 57 +++++++++++++---------
.../components/AceEditorWrapper/useKeywords.ts | 37 ++++++++++++--
3 files changed, 86 insertions(+), 26 deletions(-)
diff --git a/superset-frontend/packages/superset-ui-core/src/ui-overrides/types.ts b/superset-frontend/packages/superset-ui-core/src/ui-overrides/types.ts
index 60598bd4e1..98b464de16 100644
--- a/superset-frontend/packages/superset-ui-core/src/ui-overrides/types.ts
+++ b/superset-frontend/packages/superset-ui-core/src/ui-overrides/types.ts
@@ -144,6 +144,21 @@ export interface DashboardEmbedModalExtensions {
onHide: () => void;
}
+export interface CustomAutoCompleteArgs {
+ queryEditorId: string;
+ dbId?: string | number;
+ schema?: string;
+}
+
+export interface CustomAutocomplete {
+ docHTML?: string | undefined;
+ docText?: string | undefined;
+ name: string;
+ value: string;
+ score: number;
+ meta: string;
+}
+
export type Extensions = Partial<{
'alertsreports.header.icon': React.ComponentType;
'embedded.documentation.configuration_details': React.ComponentType<ConfigDetailsProps>;
@@ -166,4 +181,7 @@ export type Extensions = Partial<{
'sqleditor.extension.form': React.ComponentType<SQLFormExtensionProps>;
'sqleditor.extension.resultTable': React.ComponentType<SQLResultTableExtentionProps>;
'dashboard.slice.header': React.ComponentType<SliceHeaderExtension>;
+ 'sqleditor.extension.customAutocomplete': (args: CustomAutoCompleteArgs) => {
+ data?: CustomAutocomplete[];
+ };
}>;
diff --git a/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx b/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
index a01b1cee76..f44a7e3f76 100644
--- a/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
+++ b/superset-frontend/src/SqlLab/components/AceEditorWrapper/index.tsx
@@ -19,7 +19,8 @@
import React, { useState, useEffect, useRef } from 'react';
import type { IAceEditor } from 'react-ace/lib/types';
import { useDispatch } from 'react-redux';
-import { css, styled, usePrevious } from '@superset-ui/core';
+import { css, styled, usePrevious, useTheme } from '@superset-ui/core';
+import { Global } from '@emotion/react';
import { queryEditorSetSelectedText } from 'src/SqlLab/actions/sqlLab';
import { FullSQLEditor as AceEditor } from 'src/components/AsyncAceEditor';
@@ -54,16 +55,6 @@ const StyledAceEditor = styled(AceEditor)`
font-feature-settings:
'liga' off,
'calt' off;
-
- &.ace_autocomplete {
- // Use !important because Ace Editor applies extra CSS at the last second
- // when opening the autocomplete.
- width: ${theme.gridUnit * 130}px !important;
- }
-
- .ace_scroller {
- background-color: ${theme.colors.grayscale.light4};
- }
}
`}
`;
@@ -182,20 +173,40 @@ const AceEditorWrapper = ({
},
!autocomplete,
);
+ const theme = useTheme();
return (
- <StyledAceEditor
- keywords={keywords}
- onLoad={onEditorLoad}
- onBlur={onBlurSql}
- height={height}
- onChange={onChangeText}
- width="100%"
- editorProps={{ $blockScrolling: true }}
- enableLiveAutocompletion={autocomplete}
- value={sql}
- annotations={annotations}
- />
+ <>
+ <Global
+ styles={css`
+ .ace_text-layer {
+ width: 100% !important;
+ }
+
+ .ace_autocomplete {
+ // Use !important because Ace Editor applies extra CSS at the last second
+ // when opening the autocomplete.
+ width: ${theme.gridUnit * 130}px !important;
+ }
+
+ .ace_scroller {
+ background-color: ${theme.colors.grayscale.light4};
+ }
+ `}
+ />
+ <StyledAceEditor
+ keywords={keywords}
+ onLoad={onEditorLoad}
+ onBlur={onBlurSql}
+ height={height}
+ onChange={onChangeText}
+ width="100%"
+ editorProps={{ $blockScrolling: true }}
+ enableLiveAutocompletion={autocomplete}
+ value={sql}
+ annotations={annotations}
+ />
+ </>
);
};
diff --git a/superset-frontend/src/SqlLab/components/AceEditorWrapper/useKeywords.ts b/superset-frontend/src/SqlLab/components/AceEditorWrapper/useKeywords.ts
index b42edc5822..680d9d73c6 100644
--- a/superset-frontend/src/SqlLab/components/AceEditorWrapper/useKeywords.ts
+++ b/superset-frontend/src/SqlLab/components/AceEditorWrapper/useKeywords.ts
@@ -18,7 +18,7 @@
*/
import { useEffect, useMemo, useRef } from 'react';
import { useSelector, useDispatch, shallowEqual, useStore } from 'react-redux';
-import { t } from '@superset-ui/core';
+import { getExtensionsRegistry, t } from '@superset-ui/core';
import { Editor } from 'src/components/AsyncAceEditor';
import sqlKeywords from 'src/SqlLab/utils/sqlKeywords';
@@ -55,10 +55,23 @@ const getHelperText = (value: string) =>
docText: value,
};
+const extensionsRegistry = getExtensionsRegistry();
+
+const useDefaultCustomKeywords = () => ({ data: undefined });
+
export function useKeywords(
{ queryEditorId, dbId, schema }: Params,
skip = false,
) {
+ const useCustomAutocomplete =
+ extensionsRegistry.get('sqleditor.extension.customAutocomplete') ??
+ useDefaultCustomKeywords;
+
+ const { data: customOptions } = useCustomAutocomplete({
+ queryEditorId: String(queryEditorId),
+ dbId,
+ schema,
+ });
const dispatch = useDispatch();
const hasFetchedKeywords = useRef(false);
// skipFetch is used to prevent re-evaluating memoized keywords
@@ -201,14 +214,32 @@ export function useKeywords(
[functionNames, insertMatch],
);
+ const customKeywords = useMemo(
+ () =>
+ (customOptions ?? []).map(option => ({
+ ...option,
+ completer: {
+ insertMatch,
+ },
+ })),
+ [customOptions, insertMatch],
+ );
+
const keywords = useMemo(
() =>
columnKeywords
.concat(schemaKeywords)
.concat(tableKeywords)
.concat(functionKeywords)
- .concat(sqlKeywords),
- [schemaKeywords, tableKeywords, columnKeywords, functionKeywords],
+ .concat(sqlKeywords)
+ .concat(customKeywords),
+ [
+ schemaKeywords,
+ tableKeywords,
+ columnKeywords,
+ functionKeywords,
+ customKeywords,
+ ],
);
hasFetchedKeywords.current = !skip;