Skip to content
This repository has been archived by the owner on Jun 1, 2024. It is now read-only.

Feature/navigation controllers #251

Merged
merged 37 commits into from
Sep 18, 2020
Merged

Conversation

Tiagoperes
Copy link
Contributor

@Tiagoperes Tiagoperes commented Sep 16, 2020

What I did

Closes #248

Issue summary:

We need to comply with the definition of NavigationController, which can be changed via the NavigationActions.

The NavigationController is the set of options responsible for the user feedback regarding the requests to navigate between views. In Beagle Web, they are:

  • errorComponent
  • loadingComponent
  • shouldShowError
  • shouldShowLoading

A NavigationController should be attached to a navigation stack and it can be changed via the actions: beagle:pushStack, beagle:resetStack and beagle:resetApplication. An important point is that the navigationController to use is the controller corresponding to the current stack. So, we can't change the navigation history before we make the request to the new view, the navigation history can only be changed after successfully rendering the new view.

In order to implement this, I had to do the following:

  • Added a new configuration to the BeagleService: navigationControllers.
  • Refactored the navigator:
    • Altered the data structure, so a stack includes a controllerId.
    • All navigations are async now and they resolve only after the new view is fully rendered.
    • The navigation accepts subscriptions, which are async functions to be executed just before the navigation history is altered. This is how The BeagleView is able to fetch and render the new view. If a listener throws an error, the navigation is aborted.
    • If a navigation is called while another navigation is in progress, it will fail with a BeagleNavigationError.

BeagleView.fetch has been deprecated

While resolving this issue, I noticed a big problem with our current navigation. The navigation history was completely decoupled from what was actually rendered in the BeagleView.

This is a problem because we could fall in the following situations:

  1. BeagleView is started at /home. The view rendered is /home and the route at the top of the navigator is /home. A call is made to beagleView.fetch({ path: '/products' }). Now the rendered view is /products while the view at the top of the navigator is /home, i.e., these two sources of truth contradict themselves.

  2. BeagleView is started at /home. The view rendered is /home and the route at the top of the navigator is /home. A call is made to beagleView.getBeagleNavigator().pushView({ url: '/products' }). The rendered view is still /home, but now, the view at the top of the navigator is /products. Again, two sources of truth contradicting themselves.

After much discussion between the team, we decided we have no need for beagleView.fetch anymore. To fully change a view, we can now use the navigator, which, with this PR, also fetches the view and renders its content. To partially change a view we can use the LazyComponent and the action beagle:addChildren.

The BeagleRemoteView (React and Angular)

With beagleView.fetch now deprecated and stuff like showLoading and showError being controlled by a navigation controller. It makes no sense to use the LoadParams as the parameter to create a BeagleRemoteView.

Also there is a huge problem regarding the configuration of the requests via the LoadParams. Every option set in the LoadParams are used only for the first request, every request after that completely ignores the parameters provided.

We can also not change the behavior for people using the LoadParams. So... LoadParams as a parameter to the component BeagleRemoteView has been deprecated. When used, it will work just like it was working previously, but it will warn the developer to consider changing to the new parameters.

The new parameters for a BeagleRemoteView are:

  • route: replaces path. Tells the route to navigate to when the BeagleView is created. When route is first set, it generates a pushView({ url: route }) on the navigator. When route is changed, it generates a resetStack({ url: route }) on the navigator. route is not required, if it's not specified, no navigation will be done by default. This is interesting because today, we can manually control the BeagleView and in this case, it makes no sense to navigate by default.
  • controllerId: tells which navigation controller should be used for first navigation stack. When not provided, the default navigation controller is used.
  • networkOptions: new way of specifying options to all requests of the BeagleView. Differently from LoadParams, this will be valid to every request and not just the first one. Accepts headers, strategy and method. When not specified, use the default options.

The parameters path, for React, and the parameter loadParams, for Angular, are no longer required. Deprecated parameters can't be required.

Other problems fixed

  • The parameter method of the function Tree.insertIntoTree was not working when method = 'replace'
  • In cases of pre-fetched views, if the cache retrieval failed, the navigation wouldn't be performed at all. When a pre-fetch fails, it should proceed with the normal network request.
  • When pre-fetching a view, it was assumed the navigation action had route.url, which is dangerous, some navigations might not have it.

Tests

  • Refactored tests for the BeagleNavigator and placed it under the new test structure.
  • Created many new tests.

Related Pull Requests:

How I did it

  • Refactored the BeagleNavigator.
  • Made the navigation also fetch and render the view.
  • Deprecated the method beagleView.fetch and created new ways of specifying the request options.

How to verify it

