> Pull Request Template > > Use this template to quickly create a well written pull request. Delete all quotes before creating the pull request. > ## Description > Add a TL;DR when description is extra long (helps content team) > > Please include a summary of the changes and which issue has been fixed. Please also include relevant motivation > and context. List any dependencies that are required for this change > > Links to Notion, Figma or any other documents that might be relevant to the PR > > #### PR fixes following issue(s) Fixes # (issue number) > if no issue exists, please create an issue and ask the maintainers about this first > > #### Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video > > #### Type of change > Please delete options that are not relevant. - Bug fix (non-breaking change which fixes an issue) - New feature (non-breaking change which adds functionality) - Breaking change (fix or feature that would cause existing functionality to not work as expected) - Chore (housekeeping or task changes that don't impact user perception) - This change requires a documentation update > > > ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [x] Manual - [x] Jest - [x] Cypress > > #### Test Plan > One Click Binding - https://github.com/appsmithorg/TestSmith/issues/2390 > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Test-plan-implementation#speedbreaker-features-to-consider-for-every-change) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans/_edit#areas-of-interest) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed --------- Co-authored-by: Vemparala Surya Vamsi <vamsi@appsmith.com>
165 lines
4.5 KiB
TypeScript
165 lines
4.5 KiB
TypeScript
import type { Plugin } from "api/PluginApi";
|
|
import {
|
|
DATASOURCE_DB_FORM,
|
|
DATASOURCE_REST_API_FORM,
|
|
DATASOURCE_SAAS_FORM,
|
|
} from "ce/constants/forms";
|
|
import { diff } from "deep-diff";
|
|
import { PluginPackageName, PluginType } from "entities/Action";
|
|
import type { Datasource } from "entities/Datasource";
|
|
import { AuthenticationStatus, AuthType } from "entities/Datasource";
|
|
import { isArray } from "lodash";
|
|
export function isCurrentFocusOnInput() {
|
|
return (
|
|
["input", "textarea"].indexOf(
|
|
document.activeElement?.tagName?.toLowerCase() || "",
|
|
) >= 0
|
|
);
|
|
}
|
|
|
|
/**
|
|
* This method returns boolean if the propertyControl is focused.
|
|
* @param domElement
|
|
* @returns
|
|
*/
|
|
export function shouldFocusOnPropertyControl(
|
|
domElement?: HTMLDivElement | null,
|
|
) {
|
|
let isCurrentFocusOnProperty = false;
|
|
|
|
if (domElement) {
|
|
isCurrentFocusOnProperty = domElement.contains(document.activeElement);
|
|
}
|
|
|
|
return !(isCurrentFocusOnInput() || isCurrentFocusOnProperty);
|
|
}
|
|
|
|
/**
|
|
* Returns a focusable field of PropertyControl.
|
|
* @param element
|
|
* @returns
|
|
*/
|
|
export function getPropertyControlFocusElement(
|
|
element: HTMLDivElement | null,
|
|
): HTMLElement | undefined {
|
|
if (element?.children) {
|
|
const [, propertyInputElement] = element.children;
|
|
|
|
if (propertyInputElement) {
|
|
const uiInputElement = propertyInputElement.querySelector(
|
|
'button:not([tabindex="-1"]), input, [tabindex]:not([tabindex="-1"])',
|
|
) as HTMLElement | undefined;
|
|
if (uiInputElement) {
|
|
return uiInputElement;
|
|
}
|
|
const codeEditorInputElement =
|
|
propertyInputElement.getElementsByClassName("CodeEditorTarget")[0] as
|
|
| HTMLElement
|
|
| undefined;
|
|
if (codeEditorInputElement) {
|
|
return codeEditorInputElement;
|
|
}
|
|
|
|
const lazyCodeEditorInputElement =
|
|
propertyInputElement.getElementsByClassName("LazyCodeEditor")[0] as
|
|
| HTMLElement
|
|
| undefined;
|
|
if (lazyCodeEditorInputElement) {
|
|
return lazyCodeEditorInputElement;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns true if :
|
|
* - authentication type is not oauth2 or is not a Google Sheet Plugin
|
|
* - authentication type is oauth2 and authorized status success and is a Google Sheet Plugin
|
|
* @param datasource Datasource
|
|
* @param plugin Plugin
|
|
* @returns boolean
|
|
*/
|
|
export function isDatasourceAuthorizedForQueryCreation(
|
|
datasource: Datasource,
|
|
plugin: Plugin,
|
|
): boolean {
|
|
if (!datasource) return false;
|
|
const authType =
|
|
datasource &&
|
|
datasource?.datasourceConfiguration?.authentication?.authenticationType;
|
|
|
|
const isGoogleSheetPlugin = isGoogleSheetPluginDS(plugin?.packageName);
|
|
if (isGoogleSheetPlugin) {
|
|
const isAuthorized =
|
|
authType === AuthType.OAUTH2 &&
|
|
datasource?.datasourceConfiguration?.authentication
|
|
?.authenticationStatus === AuthenticationStatus.SUCCESS;
|
|
return isAuthorized;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Determines whether plugin is google sheet or not
|
|
* @param pluginPackageName string
|
|
* @returns boolean
|
|
*/
|
|
export function isGoogleSheetPluginDS(pluginPackageName?: string) {
|
|
return pluginPackageName === PluginPackageName.GOOGLE_SHEETS;
|
|
}
|
|
|
|
/**
|
|
* Returns datasource property value from datasource?.datasourceConfiguration?.properties
|
|
* @param datasource Datasource
|
|
* @param propertyKey string
|
|
* @returns string | null
|
|
*/
|
|
export function getDatasourcePropertyValue(
|
|
datasource: Datasource,
|
|
propertyKey: string,
|
|
): string | null {
|
|
if (!datasource) {
|
|
return null;
|
|
}
|
|
|
|
const properties = datasource?.datasourceConfiguration?.properties;
|
|
if (!!properties && properties.length > 0) {
|
|
const propertyObj = properties.find((prop) => prop.key === propertyKey);
|
|
if (!!propertyObj) {
|
|
return propertyObj.value;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function getFormName(plugin: Plugin): string {
|
|
const pluginType = plugin?.type;
|
|
if (!!pluginType) {
|
|
switch (pluginType) {
|
|
case PluginType.DB:
|
|
case PluginType.REMOTE:
|
|
return DATASOURCE_DB_FORM;
|
|
case PluginType.SAAS:
|
|
return DATASOURCE_SAAS_FORM;
|
|
case PluginType.API:
|
|
return DATASOURCE_REST_API_FORM;
|
|
}
|
|
}
|
|
return DATASOURCE_DB_FORM;
|
|
}
|
|
|
|
export function getFormDiffPaths(initialValues: any, currentValues: any) {
|
|
const difference = diff(initialValues, currentValues);
|
|
const diffPaths: string[] = [];
|
|
if (!!difference) {
|
|
difference.forEach((diff) => {
|
|
if (!!diff.path && isArray(diff.path)) {
|
|
diffPaths.push(diff.path.join("."));
|
|
}
|
|
});
|
|
}
|
|
return diffPaths;
|
|
}
|