BookmarkSubscribeRSS Feed

An approach to SAS Portal in Viya : Adding an application bar and authenticating

Started ‎06-14-2022 by
Modified ‎09-30-2022 by
Views 2,666

At this stage of the series, you have seen how to display reports and report objects in the portal and how to navigate in the SAS Content to select the report you want to see. If you followed along, you might have noticed that for every SAS object in the portal, the web application displays a login button. In this article, we will discover how we can add an application bar at the top and handle authentication from a single button. Other articles in the series are:

 

Upgrade the SAS Components

 

Even though our web application is already built and has good functionality we should consider updating the SAS components and refactor the application to be more modular.

 

Why is it important to upgrade your SAS components?

 

The first reason is that SAS Viya has a monthly release cycle. This means that the components in the stable release are updated every month. This also applies to the SAS SDKs. The second reason is that in the last release, Stable 2021.2.5 or LTS 2022.1, a new component has been added: sas-auth-browser. This new component can be used for authentication and ease the development of authentication in web applications which are based on SAS SDKs. For this article, we will start where we stopped from the previous article. If you want to start from this article, you can download the code from here. If you want to learn more about each component, I recommend starting with the introduction.

 

Let's start with the upgrade process.

 

For this web application, the components are installed using npm packages and the information about the package versions is stored in the package.json file in the project folder. Open the project in Visual Studio Code and open the folder containing the web application. In the root folder, open the package.json file. You should find two lines for the @sassoftware in the dependencies section.

 

xab1_Portal_Authenticate_oldVersions.png

Select any image to see a larger version.
Mobile users: To view the images, select the "Full" version at the bottom of the page.

 

 

 

 

You can update the versions of the components to versions highlighted here:

 

 

xab2_Portal_Authenticate_newVersions.png

 

 

As you may have noticed it, there is a third component: sas-auth-browser. This is the component we will use for the authentication.

 

When done with the edits, save the file and execute the following command to update the different packages: npm install

 

There is something you need to remember about the content-sdk and the sas-report-components packages installed through npm. In order to use their content in the application, we need to copy the content located under node_modules as indicated on the installation instructions (SAS Content SDK and SAS Visual Analytics SDK). Don't forget that step when you upgrade the packages. For the sas-auth-browser, it is a bit different as we can import it directly in our code using ES6 imports.

 

 

Refactor the application

 

Refactoring an application is the process of reviewing the code you have and adapt the code to clean it, make it more readable and improve it where possible.

 

The application I’ve built already has a few components and it will be good to refactor the application to move the drawers in their own components. This will be useful as we add more components because it will reduce the size of the App.js file and make it more readable. With that in mind, here are the tasks we will perform:

 

  1. Import vaInfo variable from a file and not directly in the App.js file
  2. Rename the CenterContext to LayoutContext to provide a more general usage
  3. Create a specific component for the Navigation content
  4. Create a specific component for the drawer on the right
  5. Adapt the App.js file to use the new components
  6. Adapt the CenterContent.js file to use the context
  7. Adapt the App.css to improve the layout

 

 

Task1: Import vaInfo variable from a file and not directly in the App.js file

 

The vaInfo variable stores the information about the Visual Analytics environment. This information might be consumed by different components and is not subject to change.

 

  • Open App.js
  • Remove the vaInfo variable assignment
  • Create a new file under src folder and name it: constants.js
  • Open the constants.js file
  • Insert following code:

 

export const vaInfo = { url: "https://live.stable.gel.race.sas.com" }

 

  • Save the file
  • Open App.js
  • Add the following line at the top of the file:

 

import { vaInfo } from "./constants"

 

  • Save App.js

Task 2: Rename the CenterContext to LayoutContext to provide a more general usage

 

The CenterContext is used to pass information between components of the application and it does a bit more than handling the center component of the application. To make it clearer to people reading the code, we will rename it to LayoutContext. You can use the search functionality of VSCode to achieve this:

 

 

 

xab3_Portal_Authenticate_replaceAllContext.png

 

 

When done, we need also to rename the CenterContext.js file located under contexts folder to LayoutContext.js. 

 

When done, save all the files which were updated.

 

Start the application and validate that everything still works.

 

Task 3: Create a specific component for the Navigation content

 

Our application at this point has three areas:

 

  • a drawer on the left which displays the SAS Content
  • a center piece to display the report
  • a drawer on the right which displays the KPIs

 

We have defined all these components in the App.js file which is not ideal for readability or debugging.  This is the reason why we will move the drawers in their specific components. Let's start with the Navigation content!

 

  • Under src/components folder create a new file named: ContentDrawer.js
  • Define the following code:xab4_Portal_Authenticate_createContentDrawer.png

     

  • Save the file

 

Task 4: Create a specific component for the drawer on the right

 

