Reporting and Analytics for Service

Get Involved. Join the Conversation.


    Scott Harwell
    External Data Reports with Browser UI - Analytics Cookbook...
    Topic posted June 19, 2017 by Scott HarwellGold Crown: 30,000+ Points, last edited June 20, 2017 
    1706 Views, 37 Comments
    External Data Reports with Browser UI - Analytics Cookbook Recipe

    External Data Reports with Browser UI

    Expose External Data to OSvC


    Author: Scott Harwell, Principal Product Manager

    Scott Harwell's Image


    Difficulty rating: (Advanced)

    Target persona: Advanced Analytics Users; Developers / Technical Consultants; Systems Integraters


    1. Pre-packaged BUI extension with the following contents: 1) JSON file for data dictionary extensibility, 2) pre-packaged BUI extension with external integration simulation.
    2. Basic reports that demonstrate utilizing external data sources through the data dictionary


    Overall description/purpose: The attached recipe is intended to demonstrate the maturity of BUI extensibility with the power of OSvC analytics to leverage external data tables as if they were native within OSvC.  This allows robust OSvC implementations that can reduce implementation costs and performance issues by limiting the need to synchronize data by offering real-time visibility into other data sets as if it is native in OSvC.

    Use case being served: The attached example is meant to assist a few different personas that contribute to the external data integration use case.  System administrators / report administrators will find value in correlating and displaying data from disparate systems directly in OSvC, such as displaying Sales Cloud data in OSvC to correlate service incidents with sales opportunities.  Technical Consultants will find value in our demonstration of implementing integrations through Browser UI’s extensibility layer.

    Data Diagram: Extending OSvC’s data model with third party data sources is possible both inside and outside a corporate firewall.  This allows organizations to blend data hosted on-premises and in the cloud with a seamless experience for agents.

    Special functionality usage: Our report examples in this solution will be basic, simply showing tabular data sets.  The function of those reports is the important component of these examples in that the reports will be constructed using familiar tools in OSvC, but will pull data from external data sets.

    Minimum Requirements: For this example extension to work, you will need an OSvC site on version 17.2 or newer with Browser UI enabled through AgentServices.

    Extension Configuration Details​

    This recipe simulates connecting OSvC with an external OData endpoint, called TripPin.  This endpoint is a familiar demo for OData REST API development.  While the endpoints for an OData endpoint are simulated in this example to avoid troubleshooting Cross-Origin Request Scripting (CORS) issues, the source could be directed to any OAuth TripPin endpoint and would work.  Remote data endpoints do not require OData; this is just one example of a potential endpoint.

    There are two methods in which data is simulated in this extension: 1) a hard-coded set of data that generates report info from directly in the code, and 2) a set of JSON files that simulate an AJAX request to a remote resource for external data.  We will walk through switching between the hard-coded and simulated calls later in this document.

    This cookbook recipe comes with a zip file that contains a number of different components to enable the external report feature.  The custom extension code is setup for use as it sits.  The following setup process should guide you through the extension configuration to enable the external data for use in OSvC analytics.

    Browser UI extensions are combinations of HTML, CSS, JavaScript, and sometimes TypeScript files that define what the extension does and the business logic in which it operates.  In our extension, there are a few important files to note:

    • /html/index.html – The “Initialization File” for the extension.  This file is responsible for loading the base content for the extension.
    • /scripts/TripPinPackage.json – This file defines the virtual tables for OSvC.  It is the file that establishes the names of the virtual tables, the columns of each table, and the data type that each column represent.
    • /scripts/dataProviders/  - The files in this folder contain the business logic for retrieving the remote data for the virtual data set.  Each provider has custom logic to retrieve and parse data from a remote endpoint.
    • /scripts/models/ - The files in this folder define JavaScript objects that we can map the remote data into for programmatic access to the information once retrieved from the remote endpoint.
    • /scripts/odata/ - The files in this folder represent responses from the TripPin OData endpoint.  The content is the same as if you leveraged the OData endpoint directly.
    • /ext-libs/ - Third-party dependencies that this extension uses.

    Note: The TripPinPackage.json file defines four virtual tables in its schema.  However, only two are leveraged as part of this example extension.

    Before starting the configuration process, unzip the file attached to this post.  Then, create a zip file of the sub-folder called "extension", which contains the folders listed above.

    Extension Setup

    Configuration of Browser UI extensions is managed through the .NET Agent Console.  You will need to login to the agent console to begin configuration.

    Using an account with profile permissions to manage Add-Ins, navigate to Configuration > Site Settings > Add-In Manager.

    In the ribbon, click the “New” icon and select “New Browser UI Extension”.

    A file selection dialog will appear.  Navigate to the zip file provided as part of this cookbook recipe and select it.  The zip file will be uploaded and you will be presented with the contents of the zip file to manage in the Add-In Manager.  Give the extension a name; ensure that there are no spaces in the name as this can have cause an issue with file paths.  Select “Analytics” as the extension type.

    Select “index.html” as the init file and “TripPinPackage.json” as the schema definition.

    In the ribbon, click the “Profile Access” button and assign the extension to the profiles that will have access to the report and the extension.  We recommend testing with one profile first, then adding more when you have confirmed that all is working.

    Click “Save & Close” in the ribbon.  You will need to log out of the agent console and log back in for the data dictionary changes take place.

    When you log back in, navigate to the Analytics Explorer and create a new grid report.  Using the data dictionary, scroll down until you see tables in the “TripPin” package.  The tables in this package are the virtual tables that your extension provides.

    Select the “Trips” table and drag all of the field of the table on the report (order does not matter and you can omit some fields if you desire). Later, we want to connect the “trips” report to the “people” report through report linking; that way, we can deep link into a person’s trips from the person report.  To do so, we want to make sure that there is a filter on the “trips” report that can filter the trips based on username.  Click on the “Home” tab in the ribbon and select the filter editor.  Add a new filter called “Username”.  Set this filter to “selectable at run time” and assign the expression to the following field “TripPin$Trips.Person_Ref_Username”.  Set the “operator” to equals and the “value” field should remain blank.  Click “ok.”

    Then, save the “trips” report.  For organizational purposes, it’s a good idea to create a folder for these example reports as in the screenshot below.

    Create a new grid report for “people”.  In this case, drag all of the columns for the people object onto the report.  We will not need a filter on this report, but we do want to create a report link to the trips report.  Select the “Username” column that you dragged onto the report designer.  In the ribbon, click on the “design” tab.  Click the “Report Linking” button and select “Add Report Link.”  We want to map the “Username” filter that we created on our “trips” report with the “username” field on the “people” report.  Set the “use” column to “Parent Column Value” and the “value” column to “UserName.”  This tells the report link that we want to pass the username from our “people” report as the filter value to the trips report.

    Once you have completed the report linking, then you can save and close the reports.  Now, you will want to put those reports in your Navigation Set so that you can access them in BUI (your profile will need permissions to do this).  In the example below, I have placed the reports in my “Home” section so that I can access them quickly in Browser UI.

    Using the Extension

    Now, switch to your browser and login to OSvC’s Browser UI.  Open your browser’s developer tools so that you can determine any issues with the extension while logging in.  Set your developer tools to show the console before logging in to BUI; once shown, then login to BUI.

    If the extension loaded properly, then you should see a number of messages from the extension that the tables provided by the extension have been loaded.  If you do not see these messages, then the likely cause is that you missed profile permission settings in an earlier step.  If you see error messages, then that typically means an expected file is missing from the extension.

    Next, click the “hamburger menu” and open your people report.

    The extension has been developed with verbose logging to the console; this is something to reduce in a production extension, but excellent for demonstrating data being pulled and set by our custom example extension.  When the report runs, the table should be populated by the code in our personDataProvider.js file.  The code that sets the data is highlighted below, then followed by a screenshot of the report and the console output.

    //Render data built in this file
    if (useLocalData) {
    people.push(new person_1.Person("Gladwin", "Randal", "Male", "grandall"));
    people.push(new person_1.Person("Rodger", "Josephs", "Male", "rjosephs"));
    people.push(new person_1.Person("Louie", "Goffe", "Male", "lg"));
    people.push(new person_1.Person("Neil", "Berry", "Male", "nberry"));
    people.push(new person_1.Person("Kate", "Truman", "Female", "ktru"));
    return new ORACLE_SERVICE_CLOUD.ExtensionPromise((resolve, reject) => {
    let reportDataToRender = PersonDataProvider.processFilters(report, people);
    let reportData = PersonDataProvider.renderReportData(report, reportDataToRender, reportDataToRender.length, reportDataToRender.length, 0);

    When you click on a user name, then the trip report will display; a simple example of linking remote data sets.  Like the people report, the trips report pulls data from a hard-coded set of values.  In this case, it uses the same set of trip information for any username that is selected.  In a real-word application, your trips data provider would make an API call to get the specific trip for the username that you selected in your report.  The code the performs this is highlighted below, and can be explored in the tripsDataProvider.js file.

    static setTripDataFromCodeSource(report, username, trips, resolve, reject) {
    var t1 = new trip_1.Trip("Walley World");
    t1.budget = "$10000.00";
    t1.description = "Trip to Walley World";
    t1.endsat = "05/05/2017";
    t1.startsat = "05/01/2017";
    t1.person_ref_username = username;
    t1.shareid = "";
    t1.tripid = "t1";
    var t2 = new trip_1.Trip("Grand Canyon");
    t2.budget = "$50000.00";
    t2.description = "A really expensive trip to the Grand Canyon.";
    t2.endsat = "08/155/2017";
    t2.startsat = "08/01/2017";
    t2.person_ref_username = username;
    t2.shareid = "55555";
    t2.tripid = "t2";
    let reportDataToRender = TripDataProvider.processFilters(report, trips);
    let reportData = TripDataProvider.renderReportData(report, reportDataToRender, reportDataToRender.length, reportDataToRender.length, 0);

    Now that we have explored the data that is hard-coded in the extension, let’s try to simulate remote data.  First, close the open reports.

    We have baked a flag into the extension that lets us turn this on and off easily.  In your browser’s developer tools, navigate to the “local storage” section.  Within local storage, your BUI site URL should be in the list.  Select your site and then change the “use_data_in_code” value from true to false.

    Once this value is set, switch to the network tab in your developer tools.  This way, you can see the call to the hosted resource for the data that will be displayed in the report.  Open the “people” report again, and this time the data will be retrieved from our virtual OData endpoint.  You will see the person.json file, which represents a remote OData call, fetched from the server and parsed by the extension as report data.

    If you click on “russellwhyte” to open the trips report, then you will also see a remote call to “trips_russellwhyte.json”, which represents an OData collection call for all of the trips for the selected username.


    At this point, we have demonstrated extending BUI analytics with two different remote data sources; our extension’s source code as well as remote OData endpoints.  From those sources, we demonstrated connecting those remote endpoints through related report deep-linking, which allows for agents to leverage the remote data with the same capabilities as native tables in OSvC.

    The remote data sources used in this extension are just two examples for the types of remote data sources that can be used.  The remote data can be data source that is accessible through standard AJAX processes; information is not limited to OData or REST APIs, but rather what the logic in your BUI extension can implement.

    The BUI extensibility framework is already very powerful and can help you implement remote data sources as native analytics citizens as you roll out Browser UI to your organization.

    Included are the following (in a .ZIP file):

    • Source code for analytics report extension in JavaScript and TypeScript
    • XML Report definitions