chore: Modify logic to detect and hide deep paths in autocomplete suggestions (#33966)
## Description
This PR modifies how the AutocompleteSortRules suppresses paths with
more than 2 level of nesting.
Example: `Table1.selectedRow.address`
A path like the above should be suppressed from autocomplete suggestion
but it should not suppress `.run` of a module instance with autocomplete
params
Example `QueryModule1.run({ limit: 10, user: appsmith.user.name })`
With the above completion, the AutocompleteSortRules's
NoDeepNestedSuggestionsRule check for the `text` property of the
completion and checked agains the value shared in the above example.
This resulted in suppression of the `QueryModule.run` for the
autocomplete list. Therefore the logic now shift from check the `text`
property which is what gets replaced on selection to `displayText` which
is what we see in the autocomplete suggestion.
Fixes https://github.com/appsmithorg/appsmith/issues/33959
## Automation
/ok-to-test tags="@tag.All"
### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/9378147789>
> Commit: 62c4d96c18b2ed931dbe9d671f1eeaaa5c989059
> Cypress dashboard url: <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=9378147789&attempt=3"
target="_blank">Click here!</a>
<!-- end of auto-generated comment: Cypress test results -->
## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Enhanced autocomplete functionality by considering `displayText` for
more accurate suggestions.
- Improved code completion in the test suite by adding a new parameter
`name` with a default value referencing `appsmith.user.name`.
- **Tests**
- Updated test cases to reflect new autocomplete and code completion
features, including new declarations for `fieldEntityInformation`.
- **Refactor**
- Updated internal logic to handle new properties and ensure consistency
across the application.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
33b3949445
commit
1e8a962b8b
|
|
@ -32,6 +32,7 @@ export const getShowHintOptions = (
|
|||
data: {},
|
||||
text: "",
|
||||
shortcut: "",
|
||||
displayText: "",
|
||||
};
|
||||
const cursor = editor.getCursor();
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -130,7 +130,9 @@ class NoDeepNestedSuggestionsRule implements AutocompleteRule {
|
|||
static threshold = -Infinity;
|
||||
computeScore(completion: Completion<TernCompletionResult>): number {
|
||||
let score = 0;
|
||||
if (completion.text.split(".").length > 2)
|
||||
const text = completion.displayText || "";
|
||||
|
||||
if (text.split(".").length > 2)
|
||||
score = NoDeepNestedSuggestionsRule.threshold;
|
||||
return score;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,11 +26,13 @@ const bigDoc = 250;
|
|||
const cls = "CodeMirror-Tern-";
|
||||
const hintDelay = 1700;
|
||||
|
||||
type MakeRequired<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;
|
||||
|
||||
export interface Completion<
|
||||
T = {
|
||||
doc: string;
|
||||
},
|
||||
> extends Hint {
|
||||
> extends MakeRequired<Hint, "displayText"> {
|
||||
origin: string;
|
||||
type: AutocompleteDataType | string;
|
||||
data: T;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { AutocompleteSorter, ScoredCompletion } from "../AutocompleteSortRules";
|
|||
import type CodeMirror from "codemirror";
|
||||
import type { Def } from "tern";
|
||||
import type { Doc } from "codemirror";
|
||||
import type { FieldEntityInformation } from "components/editorComponents/CodeEditor/EditorConfig";
|
||||
|
||||
jest.mock("utils/getCodeMirrorNamespace", () => {
|
||||
const actual = jest.requireActual("utils/getCodeMirrorNamespace");
|
||||
|
|
@ -243,6 +244,7 @@ describe("Tern server sorting", () => {
|
|||
new Map();
|
||||
const contextCompletion: Completion = {
|
||||
text: "context",
|
||||
displayText: "context",
|
||||
type: AutocompleteDataType.STRING,
|
||||
origin: "[doc]",
|
||||
data: {
|
||||
|
|
@ -252,6 +254,7 @@ describe("Tern server sorting", () => {
|
|||
|
||||
const sameEntityCompletion: Completion<any> = {
|
||||
text: "sameEntity.tableData",
|
||||
displayText: "sameEntity.tableData",
|
||||
type: AutocompleteDataType.ARRAY,
|
||||
origin: "DATA_TREE",
|
||||
data: {},
|
||||
|
|
@ -267,6 +270,7 @@ describe("Tern server sorting", () => {
|
|||
|
||||
const priorityCompletion: Completion<any> = {
|
||||
text: "selectedRow",
|
||||
displayText: "selectedRow",
|
||||
type: AutocompleteDataType.OBJECT,
|
||||
origin: "DATA_TREE",
|
||||
data: {},
|
||||
|
|
@ -282,6 +286,7 @@ describe("Tern server sorting", () => {
|
|||
|
||||
const diffTypeCompletion: Completion<any> = {
|
||||
text: "diffType.tableData",
|
||||
displayText: "diffType.tableData",
|
||||
type: AutocompleteDataType.ARRAY,
|
||||
origin: "DATA_TREE.WIDGET",
|
||||
data: {},
|
||||
|
|
@ -298,6 +303,7 @@ describe("Tern server sorting", () => {
|
|||
|
||||
const sameTypeDiffEntityTypeCompletion: Completion<any> = {
|
||||
text: "diffEntity.data",
|
||||
displayText: "diffEntity.data",
|
||||
type: AutocompleteDataType.OBJECT,
|
||||
origin: "DATA_TREE",
|
||||
data: {},
|
||||
|
|
@ -310,6 +316,7 @@ describe("Tern server sorting", () => {
|
|||
|
||||
const dataTreeCompletion: Completion<any> = {
|
||||
text: "otherDataTree",
|
||||
displayText: "otherDataTree",
|
||||
type: AutocompleteDataType.STRING,
|
||||
origin: "DATA_TREE",
|
||||
data: {},
|
||||
|
|
@ -322,6 +329,7 @@ describe("Tern server sorting", () => {
|
|||
|
||||
const functionCompletion: Completion<any> = {
|
||||
text: "otherDataFunction",
|
||||
displayText: "otherDataFunction",
|
||||
type: AutocompleteDataType.FUNCTION,
|
||||
origin: "DATA_TREE.APPSMITH.FUNCTIONS",
|
||||
data: {},
|
||||
|
|
@ -329,6 +337,7 @@ describe("Tern server sorting", () => {
|
|||
|
||||
const ecmascriptCompletion: Completion<any> = {
|
||||
text: "otherJS",
|
||||
displayText: "otherJS",
|
||||
type: AutocompleteDataType.OBJECT,
|
||||
origin: "ecmascript",
|
||||
data: {},
|
||||
|
|
@ -336,6 +345,7 @@ describe("Tern server sorting", () => {
|
|||
|
||||
const libCompletion: Completion<any> = {
|
||||
text: "libValue",
|
||||
displayText: "libValue",
|
||||
type: AutocompleteDataType.OBJECT,
|
||||
origin: "LIB/lodash",
|
||||
data: {},
|
||||
|
|
@ -343,6 +353,7 @@ describe("Tern server sorting", () => {
|
|||
|
||||
const unknownCompletion: Completion<any> = {
|
||||
text: "unknownSuggestion",
|
||||
displayText: "unknownSuggestion",
|
||||
type: AutocompleteDataType.UNKNOWN,
|
||||
origin: "unknown",
|
||||
data: {},
|
||||
|
|
@ -445,8 +456,10 @@ describe("Tern server completion", () => {
|
|||
"!type": "?",
|
||||
},
|
||||
run: {
|
||||
"!type": "fn(inputs: {gender: any, limit: any}) -> +Promise",
|
||||
"!fnParams": '{ gender: "male", limit: "5" }',
|
||||
"!type":
|
||||
"fn(inputs: {gender: any, limit: any, name: any }) -> +Promise",
|
||||
"!fnParams":
|
||||
'{ gender: "male", limit: "5", name: "Mr. " + appsmith.user.name }',
|
||||
"!url":
|
||||
"https://docs.appsmith.com/reference/appsmith-framework/query-object#queryrun",
|
||||
"!doc": "Executes the query with the given input values.",
|
||||
|
|
@ -461,7 +474,8 @@ describe("Tern server completion", () => {
|
|||
},
|
||||
"QueryModule11.run": {
|
||||
"!type": "fn(inputs: {gender: any, limit: any}) -> +Promise",
|
||||
"!fnParams": '{ gender: "male", limit: "5" }',
|
||||
"!fnParams":
|
||||
'{ gender: "male", limit: "5", name: "Mr. " + appsmith.user.name }',
|
||||
"!url":
|
||||
"https://docs.appsmith.com/reference/appsmith-framework/query-object#queryrun",
|
||||
"!doc": "Executes the query with the given input values.",
|
||||
|
|
@ -496,7 +510,7 @@ describe("Tern server completion", () => {
|
|||
},
|
||||
{
|
||||
name: "QueryModule11.run",
|
||||
type: "fn(inputs: {gender: ?, limit: ?}) -> Promise",
|
||||
type: "fn(inputs: {gender: ?, limit: ?, name: ?}) -> Promise",
|
||||
doc: "Executes the query with the given input values.",
|
||||
url: "https://docs.appsmith.com/reference/appsmith-framework/query-object#queryrun",
|
||||
origin: "DATA_TREE",
|
||||
|
|
@ -542,12 +556,12 @@ describe("Tern server completion", () => {
|
|||
isEntityName: true,
|
||||
},
|
||||
{
|
||||
text: 'QueryModule11.run({ gender: "male", limit: "5" })',
|
||||
text: 'QueryModule11.run({ gender: "male", limit: "5", name: "Mr. " + appsmith.user.name })',
|
||||
displayText: "QueryModule11.run",
|
||||
className: "CodeMirror-Tern-completion CodeMirror-Tern-completion-fn",
|
||||
data: {
|
||||
name: "QueryModule11.run",
|
||||
type: "fn(inputs: {gender: ?, limit: ?}) -> Promise",
|
||||
type: "fn(inputs: {gender: ?, limit: ?, name: ?}) -> Promise",
|
||||
doc: "Executes the query with the given input values.",
|
||||
url: "https://docs.appsmith.com/reference/appsmith-framework/query-object#queryrun",
|
||||
origin: "DATA_TREE",
|
||||
|
|
@ -560,13 +574,7 @@ describe("Tern server completion", () => {
|
|||
},
|
||||
];
|
||||
|
||||
// The current cursor location that is being written in the code mirror editor
|
||||
MockCodemirrorEditor.getCursor.mockResolvedValue({
|
||||
line: 10,
|
||||
ch: 30,
|
||||
sticky: null,
|
||||
});
|
||||
MockCodemirrorEditor.getTokenAt.mockResolvedValue({
|
||||
const mockToken = {
|
||||
start: 22,
|
||||
end: 30,
|
||||
string: "QueryMod",
|
||||
|
|
@ -639,8 +647,35 @@ describe("Tern server completion", () => {
|
|||
},
|
||||
indented: 4,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const fieldEntityInformation = {
|
||||
mode: "javascript",
|
||||
isTriggerPath: true,
|
||||
entityName: "JSObject1",
|
||||
propertyPath: "body",
|
||||
entityType: "JSACTION",
|
||||
blockCompletions: [
|
||||
{
|
||||
parentPath: "this",
|
||||
subPath: "myFun2()",
|
||||
},
|
||||
{
|
||||
parentPath: "JSObject1",
|
||||
subPath: "myFun2()",
|
||||
},
|
||||
],
|
||||
token: mockToken,
|
||||
} as FieldEntityInformation;
|
||||
|
||||
// The current cursor location that is being written in the code mirror editor
|
||||
MockCodemirrorEditor.getCursor.mockResolvedValue({
|
||||
line: 10,
|
||||
ch: 30,
|
||||
sticky: null,
|
||||
});
|
||||
MockCodemirrorEditor.getTokenAt.mockResolvedValue(mockToken);
|
||||
CodemirrorTernService.fieldEntityInformation = fieldEntityInformation;
|
||||
CodemirrorTernService.entityDef = entityDef;
|
||||
|
||||
// The current line that is being written in the code mirror editor
|
||||
|
|
@ -662,9 +697,6 @@ describe("Tern server completion", () => {
|
|||
name: "",
|
||||
changed: null,
|
||||
});
|
||||
jest
|
||||
.spyOn(AutocompleteSorter, "sort")
|
||||
.mockImplementation((completions) => completions);
|
||||
|
||||
CodemirrorTernService.defEntityInformation = new Map([
|
||||
[
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user