In this tutorial, we’ll explore how to add analytical features, such as reporting and dashboarding to an existing e-commerce web application with Cube.js. We’re going to use Saleor as our e-commerce platform. It is powered by a GraphQL server running on top of Python 3 and a Django 2 framework. Both the storefront and the admin dashboard are React applications written in TypeScript and powered by Apollo GraphQL. We’ll add dashboarding and reporting capabilities to the admin dashboard with the Cube.js.
Installing Saleor
Saleor server and the admin dashboard are located in a single repo , and the storefront is in the separate repo. For the purpose of the tutorial, we need only the server and the admin dashboard. It comes with very good documentation and detailed installation guide, which you can find here. Please follow the instructions on installation and them come back here.
Saleor server and the admin dashboard are located in a single repo here. It comes with very good documentation and detailed installation guide, which you can find here. Please follow the installation instructions and them come back here.
Once, it is installed, let’s populate our store with example products and orders, as well as the admin account. Run the following command in your terminal.
$ python manage.py populatedb --createsuperuser
Next, start the local server.
$ python manage.py runserver
Open http://localhost:8000 in your browser and it will show you your storefront. Since in previous step we loaded some example data, it will show you some categories and products inside. In this tutorial we’re going to work with the admin dashboard, which could be found here http://localhost:8000/dashboard/next. Notice, next in the url - Saleor is updating the admin UI and we’re going to work the latest one. To access admin dashboard enter admin@example.com for email and admin for password.
This how it should look like after you log in.
Installing Cube.js
Now, as we have Saleor up and running we can install Cube.js to start adding analytical features to our e-commerce dashboard. The Cube.js backend is a Node app, which could be run as a separate microservice or in a serverless mode. Let’s create our Cube.js backend instance.
Run the following commands in your terminal
$ npminstall -g cubejs-cli
$ cubejs create saleor-analytics -d postgres
The above commands should create a new Cube.js application. Since we are using Postgres with Saleor we set it as a database type (-d). Cube.js use ‘dotenv’ to manage credentials, so we need to update .env file with our database's credentials.
# Update database credentials in the .env file
CUBEJS_DB_TYPE=postgres
CUBEJS_DB_NAME=saleor
CUBEJS_DB_USER=saleor
The next step is to tell Cube.js how to convert raw data in the database into meaningful analytics insights. This process is sometimes called data modeling. It is a way to translate business level definitions, such as customer lifetime value into SQL. In Cube.js it’s called schema and schema files are located in ‘schema’ folder.
Cube.js CLI generates an example schema file - schema/Orders.js. Change it’s content to the following.
cube(`Orders`,{
sql:`select * from order_order`,
measures:{
count:{
type:`count`
}
},
dimensions:{
created:{
type:`time`,
sql:`created`
}
}
});
Cube.js uses schema to generate a SQL code, which will run in your database and return a result back. A schema is also used to manage pre-aggregations and cache, you can learn more about it here.
That is all we need to start our first analytics server. In the project folder run:
$ npm run dev
It will spin up the development server at http://localhost:4000. If you open it in the browser it’ll show the codesandbox with an example on how to use an API with React.
Now, as we have Cube.js server up and running the next step is to add analytics section to our Saleor admin dashboard.
Add Analytics Section to Saleor Dashboard
We’re going to add analytics section to to the Saleor dashboard. The admin dashboard is a React app written in Typescript, which is located in saleor/static/dashboard-next folder. Within this folder create a new folder - analytics. it is going to contain all our code for analytics sections. First, we’ll add an analytics page, which is going to be a container for all of our charts.
// Create analytics/index.tsx with the following content
import*asReactfrom"react";
importDashboardPagefrom"./views/DashboardPage";
constComponent=()=><DashboardPage/>;
exportdefaultComponent;
// Create analytics/views/DashboardPage.tsx with the following content
That should be enough to render our new blank analytics page at http://localhost:8000/dashboard/next/analytics. You can try to open it in your browser. Next, let’s add Analytics item to the left menu.
First, will add new icon component and then edit AppRoot.tsx to add menu item.
// Create icons/Analytics.tsx with the following content
That’s it! Open admin dashboard in your browser and you should see the new menu item. Now, let’s add some charts to our Analytics Page.
Create First Char
Let’s create a ChartCard React Component in analytics/components/ChartCard.tsx. It will receive a query as an input and will encapsulate getting data from Cube.js API and then rendering the visualization.
We need to install Cube.js javascript client with React wrapper and Bizcharts for visualizations. Bizcharts is easy to use visualization library for React apps based on G2. It comes with pretty nice default styles. Run the following commands in the Saleor root directory:
$ npminstall @cubejs-client/core @cubejs-client/react bizcharts moment numeral --save
Our Cube.js server is running on http://localhost:4000 and API endpoint is located at http://localhost:4000/cubejs-api/v1, so we need to specify it in the apiUrl parameter when initializing Cube.js client instance. It also expects an API key, which you can copy from Cube.js server console output when you start it.
// Create analytics/components/ChartCard.tsx with the following content
First, let’s add support for other visualizations, such as a pie chart. The query to Cube.js will remain the same, we just need to support the pie chart in the renderChart methods. Also, we’ll add support for currency formatting using numeraljs.
// Replace the content of analytics/components/ChartCard.tsx with the following
Now, let’s define more measures and dimensions in the Cube.js schema. Open your Cube.js Service project and edit the Orders.js file in the schema folder.
// Replace the content of schema/Orders.js with the following:
cube(`Orders`,{
sql:`select * from order_order`,
measures:{
count:{
type:`count`
},
totalNet:{
sql:`total_net`,
type:`sum`,
format:`currency`
},
averageValue:{
sql:`total_net`,
type:`avg`,
format:`currency`
}
},
dimensions:{
created:{
sql:`created`,
type:`time`
},
status:{
sql:`status`,
type:`string`
}
}
});
We have added two new measures — total sales and average sales. And one new dimension — status.
Now, let’s define all new queries in the DashboardPage component. We will display the line charts for total orders, total sales, and average order value (per day), and pie chart for the breakdown of order count by status. The default date range is set to last 30 days.
// Replace the content of analytics/views/DashboardPage.tsx with the following
This will give us a fully working dashboard with four basic metrics. In the next tutorial, we’ll show you how to add dashboard filters and a query builder to let users build custom reports.