chore: upgrade to prettier v2 + enforce import types (#21013)Co-authored-by: Satish Gandham <hello@satishgandham.com> Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
## Description
This PR upgrades Prettier to v2 + enforces TypeScript’s [`import
type`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export)
syntax where applicable. It’s submitted as a separate PR so we can merge
it easily.
As a part of this PR, we reformat the codebase heavily:
- add `import type` everywhere where it’s required, and
- re-format the code to account for Prettier 2’s breaking changes:
https://prettier.io/blog/2020/03/21/2.0.0.html#breaking-changes
This PR is submitted against `release` to make sure all new code by team
members will adhere to new formatting standards, and we’ll have fewer
conflicts when merging `bundle-optimizations` into `release`. (I’ll
merge `release` back into `bundle-optimizations` once this PR is
merged.)
### Why is this needed?
This PR is needed because, for the Lodash optimization from
https://github.com/appsmithorg/appsmith/commit/7cbb12af886621256224be0c93e6a465dd710ad3,
we need to use `import type`. Otherwise, `babel-plugin-lodash` complains
that `LoDashStatic` is not a lodash function.
However, just using `import type` in the current codebase will give you
this:
<img width="962" alt="Screenshot 2023-03-08 at 17 45 59"
src="https://user-images.githubusercontent.com/2953267/223775744-407afa0c-e8b9-44a1-90f9-b879348da57f.png">
That’s because Prettier 1 can’t parse `import type` at all. To parse it,
we need to upgrade to Prettier 2.
### Why enforce `import type`?
Apart from just enabling `import type` support, this PR enforces
specifying `import type` everywhere it’s needed. (Developers will get
immediate TypeScript and ESLint errors when they forget to do so.)
I’m doing this because I believe `import type` improves DX and makes
refactorings easier.
Let’s say you had a few imports like below. Can you tell which of these
imports will increase the bundle size? (Tip: it’s not all of them!)
```ts
// app/client/src/workers/Linting/utils.ts
import { Position } from "codemirror";
import { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
It’s pretty hard, right?
What about now?
```ts
// app/client/src/workers/Linting/utils.ts
import type { Position } from "codemirror";
import type { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
Now, it’s clear that only `lodash` will be bundled.
This helps developers to see which imports are problematic, but it
_also_ helps with refactorings. Now, if you want to see where
`codemirror` is bundled, you can just grep for `import \{.*\} from
"codemirror"` – and you won’t get any type-only imports.
This also helps (some) bundlers. Upon transpiling, TypeScript erases
type-only imports completely. In some environment (not ours), this makes
the bundle smaller, as the bundler doesn’t need to bundle type-only
imports anymore.
## Type of change
- Chore (housekeeping or task changes that don't impact user perception)
## How Has This Been Tested?
This was tested to not break the build.
### 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
- [x] 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
- [x] 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:
- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test
---------
Co-authored-by: Satish Gandham <hello@satishgandham.com>
Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
2023-03-16 11:41:47 +00:00
|
|
|
import type { AppState } from "@appsmith/reducers";
|
2023-03-04 07:25:54 +00:00
|
|
|
import { batchUpdateMultipleWidgetProperties } from "actions/controlActions";
|
|
|
|
|
import { focusWidget } from "actions/widgetActions";
|
|
|
|
|
import { EditorContext } from "components/editorComponents/EditorContextProvider";
|
2023-04-07 13:51:35 +00:00
|
|
|
import type { OccupiedSpace } from "constants/CanvasEditorConstants";
|
|
|
|
|
import { DefaultDimensionMap, GridDefaults } from "constants/WidgetConstants";
|
2023-03-04 07:25:54 +00:00
|
|
|
import { get, omit } from "lodash";
|
chore: upgrade to prettier v2 + enforce import types (#21013)Co-authored-by: Satish Gandham <hello@satishgandham.com> Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
## Description
This PR upgrades Prettier to v2 + enforces TypeScript’s [`import
type`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export)
syntax where applicable. It’s submitted as a separate PR so we can merge
it easily.
As a part of this PR, we reformat the codebase heavily:
- add `import type` everywhere where it’s required, and
- re-format the code to account for Prettier 2’s breaking changes:
https://prettier.io/blog/2020/03/21/2.0.0.html#breaking-changes
This PR is submitted against `release` to make sure all new code by team
members will adhere to new formatting standards, and we’ll have fewer
conflicts when merging `bundle-optimizations` into `release`. (I’ll
merge `release` back into `bundle-optimizations` once this PR is
merged.)
### Why is this needed?
This PR is needed because, for the Lodash optimization from
https://github.com/appsmithorg/appsmith/commit/7cbb12af886621256224be0c93e6a465dd710ad3,
we need to use `import type`. Otherwise, `babel-plugin-lodash` complains
that `LoDashStatic` is not a lodash function.
However, just using `import type` in the current codebase will give you
this:
<img width="962" alt="Screenshot 2023-03-08 at 17 45 59"
src="https://user-images.githubusercontent.com/2953267/223775744-407afa0c-e8b9-44a1-90f9-b879348da57f.png">
That’s because Prettier 1 can’t parse `import type` at all. To parse it,
we need to upgrade to Prettier 2.
### Why enforce `import type`?
Apart from just enabling `import type` support, this PR enforces
specifying `import type` everywhere it’s needed. (Developers will get
immediate TypeScript and ESLint errors when they forget to do so.)
I’m doing this because I believe `import type` improves DX and makes
refactorings easier.
Let’s say you had a few imports like below. Can you tell which of these
imports will increase the bundle size? (Tip: it’s not all of them!)
```ts
// app/client/src/workers/Linting/utils.ts
import { Position } from "codemirror";
import { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
It’s pretty hard, right?
What about now?
```ts
// app/client/src/workers/Linting/utils.ts
import type { Position } from "codemirror";
import type { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
Now, it’s clear that only `lodash` will be bundled.
This helps developers to see which imports are problematic, but it
_also_ helps with refactorings. Now, if you want to see where
`codemirror` is bundled, you can just grep for `import \{.*\} from
"codemirror"` – and you won’t get any type-only imports.
This also helps (some) bundlers. Upon transpiling, TypeScript erases
type-only imports completely. In some environment (not ours), this makes
the bundle smaller, as the bundler doesn’t need to bundle type-only
imports anymore.
## Type of change
- Chore (housekeeping or task changes that don't impact user perception)
## How Has This Been Tested?
This was tested to not break the build.
### 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
- [x] 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
- [x] 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:
- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test
---------
Co-authored-by: Satish Gandham <hello@satishgandham.com>
Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
2023-03-16 11:41:47 +00:00
|
|
|
import type { XYCord } from "pages/common/CanvasArenas/hooks/useRenderBlocksOnCanvas";
|
2023-01-28 02:17:06 +00:00
|
|
|
import React, { memo, useContext, useMemo } from "react";
|
2023-03-04 07:25:54 +00:00
|
|
|
import { useDispatch, useSelector } from "react-redux";
|
2023-04-07 13:51:35 +00:00
|
|
|
import { ReflowResizable as AutoLayoutResizable } from "resizable/autolayoutresize";
|
|
|
|
|
import { ReflowResizable as FixedLayoutResizable } from "resizable/resizenreflow";
|
2023-03-04 07:25:54 +00:00
|
|
|
import { SelectionRequestType } from "sagas/WidgetSelectUtils";
|
2023-04-07 13:51:35 +00:00
|
|
|
import { getIsAutoLayout } from "selectors/canvasSelectors";
|
2023-03-23 11:41:58 +00:00
|
|
|
import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors";
|
2023-03-04 07:25:54 +00:00
|
|
|
import {
|
|
|
|
|
previewModeSelector,
|
|
|
|
|
snipingModeSelector,
|
|
|
|
|
} from "selectors/editorSelectors";
|
|
|
|
|
import {
|
|
|
|
|
getParentToOpenSelector,
|
|
|
|
|
isCurrentWidgetFocused,
|
|
|
|
|
isCurrentWidgetLastSelected,
|
|
|
|
|
isMultiSelectedWidget,
|
|
|
|
|
isWidgetSelected,
|
|
|
|
|
} from "selectors/widgetSelectors";
|
|
|
|
|
import AnalyticsUtil from "utils/AnalyticsUtil";
|
|
|
|
|
import { ResponsiveBehavior } from "utils/autoLayout/constants";
|
|
|
|
|
import {
|
|
|
|
|
getWidgetHeight,
|
|
|
|
|
getWidgetWidth,
|
|
|
|
|
} from "utils/autoLayout/flexWidgetUtils";
|
|
|
|
|
import {
|
|
|
|
|
useShowPropertyPane,
|
|
|
|
|
useShowTableFilterPane,
|
|
|
|
|
useWidgetDragResize,
|
|
|
|
|
} from "utils/hooks/dragResizeHooks";
|
|
|
|
|
import { useWidgetSelection } from "utils/hooks/useWidgetSelection";
|
chore: upgrade to prettier v2 + enforce import types (#21013)Co-authored-by: Satish Gandham <hello@satishgandham.com> Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
## Description
This PR upgrades Prettier to v2 + enforces TypeScript’s [`import
type`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export)
syntax where applicable. It’s submitted as a separate PR so we can merge
it easily.
As a part of this PR, we reformat the codebase heavily:
- add `import type` everywhere where it’s required, and
- re-format the code to account for Prettier 2’s breaking changes:
https://prettier.io/blog/2020/03/21/2.0.0.html#breaking-changes
This PR is submitted against `release` to make sure all new code by team
members will adhere to new formatting standards, and we’ll have fewer
conflicts when merging `bundle-optimizations` into `release`. (I’ll
merge `release` back into `bundle-optimizations` once this PR is
merged.)
### Why is this needed?
This PR is needed because, for the Lodash optimization from
https://github.com/appsmithorg/appsmith/commit/7cbb12af886621256224be0c93e6a465dd710ad3,
we need to use `import type`. Otherwise, `babel-plugin-lodash` complains
that `LoDashStatic` is not a lodash function.
However, just using `import type` in the current codebase will give you
this:
<img width="962" alt="Screenshot 2023-03-08 at 17 45 59"
src="https://user-images.githubusercontent.com/2953267/223775744-407afa0c-e8b9-44a1-90f9-b879348da57f.png">
That’s because Prettier 1 can’t parse `import type` at all. To parse it,
we need to upgrade to Prettier 2.
### Why enforce `import type`?
Apart from just enabling `import type` support, this PR enforces
specifying `import type` everywhere it’s needed. (Developers will get
immediate TypeScript and ESLint errors when they forget to do so.)
I’m doing this because I believe `import type` improves DX and makes
refactorings easier.
Let’s say you had a few imports like below. Can you tell which of these
imports will increase the bundle size? (Tip: it’s not all of them!)
```ts
// app/client/src/workers/Linting/utils.ts
import { Position } from "codemirror";
import { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
It’s pretty hard, right?
What about now?
```ts
// app/client/src/workers/Linting/utils.ts
import type { Position } from "codemirror";
import type { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
Now, it’s clear that only `lodash` will be bundled.
This helps developers to see which imports are problematic, but it
_also_ helps with refactorings. Now, if you want to see where
`codemirror` is bundled, you can just grep for `import \{.*\} from
"codemirror"` – and you won’t get any type-only imports.
This also helps (some) bundlers. Upon transpiling, TypeScript erases
type-only imports completely. In some environment (not ours), this makes
the bundle smaller, as the bundler doesn’t need to bundle type-only
imports anymore.
## Type of change
- Chore (housekeeping or task changes that don't impact user perception)
## How Has This Been Tested?
This was tested to not break the build.
### 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
- [x] 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
- [x] 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:
- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test
---------
Co-authored-by: Satish Gandham <hello@satishgandham.com>
Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
2023-03-16 11:41:47 +00:00
|
|
|
import type { WidgetProps, WidgetRowCols } from "widgets/BaseWidget";
|
|
|
|
|
import { WidgetOperations } from "widgets/BaseWidget";
|
2023-04-07 13:51:35 +00:00
|
|
|
import { getSnapColumns } from "utils/WidgetPropsUtils";
|
2023-04-03 06:11:10 +00:00
|
|
|
import {
|
|
|
|
|
isAutoHeightEnabledForWidget,
|
|
|
|
|
isAutoHeightEnabledForWidgetWithLimits,
|
|
|
|
|
} from "widgets/WidgetUtils";
|
2023-03-04 07:25:54 +00:00
|
|
|
import { DropTargetContext } from "./DropTargetComponent";
|
chore: upgrade to prettier v2 + enforce import types (#21013)Co-authored-by: Satish Gandham <hello@satishgandham.com> Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
## Description
This PR upgrades Prettier to v2 + enforces TypeScript’s [`import
type`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export)
syntax where applicable. It’s submitted as a separate PR so we can merge
it easily.
As a part of this PR, we reformat the codebase heavily:
- add `import type` everywhere where it’s required, and
- re-format the code to account for Prettier 2’s breaking changes:
https://prettier.io/blog/2020/03/21/2.0.0.html#breaking-changes
This PR is submitted against `release` to make sure all new code by team
members will adhere to new formatting standards, and we’ll have fewer
conflicts when merging `bundle-optimizations` into `release`. (I’ll
merge `release` back into `bundle-optimizations` once this PR is
merged.)
### Why is this needed?
This PR is needed because, for the Lodash optimization from
https://github.com/appsmithorg/appsmith/commit/7cbb12af886621256224be0c93e6a465dd710ad3,
we need to use `import type`. Otherwise, `babel-plugin-lodash` complains
that `LoDashStatic` is not a lodash function.
However, just using `import type` in the current codebase will give you
this:
<img width="962" alt="Screenshot 2023-03-08 at 17 45 59"
src="https://user-images.githubusercontent.com/2953267/223775744-407afa0c-e8b9-44a1-90f9-b879348da57f.png">
That’s because Prettier 1 can’t parse `import type` at all. To parse it,
we need to upgrade to Prettier 2.
### Why enforce `import type`?
Apart from just enabling `import type` support, this PR enforces
specifying `import type` everywhere it’s needed. (Developers will get
immediate TypeScript and ESLint errors when they forget to do so.)
I’m doing this because I believe `import type` improves DX and makes
refactorings easier.
Let’s say you had a few imports like below. Can you tell which of these
imports will increase the bundle size? (Tip: it’s not all of them!)
```ts
// app/client/src/workers/Linting/utils.ts
import { Position } from "codemirror";
import { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
It’s pretty hard, right?
What about now?
```ts
// app/client/src/workers/Linting/utils.ts
import type { Position } from "codemirror";
import type { LintError as JSHintError, LintOptions } from "jshint";
import { get, isEmpty, isNumber, keys, last, set } from "lodash";
```
Now, it’s clear that only `lodash` will be bundled.
This helps developers to see which imports are problematic, but it
_also_ helps with refactorings. Now, if you want to see where
`codemirror` is bundled, you can just grep for `import \{.*\} from
"codemirror"` – and you won’t get any type-only imports.
This also helps (some) bundlers. Upon transpiling, TypeScript erases
type-only imports completely. In some environment (not ours), this makes
the bundle smaller, as the bundler doesn’t need to bundle type-only
imports anymore.
## Type of change
- Chore (housekeeping or task changes that don't impact user perception)
## How Has This Been Tested?
This was tested to not break the build.
### 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
- [x] 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
- [x] 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:
- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test
---------
Co-authored-by: Satish Gandham <hello@satishgandham.com>
Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
2023-03-16 11:41:47 +00:00
|
|
|
import type { UIElementSize } from "./ResizableUtils";
|
2023-04-07 13:51:35 +00:00
|
|
|
import { computeFinalRowCols } from "./ResizableUtils";
|
|
|
|
|
import { computeFinalAutoLayoutRowCols } from "./ResizableUtils";
|
2020-02-19 10:00:03 +00:00
|
|
|
import {
|
2023-01-28 02:17:06 +00:00
|
|
|
BottomHandleStyles,
|
|
|
|
|
BottomLeftHandleStyles,
|
|
|
|
|
BottomRightHandleStyles,
|
2020-02-19 10:00:03 +00:00
|
|
|
LeftHandleStyles,
|
|
|
|
|
RightHandleStyles,
|
|
|
|
|
TopHandleStyles,
|
|
|
|
|
TopLeftHandleStyles,
|
|
|
|
|
TopRightHandleStyles,
|
2023-01-28 02:17:06 +00:00
|
|
|
VisibilityContainer,
|
2020-02-19 10:00:03 +00:00
|
|
|
} from "./ResizeStyledComponents";
|
2023-04-07 13:51:35 +00:00
|
|
|
import { ReduxActionTypes } from "ce/constants/ReduxActionConstants";
|
2020-02-18 19:56:58 +00:00
|
|
|
|
2020-10-12 13:06:05 +00:00
|
|
|
export type ResizableComponentProps = WidgetProps & {
|
2020-02-18 19:56:58 +00:00
|
|
|
paddingOffset: number;
|
|
|
|
|
};
|
|
|
|
|
|
2021-05-11 06:33:07 +00:00
|
|
|
export const ResizableComponent = memo(function ResizableComponent(
|
|
|
|
|
props: ResizableComponentProps,
|
|
|
|
|
) {
|
2019-11-13 07:00:25 +00:00
|
|
|
// Fetch information from the context
|
Feature/entity browse (#220)
# New Feature: Entity Explorer
- Entities are actions (apis and queries), datasources, pages, and widgets
- With this new feature, all entities in the application will be available
to view in the new entity explorer sidebar
- All existing application features from the api sidebar, query sidebar, datasource sidebar and pages sidebar
now are avialable on the entity explorer sidebar
- Users are now able to quickly switch to any entity in the application from the entity explorer sidebar.
- Users can also search all entities in the application from the new sidebar. Use cmd + f or ctrl + f to focus on the search input
- Users can rename entities from the new sidebar
- Users can also perform contextual actions on these entities like set a page as home page, copy/move actions, delete entity, etc from the context menu available alongside the entities in the sidebar
- Users can view the properties of the entities in the sidebar, as well as copy bindings to use in the application.
2020-08-10 08:52:45 +00:00
|
|
|
const { updateWidget } = useContext(EditorContext);
|
2023-03-04 07:25:54 +00:00
|
|
|
const dispatch = useDispatch();
|
2023-04-07 13:51:35 +00:00
|
|
|
const isAutoLayout = useSelector(getIsAutoLayout);
|
Feature/entity browse (#220)
# New Feature: Entity Explorer
- Entities are actions (apis and queries), datasources, pages, and widgets
- With this new feature, all entities in the application will be available
to view in the new entity explorer sidebar
- All existing application features from the api sidebar, query sidebar, datasource sidebar and pages sidebar
now are avialable on the entity explorer sidebar
- Users are now able to quickly switch to any entity in the application from the entity explorer sidebar.
- Users can also search all entities in the application from the new sidebar. Use cmd + f or ctrl + f to focus on the search input
- Users can rename entities from the new sidebar
- Users can also perform contextual actions on these entities like set a page as home page, copy/move actions, delete entity, etc from the context menu available alongside the entities in the sidebar
- Users can view the properties of the entities in the sidebar, as well as copy bindings to use in the application.
2020-08-10 08:52:45 +00:00
|
|
|
|
2023-04-07 13:51:35 +00:00
|
|
|
const Resizable = isAutoLayout ? AutoLayoutResizable : FixedLayoutResizable;
|
2021-07-26 16:44:10 +00:00
|
|
|
const isSnipingMode = useSelector(snipingModeSelector);
|
2022-11-27 17:12:00 +00:00
|
|
|
const isPreviewMode = useSelector(previewModeSelector);
|
2023-03-23 11:41:58 +00:00
|
|
|
const isAppSettingsPaneWithNavigationTabOpen = useSelector(
|
|
|
|
|
getIsAppSettingsPaneWithNavigationTabOpen,
|
|
|
|
|
);
|
2021-06-09 10:35:10 +00:00
|
|
|
|
2020-01-20 09:00:37 +00:00
|
|
|
const showPropertyPane = useShowPropertyPane();
|
2021-07-20 05:18:58 +00:00
|
|
|
const showTableFilterPane = useShowTableFilterPane();
|
2020-01-20 09:00:37 +00:00
|
|
|
const { selectWidget } = useWidgetSelection();
|
|
|
|
|
const { setIsResizing } = useWidgetDragResize();
|
2022-09-14 06:55:08 +00:00
|
|
|
// Check if current widget is in the list of selected widgets
|
|
|
|
|
const isSelected = useSelector(isWidgetSelected(props.widgetId));
|
|
|
|
|
// Check if current widget is the last selected widget
|
|
|
|
|
const isLastSelected = useSelector(
|
|
|
|
|
isCurrentWidgetLastSelected(props.widgetId),
|
2020-01-20 09:00:37 +00:00
|
|
|
);
|
2022-09-14 06:55:08 +00:00
|
|
|
const isFocused = useSelector(isCurrentWidgetFocused(props.widgetId));
|
|
|
|
|
// Check if current widget is one of multiple selected widgets
|
|
|
|
|
const isMultiSelected = useSelector(isMultiSelectedWidget(props.widgetId));
|
2020-01-20 09:00:37 +00:00
|
|
|
|
|
|
|
|
const isDragging = useSelector(
|
|
|
|
|
(state: AppState) => state.ui.widgetDragResize.isDragging,
|
|
|
|
|
);
|
2020-02-18 19:56:58 +00:00
|
|
|
const isResizing = useSelector(
|
|
|
|
|
(state: AppState) => state.ui.widgetDragResize.isResizing,
|
|
|
|
|
);
|
2022-08-19 10:10:36 +00:00
|
|
|
const parentWidgetToSelect = useSelector(
|
|
|
|
|
getParentToOpenSelector(props.widgetId),
|
2021-08-09 05:35:01 +00:00
|
|
|
);
|
2022-09-14 06:55:08 +00:00
|
|
|
const isParentWidgetSelected = useSelector(
|
|
|
|
|
isCurrentWidgetLastSelected(parentWidgetToSelect?.widgetId || ""),
|
|
|
|
|
);
|
|
|
|
|
const isWidgetFocused = isFocused || isLastSelected || isSelected;
|
2019-10-08 06:19:10 +00:00
|
|
|
|
2019-11-13 07:00:25 +00:00
|
|
|
// Calculate the dimensions of the widget,
|
|
|
|
|
// The ResizableContainer's size prop is controlled
|
|
|
|
|
const dimensions: UIElementSize = {
|
2020-03-06 09:33:20 +00:00
|
|
|
width:
|
2023-03-04 07:25:54 +00:00
|
|
|
getWidgetWidth(props, !!props.isFlexChild ? !!props.isMobile : false) *
|
|
|
|
|
props.parentColumnSpace -
|
2020-03-06 09:33:20 +00:00
|
|
|
2 * props.paddingOffset,
|
|
|
|
|
height:
|
2023-03-04 07:25:54 +00:00
|
|
|
getWidgetHeight(props, !!props.isFlexChild ? !!props.isMobile : false) *
|
|
|
|
|
props.parentRowSpace -
|
2020-03-06 09:33:20 +00:00
|
|
|
2 * props.paddingOffset,
|
2019-11-13 07:00:25 +00:00
|
|
|
};
|
|
|
|
|
// onResize handler
|
2023-04-07 13:51:35 +00:00
|
|
|
const getResizedPositions = (resizedPositions: OccupiedSpace) => {
|
2022-11-23 09:48:23 +00:00
|
|
|
let canResizeVertically = true;
|
|
|
|
|
let canResizeHorizontally = true;
|
2020-02-18 19:56:58 +00:00
|
|
|
|
2022-01-13 13:21:57 +00:00
|
|
|
// this is required for list widget so that template have no collision
|
|
|
|
|
if (props.ignoreCollision)
|
|
|
|
|
return {
|
|
|
|
|
canResizeHorizontally,
|
|
|
|
|
canResizeVertically,
|
|
|
|
|
};
|
2020-03-27 09:02:11 +00:00
|
|
|
|
2020-02-19 10:00:03 +00:00
|
|
|
if (
|
2023-04-07 13:51:35 +00:00
|
|
|
resizedPositions &&
|
|
|
|
|
(resizedPositions.right > getSnapColumns() ||
|
|
|
|
|
resizedPositions.left < 0 ||
|
|
|
|
|
resizedPositions.right - resizedPositions.left < 2)
|
2020-02-19 10:00:03 +00:00
|
|
|
) {
|
2022-01-13 13:21:57 +00:00
|
|
|
canResizeHorizontally = false;
|
2020-02-19 10:00:03 +00:00
|
|
|
}
|
|
|
|
|
|
2020-02-18 19:56:58 +00:00
|
|
|
if (
|
2023-04-07 13:51:35 +00:00
|
|
|
resizedPositions &&
|
|
|
|
|
(resizedPositions.top < 0 ||
|
|
|
|
|
resizedPositions.bottom - resizedPositions.top < 4)
|
2020-02-18 19:56:58 +00:00
|
|
|
) {
|
2022-01-13 13:21:57 +00:00
|
|
|
canResizeVertically = false;
|
2020-02-18 19:56:58 +00:00
|
|
|
}
|
2021-08-09 05:35:01 +00:00
|
|
|
|
2022-11-23 09:48:23 +00:00
|
|
|
if (isAutoHeightEnabledForWidget(props)) {
|
|
|
|
|
canResizeVertically = false;
|
|
|
|
|
resizedPositions.top = props.topRow;
|
|
|
|
|
resizedPositions.bottom = props.bottomRow;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-18 19:56:58 +00:00
|
|
|
// Check if new row cols are occupied by sibling widgets
|
2022-01-13 13:21:57 +00:00
|
|
|
return {
|
|
|
|
|
canResizeHorizontally,
|
|
|
|
|
canResizeVertically,
|
|
|
|
|
};
|
2019-10-08 06:19:10 +00:00
|
|
|
};
|
2019-11-13 07:00:25 +00:00
|
|
|
|
|
|
|
|
// onResizeStop handler
|
|
|
|
|
// when done resizing, check if;
|
|
|
|
|
// 1) There is no collision
|
|
|
|
|
// 2) There is a change in widget size
|
|
|
|
|
// Update widget, if both of the above are true.
|
2023-04-07 13:51:35 +00:00
|
|
|
const updateSize = (
|
|
|
|
|
newDimensions: UIElementSize,
|
|
|
|
|
position: XYCord,
|
|
|
|
|
dimensionMap = DefaultDimensionMap,
|
|
|
|
|
) => {
|
2019-11-13 07:00:25 +00:00
|
|
|
// Get the difference in size of the widget, before and after resizing.
|
|
|
|
|
const delta: UIElementSize = {
|
2020-02-18 19:56:58 +00:00
|
|
|
height: newDimensions.height - dimensions.height,
|
|
|
|
|
width: newDimensions.width - dimensions.width,
|
2019-11-13 07:00:25 +00:00
|
|
|
};
|
|
|
|
|
|
2023-04-07 13:51:35 +00:00
|
|
|
const {
|
|
|
|
|
bottomRow: bottomRowMap,
|
|
|
|
|
leftColumn: leftColumnMap,
|
|
|
|
|
rightColumn: rightColumnMap,
|
|
|
|
|
topRow: topRowMap,
|
|
|
|
|
} = dimensionMap;
|
|
|
|
|
const {
|
|
|
|
|
parentColumnSpace,
|
|
|
|
|
parentRowSpace,
|
|
|
|
|
[bottomRowMap]: bottomRow,
|
|
|
|
|
[leftColumnMap]: leftColumn,
|
|
|
|
|
[rightColumnMap]: rightColumn,
|
|
|
|
|
[topRowMap]: topRow,
|
|
|
|
|
} = props as any;
|
|
|
|
|
|
2019-11-13 07:00:25 +00:00
|
|
|
// Get the updated Widget rows and columns props
|
|
|
|
|
// False, if there is collision
|
|
|
|
|
// False, if none of the rows and cols have changed.
|
2023-04-07 13:51:35 +00:00
|
|
|
const newRowCols: WidgetRowCols | false = isAutoLayout
|
|
|
|
|
? computeFinalAutoLayoutRowCols(delta, position, {
|
|
|
|
|
bottomRow,
|
|
|
|
|
topRow,
|
|
|
|
|
leftColumn,
|
|
|
|
|
rightColumn,
|
|
|
|
|
parentColumnSpace,
|
|
|
|
|
parentRowSpace,
|
|
|
|
|
})
|
|
|
|
|
: computeFinalRowCols(delta, position, {
|
|
|
|
|
bottomRow,
|
|
|
|
|
topRow,
|
|
|
|
|
leftColumn,
|
|
|
|
|
rightColumn,
|
|
|
|
|
parentColumnSpace,
|
|
|
|
|
parentRowSpace,
|
|
|
|
|
});
|
2019-11-13 07:00:25 +00:00
|
|
|
|
|
|
|
|
if (newRowCols) {
|
|
|
|
|
updateWidget &&
|
2021-09-21 07:55:56 +00:00
|
|
|
updateWidget(WidgetOperations.RESIZE, props.widgetId, {
|
2023-04-07 13:51:35 +00:00
|
|
|
[leftColumnMap]: newRowCols.leftColumn,
|
|
|
|
|
[rightColumnMap]: newRowCols.rightColumn,
|
|
|
|
|
[topRowMap]: newRowCols.topRow,
|
|
|
|
|
[bottomRowMap]: newRowCols.bottomRow,
|
2021-09-21 07:55:56 +00:00
|
|
|
parentId: props.parentId,
|
2022-01-13 13:21:57 +00:00
|
|
|
snapColumnSpace: props.parentColumnSpace,
|
|
|
|
|
snapRowSpace: props.parentRowSpace,
|
2021-09-21 07:55:56 +00:00
|
|
|
});
|
2019-11-13 07:00:25 +00:00
|
|
|
}
|
|
|
|
|
// Tell the Canvas that we've stopped resizing
|
2020-03-04 08:10:40 +00:00
|
|
|
// Put it later in the stack so that other updates like click, are not propagated to the parent container
|
2020-01-07 12:28:58 +00:00
|
|
|
setTimeout(() => {
|
|
|
|
|
setIsResizing && setIsResizing(false);
|
2023-04-07 13:51:35 +00:00
|
|
|
|
|
|
|
|
if (isAutoLayout) {
|
|
|
|
|
dispatch({
|
|
|
|
|
type: ReduxActionTypes.PROCESS_AUTO_LAYOUT_DIMENSION_UPDATES,
|
|
|
|
|
});
|
|
|
|
|
}
|
2020-01-17 12:34:58 +00:00
|
|
|
}, 0);
|
2019-11-13 07:00:25 +00:00
|
|
|
// Tell the Canvas to put the focus back to this widget
|
|
|
|
|
// By setting the focus, we enable the control buttons on the widget
|
2020-03-04 08:10:40 +00:00
|
|
|
selectWidget &&
|
2022-09-14 06:55:08 +00:00
|
|
|
!isLastSelected &&
|
2021-08-09 05:35:01 +00:00
|
|
|
parentWidgetToSelect?.widgetId !== props.widgetId &&
|
2023-01-28 02:17:06 +00:00
|
|
|
selectWidget(SelectionRequestType.One, [props.widgetId]);
|
2021-08-09 05:35:01 +00:00
|
|
|
|
|
|
|
|
if (parentWidgetToSelect) {
|
|
|
|
|
selectWidget &&
|
2022-09-14 06:55:08 +00:00
|
|
|
!isParentWidgetSelected &&
|
2023-01-28 02:17:06 +00:00
|
|
|
selectWidget(SelectionRequestType.One, [parentWidgetToSelect.widgetId]);
|
2021-08-09 05:35:01 +00:00
|
|
|
focusWidget(parentWidgetToSelect.widgetId);
|
|
|
|
|
} else {
|
2023-01-28 02:17:06 +00:00
|
|
|
selectWidget &&
|
|
|
|
|
!isLastSelected &&
|
|
|
|
|
selectWidget(SelectionRequestType.One, [props.widgetId]);
|
2021-08-09 05:35:01 +00:00
|
|
|
}
|
2021-08-23 14:12:17 +00:00
|
|
|
// Property pane closes after a resize/drag
|
|
|
|
|
showPropertyPane && showPropertyPane();
|
2020-03-03 07:02:53 +00:00
|
|
|
AnalyticsUtil.logEvent("WIDGET_RESIZE_END", {
|
|
|
|
|
widgetName: props.widgetName,
|
|
|
|
|
widgetType: props.type,
|
|
|
|
|
startHeight: dimensions.height,
|
|
|
|
|
startWidth: dimensions.width,
|
|
|
|
|
endHeight: newDimensions.height,
|
|
|
|
|
endWidth: newDimensions.width,
|
|
|
|
|
});
|
2020-02-18 19:56:58 +00:00
|
|
|
};
|
|
|
|
|
|
2023-03-04 07:25:54 +00:00
|
|
|
const handleResizeStart = (affectsWidth = false) => {
|
2020-02-18 19:56:58 +00:00
|
|
|
setIsResizing && !isResizing && setIsResizing(true);
|
2023-01-28 02:17:06 +00:00
|
|
|
selectWidget &&
|
|
|
|
|
!isLastSelected &&
|
|
|
|
|
selectWidget(SelectionRequestType.One, [props.widgetId]);
|
2021-07-20 05:18:58 +00:00
|
|
|
// Make sure that this tableFilterPane should close
|
|
|
|
|
showTableFilterPane && showTableFilterPane();
|
2023-03-04 07:25:54 +00:00
|
|
|
// If resizing a fill widget "horizontally", then convert it to a hug widget.
|
|
|
|
|
if (
|
|
|
|
|
props.isFlexChild &&
|
|
|
|
|
props.responsiveBehavior === ResponsiveBehavior.Fill &&
|
|
|
|
|
affectsWidth
|
|
|
|
|
)
|
|
|
|
|
dispatch(
|
|
|
|
|
batchUpdateMultipleWidgetProperties([
|
|
|
|
|
{
|
|
|
|
|
widgetId: props.widgetId,
|
|
|
|
|
updates: {
|
|
|
|
|
modify: {
|
|
|
|
|
responsiveBehavior: ResponsiveBehavior.Hug,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
]),
|
|
|
|
|
);
|
2020-03-03 07:02:53 +00:00
|
|
|
AnalyticsUtil.logEvent("WIDGET_RESIZE_START", {
|
|
|
|
|
widgetName: props.widgetName,
|
|
|
|
|
widgetType: props.type,
|
|
|
|
|
});
|
2019-09-22 20:25:05 +00:00
|
|
|
};
|
2021-06-18 07:42:57 +00:00
|
|
|
const handles = useMemo(() => {
|
|
|
|
|
const allHandles = {
|
|
|
|
|
left: LeftHandleStyles,
|
|
|
|
|
top: TopHandleStyles,
|
|
|
|
|
bottom: BottomHandleStyles,
|
|
|
|
|
right: RightHandleStyles,
|
|
|
|
|
bottomRight: BottomRightHandleStyles,
|
|
|
|
|
topLeft: TopLeftHandleStyles,
|
|
|
|
|
topRight: TopRightHandleStyles,
|
|
|
|
|
bottomLeft: BottomLeftHandleStyles,
|
|
|
|
|
};
|
2023-03-04 07:25:54 +00:00
|
|
|
const handlesToOmit = get(props, "disabledResizeHandles", []);
|
|
|
|
|
return omit(allHandles, handlesToOmit);
|
2021-06-18 07:42:57 +00:00
|
|
|
}, [props]);
|
2023-04-07 13:51:35 +00:00
|
|
|
const isAutoCanvasResizing = useSelector(
|
|
|
|
|
(state: AppState) => state.ui.widgetDragResize.isAutoCanvasResizing,
|
|
|
|
|
);
|
2020-02-18 19:56:58 +00:00
|
|
|
|
2021-06-09 10:35:10 +00:00
|
|
|
const isEnabled =
|
2023-04-07 13:51:35 +00:00
|
|
|
!isAutoCanvasResizing &&
|
2022-11-27 17:12:00 +00:00
|
|
|
!isDragging &&
|
|
|
|
|
isWidgetFocused &&
|
|
|
|
|
!props.resizeDisabled &&
|
|
|
|
|
!isSnipingMode &&
|
2023-03-23 11:41:58 +00:00
|
|
|
!isPreviewMode &&
|
|
|
|
|
!isAppSettingsPaneWithNavigationTabOpen;
|
2022-01-13 13:21:57 +00:00
|
|
|
const { updateDropTargetRows } = useContext(DropTargetContext);
|
|
|
|
|
|
|
|
|
|
const gridProps = {
|
|
|
|
|
parentColumnSpace: props.parentColumnSpace,
|
|
|
|
|
parentRowSpace: props.parentRowSpace,
|
|
|
|
|
paddingOffset: props.paddingOffset,
|
|
|
|
|
maxGridColumns: GridDefaults.DEFAULT_GRID_COLUMNS,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const originalPositions = {
|
|
|
|
|
id: props.widgetId,
|
|
|
|
|
left: props.leftColumn,
|
|
|
|
|
top: props.topRow,
|
|
|
|
|
bottom: props.bottomRow,
|
|
|
|
|
right: props.rightColumn,
|
|
|
|
|
};
|
|
|
|
|
const updateBottomRow = (bottom: number) => {
|
|
|
|
|
if (props.parentId) {
|
2022-01-25 15:28:31 +00:00
|
|
|
updateDropTargetRows && updateDropTargetRows([props.parentId], bottom);
|
2022-01-13 13:21:57 +00:00
|
|
|
}
|
|
|
|
|
};
|
2021-06-09 10:35:10 +00:00
|
|
|
|
2022-11-23 09:48:23 +00:00
|
|
|
const snapGrid = useMemo(
|
|
|
|
|
() => ({
|
|
|
|
|
x: props.parentColumnSpace,
|
|
|
|
|
y: props.parentRowSpace,
|
|
|
|
|
}),
|
|
|
|
|
[props.parentColumnSpace, props.parentRowSpace],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const isVerticalResizeEnabled = useMemo(() => {
|
|
|
|
|
return !isAutoHeightEnabledForWidget(props) && isEnabled;
|
|
|
|
|
}, [props, isAutoHeightEnabledForWidget, isEnabled]);
|
|
|
|
|
|
2023-02-03 05:47:40 +00:00
|
|
|
const fixedHeight =
|
2023-04-03 06:11:10 +00:00
|
|
|
isAutoHeightEnabledForWidgetWithLimits(props) ||
|
2023-02-03 05:47:40 +00:00
|
|
|
!isAutoHeightEnabledForWidget(props) ||
|
|
|
|
|
!props.isCanvas;
|
|
|
|
|
|
2023-03-04 07:25:54 +00:00
|
|
|
const allowResize: boolean =
|
2023-04-07 13:51:35 +00:00
|
|
|
!isMultiSelected || (isAutoLayout && !props.isFlexChild);
|
|
|
|
|
|
2023-03-04 07:25:54 +00:00
|
|
|
const isHovered = isFocused && !isSelected;
|
|
|
|
|
const showResizeBoundary =
|
2023-04-07 13:51:35 +00:00
|
|
|
!isAutoCanvasResizing &&
|
2023-03-23 11:41:58 +00:00
|
|
|
!isPreviewMode &&
|
|
|
|
|
!isAppSettingsPaneWithNavigationTabOpen &&
|
|
|
|
|
!isDragging &&
|
|
|
|
|
(isHovered || isSelected);
|
2019-09-22 20:25:05 +00:00
|
|
|
return (
|
2020-02-18 19:56:58 +00:00
|
|
|
<Resizable
|
2023-03-04 07:25:54 +00:00
|
|
|
allowResize={allowResize}
|
2021-04-28 10:28:39 +00:00
|
|
|
componentHeight={dimensions.height}
|
|
|
|
|
componentWidth={dimensions.width}
|
2023-03-04 07:25:54 +00:00
|
|
|
direction={props.direction}
|
2022-11-23 09:48:23 +00:00
|
|
|
enableHorizontalResize={isEnabled}
|
|
|
|
|
enableVerticalResize={isVerticalResizeEnabled}
|
2023-02-03 05:47:40 +00:00
|
|
|
fixedHeight={fixedHeight}
|
2022-01-13 13:21:57 +00:00
|
|
|
getResizedPositions={getResizedPositions}
|
|
|
|
|
gridProps={gridProps}
|
2021-06-18 07:42:57 +00:00
|
|
|
handles={handles}
|
2023-03-04 07:25:54 +00:00
|
|
|
isFlexChild={props.isFlexChild}
|
|
|
|
|
isHovered={isHovered}
|
|
|
|
|
isMobile={props.isMobile || false}
|
2023-02-03 05:47:40 +00:00
|
|
|
maxDynamicHeight={props.maxDynamicHeight}
|
2020-02-18 19:56:58 +00:00
|
|
|
onStart={handleResizeStart}
|
|
|
|
|
onStop={updateSize}
|
2022-01-13 13:21:57 +00:00
|
|
|
originalPositions={originalPositions}
|
2023-03-04 07:25:54 +00:00
|
|
|
paddingOffset={props.paddingOffset}
|
2022-01-13 13:21:57 +00:00
|
|
|
parentId={props.parentId}
|
2023-03-04 07:25:54 +00:00
|
|
|
responsiveBehavior={props.responsiveBehavior}
|
|
|
|
|
showResizeBoundary={showResizeBoundary}
|
2022-11-23 09:48:23 +00:00
|
|
|
snapGrid={snapGrid}
|
2023-04-07 13:51:35 +00:00
|
|
|
topRow={props.topRow}
|
2022-01-13 13:21:57 +00:00
|
|
|
updateBottomRow={updateBottomRow}
|
2021-07-06 09:21:46 +00:00
|
|
|
// Used only for performance tracking, can be removed after optimization.
|
2023-02-03 05:47:40 +00:00
|
|
|
widgetId={props.widgetId}
|
2021-07-06 09:21:46 +00:00
|
|
|
zWidgetId={props.widgetId}
|
|
|
|
|
zWidgetType={props.type}
|
2019-09-22 20:25:05 +00:00
|
|
|
>
|
2020-02-18 20:35:52 +00:00
|
|
|
<VisibilityContainer
|
|
|
|
|
padding={props.paddingOffset}
|
2023-03-04 07:25:54 +00:00
|
|
|
reduceOpacity={props.isFlexChild ? isSelected && isDragging : false}
|
2021-04-28 10:28:39 +00:00
|
|
|
visible={!!props.isVisible}
|
2020-02-18 20:35:52 +00:00
|
|
|
>
|
|
|
|
|
{props.children}
|
|
|
|
|
</VisibilityContainer>
|
2020-02-18 19:56:58 +00:00
|
|
|
</Resizable>
|
2019-09-22 20:25:05 +00:00
|
|
|
);
|
Feature/entity browse (#220)
# New Feature: Entity Explorer
- Entities are actions (apis and queries), datasources, pages, and widgets
- With this new feature, all entities in the application will be available
to view in the new entity explorer sidebar
- All existing application features from the api sidebar, query sidebar, datasource sidebar and pages sidebar
now are avialable on the entity explorer sidebar
- Users are now able to quickly switch to any entity in the application from the entity explorer sidebar.
- Users can also search all entities in the application from the new sidebar. Use cmd + f or ctrl + f to focus on the search input
- Users can rename entities from the new sidebar
- Users can also perform contextual actions on these entities like set a page as home page, copy/move actions, delete entity, etc from the context menu available alongside the entities in the sidebar
- Users can view the properties of the entities in the sidebar, as well as copy bindings to use in the application.
2020-08-10 08:52:45 +00:00
|
|
|
});
|
2019-09-22 20:25:05 +00:00
|
|
|
export default ResizableComponent;
|