Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 23 additions & 26 deletions sample-application/baselayer/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,33 @@
# Visier Baselayer Sample Application
The `Baselayer` is a sample application that showcases client application interaction with the Visier OAuth 2.0 API without any additional third-party OAuth libraries. It also showcases several API calls to the Visier API built on top of a Next.js application. You must login to your account first.
Baselayer is a Visier sample application that showcases:
* Client application interaction with Visier's OAuth 2.0 client without any third-party OAuth libraries.
* API calls to Visier's public APIs built on top of a Next.js application.

## Technical Summary
This application is built using [React](https://react.dev/) and [Next.js](https://nextjs.org/).
Baselayer is built with [React](https://react.dev/) and [Next.js](https://nextjs.org/). It consists of 4 smaller React components, each showcasing a Visier API. All React components live together in the main React app. The React components use Visier's [Data Model and Data Query API](https://docs.visier.com/developer/apis/data-model-query/data-model-query-api.htm). Next.js routes API calls through `pages/api/execute.js`, which utilizes `axios` to make API calls. Each API call routes through this workflow before returning the data. Each component sets up its own API call within the component itself.

It is built of 4 smaller React components, each of which showcases a Visier Alpine API. All of these live together as part of the main React app.
- Most of the API explores the capabilities of the [Data Model and Data Query API](https://docs.visier.com/developer/apis/data-model-query/data-model-query-api.htm#:~:text=Use%20the%20Data%20Model%20API,in%20Visier%20unless%20otherwise%20specified.)
- We also have built in a data intake widget to showcase the [Data Intake API](https://docs.visier.com/developer/Tutorials/data-file-upload/upload-data-files-solution.htm).
Baselayer also has a data intake widget to showcase Visier's [Direct Data Intake API](https://docs.visier.com/developer/Tutorials/direct-data-intake/send-data-to-visier.htm).

Next.js routes the API calls through the `pages/api/execute.js` which utilizes `axios` in order to make API calls. Each API call is routed through this workflow before returning the data back. Each component also sets up its own API call within the component itself as well.
To use Baselayer, you must authenticate with OAuth 2.0 in Visier.

# Prerequisites
* Register a client application in Visier. For more information, see [Register a Client Application](https://docs.visier.com/developer/Studio/sign-in%20settings/oauth2-setup.htm).
* Obtain the client application's `Client ID` and `Client secret`.
* Set the client application's `Redirect URI` to http://localhost:3000/oauth2/callback. In development mode, Baselayer listens for authorization codes at this URL.
* Retrieve your Visier API key. For more information, see [Generate an API Key](https://docs.visier.com/developer/Studio/solution%20settings/api-key-generate.htm).
* Create Expense Report objects and load data in Visier. For more information, see [Create a Subject to Analyze Expense Report Data](https://docs.visier.com/developer/Tutorials/analytic-model/extend-analytic-model-subject.htm).
* Install `node`.

## Prerequisites
There are a few pre-requisites before Baselayer will work out of the box.
- You must register a client application in Visier and obtain its `Client ID` and `Client Secret`.
- You must have a Visier `API Key`.
- You must have completed the [Extend the Analytic Model: Create a Subject](https://docs.visier.com/developer/Tutorials/analytic-model/extend-analytic-model-subject.htm) tutorial successfully and set up expense report subjects.
- In development mode, the application will listen for authorization codes on http://localhost:3000/oauth2/callback. The registered client application must also have a redirect URI that exactly matches this application.
# Environment
Before you start the application, create a file named `.env.development.local` to define the following variables:
* `VISIER_HOST`: The base URL for API calls; for example, `https://vanity.api.visier.io`.
* `VISIER_APIKEY`: The API key required for all Visier API calls.
* `VISIER_CLIENT_ID`: A Visier-generated unique identifier for the registered OAuth 2.0 client.
* `VISIER_CLIENT_SECRET`: A Visier-generated secret to protect the registered OAuth 2.0 client.

You must also have `node` installed.
## Installation
Run `yarn install` in a command line application of your choice, such as Terminal.

## Client Environment
The application-specific values are provided to the application through an environment file.
Before starting the application, create a file named `.env.development.local` to provide actual values for the following variables:
```sh
VISIER_HOST=https://customer-specific.api.visier.io
VISIER_CLIENT_ID='client-id-from-registration'
VISIER_CLIENT_SECRET='client-secret-from-registration'
VISIER_APIKEY='visier-provided-api-key'
```

## Installation and Running
First install the dependencies by running `yarn install` in your command line application of choice, such as Terminal. Executing `yarn dev` will run the application in development mode. Afterwards, navigate to `localhost:3000` in order to login, authenticate, and begin sending API calls.
## Run the Sample
Execute `yarn dev` to run Baselayer in development mode. Next, navigate to `localhost:3000` to login, authenticate, and begin sending API calls.


2 changes: 1 addition & 1 deletion sample-application/baselayer/pages/api/execute.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default async (req, res) => {
const data = await POST(req);
res.status(200).json(data.data);
} catch (error) {
res.status(500).json({ error: error.toString() }); //Make sure your error is serializable or use error.message
res.status(500).json({ error: error.toString() }); // Make sure your error is serializable or use error.message
}
} else {
// Handle any requests that aren't POST
Expand Down
6 changes: 3 additions & 3 deletions sample-application/baselayer/src/app/data-intake/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ export default function DataIntake() {
return (
<Card style={{ width: '100%' }} className="m-3">
<Card.Body>
<Card.Title>Data Upload (Data Intake API)</Card.Title>
<Card.Title>Data Upload (Direct Data Intake API)</Card.Title>
<Card.Text>
Load data directly into Visier objects. These objects can be delivered as part of Visier Blueprint, locally modified objects, or even completely custom objects.
Please upload expense report data.
In this application, please upload expense report data.
</Card.Text>
<Form>
<Form.Group controlId="apiTransaction">
Expand All @@ -114,4 +114,4 @@ export default function DataIntake() {
</Card.Body>
</Card>
);
}
}
6 changes: 3 additions & 3 deletions sample-application/baselayer/src/app/data-model/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ export default function DataModel() {
return (
<Card style={{ width: '100%' }} className="m-3">
<Card.Body>
<Card.Title>Expense Reports Dimensions (Data Model API)</Card.Title>
<Card.Title>Expense Report Dimensions (Data Model API)</Card.Title>
<Card.Text>
The response will return a list of all expense report dimensions.
The response returns a list of all expense report dimensions.
</Card.Text>
<Form>
<Form.Group controlId="apiTransaction">
Expand Down Expand Up @@ -101,4 +101,4 @@ export default function DataModel() {
</Card.Body>
</Card>
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function DataQuery() {

const formattedData = {
count: count.trim(),
visierTime: visierTime.trim().split(' - ')[0] // Extract the datetime without the ' - [0]' part
visierTime: visierTime.trim().split(' - ')[0] // Extract the datetime without ' - [0]'.
};

setExpenseReportsValue(formattedData);
Expand Down Expand Up @@ -86,7 +86,7 @@ export default function DataQuery() {

const formattedData = {
count: count.trim(),
visierTime: visierTime.trim().split(' - ')[0] // Extract the datetime without the ' - [0]' part
visierTime: visierTime.trim().split(' - ')[0] // Extract the datetime without ' - [0]'.
};

setExpenseReportsCount(formattedData);
Expand Down Expand Up @@ -125,7 +125,7 @@ export default function DataQuery() {
<td>{expenseReportsValue?.count}</td>
</tr>
<tr>
<td>Avg Value of Expense Report</td>
<td>Average Value of Expense Report</td>
<td>{expenseReportsValue?.count / expenseReportsCount?.count}</td>
</tr>
</tbody>
Expand All @@ -134,4 +134,4 @@ export default function DataQuery() {
</Card.Body>
</Card>
);
}
}
6 changes: 3 additions & 3 deletions sample-application/baselayer/src/app/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import React from 'react';
const inter = Inter({ subsets: ['latin'] })

export const metadata = {
title: 'Visier Sample app',
description: 'Public Visier sample application with OAuth and API calls',
title: 'Visier Sample Application',
description: 'Public Visier sample application with OAuth 2.0 and API calls',
}

export default function RootLayout({ children }) {
Expand All @@ -31,4 +31,4 @@ export default function RootLayout({ children }) {
</html>
)
}


27 changes: 14 additions & 13 deletions sample-application/baselayer/src/app/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,22 @@ export default function Home() {
<Container>
<Row className="mb-4">
<Col className="mb-4" sm={6}>
<h2 style={{ "padding": "40px 20px 10px 20px" }}>Expense Report Baselayer Application</h2>
<h4 style={{ "padding": "10px 20px 0 20px" }}>A Sample Application built on Alpine by Visier</h4>
<h2 style={{ "padding": "40px 20px 10px 20px" }}>Visier Baselayer Application</h2>
<h4 style={{ "padding": "10px 20px 0 20px" }}>A sample application built on Alpine by Visier</h4>
<p style={{ "padding": "20px" }}>
This is a sample Next.js application that shows calls to our Data Model, Data Query and Data Intake APIs. It utilizes our OAuth-API flow for authentication.
Please consult the README.md file for how to configure the Visier access using OAuth 2.0.
This is a sample Next.js application that shows calls to Visier's Data Model, Data Query, and Direct Data Intake APIs. It utilizes Visier's OAuth 2.0 authentication flow.
For more information about configuring Visier access with OAuth 2.0, see the README.md.
</p>
</Col>
<Col sm={6}>
<h2 style={{ "padding": "40px 20px 10px 20px" }}>Pre-requisites and Resources</h2>
<h2 style={{ "padding": "40px 20px 10px 20px" }}>Prerequisites</h2>
<p style={{ "padding": "20px" }}>
There are some pre-requisites you need to do before you can get this application API calls working:
Before calling this application's APIs, you need:
<ul>
<li> A Visier tenant. If you don't already have a Visier tenant, join the <a href="https://www.visier.com/platform/advance-access-program/">Alpine Advance Access Program,</a> or sign up for our <a href="https://www.visier.com/sandbox/">Visier free trial.</a></li>
<li><a href="https://docs.visier.com/developer/Studio/sign-in%20settings/oauth2.htm">OAuth 2.0</a> capabilities in your Visier tenant, along with the client ID and API key.</li>
<li> Finished setting up Expense Reports in the <a href="https://docs.visier.com/developer/Tutorials/analytic-model/extend-analytic-model-subject.htm">Extend the Analytic Model: Create a Subject</a> tutorial.</li>
<li>A Visier tenant. If you don't already have a Visier tenant, sign up for the <a href="https://www.visier.com/sandbox/">Visier free trial</a>.</li>
<li>A registered <a href="https://docs.visier.com/developer/Studio/sign-in%20settings/oauth2.htm">OAuth 2.0</a> client in Visier.</li>
<li>A Visier <a href="https://docs.visier.com/developer/Studio/solution%20settings/api-key-generate.htm">API key</a>.</li>
<li><a href="https://docs.visier.com/developer/Tutorials/analytic-model/extend-analytic-model-subject.htm">Expense Report objects and loaded data</a> in Visier.</li>
</ul>
</p>
</Col>
Expand All @@ -79,13 +80,13 @@ export default function Home() {
<>
<Card style={{ width: '40rem' }}>
<Card.Body>
<Card.Title>Visier Application Baselayer</Card.Title>
<Card.Title>Visier Baselayer Application</Card.Title>
<Card.Text>
This is a sample Next.js application that shows the three-legged (authorization_code flow) OAuth authentication with calls to our Data Model, Data Query and Data Intake APIs.
Please consult the README.md file for how to configure the Visier access using OAuth 2.0.
This is a sample Next.js application that shows the three-legged (`authorization_code` grant type) OAuth authentication with calls to Visier's Data Model, Data Query, and Direct Data Intake APIs.
For more information about configuring Visier access with OAuth 2.0, see the README.md.
</Card.Text>
<Alert key="warning" variant="warning">
<b>Note:</b> This is a sample application intended to showcase Visier Alpine APIs and Oauth functionality. For information about acceptable use, see the LICENSE file.
<b>Note:</b> This sample application shows Visier's public APIs and OAuth 2.0 functionality. For information about acceptable use, see the LICENSE file.
</Alert>
<Button variant="primary" onClick={() => router.push("/oauth2/login")}>Login to Visier</Button>
</Card.Body>
Expand Down