diff --git a/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.stories.tsx b/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.stories.tsx new file mode 100644 index 000000000000..0327ddedc158 --- /dev/null +++ b/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.stories.tsx @@ -0,0 +1,21 @@ +/* eslint-disable no-console */ +import type { Meta, StoryObj } from "@storybook/react"; + +import { DismissibleTab } from "."; + +const meta: Meta = { + title: "ADS/Components/Dismissible Tab", + component: DismissibleTab, +}; + +export default meta; + +type Story = StoryObj; + +export const Basic: Story = { + args: { + isActive: true, + dataTestId: "t--dismissible-tab", + children: "Dismissible tab", + }, +}; diff --git a/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.styles.ts b/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.styles.ts new file mode 100644 index 000000000000..42abfbe698c9 --- /dev/null +++ b/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.styles.ts @@ -0,0 +1,55 @@ +import styled from "styled-components"; + +import { Button as ADSButton } from ".."; + +export const Tab = styled.div` + position: relative; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + gap: var(--ads-v2-spaces-2); + height: 100%; + font-size: 12px; + color: var(--ads-v2-color-fg); + cursor: pointer; + + border-top-left-radius: var(--ads-v2-border-radius); + border-top-right-radius: var(--ads-v2-border-radius); + border-left: 1px solid transparent; + border-right: 1px solid transparent; + border-top: 3px solid transparent; + + padding: var(--ads-v2-spaces-3); + padding-top: 6px; + + &.active { + background: var(--ads-v2-colors-control-field-default-bg); + border-top-color: var(--ads-v2-color-bg-brand); + border-left-color: var(--ads-v2-color-border-muted); + border-right-color: var(--ads-v2-color-border-muted); + + span { + font-weight: var(--ads-v2-font-weight-bold); + } + } + + & > .tab-close { + opacity: 0; + transition: opacity 0.2s ease; + } + + &:hover > .tab-close, + &:focus-within > .tab-close, + &.active > .tab-close { + opacity: 1; + } +`; + +export const CloseButton = styled(ADSButton)` + border-radius: 2px; + cursor: pointer; + padding: var(--ads-v2-spaces-1); + max-width: 16px; + max-height: 16px; +`; diff --git a/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.tsx b/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.tsx new file mode 100644 index 000000000000..78a05a887bbf --- /dev/null +++ b/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.tsx @@ -0,0 +1,43 @@ +import React from "react"; + +import clsx from "classnames"; + +import { Icon } from ".."; + +import * as Styled from "./DismissibleTab.styles"; +import { DATA_TEST_ID } from "./constants"; + +import type { DismissibleTabProps } from "./DismissibleTab.types"; + +export const DismissibleTab = ({ + children, + dataTestId, + isActive, + onClick, + onClose, + onDoubleClick, +}: DismissibleTabProps) => { + return ( + + {children} + + + + + ); +}; diff --git a/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.types.ts b/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.types.ts new file mode 100644 index 000000000000..909dafab3177 --- /dev/null +++ b/app/client/packages/design-system/ads/src/DismissibleTab/DismissibleTab.types.ts @@ -0,0 +1,10 @@ +import type React from "react"; + +export interface DismissibleTabProps { + children: React.ReactNode; + dataTestId?: string; + isActive: boolean; + onClick: () => void; + onClose: (e: React.MouseEvent) => void; + onDoubleClick?: () => void; +} diff --git a/app/client/packages/design-system/ads/src/DismissibleTab/constants.ts b/app/client/packages/design-system/ads/src/DismissibleTab/constants.ts new file mode 100644 index 000000000000..71d29d3f7c48 --- /dev/null +++ b/app/client/packages/design-system/ads/src/DismissibleTab/constants.ts @@ -0,0 +1,3 @@ +export const DATA_TEST_ID = { + CLOSE_BUTTON: "t--tab-close-btn", +}; diff --git a/app/client/packages/design-system/ads/src/DismissibleTab/index.ts b/app/client/packages/design-system/ads/src/DismissibleTab/index.ts new file mode 100644 index 000000000000..f00320299ac8 --- /dev/null +++ b/app/client/packages/design-system/ads/src/DismissibleTab/index.ts @@ -0,0 +1,2 @@ +export { DismissibleTab } from "./DismissibleTab"; +export type { DismissibleTabProps } from "./DismissibleTab.types"; diff --git a/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/EditableDismissibleTab.stories.tsx b/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/EditableDismissibleTab.stories.tsx new file mode 100644 index 000000000000..7dfe5b8289e3 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/EditableDismissibleTab.stories.tsx @@ -0,0 +1,53 @@ +/* eslint-disable no-console */ +import React from "react"; +import type { Meta, StoryObj } from "@storybook/react"; + +import { EditableDismissibleTab } from "."; +import styled from "styled-components"; + +import { Icon } from "../.."; + +const meta: Meta = { + title: "ADS/Templates/Editable Dismissible Tab", + component: EditableDismissibleTab, +}; + +const EntityIcon = styled.div` + height: 18px; + width: 18px; + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: center; + + svg, + img { + height: 100%; + width: 100%; + } +`; + +const JSIcon = () => { + return ( + + + + ); +}; + +export default meta; + +type Story = StoryObj; + +export const Basic: Story = { + args: { + isActive: true, + dataTestId: "t--dismissible-tab", + icon: JSIcon(), + name: "Hello", + + onNameSave: console.log, + validateName: (name: string) => + name.length < 3 ? "Name must be at least 3 characters" : null, + }, +}; diff --git a/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/EditableDismissibleTab.tsx b/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/EditableDismissibleTab.tsx new file mode 100644 index 000000000000..9ed6cc20e50e --- /dev/null +++ b/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/EditableDismissibleTab.tsx @@ -0,0 +1,51 @@ +import React from "react"; +import { noop } from "lodash"; +import { useBoolean } from "usehooks-ts"; + +import { DismissibleTab } from "../.."; +import { EditableEntityName } from ".."; + +import type { EditableDismissibleTabProps } from "./EditableDismissibleTab.types"; + +export const EditableDismissibleTab = (props: EditableDismissibleTabProps) => { + const { + dataTestId, + icon, + isActive, + isEditable = true, + isLoading, + name, + onClick, + onClose, + onNameSave, + validateName, + } = props; + + const { + setFalse: exitEditMode, + setTrue: enterEditMode, + value: isEditing, + } = useBoolean(false); + + const handleDoubleClick = isEditable ? enterEditMode : noop; + + return ( + + + + ); +}; diff --git a/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/EditableDismissibleTab.types.ts b/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/EditableDismissibleTab.types.ts new file mode 100644 index 000000000000..2ee09e171053 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/EditableDismissibleTab.types.ts @@ -0,0 +1,14 @@ +import type React from "react"; + +export interface EditableDismissibleTabProps { + dataTestId?: string; + icon: React.ReactNode; + isActive: boolean; + isEditable?: boolean; + isLoading: boolean; + name: string; + onClick: () => void; + onClose: () => void; + onNameSave: (name: string) => void; + validateName: (name: string) => string | null; +} diff --git a/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/index.ts b/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/index.ts new file mode 100644 index 000000000000..5c3ff232bae3 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Templates/EditableDismissibleTab/index.ts @@ -0,0 +1 @@ +export { EditableDismissibleTab } from "./EditableDismissibleTab"; diff --git a/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.stories.tsx b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.stories.tsx new file mode 100644 index 000000000000..48c9a769c093 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.stories.tsx @@ -0,0 +1,53 @@ +/* eslint-disable no-console */ +import React from "react"; +import type { Meta, StoryObj } from "@storybook/react"; +import styled from "styled-components"; + +import { Icon } from "../.."; +import { EditableEntityName } from "."; + +const EntityIcon = styled.div` + height: 18px; + width: 18px; + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: center; + + svg, + img { + height: 100%; + width: 100%; + } +`; + +const JSIcon = () => { + return ( + + + + ); +}; + +const meta: Meta = { + title: "ADS/Templates/Editable Entity Name", + component: EditableEntityName, +}; + +export default meta; + +type Story = StoryObj; + +export const Basic: Story = { + args: { + name: "Hello", + onNameSave: console.log, + onExitEditing: console.log, + icon: JSIcon(), + inputTestId: "t--editable-name", + isEditing: true, + isLoading: false, + validateName: (name: string) => + name.length < 3 ? "Name must be at least 3 characters" : null, + }, +}; diff --git a/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.styles.ts b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.styles.ts new file mode 100644 index 000000000000..171b508e6b8b --- /dev/null +++ b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.styles.ts @@ -0,0 +1,29 @@ +import styled from "styled-components"; +import { Text as ADSText } from "../../Text"; + +export const Root = styled.div` + display: flex; + flex-direction: row; + flex-wrap: nowrap; + justify-content: start; + align-items: center; + gap: var(--ads-v2-spaces-2); +`; + +export const Text = styled(ADSText)` + min-width: 3ch; + bottom: -0.5px; +`; + +export const IconContainer = styled.div` + height: 12px; + width: 12px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + + img { + width: 12px; + } +`; diff --git a/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.tsx b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.tsx new file mode 100644 index 000000000000..fa26160d2a37 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.tsx @@ -0,0 +1,64 @@ +import React, { useMemo } from "react"; + +import { Spinner, Tooltip } from "../.."; +import { useEditableText } from "../../__hooks__"; + +import * as Styled from "./EditableEntityName.styles"; + +import type { EditableEntityNameProps } from "./EditableEntityName.types"; + +export const EditableEntityName = ({ + icon, + inputTestId, + isEditing, + isLoading = false, + name, + onExitEditing, + onNameSave, + validateName, +}: EditableEntityNameProps) => { + const [ + inputRef, + editableName, + validationError, + handleKeyUp, + handleTitleChange, + ] = useEditableText(isEditing, name, onExitEditing, validateName, onNameSave); + + const inputProps = useMemo( + () => ({ + ["data-testid"]: inputTestId, + onKeyUp: handleKeyUp, + onChange: handleTitleChange, + autoFocus: true, + style: { + paddingTop: 4, + paddingBottom: 4, + left: -1, + top: -5, + }, + }), + [handleKeyUp, handleTitleChange, inputTestId], + ); + + return ( + + {isLoading ? ( + + ) : ( + {icon} + )} + + + {editableName} + + + + ); +}; diff --git a/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.types.ts b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.types.ts new file mode 100644 index 000000000000..b092f01b41be --- /dev/null +++ b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/EditableEntityName.types.ts @@ -0,0 +1,12 @@ +import type React from "react"; + +export interface EditableEntityNameProps { + icon: React.ReactNode; + inputTestId?: string; + isEditing: boolean; + isLoading?: boolean; + name: string; + onExitEditing: () => void; + onNameSave: (name: string) => void; + validateName: (name: string) => string | null; +} diff --git a/app/client/packages/design-system/ads/src/Templates/EditableEntityName/index.ts b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/index.ts new file mode 100644 index 000000000000..0230a869ac95 --- /dev/null +++ b/app/client/packages/design-system/ads/src/Templates/EditableEntityName/index.ts @@ -0,0 +1 @@ +export { EditableEntityName } from "./EditableEntityName"; diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.tsx b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.tsx index cf5191006712..066ff8cf0599 100644 --- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.tsx +++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/EntityItem/EntityItem.tsx @@ -5,7 +5,7 @@ import { Tooltip } from "../../../Tooltip"; import type { EntityItemProps } from "./EntityItem.types"; import { EntityEditableName } from "./EntityItem.styles"; -import { useEditableText } from "../Editable"; +import { useEditableText } from "../../../__hooks__/useEditableText"; import clx from "classnames"; export const EntityItem = (props: EntityItemProps) => { diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/index.ts b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/index.ts index bae3358c1a06..82b07ac50f5a 100644 --- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/index.ts +++ b/app/client/packages/design-system/ads/src/Templates/EntityExplorer/index.ts @@ -6,6 +6,6 @@ export { EmptyState } from "./EmptyState"; export { NoSearchResults } from "./NoSearchResults"; export * from "./ExplorerContainer"; export * from "./EntityItem"; -export { useEditableText } from "./Editable"; +export { useEditableText } from "../../__hooks__/useEditableText"; export * from "./EntityGroupsList"; export * from "./EntityListTree"; diff --git a/app/client/packages/design-system/ads/src/Templates/index.ts b/app/client/packages/design-system/ads/src/Templates/index.ts index e8258f9d1b5f..4b7b197c824f 100644 --- a/app/client/packages/design-system/ads/src/Templates/index.ts +++ b/app/client/packages/design-system/ads/src/Templates/index.ts @@ -1,3 +1,5 @@ export * from "./IDEHeader"; export * from "./EntityExplorer"; export * from "./Sidebar"; +export * from "./EditableEntityName"; +export * from "./EditableDismissibleTab"; diff --git a/app/client/packages/design-system/ads/src/__hooks__/index.ts b/app/client/packages/design-system/ads/src/__hooks__/index.ts new file mode 100644 index 000000000000..b75011d84cf4 --- /dev/null +++ b/app/client/packages/design-system/ads/src/__hooks__/index.ts @@ -0,0 +1,2 @@ +export { useDOMRef } from "./useDomRef"; +export { useEditableText } from "./useEditableText"; diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/index.ts b/app/client/packages/design-system/ads/src/__hooks__/useEditableText/index.ts similarity index 100% rename from app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/index.ts rename to app/client/packages/design-system/ads/src/__hooks__/useEditableText/index.ts diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.test.tsx b/app/client/packages/design-system/ads/src/__hooks__/useEditableText/useEditableText.test.tsx similarity index 99% rename from app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.test.tsx rename to app/client/packages/design-system/ads/src/__hooks__/useEditableText/useEditableText.test.tsx index d314a8e193cb..628e7aceaabd 100644 --- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.test.tsx +++ b/app/client/packages/design-system/ads/src/__hooks__/useEditableText/useEditableText.test.tsx @@ -1,8 +1,9 @@ import React from "react"; import { renderHook, act } from "@testing-library/react-hooks"; -import { useEditableText } from "./useEditableText"; import { fireEvent, render } from "@testing-library/react"; -import { Text } from "../../.."; +import { Text } from "../.."; + +import { useEditableText } from "./useEditableText"; describe("useEditableText", () => { const mockExitEditing = jest.fn(); diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.ts b/app/client/packages/design-system/ads/src/__hooks__/useEditableText/useEditableText.ts similarity index 99% rename from app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.ts rename to app/client/packages/design-system/ads/src/__hooks__/useEditableText/useEditableText.ts index 59b3d4e26784..80b95891d40e 100644 --- a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/useEditableText.ts +++ b/app/client/packages/design-system/ads/src/__hooks__/useEditableText/useEditableText.ts @@ -7,8 +7,10 @@ import { useRef, type RefObject, } from "react"; + import { usePrevious } from "@mantine/hooks"; import { useEventCallback, useEventListener } from "usehooks-ts"; + import { normaliseName } from "./utils"; export function useEditableText( diff --git a/app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/utils.ts b/app/client/packages/design-system/ads/src/__hooks__/useEditableText/utils.ts similarity index 100% rename from app/client/packages/design-system/ads/src/Templates/EntityExplorer/Editable/utils.ts rename to app/client/packages/design-system/ads/src/__hooks__/useEditableText/utils.ts diff --git a/app/client/packages/design-system/ads/src/index.ts b/app/client/packages/design-system/ads/src/index.ts index 4a9cee88b871..e6e603b714a4 100644 --- a/app/client/packages/design-system/ads/src/index.ts +++ b/app/client/packages/design-system/ads/src/index.ts @@ -1,14 +1,16 @@ import "./__theme__/default/index.css"; -export * from "./AnnouncementPopover"; export * from "./AnnouncementModal"; +export * from "./AnnouncementPopover"; export * from "./Avatar"; -export * from "./Button"; +export * from "./Badge"; export * from "./Banner"; +export * from "./Button"; export * from "./Callout"; export * from "./Checkbox"; export * from "./Collapsible"; export * from "./DatePicker"; +export * from "./DismissibleTab"; export * from "./Divider"; export * from "./Flex"; export * from "./FormControl"; @@ -31,10 +33,9 @@ export * from "./Switch"; export * from "./Tab"; export * from "./Table"; export * from "./Tag"; +export * from "./Templates"; export * from "./Text"; export * from "./Toast"; export * from "./ToggleButton"; -export * from "./Tooltip"; export * from "./ToggleButtonGroup"; -export * from "./Templates"; -export * from "./Badge"; +export * from "./Tooltip"; diff --git a/app/client/src/PluginActionEditor/components/PluginActionForm/components/ActionForm/Zone/styles.module.css b/app/client/src/PluginActionEditor/components/PluginActionForm/components/ActionForm/Zone/styles.module.css index 9f616da7c93b..d0f508e8b725 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionForm/components/ActionForm/Zone/styles.module.css +++ b/app/client/src/PluginActionEditor/components/PluginActionForm/components/ActionForm/Zone/styles.module.css @@ -17,60 +17,26 @@ } /* - This section can be removed once the condition abouve each is resolved + This section can be removed once the condition below each is resolved */ + /* 1. Margin is removed from FieldWrapper component in FormRender file */ + & :global(.uqi-form-wrapper) { margin: 0; } - /* DropdownControl default width is removed */ - & :global(.uqi-dropdown-select) { - width: unset !important; - } - /* InputTexctControl min,max and width removed */ - & :global(.uqi-input-text) { - width: unset !important; - min-width: unset !important; - max-width: unset !important; - } - /* FieldArrayControl hardcoded width is removed */ - & :global(.t--form-control-ARRAY_FIELD) { - & :global(.t--form-control-QUERY_DYNAMIC_INPUT_TEXT) > div { - width: unset !important; - } - - & > div { - width: 100% !important; - - & > :global(.array-control-secondary-box) { - width: 100% !important; - - & > div { - flex: 1; - } - } - } - } - - /* DynamicInputTextControl min height and width removed */ - & :global(.uqi-dynamic-input-text) { - width: unset !important; - min-height: unset !important; - } - - /* Remove when code editor min width is resolved in DynamicTextFeildControl */ - & :global(.dynamic-text-field-control) { - min-width: 260px; - } /* reset ads select min width */ + & :global(.ads-v2-select > .rc-select-selector) { min-width: unset; } /* Remove this once the config in DB is updated to use Section and Zone (Twilio, Airtable) */ + & :global(.ar-form-info-text) { max-width: unset; } + /* Removable section ends here */ } diff --git a/app/client/src/PluginActionEditor/components/PluginActionForm/components/UQIEditor/FormRender.tsx b/app/client/src/PluginActionEditor/components/PluginActionForm/components/UQIEditor/FormRender.tsx index 2666f2eb2b92..644c090f73a8 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionForm/components/UQIEditor/FormRender.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionForm/components/UQIEditor/FormRender.tsx @@ -179,7 +179,7 @@ const FormRender = (props: Props) => { const modifiedSection = modifySectionConfig(section, enabled); return ( - // TODO: Remove classname once action redesign epic is done + // TODO: Remove classname once DB configs are migrated div { - min-width: unset; - width: 100%; - } - } `; const LearnMoreLink = styled(Link)` diff --git a/app/client/src/ce/actions/environmentAction.ts b/app/client/src/ce/actions/environmentAction.ts index cf28077c36d7..a509c445cd0b 100644 --- a/app/client/src/ce/actions/environmentAction.ts +++ b/app/client/src/ce/actions/environmentAction.ts @@ -1,3 +1,5 @@ +import type { APP_MODE } from "entities/App"; + // Redux action to show the environment info modal before deploy export const showEnvironmentDeployInfoModal = () => ({}); @@ -11,12 +13,14 @@ export const setCurrentEditingEnvironmentID = (currentEditingId: string) => ({ export const fetchingEnvironmentConfigs = ({ editorId, fetchDatasourceMeta = false, + mode, workspaceId, }: { editorId: string; fetchDatasourceMeta: boolean; workspaceId: string; + mode?: APP_MODE; }) => ({ type: "", - payload: { workspaceId, editorId, fetchDatasourceMeta }, + payload: { workspaceId, editorId, fetchDatasourceMeta, mode }, }); diff --git a/app/client/src/ce/entities/FeatureFlag.ts b/app/client/src/ce/entities/FeatureFlag.ts index 9fab664fe470..23b10ca1545b 100644 --- a/app/client/src/ce/entities/FeatureFlag.ts +++ b/app/client/src/ce/entities/FeatureFlag.ts @@ -36,8 +36,6 @@ export const FEATURE_FLAG = { release_ide_animations_enabled: "release_ide_animations_enabled", release_ide_datasource_selector_enabled: "release_ide_datasource_selector_enabled", - release_table_custom_loading_state_enabled: - "release_table_custom_loading_state_enabled", release_custom_widget_ai_builder: "release_custom_widget_ai_builder", ab_request_new_integration_enabled: "ab_request_new_integration_enabled", release_evaluation_scope_cache: "release_evaluation_scope_cache", @@ -86,7 +84,6 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = { release_git_persist_branch_enabled: false, release_ide_animations_enabled: false, release_ide_datasource_selector_enabled: false, - release_table_custom_loading_state_enabled: false, release_custom_widget_ai_builder: false, ab_request_new_integration_enabled: false, release_evaluation_scope_cache: false, diff --git a/app/client/src/ce/sagas/ApplicationSagas.tsx b/app/client/src/ce/sagas/ApplicationSagas.tsx index 463c80b0f34b..3eea5281824f 100644 --- a/app/client/src/ce/sagas/ApplicationSagas.tsx +++ b/app/client/src/ce/sagas/ApplicationSagas.tsx @@ -293,6 +293,7 @@ export function* fetchAppAndPagesSaga( payload: { workspaceId: response.data.workspaceId, editorId: response.data.application?.id, + mode: request.mode, }, }); diff --git a/app/client/src/components/editorComponents/PartialImportExport/PartialExportModal/unitTestUtils.ts b/app/client/src/components/editorComponents/PartialImportExport/PartialExportModal/unitTestUtils.ts index 1fe0cdb1451a..6caa81392991 100644 --- a/app/client/src/components/editorComponents/PartialImportExport/PartialExportModal/unitTestUtils.ts +++ b/app/client/src/components/editorComponents/PartialImportExport/PartialExportModal/unitTestUtils.ts @@ -10165,7 +10165,6 @@ export const defaultAppState = { controlType: "INPUT_TEXT", configProperty: "actionConfiguration.timeoutInMillisecond", dataType: "NUMBER", - width: "270px", }, ], }, @@ -10231,7 +10230,6 @@ export const defaultAppState = { controlType: "INPUT_TEXT", configProperty: "actionConfiguration.timeoutInMillisecond", dataType: "NUMBER", - width: "270px", }, ], }, diff --git a/app/client/src/components/formControls/DropDownControl.tsx b/app/client/src/components/formControls/DropDownControl.tsx index 972040517348..cf4796e2cedd 100644 --- a/app/client/src/components/formControls/DropDownControl.tsx +++ b/app/client/src/components/formControls/DropDownControl.tsx @@ -1,7 +1,6 @@ import React from "react"; import type { ControlProps } from "./BaseControl"; import BaseControl from "./BaseControl"; -import styled from "styled-components"; import type { ControlType } from "constants/PropertyControlConstants"; import { get, isEmpty, isNil } from "lodash"; import type { WrappedFieldInputProps, WrappedFieldMetaProps } from "redux-form"; @@ -19,13 +18,6 @@ import type { Action } from "entities/Action"; import type { SelectOptionProps } from "@appsmith/ads"; import { Icon, Option, Select } from "@appsmith/ads"; -const DropdownSelect = styled.div<{ - width: string; -}>` - /* font-size: 14px; */ - width: ${(props) => (props?.width ? props?.width : "270px")}; -`; - class DropDownControl extends BaseControl { componentDidUpdate(prevProps: Props) { // if options received by the fetchDynamicValues for the multi select changes, update the config property path's values. @@ -93,11 +85,10 @@ class DropDownControl extends BaseControl { }; return ( - { props={{ ...this.props, width: styles.width }} type={this.props?.isMultiSelect ? "select-multiple" : undefined} /> - + ); } diff --git a/app/client/src/components/formControls/DynamicInputTextControl.tsx b/app/client/src/components/formControls/DynamicInputTextControl.tsx index 9c5e21f02932..c67bfcf2de7c 100644 --- a/app/client/src/components/formControls/DynamicInputTextControl.tsx +++ b/app/client/src/components/formControls/DynamicInputTextControl.tsx @@ -13,7 +13,6 @@ import { EditorSize, } from "components/editorComponents/CodeEditor/EditorConfig"; import styled from "styled-components"; -import _ from "lodash"; // Enum for the different types of input fields export enum INPUT_TEXT_INPUT_TYPES { @@ -27,13 +26,16 @@ const StyledDynamicTextField = styled(DynamicTextField)` .CodeEditorTarget .CodeMirror.CodeMirror-wrap { background-color: var(--ads-v2-color-bg); } + .CodeEditorTarget .CodeMirror.CodeMirror-wrap:hover { background-color: var(--ads-v2-color-bg); border-color: var(--ads-v2-color-border-emphasis); } + &&& .t--code-editor-wrapper { border: none; } + .CodeEditorTarget { border-radius: var(--ads-v2-border-radius); } @@ -73,25 +75,8 @@ export function InputText(props: { }; } - let customStyle = { width: "270px", minHeight: "36px" }; - - if (!!props.customStyles && _.isEmpty(props.customStyles) === false) { - customStyle = { ...props.customStyles }; - - if ("width" in props.customStyles) { - customStyle.width = props.customStyles.width; - } - - if ("minHeight" in props.customStyles) { - customStyle.minHeight = props.customStyles.minHeight; - } - } - return ( -
+
{/*
*/} @@ -98,7 +95,6 @@ export interface DynamicTextFieldProps extends ControlProps { evaluationSubstitutionType: EvaluationSubstitutionType; mutedHinting?: boolean; pluginName: string; - isActionRedesignEnabled: boolean; } const mapStateToProps = (state: AppState, props: DynamicTextFieldProps) => { diff --git a/app/client/src/components/formControls/FieldArrayControl.tsx b/app/client/src/components/formControls/FieldArrayControl.tsx index 098914f2001e..09da6b63eda6 100644 --- a/app/client/src/components/formControls/FieldArrayControl.tsx +++ b/app/client/src/components/formControls/FieldArrayControl.tsx @@ -28,19 +28,16 @@ const PrimaryBox = styled.div` const SecondaryBox = styled.div` display: flex; flex-direction: row; - width: min-content; + width: 100%; align-items: center; justify-content: space-between; & > div { + flex: 1; margin-right: 8px; margin-bottom: 8px; } - & > .t--form-control-QUERY_DYNAMIC_INPUT_TEXT > div { - width: 20vw !important; - } - & > .t--form-control-DROP_DOWN, & > .t--form-control-DROP_DOWN > div > div, & > .t--form-control-DROP_DOWN > div > div > div > div { diff --git a/app/client/src/components/formControls/InputTextControl.tsx b/app/client/src/components/formControls/InputTextControl.tsx index 6d91e80f067a..466b8d960b98 100644 --- a/app/client/src/components/formControls/InputTextControl.tsx +++ b/app/client/src/components/formControls/InputTextControl.tsx @@ -23,8 +23,6 @@ const FieldWrapper = styled.div<{ width: string; }>` position: relative; - min-width: ${(props) => (props?.width ? props.width : "380px")}; - max-width: 545px; width: ${(props) => (props?.width ? props.width : "")}; `; @@ -193,6 +191,7 @@ class InputTextControl extends BaseControl { return "text"; } } + getControlType(): ControlType { return "INPUT_TEXT"; } diff --git a/app/client/src/constants/AppsmithActionConstants/formConfig/ApiSettingsConfig.ts b/app/client/src/constants/AppsmithActionConstants/formConfig/ApiSettingsConfig.ts index 103aff745a68..fd5a1aa73022 100644 --- a/app/client/src/constants/AppsmithActionConstants/formConfig/ApiSettingsConfig.ts +++ b/app/client/src/constants/AppsmithActionConstants/formConfig/ApiSettingsConfig.ts @@ -54,7 +54,6 @@ export default [ controlType: "INPUT_TEXT", configProperty: "actionConfiguration.timeoutInMillisecond", dataType: "NUMBER", - width: "270px", }, ], }, diff --git a/app/client/src/constants/AppsmithActionConstants/formConfig/GoogleSheetsSettingsConfig.ts b/app/client/src/constants/AppsmithActionConstants/formConfig/GoogleSheetsSettingsConfig.ts index 7ad33fde15e2..1e412ed1a235 100644 --- a/app/client/src/constants/AppsmithActionConstants/formConfig/GoogleSheetsSettingsConfig.ts +++ b/app/client/src/constants/AppsmithActionConstants/formConfig/GoogleSheetsSettingsConfig.ts @@ -21,7 +21,6 @@ export default [ configProperty: "actionConfiguration.timeoutInMillisecond", controlType: "INPUT_TEXT", dataType: "NUMBER", - width: "270px", }, ], }, diff --git a/app/client/src/constants/AppsmithActionConstants/formConfig/QuerySettingsConfig.ts b/app/client/src/constants/AppsmithActionConstants/formConfig/QuerySettingsConfig.ts index d5a4f038f08a..03ecbf2ace1f 100644 --- a/app/client/src/constants/AppsmithActionConstants/formConfig/QuerySettingsConfig.ts +++ b/app/client/src/constants/AppsmithActionConstants/formConfig/QuerySettingsConfig.ts @@ -21,7 +21,6 @@ export default [ configProperty: "actionConfiguration.timeoutInMillisecond", controlType: "INPUT_TEXT", dataType: "NUMBER", - width: "270px", }, ], }, diff --git a/app/client/src/sagas/EvaluationsSaga.test.ts b/app/client/src/sagas/EvaluationsSaga.test.ts index 87686bb4a3a1..9411d9a072ba 100644 --- a/app/client/src/sagas/EvaluationsSaga.test.ts +++ b/app/client/src/sagas/EvaluationsSaga.test.ts @@ -1,10 +1,14 @@ import { defaultAffectedJSObjects, + evalAndLintingHandler, evalQueueBuffer, evaluateTreeSaga, + evaluationLoopWithDebounce, + type BUFFERED_ACTION, } from "./EvaluationsSaga"; import { evalWorker } from "utils/workerInstances"; -import { expectSaga } from "redux-saga-test-plan"; +import { expectSaga, testSaga } from "redux-saga-test-plan"; + import { EVAL_WORKER_ACTIONS } from "ee/workers/Evaluation/evalWorkerActions"; import { select } from "redux-saga/effects"; import { getMetaWidgets, getWidgets, getWidgetsMeta } from "./selectors"; @@ -76,6 +80,7 @@ describe("evaluateTreeSaga", () => { widgetsMeta: {}, shouldRespondWithLogs: true, affectedJSObjects: { ids: [], isAllAffected: false }, + actionDataPayloadConsolidated: undefined, }) .run(); }); @@ -121,6 +126,7 @@ describe("evaluateTreeSaga", () => { widgetsMeta: {}, shouldRespondWithLogs: false, affectedJSObjects: { ids: [], isAllAffected: false }, + actionDataPayloadConsolidated: undefined, }) .run(); }); @@ -175,6 +181,7 @@ describe("evaluateTreeSaga", () => { widgetsMeta: {}, shouldRespondWithLogs: false, affectedJSObjects, + actionDataPayloadConsolidated: undefined, }) .run(); }); @@ -385,3 +392,136 @@ describe("evalQueueBuffer", () => { }); }); }); + +describe("evaluationLoopWithDebounce", () => { + describe("debounce", () => { + test("should call a regular evaluation with the consolidated action data payload when both updateActionData and evaluation action is triggered", async () => { + const buffer = evalQueueBuffer(); + + buffer.put( + updateActionData([ + { + entityName: "widget1", + dataPath: "data", + data: { a: 1 }, + dataPathRef: "", + }, + ]), + ); + buffer.put( + updateActionData([ + { + entityName: "widget2", + dataPath: "data", + data: { a: 2 }, + dataPathRef: "", + }, + ]), + ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + buffer.put(createJSCollectionSuccess({ id: "1" } as any)); + const action = buffer.take(); + + const mockChannel = "mock-channel"; + + // assert that a regular evaluation is only triggered and no evalTreeWithChanges evaluation is triggered + return ( + testSaga(evaluationLoopWithDebounce, mockChannel) + .next() + .take(mockChannel) + .next(action) + .call(evalAndLintingHandler, true, action, { + actionDataPayloadConsolidated: [ + { + entityName: "widget1", + dataPath: "data", + data: { a: 1 }, + dataPathRef: "", + }, + { + entityName: "widget2", + dataPath: "data", + data: { a: 2 }, + dataPathRef: "", + }, + ], + shouldReplay: undefined, + forceEvaluation: false, + requiresLogging: undefined, + affectedJSObjects: { isAllAffected: false, ids: ["1"] }, + }) + .next() + // wait for the next action in the event loop + .take(mockChannel) + ); + }); + test("should call an evalTreeWithChanges when only updateActionData actions are triggered", async () => { + const buffer = evalQueueBuffer(); + + buffer.put( + updateActionData([ + { + entityName: "widget1", + dataPath: "data", + data: { a: 1 }, + dataPathRef: "", + }, + ]), + ); + buffer.put( + updateActionData([ + { + entityName: "widget2", + dataPath: "data", + data: { a: 2 }, + dataPathRef: "", + }, + ]), + ); + const action = buffer.take() as unknown as BUFFERED_ACTION; + + const mockChannel = "mock-channel"; + + return ( + testSaga(evaluationLoopWithDebounce, mockChannel) + .next() + .take(mockChannel) + .next(action) + .call( + evalWorker.request, + EVAL_WORKER_ACTIONS.UPDATE_ACTION_DATA, + action.actionDataPayloadConsolidated, + ) + .next() + // wait for the next action in the event loop + .take(mockChannel) + ); + }); + test("should call a regular evaluation when evaluation actions are triggered", async () => { + const buffer = evalQueueBuffer(); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + buffer.put(createJSCollectionSuccess({ id: "1" } as any)); + + const action = buffer.take(); + + const mockChannel = "mock-channel"; + + return ( + testSaga(evaluationLoopWithDebounce, mockChannel) + .next() + .take(mockChannel) + .next(action) + .call(evalAndLintingHandler, true, action, { + shouldReplay: undefined, + forceEvaluation: false, + requiresLogging: undefined, + affectedJSObjects: { isAllAffected: false, ids: ["1"] }, + }) + .next() + // wait for the next action in the event loop + .take(mockChannel) + ); + }); + }); +}); diff --git a/app/client/src/sagas/EvaluationsSaga.ts b/app/client/src/sagas/EvaluationsSaga.ts index f0b067526904..18c4e04aa490 100644 --- a/app/client/src/sagas/EvaluationsSaga.ts +++ b/app/client/src/sagas/EvaluationsSaga.ts @@ -249,6 +249,7 @@ export function* evaluateTreeSaga( forceEvaluation = false, requiresLogging = false, affectedJSObjects: AffectedJSObjects = defaultAffectedJSObjects, + actionDataPayloadConsolidated?: actionDataPayload, ) { const allActionValidationConfig: ReturnType< typeof getAllActionValidationConfig @@ -291,6 +292,7 @@ export function* evaluateTreeSaga( widgetsMeta, shouldRespondWithLogs, affectedJSObjects, + actionDataPayloadConsolidated, }; const workerResponse: EvalTreeResponseData = yield call( @@ -542,7 +544,7 @@ export const defaultAffectedJSObjects: AffectedJSObjects = { ids: [], }; -interface BUFFERED_ACTION { +export interface BUFFERED_ACTION { hasDebouncedHandleUpdate: boolean; hasBufferedAction: boolean; actionDataPayloadConsolidated: actionDataPayload[]; @@ -674,7 +676,7 @@ function getPostEvalActions( return postEvalActions; } -function* evalAndLintingHandler( +export function* evalAndLintingHandler( isBlockingCall = true, action: ReduxAction, options: Partial<{ @@ -682,11 +684,17 @@ function* evalAndLintingHandler( forceEvaluation: boolean; requiresLogging: boolean; affectedJSObjects: AffectedJSObjects; + actionDataPayloadConsolidated: actionDataPayload[]; }>, ) { const span = startRootSpan("evalAndLintingHandler"); - const { affectedJSObjects, forceEvaluation, requiresLogging, shouldReplay } = - options; + const { + actionDataPayloadConsolidated, + affectedJSObjects, + forceEvaluation, + requiresLogging, + shouldReplay, + } = options; const requiresLinting = getRequiresLinting(action); @@ -728,6 +736,7 @@ function* evalAndLintingHandler( forceEvaluation, requiresLogging, affectedJSObjects, + actionDataPayloadConsolidated, ), ); } @@ -800,6 +809,13 @@ function* evaluationChangeListenerSaga(): any { evalQueueBuffer(), ); + yield call(evaluationLoopWithDebounce, evtActionChannel); +} + +export function* evaluationLoopWithDebounce( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + evtActionChannel: ActionPattern>, +) { while (true) { const action: EvaluationReduxAction = yield take(evtActionChannel); @@ -834,6 +850,23 @@ function* evaluationChangeListenerSaga(): any { hasDebouncedHandleUpdate, } = action as unknown as BUFFERED_ACTION; + // when there are both debounced action updates evaluation and a regular evaluation + // we will convert that to a regular evaluation this should help in performance by + // not performing a debounced action updates evaluation + if (hasDebouncedHandleUpdate && hasBufferedAction) { + const affectedJSObjects = getAffectedJSObjectIdsFromAction(action); + + yield call(evalAndLintingHandler, true, action, { + actionDataPayloadConsolidated, + shouldReplay: get(action, "payload.shouldReplay"), + forceEvaluation: shouldForceEval(action), + requiresLogging: shouldLog(action), + affectedJSObjects, + }); + + continue; + } + if (hasDebouncedHandleUpdate) { yield call( evalWorker.request, @@ -856,7 +889,6 @@ function* evaluationChangeListenerSaga(): any { } } } - // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any export function* evaluateActionSelectorFieldSaga(action: any) { diff --git a/app/client/src/widgets/JSONFormWidget/schemaParser.test.ts b/app/client/src/widgets/JSONFormWidget/schemaParser.test.ts index 947a1c48ac08..20e7ed8a6b99 100644 --- a/app/client/src/widgets/JSONFormWidget/schemaParser.test.ts +++ b/app/client/src/widgets/JSONFormWidget/schemaParser.test.ts @@ -1873,54 +1873,123 @@ describe(".normalizeArrayValue", () => { }); describe(".fieldTypeFor", () => { - it("return default field type of data passed", () => { - // TODO: Fix this the next time the file is edited - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const inputAndExpectedOutputs: [any, FieldType][] = [ - ["string", FieldType.TEXT_INPUT], - ["2021-12-30T10:36:12.1212+05:30", FieldType.DATEPICKER], - ["December 30, 2021 10:36 AM", FieldType.DATEPICKER], - ["December 30, 2021", FieldType.DATEPICKER], - ["2021-12-30 10:36", FieldType.DATEPICKER], - ["2021-12-30T10:36:12", FieldType.DATEPICKER], - ["2021-12-30 10:36:12 AM", FieldType.DATEPICKER], - ["30/12/2021 10:36", FieldType.DATEPICKER], - ["30 December, 2021", FieldType.DATEPICKER], - ["10:36 AM 30 December, 2021", FieldType.DATEPICKER], - ["2021-12-30", FieldType.DATEPICKER], - ["12-30-2021", FieldType.DATEPICKER], - ["30-12-2021", FieldType.DATEPICKER], - ["12/30/2021", FieldType.DATEPICKER], - ["30/12/2021", FieldType.DATEPICKER], - ["30/12/21", FieldType.DATEPICKER], - ["12/30/21", FieldType.DATEPICKER], - ["40/10/40", FieldType.TEXT_INPUT], - ["2000/10", FieldType.TEXT_INPUT], - ["1", FieldType.TEXT_INPUT], - ["#111", FieldType.TEXT_INPUT], - ["999", FieldType.TEXT_INPUT], - ["test@demo.com", FieldType.EMAIL_INPUT], - ["test@.com", FieldType.TEXT_INPUT], - [10, FieldType.NUMBER_INPUT], - [[{}], FieldType.ARRAY], - [[""], FieldType.MULTISELECT], - [[1], FieldType.MULTISELECT], - [[null], FieldType.MULTISELECT], - [null, FieldType.TEXT_INPUT], - [undefined, FieldType.TEXT_INPUT], - [{ foo: "" }, FieldType.OBJECT], - [ - () => { - 10; - }, - FieldType.TEXT_INPUT, - ], + it("returns appropriate field types for primitive values", () => { + const testCases = [ + { input: "simple text", expected: FieldType.TEXT_INPUT }, + { input: 42, expected: FieldType.NUMBER_INPUT }, + { input: true, expected: FieldType.SWITCH }, + { input: null, expected: FieldType.TEXT_INPUT }, + { input: undefined, expected: FieldType.TEXT_INPUT }, ]; - inputAndExpectedOutputs.forEach(([input, expectedOutput]) => { - const result = fieldTypeFor(input); + testCases.forEach(({ expected, input }) => { + expect(fieldTypeFor(input)).toEqual(expected); + }); + }); - expect(result).toEqual(expectedOutput); + it("detects email field type correctly", () => { + const testCases = [ + { input: "valid@email.com", expected: FieldType.EMAIL_INPUT }, + { input: "user.name+tag@example.co.uk", expected: FieldType.EMAIL_INPUT }, + { input: "invalid.email@", expected: FieldType.TEXT_INPUT }, + { input: "@invalid.com", expected: FieldType.TEXT_INPUT }, + { input: "not-an-email", expected: FieldType.TEXT_INPUT }, + ]; + + testCases.forEach(({ expected, input }) => { + expect(fieldTypeFor(input)).toEqual(expected); + }); + }); + + it("detects date field type correctly", () => { + const testCases = [ + { input: "2024-03-14", expected: FieldType.DATEPICKER }, + { input: "03/14/2024", expected: FieldType.DATEPICKER }, + { input: "14/03/2024", expected: FieldType.DATEPICKER }, + { input: "2024-03-14T15:30:00", expected: FieldType.DATEPICKER }, + { input: "March 14, 2024", expected: FieldType.DATEPICKER }, + { input: "not-a-date", expected: FieldType.TEXT_INPUT }, + { input: "99/99/9999", expected: FieldType.TEXT_INPUT }, + { + input: "2021-12-30T10:36:12.1212+05:30", + expected: FieldType.DATEPICKER, + }, + { input: "December 30, 2021 10:36 AM", expected: FieldType.DATEPICKER }, + { input: "2021-12-30 10:36", expected: FieldType.DATEPICKER }, + { input: "2021-12-30 10:36:12 AM", expected: FieldType.DATEPICKER }, + { input: "30/12/2021 10:36", expected: FieldType.DATEPICKER }, + { input: "30 December, 2021", expected: FieldType.DATEPICKER }, + { input: "10:36 AM 30 December, 2021", expected: FieldType.DATEPICKER }, + ]; + + testCases.forEach(({ expected, input }) => { + expect(fieldTypeFor(input)).toEqual(expected); + }); + }); + + it("determines array field types correctly", () => { + const testCases = [ + { + input: [ + { id: 1, name: "test1" }, + { id: 2, name: "test2" }, + ], + expected: FieldType.ARRAY, + }, + { + input: ["option1", "option2"], + expected: FieldType.MULTISELECT, + }, + { + input: [1, 2, 3], + expected: FieldType.MULTISELECT, + }, + { + input: [], + expected: FieldType.MULTISELECT, + }, + { + input: [["nested"], ["arrays"]], + expected: FieldType.ARRAY, + }, + ]; + + testCases.forEach(({ expected, input }) => { + expect(fieldTypeFor(input)).toEqual(expected); + }); + }); + + it("handles object field types correctly", () => { + const testCases = [ + { + input: { key: "value" }, + expected: FieldType.OBJECT, + }, + { + input: { nested: { object: true } }, + expected: FieldType.OBJECT, + }, + { + input: {}, + expected: FieldType.OBJECT, + }, + ]; + + testCases.forEach(({ expected, input }) => { + expect(fieldTypeFor(input)).toEqual(expected); + }); + }); + + it("handles special cases and edge values", () => { + const testCases = [ + { input: () => {}, expected: FieldType.TEXT_INPUT }, + { input: Symbol("test"), expected: FieldType.TEXT_INPUT }, + { input: BigInt(9007199254740991), expected: FieldType.NUMBER_INPUT }, + { input: NaN, expected: FieldType.NUMBER_INPUT }, + ]; + + testCases.forEach(({ expected, input }) => { + expect(fieldTypeFor(input)).toEqual(expected); }); }); }); diff --git a/app/client/src/widgets/JSONFormWidget/schemaParser.ts b/app/client/src/widgets/JSONFormWidget/schemaParser.ts index 42c4724f9ec1..da63757acc9c 100644 --- a/app/client/src/widgets/JSONFormWidget/schemaParser.ts +++ b/app/client/src/widgets/JSONFormWidget/schemaParser.ts @@ -183,9 +183,7 @@ export const getSourceDataPathFromSchemaItemPath = ( return sourceDataPath; }; -// TODO: Fix this the next time the file is edited -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const dataTypeFor = (value: any) => { +export const dataTypeFor = (value: unknown) => { const typeOfValue = typeof value; if (Array.isArray(value)) return DataType.ARRAY; @@ -195,13 +193,11 @@ export const dataTypeFor = (value: any) => { return typeOfValue as DataType; }; -// TODO: Fix this the next time the file is edited -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export const subDataTypeFor = (value: any) => { +export const subDataTypeFor = (value: unknown) => { const dataType = dataTypeFor(value); if (dataType === DataType.ARRAY) { - return dataTypeFor(value[0]); + return dataTypeFor((value as unknown[])[0]); } return undefined; @@ -352,6 +348,13 @@ export const checkIfArrayAndSubDataTypeChanged = ( const currSubDataType = subDataTypeFor(currentData); const prevSubDataType = subDataTypeFor(prevData); + /** + * If the array is empty, then we don't need to check for sub data type + * as it would be an empty array, which will always be `undefined`. + * which leads to unnecessary re calculation of a type(https://github.com/appsmithorg/appsmith/issues/37246) + */ + if (currentData.length === 0 || prevData.length === 0) return false; + return currSubDataType !== prevSubDataType; }; diff --git a/app/client/src/widgets/TableWidgetV2/constants.ts b/app/client/src/widgets/TableWidgetV2/constants.ts index 717cda817ab6..35d1e7eaee1b 100644 --- a/app/client/src/widgets/TableWidgetV2/constants.ts +++ b/app/client/src/widgets/TableWidgetV2/constants.ts @@ -244,8 +244,5 @@ export const DEFAULT_COLUMN_NAME = "Table Column"; export const ALLOW_TABLE_WIDGET_SERVER_SIDE_FILTERING = FEATURE_FLAG["release_table_serverside_filtering_enabled"]; -export const CUSTOM_LOADING_STATE_ENABLED = - FEATURE_FLAG["release_table_custom_loading_state_enabled"]; - export const HTML_COLUMN_TYPE_ENABLED = FEATURE_FLAG["release_table_html_column_type_enabled"]; diff --git a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/contentConfig.ts b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/contentConfig.ts index 580daa70f83f..1484cced338d 100644 --- a/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/contentConfig.ts +++ b/app/client/src/widgets/TableWidgetV2/widget/propertyConfig/contentConfig.ts @@ -7,10 +7,7 @@ import { ValidationTypes } from "constants/WidgetValidation"; import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory"; import { AutocompleteDataType } from "utils/autocomplete/AutocompleteDataType"; import type { TableWidgetProps } from "widgets/TableWidgetV2/constants"; -import { - ALLOW_TABLE_WIDGET_SERVER_SIDE_FILTERING, - CUSTOM_LOADING_STATE_ENABLED, -} from "../../constants"; +import { ALLOW_TABLE_WIDGET_SERVER_SIDE_FILTERING } from "../../constants"; import { InlineEditingSaveOptions } from "widgets/TableWidgetV2/constants"; import { composePropertyUpdateHook } from "widgets/WidgetUtils"; import { @@ -513,7 +510,6 @@ export default [ isBindProperty: true, isTriggerProperty: false, validation: { type: ValidationTypes.BOOLEAN }, - hidden: () => !Widget.getFeatureFlag(CUSTOM_LOADING_STATE_ENABLED), }, { propertyName: "customIsLoadingValue", diff --git a/app/client/src/workers/Evaluation/fns/utils/TriggerEmitter.ts b/app/client/src/workers/Evaluation/fns/utils/TriggerEmitter.ts index df79758b4ba9..86040aca12d2 100644 --- a/app/client/src/workers/Evaluation/fns/utils/TriggerEmitter.ts +++ b/app/client/src/workers/Evaluation/fns/utils/TriggerEmitter.ts @@ -4,7 +4,7 @@ import { WorkerMessenger } from "workers/Evaluation/fns/utils/Messenger"; import type { UpdatedPathsMap } from "workers/Evaluation/JSObject/JSVariableUpdates"; import { applyJSVariableUpdatesToEvalTree } from "workers/Evaluation/JSObject/JSVariableUpdates"; import ExecutionMetaData from "./ExecutionMetaData"; -import type { UpdateActionProps } from "workers/Evaluation/handlers/updateActionData"; +import type { UpdateActionProps } from "workers/Evaluation/handlers/types"; import { handleActionsDataUpdate } from "workers/Evaluation/handlers/updateActionData"; import { getEntityNameAndPropertyPath } from "ee/workers/Evaluation/evaluationUtils"; import type { Patch } from "workers/Evaluation/JSObject/Collection"; diff --git a/app/client/src/workers/Evaluation/handlers/evalTree.ts b/app/client/src/workers/Evaluation/handlers/evalTree.ts index c8e53a4fc9e3..52b6ccacd908 100644 --- a/app/client/src/workers/Evaluation/handlers/evalTree.ts +++ b/app/client/src/workers/Evaluation/handlers/evalTree.ts @@ -34,6 +34,7 @@ import { import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; import type { MetaWidgetsReduxState } from "reducers/entityReducers/metaWidgetsReducer"; import type { Attributes } from "instrumentation/types"; +import { updateActionsToEvalTree } from "./updateActionData"; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -70,6 +71,7 @@ export async function evalTree( let isNewWidgetAdded = false; const { + actionDataPayloadConsolidated, affectedJSObjects, allActionValidationConfig, appMode, @@ -190,6 +192,13 @@ export async function evalTree( }); staleMetaIds = dataTreeResponse.staleMetaIds; } else { + const tree = dataTreeEvaluator.getEvalTree(); + + // during update cycles update actions to the dataTree directly + // this is useful in cases where we have debounced updateActionData and a regular evaluation + // triggered together, in those cases we merge them both into a regular evaluation + updateActionsToEvalTree(tree, actionDataPayloadConsolidated); + if (dataTreeEvaluator && !isEmpty(allActionValidationConfig)) { dataTreeEvaluator.setAllActionValidationConfig( allActionValidationConfig, @@ -212,6 +221,7 @@ export async function evalTree( configTree, webworkerTelemetry, affectedJSObjects, + actionDataPayloadConsolidated, ), ); diff --git a/app/client/src/workers/Evaluation/handlers/types.ts b/app/client/src/workers/Evaluation/handlers/types.ts new file mode 100644 index 000000000000..a1e2d0b3dc02 --- /dev/null +++ b/app/client/src/workers/Evaluation/handlers/types.ts @@ -0,0 +1,6 @@ +export interface UpdateActionProps { + entityName: string; + dataPath: string; + data: unknown; + dataPathRef?: string; +} diff --git a/app/client/src/workers/Evaluation/handlers/updateActionData.ts b/app/client/src/workers/Evaluation/handlers/updateActionData.ts index dadf1f5654e5..ccb3f6693e69 100644 --- a/app/client/src/workers/Evaluation/handlers/updateActionData.ts +++ b/app/client/src/workers/Evaluation/handlers/updateActionData.ts @@ -4,13 +4,9 @@ import set from "lodash/set"; import { evalTreeWithChanges } from "../evalTreeWithChanges"; import DataStore from "../dataStore"; import { EVAL_WORKER_SYNC_ACTION } from "ee/workers/Evaluation/evalWorkerActions"; +import type { DataTree } from "entities/DataTree/dataTreeTypes"; +import type { UpdateActionProps } from "./types"; -export interface UpdateActionProps { - entityName: string; - dataPath: string; - data: unknown; - dataPathRef?: string; -} export default function (request: EvalWorkerSyncRequest) { const actionsDataToUpdate: UpdateActionProps[] = request.data; @@ -26,6 +22,29 @@ export function handleActionsDataUpdate(actionsToUpdate: UpdateActionProps[]) { const evalTree = dataTreeEvaluator.getEvalTree(); + updateActionsToEvalTree(evalTree, actionsToUpdate); + + const updatedProperties: string[][] = []; + + actionsToUpdate.forEach(({ dataPath, entityName }) => { + updatedProperties.push([entityName, dataPath]); + }); + evalTreeWithChanges({ + data: { + updatedValuePaths: updatedProperties, + metaUpdates: [], + }, + method: EVAL_WORKER_SYNC_ACTION.EVAL_TREE_WITH_CHANGES, + webworkerTelemetry: {}, + }); +} + +export function updateActionsToEvalTree( + evalTree: DataTree, + actionsToUpdate?: UpdateActionProps[], +) { + if (!actionsToUpdate) return; + for (const actionToUpdate of actionsToUpdate) { const { dataPath, dataPathRef, entityName } = actionToUpdate; let { data } = actionToUpdate; @@ -44,18 +63,4 @@ export function handleActionsDataUpdate(actionsToUpdate: UpdateActionProps[]) { DataStore.setActionData(path, data); } - - const updatedProperties: string[][] = []; - - actionsToUpdate.forEach(({ dataPath, entityName }) => { - updatedProperties.push([entityName, dataPath]); - }); - evalTreeWithChanges({ - data: { - updatedValuePaths: updatedProperties, - metaUpdates: [], - }, - method: EVAL_WORKER_SYNC_ACTION.EVAL_TREE_WITH_CHANGES, - webworkerTelemetry: {}, - }); } diff --git a/app/client/src/workers/Evaluation/types.ts b/app/client/src/workers/Evaluation/types.ts index 97adaa6fc2b4..a6e450e9d1cd 100644 --- a/app/client/src/workers/Evaluation/types.ts +++ b/app/client/src/workers/Evaluation/types.ts @@ -18,6 +18,7 @@ import type { APP_MODE } from "entities/App"; import type { WebworkerSpanData, Attributes } from "instrumentation/types"; import type { ICacheProps } from "../common/AppComputationCache/types"; import type { AffectedJSObjects } from "actions/EvaluationReduxActionTypes"; +import type { UpdateActionProps } from "./handlers/types"; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -51,6 +52,7 @@ export interface EvalTreeRequestData { widgetsMeta: Record; shouldRespondWithLogs?: boolean; affectedJSObjects: AffectedJSObjects; + actionDataPayloadConsolidated?: UpdateActionProps[]; } export interface EvalTreeResponseData { diff --git a/app/client/src/workers/common/DataTreeEvaluator/dataTreeEvaluator.test.ts b/app/client/src/workers/common/DataTreeEvaluator/dataTreeEvaluator.test.ts index ee6a876ee267..514fc3691f91 100644 --- a/app/client/src/workers/common/DataTreeEvaluator/dataTreeEvaluator.test.ts +++ b/app/client/src/workers/common/DataTreeEvaluator/dataTreeEvaluator.test.ts @@ -379,6 +379,67 @@ describe("DataTreeEvaluator", () => { }); }); + describe("actionsToUpdate affects setupTree", () => { + beforeEach(async () => { + await dataTreeEvaluator.setupFirstTree( + unEvalTree as unknown as DataTree, + configTree as unknown as ConfigTree, + {}, + { + appId: "appId", + pageId: "pageId", + timestamp: "timestamp", + appMode: APP_MODE.PUBLISHED, + instanceId: "instanceId", + }, + ); + dataTreeEvaluator.evalAndValidateFirstTree(); + }); + describe("when unevalTree is the same", () => { + it("should not call the setupTree when there are actionsToUpdate", () => { + const spy = jest.spyOn(dataTreeEvaluator, "setupTree"); + + dataTreeEvaluator.setupUpdateTree( + unEvalTree as unknown as DataTree, + configTree as unknown as ConfigTree, + undefined, + undefined, + [], + ); + + expect(spy).not.toHaveBeenCalled(); + }); + it("should pass in actionsToUpdate as updatedValuePaths to the setupTree", () => { + const spy = jest.spyOn(dataTreeEvaluator, "setupTree"); + + dataTreeEvaluator.setupUpdateTree( + unEvalTree as unknown as DataTree, + configTree as unknown as ConfigTree, + undefined, + undefined, + [ + { + entityName: "JSAction1", + dataPath: "data", + data: ["Some data"], + }, + ], + ); + + expect(spy).toHaveBeenCalledWith( + expect.anything(), + [["JSAction1", "data"]], + { + dependenciesOfRemovedPaths: [], + pathsToSkipFromEval: ["JSAction1.data"], + removedPaths: [], + translatedDiffs: [], + }, + ); + }); + }); + }); + describe("array accessor dependency handling", () => { const dataTreeEvaluator = new DataTreeEvaluator(widgetConfigMap); diff --git a/app/client/src/workers/common/DataTreeEvaluator/index.ts b/app/client/src/workers/common/DataTreeEvaluator/index.ts index 8f2eb2f09557..dd4e33d8ff88 100644 --- a/app/client/src/workers/common/DataTreeEvaluator/index.ts +++ b/app/client/src/workers/common/DataTreeEvaluator/index.ts @@ -155,6 +155,7 @@ import { getDataTreeContext } from "ee/workers/Evaluation/Actions"; import { WorkerEnv } from "workers/Evaluation/handlers/workerEnv"; import type { WebworkerSpanData, Attributes } from "instrumentation/types"; import type { AffectedJSObjects } from "actions/EvaluationReduxActionTypes"; +import type { UpdateActionProps } from "workers/Evaluation/handlers/types"; type SortedDependencies = Array; export interface EvalProps { @@ -637,6 +638,7 @@ export default class DataTreeEvaluator { configTree: ConfigTree, webworkerTelemetry: Record = {}, affectedJSObjects: AffectedJSObjects = { isAllAffected: false, ids: [] }, + actionDataPayloadConsolidated?: UpdateActionProps[], ): { unEvalUpdates: DataTreeDiff[]; evalOrder: string[]; @@ -677,7 +679,7 @@ export default class DataTreeEvaluator { // Since eval tree is listening to possible events that don't cause differences // We want to check if no diffs are present and bail out early - if (differences.length === 0) { + if (differences.length === 0 && !actionDataPayloadConsolidated?.length) { return { removedPaths: [], unEvalUpdates: [], @@ -724,7 +726,12 @@ export default class DataTreeEvaluator { this.dependencies = dependencies; this.inverseDependencies = inverseDependencies; - const pathsChangedSet = new Set(); + const pathsChangedSet = new Set( + actionDataPayloadConsolidated?.map(({ dataPath, entityName }) => [ + entityName, + dataPath, + ]) || [], + ); for (const diff of differences) { if (isArray(diff.path)) { @@ -735,16 +742,23 @@ export default class DataTreeEvaluator { const updatedValuePaths = [...pathsChangedSet]; this.updateEvalTreeWithChanges({ differences }); - const setupUpdateTreeOutput = profileFn( "setupTree", undefined, webworkerTelemetry, () => { + const pathsToSkipFromEval = + actionDataPayloadConsolidated + ?.map(({ dataPath, entityName }) => { + return [entityName, dataPath]; + }) + .map((path: string[]) => path.join(".")) || []; + return this.setupTree(updatedUnEvalTreeJSObjects, updatedValuePaths, { dependenciesOfRemovedPaths, removedPaths, translatedDiffs, + pathsToSkipFromEval, }); }, ); diff --git a/app/client/test/factories/MockPluginsState.ts b/app/client/test/factories/MockPluginsState.ts index 636a21f5afbd..ebbe018e2049 100644 --- a/app/client/test/factories/MockPluginsState.ts +++ b/app/client/test/factories/MockPluginsState.ts @@ -7007,7 +7007,6 @@ export default { controlType: "INPUT_TEXT", configProperty: "actionConfiguration.timeoutInMillisecond", dataType: "NUMBER", - width: "270px", }, ], }, @@ -7073,7 +7072,6 @@ export default { controlType: "INPUT_TEXT", configProperty: "actionConfiguration.timeoutInMillisecond", dataType: "NUMBER", - width: "270px", }, ], }, diff --git a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/setting.json b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/setting.json index cb5ad8bfc24f..b7cc1753e1b5 100644 --- a/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/amazons3Plugin/src/main/resources/setting.json @@ -27,8 +27,7 @@ "subtitle": "Maximum time after which the query will return", "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/chat.json b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/chat.json index a1621376380e..b212efd4e0ff 100644 --- a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/chat.json +++ b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/chat.json @@ -44,11 +44,7 @@ "controlType": "INPUT_TEXT", "initialValue": "256", "isRequired": true, - "dataType": "NUMBER", - "customStyles": { - "width": "270px", - "minWidth": "270px" - } + "dataType": "NUMBER" } ] }, @@ -63,11 +59,7 @@ "controlType": "QUERY_DYNAMIC_TEXT", "placeholderText": "Write some text or use {{ }} to reference a dynamic text value", "initialValue": "", - "isRequired": false, - "customStyles": { - "width": "590px", - "minWidth": "400px" - } + "isRequired": false }, { "label": "Messages", @@ -118,11 +110,7 @@ "controlType": "INPUT_TEXT", "dataType": "NUMBER", "initialValue": "1", - "isRequired": false, - "customStyles": { - "width": "270px", - "minWidth": "270px" - } + "isRequired": false } ] } diff --git a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/vision.json b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/vision.json index 282ddac5355b..74fe25a4f8db 100644 --- a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/vision.json +++ b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/editor/vision.json @@ -44,11 +44,7 @@ "controlType": "INPUT_TEXT", "initialValue": "256", "isRequired": true, - "dataType": "NUMBER", - "customStyles": { - "width": "270px", - "minWidth": "270px" - } + "dataType": "NUMBER" } ] }, @@ -130,11 +126,7 @@ "controlType": "INPUT_TEXT", "dataType": "NUMBER", "initialValue": "1", - "isRequired": false, - "customStyles": { - "width": "270px", - "minWidth": "270px" - } + "isRequired": false } ] } diff --git a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/setting.json index f24806929a67..7fb951ba3a07 100644 --- a/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/anthropicPlugin/src/main/resources/setting.json @@ -21,8 +21,7 @@ "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", "initialValue": 60000, - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/resources/setting.json index f24806929a67..7fb951ba3a07 100644 --- a/app/server/appsmith-plugins/appsmithAiPlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/appsmithAiPlugin/src/main/resources/setting.json @@ -21,8 +21,7 @@ "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", "initialValue": 60000, - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/setting.json index 10edd6468460..83026f023cf8 100644 --- a/app/server/appsmith-plugins/firestorePlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/firestorePlugin/src/main/resources/setting.json @@ -27,8 +27,7 @@ "subtitle": "Maximum time after which the query will return", "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/googleAiPlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/googleAiPlugin/src/main/resources/setting.json index f24806929a67..7fb951ba3a07 100644 --- a/app/server/appsmith-plugins/googleAiPlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/googleAiPlugin/src/main/resources/setting.json @@ -21,8 +21,7 @@ "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", "initialValue": 60000, - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json index 9d8c67c9ffc8..c48f7ad9e163 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/form.json @@ -53,9 +53,6 @@ } ], "initialValue": "https://www.googleapis.com/auth/drive.file", - "customStyles": { - "width": "340px" - }, "hidden": { "flagValue": "release_gs_all_sheets_options_enabled", "comparison": "FEATURE_FLAG", @@ -73,9 +70,6 @@ } ], "initialValue": "https://www.googleapis.com/auth/drive.file", - "customStyles": { - "width": "340px" - }, "hidden": { "flagValue": "release_gs_all_sheets_options_enabled", "comparison": "FEATURE_FLAG", diff --git a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/setting.json index ac19bcf35b43..e3c0e476cd4b 100644 --- a/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/googleSheetsPlugin/src/main/resources/setting.json @@ -27,8 +27,7 @@ "subtitle": "Maximum time after which the query will return", "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/setting.json index 7c673d6df3e1..6ff7548ee5a4 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/resources/setting.json @@ -27,8 +27,7 @@ "subtitle": "Maximum time after which the query will return", "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/mssqlPlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/mssqlPlugin/src/main/resources/setting.json index 3796dc7c50f8..105a4b98b6a4 100644 --- a/app/server/appsmith-plugins/mssqlPlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/mssqlPlugin/src/main/resources/setting.json @@ -27,8 +27,7 @@ "subtitle": "Maximum time after which the query will return", "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/mysqlPlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/mysqlPlugin/src/main/resources/setting.json index 3796dc7c50f8..105a4b98b6a4 100644 --- a/app/server/appsmith-plugins/mysqlPlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/mysqlPlugin/src/main/resources/setting.json @@ -27,8 +27,7 @@ "subtitle": "Maximum time after which the query will return", "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/openAiPlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/openAiPlugin/src/main/resources/setting.json index f24806929a67..7fb951ba3a07 100644 --- a/app/server/appsmith-plugins/openAiPlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/openAiPlugin/src/main/resources/setting.json @@ -21,8 +21,7 @@ "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", "initialValue": 60000, - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/oraclePlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/oraclePlugin/src/main/resources/setting.json index e75716975b22..5976f0c624fc 100755 --- a/app/server/appsmith-plugins/oraclePlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/oraclePlugin/src/main/resources/setting.json @@ -27,8 +27,7 @@ "subtitle": "Maximum time after which the query will return", "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] } diff --git a/app/server/appsmith-plugins/postgresPlugin/src/main/resources/setting.json b/app/server/appsmith-plugins/postgresPlugin/src/main/resources/setting.json index 3796dc7c50f8..105a4b98b6a4 100644 --- a/app/server/appsmith-plugins/postgresPlugin/src/main/resources/setting.json +++ b/app/server/appsmith-plugins/postgresPlugin/src/main/resources/setting.json @@ -27,8 +27,7 @@ "subtitle": "Maximum time after which the query will return", "configProperty": "actionConfiguration.timeoutInMillisecond", "controlType": "INPUT_TEXT", - "dataType": "NUMBER", - "width": "270px" + "dataType": "NUMBER" } ] }