2019-11-25 05:07:27 +00:00
|
|
|
import CanvasWidgetsNormalizer from "normalizers/CanvasWidgetsNormalizer";
|
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";
|
|
|
|
|
import type {
|
2020-11-04 11:40:59 +00:00
|
|
|
Page,
|
2019-09-16 08:08:03 +00:00
|
|
|
ReduxAction,
|
2019-09-24 12:36:03 +00:00
|
|
|
UpdateCanvasPayload,
|
2022-04-12 10:50:01 +00:00
|
|
|
} from "@appsmith/constants/ReduxActionConstants";
|
2019-11-22 14:02:55 +00:00
|
|
|
import {
|
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
|
|
|
ReduxActionErrorTypes,
|
|
|
|
|
ReduxActionTypes,
|
|
|
|
|
} from "@appsmith/constants/ReduxActionConstants";
|
|
|
|
|
import type {
|
2023-01-28 02:17:06 +00:00
|
|
|
ClonePageActionPayload,
|
|
|
|
|
CreatePageActionPayload,
|
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
|
|
|
FetchPageListPayload,
|
|
|
|
|
} from "actions/pageActions";
|
2023-04-07 13:51:35 +00:00
|
|
|
import { createPage } from "actions/pageActions";
|
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 {
|
|
|
|
|
clonePageSuccess,
|
[API breaking change : Automated Tests Will Fail] Page And Action Refactor (#549)
* Introduced new page which stores the published and unpublished pages as separate.
* Mid level commit to save the state.
* Parity of new page repository with old page repository (custom functions)
* WIP : Delete a page. This requires changes across application structure as well.
* Added publishedPages construct inside application to store the pages in the deployed view as well as isDefault so that the same changes (delete or isDefault) in unpublished view doesn't alter these fields for the published application
* Parity reached with PageService.
* Minor ActionService refactor to remove unnecessary code.
ApplicationPageService, LayoutActionService, LayoutService use the new page service to fetch the pages
Minor corrections in fetching the page from new page service in tests
* New save function which sets the PageDTO for unpublished page and then saves the new page into repository.
* Migration of page service functions to new page service functions across other services/tests/controller
* Finished migrating all the page service functions to the new page service functions
* Application Service Tests have been fixed.
* All the existing test cases are working now.
* Publish application implemented to store published pages as well. Added a basic test case to check that published pages is being set and that page's publishedPageDTO is being set accordingly.
* Minor TODOs added to add test cases for published application.
* A few tests to ascertain that published application page fields (deleted, isDefault) does not get changed when these statuses are changed for a page in edit mode.
* Added a new controller end point to fetch application in view mode.
* Added new endpoint for fetching an application in view mode on the client.
* Bug fix where get application in view mode API was not getting called.
* Fixed the get page names by application & archive pages which have been deleted in edit mode during publishing of application.
* During delete page, if a page was never published and it was deleted during edit, delete the entire page instead of just deleting the unpublished PageDTO
* Minor formatting.
* Non working client side code to fetch page list using view mode.
* revert unnecassary changes and streamlined view and edit actions
* Fix missed import
* Fixed a bug where if a page is not published, it should not be returned in view mode in list of page names api.
* Fixed update for a page which was not working in integration test.
* ActionDTO added.
* Solidified the new action structure.
* Migration added for NewAction index creation and NewAction per Action insertion in the database.
* Basic file structure added the new repository, custom repository, service, etc.
* Delete OldPage.java
* Repo functions added - TODO : Haven;t handled the published/edited views
* Helper functions added to convert Action to NewAction and vice-versa. Removed unused currentUserMono usage.
* Create & update action functionality added.
* Execute Action refactored. Removed dry run specific code.
* Repository migrated to handle new data structure. Execute action refactored to no longer support dry runs of actions.
* TODO added for special handling of change view of application to handle edge cases of pages/actions which either exist in published mode but don't exist in unpublished mode or vice versa.
* Migrated finding on load actions from spring repository to custom repository.
* In view mode, now actions are being fetched by application id directly instead of first fetching application and then using the page ids, fetching the actions. This reduces the db calls from 2 to 1 per fetch actions in view mode api call.
* Delete action and get all actions (used in edit mode on the client side) implemented.
* Updated CollectionService and ActionCollectionService to use the new action service instead of the old one.
* LayoutActionService refactored to now use the new service functions.
* ActionController now no longer used ActionService. The remaining service functions have been migrated to the new action service.
* Refactor across ACL code for addition/removal of policies during addition/removal of users to organization, making app public, refactor for services like policy utils, item service, etc.
* Removed the last of action repository and action service and replaced with new action repo and new action service.
* Compile and run time issues fixed. The server is coming up without any spring dependency errors.
* WIP in fixing fetching actions by page id.
* Finally!!! Fixed the fetch actions (both published and unpublished actions) by page id repository function.
* Fixed create action bug where null datasource in published actiondto (inside newly created action) leads to error.
* Fixed the execute action issues :
1. Removed the dry runs from the tests
2. Fixed the null pointer error in variable substituted action and datasource configurations.
* 1. Fixed the custom action repository field names.
2. Fixed the data structures used in ExamplesOrganizationClonerTests
* Fixed countByDatasourceId repository function which was querying the actions incorrectly.
* Fixed the clone example organization error where the id of the action was not getting updated in the page correctly. Yay!
* Fixed post merge compilation failure.
* Fixed more compilation time failures in ActionServiceTest
* Fixed failing test case for fetching actions in view mode.
* Minor changes to resolve merge changes and incorporate in the new refactored code.
* 1. Fixed compile time errors on Client code.
2. Fixed fetching of actions in view mode by application id. The repository function did not need name parameter. Removed the same.
* [Integration Testing Error Fix] : Added a new test case for refactor action name.
* Instead of fetching actions in the page, mistakenly used the base service which was fetching all the actions in the repository, barring none which led to the name refactor being blocked even though no action in the current page exists with the new proposed name,
* Added delete functionality to action service.
* Minor code cleanup
* Adding viewMode to action execution
* Replacing action with actionId.
* 1. Bug fix for deletion of unpublished action. In case of never published action, the entire action should be deleted. In case an action was published, only the unpublished action should be deleted.
2. In case of DB actions (external datasources), only the bare minimum fields should be stored inside the action (datasource id and datasource plugin id). The other fields should not be duplicated across code.
* Fixed yarn build compilation issues.
* Update app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ActionController.java
Co-authored-by: Arpit Mohan <mohanarpit@users.noreply.github.com>
* Changed the API path for GET applications in view mode. Some minor code formatting.
* Incorporated review comments.
* Some more unnecessary code removed.
* Instead of returning Page, now the interface object between client and server for Pages is PageDTO
* Migrated Page and Action to PageDTO and ActionDTO
Fixed the compilation issues.
TODO : Fix the test compilation issues.
* Fixed compilation time issues with all the tests by migrating Page and Action to PageDTO and ActionDTO respectively
* Action Controller and Page Controller no longer extend Base Controller. All the required functions have now been implemented and no base line API end points are being re-used from the base.
* Test case fixes.
* Bug Fix : Updating an action was not updating execute on load. Fixed the data flow leading to the error.
* Deprecating Page and Action domain objects. This is to ensure no new code is written with these till we remove this old code.
* Cloned example applications are now published before returning. This is to ensure that the applications are in ready to view mode when the new user signs up.
* Added a function comment to expand on the usage of new param introduced.
* When cloning a page, new actions were not being stored. Added that. Also updated the clonePage test to assert that the actions are also cloned when the pages are cloned.
* Updated a Api call
* removed extra slash
Co-authored-by: Hetu Nandu <hetunandu@gmail.com>
Co-authored-by: Satbir Singh <satbir121@gmail.com>
Co-authored-by: Arpit Mohan <mohanarpit@users.noreply.github.com>
Co-authored-by: nandan.anantharamu <nandan@thinkify.io>
2020-10-26 12:34:23 +00:00
|
|
|
deletePageSuccess,
|
2023-01-28 02:17:06 +00:00
|
|
|
fetchAllPageEntityCompletion,
|
|
|
|
|
fetchPage,
|
2020-08-14 07:43:01 +00:00
|
|
|
fetchPageSuccess,
|
2020-03-19 03:25:52 +00:00
|
|
|
fetchPublishedPageSuccess,
|
2023-01-28 02:17:06 +00:00
|
|
|
generateTemplateError,
|
|
|
|
|
generateTemplateSuccess,
|
2021-01-25 08:57:26 +00:00
|
|
|
initCanvasLayout,
|
2021-05-18 18:29:39 +00:00
|
|
|
saveLayout,
|
2023-01-28 02:17:06 +00:00
|
|
|
savePageSuccess,
|
2021-07-07 12:47:01 +00:00
|
|
|
setLastUpdatedTime,
|
2023-01-28 02:17:06 +00:00
|
|
|
setUrlData,
|
|
|
|
|
updateAndSaveLayout,
|
|
|
|
|
updateCurrentPage,
|
2022-12-02 05:49:51 +00:00
|
|
|
updatePageError,
|
2023-01-28 02:17:06 +00:00
|
|
|
updatePageSuccess,
|
|
|
|
|
updateWidgetNameSuccess,
|
2019-11-25 05:07:27 +00:00
|
|
|
} from "actions/pageActions";
|
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 {
|
[API breaking change : Automated Tests Will Fail] Page And Action Refactor (#549)
* Introduced new page which stores the published and unpublished pages as separate.
* Mid level commit to save the state.
* Parity of new page repository with old page repository (custom functions)
* WIP : Delete a page. This requires changes across application structure as well.
* Added publishedPages construct inside application to store the pages in the deployed view as well as isDefault so that the same changes (delete or isDefault) in unpublished view doesn't alter these fields for the published application
* Parity reached with PageService.
* Minor ActionService refactor to remove unnecessary code.
ApplicationPageService, LayoutActionService, LayoutService use the new page service to fetch the pages
Minor corrections in fetching the page from new page service in tests
* New save function which sets the PageDTO for unpublished page and then saves the new page into repository.
* Migration of page service functions to new page service functions across other services/tests/controller
* Finished migrating all the page service functions to the new page service functions
* Application Service Tests have been fixed.
* All the existing test cases are working now.
* Publish application implemented to store published pages as well. Added a basic test case to check that published pages is being set and that page's publishedPageDTO is being set accordingly.
* Minor TODOs added to add test cases for published application.
* A few tests to ascertain that published application page fields (deleted, isDefault) does not get changed when these statuses are changed for a page in edit mode.
* Added a new controller end point to fetch application in view mode.
* Added new endpoint for fetching an application in view mode on the client.
* Bug fix where get application in view mode API was not getting called.
* Fixed the get page names by application & archive pages which have been deleted in edit mode during publishing of application.
* During delete page, if a page was never published and it was deleted during edit, delete the entire page instead of just deleting the unpublished PageDTO
* Minor formatting.
* Non working client side code to fetch page list using view mode.
* revert unnecassary changes and streamlined view and edit actions
* Fix missed import
* Fixed a bug where if a page is not published, it should not be returned in view mode in list of page names api.
* Fixed update for a page which was not working in integration test.
* ActionDTO added.
* Solidified the new action structure.
* Migration added for NewAction index creation and NewAction per Action insertion in the database.
* Basic file structure added the new repository, custom repository, service, etc.
* Delete OldPage.java
* Repo functions added - TODO : Haven;t handled the published/edited views
* Helper functions added to convert Action to NewAction and vice-versa. Removed unused currentUserMono usage.
* Create & update action functionality added.
* Execute Action refactored. Removed dry run specific code.
* Repository migrated to handle new data structure. Execute action refactored to no longer support dry runs of actions.
* TODO added for special handling of change view of application to handle edge cases of pages/actions which either exist in published mode but don't exist in unpublished mode or vice versa.
* Migrated finding on load actions from spring repository to custom repository.
* In view mode, now actions are being fetched by application id directly instead of first fetching application and then using the page ids, fetching the actions. This reduces the db calls from 2 to 1 per fetch actions in view mode api call.
* Delete action and get all actions (used in edit mode on the client side) implemented.
* Updated CollectionService and ActionCollectionService to use the new action service instead of the old one.
* LayoutActionService refactored to now use the new service functions.
* ActionController now no longer used ActionService. The remaining service functions have been migrated to the new action service.
* Refactor across ACL code for addition/removal of policies during addition/removal of users to organization, making app public, refactor for services like policy utils, item service, etc.
* Removed the last of action repository and action service and replaced with new action repo and new action service.
* Compile and run time issues fixed. The server is coming up without any spring dependency errors.
* WIP in fixing fetching actions by page id.
* Finally!!! Fixed the fetch actions (both published and unpublished actions) by page id repository function.
* Fixed create action bug where null datasource in published actiondto (inside newly created action) leads to error.
* Fixed the execute action issues :
1. Removed the dry runs from the tests
2. Fixed the null pointer error in variable substituted action and datasource configurations.
* 1. Fixed the custom action repository field names.
2. Fixed the data structures used in ExamplesOrganizationClonerTests
* Fixed countByDatasourceId repository function which was querying the actions incorrectly.
* Fixed the clone example organization error where the id of the action was not getting updated in the page correctly. Yay!
* Fixed post merge compilation failure.
* Fixed more compilation time failures in ActionServiceTest
* Fixed failing test case for fetching actions in view mode.
* Minor changes to resolve merge changes and incorporate in the new refactored code.
* 1. Fixed compile time errors on Client code.
2. Fixed fetching of actions in view mode by application id. The repository function did not need name parameter. Removed the same.
* [Integration Testing Error Fix] : Added a new test case for refactor action name.
* Instead of fetching actions in the page, mistakenly used the base service which was fetching all the actions in the repository, barring none which led to the name refactor being blocked even though no action in the current page exists with the new proposed name,
* Added delete functionality to action service.
* Minor code cleanup
* Adding viewMode to action execution
* Replacing action with actionId.
* 1. Bug fix for deletion of unpublished action. In case of never published action, the entire action should be deleted. In case an action was published, only the unpublished action should be deleted.
2. In case of DB actions (external datasources), only the bare minimum fields should be stored inside the action (datasource id and datasource plugin id). The other fields should not be duplicated across code.
* Fixed yarn build compilation issues.
* Update app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ActionController.java
Co-authored-by: Arpit Mohan <mohanarpit@users.noreply.github.com>
* Changed the API path for GET applications in view mode. Some minor code formatting.
* Incorporated review comments.
* Some more unnecessary code removed.
* Instead of returning Page, now the interface object between client and server for Pages is PageDTO
* Migrated Page and Action to PageDTO and ActionDTO
Fixed the compilation issues.
TODO : Fix the test compilation issues.
* Fixed compilation time issues with all the tests by migrating Page and Action to PageDTO and ActionDTO respectively
* Action Controller and Page Controller no longer extend Base Controller. All the required functions have now been implemented and no base line API end points are being re-used from the base.
* Test case fixes.
* Bug Fix : Updating an action was not updating execute on load. Fixed the data flow leading to the error.
* Deprecating Page and Action domain objects. This is to ensure no new code is written with these till we remove this old code.
* Cloned example applications are now published before returning. This is to ensure that the applications are in ready to view mode when the new user signs up.
* Added a function comment to expand on the usage of new param introduced.
* When cloning a page, new actions were not being stored. Added that. Also updated the clonePage test to assert that the actions are also cloned when the pages are cloned.
* Updated a Api call
* removed extra slash
Co-authored-by: Hetu Nandu <hetunandu@gmail.com>
Co-authored-by: Satbir Singh <satbir121@gmail.com>
Co-authored-by: Arpit Mohan <mohanarpit@users.noreply.github.com>
Co-authored-by: nandan.anantharamu <nandan@thinkify.io>
2020-10-26 12:34:23 +00:00
|
|
|
ClonePageRequest,
|
2020-08-14 07:43:01 +00:00
|
|
|
CreatePageRequest,
|
|
|
|
|
DeletePageRequest,
|
|
|
|
|
FetchPageListResponse,
|
2019-09-17 15:09:55 +00:00
|
|
|
FetchPageRequest,
|
2020-08-14 07:43:01 +00:00
|
|
|
FetchPageResponse,
|
2019-10-24 07:03:59 +00:00
|
|
|
FetchPublishedPageRequest,
|
2023-01-28 02:17:06 +00:00
|
|
|
GenerateTemplatePageRequest,
|
2020-08-14 07:43:01 +00:00
|
|
|
PageLayout,
|
2023-04-07 13:51:35 +00:00
|
|
|
PageLayoutsRequest,
|
2022-10-11 05:32:44 +00:00
|
|
|
SavePageRequest,
|
2020-08-14 07:43:01 +00:00
|
|
|
SavePageResponse,
|
2022-09-24 10:01:52 +00:00
|
|
|
SavePageResponseData,
|
2021-08-13 11:38:26 +00:00
|
|
|
SetPageOrderRequest,
|
2020-01-27 08:24:58 +00:00
|
|
|
UpdatePageRequest,
|
2022-12-02 05:49:51 +00:00
|
|
|
UpdatePageResponse,
|
2020-02-21 12:16:49 +00:00
|
|
|
UpdateWidgetNameRequest,
|
|
|
|
|
UpdateWidgetNameResponse,
|
2019-11-25 05:07:27 +00:00
|
|
|
} from "api/PageApi";
|
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 PageApi from "api/PageApi";
|
|
|
|
|
import type {
|
2022-06-21 13:57:34 +00:00
|
|
|
CanvasWidgetsReduxState,
|
|
|
|
|
FlattenedWidgetProps,
|
|
|
|
|
} from "reducers/entityReducers/canvasWidgetsReducer";
|
2019-09-22 20:25:05 +00:00
|
|
|
import {
|
2020-08-14 07:43:01 +00:00
|
|
|
all,
|
2019-09-22 20:25:05 +00:00
|
|
|
call,
|
2020-08-14 07:43:01 +00:00
|
|
|
debounce,
|
2023-01-09 14:22:23 +00:00
|
|
|
delay,
|
2019-09-22 20:25:05 +00:00
|
|
|
put,
|
2020-08-14 07:43:01 +00:00
|
|
|
select,
|
2022-12-02 05:49:51 +00:00
|
|
|
takeEvery,
|
2019-09-22 20:25:05 +00:00
|
|
|
takeLatest,
|
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
|
|
|
takeLeading,
|
2019-09-22 20:25:05 +00:00
|
|
|
} from "redux-saga/effects";
|
2020-02-21 07:19:10 +00:00
|
|
|
import history from "utils/history";
|
2023-04-13 11:44:24 +00:00
|
|
|
import { isNameValid } from "utils/helpers";
|
2021-09-09 15:10:22 +00:00
|
|
|
import { extractCurrentDSL } from "utils/WidgetPropsUtils";
|
|
|
|
|
import { checkIfMigrationIsNeeded } from "utils/DSLMigrations";
|
2023-04-07 13:51:35 +00:00
|
|
|
import {
|
|
|
|
|
getAllPageIds,
|
|
|
|
|
getDefaultPageId,
|
|
|
|
|
getEditorConfigs,
|
|
|
|
|
getWidgets,
|
|
|
|
|
} from "./selectors";
|
2021-03-04 05:24:47 +00:00
|
|
|
import { IncorrectBindingError, validateResponse } from "./ErrorSagas";
|
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 { ApiResponse } from "api/ApiResponses";
|
2020-02-21 12:16:49 +00:00
|
|
|
import {
|
|
|
|
|
getCurrentApplicationId,
|
2020-08-14 07:43:01 +00:00
|
|
|
getCurrentLayoutId,
|
|
|
|
|
getCurrentPageId,
|
2020-02-21 12:16:49 +00:00
|
|
|
getCurrentPageName,
|
2023-04-07 13:51:35 +00:00
|
|
|
getIsAutoLayout,
|
|
|
|
|
getMainCanvasProps,
|
2022-12-01 06:30:50 +00:00
|
|
|
getPageById,
|
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
|
|
|
previewModeSelector,
|
2020-02-21 12:16:49 +00:00
|
|
|
} from "selectors/editorSelectors";
|
2020-08-27 15:39:16 +00:00
|
|
|
import {
|
2021-08-27 09:25:28 +00:00
|
|
|
executePageLoadActions,
|
2020-08-27 15:39:16 +00:00
|
|
|
fetchActionsForPage,
|
2023-01-28 02:17:06 +00:00
|
|
|
fetchActionsForPageError,
|
|
|
|
|
fetchActionsForPageSuccess,
|
2020-08-27 15:39:16 +00:00
|
|
|
setActionsToExecuteOnPageLoad,
|
2022-03-17 12:05:17 +00:00
|
|
|
setJSActionsToExecuteOnPageLoad,
|
2021-08-27 09:25:28 +00:00
|
|
|
} from "actions/pluginActionActions";
|
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 { UrlDataState } from "reducers/entityReducers/appReducer";
|
2021-08-06 09:17:56 +00:00
|
|
|
import { APP_MODE } from "entities/App";
|
2021-01-04 10:16:08 +00:00
|
|
|
import { clearEvalCache } from "./EvaluationsSaga";
|
2022-08-04 05:40:44 +00:00
|
|
|
import { getQueryParams } from "utils/URLUtils";
|
2020-09-28 05:12:23 +00:00
|
|
|
import PerformanceTracker, {
|
|
|
|
|
PerformanceTransactionName,
|
|
|
|
|
} from "utils/PerformanceTracker";
|
2021-03-13 14:24:45 +00:00
|
|
|
import log from "loglevel";
|
2021-03-04 05:24:47 +00:00
|
|
|
import { migrateIncorrectDynamicBindingPathLists } from "utils/migrations/IncorrectDynamicBindingPathLists";
|
|
|
|
|
import * as Sentry from "@sentry/react";
|
2022-01-07 06:08:17 +00:00
|
|
|
import { ERROR_CODES } from "@appsmith/constants/ApiConstants";
|
2021-03-08 10:28:20 +00:00
|
|
|
import AnalyticsUtil from "utils/AnalyticsUtil";
|
2021-03-09 14:35:42 +00:00
|
|
|
import DEFAULT_TEMPLATE from "templates/default";
|
2022-06-06 03:56:14 +00:00
|
|
|
|
2023-03-29 17:07:06 +00:00
|
|
|
import { getAppMode } from "@appsmith/selectors/applicationSelectors";
|
2021-08-26 07:23:39 +00:00
|
|
|
import { setCrudInfoModalData } from "actions/crudInfoModalActions";
|
2023-01-28 02:17:06 +00:00
|
|
|
import { selectWidgetInitAction } from "actions/widgetSelectionActions";
|
2022-09-30 13:41:04 +00:00
|
|
|
import { inGuidedTour } from "selectors/onboardingSelectors";
|
2022-06-06 03:56:14 +00:00
|
|
|
import {
|
|
|
|
|
fetchJSCollectionsForPage,
|
|
|
|
|
fetchJSCollectionsForPageError,
|
2023-01-28 02:17:06 +00:00
|
|
|
fetchJSCollectionsForPageSuccess,
|
2022-06-06 03:56:14 +00:00
|
|
|
} from "actions/jsActionActions";
|
2020-02-21 12:16:49 +00:00
|
|
|
|
2021-09-09 15:10:22 +00:00
|
|
|
import WidgetFactory from "utils/WidgetFactory";
|
2022-01-25 13:56:52 +00:00
|
|
|
import { toggleShowDeviationDialog } from "actions/onboardingActions";
|
2022-09-30 13:41:04 +00:00
|
|
|
import { builderURL } from "RouteBuilder";
|
2022-06-06 03:56:14 +00:00
|
|
|
import { failFastApiCalls } from "./InitSagas";
|
2022-12-01 06:30:50 +00:00
|
|
|
import { hasManagePagePermission } from "@appsmith/utils/permissionHelpers";
|
2022-09-30 08:19:52 +00:00
|
|
|
import { resizePublishedMainCanvasToLowestWidget } from "./WidgetOperationUtils";
|
2022-09-24 10:01:52 +00:00
|
|
|
import { checkAndLogErrorsIfCyclicDependency } from "./helper";
|
2022-11-02 09:09:59 +00:00
|
|
|
import { LOCAL_STORAGE_KEYS } from "utils/localStorage";
|
2022-11-23 09:48:23 +00:00
|
|
|
import { generateAutoHeightLayoutTreeAction } from "actions/autoHeightActions";
|
2022-12-21 17:14:47 +00:00
|
|
|
import { getUsedActionNames } from "selectors/actionSelectors";
|
2022-12-13 09:19:22 +00:00
|
|
|
import { getPageList } from "selectors/entitiesSelector";
|
2023-01-09 14:22:23 +00:00
|
|
|
import { setPreviewModeAction } from "actions/editorActions";
|
2023-01-28 02:17:06 +00:00
|
|
|
import { SelectionRequestType } from "sagas/WidgetSelectUtils";
|
2023-05-19 18:37:06 +00:00
|
|
|
import { toast } from "design-system";
|
2023-04-07 13:51:35 +00:00
|
|
|
import { getCurrentGitBranch } from "selectors/gitSyncSelectors";
|
|
|
|
|
import type { MainCanvasReduxState } from "reducers/uiReducers/mainCanvasReducer";
|
2023-05-22 04:11:00 +00:00
|
|
|
import { UserCancelledActionExecutionError } from "./ActionExecution/errorUtils";
|
2023-05-29 12:35:38 +00:00
|
|
|
import { getCurrentWorkspaceId } from "@appsmith/selectors/workspaceSelectors";
|
|
|
|
|
import { getInstanceId } from "@appsmith/selectors/tenantSelectors";
|
2021-10-13 09:43:57 +00:00
|
|
|
|
2021-09-09 15:10:22 +00:00
|
|
|
const WidgetTypes = WidgetFactory.widgetTypes;
|
|
|
|
|
|
2020-02-21 12:16:49 +00:00
|
|
|
const getWidgetName = (state: AppState, widgetId: string) =>
|
|
|
|
|
state.entities.canvasWidgets[widgetId];
|
2019-03-30 12:30:42 +00:00
|
|
|
|
2019-11-22 14:02:55 +00:00
|
|
|
export function* fetchPageListSaga(
|
|
|
|
|
fetchPageListAction: ReduxAction<FetchPageListPayload>,
|
|
|
|
|
) {
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.startAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_LIST_API,
|
|
|
|
|
);
|
2019-10-31 08:36:04 +00:00
|
|
|
try {
|
[API breaking change : Automated Tests Will Fail] Page And Action Refactor (#549)
* Introduced new page which stores the published and unpublished pages as separate.
* Mid level commit to save the state.
* Parity of new page repository with old page repository (custom functions)
* WIP : Delete a page. This requires changes across application structure as well.
* Added publishedPages construct inside application to store the pages in the deployed view as well as isDefault so that the same changes (delete or isDefault) in unpublished view doesn't alter these fields for the published application
* Parity reached with PageService.
* Minor ActionService refactor to remove unnecessary code.
ApplicationPageService, LayoutActionService, LayoutService use the new page service to fetch the pages
Minor corrections in fetching the page from new page service in tests
* New save function which sets the PageDTO for unpublished page and then saves the new page into repository.
* Migration of page service functions to new page service functions across other services/tests/controller
* Finished migrating all the page service functions to the new page service functions
* Application Service Tests have been fixed.
* All the existing test cases are working now.
* Publish application implemented to store published pages as well. Added a basic test case to check that published pages is being set and that page's publishedPageDTO is being set accordingly.
* Minor TODOs added to add test cases for published application.
* A few tests to ascertain that published application page fields (deleted, isDefault) does not get changed when these statuses are changed for a page in edit mode.
* Added a new controller end point to fetch application in view mode.
* Added new endpoint for fetching an application in view mode on the client.
* Bug fix where get application in view mode API was not getting called.
* Fixed the get page names by application & archive pages which have been deleted in edit mode during publishing of application.
* During delete page, if a page was never published and it was deleted during edit, delete the entire page instead of just deleting the unpublished PageDTO
* Minor formatting.
* Non working client side code to fetch page list using view mode.
* revert unnecassary changes and streamlined view and edit actions
* Fix missed import
* Fixed a bug where if a page is not published, it should not be returned in view mode in list of page names api.
* Fixed update for a page which was not working in integration test.
* ActionDTO added.
* Solidified the new action structure.
* Migration added for NewAction index creation and NewAction per Action insertion in the database.
* Basic file structure added the new repository, custom repository, service, etc.
* Delete OldPage.java
* Repo functions added - TODO : Haven;t handled the published/edited views
* Helper functions added to convert Action to NewAction and vice-versa. Removed unused currentUserMono usage.
* Create & update action functionality added.
* Execute Action refactored. Removed dry run specific code.
* Repository migrated to handle new data structure. Execute action refactored to no longer support dry runs of actions.
* TODO added for special handling of change view of application to handle edge cases of pages/actions which either exist in published mode but don't exist in unpublished mode or vice versa.
* Migrated finding on load actions from spring repository to custom repository.
* In view mode, now actions are being fetched by application id directly instead of first fetching application and then using the page ids, fetching the actions. This reduces the db calls from 2 to 1 per fetch actions in view mode api call.
* Delete action and get all actions (used in edit mode on the client side) implemented.
* Updated CollectionService and ActionCollectionService to use the new action service instead of the old one.
* LayoutActionService refactored to now use the new service functions.
* ActionController now no longer used ActionService. The remaining service functions have been migrated to the new action service.
* Refactor across ACL code for addition/removal of policies during addition/removal of users to organization, making app public, refactor for services like policy utils, item service, etc.
* Removed the last of action repository and action service and replaced with new action repo and new action service.
* Compile and run time issues fixed. The server is coming up without any spring dependency errors.
* WIP in fixing fetching actions by page id.
* Finally!!! Fixed the fetch actions (both published and unpublished actions) by page id repository function.
* Fixed create action bug where null datasource in published actiondto (inside newly created action) leads to error.
* Fixed the execute action issues :
1. Removed the dry runs from the tests
2. Fixed the null pointer error in variable substituted action and datasource configurations.
* 1. Fixed the custom action repository field names.
2. Fixed the data structures used in ExamplesOrganizationClonerTests
* Fixed countByDatasourceId repository function which was querying the actions incorrectly.
* Fixed the clone example organization error where the id of the action was not getting updated in the page correctly. Yay!
* Fixed post merge compilation failure.
* Fixed more compilation time failures in ActionServiceTest
* Fixed failing test case for fetching actions in view mode.
* Minor changes to resolve merge changes and incorporate in the new refactored code.
* 1. Fixed compile time errors on Client code.
2. Fixed fetching of actions in view mode by application id. The repository function did not need name parameter. Removed the same.
* [Integration Testing Error Fix] : Added a new test case for refactor action name.
* Instead of fetching actions in the page, mistakenly used the base service which was fetching all the actions in the repository, barring none which led to the name refactor being blocked even though no action in the current page exists with the new proposed name,
* Added delete functionality to action service.
* Minor code cleanup
* Adding viewMode to action execution
* Replacing action with actionId.
* 1. Bug fix for deletion of unpublished action. In case of never published action, the entire action should be deleted. In case an action was published, only the unpublished action should be deleted.
2. In case of DB actions (external datasources), only the bare minimum fields should be stored inside the action (datasource id and datasource plugin id). The other fields should not be duplicated across code.
* Fixed yarn build compilation issues.
* Update app/server/appsmith-server/src/main/java/com/appsmith/server/controllers/ActionController.java
Co-authored-by: Arpit Mohan <mohanarpit@users.noreply.github.com>
* Changed the API path for GET applications in view mode. Some minor code formatting.
* Incorporated review comments.
* Some more unnecessary code removed.
* Instead of returning Page, now the interface object between client and server for Pages is PageDTO
* Migrated Page and Action to PageDTO and ActionDTO
Fixed the compilation issues.
TODO : Fix the test compilation issues.
* Fixed compilation time issues with all the tests by migrating Page and Action to PageDTO and ActionDTO respectively
* Action Controller and Page Controller no longer extend Base Controller. All the required functions have now been implemented and no base line API end points are being re-used from the base.
* Test case fixes.
* Bug Fix : Updating an action was not updating execute on load. Fixed the data flow leading to the error.
* Deprecating Page and Action domain objects. This is to ensure no new code is written with these till we remove this old code.
* Cloned example applications are now published before returning. This is to ensure that the applications are in ready to view mode when the new user signs up.
* Added a function comment to expand on the usage of new param introduced.
* When cloning a page, new actions were not being stored. Added that. Also updated the clonePage test to assert that the actions are also cloned when the pages are cloned.
* Updated a Api call
* removed extra slash
Co-authored-by: Hetu Nandu <hetunandu@gmail.com>
Co-authored-by: Satbir Singh <satbir121@gmail.com>
Co-authored-by: Arpit Mohan <mohanarpit@users.noreply.github.com>
Co-authored-by: nandan.anantharamu <nandan@thinkify.io>
2020-10-26 12:34:23 +00:00
|
|
|
const { applicationId, mode } = fetchPageListAction.payload;
|
|
|
|
|
const apiCall =
|
|
|
|
|
mode === APP_MODE.EDIT
|
|
|
|
|
? PageApi.fetchPageList
|
|
|
|
|
: PageApi.fetchPageListViewMode;
|
|
|
|
|
const response: FetchPageListResponse = yield call(apiCall, applicationId);
|
2021-07-29 08:13:10 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(response);
|
2022-12-13 09:19:22 +00:00
|
|
|
const prevPagesState: Page[] = yield select(getPageList);
|
|
|
|
|
const pagePermissionsMap = prevPagesState.reduce((acc, page) => {
|
|
|
|
|
acc[page.pageId] = page.userPermissions ?? [];
|
|
|
|
|
return acc;
|
|
|
|
|
}, {} as Record<string, string[]>);
|
2019-10-31 08:36:04 +00:00
|
|
|
if (isValidResponse) {
|
2022-06-15 15:37:41 +00:00
|
|
|
const workspaceId = response.data.workspaceId;
|
2022-06-21 13:57:34 +00:00
|
|
|
const pages: Page[] = response.data.pages.map((page) => ({
|
2019-10-31 08:36:04 +00:00
|
|
|
pageName: page.name,
|
2023-01-14 19:28:02 +00:00
|
|
|
description: page.description,
|
2019-10-31 08:36:04 +00:00
|
|
|
pageId: page.id,
|
2020-01-27 08:24:58 +00:00
|
|
|
isDefault: page.isDefault,
|
2021-02-24 13:47:37 +00:00
|
|
|
isHidden: !!page.isHidden,
|
2022-03-25 10:43:26 +00:00
|
|
|
slug: page.slug,
|
2022-12-13 09:19:22 +00:00
|
|
|
userPermissions: page.userPermissions
|
|
|
|
|
? page.userPermissions
|
|
|
|
|
: pagePermissionsMap[page.id],
|
2019-10-31 08:36:04 +00:00
|
|
|
}));
|
|
|
|
|
yield put({
|
2022-06-15 15:37:41 +00:00
|
|
|
type: ReduxActionTypes.SET_CURRENT_WORKSPACE_ID,
|
2019-11-22 14:02:55 +00:00
|
|
|
payload: {
|
2022-06-15 15:37:41 +00:00
|
|
|
workspaceId,
|
2019-11-22 14:02:55 +00:00
|
|
|
},
|
2019-10-31 08:36:04 +00:00
|
|
|
});
|
2020-06-17 10:19:56 +00:00
|
|
|
yield put({
|
2020-08-26 13:22:10 +00:00
|
|
|
type: ReduxActionTypes.FETCH_PAGE_LIST_SUCCESS,
|
2020-06-17 10:19:56 +00:00
|
|
|
payload: {
|
2020-08-26 13:22:10 +00:00
|
|
|
pages,
|
2021-10-18 14:03:44 +00:00
|
|
|
applicationId: applicationId,
|
2020-06-17 10:19:56 +00:00
|
|
|
},
|
|
|
|
|
});
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_LIST_API,
|
|
|
|
|
);
|
2020-11-04 11:40:59 +00:00
|
|
|
} else {
|
|
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_LIST_API,
|
|
|
|
|
);
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.FETCH_PAGE_LIST_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error: response.responseMeta.error,
|
|
|
|
|
},
|
|
|
|
|
});
|
2019-10-31 08:36:04 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_LIST_API,
|
|
|
|
|
{ failed: true },
|
|
|
|
|
);
|
2019-10-31 08:36:04 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.FETCH_PAGE_LIST_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-11-08 11:02:00 +00:00
|
|
|
|
2023-04-07 13:51:35 +00:00
|
|
|
//Method to load the default page if current page is not found
|
|
|
|
|
export function* refreshTheApp() {
|
|
|
|
|
try {
|
|
|
|
|
const currentPageId: string = yield select(getCurrentPageId);
|
|
|
|
|
const defaultPageId: string = yield select(getDefaultPageId);
|
|
|
|
|
const pagesList: Page[] = yield select(getPageList);
|
|
|
|
|
const gitBranch: string = yield select(getCurrentGitBranch);
|
|
|
|
|
|
|
|
|
|
const isCurrentPageIdInList =
|
|
|
|
|
pagesList.filter((page) => page.pageId === currentPageId).length > 0;
|
|
|
|
|
|
|
|
|
|
if (isCurrentPageIdInList) {
|
|
|
|
|
location.reload();
|
|
|
|
|
} else {
|
|
|
|
|
location.assign(
|
|
|
|
|
builderURL({
|
|
|
|
|
pageId: defaultPageId,
|
|
|
|
|
branch: gitBranch,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
log.error(error);
|
|
|
|
|
location.reload();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-27 07:16:54 +00:00
|
|
|
export const getCanvasWidgetsPayload = (
|
2019-10-31 08:36:04 +00:00
|
|
|
pageResponse: FetchPageResponse,
|
2023-04-07 13:51:35 +00:00
|
|
|
isAutoLayout?: boolean,
|
|
|
|
|
mainCanvasWidth?: number,
|
2019-10-31 08:36:04 +00:00
|
|
|
): UpdateCanvasPayload => {
|
2023-04-07 13:51:35 +00:00
|
|
|
const extractedDSL = extractCurrentDSL(
|
|
|
|
|
pageResponse,
|
|
|
|
|
isAutoLayout,
|
|
|
|
|
mainCanvasWidth,
|
|
|
|
|
).dsl;
|
|
|
|
|
const normalizedResponse = CanvasWidgetsNormalizer.normalize(extractedDSL);
|
2019-10-31 08:36:04 +00:00
|
|
|
return {
|
|
|
|
|
pageWidgetId: normalizedResponse.result,
|
|
|
|
|
currentPageName: pageResponse.data.name,
|
|
|
|
|
currentPageId: pageResponse.data.id,
|
2023-04-07 13:51:35 +00:00
|
|
|
dsl: extractedDSL,
|
2019-10-31 08:36:04 +00:00
|
|
|
widgets: normalizedResponse.entities.canvasWidgets,
|
|
|
|
|
currentLayoutId: pageResponse.data.layouts[0].id, // TODO(abhinav): Handle for multiple layouts
|
|
|
|
|
currentApplicationId: pageResponse.data.applicationId,
|
2019-12-11 15:24:27 +00:00
|
|
|
pageActions: pageResponse.data.layouts[0].layoutOnLoadActions || [],
|
2022-09-24 10:01:52 +00:00
|
|
|
layoutOnLoadActionErrors:
|
|
|
|
|
pageResponse.data.layouts[0].layoutOnLoadActionErrors || [],
|
2019-10-31 08:36:04 +00:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2022-03-25 10:43:26 +00:00
|
|
|
export function* handleFetchedPage({
|
2021-07-29 08:13:10 +00:00
|
|
|
fetchPageResponse,
|
|
|
|
|
isFirstLoad = false,
|
|
|
|
|
pageId,
|
|
|
|
|
}: {
|
|
|
|
|
fetchPageResponse: FetchPageResponse;
|
|
|
|
|
pageId: string;
|
|
|
|
|
isFirstLoad?: boolean;
|
|
|
|
|
}) {
|
2023-04-07 13:51:35 +00:00
|
|
|
const isAutoLayout: boolean = yield select(getIsAutoLayout);
|
|
|
|
|
const mainCanvasProps: MainCanvasReduxState = yield select(
|
|
|
|
|
getMainCanvasProps,
|
|
|
|
|
);
|
2022-06-21 13:57:34 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(fetchPageResponse);
|
2021-07-29 08:13:10 +00:00
|
|
|
const willPageBeMigrated = checkIfMigrationIsNeeded(fetchPageResponse);
|
|
|
|
|
const lastUpdatedTime = getLastUpdateTime(fetchPageResponse);
|
2022-03-25 10:43:26 +00:00
|
|
|
const pageSlug = fetchPageResponse.data.slug;
|
2022-12-01 06:30:50 +00:00
|
|
|
const pagePermissions = fetchPageResponse.data.userPermissions;
|
2021-07-29 08:13:10 +00:00
|
|
|
|
|
|
|
|
if (isValidResponse) {
|
|
|
|
|
// Clear any existing caches
|
|
|
|
|
yield call(clearEvalCache);
|
|
|
|
|
// Set url params
|
|
|
|
|
yield call(setDataUrl);
|
|
|
|
|
// Get Canvas payload
|
2023-04-07 13:51:35 +00:00
|
|
|
const canvasWidgetsPayload = getCanvasWidgetsPayload(
|
|
|
|
|
fetchPageResponse,
|
|
|
|
|
isAutoLayout,
|
|
|
|
|
mainCanvasProps.width,
|
|
|
|
|
);
|
2021-07-29 08:13:10 +00:00
|
|
|
// Update the canvas
|
|
|
|
|
yield put(initCanvasLayout(canvasWidgetsPayload));
|
|
|
|
|
// set current page
|
2022-12-01 06:30:50 +00:00
|
|
|
yield put(updateCurrentPage(pageId, pageSlug, pagePermissions));
|
2021-07-29 08:13:10 +00:00
|
|
|
// dispatch fetch page success
|
2022-06-06 03:56:14 +00:00
|
|
|
yield put(fetchPageSuccess());
|
|
|
|
|
|
|
|
|
|
/* Currently, All Actions are fetched in initSagas and on pageSwitch we only fetch page
|
|
|
|
|
*/
|
|
|
|
|
// Hence, if is not isFirstLoad then trigger evaluation with execute pageLoad action
|
|
|
|
|
if (!isFirstLoad) {
|
|
|
|
|
yield put(fetchAllPageEntityCompletion([executePageLoadActions()]));
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-29 08:13:10 +00:00
|
|
|
// Sets last updated time
|
|
|
|
|
yield put(setLastUpdatedTime(lastUpdatedTime));
|
2023-04-07 13:51:35 +00:00
|
|
|
|
2021-07-29 08:13:10 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.UPDATE_CANVAS_STRUCTURE,
|
2023-04-07 13:51:35 +00:00
|
|
|
payload: canvasWidgetsPayload.dsl,
|
2021-07-29 08:13:10 +00:00
|
|
|
});
|
|
|
|
|
|
2022-11-23 09:48:23 +00:00
|
|
|
// Since new page has new layout, we need to generate a data structure
|
|
|
|
|
// to compute dynamic height based on the new layout.
|
|
|
|
|
yield put(generateAutoHeightLayoutTreeAction(true, true));
|
|
|
|
|
|
2021-07-29 08:13:10 +00:00
|
|
|
if (willPageBeMigrated) {
|
|
|
|
|
yield put(saveLayout());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-01-14 19:28:02 +00:00
|
|
|
|
2021-07-07 12:47:01 +00:00
|
|
|
const getLastUpdateTime = (pageResponse: FetchPageResponse): number =>
|
|
|
|
|
pageResponse.data.lastUpdatedTime;
|
|
|
|
|
|
2019-09-19 22:25:37 +00:00
|
|
|
export function* fetchPageSaga(
|
2020-03-06 09:33:20 +00:00
|
|
|
pageRequestAction: ReduxAction<FetchPageRequest>,
|
2019-09-19 22:25:37 +00:00
|
|
|
) {
|
2019-08-26 12:41:21 +00:00
|
|
|
try {
|
2021-06-30 07:19:43 +00:00
|
|
|
const { id, isFirstLoad } = pageRequestAction.payload;
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.startAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_API,
|
|
|
|
|
{ pageId: id },
|
|
|
|
|
);
|
2020-02-13 09:32:24 +00:00
|
|
|
const fetchPageResponse: FetchPageResponse = yield call(PageApi.fetchPage, {
|
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
|
|
|
id,
|
2020-02-13 09:32:24 +00:00
|
|
|
});
|
2022-03-25 10:43:26 +00:00
|
|
|
|
2021-07-29 08:13:10 +00:00
|
|
|
yield handleFetchedPage({
|
|
|
|
|
fetchPageResponse,
|
|
|
|
|
pageId: id,
|
|
|
|
|
isFirstLoad,
|
|
|
|
|
});
|
2021-05-18 18:29:39 +00:00
|
|
|
|
2021-07-29 08:13:10 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_API,
|
|
|
|
|
);
|
2019-09-23 10:27:45 +00:00
|
|
|
} catch (error) {
|
2021-03-13 14:24:45 +00:00
|
|
|
log.error(error);
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_API,
|
|
|
|
|
{
|
|
|
|
|
failed: true,
|
|
|
|
|
},
|
|
|
|
|
);
|
2019-09-27 16:05:33 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.FETCH_PAGE_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
2019-03-30 12:30:42 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-24 07:03:59 +00:00
|
|
|
export function* fetchPublishedPageSaga(
|
2022-05-11 07:06:25 +00:00
|
|
|
pageRequestAction: ReduxAction<{
|
|
|
|
|
pageId: string;
|
|
|
|
|
bustCache: boolean;
|
|
|
|
|
firstLoad: boolean;
|
|
|
|
|
}>,
|
2019-10-24 07:03:59 +00:00
|
|
|
) {
|
|
|
|
|
try {
|
2022-05-11 07:06:25 +00:00
|
|
|
const { bustCache, firstLoad, pageId } = pageRequestAction.payload;
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.startAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_API,
|
2021-04-23 05:43:13 +00:00
|
|
|
{
|
|
|
|
|
pageId: pageId,
|
|
|
|
|
published: true,
|
|
|
|
|
},
|
2020-09-28 05:12:23 +00:00
|
|
|
);
|
2019-10-31 08:36:04 +00:00
|
|
|
const request: FetchPublishedPageRequest = {
|
|
|
|
|
pageId,
|
2020-05-05 12:16:51 +00:00
|
|
|
bustCache,
|
2019-10-31 08:36:04 +00:00
|
|
|
};
|
2022-06-21 13:57:34 +00:00
|
|
|
const response: FetchPageResponse = yield call(
|
2019-10-24 07:03:59 +00:00
|
|
|
PageApi.fetchPublishedPage,
|
2019-10-24 09:23:50 +00:00
|
|
|
request,
|
2019-10-24 07:03:59 +00:00
|
|
|
);
|
2021-07-29 08:13:10 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(response);
|
2019-10-24 07:03:59 +00:00
|
|
|
if (isValidResponse) {
|
2020-04-17 16:15:09 +00:00
|
|
|
// Clear any existing caches
|
2020-10-21 04:25:32 +00:00
|
|
|
yield call(clearEvalCache);
|
2020-08-07 14:24:26 +00:00
|
|
|
// Set url params
|
|
|
|
|
yield call(setDataUrl);
|
|
|
|
|
// Get Canvas payload
|
2020-03-06 09:33:20 +00:00
|
|
|
const canvasWidgetsPayload = getCanvasWidgetsPayload(response);
|
2022-09-30 08:19:52 +00:00
|
|
|
// resize main canvas
|
|
|
|
|
resizePublishedMainCanvasToLowestWidget(canvasWidgetsPayload.widgets);
|
2020-08-07 14:24:26 +00:00
|
|
|
// Update the canvas
|
2021-01-25 08:57:26 +00:00
|
|
|
yield put(initCanvasLayout(canvasWidgetsPayload));
|
2020-08-07 14:24:26 +00:00
|
|
|
// set current page
|
2022-12-14 15:02:13 +00:00
|
|
|
yield put(
|
|
|
|
|
updateCurrentPage(
|
|
|
|
|
pageId,
|
|
|
|
|
response.data.slug,
|
|
|
|
|
response.data.userPermissions,
|
|
|
|
|
),
|
|
|
|
|
);
|
2022-05-11 07:06:25 +00:00
|
|
|
|
2022-06-06 03:56:14 +00:00
|
|
|
// dispatch fetch page success
|
|
|
|
|
yield put(fetchPublishedPageSuccess());
|
|
|
|
|
|
2022-11-23 09:48:23 +00:00
|
|
|
// Since new page has new layout, we need to generate a data structure
|
|
|
|
|
// to compute dynamic height based on the new layout.
|
|
|
|
|
yield put(generateAutoHeightLayoutTreeAction(true, true));
|
|
|
|
|
|
2022-06-06 03:56:14 +00:00
|
|
|
/* Currently, All Actions are fetched in initSagas and on pageSwitch we only fetch page
|
|
|
|
|
*/
|
|
|
|
|
// Hence, if is not isFirstLoad then trigger evaluation with execute pageLoad action
|
2022-05-11 07:06:25 +00:00
|
|
|
if (!firstLoad) {
|
2022-06-06 03:56:14 +00:00
|
|
|
yield put(fetchAllPageEntityCompletion([executePageLoadActions()]));
|
2022-05-11 07:06:25 +00:00
|
|
|
}
|
2022-06-06 03:56:14 +00:00
|
|
|
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_API,
|
|
|
|
|
);
|
2019-10-24 07:03:59 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.FETCH_PAGE_API,
|
|
|
|
|
{
|
|
|
|
|
failed: true,
|
|
|
|
|
},
|
|
|
|
|
);
|
2019-10-24 07:03:59 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.FETCH_PUBLISHED_PAGE_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-05 12:16:51 +00:00
|
|
|
export function* fetchAllPublishedPagesSaga() {
|
|
|
|
|
try {
|
2022-06-21 13:57:34 +00:00
|
|
|
const pageIds: string[] = yield select(getAllPageIds);
|
2020-05-05 12:16:51 +00:00
|
|
|
yield all(
|
|
|
|
|
pageIds.map((pageId: string) => {
|
2022-05-04 09:45:57 +00:00
|
|
|
return call(PageApi.fetchPublishedPage, { pageId, bustCache: true });
|
2020-05-05 12:16:51 +00:00
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
} catch (error) {
|
2021-03-13 14:24:45 +00:00
|
|
|
log.error({ error });
|
2020-05-05 12:16:51 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-04 05:24:47 +00:00
|
|
|
function* savePageSaga(action: ReduxAction<{ isRetry?: boolean }>) {
|
2022-06-21 13:57:34 +00:00
|
|
|
const widgets: CanvasWidgetsReduxState = yield select(getWidgets);
|
|
|
|
|
const editorConfigs:
|
|
|
|
|
| {
|
2022-10-11 05:32:44 +00:00
|
|
|
applicationId: string;
|
2022-06-21 13:57:34 +00:00
|
|
|
pageId: string;
|
|
|
|
|
layoutId: string;
|
|
|
|
|
}
|
|
|
|
|
| undefined = yield select(getEditorConfigs) as any;
|
2023-04-07 13:51:35 +00:00
|
|
|
|
|
|
|
|
if (!editorConfigs) return;
|
|
|
|
|
|
2022-06-21 13:57:34 +00:00
|
|
|
const guidedTourEnabled: boolean = yield select(inGuidedTour);
|
2022-10-11 05:32:44 +00:00
|
|
|
const savePageRequest: SavePageRequest = getLayoutSavePayload(
|
|
|
|
|
widgets,
|
|
|
|
|
editorConfigs,
|
|
|
|
|
);
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.startAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.SAVE_PAGE_API,
|
|
|
|
|
{
|
|
|
|
|
pageId: savePageRequest.pageId,
|
|
|
|
|
},
|
|
|
|
|
);
|
2019-09-17 15:09:55 +00:00
|
|
|
try {
|
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
|
|
|
// Store the updated DSL in the pageDSLs reducer
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.FETCH_PAGE_DSL_SUCCESS,
|
|
|
|
|
payload: {
|
|
|
|
|
pageId: savePageRequest.pageId,
|
|
|
|
|
dsl: savePageRequest.dsl,
|
2023-04-07 13:51:35 +00:00
|
|
|
layoutId: savePageRequest.layoutId,
|
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
|
|
|
},
|
|
|
|
|
});
|
2020-11-03 13:05:40 +00:00
|
|
|
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.UPDATE_CANVAS_STRUCTURE,
|
|
|
|
|
payload: savePageRequest.dsl,
|
|
|
|
|
});
|
|
|
|
|
|
2023-04-13 11:44:24 +00:00
|
|
|
/**
|
|
|
|
|
* TODO: Reactivate the capturing or remove this block
|
|
|
|
|
* once the below issue has been fixed. Commenting to avoid
|
|
|
|
|
* Sentry quota to fill up
|
|
|
|
|
* https://github.com/appsmithorg/appsmith/issues/20744
|
|
|
|
|
*/
|
|
|
|
|
// captureInvalidDynamicBindingPath(
|
|
|
|
|
// CanvasWidgetsNormalizer.denormalize("0", {
|
|
|
|
|
// canvasWidgets: widgets,
|
|
|
|
|
// }),
|
|
|
|
|
// );
|
2022-02-03 05:52:14 +00:00
|
|
|
|
2019-09-17 15:09:55 +00:00
|
|
|
const savePageResponse: SavePageResponse = yield call(
|
|
|
|
|
PageApi.savePage,
|
|
|
|
|
savePageRequest,
|
|
|
|
|
);
|
2021-07-29 08:13:10 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(savePageResponse);
|
2019-09-27 16:05:33 +00:00
|
|
|
if (isValidResponse) {
|
2021-05-13 08:35:39 +00:00
|
|
|
const { actionUpdates, messages } = savePageResponse.data;
|
2022-01-25 13:56:52 +00:00
|
|
|
// We do not want to show these toasts in guided tour
|
2021-02-15 16:13:44 +00:00
|
|
|
// Show toast messages from the server
|
2022-01-25 13:56:52 +00:00
|
|
|
if (messages && messages.length && !guidedTourEnabled) {
|
2021-02-15 16:13:44 +00:00
|
|
|
savePageResponse.data.messages.forEach((message) => {
|
2023-05-19 18:37:06 +00:00
|
|
|
toast.show(message, {
|
|
|
|
|
kind: "info",
|
2021-02-15 16:13:44 +00:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
// Update actions
|
|
|
|
|
if (actionUpdates && actionUpdates.length > 0) {
|
2022-03-17 12:05:17 +00:00
|
|
|
const actions = actionUpdates.filter(
|
|
|
|
|
(d) => !d.hasOwnProperty("collectionId"),
|
|
|
|
|
);
|
|
|
|
|
if (actions && actions.length) {
|
|
|
|
|
yield put(setActionsToExecuteOnPageLoad(actions));
|
|
|
|
|
}
|
|
|
|
|
const jsActions = actionUpdates.filter((d) =>
|
|
|
|
|
d.hasOwnProperty("collectionId"),
|
|
|
|
|
);
|
|
|
|
|
if (jsActions && jsActions.length) {
|
|
|
|
|
yield put(setJSActionsToExecuteOnPageLoad(jsActions));
|
|
|
|
|
}
|
2020-08-27 15:39:16 +00:00
|
|
|
}
|
2021-07-07 12:47:01 +00:00
|
|
|
yield put(setLastUpdatedTime(Date.now() / 1000));
|
2019-09-27 16:05:33 +00:00
|
|
|
yield put(savePageSuccess(savePageResponse));
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.SAVE_PAGE_API,
|
|
|
|
|
);
|
2022-09-24 10:01:52 +00:00
|
|
|
checkAndLogErrorsIfCyclicDependency(
|
|
|
|
|
(savePageResponse.data as SavePageResponseData)
|
|
|
|
|
.layoutOnLoadActionErrors,
|
|
|
|
|
);
|
2019-09-27 16:05:33 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2020-09-28 05:12:23 +00:00
|
|
|
PerformanceTracker.stopAsyncTracking(
|
|
|
|
|
PerformanceTransactionName.SAVE_PAGE_API,
|
|
|
|
|
{
|
|
|
|
|
failed: true,
|
|
|
|
|
},
|
|
|
|
|
);
|
2021-01-11 05:28:10 +00:00
|
|
|
|
2023-05-22 04:11:00 +00:00
|
|
|
if (error instanceof UserCancelledActionExecutionError) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-27 16:05:33 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.SAVE_PAGE_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
2020-10-15 15:28:54 +00:00
|
|
|
show: false,
|
2019-09-27 16:05:33 +00:00
|
|
|
},
|
|
|
|
|
});
|
2021-03-04 05:24:47 +00:00
|
|
|
|
|
|
|
|
if (error instanceof IncorrectBindingError) {
|
2021-06-07 14:33:20 +00:00
|
|
|
const { isRetry } = action?.payload;
|
2021-03-04 05:24:47 +00:00
|
|
|
const incorrectBindingError = JSON.parse(error.message);
|
2021-03-19 06:09:35 +00:00
|
|
|
const { message } = incorrectBindingError;
|
2021-03-04 05:24:47 +00:00
|
|
|
if (isRetry) {
|
|
|
|
|
Sentry.captureException(new Error("Failed to correct binding paths"));
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.FAILED_CORRECTING_BINDING_PATHS,
|
|
|
|
|
payload: {
|
|
|
|
|
error: {
|
|
|
|
|
message,
|
|
|
|
|
code: ERROR_CODES.FAILED_TO_CORRECT_BINDING,
|
|
|
|
|
crash: true,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} else {
|
2021-03-19 06:09:35 +00:00
|
|
|
// Create a denormalized structure because the migration needs the children in the dsl form
|
|
|
|
|
const denormalizedWidgets = CanvasWidgetsNormalizer.denormalize("0", {
|
|
|
|
|
canvasWidgets: widgets,
|
|
|
|
|
});
|
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
|
|
|
const correctedWidgets =
|
|
|
|
|
migrateIncorrectDynamicBindingPathLists(denormalizedWidgets);
|
2021-03-19 06:09:35 +00:00
|
|
|
// Normalize the widgets because the save page needs it in the flat structure
|
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
|
|
|
const normalizedWidgets =
|
|
|
|
|
CanvasWidgetsNormalizer.normalize(correctedWidgets);
|
2021-03-08 10:28:20 +00:00
|
|
|
AnalyticsUtil.logEvent("CORRECT_BAD_BINDING", {
|
2021-03-16 05:31:48 +00:00
|
|
|
error: error.message,
|
2021-03-19 06:09:35 +00:00
|
|
|
correctWidget: JSON.stringify(normalizedWidgets),
|
2021-03-08 10:28:20 +00:00
|
|
|
});
|
2021-03-04 05:24:47 +00:00
|
|
|
yield put(
|
2022-08-19 10:10:36 +00:00
|
|
|
updateAndSaveLayout(normalizedWidgets.entities.canvasWidgets, {
|
|
|
|
|
isRetry: true,
|
|
|
|
|
}),
|
2021-03-04 05:24:47 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-09-17 15:09:55 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-07 13:51:35 +00:00
|
|
|
export function* saveAllPagesSaga(pageLayouts: PageLayoutsRequest[]) {
|
|
|
|
|
let response: ApiResponse | undefined;
|
|
|
|
|
try {
|
|
|
|
|
const applicationId: string = yield select(getCurrentApplicationId);
|
|
|
|
|
response = yield PageApi.saveAllPages(applicationId, pageLayouts);
|
|
|
|
|
|
|
|
|
|
const isValidResponse: boolean = yield validateResponse(response, false);
|
|
|
|
|
|
|
|
|
|
if (isValidResponse) {
|
|
|
|
|
return true;
|
2023-05-07 05:10:03 +00:00
|
|
|
} else {
|
|
|
|
|
throw new Error(`Error while Saving all pages, ${response?.data}`);
|
2023-04-07 13:51:35 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Property Pane Controls
- Fixes #121, #122, #123, #124, #90, #46, #65, #100, #101, #68, #102
2019-10-24 05:24:45 +00:00
|
|
|
function getLayoutSavePayload(
|
|
|
|
|
widgets: {
|
|
|
|
|
[widgetId: string]: FlattenedWidgetProps;
|
|
|
|
|
},
|
|
|
|
|
editorConfigs: any,
|
|
|
|
|
) {
|
|
|
|
|
const denormalizedDSL = CanvasWidgetsNormalizer.denormalize(
|
|
|
|
|
Object.keys(widgets)[0],
|
|
|
|
|
{ canvasWidgets: widgets },
|
|
|
|
|
);
|
|
|
|
|
return {
|
|
|
|
|
...editorConfigs,
|
|
|
|
|
dsl: denormalizedDSL,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-04 05:24:47 +00:00
|
|
|
export function* saveLayoutSaga(action: ReduxAction<{ isRetry?: boolean }>) {
|
2019-09-19 22:25:37 +00:00
|
|
|
try {
|
2022-12-01 06:30:50 +00:00
|
|
|
const currentPageId: string = yield select(getCurrentPageId);
|
|
|
|
|
const currentPage: Page = yield select(getPageById(currentPageId));
|
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
|
|
|
const isPreviewMode: boolean = yield select(previewModeSelector);
|
2022-12-01 06:30:50 +00:00
|
|
|
|
2022-12-24 10:23:34 +00:00
|
|
|
const appMode: APP_MODE | undefined = yield select(getAppMode);
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
!hasManagePagePermission(currentPage?.userPermissions || []) &&
|
|
|
|
|
appMode === APP_MODE.EDIT
|
|
|
|
|
) {
|
2022-12-01 06:30:50 +00:00
|
|
|
yield validateResponse({
|
|
|
|
|
status: 403,
|
|
|
|
|
resourceType: "Page",
|
|
|
|
|
resourceId: currentPage.pageId,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
if (appMode === APP_MODE.EDIT && !isPreviewMode) {
|
2021-07-14 16:30:10 +00:00
|
|
|
yield put(saveLayout(action.payload.isRetry));
|
|
|
|
|
}
|
2019-11-07 04:59:40 +00:00
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.SAVE_PAGE_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
2019-09-19 22:25:37 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-07 13:51:35 +00:00
|
|
|
export function* createNewPageFromEntity(
|
|
|
|
|
createPageAction: ReduxAction<CreatePageActionPayload>,
|
|
|
|
|
) {
|
|
|
|
|
try {
|
|
|
|
|
const isAutoLayout: boolean = yield select(getIsAutoLayout);
|
|
|
|
|
const mainCanvasProps: MainCanvasReduxState = yield select(
|
|
|
|
|
getMainCanvasProps,
|
|
|
|
|
);
|
|
|
|
|
// Default layout is extracted by adding dynamically computed properties like min-height.
|
|
|
|
|
const defaultPageLayouts = [
|
|
|
|
|
{
|
|
|
|
|
dsl: extractCurrentDSL(undefined, isAutoLayout, mainCanvasProps?.width)
|
|
|
|
|
.dsl,
|
|
|
|
|
layoutOnLoadActions: [],
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const { applicationId, blockNavigation, name } =
|
|
|
|
|
createPageAction?.payload || {};
|
|
|
|
|
|
2023-05-29 12:35:38 +00:00
|
|
|
const workspaceId: string = yield select(getCurrentWorkspaceId);
|
|
|
|
|
const instanceId: string | undefined = yield select(getInstanceId);
|
|
|
|
|
|
2023-04-07 13:51:35 +00:00
|
|
|
yield put(
|
2023-05-29 12:35:38 +00:00
|
|
|
createPage(
|
|
|
|
|
applicationId,
|
|
|
|
|
name,
|
|
|
|
|
defaultPageLayouts,
|
|
|
|
|
workspaceId,
|
|
|
|
|
blockNavigation,
|
|
|
|
|
instanceId,
|
|
|
|
|
),
|
2023-04-07 13:51:35 +00:00
|
|
|
);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.CREATE_PAGE_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-10-31 08:36:04 +00:00
|
|
|
export function* createPageSaga(
|
2021-08-13 11:38:26 +00:00
|
|
|
createPageAction: ReduxAction<CreatePageActionPayload>,
|
2019-10-31 08:36:04 +00:00
|
|
|
) {
|
|
|
|
|
try {
|
2022-06-21 13:57:34 +00:00
|
|
|
const guidedTourEnabled: boolean = yield select(inGuidedTour);
|
2023-04-07 13:51:35 +00:00
|
|
|
const isAutoLayout: boolean = yield select(getIsAutoLayout);
|
|
|
|
|
const mainCanvasProps: MainCanvasReduxState = yield select(
|
|
|
|
|
getMainCanvasProps,
|
|
|
|
|
);
|
|
|
|
|
|
2022-01-25 13:56:52 +00:00
|
|
|
// Prevent user from creating a new page during the guided tour
|
|
|
|
|
if (guidedTourEnabled) {
|
|
|
|
|
yield put(toggleShowDeviationDialog(true));
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-10-31 08:36:04 +00:00
|
|
|
const request: CreatePageRequest = createPageAction.payload;
|
|
|
|
|
const response: FetchPageResponse = yield call(PageApi.createPage, request);
|
2021-07-29 08:13:10 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(response);
|
2019-10-31 08:36:04 +00:00
|
|
|
if (isValidResponse) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.CREATE_PAGE_SUCCESS,
|
|
|
|
|
payload: {
|
|
|
|
|
pageId: response.data.id,
|
|
|
|
|
pageName: response.data.name,
|
|
|
|
|
layoutId: response.data.layouts[0].id,
|
2022-03-25 10:43:26 +00:00
|
|
|
slug: response.data.slug,
|
2022-07-11 04:06:29 +00:00
|
|
|
customSlug: response.data.customSlug,
|
2022-12-01 06:30:50 +00:00
|
|
|
userPermissions: response.data.userPermissions,
|
2019-10-31 08:36:04 +00:00
|
|
|
},
|
|
|
|
|
});
|
2020-11-03 13:05:40 +00:00
|
|
|
// Add this to the page DSLs for entity explorer
|
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
|
|
|
yield put({
|
2020-11-03 13:05:40 +00:00
|
|
|
type: ReduxActionTypes.FETCH_PAGE_DSL_SUCCESS,
|
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
|
|
|
payload: {
|
|
|
|
|
pageId: response.data.id,
|
2023-04-07 13:51:35 +00:00
|
|
|
dsl: extractCurrentDSL(response, isAutoLayout, mainCanvasProps?.width)
|
|
|
|
|
.dsl,
|
|
|
|
|
layoutId: response.data.layouts[0].id,
|
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
|
|
|
},
|
|
|
|
|
});
|
2022-07-11 04:06:29 +00:00
|
|
|
// TODO: Update URL params here
|
2021-07-29 08:13:10 +00:00
|
|
|
// route to generate template for new page created
|
2021-08-13 11:38:26 +00:00
|
|
|
if (!createPageAction.payload.blockNavigation) {
|
2022-09-30 13:41:04 +00:00
|
|
|
history.push(
|
|
|
|
|
builderURL({
|
|
|
|
|
pageId: response.data.id,
|
|
|
|
|
}),
|
2022-09-26 08:14:39 +00:00
|
|
|
);
|
2021-08-13 11:38:26 +00:00
|
|
|
}
|
2019-10-31 08:36:04 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.CREATE_PAGE_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-27 08:24:58 +00:00
|
|
|
export function* updatePageSaga(action: ReduxAction<UpdatePageRequest>) {
|
|
|
|
|
try {
|
|
|
|
|
const request: UpdatePageRequest = action.payload;
|
2023-03-30 11:29:52 +00:00
|
|
|
|
2022-12-02 05:49:51 +00:00
|
|
|
// to be done in backend
|
|
|
|
|
request.customSlug = request.customSlug?.replaceAll(" ", "-");
|
|
|
|
|
|
|
|
|
|
const response: ApiResponse<UpdatePageResponse> = yield call(
|
|
|
|
|
PageApi.updatePage,
|
|
|
|
|
request,
|
|
|
|
|
);
|
2021-07-29 08:13:10 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(response);
|
2020-01-27 08:24:58 +00:00
|
|
|
if (isValidResponse) {
|
2022-12-02 05:49:51 +00:00
|
|
|
yield put(updatePageSuccess(response.data));
|
2020-01-27 08:24:58 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
2022-12-02 05:49:51 +00:00
|
|
|
yield put(
|
|
|
|
|
updatePageError({
|
|
|
|
|
request: action.payload,
|
2020-01-27 08:24:58 +00:00
|
|
|
error,
|
2022-12-02 05:49:51 +00:00
|
|
|
}),
|
|
|
|
|
);
|
2020-01-27 08:24:58 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* deletePageSaga(action: ReduxAction<DeletePageRequest>) {
|
|
|
|
|
try {
|
|
|
|
|
const request: DeletePageRequest = action.payload;
|
2022-03-25 10:43:26 +00:00
|
|
|
const defaultPageId: string = yield select(
|
2020-02-21 07:19:10 +00:00
|
|
|
(state: AppState) => state.entities.pageList.defaultPageId,
|
|
|
|
|
);
|
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
|
|
|
if (defaultPageId === request.id) {
|
2020-02-21 07:19:10 +00:00
|
|
|
throw Error("Cannot delete the home page.");
|
|
|
|
|
} else {
|
|
|
|
|
const response: ApiResponse = yield call(PageApi.deletePage, request);
|
2021-07-29 08:13:10 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(response);
|
2020-02-21 07:19:10 +00:00
|
|
|
if (isValidResponse) {
|
|
|
|
|
yield put(deletePageSuccess());
|
|
|
|
|
}
|
2020-11-03 13:05:40 +00:00
|
|
|
// Remove this page from page DSLs
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.FETCH_PAGE_DSL_SUCCESS,
|
|
|
|
|
payload: {
|
|
|
|
|
pageId: request.id,
|
|
|
|
|
dsl: undefined,
|
|
|
|
|
},
|
|
|
|
|
});
|
2022-07-11 04:06:29 +00:00
|
|
|
// Update route params here
|
2022-03-25 10:43:26 +00:00
|
|
|
const currentPageId: string = yield select(
|
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
|
|
|
(state: AppState) => state.entities.pageList.currentPageId,
|
|
|
|
|
);
|
|
|
|
|
if (currentPageId === action.payload.id)
|
2021-10-18 14:03:44 +00:00
|
|
|
history.push(
|
2022-03-25 10:43:26 +00:00
|
|
|
builderURL({
|
2021-10-18 14:03:44 +00:00
|
|
|
pageId: defaultPageId,
|
|
|
|
|
}),
|
|
|
|
|
);
|
2020-01-27 08:24:58 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.DELETE_PAGE_ERROR,
|
|
|
|
|
payload: {
|
2022-06-21 13:57:34 +00:00
|
|
|
error: { message: (error as Error).message, show: true },
|
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
|
|
|
show: true,
|
2020-01-27 08:24:58 +00:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-13 11:38:26 +00:00
|
|
|
export function* clonePageSaga(
|
|
|
|
|
clonePageAction: ReduxAction<ClonePageActionPayload>,
|
|
|
|
|
) {
|
2020-08-22 03:10:22 +00:00
|
|
|
try {
|
|
|
|
|
const request: ClonePageRequest = clonePageAction.payload;
|
|
|
|
|
const response: FetchPageResponse = yield call(PageApi.clonePage, request);
|
2021-07-29 08:13:10 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(response);
|
2020-08-22 03:10:22 +00:00
|
|
|
if (isValidResponse) {
|
|
|
|
|
yield put(
|
|
|
|
|
clonePageSuccess(
|
|
|
|
|
response.data.id,
|
|
|
|
|
response.data.name,
|
|
|
|
|
response.data.layouts[0].id,
|
2022-07-11 04:06:29 +00:00
|
|
|
response.data.slug,
|
2020-08-22 03:10:22 +00:00
|
|
|
),
|
|
|
|
|
);
|
2020-11-03 13:05:40 +00:00
|
|
|
// Add this to the page DSLs for entity explorer
|
2023-04-07 13:51:35 +00:00
|
|
|
const { dsl, layoutId } = extractCurrentDSL(response);
|
2020-08-22 03:10:22 +00:00
|
|
|
yield put({
|
2020-11-03 13:05:40 +00:00
|
|
|
type: ReduxActionTypes.FETCH_PAGE_DSL_SUCCESS,
|
2020-08-22 03:10:22 +00:00
|
|
|
payload: {
|
|
|
|
|
pageId: response.data.id,
|
2023-04-07 13:51:35 +00:00
|
|
|
dsl,
|
|
|
|
|
layoutId,
|
2020-08-22 03:10:22 +00:00
|
|
|
},
|
|
|
|
|
});
|
2020-11-03 13:05:40 +00:00
|
|
|
|
2023-02-28 18:28:20 +00:00
|
|
|
const triggersAfterPageFetch = [
|
|
|
|
|
fetchActionsForPage(response.data.id),
|
|
|
|
|
fetchJSCollectionsForPage(response.data.id),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const afterActionsFetch: unknown = yield failFastApiCalls(
|
|
|
|
|
triggersAfterPageFetch,
|
|
|
|
|
[
|
|
|
|
|
fetchActionsForPageSuccess([]).type,
|
|
|
|
|
fetchJSCollectionsForPageSuccess([]).type,
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
fetchActionsForPageError().type,
|
|
|
|
|
fetchJSCollectionsForPageError().type,
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (!afterActionsFetch) {
|
|
|
|
|
throw new Error("Failed cloning page");
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-28 02:17:06 +00:00
|
|
|
yield put(selectWidgetInitAction(SelectionRequestType.Empty));
|
2023-02-28 18:28:20 +00:00
|
|
|
yield put(fetchAllPageEntityCompletion([executePageLoadActions()]));
|
2020-12-16 09:21:31 +00:00
|
|
|
|
2022-07-11 04:06:29 +00:00
|
|
|
// TODO: Update URL params here.
|
|
|
|
|
|
2021-08-13 11:38:26 +00:00
|
|
|
if (!clonePageAction.payload.blockNavigation) {
|
2021-10-18 14:03:44 +00:00
|
|
|
history.push(
|
2022-03-25 10:43:26 +00:00
|
|
|
builderURL({
|
2021-10-18 14:03:44 +00:00
|
|
|
pageId: response.data.id,
|
|
|
|
|
}),
|
|
|
|
|
);
|
2021-08-13 11:38:26 +00:00
|
|
|
}
|
2020-08-22 03:10:22 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.CLONE_PAGE_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-23 09:27:00 +00:00
|
|
|
/**
|
|
|
|
|
* this saga do two things
|
|
|
|
|
*
|
|
|
|
|
* 1. Checks if the name of page is conflicting with any used name
|
|
|
|
|
* 2. dispatches a action which triggers a request to update the name
|
|
|
|
|
*
|
|
|
|
|
* @param action
|
|
|
|
|
*/
|
2020-02-21 12:16:49 +00:00
|
|
|
export function* updateWidgetNameSaga(
|
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
|
|
|
action: ReduxAction<{ id: string; newName: string }>,
|
2020-02-21 12:16:49 +00:00
|
|
|
) {
|
|
|
|
|
try {
|
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 { widgetName } = yield select(getWidgetName, action.payload.id);
|
2022-06-21 13:57:34 +00:00
|
|
|
const layoutId: string | undefined = yield select(getCurrentLayoutId);
|
|
|
|
|
const pageId: string | undefined = yield select(getCurrentPageId);
|
2022-12-21 17:14:47 +00:00
|
|
|
const getUsedNames: Record<string, true> = yield select(
|
|
|
|
|
getUsedActionNames,
|
|
|
|
|
"",
|
2022-06-21 13:57:34 +00:00
|
|
|
);
|
2020-11-23 09:27:00 +00:00
|
|
|
|
2021-02-01 13:17:55 +00:00
|
|
|
// TODO(abhinav): Why do we need to jump through these hoops just to
|
|
|
|
|
// change the tab name? Figure out a better design to make this moot.
|
2021-04-27 07:16:54 +00:00
|
|
|
const tabsObj: Record<
|
|
|
|
|
string,
|
|
|
|
|
{
|
|
|
|
|
id: string;
|
|
|
|
|
widgetId: string;
|
|
|
|
|
label: string;
|
|
|
|
|
}
|
|
|
|
|
> = yield select((state: AppState) => {
|
2021-02-01 13:17:55 +00:00
|
|
|
// Check if this widget exists in the canvas widgets
|
|
|
|
|
if (state.entities.canvasWidgets.hasOwnProperty(action.payload.id)) {
|
|
|
|
|
// If it does assign it to a variable
|
|
|
|
|
const widget = state.entities.canvasWidgets[action.payload.id];
|
|
|
|
|
// Check if this widget has a parent in the canvas widgets
|
|
|
|
|
if (
|
|
|
|
|
widget.parentId &&
|
|
|
|
|
state.entities.canvasWidgets.hasOwnProperty(widget.parentId)
|
|
|
|
|
) {
|
|
|
|
|
// If the parent exists assign it to a variable
|
|
|
|
|
const parent = state.entities.canvasWidgets[widget.parentId];
|
|
|
|
|
// Check if this parent is a TABS_WIDGET
|
|
|
|
|
if (parent.type === WidgetTypes.TABS_WIDGET) {
|
|
|
|
|
// If it is return the tabs property
|
2021-04-27 07:16:54 +00:00
|
|
|
return parent.tabsObj;
|
2021-02-01 13:17:55 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// This isn't a tab in a tabs widget so return undefined
|
|
|
|
|
return;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// If we're trying to update the name of a tab in the TABS_WIDGET
|
2021-04-27 07:16:54 +00:00
|
|
|
if (tabsObj !== undefined) {
|
|
|
|
|
const tabs: any = Object.values(tabsObj);
|
2021-02-01 13:17:55 +00:00
|
|
|
// Get all canvas widgets
|
2022-06-21 13:57:34 +00:00
|
|
|
const stateWidgets: CanvasWidgetsReduxState = yield select(getWidgets);
|
2021-02-01 13:17:55 +00:00
|
|
|
// Shallow copy canvas widgets as they're immutable
|
|
|
|
|
const widgets = { ...stateWidgets };
|
|
|
|
|
// Get the parent Id of the tab (canvas widget) whose name we're updating
|
|
|
|
|
const parentId = widgets[action.payload.id].parentId;
|
|
|
|
|
// Update the tabName property of the tab (canvas widget)
|
|
|
|
|
widgets[action.payload.id] = {
|
|
|
|
|
...widgets[action.payload.id],
|
|
|
|
|
tabName: action.payload.newName,
|
2020-02-21 12:16:49 +00:00
|
|
|
};
|
2021-02-01 13:17:55 +00:00
|
|
|
// Shallow copy the parent widget so that we can update the properties
|
2022-06-21 13:57:34 +00:00
|
|
|
// @ts-expect-error parentId can be undefined
|
2021-02-01 13:17:55 +00:00
|
|
|
const parent = { ...widgets[parentId] };
|
|
|
|
|
// Update the tabs property of the parent tabs widget
|
2021-04-27 07:16:54 +00:00
|
|
|
const tabToChange = tabs.find(
|
|
|
|
|
(each: any) => each.widgetId === action.payload.id,
|
2020-02-21 12:16:49 +00:00
|
|
|
);
|
2021-04-27 07:16:54 +00:00
|
|
|
const updatedTab = {
|
|
|
|
|
...tabToChange,
|
|
|
|
|
label: action.payload.newName,
|
|
|
|
|
};
|
|
|
|
|
parent.tabsObj = {
|
|
|
|
|
...parent.tabsObj,
|
|
|
|
|
[updatedTab.id]: {
|
|
|
|
|
...updatedTab,
|
|
|
|
|
},
|
|
|
|
|
};
|
2021-02-01 13:17:55 +00:00
|
|
|
// replace the parent widget in the canvas widgets
|
2022-06-21 13:57:34 +00:00
|
|
|
// @ts-expect-error parentId can be undefined
|
2021-02-01 13:17:55 +00:00
|
|
|
widgets[parentId] = parent;
|
|
|
|
|
// Update and save the new widgets
|
2022-08-19 10:10:36 +00:00
|
|
|
//TODO Identify the updated widgets and pass the values
|
2021-02-01 13:17:55 +00:00
|
|
|
yield put(updateAndSaveLayout(widgets));
|
|
|
|
|
// Send a update saying that we've successfully updated the name
|
|
|
|
|
yield put(updateWidgetNameSuccess());
|
|
|
|
|
} else {
|
|
|
|
|
// check if name is not conflicting with any
|
|
|
|
|
// existing entity/api/queries/reserved words
|
2022-12-21 17:14:47 +00:00
|
|
|
if (isNameValid(action.payload.newName, getUsedNames)) {
|
2021-02-01 13:17:55 +00:00
|
|
|
const request: UpdateWidgetNameRequest = {
|
|
|
|
|
newName: action.payload.newName,
|
|
|
|
|
oldName: widgetName,
|
2022-06-21 13:57:34 +00:00
|
|
|
// @ts-expect-error: pageId can be undefined
|
2021-02-01 13:17:55 +00:00
|
|
|
pageId,
|
2022-06-21 13:57:34 +00:00
|
|
|
// @ts-expect-error: layoutId can be undefined
|
2021-02-01 13:17:55 +00:00
|
|
|
layoutId,
|
|
|
|
|
};
|
|
|
|
|
const response: UpdateWidgetNameResponse = yield call(
|
|
|
|
|
PageApi.updateWidgetName,
|
|
|
|
|
request,
|
|
|
|
|
);
|
2021-07-29 08:13:10 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(response);
|
2021-02-01 13:17:55 +00:00
|
|
|
if (isValidResponse) {
|
2022-06-21 13:57:34 +00:00
|
|
|
// @ts-expect-error: pageId can be undefined
|
2021-02-01 13:17:55 +00:00
|
|
|
yield updateCanvasWithDSL(response.data, pageId, layoutId);
|
|
|
|
|
yield put(updateWidgetNameSuccess());
|
|
|
|
|
// Add this to the page DSLs for entity explorer
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.FETCH_PAGE_DSL_SUCCESS,
|
|
|
|
|
payload: {
|
|
|
|
|
pageId: pageId,
|
|
|
|
|
dsl: response.data.dsl,
|
2023-04-07 13:51:35 +00:00
|
|
|
layoutId,
|
2021-02-01 13:17:55 +00:00
|
|
|
},
|
|
|
|
|
});
|
2022-09-24 10:01:52 +00:00
|
|
|
checkAndLogErrorsIfCyclicDependency(
|
|
|
|
|
(response.data as PageLayout).layoutOnLoadActionErrors,
|
|
|
|
|
);
|
2021-02-01 13:17:55 +00:00
|
|
|
}
|
|
|
|
|
} else {
|
2020-08-31 05:56:52 +00:00
|
|
|
yield put({
|
2021-02-01 13:17:55 +00:00
|
|
|
type: ReduxActionErrorTypes.UPDATE_WIDGET_NAME_ERROR,
|
2020-08-31 05:56:52 +00:00
|
|
|
payload: {
|
2021-02-01 13:17:55 +00:00
|
|
|
error: {
|
2021-11-10 13:59:24 +00:00
|
|
|
message: `Entity name: ${action.payload.newName} is already being used or is a restricted keyword.`,
|
2021-02-01 13:17:55 +00:00
|
|
|
},
|
2020-08-31 05:56:52 +00:00
|
|
|
},
|
|
|
|
|
});
|
2020-02-21 12:16:49 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.UPDATE_WIDGET_NAME_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-16 10:23:19 +00:00
|
|
|
export function* updateCanvasWithDSL(
|
|
|
|
|
data: PageLayout,
|
|
|
|
|
pageId: string,
|
|
|
|
|
layoutId: string,
|
|
|
|
|
) {
|
|
|
|
|
const normalizedWidgets = CanvasWidgetsNormalizer.normalize(data.dsl);
|
2022-06-21 13:57:34 +00:00
|
|
|
const currentPageName: string = yield select(getCurrentPageName);
|
|
|
|
|
|
|
|
|
|
const applicationId: string = yield select(getCurrentApplicationId);
|
2020-06-16 10:23:19 +00:00
|
|
|
const canvasWidgetsPayload: UpdateCanvasPayload = {
|
|
|
|
|
pageWidgetId: normalizedWidgets.result,
|
|
|
|
|
currentPageName,
|
|
|
|
|
currentPageId: pageId,
|
|
|
|
|
currentLayoutId: layoutId,
|
|
|
|
|
currentApplicationId: applicationId,
|
2023-04-07 13:51:35 +00:00
|
|
|
dsl: data.dsl,
|
2020-06-16 10:23:19 +00:00
|
|
|
pageActions: data.layoutOnLoadActions,
|
|
|
|
|
widgets: normalizedWidgets.entities.canvasWidgets,
|
|
|
|
|
};
|
2021-01-25 08:57:26 +00:00
|
|
|
yield put(initCanvasLayout(canvasWidgetsPayload));
|
2021-09-21 06:02:30 +00:00
|
|
|
yield put(fetchActionsForPage(pageId));
|
|
|
|
|
yield put(fetchJSCollectionsForPage(pageId));
|
2020-06-16 10:23:19 +00:00
|
|
|
}
|
|
|
|
|
|
2020-08-07 14:24:26 +00:00
|
|
|
export function* setDataUrl() {
|
|
|
|
|
const urlData: UrlDataState = {
|
2020-08-14 07:43:01 +00:00
|
|
|
fullPath: window.location.href,
|
2020-08-07 14:24:26 +00:00
|
|
|
host: window.location.host,
|
|
|
|
|
hostname: window.location.hostname,
|
|
|
|
|
queryParams: getQueryParams(),
|
|
|
|
|
protocol: window.location.protocol,
|
|
|
|
|
pathname: window.location.pathname,
|
|
|
|
|
port: window.location.port,
|
|
|
|
|
hash: window.location.hash,
|
|
|
|
|
};
|
|
|
|
|
yield put(setUrlData(urlData));
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-23 12:31:33 +00:00
|
|
|
export function* fetchPageDSLSaga(pageId: string) {
|
2020-11-04 11:40:59 +00:00
|
|
|
try {
|
2023-04-07 13:51:35 +00:00
|
|
|
const isAutoLayout: boolean = yield select(getIsAutoLayout);
|
|
|
|
|
const mainCanvasProps: MainCanvasReduxState = yield select(
|
|
|
|
|
getMainCanvasProps,
|
|
|
|
|
);
|
2020-11-04 11:40:59 +00:00
|
|
|
const fetchPageResponse: FetchPageResponse = yield call(PageApi.fetchPage, {
|
|
|
|
|
id: pageId,
|
|
|
|
|
});
|
2021-07-29 08:13:10 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(fetchPageResponse);
|
2020-11-04 11:40:59 +00:00
|
|
|
if (isValidResponse) {
|
2023-04-07 13:51:35 +00:00
|
|
|
const { dsl, layoutId } = extractCurrentDSL(
|
|
|
|
|
fetchPageResponse,
|
|
|
|
|
isAutoLayout,
|
|
|
|
|
mainCanvasProps?.width,
|
|
|
|
|
);
|
2020-11-04 11:40:59 +00:00
|
|
|
return {
|
2023-04-07 13:51:35 +00:00
|
|
|
pageId,
|
|
|
|
|
dsl,
|
|
|
|
|
layoutId,
|
2022-12-01 06:30:50 +00:00
|
|
|
userPermissions: fetchPageResponse.data?.userPermissions,
|
2020-11-04 11:40:59 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
2021-03-09 14:35:42 +00:00
|
|
|
type: ReduxActionErrorTypes.FETCH_PAGE_DSL_ERROR,
|
2020-11-04 11:40:59 +00:00
|
|
|
payload: {
|
|
|
|
|
pageId: pageId,
|
|
|
|
|
error,
|
2021-03-09 14:35:42 +00:00
|
|
|
show: true,
|
2020-11-04 11:40:59 +00:00
|
|
|
},
|
|
|
|
|
});
|
2021-03-09 14:35:42 +00:00
|
|
|
return {
|
|
|
|
|
pageId: pageId,
|
|
|
|
|
dsl: DEFAULT_TEMPLATE,
|
|
|
|
|
};
|
2020-11-04 11:40:59 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function* populatePageDSLsSaga() {
|
|
|
|
|
try {
|
|
|
|
|
const pageIds: string[] = yield select((state: AppState) =>
|
|
|
|
|
state.entities.pageList.pages.map((page: Page) => page.pageId),
|
|
|
|
|
);
|
2022-06-21 13:57:34 +00:00
|
|
|
const pageDSLs: unknown = yield all(
|
2020-11-04 11:40:59 +00:00
|
|
|
pageIds.map((pageId: string) => {
|
|
|
|
|
return call(fetchPageDSLSaga, pageId);
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.FETCH_PAGE_DSLS_SUCCESS,
|
|
|
|
|
payload: pageDSLs,
|
|
|
|
|
});
|
2022-12-01 06:30:50 +00:00
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.UPDATE_PAGE_LIST,
|
|
|
|
|
payload: pageDSLs,
|
|
|
|
|
});
|
2020-11-04 11:40:59 +00:00
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.POPULATE_PAGEDSLS_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-13 11:38:26 +00:00
|
|
|
/**
|
|
|
|
|
* saga to update the page order
|
|
|
|
|
*
|
|
|
|
|
* @param action
|
|
|
|
|
*/
|
|
|
|
|
export function* setPageOrderSaga(action: ReduxAction<SetPageOrderRequest>) {
|
|
|
|
|
try {
|
|
|
|
|
const request: SetPageOrderRequest = action.payload;
|
|
|
|
|
const response: ApiResponse = yield call(PageApi.setPageOrder, request);
|
2022-06-21 13:57:34 +00:00
|
|
|
const isValidResponse: boolean = yield validateResponse(response);
|
2021-08-13 11:38:26 +00:00
|
|
|
if (isValidResponse) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionTypes.SET_PAGE_ORDER_SUCCESS,
|
|
|
|
|
payload: {
|
2022-06-21 13:57:34 +00:00
|
|
|
// @ts-expect-error: response.data is of type unknown
|
2021-08-13 11:38:26 +00:00
|
|
|
pages: response.data.pages,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put({
|
|
|
|
|
type: ReduxActionErrorTypes.SET_PAGE_ORDER_ERROR,
|
|
|
|
|
payload: {
|
|
|
|
|
error,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-29 08:13:10 +00:00
|
|
|
export function* generateTemplatePageSaga(
|
|
|
|
|
action: ReduxAction<GenerateTemplatePageRequest>,
|
|
|
|
|
) {
|
|
|
|
|
try {
|
|
|
|
|
const request: GenerateTemplatePageRequest = action.payload;
|
|
|
|
|
// if pageId is available in request, it will just update that page else it will generate new page.
|
2022-06-21 13:57:34 +00:00
|
|
|
const response: ApiResponse<{
|
2021-08-26 07:23:39 +00:00
|
|
|
page: any;
|
|
|
|
|
successImageUrl: string;
|
|
|
|
|
successMessage: string;
|
|
|
|
|
}> = yield call(PageApi.generateTemplatePage, request);
|
2021-07-29 08:13:10 +00:00
|
|
|
|
|
|
|
|
const isValidResponse: boolean = yield validateResponse(response);
|
|
|
|
|
if (isValidResponse) {
|
2021-08-26 07:23:39 +00:00
|
|
|
const pageId = response.data.page.id;
|
2022-06-06 03:56:14 +00:00
|
|
|
|
|
|
|
|
yield put(
|
|
|
|
|
generateTemplateSuccess({
|
|
|
|
|
page: response.data.page,
|
|
|
|
|
isNewPage: !request.pageId,
|
|
|
|
|
// if pageId if not defined, that means a new page is generated.
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
|
2021-07-29 08:13:10 +00:00
|
|
|
yield handleFetchedPage({
|
2021-08-26 07:23:39 +00:00
|
|
|
fetchPageResponse: {
|
|
|
|
|
data: response.data.page,
|
|
|
|
|
responseMeta: response.responseMeta,
|
|
|
|
|
},
|
2021-07-29 08:13:10 +00:00
|
|
|
pageId,
|
2022-04-27 18:28:52 +00:00
|
|
|
isFirstLoad: true,
|
2021-07-29 08:13:10 +00:00
|
|
|
});
|
2021-08-26 07:23:39 +00:00
|
|
|
|
2022-12-27 20:38:04 +00:00
|
|
|
yield put(fetchPage(pageId));
|
|
|
|
|
|
2022-06-06 03:56:14 +00:00
|
|
|
// trigger evaluation after completion of page success & fetch actions for page + fetch jsobject for page
|
|
|
|
|
|
|
|
|
|
const triggersAfterPageFetch = [
|
|
|
|
|
fetchActionsForPage(pageId),
|
|
|
|
|
fetchJSCollectionsForPage(pageId),
|
|
|
|
|
];
|
|
|
|
|
|
2022-06-21 13:57:34 +00:00
|
|
|
const afterActionsFetch: unknown = yield failFastApiCalls(
|
2022-06-06 03:56:14 +00:00
|
|
|
triggersAfterPageFetch,
|
|
|
|
|
[
|
|
|
|
|
fetchActionsForPageSuccess([]).type,
|
|
|
|
|
fetchJSCollectionsForPageSuccess([]).type,
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
fetchActionsForPageError().type,
|
|
|
|
|
fetchJSCollectionsForPageError().type,
|
|
|
|
|
],
|
2021-07-29 08:13:10 +00:00
|
|
|
);
|
2022-06-06 03:56:14 +00:00
|
|
|
|
|
|
|
|
if (!afterActionsFetch) {
|
|
|
|
|
throw new Error("Failed generating template");
|
|
|
|
|
}
|
|
|
|
|
yield put(fetchAllPageEntityCompletion([executePageLoadActions()]));
|
|
|
|
|
|
2021-10-18 14:03:44 +00:00
|
|
|
history.replace(
|
2022-03-25 10:43:26 +00:00
|
|
|
builderURL({
|
2021-10-18 14:03:44 +00:00
|
|
|
pageId,
|
|
|
|
|
}),
|
|
|
|
|
);
|
2021-07-29 08:13:10 +00:00
|
|
|
// TODO : Add it to onSuccessCallback
|
2023-05-19 18:37:06 +00:00
|
|
|
toast.show("Successfully generated a page", {
|
|
|
|
|
kind: "success",
|
2021-07-29 08:13:10 +00:00
|
|
|
});
|
2021-08-16 18:04:54 +00:00
|
|
|
|
2021-08-26 07:23:39 +00:00
|
|
|
yield put(
|
|
|
|
|
setCrudInfoModalData({
|
|
|
|
|
open: true,
|
|
|
|
|
generateCRUDSuccessInfo: {
|
|
|
|
|
successImageUrl: response.data.successImageUrl,
|
|
|
|
|
successMessage: response.data.successMessage,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
);
|
2021-07-29 08:13:10 +00:00
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
yield put(generateTemplateError());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-02 09:09:59 +00:00
|
|
|
function* deleteCanvasCardsStateSaga() {
|
|
|
|
|
const currentPageId: string = yield select(getCurrentPageId);
|
|
|
|
|
const state = JSON.parse(
|
|
|
|
|
localStorage.getItem(LOCAL_STORAGE_KEYS.CANVAS_CARDS_STATE) ?? "{}",
|
|
|
|
|
);
|
|
|
|
|
delete state[currentPageId];
|
|
|
|
|
localStorage.setItem(
|
|
|
|
|
LOCAL_STORAGE_KEYS.CANVAS_CARDS_STATE,
|
|
|
|
|
JSON.stringify(state),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function* setCanvasCardsStateSaga(action: ReduxAction<string>) {
|
|
|
|
|
const state = localStorage.getItem(LOCAL_STORAGE_KEYS.CANVAS_CARDS_STATE);
|
|
|
|
|
const stateObject = JSON.parse(state ?? "{}");
|
|
|
|
|
stateObject[action.payload] = true;
|
|
|
|
|
localStorage.setItem(
|
|
|
|
|
LOCAL_STORAGE_KEYS.CANVAS_CARDS_STATE,
|
|
|
|
|
JSON.stringify(stateObject),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-09 14:22:23 +00:00
|
|
|
function* setPreviewModeInitSaga(action: ReduxAction<boolean>) {
|
|
|
|
|
const currentPageId: string = yield select(getCurrentPageId);
|
|
|
|
|
if (action.payload) {
|
|
|
|
|
// we animate out elements and then move to the canvas
|
|
|
|
|
yield put(setPreviewModeAction(action.payload));
|
|
|
|
|
history.push(
|
|
|
|
|
builderURL({
|
|
|
|
|
pageId: currentPageId,
|
|
|
|
|
}),
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
// when switching back to edit mode
|
|
|
|
|
// we go back to the previous route e.g query, api etc.
|
|
|
|
|
history.goBack();
|
|
|
|
|
// small delay to wait for the content to render and then animate
|
|
|
|
|
yield delay(10);
|
|
|
|
|
yield put(setPreviewModeAction(action.payload));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-17 15:09:55 +00:00
|
|
|
export default function* pageSagas() {
|
|
|
|
|
yield all([
|
2019-11-22 14:02:55 +00:00
|
|
|
takeLatest(ReduxActionTypes.FETCH_PAGE_INIT, fetchPageSaga),
|
2019-10-24 07:03:59 +00:00
|
|
|
takeLatest(
|
|
|
|
|
ReduxActionTypes.FETCH_PUBLISHED_PAGE_INIT,
|
|
|
|
|
fetchPublishedPageSaga,
|
|
|
|
|
),
|
2020-04-13 14:00:50 +00:00
|
|
|
takeLatest(ReduxActionTypes.UPDATE_LAYOUT, saveLayoutSaga),
|
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
|
|
|
takeLeading(ReduxActionTypes.CREATE_PAGE_INIT, createPageSaga),
|
2023-04-07 13:51:35 +00:00
|
|
|
takeLeading(
|
|
|
|
|
ReduxActionTypes.CREATE_NEW_PAGE_FROM_ENTITIES,
|
|
|
|
|
createNewPageFromEntity,
|
|
|
|
|
),
|
2020-08-22 03:10:22 +00:00
|
|
|
takeLeading(ReduxActionTypes.CLONE_PAGE_INIT, clonePageSaga),
|
2020-01-27 08:24:58 +00:00
|
|
|
takeLatest(ReduxActionTypes.UPDATE_PAGE_INIT, updatePageSaga),
|
|
|
|
|
takeLatest(ReduxActionTypes.DELETE_PAGE_INIT, deletePageSaga),
|
2020-01-31 10:46:43 +00:00
|
|
|
debounce(500, ReduxActionTypes.SAVE_PAGE_INIT, savePageSaga),
|
2020-02-21 12:16:49 +00:00
|
|
|
takeLatest(ReduxActionTypes.UPDATE_WIDGET_NAME_INIT, updateWidgetNameSaga),
|
2020-05-05 12:16:51 +00:00
|
|
|
takeLatest(
|
|
|
|
|
ReduxActionTypes.FETCH_ALL_PUBLISHED_PAGES,
|
|
|
|
|
fetchAllPublishedPagesSaga,
|
|
|
|
|
),
|
2021-07-29 08:13:10 +00:00
|
|
|
takeLatest(
|
|
|
|
|
ReduxActionTypes.GENERATE_TEMPLATE_PAGE_INIT,
|
|
|
|
|
generateTemplatePageSaga,
|
|
|
|
|
),
|
2021-08-13 11:38:26 +00:00
|
|
|
takeLatest(ReduxActionTypes.SET_PAGE_ORDER_INIT, setPageOrderSaga),
|
2022-07-11 04:06:29 +00:00
|
|
|
takeLatest(ReduxActionTypes.POPULATE_PAGEDSLS_INIT, populatePageDSLsSaga),
|
2022-11-02 09:09:59 +00:00
|
|
|
takeEvery(ReduxActionTypes.SET_CANVAS_CARDS_STATE, setCanvasCardsStateSaga),
|
|
|
|
|
takeEvery(
|
|
|
|
|
ReduxActionTypes.DELETE_CANVAS_CARDS_STATE,
|
|
|
|
|
deleteCanvasCardsStateSaga,
|
|
|
|
|
),
|
2023-01-09 14:22:23 +00:00
|
|
|
takeEvery(ReduxActionTypes.SET_PREVIEW_MODE_INIT, setPreviewModeInitSaga),
|
2023-04-07 13:51:35 +00:00
|
|
|
takeLatest(ReduxActionTypes.REFRESH_THE_APP, refreshTheApp),
|
2019-09-17 15:09:55 +00:00
|
|
|
]);
|
2019-03-30 12:30:42 +00:00
|
|
|
}
|