# React Report Builder component

Report builder is powerful reporting module for Peekdata API, consisting of customizable React components.

Key features:

- Introduce comprehensive reporting capabilities into your application in no time
- Your end users can build any report they want
- Create ready to use templates for the most common searches
- Define any filtering and sorting criteria
- Easy way to explore data and learn from it

See [reportbuilder.peekdata.io](http://reportbuilder.peekdata.io/) for live demo.

## Installation and usage

The easiest way to use react-report-builder is to install it from npm and build it into your app using bundler (Webpack, etc.).
Report builder uses [`peekdata-datagateway-api-sdk`](https://www.npmjs.com/package/peekdata-datagateway-api-sdk) as a dependency therefore you must install it as well:

`npm install --save react-report-builder peekdata-datagateway-api-sdk -force`

or

`yarn add react-report-builder peekdata-datagateway-api-sdk`

To use report builder in your project you must also import needed styles in code:

- Report builder own styles: `react-report-builder/lib/main.css`
- [Bootstrap](https://getbootstrap.com/docs/3.4/css/) styles: `bootstrap/dist/css/bootstrap.min.css`
- [React DatePicker](https://github.com/Hacker0x01/react-datepicker/) styles: `react-datepicker/dist/react-datepicker.css`
- [React table](https://github.com/tannerlinsley/react-table/tree/v6) styles: `react-table/react-table.css`

NOTE: all third-party styles are already installed with `react-report-builder` - no need to install them separately.

```tsx
import React from "react";
import { ReportBuilder } from "react-report-builder";
import { PeekdataApi } from "peekdata-datagateway-api-sdk";

import "bootstrap/dist/css/bootstrap.min.css";
import "react-datepicker/dist/react-datepicker.css";
import "react-table/react-table.css";
import "react-report-builder/lib/main.css";

const peekdataApi = new PeekdataApi({
  baseUrl: "https://demo.peekdata.io:8443/datagateway/v1",
  timeout: 60000,
});

export class App extends React.Component {
  render() {
    return <ReportBuilder peekdataApi={peekdataApi} />;
  }
}
```

## Properties

These are the properties for `ReportBuilder` component:

|          Name          | Type        | Default value | Description                                                                                                                                                                                                                                      |
| :--------------------: | :---------- | :------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| peekdataApi (required) | object      |               | Peekdata API object. To understand how to create it read [here](https://peekdata.io/developers/index.html#datagateway-api-sdk).                                                                                                                  |
|      translations      | object      |               | Translations object. All available translations can be seen in `ITranslations` interface.                                                                                                                                                        |
|     reportRequest      | object      |               | This object can be used to prefill report builder form fields. All properties are optional. To understand how to create or modify this object read [here](https://peekdata.io/developers/index.html#datagateway-api-sdk-report-request-options). |
|         loader         | elementType |               | Loader can be changed by passing custom loader component.                                                                                                                                                                                        |
|   showScopesDropdown   | boolean     | true          | Whether the scopes dropdown is shown                                                                                                                                                                                                             |
| showDataModelsDropdown | boolean     | true          | Whether the data models dropdown is shown                                                                                                                                                                                                        |
|   showDimensionsList   | boolean     | true          | Whether the dimensions list is shown                                                                                                                                                                                                             |
|    showMetricsList     | boolean     | true          | Whether the metrics list is shown                                                                                                                                                                                                                |
|      showFilters       | boolean     | true          | Whether the filters component is shown                                                                                                                                                                                                           |
|     showRowsOffset     | boolean     | true          | Whether the rows offset input is shown                                                                                                                                                                                                           |
|     showRowsLimit      | boolean     | true          | Whether the rows limit input is shown                                                                                                                                                                                                            |
|   defaultRowsOffset    | number      | 0             | Sets default rows offset                                                                                                                                                                                                                         |
|    defaultRowsLimit    | number      | 100           | Sets default rows limit                                                                                                                                                                                                                          |
|      maxRowsLimit      | number      | 1000          | Sets max value of rows limit input                                                                                                                                                                                                               |
| showRequestViewButton  | boolean     | true          | Whether the request view button is shown                                                                                                                                                                                                         |
| showResponseViewButton | boolean     | true          | Whether the response view button is shown                                                                                                                                                                                                        |
|      showDataTabs      | boolean     | true          | Whether the tabs section is shown                                                                                                                                                                                                                |
|       showChart        | boolean     | true          | Whether the chart is shown                                                                                                                                                                                                                       |
|     showDataTable      | boolean     | true          | Whether the data table is shown                                                                                                                                                                                                                  |
|       defaultTab       | number      | 0             | Sets index of active tab                                                                                                                                                                                                                         |
|      chartColors       | IRgb[]      | 0             | Custom colors for chart data in rgb format. Example: `[{ r: 10, g: 20, b: 30 }, { r: 50, g: 90, b: 16 }]`                                                                                                                                        |

### Translations

Every label in report builder is translatable. All possible translation can be seen in `ITranslations` interface. Translation object based on this interface can be passed to `ReportBuilder` component `translations` property.

Translation object example:

```javascript
import { ITranslations } from "react-report-builder";
import { ApiErrorCode } from "peekdata-datagateway-api-sdk";

const translations: Partial<ITranslations> = {
  contentTitle: "Report content",
  dataModelDropdownTitle: "Data Source",
  dimensionsListTitle: "Dimensions",
  apiErrors: {
    [ApiErrorCode.DimensionsMetricsNotCompatible]:
      "Dimension/metric combination is not valid",
  },
};
```

### Color scheme

To customize colors in report builder components, you will have to make two changes:

1. Include custom css file
1. Provide `chartColors` property for chart data coloring

First, include the following CSS file and modify color variables in it according to your needs:

<div style="max-height: 600px; overflow-y: auto;">

```css
/* Customize these color variables to make your color scheme */
:root {
  --white: #fff;
  --black: #000;
  --caramel: #f4d2b6;
  --dark-caramel: #db955c;
  --grey-lighter: #fbfbfb;
  --grey-light: #e0e2e6;
  --grey: #aab0bb;
  --grey-dark: #808799;
  --grey-blue-dark: #323d4b;
  --crimson-light: #d71c4e;
  --crimson-dark: #910c2e;
}

/* -------- COMMON --------- */

.rb-title-dark {
  color: var(--grey-blue-dark);
}

.rb-title-dark > span {
  color: var(--grey);
}

.rb-input {
  border-color: var(--grey-dark);
}

.rb-input::placeholder {
  color: var(--grey);
}

.rb-btn-crimson {
  color: var(--caramel) !important;
  background-color: var(--crimson-light);
}

.rb-btn-crimson:focus {
  color: var(--caramel) !important;
  background-color: var(--crimson-light);
}

.rb-btn-crimson:hover,
.rb-btn-crimson:active {
  color: var(--caramel) !important;
  background-color: var(--crimson-dark);
}

.rb-btn-crimson.disabled:focus,
.rb-btn-crimson.disabled:active,
.rb-btn-crimson.disabled:active:hover,
.rb-btn-crimson.disabled:focus:active {
  background-color: var(--crimson-light);
}

.rb-btn-caramel-dashed {
  color: var(--dark-caramel) !important;
  background-color: transparent;
  border-color: var(--dark-caramel);
}

.rb-split-btn .btn {
  background-color: var(--white);
  border-color: var(--crimson-dark);
}

.rb-split-btn .btn:hover,
.rb-split-btn .btn:focus {
  background-color: var(--white);
  border-color: var(--crimson-dark);
}

.rb-split-btn .caret {
  border-top-color: var(--crimson-dark);
}

.rb-split-btn .open .btn {
  background-color: var(--white);
  border-color: var(--crimson-dark);
}

.rb-split-btn .open .btn:hover,
.rb-split-btn .open .btn:focus {
  background-color: var(--white);
  border-color: var(--crimson-dark);
}

.rb-split-btn .open .caret {
  border-bottom-color: var(--crimson-dark);
}

.rb-split-btn .dropdown-menu li:first-child a {
  border-top-color: var(--grey-light);
}

.rb-split-btn .dropdown-menu li a {
  border-color: var(--grey-light);
}

.rb-split-btn .dropdown-menu li a:hover {
  color: var(--crimson-dark);
  background-color: var(--grey-lighter);
}

.rb-btn-group button {
  color: var(--grey-blue-dark);
  background-color: var(--white);
  border-color: var(--grey);
}

.rb-btn-group button:hover {
  color: var(--crimson-dark);
}

.rb-btn-group button:last-child {
  border-right-color: var(--grey);
}

.rb-btn-group .btn-active {
  color: var(--caramel);
  background-color: var(--crimson-light);
  border-color: var(--crimson-light);
}

.rb-btn-group .btn-active:last-child {
  border-right-color: var(--crimson-light);
}

.rb-btn-group .btn-active + button {
  border-left-color: var(--crimson-light);
}

.rb-btn-group .btn-active:hover {
  color: var(--caramel);
}

/* -------- DATE PICKER --------- */

.rb-datepicker .rb-datepicker-icon:hover i {
  color: var(--crimson-dark);
}

/* */
.rb-datepicker .react-datepicker-popper .react-datepicker {
  border-color: var(--grey-blue-dark);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__triangle {
  border-bottom-color: var(--grey-dark);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__triangle::before {
  border-bottom-color: var(--grey-blue-dark);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__navigation:hover {
  background-color: var(--grey-blue-dark);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__navigation.react-datepicker__navigation--previous {
  border-right-color: var(--grey-blue-dark);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__navigation.react-datepicker__navigation--previous::after {
  border-right-color: var(--white);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__navigation.react-datepicker__navigation--next {
  border-left-color: var(--grey-blue-dark);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__navigation.react-datepicker__navigation--next::after {
  border-left-color: var(--white);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__month-container
  .react-datepicker__header {
  background-color: var(--white);
  border-bottom-color: var(--grey-light);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__month-container
  .react-datepicker__header
  .react-datepicker__current-month {
  color: var(--white);
  background-color: var(--grey-dark);
  border-bottom-color: var(--grey-blue-dark);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__month-container
  .react-datepicker__header
  .react-datepicker__day-names
  > div {
  border-top-color: var(--grey-light);
  border-right-color: var(--grey-light);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__month-container
  .react-datepicker__month
  .react-datepicker__week
  > div {
  border-right-color: var(--grey-light);
  border-bottom-color: var(--grey-light);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__month-container
  .react-datepicker__month
  .react-datepicker__week
  > div:hover {
  color: var(--crimson-dark);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__month-container
  .react-datepicker__month
  .react-datepicker__week
  .react-datepicker__day--selected {
  color: var(--crimson-dark);
  background-color: var(--white);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__month-container
  .react-datepicker__month
  .react-datepicker__week
  .react-datepicker__day--outside-month {
  color: var(--grey);
}

.rb-datepicker
  .react-datepicker-popper
  .react-datepicker
  .react-datepicker__month-container
  .react-datepicker__month
  .react-datepicker__week
  .react-datepicker__day--disabled:hover {
  color: var(--grey);
}

/* -------- DROPDOWN LIST --------- */

.rb-dropdown-container {
  color: var(--grey-blue-dark);
}

.rb-dropdown-container.rb-show-list
  > .rb-dropdown-display
  .rb-selection-icon
  > div {
  border-bottom-color: var(--crimson-dark);
}

.rb-dropdown-container > .rb-dropdown-display {
  border-color: var(--crimson-dark);
}

.rb-dropdown-container > .rb-dropdown-display .rb-selection-icon > div {
  border-top-color: var(--crimson-dark);
}

.rb-dropdown-container > .rb-dropdown-list > div {
  background: var(--white);
}

.rb-dropdown-container > .rb-dropdown-list > div > .rb-dropdown-item {
  border-color: var(--grey-light);
}

.rb-dropdown-container
  > .rb-dropdown-list
  > div
  > .rb-dropdown-item:first-child {
  border-top-color: var(--grey-light);
}

.rb-dropdown-container > .rb-dropdown-list > div > .rb-dropdown-item:hover {
  color: var(--crimson-dark);
  background-color: var(--grey-lighter);
}

/* -------- DROPDOWN LIST WITH SEARCH --------- */

.rb-dropdown-with-search-container .rb-dropdown-with-search__control {
  background-color: var(--white);
  border-color: var(--crimson-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__control
  .rb-dropdown-with-search__value-container
  .rb-dropdown-with-search__placeholder {
  color: var(--grey);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__control
  .rb-dropdown-with-search__value-container
  > div {
  color: var(--grey-blue-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__control
  .rb-dropdown-with-search__value-container
  .rb-dropdown-with-search__multi-value {
  background-color: var(--white);
  border-color: var(--grey-light);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__control
  .rb-dropdown-with-search__indicators
  .rb-dropdown-with-search__dropdown-indicator::after {
  border-top-color: var(--crimson-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__control.rb-dropdown-with-search__control--is-disabled
  .rb-dropdown-with-search__placeholder {
  color: var(--grey-blue-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__control--is-focused
  .rb-dropdown-with-search__indicators
  .rb-dropdown-with-search__dropdown-indicator::after {
  border-bottom-color: var(--crimson-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__group
  .rb-dropdown-with-search__group-heading {
  color: var(--grey-blue-dark);
  background-color: var(--grey-light);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__group
  .rb-dropdown-with-search__group-heading
  .rb-dropdown-with-search-group-heading {
  border-bottom-color: var(--grey-blue-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__group
  .rb-dropdown-with-search__group-heading
  .rb-dropdown-with-search-group-heading
  .rb-group-heading-indicator
  > div::after {
  border-top-color: var(--grey-blue-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__group
  .rb-dropdown-with-search__group-heading
  .rb-dropdown-with-search-group-heading
  .rb-group-heading-indicator.is-expanded
  > div::after {
  border-bottom-color: var(--grey-blue-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__option {
  color: var(--grey-blue-dark);
  background-color: var(--white);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__option.rb-dropdown-with-search__option--is-focused {
  color: var(--crimson-dark);
  background-color: var(--grey-lighter);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__option
  .rb-dropdown-with-search-label {
  border-color: var(--grey-light);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__option
  .rb-dropdown-with-search-label
  .rb-tooltip {
  color: var(--caramel);
  background-color: var(--crimson-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__option
  .rb-dropdown-with-search-label
  .rb-tooltip
  > div::before {
  border-bottom-color: var(--crimson-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__option:first-child
  .rb-dropdown-with-search-label {
  border-top-color: var(--grey-light);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__option:last-child
  .rb-tooltip
  > div::after {
  border-top-color: var(--crimson-dark);
}

.rb-dropdown-with-search-container
  .rb-dropdown-with-search__menu
  .rb-dropdown-with-search__menu-list
  .rb-dropdown-with-search__menu-notice {
  color: var(--grey);
  border-color: var(--grey-light);
}

/* -------- RESULT PREVIEWER --------- */

.rb-content-with-copy-container .rb-content-with-copy {
  border-color: var(--grey-light);
}

/* -------- FILTER --------- */

.rb-filter-control {
  border-bottom-color: var(--grey-light);
}

.rb-filter-control .rb-btn-filter-remove {
  border-color: var(--grey-dark);
}

.rb-filter-control .rb-btn-filter-remove:hover > i {
  color: var(--crimson-dark);
}

.rb-filter-control
  .rb-filter-dropdown.rb-filter-multi
  .rb-dropdown-with-search__multi-value,
.rb-filter-control
  .rb-filter-value.rb-filter-multi
  .rb-dropdown-with-search__multi-value {
  background-color: var(--white);
  border-color: var(--grey-light);
}

.rb-filter-control
  .rb-filter-dropdown.rb-filter-multi
  .rb-dropdown-with-search__multi-value
  .rb-dropdown-with-search__multi-value__remove,
.rb-filter-control
  .rb-filter-value.rb-filter-multi
  .rb-dropdown-with-search__multi-value
  .rb-dropdown-with-search__multi-value__remove {
  color: var(--black);
  background-color: var(--white);
}

.rb-filter-control
  .rb-filter-dropdown.rb-filter-multi
  .rb-dropdown-with-search__multi-value
  .rb-dropdown-with-search__multi-value__remove:hover,
.rb-filter-control
  .rb-filter-value.rb-filter-multi
  .rb-dropdown-with-search__multi-value
  .rb-dropdown-with-search__multi-value__remove:hover {
  color: var(--crimson-dark);
}

.rb-filter-control
  .rb-dropdown-container.rb-show-list
  > .rb-dropdown-display
  .rb-selection-icon
  > div {
  border-bottom-color: var(--grey-dark);
}

.rb-filter-control .rb-dropdown-container > .rb-dropdown-display {
  border-color: var(--grey-dark);
}

.rb-filter-control
  .rb-dropdown-container
  > .rb-dropdown-display
  .rb-selection-icon
  > div {
  border-top-color: var(--grey-dark);
}

.rb-filter-control
  .rb-dropdown-with-search-container
  .rb-dropdown-with-search__control {
  border-color: var(--grey-dark);
}

.rb-filter-control
  .rb-dropdown-with-search-container
  .rb-dropdown-with-search__control
  .rb-dropdown-with-search__indicators
  .rb-dropdown-with-search__dropdown-indicator::after {
  border-top-color: var(--grey);
}

.rb-filter-control
  .rb-dropdown-with-search-container
  .rb-dropdown-with-search__control
  .rb-dropdown-with-search__indicators
  .rb-dropdown-with-search__clear-indicator {
  color: var(--grey);
}

.rb-filter-control
  .rb-dropdown-with-search-container
  .rb-dropdown-with-search__control--is-focused
  .rb-dropdown-with-search__indicators
  .rb-dropdown-with-search__dropdown-indicator::after {
  border-bottom-color: var(--grey);
}

/* -------- REPORT OPTIONS --------- */

.rb-report-options {
  border-color: var(--crimson-dark);
}

/* -------- TABLES --------- */

.rb-table .ReactTable .rt-table .rt-thead .rt-tr .rt-th {
  color: var(--white);
  background-color: var(--grey);
  border-left-color: var(--grey-blue-dark);
}

.rb-table .ReactTable .rt-table .rt-thead .rt-tr .rt-th.-sort-desc {
  box-shadow: inset 0 -3px 0 0 var(--grey-blue-dark);
}

.rb-table .ReactTable .rt-table .rt-thead .rt-tr .rt-th.-sort-asc {
  box-shadow: inset 0 3px 0 0 var(--grey-blue-dark);
}

.rb-table .ReactTable .pagination-bottom .-btn {
  color: var(--caramel);
  background-color: var(--crimson-light);
}

.rb-table .ReactTable .pagination-bottom .-btn:hover,
.rb-table .ReactTable .pagination-bottom .-btn:active {
  color: var(--caramel);
  background-color: var(--crimson-dark);
}

.rb-reports-table .rt-tr-group:hover {
  color: var(--crimson-dark);
}

.rb-reports-table .rb-report-actions > div:hover {
  color: var(--grey-blue-dark);
}

/* -------- TABS --------- */

.rb-tabs-control > ul.nav-tabs .rb-tab {
  background-color: var(--grey);
}

.rb-tabs-control > ul.nav-tabs .rb-tab + .rb-tab {
  border-left-color: var(--grey-blue-dark);
}

.rb-tabs-control > ul.nav-tabs .rb-tab.active {
  background-color: var(--grey-blue-dark);
}

.rb-tabs-control > ul.nav-tabs .rb-tab.active:hover {
  background-color: var(--grey-blue-dark);
}

.rb-tabs-control > ul.nav-tabs .rb-tab:hover {
  background-color: var(--grey-dark);
}

.rb-tabs-control > ul.nav-tabs .rb-tab > a {
  color: var(--white);
}

/* -------- REPORT BUILDER --------- */

.rb-report-builder-container
  .rb-report-container
  .rb-report-filters
  .rb-filter-container {
  border-color: var(--crimson-dark);
}

.rb-report-option
  .rb-dropdown-with-search-container
  .rb-dropdown-with-search__control {
  border-color: var(--grey-light);
}

.rb-report-option
  .rb-dropdown-with-search-container
  .rb-dropdown-with-search__control
  .rb-dropdown-with-search__indicators
  .rb-dropdown-with-search__dropdown-indicator::after {
  border-top-color: var(--grey);
}

.rb-report-option
  .rb-dropdown-with-search-container
  .rb-dropdown-with-search__control--is-focused
  .rb-dropdown-with-search__indicators
  .rb-dropdown-with-search__dropdown-indicator::after {
  border-bottom-color: var(--grey);
}

.rb-report-option .rb-btn-close:hover > i,
.rb-report-option .rb-btn-sort:hover > i {
  color: var(--crimson-dark);
}
```

</div>

Second, provide `chartColors` property to `ReportBuilder` component as in the example below:

```javascript
<ReportBuilder
  chartColors={[
    { r: 10, g: 20, b: 30 },
    { r: 50, g: 90, b: 16 },
  ]}
  ...
/>
```

## Example

A working example project can be found [here](https://gitlab.com/peekdata/react-report-builder-example)
