From 4aa7430c323c964a112b8eef336ef4e80bbf1c63 Mon Sep 17 00:00:00 2001 From: carlossteinzup Date: Thu, 10 Mar 2022 10:07:40 -0300 Subject: [PATCH] feat: Translate docs 2.0 (#868) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Translated BeagleRemoteView to EN Signed-off-by: carlossteinzup * Navigation controller translated to PT Signed-off-by: carlossteinzup * Navigation Controller translated to PT Signed-off-by: carlossteinzup * Revises View client web and translates to PT Signed-off-by: carlossteinzup * adjusts view client inf Signed-off-by: carlossteinzup * revises ViewClient Android and translates to PT Signed-off-by: carlossteinzup * adjustment in shortcode Signed-off-by: carlossteinzup * log system revised and translated to EN Signed-off-by: carlossteinzup * Overview from dependencies revised and translated to PT Signed-off-by: carlossteinzup * view client for dependencies revised and translated to EN Signed-off-by: carlossteinzup * Update content/en/android/customization/view-client.md Co-authored-by: Hector Custódio * Update content/en/android/customization/view-client.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/en/android/customization/view-client.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/web/commons/view-client.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/web/commons/beagle-remote-view.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/ios/customization/dependencies/overview.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/ios/customization/dependencies/overview.md Signed-off-by: carlossteinzup * Update content/pt/ios/customization/dependencies/view-client.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/ios/customization/dependencies/view-client.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/en/android/customization/view-client.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/en/ios/customization/dependencies/overview.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/en/ios/customization/dependencies/overview.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/en/web/commons/navigation/navigation-controllers.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/en/web/commons/view-client.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/ios/customization/dependencies/overview.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/ios/customization/dependencies/overview.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/ios/customization/dependencies/overview.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/ios/customization/dependencies/overview.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio * Update content/pt/ios/customization/dependencies/overview.md Signed-off-by: carlossteinzup Co-authored-by: Hector Custódio Co-authored-by: Hector Custódio --- .../en/android/customization/view-client.md | 34 ++- .../ios/customization/dependencies/_index.md | 4 +- .../customization/dependencies/log-system.md | 61 ++--- .../customization/dependencies/overview.md | 68 ++--- .../customization/dependencies/view-client.md | 233 ++++++++++++++++++ content/en/web/commons/beagle-remote-view.md | 39 +-- .../navigation/navigation-controllers.md | 84 +++++-- content/en/web/commons/view-client.md | 31 ++- .../pt/android/customization/view-client.md | 40 +-- .../ios/customization/dependencies/_index.md | 5 +- .../customization/dependencies/log-system.md | 75 +++++- .../customization/dependencies/overview.md | 111 +++++---- .../customization/dependencies/view-client.md | 19 +- content/pt/web/commons/beagle-remote-view.md | 23 +- .../navigation/navigation-controllers.md | 96 +++++--- content/pt/web/commons/view-client.md | 35 ++- 16 files changed, 688 insertions(+), 270 deletions(-) create mode 100644 content/en/ios/customization/dependencies/view-client.md diff --git a/content/en/android/customization/view-client.md b/content/en/android/customization/view-client.md index 80154b440..f17efdb94 100644 --- a/content/en/android/customization/view-client.md +++ b/content/en/android/customization/view-client.md @@ -7,23 +7,31 @@ description: >- --- -# Introduction -Similar to the HttpClient, but more specific. While the HttpClient is responsible for managing every request (views, json data, images, etc), the ViewClient is only responsible for fetching views, i.e. server driven pages. -The ViewClient interface has to functions `fetch` and `prefetch`. +## What is it? -The default implementation of `fetch` does two things: -1. search for a response data in a local cache, if exists, remove it from cache and return; -2. if there is no response data in cache, it calls HttpClient and make the request for the ResponseData. +The `View Client` is very similar to the HttpClient. While the HttpClient is responsible for handling requests (views, json data, images, etc), the ``ViewClient`` is only responsible for fetching views (Server Driven Views). -The default implementation of `prefech` does two things: -1. search for a response data in a local cache, and return it if exists; -2. if there is no response data in cache, it calls HttpClient and make the request for the ResponseData and store it in cache (memory). +The ViewClient interface has two functions **`fetch`** and **`prefetch`**. -Note that `fetch` just search for responses that may have been prefetched earlier, and `prefetch` just store responses. It does nothing other than this, and this might be enough for most applications. But some applications may need extra behavior when fetching views, and this is the place where it should be implemented. +The **`fetch`** default implementation has 2 functionalities: -# Creating a new ViewClient +1. It searches for a response data in a local cache, and if a cache exists, this function removes it from cache and return its contents; +2. If there is no response data in cache, this function calls the `HttpClient` and makes a request which returns a ResponseData. -A good example is caching. Let's say we want to locally store a response so when Beagle calls `viewClient.fetch` again, it returns the cached result instead of calling the HttpClient. To do this, we can create a new ViewClient class that implement ViewClient, has storage and is annotated with `@BeagleComponent` as follows: +The **`prefetch`** default implementation has 2 functionalities: + +1. It searches for a response data in a local cache, and it returns this cache if it exists; +2. If there is no response data in cache, this function calls the `HttpClient` and make the request for a ResponseData and store it in cache (memory). + +{{% alert color="success" %}} +Please note that `fetch` just search for responses that may have been *prefetched* earlier, and `prefetch` just store responses. It just do this, and that is enough for most applications. But some other applications may need an extra behavior when fetching views, and this is when a customized ViewClient must be made. +{{% /alert %}} + +## Creating a new ViewClient + +A good example is caching. Let's say we want to locally store a view in a way that when Beagle calls `viewClient.fetch` again, it returns the cached result, instead of calling the HttpClient. + +To do this, we can create a ``**MyViewClient**`` class that implements ``ViewClient``, has a storage and is annotated with `@BeagleComponent` as follows: ```kotlin @BeagleComponent @@ -65,4 +73,4 @@ class MyViewClient( ``` -Above we implemented a very simple logic to `fetch` and `prefetch` that will store every fetch result in memory using a MutableMap `cachedResponses` using the request url as key, and search for a ResponseData in it every time `fetch` or `prefetch` is called. This is a very dumb implementation, because this cache would never expire, but the objective here is just to show how such feature could be implemented using the ViewClient. \ No newline at end of file +Above we have implemented a logic to `fetch` and `prefetch` that will store every fetch result in memory using a MutableMap called `cachedResponses`. It uses the *request url* as key, and searches for a ``ResponseData`` in it every time `fetch` or `prefetch` is called. This is a simple implementation, since this cache would never expire, and the objective here is to show how this feature could be implemented using the ViewClient. diff --git a/content/en/ios/customization/dependencies/_index.md b/content/en/ios/customization/dependencies/_index.md index d47d18c2f..821499f2d 100644 --- a/content/en/ios/customization/dependencies/_index.md +++ b/content/en/ios/customization/dependencies/_index.md @@ -2,7 +2,5 @@ title: Beagle dependencies weight: 159 description: >- - In this section you will learn about Beagles' dependencies and their properties for iOS environment. + In this section you will learn about Beagles' dependencies and its properties for the iOS environment. --- - ---- \ No newline at end of file diff --git a/content/en/ios/customization/dependencies/log-system.md b/content/en/ios/customization/dependencies/log-system.md index 7788f156f..1350cc212 100644 --- a/content/en/ios/customization/dependencies/log-system.md +++ b/content/en/ios/customization/dependencies/log-system.md @@ -5,57 +5,59 @@ weight: 151 --- -#### Introduction +## What is it? -Beagle uses the unified log system recommend by Apple, to provide different log messages in critical stages of a server driven flow. +Beagle uses the unified log system recommended by Apple, to provide different log messages in critical stages of a server driven flow. The log messages provided for Beagle iOS can be access through: -* Xcode console -* Application console +* **Xcode console** and +* **Application console** -They are divided in 4 categories: +They are divided in 4 categories: 1. **Network:** related to the network layer, information and error messages for each request, response and network URL construction. 2. **Decoding:** displays messages every time a `parse` error occurs. -3. **Navigation:** informative messages that describes the navigations inside the server driven flow and possible errors may occur. -4. **Form:** related to forms. +3. **Navigation:** informative messages that describes the navigations inside the server driven flow and possible errors may occur. +4. **Form:** related to forms. -It is possible to disable triggered log messages. Beagle will not call the Log's API, even if it is default or customized. You will need to change the attribute `isLoggingEnabled` of`BeagleDependencies` to`false`. +It is possible to disable the triggered log messages. Beagle will not call the Log's API, even if it is default or customized. You will need to change the attribute `isLoggingEnabled` of `BeagleDependencies` to `false`. -The log messages can be filtered using these categories names and the main package identifier of the application as a subsystems. +The log messages can be filtered using these categories names and the application main package identifier as a subsystems. -## Instructions to filter log messages: +## Instructions to filter log messages -Follow the steps below to filter the log messages: +Follow the steps below to filter the log messages: **Step 1:** open `Console App`; **Step 2:** select `device` on the `Devices` menu; -**Step 3:** insert the filters in the search bar, search only for log messages with the Network category in the subsystem ~~`br.com.zup.BeagleDemoApp`~~ +**Step 3:** insert the filters in the search bar, search only for log messages with the Network category in the subsystem ~~`br.com.zup.BeagleDemoApp`~~ +{{< figure src="/shared/1.png">}} -![](/shared/1.png) +**Step 4:** when you open the `BeagleDemo` application, you will see two log messages with the `network category`, one will show that Beagle made a request and the other indicating the response. +{{< figure src="/shared/2.png">}} -**Step 4:** when you open the `BeagleDemo` application, you will see two log messages with the network category, one will show that Beagle made a request and the other indicating the response. - -![](/shared/2.png) - -**Step 5:** error messages will be displayed with a yellow dot in the field `Type`, as showed below: - -![](/shared/3.png) +**Step 5:** error messages will be displayed with a yellow dot in the field `Type`, as showed below: +{{< figure src="/shared/3.png">}} **Step 6:** to select the second log message received with a Network filter, you will see a `verbosa` version of this response. +{{< figure src="/shared/4.png">}} -![](/shared/4.png) - -**Step 7:** the body of the response contains the server-driven screen and all its attributes and specifications can be accessed. +**Step 7:** the body of the response contains the server-driven screen and all its attributes and specifications can be accessed. ## Customization -In order to let Beagle's environment open to modifications, the default API logs can be replaced to any other. Follow th next steps to make the API's logs replacement: +In order to let Beagle's environment open to modifications, the default API logs can be replaced by any other. THe next steps explains how to replace the API's logs: -**Step 1:** implement BeagleLoggerType protocol on the class you want to use as log API, you will see that it is necessary to implement the methods `log(_ log: LogType)` and `logDecodingError(type: String)` that are internally called by Beagle when a message needs to be triggered: +**Step 1:** implement BeagleLoggerType protocol on the class you want to use as the log API. You will see that it is necessary to implement the methods: + +* **`log(_ log: LogType)`** and +* **`logDecodingError(type: String)`** + +These are internally called by Beagle when a message needs to be triggered +We have listed an example below: ```swift class CustomLogger: BeagleLoggerType { @@ -69,18 +71,21 @@ class CustomLogger: BeagleLoggerType { } ``` -**Step 2:** on Beagle's configuration of your project, assign to a class' instance to the `logger` dependency on `BeagleDependencies`: +**Step 2:** Go to your project Beagle's configuration and assign a class' instance to `logger` dependency on the `BeagleDependencies`: ```swift let dependencies = BeagleDependencies() dependencies.logger = CustomLogger() Beagle.dependencies = dependencies ``` + ## BeagleLoggerProxy -This class should not be used by the user in the majority of cases. This is the object that will be internally stored in `Beagle.dependencies.logger` instead of` BeagleLogger` customized by the user. +{{% alert color="warning" %}} +This class shouldn't be changed in most cases, since this is the object that will be internally stored in the `Beagle.dependencies.logger` instead of the customized `BeagleLogger`. +{{% /alert %}} -Its responsibility is to only forward calls to the user's class if `Beagle.dependencies.isLogginEnabled` is` true`, otherwise it won't pass along the message. Today it is public just to allow access to the user's custom class via: +Its responsibility is only to forward calls to the user's class if `Beagle.dependencies.isLogginEnabled` is `true`, otherwise it won't pass the message. This property is public to allow access to the user's custom class via the code below: ```swift (Beagle.dependencies.logger as? BeagleLoggerProxy)?.logger diff --git a/content/en/ios/customization/dependencies/overview.md b/content/en/ios/customization/dependencies/overview.md index e769744fe..50a610abc 100644 --- a/content/en/ios/customization/dependencies/overview.md +++ b/content/en/ios/customization/dependencies/overview.md @@ -3,16 +3,18 @@ title: Overview weight: 1 type: overview description: >- - In this section you will learn about Beagles' dependencies and their properties for iOS environment. + This section describes the Beagles' dependencies and their properties for iOS environments. --- --- -## Introduction +## What is it? -Your application can change Beagle's default behavior by customizing its dependencies. +The `dependecies` file is where you can change the Beagle's default behavior in your application. -From the `BeagleConfigurator` we can call the static method `setup(dependencies: BeagleDependencies)` which receives an object of type `BeagleDependencies`, where the customization of the Beagle dependencies can be done. +## How does it work? + +The `BeagleConfigurator` calls the static method `setup(dependencies: BeagleDependencies)` that receives an `BeagleDependencies` object. This object will hold all dependencies's properties. Here follows an example: ```swift public struct BeagleDependencies { @@ -36,10 +38,13 @@ public struct BeagleDependencies { } ``` -This structure has an empty constructor that assigns the default Beagle implementations, so just start it and make the customizations that are convenient. +{{% alert color="success" %}} +This structure has an empty constructor that assigns the default Beagle implementations: -Therefore, it is appropriate to make this initial configuration of Beagle during the application startup process, that is, in the `didFinishLaunchingWithOptions` of the `AppDelegate`: +* start it and make the necessary customizations. +{{% /alert %}} +Therefore, it is appropriate to make this *Beagle initial configuration* during the application startup process, that is, in the the `AppDelegate` function `didFinishLaunchingWithOptions` as shown below: ```swift @UIApplicationMain @@ -64,7 +69,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } ``` -To access these dependencies during application execution, Beagle provides a `@Injected` property wrapper that resolves an instance to the type of the variable (wrapped value). So suppose we want to clear the global context content at some point during application execution: +{{% alert color="success" %}} +To access these dependencies during the application execution, Beagle provides a `@Injected` property wrapper that resolves an instance to the type of the variable (wrapped value). +{{% /alert %}} + +### Examples + +Below we have an example on how to clear the global context content at some point when executing the application: ```swift @Injected var globalContext: GlobalContextProtocol @@ -72,7 +83,7 @@ globalContext.clear() ``` {{% alert color="warning" %}} -This property wrapper raises a `fatalError` if it is used to resolve a dependency that is not Beagles' or that is optional and has not been configured e.g:(logger, analyticsProvider, deepLinkHandler, networkClient), to work around that, simply use `@OptionalInjected` which will return nil if the dependency is not resolved. +This property wrapper raises a `fatalError` if it is used to resolve a dependency that is not Beagles' or that is optional and has not been configured e.g:(logger, analyticsProvider, deepLinkHandler, networkClient), to work around that, simply use `@OptionalInjected` which will return nil if the dependency is not resolved, as shown below. {{% /alert %}} ```swift @@ -82,13 +93,13 @@ logger?.log(Log.network(.httpRequest(request: .init(url: urlRequest)))) ## Customizable Dependencies -Default dependencies implementation that can be customized. +Here follow a few Default dependencies implementations that can be customized. ### CoderProtocol -It is responsible for the encoding and decoding logic of the Beagle. Exposes the `register` method so that it is possible to register new components and actions. +It is responsible for the encoding and decoding Beagle's logic. It exposes the `register` method so that it is possible to register new components and actions. -Below there is an example of how to register a new component and a custom action: +Below you can find an example on how to register a new component and a custom action: ```swift dependencies.coder.register(component: CustomWidget.self) @@ -97,9 +108,9 @@ dependencies.coder.register(action: CustomAction.self) ### UrlBuilderProtocol -It is responsible for creating a URL for a Beagle request from relative URLs that can be sent through BFF (in navigation flows for example) and a configured base URL. +It is responsible for creating a Beagle request URL from relative URLs that are received from an BFF (in navigation flows for example) and a configured base URL. -See next an example on how to use it: +This is an example on how to use it: ```swift dependencies.urlBuilder = UrlBuilder(baseUrl: URL(string: "SUA URL BASE")) @@ -107,7 +118,7 @@ dependencies.urlBuilder = UrlBuilder(baseUrl: URL(string: "SUA URL BASE")) ### ThemeProtocol -Stores all your **styles** and knows how to apply them to your components. +It stores all your **styles** and knows how to apply them to your components. Some widgets have a variable that allows you to define the style. The name of each one must be passed to the **Theme** dependency, so that that style can be used in its respective component. @@ -144,10 +155,10 @@ dependencies.theme = theme ### ViewClientProtocol -It is responsible for fetching screens from the backend using the `fetch` and `prefetch` methods. It has an internal implementation that simply assembles urls from `urlBuilder` and makes requests from `networkClient`. +It is responsible for fetching screens from the backend using the `fetch` and `prefetch` methods. It has an internal implementation that assembles urls from a `urlBuilder` and makes a request from `networkClient`. {{% alert color="info" %}} -It is possible to implement a screen caching mechanism from the custom implementation of this dependency. +It is possible to implement a screen caching mechanism from this dependency custom implementation. {{% /alert %}} ### ImageDownloaderProtocol @@ -162,9 +173,9 @@ Dependencies which are not default and therefore should be implemented before us It is responsible for triggering the log messages produced when running Beagle streams from the `log` method. These logs follow the `LogType` protocol, which has the following parameters: -- category: log subject; -- message: log message; -- level: classifies the criticity level. +* category: log subject; +* message: log message; +* level: classifies the criticity level. ### NetworkClientProtocol @@ -174,7 +185,7 @@ It is responsible for executing **network requests**. Beagle does not provide a This handler is used for a [**deep link navigation**]({{< ref path="/ios/customization/dependencies/deeplink-handler.md" lang="en" >}}) action. The variable has a default value, you can add new screens or replace them with others in the application. -Below you can see a snippet on how to add a screen with a possible route for deep linking using a default value: +Below you can see a code on how to add a screen with a possible route for a deep linking using a default value: ```swift let deepLinkHandler = DeeplinkScreenManager.shared @@ -185,7 +196,7 @@ BeagleConfigurator.setup(dependencies: dependencies) ### AnalyticsProviderProtocol -It is a protocol that can be implemented to track screen appearance or completion actions and click events. +It is a protocol that can be implemented to track the screen appearance, actions and click events. See the example below: @@ -203,24 +214,23 @@ class AnalyticsSample: Analytics { } ``` -## Dependencias publicas não customizáveis - +## Public dependencies that are not customizable -Dependencies that are not customizable but have public APIs for configuring Beagle. +Here we list a few dependencies that could not be customized but have public APIs for configuring Beagle. ### NavigationProtocol -The `navigator` handles actions type of [**navigate**]({{< ref path="/api/actions/navigate/" lang="en" >}}) of your application. +The `navigator` handles the [**navigate**]({{< ref path="/api/actions/navigate/" lang="en" >}}) actions in your application. -Exposes custom navigation controller registration methods and [**navigation animation**]({{< ref path="/ios/customization/navigation-animation" lang="en" >}}). +It exposes a custom navigation controller registration methods and a [**navigation animation**]({{< ref path="/ios/customization/navigation-animation" lang="en" >}}). ### GlobalContextProtocol -It is responsible for managing the global context of Beagle, exposes `get`, `set` and `clear` functions, so that it is possible to access and change its attributes outside the scope of Beagle. +It is responsible for managing the Beagle global context, it exposes the `get`, `set` and `clear` functions, so that it is possible to access and change the Global context attributes outside the Beagle scope. ### OperationsProviderProtocol -It is responsible for providing context operations, exposes the `register` function so that it is possible to register custom operations in Beagle's default OperationsProvider. +It is responsible for providing context operations, exposing the `register` function so that it is possible to register custom operations in Beagle's default OperationsProvider. ### BundleProtocol @@ -228,4 +238,4 @@ It is responsible for providing the application's `Bundle` so that Beagle has ac ```swift dependencies.appBundle.bundle = Bundle(identifier: "myBundleId") -``` \ No newline at end of file +``` diff --git a/content/en/ios/customization/dependencies/view-client.md b/content/en/ios/customization/dependencies/view-client.md new file mode 100644 index 000000000..da2f4001a --- /dev/null +++ b/content/en/ios/customization/dependencies/view-client.md @@ -0,0 +1,233 @@ +--- +title: View Client +weight: 151 +description: >- + This section describes the ViewClient e and how to modify it. +--- + +--- + +## What is it? + +The View Client is a dependency that is called by Beagle's internal classes to search for components in the backend. It is a `middleware` between the `networkClient` layer and Beagle. In this way, this protocol exposes the methods: `fetch` and `prefetch` to do these functionalities: + +```swift +public protocol ViewClientProtocol { + @discardableResult + func fetch( + url: String, + additionalData: HttpAdditionalData?, + completion: @escaping (Result) -> Void + ) -> RequestToken? + + func prefetch(url: String, additionalData: HttpAdditionalData?) +} +``` + +## How to use? + +### Implementing `fetch` + +The default `fetch` implementation follows these steps: + +**Step 1:** Checks if there is no cached component for the given url + +**Step 2:** If a cache exists, it returns the cached component in the completion block. + +**Step 3:** assemble the URL from `urlBuilder` + +**Step 4:** make the request from the `networkClient` + +**Step 5:** decodes the response data from the `coder` + +**Step 6:** returns the ServerDrivenComponent in the completion block. + +### Implementing `prefetch` + +The default implementation of `prefetch` follows these steps: + +**Step 1:** Follows the same logic as steps 3, 4 and 5 of `fetch` + +**Step 2:** Cache (NSCache) the component and assign the url as the search key + +{{% alert color="warning" %}} +This cache logic is only used to implement prefetch functionality, ie screens are not cached by default. +{{% /alert %}} + +## **Creating a Custom ViewClient** + +Therefore, it is possible to implement the View Client in a customized way so that we can adopt a **cache** logic. + +### Dependency definition + +To implement a custom ViewClient, we can use the standard Beagle `ViewClient` as a base. In this way, we define 3 base dependencies that will be used by our implementation: + +1. NetworkClient: Execute requests + +2. URLBuilder: Mount the urls + +3. Coder: Decodes the result of requests + +In addition, we can define a *fourth dependency* that will be responsible for managing the components cache, for this example we will name it `CacheManager`. + +{{% alert color="info" %}} +We will not address the implementation of this dependency, since each application may have its own standard and unique way of performing data caching. +{{% /alert %}} + +### Implementing ViewClientProtocol + +Now we need to implement the ViewClientProtocol's `fetch` and `prefetch` methods, and from there we can adopt our custom component cache policy. + +In this example, we will fetch the component in cache every time the `fetch` method is called and if it is not found, we will make the request normally (implemented in the `fetchComponent` method) and cache the result, for that we will assign the url of the request as a search key: + +```swift +func fetch( + url: String, + additionalData: HttpAdditionalData?, + completion: @escaping (Result) -> Void + ) -> RequestToken? { + // cache custom logic + if let component = cacheManager.getComponent(for: url) { + completion(.success(component)) + return nil + } else { + return fetchComponent(url: url, additionalData: additionalData, completion: completion) + } + } +``` + +So the `fetchComponent` method will have the following implementation: + +```swift +@discardableResult + private func fetchComponent( + url: String, + additionalData: HttpAdditionalData?, + completion: @escaping (Result) -> Void + ) -> RequestToken? { + guard let fullURL = urlBuilder.build(path: url) else { + completion(.failure(.urlBuilderError)) + return nil + } + guard let networkClient = networkClient else { + completion(.failure(.networkClientWasNotConfigured)) + return nil + } + let request = Request(url: fullURL, additionalData: additionalData) + + return networkClient.executeRequest(request) { result in + switch result { + case .success(let response): + // cache custom logic + let decodeResult = self.decodeComponent(from: response.data) + if case .success(let component) = decodeResult { + self.cacheManager.insert(component: component, url: url) + } + completion(self.decodeComponent(from: response.data)) + case .failure(let networkError): + completion(.failure(.networkError(networkError))) + } + } + } +``` + +We can see that five steps are performed: + +**Step 1:** Mount url from `urlBuilder` + +**Step 2:** Execute the request from the `networkClient` + +**Step 3:** Decode the response into a component from the `coder` + +**Step 4:** Insert the cached component from the `cacheManager` + +**Step 5:** Returns the component from the `completion` block + +For the `prefetch` method we can simply follow the same behavior as the `fetchComponent` method, so just call it with the completion block being an empty closure: + +```swift +func prefetch(url: String, additionalData: HttpAdditionalData?) { + fetchComponent(url: url, additionalData: additionalData, completion: { _ in }) +} +``` + +### Final result + +Finally, we have this implementation as a result: + +```swift +class ViewClientCustom: ViewClientProtocol { + + // MARK: Beagle Dependencies + + @OptionalInjected var networkClient: NetworkClientProtocol? + @Injected var urlBuilder: UrlBuilderProtocol + @Injected var coder: CoderProtocol + + // MARK: Inner Dependencies + + // Cache manager + var cacheManager: CacheManagerProtocol! + + // MARK: ViewClientProtocol + + func fetch( + url: String, + additionalData: HttpAdditionalData?, + completion: @escaping (Result) -> Void + ) -> RequestToken? { + // cache custom logic + if let component = cacheManager.getComponent(for: url) { + completion(.success(component)) + return nil + } else { + return fetchComponent(url: url, additionalData: additionalData, completion: completion) + } + } + + func prefetch(url: String, additionalData: HttpAdditionalData?) { + fetchComponent(url: url, additionalData: additionalData, completion: { _ in }) + } + + // MARK: Private Functions + + @discardableResult + private func fetchComponent( + url: String, + additionalData: HttpAdditionalData?, + completion: @escaping (Result) -> Void + ) -> RequestToken? { + guard let fullURL = urlBuilder.build(path: url) else { + completion(.failure(.urlBuilderError)) + return nil + } + guard let networkClient = networkClient else { + completion(.failure(.networkClientWasNotConfigured)) + return nil + } + let request = Request(url: fullURL, additionalData: additionalData) + + return networkClient.executeRequest(request) { result in + switch result { + case .success(let response): + // cache custom logic + let decodeResult = self.decodeComponent(from: response.data) + if case .success(let component) = decodeResult { + self.cacheManager.insert(component: component, url: url) + } + completion(self.decodeComponent(from: response.data)) + case .failure(let networkError): + completion(.failure(.networkError(networkError))) + } + } + } + + private func decodeComponent(from data: Data) -> Swift.Result { + do { + return .success(try coder.decode(from: data)) + } catch { + return .failure(.decoding(error)) + } + } +} +``` diff --git a/content/en/web/commons/beagle-remote-view.md b/content/en/web/commons/beagle-remote-view.md index f0f14b01e..422ffe59c 100644 --- a/content/en/web/commons/beagle-remote-view.md +++ b/content/en/web/commons/beagle-remote-view.md @@ -1,17 +1,22 @@ --- title: BeagleRemoteView weight: 176 -description: Aprenda quais são os parâmetros do BeagleRemoteView +description: BeagleRemoteView description and its parameters --- --- -# Introdução +## What is it? -O componente de entrada para um fluxo server driven no Beagle Web é o `BeagleRemoteView`. Veja um exemplo de como usá-lo: +The `BeagleRemoteView` is the input component for a server driven workflow in Beagle Web. + +## How to use it? + +We have listed an exemple below on how to use this component. {{< tabs id="T81" >}} {{% tab name="Angular" %}} + ```text ``` @@ -19,6 +24,7 @@ O componente de entrada para um fluxo server driven no Beagle Web é o `BeagleRe {{% /tab %}} {{% tab name="React" %}} + ```text ``` @@ -26,17 +32,20 @@ O componente de entrada para um fluxo server driven no Beagle Web é o `BeagleRe {{% /tab %}} {{< /tabs >}} -# Parâmetros -## route -O `BeagleRemoteView` possui um único parâmetro obrigatório: a rota (route). A rota pode ser uma string com a URL ou um objeto mais complexo do tipo `RemoteView`. Quando é uma string, assumimos que a rota é um simples GET para a URL informada, sem headers adicionais. Se for necessário fazer uma requisição com outro método HTTP, corpo de resposta ou headers específicos, deve-se criar um objeto do tipo `RemoteView`, composto das seguintes propriedades: +## Parameters + +### route + +`BeagleRemoteView` has a single mandatory parameter: the route. The route can be a string with the URL or a complex object of type `RemoteView`. When it's a string, we assume the route is a simple GET to the given URL, with no additional headers. If you need to make a request with another HTTP method, response body or specific headers, you must create an object from `RemoteView` type, that has the following properties: + +- **url:** the only required property. Indicates the request URL. +- **fallback:** UI tree to render if the request fails. +- **shouldPrefetch:** is not useful when used with the `BeagleRemoteView` component. In other situations, they preload the page as soon as possible rather than waiting for specific events. +- **httpAdditionalData:** used to configure the request. An HttpAdditionalData contains: + - **method:** the HTTP method, the default is GET. + - **headers:** a map with the request headers. + - **body:** the body of the request. This is not valid for GET requests. -- **url:** a única propriedade obrigatória. Indica a URL da requisição. -- **fallback:** árvore de UI para renderizar caso haja falha na requisição. -- **shouldPrefetch:** não é útil quando usado com o componente `BeagleRemoteView`. Em outras situações, pré-carregam a página assim que possível ao invés de esperar por eventos específicos. -- **httpAdditionalData:** usado para configurar a requisição. Um HttpAdditionalData contém: - - **method:** o método HTTP, o padrão é GET. - - **headers:** um mapa com os headers da requisição. - - **body:** o corpo da requisição. Isso não é válido para requisições GET. +### controllerId -## controllerId -O segundo parâmetro aceito pelo `BeagleRemoteView` é opcional e controla qual controle de nevagação será usado. Os navigation controllers são responsáveis por decidir o que fazer nos eventos de carregamento, erro e sucesso de uma tela, se não informado, o controlador padrão é usado. Para saber mais sobre navigation controllers, leia [este artigo]({{< ref path="/web/commons/navigation/navigation-controllers" lang="pt" >}}). +The second parameter accepted by `BeagleRemoteView` is optional and defines which navigation controller will be used. The ``navigation controllers`` are responsible for deciding what to do in the loading, what error and success events should be called for a screen. If it is not informed, the default controller from beagle will be used. To learn more about ``navigation controllers``, read [this article]({{< ref path="/web/commons/navigation/navigation-controllers" lang="en" >}}). diff --git a/content/en/web/commons/navigation/navigation-controllers.md b/content/en/web/commons/navigation/navigation-controllers.md index c76119c3b..59b111ac3 100644 --- a/content/en/web/commons/navigation/navigation-controllers.md +++ b/content/en/web/commons/navigation/navigation-controllers.md @@ -2,48 +2,62 @@ title: Navigation controllers weight: 3 description: >- - In this section, you will find information on how to control the navigation feedback. + In this section, you will find information about the Navigation Controllers and how to handle the navigation feedback. --- --- {{% alert color="warning" %}} -Attention: If you just wanna change the loading and error components, read [this article]({{< ref path="/web/commons/navigation/loading-error-components" lang="en" >}}) instead. +Attention: If you just need to change the loading and error components, read [this article]({{< ref path="/web/commons/navigation/loading-error-components" lang="pt" >}}) instead. {{% /alert %}} -# Introduction -The navigation controllers are responsible for implementing the behavior of the loading, error and success events of the navigation between Beagle pages. +## What is it? -If not set, Beagle will use the `DefaultNavigationController`, which implements the following behavior: +The navigation controllers are responsible for implementing the screen loading behavior, errors and success events, from the navigation between Beagle pages. -- **onLoading**: render a Beagle UI tree with a single component called `custom:loading`. -- **onError**: render a Beagle UI tree with a single component called `custom:error`. -- **onSuccess**: render a Beagle UI tree with the UI tree returned from the backend. +If you don´t set a custom navigation controller, Beagle will use the `Default NavigationController`, which implements the following behavior: -This behavior can be customized by implementing your own NavigationController. You can have multiple navigation controllers in a single application, one for each section, for instance. Beagle, from the backend, can tell which NavigationController must be used for the next set of screens. +- **onLoading**: renders a Beagle UI tree with a single component called `custom:loading`. +- **onError**: renders a Beagle UI tree with a single component called `custom:error`. +- **onSuccess**: renders a Beagle UI tree with the UI tree returned from the backend. -When navigating to a new Stack (PushStack, ResetStack or ResetApplication), the backend can provide a controllerId to the navigation action and Beagle uses this id to find the corresponding NavigationController in the front-end. We can have an entire stack that has a totally different loading feedback, for example. +{{% alert color="success" %}} +All these behaviors can be customized by implementing a custom `NavigationController`. You can have multiple navigation controllers in a single application, one for each section if you wish. The Beagle framework present in your Frontend can tell which ``NavigationController`` must be called for each set of screens that comes from an Backend, by using a property called `controllerId` +{{% /alert %}} + +When navigating to a new Stack (using, for example, actions like PushStack, ResetStack or ResetApplication), the backend may provide a `controllerId` to the navigation action being triggered (You will only list an controller id in your Screen if you wish to use a `Custom Navigation controller`). + +Beagle will use this id to find the corresponding ``NavigationController`` in the front-end application. In this way, you would be able to have an entire stack of screens with a different loading feedback behaviour. + +## How to use it? + +The NavigationController interface -# The NavigationController interface +### onLoading -## onLoading -Called whenever Beagle is loading a new view. It receives the following object as a parameter: +Called when Beagle loads a new view. It receives the following object as a parameter: -- `view: BeagleView`: the [BeagleView]({{< ref path="/web/commons/advanced-topics/the-beagle-view" lang="en" >}}) that renders this server driven UI. +- `view: BeagleView`: the [BeagleView]({{< ref path="/web/commons/advanced-topics/the-beagle-view" lang="pt" >}}) that renders this server driven UI. - `completeNavigation: () => void`: a function to complete the navigation, i.e. to finally push the new page to the navigator with the `BeagleWidget`. You need to call it as soon as you want to render a Beagle JSON. For instance, if your loading feedback is to render a beagle component, you must call completeNavigation from within the `onLoading` method. If you'll render a Beagle UI only in the success event, you don't need to ever call `completeNavigation` because it gets automatically called after `onSuccess`. -## onError -Called whenever an error happens while loading a new view. It receives the same parameters as the `onLoading` method plus: +### onError + +Called when an error happens while loading a new view. It receives the same parameters as the `onLoading` method plus: - `error: any`: the error thrown while making the request or processing the response. - `retry: () => Promise`: a function that, when called, tries to fetch the view again. -## onSuccess -Called whenever a view is successfully loaded. To render the view, this method must call `beagleView.getRenderer().doFullRenderer(screen)`. This renders the server driven screen to the current `BeagleView`. With the exception of `completeNavigation`, which will be called anyway by Beagle, the `onSuccess` method accepts the same parameters as the `onLoading` plus: +### onSuccess + +Called whenever a view is successfully loaded. To render this view, the method must call `beagleView.getRenderer().doFullRenderer(screen)`. This this functionality renders the server driven screen to the current `BeagleView`. The `onSuccess` method accepts the same parameters as the `onLoading` plus: - `screen: BeagleUIElement`: the server driven view recovered from the [ViewClient]({{< ref path="/web/commons/view-client" lang="en" >}}). -# Example +{{% alert color="success" %}} +`completeNavigation` is the only exception here, since it will be called anyway by Beagle +{{% /alert %}} + +## Example ```typescript import { NavigationController } '@zup-it/beagle-web' @@ -58,19 +72,33 @@ const inYourFace: NavigationController = { } ``` -This is a terrible navigation controller with the sole purpose of demonstrating the feature. It shows a dialog every time a page starts loading. If an error happens, it shows an error dialog, which offers an option to retry. When the page is successfully loaded, it renders the page. +This is simple navigation controller with the sole purpose of demonstrating this feature. + +- It shows a dialog every time a page starts loading. If an error happens. +- it shows an error dialog, which offers an option to retry. +- When the page is successfully loaded, it renders the page. -The only non-intuitive parameter of the functions in a NavigationController is the `completeNavigation`. You can ignore this if you don't intend to show a Beagle UI before the success event. By default, i.e., if you don't call `completeNavigation`, the navigation with the Beagle structure of the new view will only happen after the success event. But, some navigation controllers, like the default one, uses the Beagle Structure to render the feedback. The DefaultNavigationController renders the Beagle component `custom:loading` whenever a loading event happens and because of this, it needs to call `completeNavigation` right on the method `onLoading`, so Beagle can properly render the component. +The only non-intuitive parameter in the NavigationController is the `completeNavigation`. -# Registering the navigation controllers -To provide all navigation controllers that can be used by the backend, you must create a map where the keys are the controller ids and the values are instances of `NavigationController`. +{{% alert color="success" %}} +You can ignore this if you don't intend to present a Beagle UI before the success event. +{{% /alert %}} + +By default, if you don't call the `completeNavigation` function, the navigation will occur after the success event. But, navigation controllers, like the default one, uses the Beagle Structure to render the feedback. + +The `Default NavigationController` renders the `custom:loading` Beagle component whenever a loading event happens and that is why it needs to call the `completeNavigation` function inside the `onLoading` method. In this way, Beagle can properly render the component. + +## Registering the navigation controllers + +1. You must create a map to handle all `navigation controllers` that can be used by the backend, where the keys are the *controller ids* and the values are instances of `NavigationController`. -To tell Beagle what NavigationController is the default, you need to set the property `defaultNavigationController`. The default navigation controller is used whenever no controllerId is provided or whenever no controller corresponding to the provided id is found. +2. On this map you can also define another `NavigationController` that you want to be used as the *default*. To do so, just use the `defaultNavigationController` property. The ``default`` navigation controller is used whenever no ``controllerId`` is given or whenever no controller matching the given id is found. -Suppose you have three navigation controllers: `inYourFace`, `secured` and `public`. `inYourFace` is the default, while `secured` and `public` are used in specific sections of the app and are referenced via the controllerId, from the backend. The configuration would be as following: +If you have three navigation controllers: `inYourFace`, `secured` and `public`. `inYourFace` is the default, while `secured` and `public` are used in specific sections of the app and are referenced via controllerId, set on your Screen on the backend. The configuration would be as following: {{< tabs >}} {{% tab name="Angular" %}} + ```typescript @BeagleModule({ defaultNavigationController: inYourFace, @@ -84,10 +112,13 @@ createBeagleUIService({ navigationControllers: { secured, public }, // ... }) + ``` + {{% /tab %}} {{% tab name="React" %}} + ```typescript createBeagleUIService({ defaultNavigationController: inYourFace, @@ -95,5 +126,6 @@ createBeagleUIService({ // ... }) ``` + {{% /tab %}} -{{< /tabs >}} \ No newline at end of file +{{< /tabs >}} diff --git a/content/en/web/commons/view-client.md b/content/en/web/commons/view-client.md index 48a52efb1..438240379 100644 --- a/content/en/web/commons/view-client.md +++ b/content/en/web/commons/view-client.md @@ -7,18 +7,22 @@ description: >- --- -# Introduction -Similar to the HttpClient, but more specific. While the HttpClient is responsible for managing every request (views, json data, images, etc), the ViewClient is only responsible for fetching views, i.e. server driven pages. +## What is it? -The ViewClient creates the BeagleRequest that is sent to the HttpClient. The default implementation does two things: -1. creates the BeagleRequest according to what has been requested by its caller (normally, the navigator); -2. when the response arrives from the HttpClient, it checks for navigation actions where `preFetch` is `true` and, asynchronously, pre-fetches their results. +The `View Client` is very similar to the HttpClient. While the HttpClient is responsible for managing every request (views, json data, images, etc), the ``ViewClient`` is only responsible for fetching views, i.e. Server Driven Pages. -It does nothing other than this, and this might be enough for most applications. But some applications may need extra behavior when fetching views, and this is the place where it should be implemented. +The ``ViewClient`` creates a ``BeagleRequest`` that is sent to the HttpClient. The default implementation handles 2 things: -# Creating a new ViewClient +1. It creates a ``BeagleRequest`` according to what has been requested by its caller (generally the navigator); +2. When the response arrives from the HttpClient, it checks for navigation actions where `preFetch` is `true` and, *asynchronously*, pre-fetches their results. -A good example is caching. Let's say we want to locally store a view so when Beagle calls `viewClient.fetch` again, it returns the cached result instead of calling the hHttpClient. To do this, we can implement a new ViewClient that has storage and implements `fetch` as follows: +It does nothing other than this, and this might be enough for most applications. But, some applications may need extra behavior when fetching views, and this is the place where it should be customized. + +## How to use it? + +### Creating a new ViewClient + +A good example is caching. Let's say we want to locally store a view so when Beagle calls `viewClient.fetch` again, it returns the cached result instead of calling the HttpClient. To do this, we can implement a new ``ViewClient`` that has a storage and implements `fetch` as follows: ```typescript import { ViewClient } from '@zup-it/beagle-web' @@ -43,13 +47,15 @@ function createMyViewClient(): ViewClient { } ``` -Above we implemented a very simple logic that will store every fetch result into the disk using the localStorage. This is a very dumb implementation, because this cache would never expire, but the objective here is just to show how such feature could be implemented using the ViewClient. +We have implemented a logic above that will store every fetch result into the disk using the *localStorage*. This is a simple and only *for test* implementation, since this cache would never expire. + +### Registering the new ViewClient -# Registering the new ViewClient -After creating your custom ViewClient, you just need to pass it to your BeagleService instance: +After creating your custom ``ViewClient`` above, you need to pass it to your ``BeagleService`` instance: {{< tabs >}} {{% tab name="Angular" %}} + ```typescript @BeagleModule({ viewClient: createMyViewClient(), @@ -63,14 +69,17 @@ createBeagleUIService({ // ... }) ``` + {{% /tab %}} {{% tab name="React" %}} + ```typescript createBeagleUIService({ viewClient: createMyViewClient(), // ... }) ``` + {{% /tab %}} {{< /tabs >}} diff --git a/content/pt/android/customization/view-client.md b/content/pt/android/customization/view-client.md index 80154b440..9608bdba1 100644 --- a/content/pt/android/customization/view-client.md +++ b/content/pt/android/customization/view-client.md @@ -1,29 +1,37 @@ --- -title: View client -weight: 109 +title: Ver cliente +wight: 109 description: >- - In this section, you will find information on how to setup a ViewClient in Beagle Android. + Nesta seção, você encontrará informações sobre como configurar um ViewClient customizado no Beagle Android. --- --- -# Introduction -Similar to the HttpClient, but more specific. While the HttpClient is responsible for managing every request (views, json data, images, etc), the ViewClient is only responsible for fetching views, i.e. server driven pages. -The ViewClient interface has to functions `fetch` and `prefetch`. +## O que é isso? -The default implementation of `fetch` does two things: -1. search for a response data in a local cache, if exists, remove it from cache and return; -2. if there is no response data in cache, it calls HttpClient and make the request for the ResponseData. +O `View Client` é muito semelhante ao HttpClient. Enquanto o HttpClient é responsável por lidar com requisições (views, json data, imagens, etc), o ``ViewClient`` é responsável apenas por buscar views (Server Driven Views). -The default implementation of `prefech` does two things: -1. search for a response data in a local cache, and return it if exists; -2. if there is no response data in cache, it calls HttpClient and make the request for the ResponseData and store it in cache (memory). +A interface ViewClient tem as funções **`fetch`** e **`prefetch`**. -Note that `fetch` just search for responses that may have been prefetched earlier, and `prefetch` just store responses. It does nothing other than this, and this might be enough for most applications. But some applications may need extra behavior when fetching views, and this is the place where it should be implemented. +A implementação padrão de **`fetch`** tem 2 funcionalidades: -# Creating a new ViewClient +1. Ela procura um **`response data`** em um cache local, e caso exista, esta função o remove do cache e retorna seu conteúdo; +2. Se não houver dados de resposta no cache, esta função chama o `HttpClient` e faz uma solicitação para um ResponseData. -A good example is caching. Let's say we want to locally store a response so when Beagle calls `viewClient.fetch` again, it returns the cached result instead of calling the HttpClient. To do this, we can create a new ViewClient class that implement ViewClient, has storage and is annotated with `@BeagleComponent` as follows: +A implementação padrão do **`prefech`** tem 2 funcionalidades: + +1. Ele procura dados de resposta em um cache local e retorna esse cache se existir; +2. Se não houver dados de resposta em cache, esta função chama o `HttpClient` e faz a solicitação de um ResponseData e armazena em cache (memória). + +{{% alert color="success" %}} +Observe que `fetch` apenas procura por respostas que possam ter sido *requisitadas* anteriormente, e `prefetch` apenas armazena respostas. Ele faz isso apenas, geralmente é o bastante para muitas aplicações. Mas pode haver alguma outra situação em que uma aplicação precise de um comportamento extra ao buscar `views`, e é nesse momento que um `ViewClient` customizado deve ser feito. +{{% /alert %}} + +## Criando um novo ViewClient + +Um bom exemplo é o cache. Digamos que queremos armazenar uma `view` localmente de forma que quando o Beagle chamar `viewClient.fetch` novamente, ele retorne o resultado em cache, ao invéz de chamar o HttpClient. + +Para fazer isso, criamos uma classe ``**MyViewClient**`` que implementa ``ViewClient``, que tem uma forma de armazenamento e é anotado com `@BeagleComponent` da seguinte forma: ```kotlin @BeagleComponent @@ -65,4 +73,4 @@ class MyViewClient( ``` -Above we implemented a very simple logic to `fetch` and `prefetch` that will store every fetch result in memory using a MutableMap `cachedResponses` using the request url as key, and search for a ResponseData in it every time `fetch` or `prefetch` is called. This is a very dumb implementation, because this cache would never expire, but the objective here is just to show how such feature could be implemented using the ViewClient. \ No newline at end of file +Neste exemplo implementamos uma lógica para `fetch` e `prefetch` que irá armazenar cada resultado de busca na memória usando um `MutableMap` chamado `cachedResponses`. Ele usa a *request url* como chave, e procura por um ``ResponseData`` toda vez que `fetch` ou `prefetch` é chamado. Esta é uma implementação simples, pois esse cache nunca expiraria, pois o objetivo aqui é mostrar como esse recurso pode ser implementado usando o ViewClient. diff --git a/content/pt/ios/customization/dependencies/_index.md b/content/pt/ios/customization/dependencies/_index.md index b0231c231..c4a6ca555 100644 --- a/content/pt/ios/customization/dependencies/_index.md +++ b/content/pt/ios/customization/dependencies/_index.md @@ -2,8 +2,5 @@ title: Dependências do Beagle weight: 159 description: >- - Nesta seção, você encontra informações sobre as dependências do Beagle e suas - propriedades para iOS. + Nesta seção você encontrará informações sobre as dependências do Beagle iOS e suas propriedades. --- - ---- \ No newline at end of file diff --git a/content/pt/ios/customization/dependencies/log-system.md b/content/pt/ios/customization/dependencies/log-system.md index d71d2b8eb..109226a4c 100644 --- a/content/pt/ios/customization/dependencies/log-system.md +++ b/content/pt/ios/customization/dependencies/log-system.md @@ -2,19 +2,64 @@ title: Sistema de Log weight: 157 description: >- - Nesta seção, você encontra a descrição da classe BeagleLogger e detalhes de - configuração e customização + Esta seção descreve a classe BeagleLogger e detalha como configurá-la e customizá-la --- --- -## Introdução +## O que é isso? -O Beagle não fornece uma implementação default para a camada de Log, logo, para realizar o log das menssagens produzidas pelo Beagle é preciso criar uma implementação do LoggerProtocol e atribui-la nas dependencias do Beagle. +O Beagle usa o sistema de log unificado recomendado pela Apple para fornecer diferentes mensagens de log em estágios de um fluxo Server Driven. -## Customização +As mensagens de log fornecidas para o Beagle iOS podem ser acessadas através do: -**Passo 1:** implemente o protocolo BeagleLoggerType na classe que deseja utilizar como API de logs, você irá observar que é preciso implementar os métodos `log(_ log: LogType)` e `logDecodingError(type: String)` que são chamados internamente pelo Beagle sempre que uma mensagem precisa ser disparada: +* **Consola Xcode** e do +* **Console de aplicativos** + +Eles são divididos em 4 categorias: + +1. **Rede:** relacionado à camada de rede, informações e mensagens de erro para cada solicitação, resposta e construção de URL de rede. +2. **Decodificação:** exibe mensagens sempre que ocorre um erro `parse`. +3. **Navegação:** mensagens informativas que descrevem as navegações dentro do fluxo acionado pelo servidor e possíveis erros podem ocorrer. +4. **Formulário:** relacionado a formulários. + +É possível desabilitar as mensagens de log acionadas. O Beagle não chamará a API do Log, mesmo que seja padrão ou personalizada. Você precisará alterar o atributo `isLoggingEnabled` de `BeagleDependencies` para `false`. + +As mensagens de log podem ser filtradas usando esses nomes de categorias e o identificador do pacote principal do aplicativo como um subsistema. + +## Instruções para filtrar mensagens de log + +Siga os passos abaixo para filtrar as mensagens de log: + +**Paso 1:** abra o `Console App`; + +**Passo 2:** selecione `device` no menu `Devices`; + +**Passo 3:** insira os filtros na barra de pesquisa, pesquise apenas mensagens de log com a categoria Rede no subsistema ~~`br.com.zup.BeagleDemoApp`~~ +{{< figure src="/shared/1.png">}} + +**Passo 4:** ao abrir o aplicativo `BeagleDemo`, você verá duas mensagens de log com a `network category`, uma mostra que o Beagle fez uma solicitação e a outra indica a resposta. +{{< figure src="/shared/2.png">}} + +**Etapa 5:** as mensagens de erro serão exibidas com um ponto amarelo no campo `Type`, conforme mostrado abaixo: +{{< figure src="/shared/3.png">}} + +**Etapa 6:** para selecionar a segunda mensagem de log recebida com um filtro de rede, você verá uma versão `verbosa` desta resposta. +{{< figure src="/shared/4.png">}} + +**Etapa 7:** o corpo da resposta contém a tela (Server Driven) e todos os seus atributos e especificações. + +## Costumização + +Para deixar o ambiente do Beagle aberto a modificações, os logs padrão da API podem ser substituídos por quaisquer outros. Os próximos passos explicam como substituir os logs da API: + +**Passo 1:** implemente o protocolo BeagleLoggerType na classe que você deseja usar como API de log. Você verá que é necessário implementar os métodos: + +* **`log(_ log: LogType)`** e +* **`logDecodingError(type: String)`** + +Eles são chamados internamente pelo Beagle quando uma mensagem precisa ser acionada. +Listamos um exemplo abaixo: ```swift class CustomLogger: BeagleLoggerType { @@ -28,10 +73,22 @@ class CustomLogger: BeagleLoggerType { } ``` -**Passo 2:** nas configurações do Beagle de seu projeto atribua uma instância da classe à dependência `logger` no `BeagleDependencies`: +**Passo 2:** Vá para a configuração do seu projeto Beagle e atribua uma instância de classe para a dependência do `logger` no `BeagleDependencies`: ```swift let dependencies = BeagleDependencies() dependencies.logger = CustomLogger() -BeagleConfigurator.setup(dependencies: dependencies) -``` \ No newline at end of file +Beagle.dependencies = dependencies +``` + +## BeagleLoggerProxy + +{{% alert color="warning" %}} +Esta classe não deve ser alterada na maioria dos casos, pois este é o objeto que será armazenado internamente no `Beagle.dependencies.logger` ao invés do `BeagleLogger` customizado. +{{% /alert %}} + +Sua responsabilidade é apenas encaminhar chamadas para a classe do usuário se `Beagle.dependencies.isLogginEnabled` for `true`, caso contrário não passará a mensagem. Esta propriedade é pública para permitir o acesso à classe customizada do usuário através do código abaixo: + +```swift +(Beagle.dependencies.logger as? BeagleLoggerProxy)?.logger +``` diff --git a/content/pt/ios/customization/dependencies/overview.md b/content/pt/ios/customization/dependencies/overview.md index 7216971d4..6586be49c 100644 --- a/content/pt/ios/customization/dependencies/overview.md +++ b/content/pt/ios/customization/dependencies/overview.md @@ -1,19 +1,20 @@ --- -title: Visão Geral +title: Overview weight: 1 type: overview description: >- - Nesta seção, você encontra informações sobre as dependências do Beagle e suas - propriedades para iOS. + Esta seção descreve as dependências do Beagles e suas propriedades para ambientes iOS. --- --- -## Introdução +## O que é isso? -A sua aplicação pode mudar o comportamento default do Beagle, a partir da customização das dependencias dele. +O arquivo `dependecies` é onde o comportamento padrão do Beagle pode ser alterado em sua aplicação. -A partir do `BeagleConfigurator` podemos chamar o método estático `setup(dependencies: BeagleDependencies)` que recebe um objeto do tipo `BeagleDependencies`, onde pode ser feito a customização das dependencias do Beagle. +## Como funciona? + +O `BeagleConfigurator` chama o método estático `setup(dependencies: BeagleDependencies)` que recebe um objeto `BeagleDependencies`. Este objeto conterá as propriedades de todas as dependências. Abaixo temos um exemplo desse objeto: ```swift public struct BeagleDependencies { @@ -37,19 +38,20 @@ public struct BeagleDependencies { } ``` -Essa estrutura possui um construtor vazio que atribui as implementações default do Beagle, então basta iniciá-lo e fazer as customizações que forem convenientes. +{{% alert color="success" %}} +Essa estrutura tem um construtor vazio que atribui as implementações padrão do Beagle: + +* inicie-o e faça as personalizações necessárias. +{{% /alert %}} -Dessa forma, é adequado fazer essa configuração inicial do Beagle durante o processo de inicialização da aplicação, isto é, no `didFinishLaunchingWithOptions` do `AppDelegate`: +É importante que se faça essa *configuração* das dependências durante o processo de inicialização da aplicação, ou seja, na função `AppDelegate` `didFinishLaunchingWithOptions` conforme mostrado abaixo: ```swift @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - var dependencies = BeagleDependencies() dependencies.theme = AppTheme.theme dependencies.urlBuilder = UrlBuilder(baseUrl: URL(string: .baseURL)) @@ -59,57 +61,56 @@ class AppDelegate: UIResponder, UIApplicationDelegate { )) dependencies.coder.register(type: CustomComponent.self) dependencies.coder.register(type: CustomAction.self) - BeagleConfigurator.setup(dependencies: dependencies) - let rootViewController = MainScreen().screenController() window?.rootViewController = rootViewController - return true } } - ``` -Para fazer o acesso a essas dependencias durante a execução da aplicação o Beagle provê um property wrapper `@Injected` que resolve uma instancia para o tipo da variável (wrapped value). Então supondo que desejamos limpar o conteudo do global context em algum momento durante a execução da aplicação: +{{% alert color="success" %}} +Para acessar essas dependências durante a execução do aplicativo, o Beagle fornece um wrapper de propriedade `@Injected` que resolve uma instância para o tipo da variável (valor encapsulado). +{{% /alert %}} + +### Exemplos + +Abaixo temos um exemplo de como limpar o conteúdo do contexto global em algum momento ao executar a aplicação: ```swift @Injected var globalContext: GlobalContextProtocol - globalContext.clear() ``` {{% alert color="warning" %}} -Esse property wrapper dispara um `fatalError` caso seja usado para resolver uma dependencia que não seja do Beagle ou que seja opcional e não foi configurada (logger, analyticsProvider, deepLinkHandler, networkClient), para isso você pode usar `@OptionalInjected` que irá retornar nil caso a dependencia não seja resolvida. +Este wrapper de propriedade gera um `fatalError` se for usado para resolver uma dependência que não seja do Beagle ou que seja opcional e não tenha sido configurada, por exemplo:(logger, analyticsProvider, deepLinkHandler, networkClient), para contornar isso, basta usar `@OptionalInjected` que retornará nil se a dependência não for resolvida, conforme mostrado abaixo. {{% /alert %}} ```swift @OptionalInjected var logger: LoggerProtocol? - logger?.log(Log.network(.httpRequest(request: .init(url: urlRequest)))) ``` -## Dependencias Customizáveis +## Dependências customizáveis -Dependencias que apresentam uma implementação default mas podem ser customizadas. +Aqui seguem algumas implementações de dependências padrão que podem ser personalizadas. ### CoderProtocol -É responsável pela parte de codificação e decodificação do Beagle. Expõe o método `register` para que seja possível registrar novos componentes e ações no Beagle. +Ele é responsável pela codificação e decodificação da lógica do Beagle. Ele expõe o método `register` para que seja possível registrar novos componentes e ações. -Veja abaixo um exemplo de como registrar um novo componente e uma action customizada: +Abaixo você encontra um exemplo de como registrar um novo componente e uma ação personalizada: ```swift dependencies.coder.register(component: CustomWidget.self) - dependencies.coder.register(action: CustomAction.self) ``` ### UrlBuilderProtocol -É responsavel por criar uma URL para uma requisição do Beagle a partir de URLs relativas que podem ser enviadas pelo BFF (em fluxos de navegação por exemplo) e uma URL base configurada. +Ele é responsável por criar uma URL de requisição do Beagle a partir de URLs relativas que são recebidas de um BFF (nos fluxos de navegação, por exemplo) e uma URL base configurada. -Veja abaixo um exemplo de como usar: +Este é um exemplo de como usar essa configuração: ```swift dependencies.urlBuilder = UrlBuilder(baseUrl: URL(string: "SUA URL BASE")) @@ -117,17 +118,17 @@ dependencies.urlBuilder = UrlBuilder(baseUrl: URL(string: "SUA URL BASE")) ### ThemeProtocol -Armazena todos os seus **styles** e sabe como aplicá-los em seus componentes. +Ele armazena todos os seus **estilos** e sabe como aplicá-los aos seus componentes. -Alguns widgets possuem uma variável que permite você definir o estilo. O nome de cada uma deverá ser repassada à dependência do **Theme**, de modo que aquele estilo possa ser usado no seu respectivo componente. +Alguns widgets possuem uma variável que permite definir o estilo. O nome de cada um deve ser passado para a dependência **Theme**, para que esse estilo possa ser utilizado em seu respectivo componente. -Para configurar os estilos customizados, siga os seguintes passos: +Para configurar estilos personalizados, siga estas etapas: {{% alert color="info" %}} -Você irá usar o `Text` como um widget que possui o `UITextView` como seu **UIKit view**. Depois disso, você irá aplicar suas mudanças de estilo para esse view nos quais terão também customizações de `font` e `textColor`. +Você usará `Text` como um widget que tem `UITextView` como sua **UIKit view**. Depois disso, você aplicará suas alterações de estilo a esta visualização, que também terá as personalizações `font` e `textColor`. {{% /alert %}} -**Passo 1:** crie uma função que irá receber a representação o `UIKit` com a representação do widget que você quer aplicar o estilo. +**Passo 1:** crie uma função que receba uma representação do `UIKit` do Widget ao qual você deseja aplicar estilos. ```swift static func blackTextNormalStyle() -> (UITextView?) -> Void { @@ -138,7 +139,7 @@ static func blackTextNormalStyle() -> (UITextView?) -> Void { } ``` -**Passo 2**: crie uma instância concreta do `AppTheme` com os nomes dos seus estilos e as funções correspondentes. +**Passo 2**: Instancie AppTheme com uma matriz de valores de chave representando o nome do estilo e a função correspondente. ```swift let theme = AppTheme(styles: [ @@ -146,7 +147,7 @@ let theme = AppTheme(styles: [ ]) ``` -**Passo 3**: atribua sua instância Theme às dependências do Beagle. +**Passo 3**: adicione a dependência de tema personalizado às dependências do Beagle ```swift dependencies.theme = theme @@ -154,37 +155,37 @@ dependencies.theme = theme ### ViewClientProtocol -É responsável por realizar a busca de telas no backend a partir do método `fetch` e `prefetch`. Possui uma implementação interna que simplesmente monta as urls a partir do `urlBuilder` e faz a requisições a partir do `networkClient`. +Ele é responsável por buscar telas do backend usando os métodos `fetch` e `prefetch`. Ele tem uma implementação interna que monta urls de um `urlBuilder` e faz uma requisição do `networkClient`. {{% alert color="info" %}} -É possível implementar um mecanismo de cache de telas a partir da implementação customizada dessa dependencia. +É possível implementar um mecanismo de cache de tela a partir desta implementação customizada de dependência. {{% /alert %}} ### ImageDownloaderProtocol -É responsável por fazer requisições de imagens remotas a partir do método `fetchImage`. O Beagle possui uma implementação default para essa dependencia, que simplesmente chama o `networkClient` para buscar as imagens e não realiza nenhum tipo de cache. +Ele é responsável por fazer requisições de imagens remotas a partir do método `fetchImage`. O Beagle tem uma implementação padrão para essa dependência, que simplesmente chama o `networkClient` para buscar as imagens e não executa nenhum cache. -## Dependencias Opcionais +## Optional Dependencies -Dependencias que não possuem uma implementação default e portanto devem ser implementadas para o funcionamento correto do Beagle. +Estas são dependências que não estão no padrão e, portanto, devem ser implementadas antes de serem usadas. ### LoggerProtocol -É responsável por disparar as menssagens de log produzidas durante a execução de fluxos do Beagle a partir do método `log`. Esses logs seguem o protocolo LogType, o qual tem os parâmetros: +Ele é responsável por acionar as mensagens de log produzidas ao executar streams do Beagle a partir do método `log`. Esses logs seguem o protocolo `LogType`, que possui os seguintes parâmetros: -- category: assunto do log; -- message: mensagem do log; -- level: classifica o nível crítico. +* category: categoria do log; +* message: mensagem do log; +* level: classifica o nivel crítico do erro. ### NetworkClientProtocol -É responsável por executar **network requests**. O Beagle não fornece uma implementação default para essa dependencia, logo, é **obrigatório** que seja fornecida uma implementação para essa dependencia para que o Beagle consiga se comunicar com o backend. +Ele é responsável por executar **network requests**. O Beagle não fornece uma implementação padrão para essa dependência, portanto, é **obrigatório** que seja fornecida uma implementação para essa dependência para que o Beagle possa se comunicar com o back-end. ### DeepLinkHandlerProtocol -Este handler é usado para uma ação de [**deep link navigation**]({{< ref path="/android/customization/deep-link-handler.md" lang="pt" >}}). A variável possui um valor default, você pode adicionar novas telas ou substituir por outras na aplicação. +Esse manipulador é usado para uma ação de [**deep link navigation**]({{< ref path="/ios/customization/dependencies/deeplink-handler.md" lang="en" >}}). A variável tem um valor padrão, você pode adicionar novas telas ou substituí-las por outras na aplicação. -Abaixo, você encontra um comando de como adicionar uma tela com um possível roteamento para deep linking usando um valor default: +Abaixo você pode ver um código de como adicionar uma tela com uma possível rota para um link direto usando um valor padrão: ```swift let deepLinkHandler = DeeplinkScreenManager.shared @@ -195,7 +196,7 @@ BeagleConfigurator.setup(dependencies: dependencies) ### AnalyticsProviderProtocol -É um protocolo que pode ser implementado para rastrear ações de aparecimento da tela ou sua finalização e eventos de clique. +É um protocolo que pode ser implementado para rastrear carregamentos de tela, ações e eventos de clique em componentes Beagle. Veja o exemplo abaixo: @@ -204,39 +205,37 @@ class AnalyticsSample: Analytics { func trackEventOnScreenAppeared(_ event: AnalyticsScreen) { print("Screen \(event.screenName) appeared") } - func trackEventOnScreenDisappeared(_ event: AnalyticsScreen) { print("Screen \(event.screenName) disappeared") } - func trackEventOnClick(_ event: AnalyticsClick) { print("Button touch with:\ncategory = \(event.category)\nlabel = \(event.label ?? "empty")\nvalue = \(event.value ?? "empty")") } } ``` -## Dependencias publicas não customizáveis +## Dependências públicas que não são customizáveis -Dependencias que não são customizáveis mas apresentam APIs públicas para configuração do Beagle. +Aqui listamos algumas dependências que não podem ser customizadas, mas possuem APIs públicas para configurar o Beagle. ### NavigationProtocol -O `navigator` lida com tipo de ações de [**navigate**]({{< ref path="/api/actions/navigate/" lang="pt" >}}) da sua aplicação. +O `navigator` lida com as ações [**navigate**]({{< ref path="/api/actions/navigate/" lang="en" >}}) em seu aplicativo. -Expõe métodos de registro de navigation controller customizadas e de [**animação de navegação**]({{< ref path="/ios/customization/navigation-animation" lang="pt" >}}). +Ele expõe métodos de registro de um `navigation controler` personalizado e uma [** animação de navegação**]({{< ref path="/ios/customization/navigation-animation" lang="en" >}}). ### GlobalContextProtocol -É reponsavel por gerenciar o contexto global do Beagle, expõe funções de `get`, `set` e `clear`, para que seja possível acessar e alterar atributos dele fora do escopo do Beagle. +Ele é responsável por gerenciar o contexto global do Beagle, ele expõe as funções `get`, `set` e `clear`, para que seja possível acessar e alterar os atributos do contexto global fora do escopo do Beagle. ### OperationsProviderProtocol -É responsavel por prover as operações de contexto, expõe a função `register` para que seja possível registrar operações customizadas no OperationsProvider default do Beagle. +Ele é responsável por fornecer operações de contexto, ele expõe a função `register` para que seja possível registrar operações personalizadas no OperationsProvider padrão do Beagle. ### BundleProtocol -É responsavel por prover o `Bundle` da aplicação para que o Beagle tenha acesso a imagens locais contidas, é inicializado com o `Bundle.main` mas esse pode ser facilmente alterado: +Ele é responsável por fornecer o `Bundle` da aplicação para que o Beagle tenha acesso às imagens locais contidas, ele é inicializado com `Bundle.main` mas isso pode ser facilmente alterado: ```swift dependencies.appBundle.bundle = Bundle(identifier: "myBundleId") -``` \ No newline at end of file +``` diff --git a/content/pt/ios/customization/dependencies/view-client.md b/content/pt/ios/customization/dependencies/view-client.md index 357af599b..9d2e76303 100644 --- a/content/pt/ios/customization/dependencies/view-client.md +++ b/content/pt/ios/customization/dependencies/view-client.md @@ -7,9 +7,9 @@ description: >- --- -## **Introdução** +## O que é isso? -O View Client é uma dependencia que é chamada pelas classes internas do Beagle para fazer a busca de componentes no backend, ou seja ele é um middleware entre a camada de rede `networkClient` e o Beagle. Dessa forma, o protocolo expõe os métodos: `fetch` e `prefetch` para fazerem essas buscas: +O View Client é uma dependencia que é chamada pelas classes internas do Beagle para fazer a busca de componentes no backend, ou seja, ele é um `middleware` entre a camada de rede `networkClient` e o Beagle. Dessa forma, o protocolo expõe os métodos: `fetch` e `prefetch` para fazerem essas buscas: ```swift public protocol ViewClientProtocol { @@ -24,6 +24,10 @@ public protocol ViewClientProtocol { } ``` +## Como usar? + +### Implementando o `fetch` + A implementação padrão `fetch` segue os seguintes passos: **Passo 1:** Verifica se não existe um componente em cache para a url dada @@ -38,6 +42,8 @@ A implementação padrão `fetch` segue os seguintes passos: **Passo 6:** retorna o ServerDrivenComponent no bloco de completion. +### Implementando o `prefetch` + A implementação padrão do `prefetch` segue os seguintes passos: **Passo 1:** Segue a mesma logica dos passos 3,4 e 5 do `fetch` @@ -54,7 +60,7 @@ Portanto, é possivel implementar o View Client de forma customizada para que po ### Definição das dependencias -Para implementar um ViewClient customizado, podemos adotar como base o ViewClient padrão do Beagle. Dessa forma, definimos 3 dependencias base que serão ultilizadas por nossa implementação: +Para implementar um ViewClient customizado, podemos adotar como base o `ViewClient` padrão do Beagle. Dessa forma, definimos 3 dependências base que serão utilizadas por nossa implementação: 1. NetworkClient: Executa as requisições @@ -62,7 +68,7 @@ Para implementar um ViewClient customizado, podemos adotar como base o ViewClien 3. Coder: Decodifica o resultado das requisições -Além disso podemos definir uma quarta dependencia que será responsável pelo gerenciamento de cache dos componentes, para esse exemplo a nomearemos de CacheManager. +Além disso podemos definir uma *quarta dependência* que será responsável pelo gerenciamento de cache dos componentes, para esse exemplo a nomearemos de `CacheManager`. {{% alert color="info" %}} Não abordaremos a implementação dessa dependencia, já que cada aplicação pode ter sua forma padrão e exclusiva de realizar o cache de dados @@ -147,7 +153,7 @@ func prefetch(url: String, additionalData: HttpAdditionalData?) { ### Resultado Final -Por fim temos como resultado essa implementação: +Por fim, temos como resultado essa implementação: ```swift class ViewClientCustom: ViewClientProtocol { @@ -225,6 +231,3 @@ class ViewClientCustom: ViewClientProtocol { } } ``` - - - diff --git a/content/pt/web/commons/beagle-remote-view.md b/content/pt/web/commons/beagle-remote-view.md index 56345d4dd..776051eae 100644 --- a/content/pt/web/commons/beagle-remote-view.md +++ b/content/pt/web/commons/beagle-remote-view.md @@ -1,17 +1,22 @@ --- title: BeagleRemoteView weight: 176 -description: Aprenda quais são os parâmetros do BeagleRemoteView +description: Descrição do BeagleRemoteView e seus parâmetros --- --- -# Introdução +## O que é isso? -O componente de entrada para um fluxo server driven no Beagle Web é o `BeagleRemoteView`. Veja um exemplo de como usá-lo: +`BeagleRemoteView` é o componente de entrada para um fluxo server driven no Beagle Web. + +## Como utilizá-lo? + +Listamos abaixo um exemplo de uso do ``BeagleRemoveView`` {{< tabs id="T81" >}} {{% tab name="Angular" %}} + ```text ``` @@ -19,6 +24,7 @@ O componente de entrada para um fluxo server driven no Beagle Web é o `BeagleRe {{% /tab %}} {{% tab name="React" %}} + ```text ``` @@ -26,8 +32,10 @@ O componente de entrada para um fluxo server driven no Beagle Web é o `BeagleRe {{% /tab %}} {{< /tabs >}} -# Parâmetros -## route +## Parâmetros + +### route + O `BeagleRemoteView` possui um único parâmetro obrigatório: a rota (route). A rota pode ser uma string com a URL ou um objeto mais complexo do tipo `RemoteView`. Quando é uma string, assumimos que a rota é um simples GET para a URL informada, sem headers adicionais. Se for necessário fazer uma requisição com outro método HTTP, corpo de resposta ou headers específicos, deve-se criar um objeto do tipo `RemoteView`, composto das seguintes propriedades: - **url:** a única propriedade obrigatória. Indica a URL da requisição. @@ -38,5 +46,6 @@ O `BeagleRemoteView` possui um único parâmetro obrigatório: a rota (route). A - **headers:** um mapa com os headers da requisição. - **body:** o corpo da requisição. Isso não é válido para requisições GET. -## controllerId -O segundo parâmetro aceito pelo `BeagleRemoteView` é opcional e controla qual controle de nevagação será usado. Os navigation controllers são responsáveis por decidir oq ue fazer nos eventos de carregamento, erro e sucesso de uma tela, se não informado, o controlador padrão é usado. Para saber mais sobre navigation controllers, leia [este artigo]({{< ref path="/web/commons/navigation/navigation-controllers" lang="pt" >}}). +### controllerId + +O segundo parâmetro aceito pelo `BeagleRemoteView` é opcional e define qual controle de nevagação será usado. Os ``navigation controllers`` são responsáveis por decidir o que fazer nos eventos de carregamento, erro e sucesso de uma tela, se não informado, o controlador padrão é utilizado. Para saber mais sobre ``navigation controllers``, leia [este artigo]({{< ref path="/web/commons/navigation/navigation-controllers" lang="pt" >}}). diff --git a/content/pt/web/commons/navigation/navigation-controllers.md b/content/pt/web/commons/navigation/navigation-controllers.md index c44c05b5e..8ca0b35a4 100644 --- a/content/pt/web/commons/navigation/navigation-controllers.md +++ b/content/pt/web/commons/navigation/navigation-controllers.md @@ -1,49 +1,63 @@ --- -title: Navigation controllers -weight: 3 +title: Controladores de navegação +wight: 3 description: >- - In this section, you will find information on how to control the navigation feedback. + Nesta seção, você encontrará informações sobre os controladores de navegação (Navigation Controllers) e como lidar com o feedback de navegação. --- --- {{% alert color="warning" %}} -Attention: If you just wanna change the loading and error components, read [this article]({{< ref path="/web/commons/navigation/loading-error-components" lang="pt" >}}) instead. +Atenção: Se você precisa apenas alterar os componentes de loading e error, leia [este artigo]({{< ref path="/web/commons/navigation/loading-error-components" lang="pt" >}}) . {{% /alert %}} -# Introduction -The navigation controllers are responsible for implementing the behavior of the loading, error and success events of the navigation between Beagle pages. +## O que é isso? -If not set, Beagle will use the `DefaultNavigationController`, which implements the following behavior: +Os controladores de navegação são responsáveis ​​por implementar o comportamento de carregamento da tela, erros e eventos de sucesso, a partir da navegação entre as páginas do Beagle. -- **onLoading**: render a Beagle UI tree with a single component called `custom:loading`. -- **onError**: render a Beagle UI tree with a single component called `custom:error`. -- **onSuccess**: render a Beagle UI tree with the UI tree returned from the backend. +Se você não definir um controlador de navegação personalizado, o Beagle usará um `Default NavigationController`, que implementa o seguinte comportamento: -This behavior can be customized by implementing your own NavigationController. You can have multiple navigation controllers in a single application, one for each section, for instance. Beagle, from the backend, can tell which NavigationController must be used for the next set of screens. +- **onLoading**: renderiza uma árvore de UI do Beagle com um único componente chamado `custom:loading`. +- **onError**: renderiza uma árvore de interface do usuário do Beagle com um único componente chamado `custom:error`. +- **onSuccess**: renderiza uma árvore de IU do Beagle com a árvore de IU retornada do back-end. -When navigating to a new Stack (PushStack, ResetStack or ResetApplication), the backend can provide a controllerId to the navigation action and Beagle uses this id to find the corresponding NavigationController in the front-end. We can have an entire stack that has a totally different loading feedback, for example. +{{% alert color="success" %}} +Todos esses comportamentos podem ser personalizados implementando um `NavigationController` customizado. Você pode ter vários controladores de navegação em um único aplicativo, um para cada seção, se desejar. O framework Beagle presente em seu Frontend consegue definir qual `NavigationController` deve ser chamado para cada conjunto de telas que vem de um Backend, usando uma propriedade chamada `controllerId` +{{% /alert %}} + +Ao navegar para um novo Stack (usando, por exemplo, ações como PushStack, ResetStack ou ResetApplication), o backend pode fornecer um `controllerId` para a ação de navegação que está sendo acionada (você só listará uma Id se quiser usar um controlador de navegação personalizado (`custom NavigationController`)). + +O Beagle usará este id para encontrar o `NavigationController` correspondente no Front end de sua aplicação. Dessa forma, você poderá ter uma pilha inteira de telas com um feedback de carregamento diferente. + +## Como usá-lo? + +A seguir listamos a interface do NavigationController -# The NavigationController interface +### onLoading -## onLoading -Called whenever Beagle is loading a new view. It receives the following object as a parameter: +Chamada quando o Beagle carrega uma nova visualização. Ela recebe o seguinte objeto como parâmetro: -- `view: BeagleView`: the [BeagleView]({{< ref path="/web/commons/advanced-topics/the-beagle-view" lang="pt" >}}) that renders this server driven UI. -- `completeNavigation: () => void`: a function to complete the navigation, i.e. to finally push the new page to the navigator with the `BeagleWidget`. You need to call it as soon as you want to render a Beagle JSON. For instance, if your loading feedback is to render a beagle component, you must call completeNavigation from within the `onLoading` method. If you'll render a Beagle UI only in the success event, you don't need to ever call `completeNavigation` because it gets automatically called after `onSuccess`. +- `view: BeagleView`: o [BeagleView]({{< ref path="/web/commons/advanced-topics/the-beagle-view" lang="pt" >}}) que renderiza essa IU orientada a servidor. +- `completeNavigation: () => void`: uma função para completar a navegação, ou seja, para finalmente enviar a nova página para o navegador com o `BeagleWidget`. Você precisa chamá-lo assim que quiser renderizar um Beagle JSON. Por exemplo, se seu feedback de carregamento é para renderizar um componente beagle, você deve chamar completeNavigation de dentro do método `onLoading`. Se você renderizar uma interface do usuário do Beagle apenas no evento de sucesso, não precisará chamar `completeNavigation` porque ele é chamado automaticamente após `onSuccess`. -## onError -Called whenever an error happens while loading a new view. It receives the same parameters as the `onLoading` method plus: +### onError -- `error: any`: the error thrown while making the request or processing the response. -- `retry: () => Promise`: a function that, when called, tries to fetch the view again. +Chamada quando ocorre um erro ao carregar uma nova visualização. Ela recebe os mesmos parâmetros que o método `onLoading` mais: -## onSuccess -Called whenever a view is successfully loaded. To render the view, this method must call `beagleView.getRenderer().doFullRenderer(screen)`. This renders the server driven screen to the current `BeagleView`. With the exception of `completeNavigation`, which will be called anyway by Beagle, the `onSuccess` method accepts the same parameters as the `onLoading` plus: +- `error: any`: o erro gerado ao fazer a solicitação ou processar a resposta. +- `retry: () => Promise`: uma função que, quando chamada, tenta buscar a visão novamente. -- `screen: BeagleUIElement`: the server driven view recovered from the [ViewClient]({{< ref path="/web/commons/view-client" lang="en" >}}). +### onSuccess -# Example +Chamado sempre que uma visualização é carregada com sucesso. Para renderizar esta visualização, o método deve chamar `beagleView.getRenderer().doFullRenderer(screen)`. Essa funcionalidade renderiza a tela orientada pelo servidor para o `BeagleView` atual. O método `onSuccess` aceita os mesmos parâmetros que o `onLoading` mais: + +- `screen: BeagleUIElement`: a visão orientada pelo servidor recuperada do [ViewClient]({{< ref path="/web/commons/view-client" lang="pt" >}}). + +{{% alert color="success" %}} +`completeNavigation` é a única exceção aqui, pois será chamado de qualquer maneira pelo Beagle +{{% /alert %}} + +## Exemplo ```typescript import { NavigationController } '@zup-it/beagle-web' @@ -58,19 +72,33 @@ const inYourFace: NavigationController = { } ``` -This is a terrible navigation controller with the sole purpose of demonstrating the feature. It shows a dialog every time a page starts loading. If an error happens, it shows an error dialog, which offers an option to retry. When the page is successfully loaded, it renders the page. +Este é um controlador de navegação simples com o único objetivo de demonstrar esse recurso. + +- Mostra uma caixa de diálogo sempre que uma página começa a carregar. Se ocorrer um erro. +- mostra uma caixa de diálogo de erro, que oferece a opção de tentar novamente. +- Quando a página é carregada com sucesso, ela renderiza a página. -The only non-intuitive parameter of the functions in a NavigationController is the `completeNavigation`. You can ignore this if you don't intend to show a Beagle UI before the success event. By default, i.e., if you don't call `completeNavigation`, the navigation with the Beagle structure of the new view will only happen after the success event. But, some navigation controllers, like the default one, uses the Beagle Structure to render the feedback. The DefaultNavigationController renders the Beagle component `custom:loading` whenever a loading event happens and because of this, it needs to call `completeNavigation` right on the method `onLoading`, so Beagle can properly render the component. +O único parâmetro não intuitivo no NavigationController é o `completeNavigation`. -# Registering the navigation controllers -To provide all navigation controllers that can be used by the backend, you must create a map where the keys are the controller ids and the values are instances of `NavigationController`. +{{% alert color="success" %}} +Você pode ignorar isso se não pretender mostrar uma IU do Beagle antes do evento de sucesso. +{{% /alert %}} + +Por padrão, se você não chamar a função `completeNavigation`, a navegação ocorrerá após o evento de sucesso. Mas, os controladores de navegação, como o padrão, usam a Estrutura Beagle para renderizar o feedback. + +O `Default NavigationController` renderiza o componente `custom:loading` Beagle sempre que um evento de carregamento acontece e é por isso que ele precisa chamar a função `completeNavigation` dentro do método `onLoading`. Dessa forma, o Beagle pode renderizar corretamente o componente. + +## Registrando os controladores de navegação + +1. Você deve criar um mapa para lidar com todos os `controladores de navegação` que podem ser usados ​​pelo backend, onde as chaves são os *IDs do controlador* e os valores são instâncias de `NavigationController`. -To tell Beagle what NavigationController is the default, you need to set the property `defaultNavigationController`. The default navigation controller is used whenever no controllerId is provided or whenever no controller corresponding to the provided id is found. +2. Neste mapa você pode também definir um outro navegador que queira que seja usado como padrão. Para tal basta a propriedade `defaultNavigationController`. O controlador de navegação padrão é usado sempre que nenhum ``controllerId`` for fornecido ou sempre que nenhum controlador correspondente ao id fornecido for encontrado. -Suppose you have three navigation controllers: `inYourFace`, `secured` and `public`. `inYourFace` is the default, while `secured` and `public` are used in specific sections of the app and are referenced via the controllerId, from the backend. The configuration would be as following: +Se você tiver três controladores de navegação: `inYourFace`, `secured` e `public`. `inYourFace` é o padrão, enquanto `secured` e `public` serão usados ​​em seções específicas do aplicativo e referenciados via controllerIds, definidos em sua tela no backend. A configuração ficaria da seguinte forma: {{< tabs >}} {{% tab name="Angular" %}} + ```typescript @BeagleModule({ defaultNavigationController: inYourFace, @@ -84,10 +112,13 @@ createBeagleUIService({ navigationControllers: { secured, public }, // ... }) + ``` + {{% /tab %}} {{% tab name="React" %}} + ```typescript createBeagleUIService({ defaultNavigationController: inYourFace, @@ -95,5 +126,6 @@ createBeagleUIService({ // ... }) ``` + {{% /tab %}} -{{< /tabs >}} \ No newline at end of file +{{< /tabs >}} diff --git a/content/pt/web/commons/view-client.md b/content/pt/web/commons/view-client.md index 48a52efb1..6d6ee0221 100644 --- a/content/pt/web/commons/view-client.md +++ b/content/pt/web/commons/view-client.md @@ -1,24 +1,28 @@ --- -title: View client +title: View Client weight: 3 description: >- - In this section, you will find information on how to setup a ViewClient in Beagle Web. + Nesta seção, você encontrará informações sobre como configurar um ViewClient no Beagle Web. --- --- -# Introduction -Similar to the HttpClient, but more specific. While the HttpClient is responsible for managing every request (views, json data, images, etc), the ViewClient is only responsible for fetching views, i.e. server driven pages. +## O que é isso? -The ViewClient creates the BeagleRequest that is sent to the HttpClient. The default implementation does two things: -1. creates the BeagleRequest according to what has been requested by its caller (normally, the navigator); -2. when the response arrives from the HttpClient, it checks for navigation actions where `preFetch` is `true` and, asynchronously, pre-fetches their results. +O `View Client` é muito semelhante ao HttpClient. Enquanto o HttpClient é responsável por gerenciar todas as requisições (views, dados json, imagens, etc), o ``ViewClient`` é responsável apenas por buscar *views*, ou seja, Páginas Server Driven. -It does nothing other than this, and this might be enough for most applications. But some applications may need extra behavior when fetching views, and this is the place where it should be implemented. +O ``ViewClient`` cria um ``BeagleRequest`` que é enviado ao HttpClient. A implementação padrão do view client faz duas ações: -# Creating a new ViewClient +1. Cria o ``BeagleRequest`` de acordo com o que foi solicitado de quem o requisitou (geralmente o navegador); +2. Quando a resposta chega do HttpClient, ele verifica se a propriedade de navegação `preFetch` tem o valor igual a ``true`` e, *de ​​forma assíncrona*, faz uma busca prévia de seus resultados. -A good example is caching. Let's say we want to locally store a view so when Beagle calls `viewClient.fetch` again, it returns the cached result instead of calling the hHttpClient. To do this, we can implement a new ViewClient that has storage and implements `fetch` as follows: +Ele não faz nada além disso, e geralmente é o suficiente para a maioria das aplicações. Mas, alguns sistemas podem precisar de um comportamento extra ao buscar as novas `views`, e este é o lugar onde ele deve ser customizado. + +## Como usá-lo? + +### Criando um novo ViewClient + +Um bom exemplo é o cache. Digamos que queremos armazenar uma ``view`` localmente para quando o Beagle chamar `viewClient.fetch` novamente, ele retorne o resultado em cache ao invés de chamar o HttpClient. Para fazer isso, podemos implementar um novo ``ViewClient`` que possui um armazenamento e implementa `fetch` da seguinte forma: ```typescript import { ViewClient } from '@zup-it/beagle-web' @@ -43,13 +47,15 @@ function createMyViewClient(): ViewClient { } ``` -Above we implemented a very simple logic that will store every fetch result into the disk using the localStorage. This is a very dumb implementation, because this cache would never expire, but the objective here is just to show how such feature could be implemented using the ViewClient. +Implementamos uma lógica acima que armazenará cada resultado de busca no disco usando o *localStorage*. Esta é uma implementação simples e apenas *para teste*, pois esse cache nunca expiraria. + +### Registrando o novo ViewClient -# Registering the new ViewClient -After creating your custom ViewClient, you just need to pass it to your BeagleService instance: +Depois de criar seu ``ViewClient`` personalizado acima, você precisa passá-lo para sua instância do ``BeagleService``: {{< tabs >}} {{% tab name="Angular" %}} + ```typescript @BeagleModule({ viewClient: createMyViewClient(), @@ -63,14 +69,17 @@ createBeagleUIService({ // ... }) ``` + {{% /tab %}} {{% tab name="React" %}} + ```typescript createBeagleUIService({ viewClient: createMyViewClient(), // ... }) ``` + {{% /tab %}} {{< /tabs >}}