PromucFlow_constructor/app/client/src/utils/WidgetPropsUtils.tsx

291 lines
7.0 KiB
TypeScript
Raw Normal View History

2019-11-25 05:07:27 +00:00
import { FetchPageResponse } from "api/PageApi";
import { XYCord } from "utils/hooks/useCanvasDragging";
2019-11-25 05:07:27 +00:00
import { WidgetConfigProps } from "reducers/entityReducers/widgetConfigReducer";
import {
WidgetOperation,
2020-03-06 09:45:21 +00:00
WidgetOperations,
WidgetProps,
2019-11-25 05:07:27 +00:00
} from "widgets/BaseWidget";
import { GridDefaults, RenderMode } from "constants/WidgetConstants";
import { snapToGrid } from "./helpers";
import { OccupiedSpace } from "constants/editorConstants";
2020-02-13 09:32:24 +00:00
import defaultTemplate from "templates/default";
import { FlattenedWidgetProps } from "reducers/entityReducers/canvasWidgetsReducer";
import { transformDSL } from "./DSLMigrations";
import { WidgetType } from "./WidgetFactory";
import { DSLWidget } from "widgets/constants";
export type WidgetOperationParams = {
operation: WidgetOperation;
widgetId: string;
payload: any;
};
2019-09-25 21:21:04 +00:00
type Rect = {
top: number;
left: number;
right: number;
bottom: number;
};
const defaultDSL = defaultTemplate;
2020-01-16 11:46:21 +00:00
export const extractCurrentDSL = (
fetchPageResponse?: FetchPageResponse,
): DSLWidget => {
const newPage = !fetchPageResponse;
const currentDSL = fetchPageResponse?.data.layouts[0].dsl || {
...defaultDSL,
};
return transformDSL(currentDSL, newPage);
};
2019-09-25 21:21:04 +00:00
export const getDropZoneOffsets = (
colWidth: number,
rowHeight: number,
dragOffset: XYCord,
parentOffset: XYCord,
2019-09-25 21:21:04 +00:00
) => {
// Calculate actual drop position by snapping based on x, y and grid cell size
return snapToGrid(
colWidth,
rowHeight,
dragOffset.x - parentOffset.x,
dragOffset.y - parentOffset.y,
2019-09-25 21:21:04 +00:00
);
};
export const areIntersecting = (r1: Rect, r2: Rect) => {
2019-09-25 21:21:04 +00:00
return !(
r2.left >= r1.right ||
r2.right <= r1.left ||
r2.top >= r1.bottom ||
r2.bottom <= r1.top
2019-09-25 21:21:04 +00:00
);
};
export const isDropZoneOccupied = (
offset: Rect,
2019-10-08 06:19:10 +00:00
widgetId: string,
occupied?: OccupiedSpace[],
2019-09-25 21:21:04 +00:00
) => {
if (occupied) {
2020-12-24 04:32:25 +00:00
occupied = occupied.filter((widgetDetails) => {
2019-10-02 21:14:58 +00:00
return (
2019-10-08 06:19:10 +00:00
widgetDetails.id !== widgetId && widgetDetails.parentId !== widgetId
2019-10-02 21:14:58 +00:00
);
2019-09-25 21:21:04 +00:00
});
for (let i = 0; i < occupied.length; i++) {
if (areIntersecting(occupied[i], offset)) {
return true;
}
}
return false;
}
return false;
};
2019-10-08 06:19:10 +00:00
export const isWidgetOverflowingParentBounds = (
parentRowCols: { rows?: number; cols?: number },
offset: Rect,
2020-01-16 11:46:21 +00:00
): boolean => {
2020-03-06 09:45:21 +00:00
return (
2020-01-16 11:46:21 +00:00
offset.right < 0 ||
offset.top < 0 ||
2019-10-08 06:19:10 +00:00
(parentRowCols.cols || GridDefaults.DEFAULT_GRID_COLUMNS) < offset.right ||
2020-03-06 09:45:21 +00:00
(parentRowCols.rows || 0) < offset.bottom
);
2019-10-08 06:19:10 +00:00
};
2019-09-25 21:21:04 +00:00
export const noCollision = (
clientOffset: XYCord,
2019-09-25 21:21:04 +00:00
colWidth: number,
rowHeight: number,
dropTargetOffset: XYCord,
widgetWidth: number,
widgetHeight: number,
widgetId: string,
occupiedSpaces?: OccupiedSpace[],
2019-10-08 06:19:10 +00:00
rows?: number,
cols?: number,
detachFromLayout = false,
2019-09-25 21:21:04 +00:00
): boolean => {
if (detachFromLayout) {
return true;
}
if (clientOffset && dropTargetOffset) {
2019-09-25 21:21:04 +00:00
const [left, top] = getDropZoneOffsets(
colWidth,
rowHeight,
clientOffset as XYCord,
2019-09-25 21:21:04 +00:00
dropTargetOffset,
);
2020-01-16 11:46:21 +00:00
if (left < 0 || top < 0) {
return false;
}
2019-09-25 21:21:04 +00:00
const currentOffset = {
left,
right: left + widgetWidth,
top,
bottom: top + widgetHeight,
};
2019-10-08 06:19:10 +00:00
return (
!isDropZoneOccupied(currentOffset, widgetId, occupiedSpaces) &&
2019-10-08 06:19:10 +00:00
!isWidgetOverflowingParentBounds({ rows, cols }, currentOffset)
);
2019-09-25 21:21:04 +00:00
}
return false;
};
2020-01-16 11:46:21 +00:00
export const currentDropRow = (
dropTargetRowSpace: number,
dropTargetVerticalOffset: number,
draggableItemVerticalOffset: number,
widget: WidgetProps & Partial<WidgetConfigProps>,
) => {
const widgetHeight = widget.rows
? widget.rows
: widget.bottomRow - widget.topRow;
const top = Math.round(
(draggableItemVerticalOffset - dropTargetVerticalOffset) /
dropTargetRowSpace,
);
const currentBottomOffset = top + widgetHeight;
return currentBottomOffset;
};
export const widgetOperationParams = (
widget: WidgetProps & Partial<WidgetConfigProps>,
widgetOffset: XYCord,
parentOffset: XYCord,
parentColumnSpace: number,
parentRowSpace: number,
parentWidgetId: string, // parentWidget
): WidgetOperationParams => {
const [leftColumn, topRow] = getDropZoneOffsets(
parentColumnSpace,
parentRowSpace,
widgetOffset,
parentOffset,
);
// If this is an existing widget, we'll have the widgetId
// Therefore, this is a move operation on drop of the widget
if (widget.widgetName) {
return {
operation: WidgetOperations.MOVE,
widgetId: widget.widgetId,
payload: {
leftColumn,
topRow,
parentId: widget.parentId,
newParentId: parentWidgetId,
},
};
// If this is not an existing widget, we'll not have the widgetId
// Therefore, this is an operation to add child to this container
}
const widgetDimensions = {
columns: widget.columns,
rows: widget.rows,
};
[Feature] Grid Widget (#2389) * Updated test * updated assertions * Resizing image to take full width of table cell * updated assertion * Stop updating dynamicBindingPathList directly from widget * Fix selectedRow and selectedRows computations * Fix primaryColumns computations * Updated test for derived column * Added tests for computed value * Added check clear data * Reordering of test * updated common method * Made image size as 100% of table cell size * add templating logic * Updated flow and dsl * Clear old primary columns * Updated testname * updated assertion * use evaluated values for children * Fix primary columns update on component mount and component update * add isArray check * remove property pane enhancement reducer * add property pane enhancement reducer * disable items other than template + fix running property enchancment on drop of list widget * disbled drag, resize, settingsControl, drag for items other than template * add grid options * uncomment the widget operation for add child for grid children * handle delete scenario for child widget in list widget * WIP: Use the new delete and update property features * add listdsl.json for testcases * add test cases for correct no. of items being rendered * add test cases currentItem binding in list widget * change dragEnabled to dragDisabled * change resizeEnabled to resizeDisabled * change settingsControlEnabled to settingsControlDisabled * change dropEnabled to dropDisabled * update settingsControlDisabled default value * Use deleteProperties in propertyControls * Fix unsetting of array indices when deleting widget properties * remove old TableWidget.tsx file * Fix derived column property update on primary column property update * Handle undefined primary columns * Fix filepicker immutable prop issue * Fix object.freeze issue when adding ids to the property pane configuration * fix widget issue in grid * Fix column actions dynamicBindingPathList inclusion issue * remove consoles + fix typo around batch update * Remove redundant tests * js binding test for date picker * hydate enhancement map on copy list widget * check for dynamicleaf * fixes * improve check * fix getNextWidgetName * update template in list widget when copying * updating template copy logic when copying widget * update dynamicBindingPathList in copied widget * Add path parameter to hidden functions in property pane configs * fix copy bug when copying list widget * add computed list property control * Remove time column type Fix editor prompt for currentRow Fix undefined derivedColumns scenario Remove validations for primaryColums and derivedColumns Fix section toggle for video, image and button column types * Fix table widget actions and custom column migrations * Add logs for cyclical dependency map :recycle: * Process array differences * add property control for list widget * Fix onClick migrations * Property pane config parity * binding and trigger paths from the property pane config (#2920) * try react virtualized library * Fix unit test * Fix unit test :white_check_mark: * Fix minor issues in table widget * Add default meta props to binding paths to ensure eval and validation * Dummy commit :tada: * Remove unnecessary datepicker test Fix chart data as string issue * Achieve table column sorting and resizing parity with release * handle scenario where last column isn't available to access * Fix for panel config path not existing in the widget * Fix bindings in currentRow (default) Add dummy property pane config for canvas widget * Update canvas widgets with dynamicPathLists on delete of property paths * Add all diffs to change paths and trim later * Add back default properties 🚶🏻‍♂️ * Use object based paths instead of arrays for primaryColumns and derivedColumns * Fix issue in reordered columns * Fix inccorect update order * add virtualized list * Fix failing property pane tests * minor change * minor list widget change * Remove .vscode from git * Rename ads to alloy Fix isVisible in list widget * move grid component to widget folder * fix import in widget registry * add sticky row in virtualized list * add sticky container * Fix Height of grid widget items container * fix dragging of items in children other than template children * update list widget * update list widget * Fix padding in list widget * hide scrollbar in list widget list * fix copy bug in list widget * regenrate enhancement map on undo delete widget * Use enhancementmap for autocomplete in list widget Basic styles for list widget scrollbar * add custom control in widget config * minor commit * update scrollbar styles * remove unused variable * fix typo in custom control * comment out test cases * remove unused imports * remove unused imports * add JSON stringify in interweave * add noPad styling in dragLayer for noPad prop * implement grid gap * add list item background color prop * add white color in color picker control * fix gap in last list item * remove onBeforeParse in textcomponent * remove virtualization in grid widget * allow overflow-y * add onListItemClick action * add beta label * add pagination * fix actions in pagination in list widget * add list widget icon * add list background color default value * remove extra div * fix pagination issue * fix list widget crashing on perpage change * extract child operation function to widgetblueprint saga * refactor enhancements * add enhancement hook * refactor propertyUpdate hook enhancment * remove enhacement map * revert renaming ads to alloy * add autopagination * Cleanup unused vars Re-write loop using map Fix binding with external input widget * update default background color * remove unnessary scrol + fix pagination per page * remove console.log * use grid gap in pixel instead of snap * fix list widget tests for binding * add tests for on click action and pagination * remove unnecessary imports * remove overflow hidden in list component * Add feature to enable template actions * update property pane help text for list widget * disable pagination in editor view * update property pane options * add test case for action * uncomment tests * fix grid gap validation * update test cases * fix property pane opening issue for list tempalte * Disable form widgets in list widget * fix template issue for actions * add validation tests for list data * update starting template * add selectedRow + enable pagination in edit mode * remove extra padding in list widget + popper fix on settingDisabled * add stop propagation for button click * fix click event in edit mode * disallow filepicker widget for list widget * add test for list widget entity definition for selectItem * remove unused imports * fix test * remove evaluated value for list child widgets * add comment * remove log * fix copying bug in list widget * add check for not allowing template to copy * fix test * add test for property pane actions * remove unused import * add draglayercomponent test * add test for draggable component * add test for evaluatedvalue popup * add test for messages.ts * add test for widgeticons * add test for property pane selector * add test for widget config response * start testing widget configresponse * add test for enhancements in widget config * add test for codeeditor * add test for base widget + list widget * add test for executeWidgetBlueprintChildOperations * remove unused import * add test for widget operation utils * remove unused import * add test for handleSpecificCasesWhilePasting * remove unused function * remove unused import * add empty list styling * resolve all review comments * fix message test * add test for widget operation utils * fix merge conflicts * move validations in property config Co-authored-by: Abhinav Jha <abhinav@appsmith.com> Co-authored-by: nandan.anantharamu <nandan.anantharamu@thoughtspot.com> Co-authored-by: vicky-primathon.in <vicky.bansal@primathon.in> Co-authored-by: Pawan Kumar <pawankumar@Pawans-MacBook-Pro.local> Co-authored-by: Piyush <piyush@codeitout.com> Co-authored-by: hetunandu <hetu@appsmith.com> Co-authored-by: Hetu Nandu <hetunandu@gmail.com> Co-authored-by: root <root@DESKTOP-9GENCK0.localdomain>
2021-04-23 05:43:13 +00:00
return {
operation: WidgetOperations.ADD_CHILD,
widgetId: parentWidgetId,
payload: {
type: widget.type,
leftColumn,
topRow,
...widgetDimensions,
parentRowSpace,
parentColumnSpace,
newWidgetId: widget.widgetId,
},
};
};
export const updateWidgetPosition = (
widget: WidgetProps,
leftColumn: number,
topRow: number,
) => {
const newPositions = {
leftColumn,
topRow,
rightColumn: leftColumn + (widget.rightColumn - widget.leftColumn),
bottomRow: topRow + (widget.bottomRow - widget.topRow),
};
return {
2020-01-16 11:46:21 +00:00
...newPositions,
};
};
export const getCanvasSnapRows = (
bottomRow: number,
canExtend: boolean,
): number => {
const totalRows = Math.floor(
bottomRow / GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
);
// Canvas Widgets do not need to accommodate for widget and container padding.
// Only when they're extensible
if (canExtend) {
return totalRows;
}
// When Canvas widgets are not extensible
return totalRows - 1;
};
export const getSnapColumns = (): number => {
return GridDefaults.DEFAULT_GRID_COLUMNS;
};
export const generateWidgetProps = (
parent: FlattenedWidgetProps,
type: WidgetType,
leftColumn: number,
topRow: number,
parentRowSpace: number,
parentColumnSpace: number,
widgetName: string,
widgetConfig: {
widgetId: string;
renderMode: RenderMode;
} & Partial<WidgetProps>,
version: number,
): DSLWidget => {
if (parent) {
const sizes = {
leftColumn,
rightColumn: leftColumn + widgetConfig.columns,
topRow,
bottomRow: topRow + widgetConfig.rows,
};
const others = {};
const props: DSLWidget = {
// Todo(abhinav): abstraction leak
isVisible: "MODAL_WIDGET" === type ? undefined : true,
...widgetConfig,
type,
2020-01-17 09:28:26 +00:00
widgetName,
2019-11-20 08:10:01 +00:00
isLoading: false,
parentColumnSpace,
parentRowSpace,
...sizes,
...others,
parentId: parent.widgetId,
version,
};
delete props.rows;
delete props.columns;
return props;
} else {
2020-01-16 11:46:21 +00:00
if (parent) {
throw Error("Failed to create widget: Parent's size cannot be calculate");
2020-01-16 11:46:21 +00:00
} else throw Error("Failed to create widget: Parent was not provided ");
}
};