As we have created a component for the left drawer, we need to create one on the right.

 

  • Under src/components folder create a new file named: RightDrawer.js
  • Define the following code:

xab5_Portal_Authenticate_createRightDrawer.png

 

 

  • Save the file

 

Task 5: Adapt the App.js file to use the new components

 

Now that we have created the components, it is time to integrate them in the App.js file. As you may have noticed while reading/typing the code of the components, we are passing information through the LayoutContext. We have to define the variables and functions and pass them to the context.

 

  • Make sure that the following import statements are defined:

xab6_Portal_Authenticate_importStatements.png

 

  • Adapt the states assignments to this:

xab7_Portal_Authenticate_defineStates.png

 

  • For the useEffects section, you should have the following code. The first useEffect is unchanged and checks for the SAS Content SDK availability. The second one will be in charge for the resizing of the elements. While refactoring the code, I've improved the function to handle the opening and closing of the two drawers independently. This will be useful later on.

xab8_Portal_Authenticate_defineUseEffects.png

  

  • Remove the handleDrawers function and will be replaced by states
  • Add a new variable which will hold the information which is passed to the LayoutContext. This variable is just for readability.

xab9_Portal_Authenticate_contextValue.png

 

  • Define the returned component

xab10_Portal_Authenticate_defineLayout.png

 

  • Save the file

Task 6: Adapt the CenterContent.js file to use the context

 

The CenterContent component still relies on the URL passed in the props and needs to be adapted to use the different states.

 

  • Adapt the import statements to use the context

xab11_Portal_Authenticate_importStatementsCenter.png

 

  • Define the useState and useContext statements

xab12_Portal_Authenticate_defineStatesCenter.png

 

 

  • In the useEffect, adapt how the sas-report object gets the url from props.url to vaInfo.url
  • Define a new function: handleMaximize. This function will use the variables and the functions passed in the context.

xab13_Portal_Authenticate_defineHandleMaximize.png

 

  • Adapt the header function to use the new handleMaximize function

xab14_Portal_Authenticate_adaptHeader.png

 

 

  • Save the file

 

Task 7: Adapt the App.css to improve the layout

 

The css should not be changed too much but it needs some improvements to better fit the display. Here is the updated css file:

 

xab15_Portal_Authenticate_adaptCSS.png

 

Adding an application bar

 

If you test the application at this stage, you may notice that after maximizing and minimizing the report, the drawer on the left is not displayed. It is expected! Displaying the left drawer will be handled by the application bar that we will add in this section.

 

Defining an application bar is an easy task using MaterialUI and React. The code can be copied from the MaterialUI website (here).

 

  • Create a new file under src/components and name it: SASAppBar.js
  • Paste the code from MaterialUI (the first example here)
  • Change the name of the function to: SASAppBar
  • Change the import statement for the MenuIcon to this:
import AccountTreeIcon from '@mui/icons-material/AccountTree'
  • Change the title from News to My Portal
  • Save the file
  • In App.js, update the return statement to include the SASAppBar.

xab16_Portal_Authenticate_addSASAppBar.png

 

  • Don't forget to add the import statement at the beginning of the file.
import SASAppBar from "./components/SASAppBar"
  • Save the file.
 
To properly display the application bar with the drawers, we need to force the drawers to leave some space for the application bar. There are different techniques to achieve this. Here is one possible option.
 
  • Open the ContentDrawer.js file
  • In the Drawer properties, add the following line:

xab17_Portal_Authenticate_addPaperBoxOption.png

 

  • Save the file
 
Do the same in the RightDrawer.js.  Here is how the application now looks like.

 

xab18_Portal_Authenticate_withAppBar.png

 

If you now click on the tree icon in the application bar, nothing happens. We should remedy to this.

 

  • Open the SASAppBar.js file
  • Add an import statement for useContext
  • Add an import statement for the context
  • Define the useContext
  • Add an onClick property to the IconButton. Clicking on the button should display or hide the ContentDrawer.

 

Here is the updated code:

 

xab19_Portal_Authenticate_addOnClickForLeftDrawer.png

 

 

After saving the file, you should now be able to hide and display the ContentDrawer even if you minimize or maximize the content at the center of the page.

 

Adding authentication

 

We are close to the end of this article. The last piece that we need to setup is the authentication mechanism. The sas-auth-browser is handy to achieve this as it brings the needed components and functions to setup authentication.

 

Using sas-auth-browser, you have two options:

Option 1: Load the code using CDN as described in this example

Option 2: Use the ES6 import statement

 

If you are building a simple web page which requires authentication, the first option is most probably the easiest as there is no need to install packages. Defining the CDN is enough to get the functions to work.

 

If you are building a more advanced web application using React like in this article series, the second option is the best as it ensures that the packages are included in the build process of the application.

 

