2022-08-04 05:40:44 +00:00
|
|
|
import { createImmerReducer } from "utils/ReducerUtils";
|
2019-02-10 13:06:05 +00:00
|
|
|
import {
|
2019-09-12 11:19:38 +00:00
|
|
|
ReduxActionTypes,
|
2019-09-24 12:36:03 +00:00
|
|
|
UpdateCanvasPayload,
|
2019-09-09 10:30:22 +00:00
|
|
|
ReduxAction,
|
2022-04-12 10:50:01 +00:00
|
|
|
} from "@appsmith/constants/ReduxActionConstants";
|
2019-11-25 05:07:27 +00:00
|
|
|
import { WidgetProps } from "widgets/BaseWidget";
|
2022-11-14 04:19:25 +00:00
|
|
|
import { uniq, get, set } from "lodash";
|
2022-11-23 09:48:23 +00:00
|
|
|
import { Diff, diff } from "deep-diff";
|
2023-02-03 05:47:40 +00:00
|
|
|
import {
|
|
|
|
|
getCanvasBottomRow,
|
|
|
|
|
getCanvasWidgetHeightsToUpdate,
|
|
|
|
|
} from "utils/WidgetSizeUtils";
|
2019-08-26 12:41:21 +00:00
|
|
|
|
2022-11-14 04:19:25 +00:00
|
|
|
/* This type is an object whose keys are widgetIds and values are arrays with property paths
|
|
|
|
|
and property values
|
|
|
|
|
For example:
|
|
|
|
|
{ "xyz123": [{ propertyPath: "bottomRow", propertyValue: 20 }] }
|
|
|
|
|
*/
|
|
|
|
|
export type UpdateWidgetsPayload = Record<
|
|
|
|
|
string,
|
|
|
|
|
Array<{
|
|
|
|
|
propertyPath: string;
|
|
|
|
|
propertyValue: unknown;
|
|
|
|
|
}>
|
|
|
|
|
>;
|
|
|
|
|
|
2022-11-23 09:48:23 +00:00
|
|
|
const initialState: CanvasWidgetsReduxState = {};
|
|
|
|
|
|
2021-08-25 05:00:31 +00:00
|
|
|
export type FlattenedWidgetProps<orType = never> =
|
|
|
|
|
| (WidgetProps & {
|
|
|
|
|
children?: string[];
|
|
|
|
|
})
|
|
|
|
|
| orType;
|
2019-02-10 13:06:05 +00:00
|
|
|
|
2022-08-19 10:10:36 +00:00
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @param updateLayoutDiff
|
|
|
|
|
* @returns list of widgets that were updated
|
|
|
|
|
*/
|
|
|
|
|
function getUpdatedWidgetLists(
|
|
|
|
|
updateLayoutDiff: Diff<
|
|
|
|
|
CanvasWidgetsReduxState,
|
|
|
|
|
{
|
|
|
|
|
[widgetId: string]: WidgetProps;
|
|
|
|
|
}
|
|
|
|
|
>[],
|
|
|
|
|
) {
|
|
|
|
|
return uniq(
|
|
|
|
|
updateLayoutDiff
|
|
|
|
|
.map((diff: Diff<CanvasWidgetsReduxState>) => diff.path?.[0])
|
|
|
|
|
.filter((widgetId) => !!widgetId),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-30 12:42:09 +00:00
|
|
|
const canvasWidgetsReducer = createImmerReducer(initialState, {
|
2021-01-25 08:57:26 +00:00
|
|
|
[ReduxActionTypes.INIT_CANVAS_LAYOUT]: (
|
2019-03-21 17:42:23 +00:00
|
|
|
state: CanvasWidgetsReduxState,
|
2019-09-24 12:36:03 +00:00
|
|
|
action: ReduxAction<UpdateCanvasPayload>,
|
2019-03-21 17:42:23 +00:00
|
|
|
) => {
|
2023-02-03 05:47:40 +00:00
|
|
|
const { widgets } = action.payload;
|
|
|
|
|
for (const [widgetId, widgetProps] of Object.entries(widgets)) {
|
|
|
|
|
if (widgetProps.type === "CANVAS_WIDGET") {
|
|
|
|
|
const bottomRow = getCanvasBottomRow(widgetId, widgets);
|
|
|
|
|
widgets[widgetId].bottomRow = bottomRow;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return widgets;
|
2019-08-26 12:41:21 +00:00
|
|
|
},
|
2019-09-19 22:25:37 +00:00
|
|
|
[ReduxActionTypes.UPDATE_LAYOUT]: (
|
2019-08-26 12:41:21 +00:00
|
|
|
state: CanvasWidgetsReduxState,
|
2019-09-24 12:36:03 +00:00
|
|
|
action: ReduxAction<UpdateCanvasPayload>,
|
2019-08-26 12:41:21 +00:00
|
|
|
) => {
|
2022-08-19 10:10:36 +00:00
|
|
|
let listOfUpdatedWidgets;
|
|
|
|
|
// if payload has knowledge of which widgets were changed, use that
|
|
|
|
|
if (action.payload.updatedWidgetIds) {
|
|
|
|
|
listOfUpdatedWidgets = action.payload.updatedWidgetIds;
|
|
|
|
|
} // else diff out the widgets that need to be updated
|
|
|
|
|
else {
|
|
|
|
|
const updatedLayoutDiffs = diff(state, action.payload.widgets);
|
|
|
|
|
if (!updatedLayoutDiffs) return state;
|
|
|
|
|
|
|
|
|
|
listOfUpdatedWidgets = getUpdatedWidgetLists(updatedLayoutDiffs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//update only the widgets that need to be updated.
|
|
|
|
|
for (const widgetId of listOfUpdatedWidgets) {
|
|
|
|
|
const updatedWidget = action.payload.widgets[widgetId];
|
|
|
|
|
if (updatedWidget) {
|
|
|
|
|
state[widgetId] = updatedWidget;
|
|
|
|
|
} else {
|
|
|
|
|
delete state[widgetId];
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-03 05:47:40 +00:00
|
|
|
|
|
|
|
|
const canvasWidgetHeightsToUpdate: Record<
|
|
|
|
|
string,
|
|
|
|
|
number
|
|
|
|
|
> = getCanvasWidgetHeightsToUpdate(listOfUpdatedWidgets, state);
|
|
|
|
|
|
|
|
|
|
for (const widgetId in canvasWidgetHeightsToUpdate) {
|
|
|
|
|
state[widgetId].bottomRow = canvasWidgetHeightsToUpdate[widgetId];
|
|
|
|
|
}
|
2019-09-09 10:30:22 +00:00
|
|
|
},
|
2022-11-14 04:19:25 +00:00
|
|
|
[ReduxActionTypes.UPDATE_MULTIPLE_WIDGET_PROPERTIES]: (
|
|
|
|
|
state: CanvasWidgetsReduxState,
|
feat: Non auto height invisible widgets (#20118)
## Description
This PR adds another feature update we had planned for Auto Height
- [ ] For new applications, in View and Preview mode, any widget which
is invisible will let go of its space and collapse if it's either on the
main Canvas or a container-like widget which has Auto-height enabled.
- [ ] Widgets within a container-like Widget, say Tabs, that doesn't
have Auto-height enabled, will now let go of their space if they're
invisible.
- [ ] The experience in Edit mode has not changed.
TL;DR: In new applications, in the Preview and Published _AKA_ View
modes, if a widget is invisible and within an Auto-height-enabled
container like a Tab, a Modal, a Form, or the main Canvas, it will fully
collapse, allowing widgets below it to move up and take its space. This
changes the behavior today prior to the release of this PR for
Auto-height-enabled widgets.
Fixes #19983
Fixes #18681
2023-02-14 13:36:19 +00:00
|
|
|
action: ReduxAction<{
|
|
|
|
|
widgetsToUpdate: UpdateWidgetsPayload;
|
|
|
|
|
shouldEval: boolean;
|
|
|
|
|
}>,
|
2022-11-14 04:19:25 +00:00
|
|
|
) => {
|
|
|
|
|
// For each widget whose properties we would like to update
|
|
|
|
|
for (const [widgetId, propertyPathsToUpdate] of Object.entries(
|
feat: Non auto height invisible widgets (#20118)
## Description
This PR adds another feature update we had planned for Auto Height
- [ ] For new applications, in View and Preview mode, any widget which
is invisible will let go of its space and collapse if it's either on the
main Canvas or a container-like widget which has Auto-height enabled.
- [ ] Widgets within a container-like Widget, say Tabs, that doesn't
have Auto-height enabled, will now let go of their space if they're
invisible.
- [ ] The experience in Edit mode has not changed.
TL;DR: In new applications, in the Preview and Published _AKA_ View
modes, if a widget is invisible and within an Auto-height-enabled
container like a Tab, a Modal, a Form, or the main Canvas, it will fully
collapse, allowing widgets below it to move up and take its space. This
changes the behavior today prior to the release of this PR for
Auto-height-enabled widgets.
Fixes #19983
Fixes #18681
2023-02-14 13:36:19 +00:00
|
|
|
action.payload.widgetsToUpdate,
|
2022-11-14 04:19:25 +00:00
|
|
|
)) {
|
|
|
|
|
// Iterate through each property to update in `widgetId`
|
|
|
|
|
propertyPathsToUpdate.forEach(({ propertyPath, propertyValue }) => {
|
|
|
|
|
const path = `${widgetId}.${propertyPath}`;
|
|
|
|
|
// Get original value in reducer
|
|
|
|
|
const originalPropertyValue = get(state, path);
|
|
|
|
|
// If the original and new values are different
|
|
|
|
|
if (propertyValue !== originalPropertyValue)
|
|
|
|
|
// Set the new values
|
|
|
|
|
set(state, path, propertyValue);
|
|
|
|
|
});
|
|
|
|
|
}
|
2023-02-03 05:47:40 +00:00
|
|
|
|
|
|
|
|
const canvasWidgetHeightsToUpdate: Record<
|
|
|
|
|
string,
|
|
|
|
|
number
|
feat: Non auto height invisible widgets (#20118)
## Description
This PR adds another feature update we had planned for Auto Height
- [ ] For new applications, in View and Preview mode, any widget which
is invisible will let go of its space and collapse if it's either on the
main Canvas or a container-like widget which has Auto-height enabled.
- [ ] Widgets within a container-like Widget, say Tabs, that doesn't
have Auto-height enabled, will now let go of their space if they're
invisible.
- [ ] The experience in Edit mode has not changed.
TL;DR: In new applications, in the Preview and Published _AKA_ View
modes, if a widget is invisible and within an Auto-height-enabled
container like a Tab, a Modal, a Form, or the main Canvas, it will fully
collapse, allowing widgets below it to move up and take its space. This
changes the behavior today prior to the release of this PR for
Auto-height-enabled widgets.
Fixes #19983
Fixes #18681
2023-02-14 13:36:19 +00:00
|
|
|
> = getCanvasWidgetHeightsToUpdate(
|
|
|
|
|
Object.keys(action.payload.widgetsToUpdate),
|
|
|
|
|
state,
|
|
|
|
|
);
|
2023-02-03 05:47:40 +00:00
|
|
|
for (const widgetId in canvasWidgetHeightsToUpdate) {
|
|
|
|
|
state[widgetId].bottomRow = canvasWidgetHeightsToUpdate[widgetId];
|
|
|
|
|
}
|
2022-11-14 04:19:25 +00:00
|
|
|
},
|
2019-09-09 10:30:22 +00:00
|
|
|
});
|
2022-11-23 09:48:23 +00:00
|
|
|
|
2019-02-10 13:06:05 +00:00
|
|
|
export interface CanvasWidgetsReduxState {
|
2019-09-09 10:30:22 +00:00
|
|
|
[widgetId: string]: FlattenedWidgetProps;
|
2019-02-10 13:06:05 +00:00
|
|
|
}
|
|
|
|
|
|
2019-09-09 10:30:22 +00:00
|
|
|
export default canvasWidgetsReducer;
|