To verify it's all working, besides running the tests, I ran the POC beagle-forms for both Angular and React and ran the Playground.

Description for the changelog

  • Added support to NavigationControllers.
  • Fixed problem where request options would be applied only to the first view.
  • A navigation now also fetches and renders the view instead of just altering the navigation history.
  • beagleView.fetch has been deprecated
  • Fixed problem where inserting a node into a tree with the mode "replace" would actually act as the mode was "prepend".
  • Fixed problem where a failed pre-fetched navigation wouldn't attempt to load the view from a network request.
  • Fixed a possible null pointer when pre-fetching views.

@github-actions
Copy link
Contributor

Code coverage

Filename Statements Branches Functions Lines
src/logger/index.ts 79.17% 70% 90% 81.82%
src/beagle-view/navigator/index.ts 97.14% 93.22% 100% 100%
src/error/BeagleNavigationError.ts 100% 100% 100% 100%
src/error/BeagleError.ts 100% 100% 100% 100%
src/beagle-view/render/expression.ts 98.99% 97.33% 100% 100%
src/operation/index.ts 100% 100% 100% 100%
src/operation/array.ts 100% 100% 100% 100%
src/operation/logic.ts 100% 100% 100% 100%
src/operation/number.ts 100% 100% 100% 100%
src/operation/other.ts 100% 100% 100% 100%
src/operation/string.ts 100% 100% 100% 100%
src/utils/automaton.ts 100% 100% 100% 100%
src/error/BeagleNotFoundError.ts 100% 100% 100% 100%
src/error/BeagleParseError.ts 100% 100% 100% 100%
src/beagle-view/render/context.ts 100% 100% 100% 100%
src/action/set-context.ts 100% 83.33% 100% 100%
src/beagle-tree/index.ts 100% 100% 100% 100%
src/beagle-tree/iteration.ts 97.14% 91.67% 87.5% 100%
src/beagle-tree/manipulation.ts 90.91% 71.43% 100% 100%
src/beagle-tree/reading.ts 97.62% 95.83% 100% 100%
src/action/index.ts 100% 100% 100% 100%
src/action/add-children.ts 100% 90.91% 100% 100%
src/action/send-request.ts 100% 92.31% 100% 100%
src/action/alert.ts 100% 100% 100% 100%
src/action/confirm.ts 100% 100% 100% 100%
src/action/submit-form.ts 25% 0% 0% 25%
src/action/condition.ts 100% 100% 100% 100%
src/action/navigation/index.ts 100% 66.67% 100% 100%
src/utils/url.ts 100% 100% 100% 100%
src/utils/string.ts 100% 100% 100% 100%
src/utils/object.ts 100% 66.67% 100% 100%
src/beagle-view/render/action.ts 97.06% 96.43% 90% 96.55%
src/service/beagle-service/index.ts 100% 100% 100% 100%
src/beagle-view/index.ts 89.25% 69.23% 85.71% 90.48%
src/beagle-view/render/index.ts 96.97% 92.86% 100% 100%
src/beagle-view/render/component.ts 100% 100% 100% 100%
src/beagle-view/render/navigation.ts 97.06% 96% 100% 100%
src/beagle-view/render/styling.ts 94.4% 89.47% 100% 99.09%
src/beagle-view/render/type-checker.ts 100% 100% 100% 100%
src/service/beagle-service/configuration.ts 100% 100% 100% 100%
src/metadata/parser.ts 94.44% 75% 100% 100%
src/legacy/middlewares.ts 100% 100% 100% 100%
src/service/beagle-service/services.ts 100% 100% 100% 100%
src/service/network/remote-cache/index.ts 100% 100% 100% 100%
src/service/network/default-headers/index.ts 100% 100% 100% 100%
src/service/network/url-builder/index.ts 100% 100% 100% 100%
src/service/network/view-client/index.ts 97.92% 94.37% 100% 97.73%
src/error/BeagleCacheError.ts 100% 100% 100% 100%
src/error/BeagleNetworkError.ts 100% 100% 100% 100%
src/error/BeagleExpiredCacheError.ts 100% 100% 100% 100%
src/service/global-context/index.ts 100% 91.67% 100% 100%
src/service/view-content-manager/index.ts 100% 100% 100% 100%
src/legacy/beagle-context.ts 100% 100% 100% 100%
src/metadata/decorator.ts 100% 100% 100% 100%
src/index.ts 100% 100% 100% 100%

@pedronaveszup pedronaveszup merged commit 78db12b into master Sep 18, 2020
@pedronaveszup pedronaveszup deleted the feature/navigation-controllers branch September 18, 2020 21:08
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BeagleView and navigation controllers
4 participants