It's now time to implement authentication! We will be using the second option: use the ES6 import statement. We have already installed the sas-auth-browser package earlier when we updated the application. Here are the steps:

 

  1. Create a Logon component
  2. Add information about whether user is authenticated or not
  3. Adapt what is displayed based on user authentication status
  4. Display the user name in the application bar

 

Task 1: Create a Logon component

 

The first step will be to create a component named: Logon.js. The component should be placed under src/components. The code for this component is:

 

xab20_Portal_Authenticate_logonComponent.png

 

You can see in the code that we are using an instance. The instance is provided by the sas-auth-browser component. In order to use the Logon component, we need to create that instance under a new folder called util under src folder. The name of the file is in our case: credentials.js and the content of the file is:

xab21_Portal_Authenticate_createInstance.png

 

We have now the basic components needed to implement authentication. The SASAppBar component has a Login button. We will replace that button by our Logon component.

 

  • Open SASAppBar.js file
  • Add an import statement for the Logon component
import Logon from './Logon'
  • Delete the import statement for the Button component
  • Replace the Button tag in the return statement by the Logon component

xab22_Portal_Authenticate_addLogonButton.png

  • Save the file

 

Task 2: Add information about whether user is authenticated or not

 

As seen in the last screenshot, we are using the setIsAuthenticated function to set the authentication status in the context. It means that we should define it in the App.js file.

 

  • Open App.js
  • With the other state assignments, add the following line:
const [isAuthenticated, setIsAuthenticated] = useState(false)
  • In the contextValue variable, add the two variables like this:

xab23_Portal_Authenticate_addAuthenticationState.png

 

  • Save the file

 

Task 3: Adapt what is displayed based on user authentication status

 

In our web application, we want to limit content access to only authenticated users. We should therefore adapt the App.js file. To achieve this, we will add a new useEffect. 

 

xab24_Portal_Authenticate_adaptContent.png

 

Note: As we are adding a Typography component, please make sure it is imported. The content which will be displayed is in fact the same as before but this time the user needs to be authenticated. We therefore use the content state and setContent function. Now, we need to adapt the return statement like this:

 

xab25_Portal_Authenticate_adaptReturn.png

 

We can also add another feature in the App.js. When the user hits the refresh button and the session is still active, we want the user to be considered as authenticated. We can therefore create another useEffect which checks if the use is authenticated on the server. Add the following code with the other useEffects.

 

xab26_Portal_Authenticate_checkAuthenticated.png

 

As we are using the instance, we need to import it from the util/credentials file. Like this:

 

import { instance } from "./util/credentials"
 
We can now save the file and check what happens. When loading the page, you should see this:
 
 
xab27_Portal_Authenticate_notAuthenticated.png

 

 
If you click on the LOGIN button, you should see this:
 
xab28_Portal_Authenticate_authenticationPrompt.png

 

 
After entering the user credentials, you should see this:
 

xab29_Portal_Authenticate_authenticated.png

 

 

Task 4: Display the user name in the application bar

 
The application can now use authentication to display content. There is still a functionality that we should add. When the user is authenticated, we should display the user name instead of the Login button.
 
  • Open the SASAppBar.js file
  • Add new states for content and userInfo
const [content, setContent] = useState({})
const [userInfo, setUserInfo] = useState({})
  • Retrieve the isAuthenticated status from the context
const { isAuthenticated, setIsAuthenticated, leftDrawerDisplayed, setLeftDrawerDisplayed } = useContext(LayoutContext)
  • Add a useEffect to retrieve the user information. This function will call a SAS REST API to retrieve information about the user. We are passing the authentication token to the REST endpoint thanks to the credentials option.

xab30_Portal_Authenticate_getUserInfo.png

 

  • Add a useEffect to generate the content to be displayed when user is authenticated or not

xab31_Portal_Authenticate_generateContent.png

 

  • Replace the Logon component by the content variable

xab32_Portal_Authenticate_replaceLogon.png

 

  • Save the file

 

Demo

 

 

 

Conclusion

 

In the previous articles, we have seen how to build a web application using SAS Visual Analytics SDK and SAS Content SDK. With the addition of the sas-auth-browser, we can easily integrate a single authentication mechanism which allows you as a developer to implement the authentication mechanism. We have seen in this article how to update the SAS provided SDKs to introduce the latest functionalities.

 

For the next article in the series, I will show how you can adapt the landing page of the portal and to integrate a chatbot. Check back for the additional articles in the series. The code at the end of this blog is available here.

 

 

Find more articles from SAS Global Enablement and Learning here.

Version history
Last update:
‎09-30-2022 03:35 AM
Updated by:
Contributors

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Free course: Data Literacy Essentials

Data Literacy is for all, even absolute beginners. Jump on board with this free e-learning  and boost your career prospects.

Get Started