## Description - Remove the config objects from widget and config maps from the widget factory. - Introduce methods in widget development API to dynamically fetch this items. - freeze the widget configuration. #### PR fixes following issue(s) Fixes https://github.com/appsmithorg/appsmith/issues/26008 > 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 - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### 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 - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] 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/Guidelines-for-test-plans#speedbreakers-) have been covered - [x] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [x] 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
248 lines
7.7 KiB
TypeScript
248 lines
7.7 KiB
TypeScript
import {
|
|
LayoutDirection,
|
|
Positioning,
|
|
ResponsiveBehavior,
|
|
} from "utils/autoLayout/constants";
|
|
import FlexBoxComponent from "components/designSystems/appsmith/autoLayout/FlexBoxComponent";
|
|
import DropTargetComponent from "components/editorComponents/DropTargetComponent";
|
|
import { CANVAS_DEFAULT_MIN_HEIGHT_PX } from "constants/AppConstants";
|
|
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
|
import { GridDefaults, RenderModes } from "constants/WidgetConstants";
|
|
import { CanvasDraggingArena } from "pages/common/CanvasArenas/CanvasDraggingArena";
|
|
import { CanvasSelectionArena } from "pages/common/CanvasArenas/CanvasSelectionArena";
|
|
import WidgetsMultiSelectBox from "pages/Editor/WidgetsMultiSelectBox";
|
|
import type { CSSProperties } from "react";
|
|
import React from "react";
|
|
import { getCanvasClassName } from "utils/generators";
|
|
import type { DerivedPropertiesMap } from "WidgetProvider/factory";
|
|
import WidgetFactory from "WidgetProvider/factory";
|
|
import { getCanvasSnapRows } from "utils/WidgetPropsUtils";
|
|
import type { WidgetProps } from "widgets/BaseWidget";
|
|
import type { ContainerWidgetProps } from "widgets/ContainerWidget/widget";
|
|
import ContainerWidget from "widgets/ContainerWidget/widget";
|
|
import type {
|
|
CanvasWidgetStructure,
|
|
DSLWidget,
|
|
WidgetDefaultProps,
|
|
} from "../WidgetProvider/constants";
|
|
import ContainerComponent from "./ContainerWidget/component";
|
|
import { AppPositioningTypes } from "reducers/entityReducers/pageListReducer";
|
|
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
|
import type { SetterConfig } from "entities/AppTheming";
|
|
|
|
class CanvasWidget extends ContainerWidget {
|
|
static type = "CANVAS_WIDGET";
|
|
|
|
static getConfig() {
|
|
return {
|
|
name: "Canvas",
|
|
hideCard: true,
|
|
eagerRender: true,
|
|
};
|
|
}
|
|
|
|
static getDefaults(): WidgetDefaultProps {
|
|
return {
|
|
rows: 0,
|
|
columns: 0,
|
|
widgetName: "Canvas",
|
|
version: 1,
|
|
detachFromLayout: true,
|
|
flexLayers: [],
|
|
responsiveBehavior: ResponsiveBehavior.Fill,
|
|
minWidth: FILL_WIDGET_MIN_WIDTH,
|
|
};
|
|
}
|
|
|
|
static getPropertyPaneConfig() {
|
|
return [];
|
|
}
|
|
|
|
static getAutocompleteDefinitions(): AutocompletionDefinitions {
|
|
return {};
|
|
}
|
|
|
|
static getSetterConfig(): SetterConfig | null {
|
|
return null;
|
|
}
|
|
|
|
getCanvasProps(): DSLWidget & { minHeight: number } {
|
|
return {
|
|
...this.props,
|
|
parentRowSpace: 1,
|
|
parentColumnSpace: 1,
|
|
topRow: 0,
|
|
leftColumn: 0,
|
|
containerStyle: "none",
|
|
detachFromLayout: true,
|
|
minHeight: this.props.minHeight || CANVAS_DEFAULT_MIN_HEIGHT_PX,
|
|
shouldScrollContents: false,
|
|
};
|
|
}
|
|
|
|
renderAsDropTarget() {
|
|
const canvasProps = this.getCanvasProps();
|
|
const { snapColumnSpace } = this.getSnapSpaces();
|
|
return (
|
|
<DropTargetComponent
|
|
bottomRow={this.props.bottomRow}
|
|
isListWidgetCanvas={this.props.isListWidgetCanvas}
|
|
isMobile={this.props.isMobile}
|
|
minHeight={this.props.minHeight || CANVAS_DEFAULT_MIN_HEIGHT_PX}
|
|
mobileBottomRow={this.props.mobileBottomRow}
|
|
noPad={this.props.noPad}
|
|
parentId={this.props.parentId}
|
|
snapColumnSpace={snapColumnSpace}
|
|
useAutoLayout={this.props.useAutoLayout}
|
|
widgetId={this.props.widgetId}
|
|
>
|
|
{this.renderAsContainerComponent(canvasProps)}
|
|
</DropTargetComponent>
|
|
);
|
|
}
|
|
|
|
renderChildWidget(childWidgetData: CanvasWidgetStructure): React.ReactNode {
|
|
if (!childWidgetData) return null;
|
|
|
|
const childWidget = { ...childWidgetData };
|
|
|
|
const snapSpaces = this.getSnapSpaces();
|
|
childWidget.parentColumnSpace = snapSpaces.snapColumnSpace;
|
|
childWidget.parentRowSpace = snapSpaces.snapRowSpace;
|
|
if (this.props.noPad) childWidget.noContainerOffset = true;
|
|
childWidget.parentId = this.props.widgetId;
|
|
// Pass layout controls to children
|
|
childWidget.positioning =
|
|
childWidget?.positioning || this.props.positioning;
|
|
childWidget.isFlexChild = this.props.useAutoLayout;
|
|
childWidget.direction = this.getDirection();
|
|
|
|
return WidgetFactory.createWidget(childWidget, this.props.renderMode);
|
|
}
|
|
|
|
renderAsContainerComponent(
|
|
props: ContainerWidgetProps<WidgetProps>,
|
|
): JSX.Element {
|
|
const direction = this.getDirection();
|
|
const snapRows = getCanvasSnapRows(
|
|
this.props.bottomRow,
|
|
this.props.mobileBottomRow,
|
|
this.props.isMobile,
|
|
this.props.appPositioningType === AppPositioningTypes.AUTO,
|
|
);
|
|
return (
|
|
<ContainerComponent {...props}>
|
|
{props.renderMode === RenderModes.CANVAS && (
|
|
<>
|
|
<CanvasDraggingArena
|
|
{...this.getSnapSpaces()}
|
|
alignItems={props.alignItems}
|
|
canExtend={props.canExtend}
|
|
direction={direction}
|
|
dropDisabled={!!props.dropDisabled}
|
|
noPad={this.props.noPad}
|
|
parentId={props.parentId}
|
|
snapRows={snapRows}
|
|
useAutoLayout={this.props.useAutoLayout}
|
|
widgetId={props.widgetId}
|
|
widgetName={props.widgetName}
|
|
/>
|
|
<CanvasSelectionArena
|
|
{...this.getSnapSpaces()}
|
|
canExtend={props.canExtend}
|
|
dropDisabled={!!props.dropDisabled}
|
|
parentId={props.parentId}
|
|
snapRows={snapRows}
|
|
widgetId={props.widgetId}
|
|
/>
|
|
</>
|
|
)}
|
|
{this.props.useAutoLayout
|
|
? this.renderFlexCanvas(direction)
|
|
: this.renderFixedCanvas(props)}
|
|
</ContainerComponent>
|
|
);
|
|
}
|
|
|
|
renderFlexCanvas(direction: LayoutDirection) {
|
|
const stretchFlexBox = !this.props.children || !this.props.children?.length;
|
|
return (
|
|
<FlexBoxComponent
|
|
direction={direction}
|
|
flexLayers={this.props.flexLayers || []}
|
|
isMobile={this.props.isMobile || false}
|
|
stretchHeight={stretchFlexBox}
|
|
useAutoLayout={this.props.useAutoLayout || false}
|
|
widgetId={this.props.widgetId}
|
|
>
|
|
{this.renderChildren()}
|
|
</FlexBoxComponent>
|
|
);
|
|
}
|
|
|
|
renderFixedCanvas(props: ContainerWidgetProps<WidgetProps>) {
|
|
return (
|
|
<>
|
|
<WidgetsMultiSelectBox
|
|
{...this.getSnapSpaces()}
|
|
noContainerOffset={!!props.noContainerOffset}
|
|
widgetId={this.props.widgetId}
|
|
widgetType={this.props.type}
|
|
/>
|
|
{this.renderChildren()}
|
|
</>
|
|
);
|
|
}
|
|
|
|
getDirection(): LayoutDirection {
|
|
return this.props.positioning === Positioning.Vertical
|
|
? LayoutDirection.Vertical
|
|
: LayoutDirection.Horizontal;
|
|
}
|
|
|
|
getPageView() {
|
|
let height = 0;
|
|
const snapRows = getCanvasSnapRows(
|
|
this.props.bottomRow,
|
|
this.props.mobileBottomRow,
|
|
this.props.isMobile,
|
|
this.props.appPositioningType === AppPositioningTypes.AUTO,
|
|
);
|
|
height = snapRows * GridDefaults.DEFAULT_GRID_ROW_HEIGHT;
|
|
const style: CSSProperties = {
|
|
width: "100%",
|
|
height: this.props.isListWidgetCanvas ? "auto" : `${height}px`,
|
|
background: "none",
|
|
position: "relative",
|
|
};
|
|
// This div is the DropTargetComponent alternative for the page view
|
|
// DropTargetComponent and this div are responsible for the canvas height
|
|
return (
|
|
<div className={getCanvasClassName()} style={style}>
|
|
{this.renderAsContainerComponent(this.getCanvasProps())}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
getCanvasView() {
|
|
if (!this.props.dropDisabled) {
|
|
return this.renderAsDropTarget();
|
|
}
|
|
return this.getPageView();
|
|
}
|
|
|
|
static getDerivedPropertiesMap(): DerivedPropertiesMap {
|
|
return {};
|
|
}
|
|
|
|
static getDefaultPropertiesMap(): Record<string, string> {
|
|
return {};
|
|
}
|
|
// TODO Find a way to enforce this, (dont let it be set)
|
|
static getMetaPropertiesMap(): Record<string, any> {
|
|
return {};
|
|
}
|
|
}
|
|
|
|
export default CanvasWidget;
|