feat: auto select parent of the removed component (#36282)

## Description

https://github.com/user-attachments/assets/764917aa-74ea-4c1b-8361-6441344227fd

Fixes #36281 
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/10845273743>
> Commit: 88d0b70bec732e804919a056cb0f350ae8580aa0
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=10845273743&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Fri, 13 Sep 2024 09:32:43 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Introduced a new optional `parentId` property for enhanced widget
selection, allowing for hierarchical management.
- Updated widget selection and deletion processes to utilize the
`parentId` for improved contextual handling based on layout type.

- **Bug Fixes**
- Enhanced logic in widget selection to ensure the correct parent ID is
used, improving overall selection accuracy.

- **Documentation**
- Updated documentation to reflect changes in widget selection and
deletion functionalities.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Ilia 2024-09-13 11:33:53 +02:00 committed by GitHub
parent 7e98542495
commit ce02d3cdef
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 40 additions and 12 deletions

View File

@ -8,6 +8,7 @@ export interface WidgetSelectionRequestPayload {
payload?: string[];
invokedBy?: NavigationMethod;
basePageId?: string;
parentId?: string;
}
export type WidgetSelectionRequest = (
@ -15,6 +16,7 @@ export type WidgetSelectionRequest = (
payload?: string[],
invokedBy?: NavigationMethod,
basePageId?: string,
parentId?: string,
) => ReduxAction<WidgetSelectionRequestPayload>;
// Use to select a widget programmatically via platform action
@ -23,9 +25,10 @@ export const selectWidgetInitAction: WidgetSelectionRequest = (
payload,
invokedBy?: NavigationMethod,
basePageId?: string,
parentId?: string,
) => ({
type: ReduxActionTypes.SELECT_WIDGET_INIT,
payload: { selectionRequestType, payload, basePageId, invokedBy },
payload: { selectionRequestType, payload, basePageId, invokedBy, parentId },
});
export interface SetSelectedWidgetsPayload {

View File

@ -327,9 +327,23 @@ export function* deleteSaga(deleteAction: ReduxAction<WidgetDelete>) {
if (!disallowUndo) {
// close property pane after delete
yield put(closePropertyPane());
yield put(
selectWidgetInitAction(SelectionRequestType.Unselect, [widgetId]),
);
if (isAnvilLayout) {
yield put(
selectWidgetInitAction(
SelectionRequestType.Unselect,
[widgetId],
undefined,
undefined,
parentId,
),
);
} else {
yield put(
selectWidgetInitAction(SelectionRequestType.Unselect, [widgetId]),
);
}
yield call(postDelete, widgetId, widgetName, otherWidgetsToDelete);
}
}

View File

@ -66,6 +66,7 @@ function* selectWidgetSaga(action: ReduxAction<WidgetSelectionRequestPayload>) {
const {
basePageId,
invokedBy,
parentId,
payload = [],
selectionRequestType,
} = action.payload;
@ -93,8 +94,9 @@ function* selectWidgetSaga(action: ReduxAction<WidgetSelectionRequestPayload>) {
// It is possible that the payload is empty.
// These properties can be used for a finding sibling widgets for certain types of selections
const widgetId = payload[0];
const parentId: string | undefined =
widgetId in allWidgets ? allWidgets[widgetId].parentId : undefined;
const finalParentId: string | undefined =
parentId ||
(widgetId in allWidgets ? allWidgets[widgetId].parentId : undefined);
if (
widgetId &&
@ -115,7 +117,7 @@ function* selectWidgetSaga(action: ReduxAction<WidgetSelectionRequestPayload>) {
}
case SelectionRequestType.One:
case SelectionRequestType.Create: {
assertParentId(parentId);
assertParentId(finalParentId);
newSelection = selectOneWidget(payload);
break;
}
@ -124,10 +126,10 @@ function* selectWidgetSaga(action: ReduxAction<WidgetSelectionRequestPayload>) {
break;
}
case SelectionRequestType.ShiftSelect: {
assertParentId(parentId);
assertParentId(finalParentId);
const siblingWidgets: string[] = yield select(
getWidgetImmediateChildren,
parentId,
finalParentId,
);
newSelection = shiftSelectWidgets(
payload,
@ -138,10 +140,10 @@ function* selectWidgetSaga(action: ReduxAction<WidgetSelectionRequestPayload>) {
break;
}
case SelectionRequestType.PushPop: {
assertParentId(parentId);
assertParentId(finalParentId);
const siblingWidgets: string[] = yield select(
getWidgetImmediateChildren,
parentId,
finalParentId,
);
newSelection = pushPopWidgetSelection(
payload,
@ -151,7 +153,16 @@ function* selectWidgetSaga(action: ReduxAction<WidgetSelectionRequestPayload>) {
break;
}
case SelectionRequestType.Unselect: {
newSelection = unselectWidget(payload, selectedWidgets);
const isParentExists = finalParentId
? finalParentId in allWidgets
: false;
if (isParentExists) {
assertParentId(finalParentId);
newSelection = [finalParentId];
} else {
newSelection = unselectWidget(payload, selectedWidgets);
}
break;
}
case SelectionRequestType.All: {