Version 7 Upgrade Guide

Version 7 of AdapTable was released in September 2020.

This was a major release (primarily to cater for changes in the new ag-Grid version) and therefore contained some breaking changes.

note

Details of all the changes are listed here - for more detailed information, including code examples, see the relevant documentation for that function.

This Quick Guide Video shows some of the new features in Version 7.0 and this clip explains the fundamental thinking behind the release.

Summary of Main Changes

These are the main updates to AdapTable in Version 7:

ag-Grid Version 23

Version 7 of AdapTable supports ag-Grid Version 23 requiring these changes:

Quick Filter

The floatingFilter property is deprecated in gridOptions - you now have to specify it at column level (or in a default column definition).

Consequently, AdapTable will only show Quick Filter bar if at least one column has this set to true (and activate it only for those columns).

Themes

ag-Grid introduced a new Alpine theme which has necessitated some slight changes to AdapTable theming:

  • If using a dark theme, make sure to specify your theme in your html, on the grid container element

    <body>
    <!-- div for adaptable - always name this 'adaptable'-->
    <div id="adaptable"></div>
    <!-- div for underlying vendor grid - always name this 'grid'
    and add the ag-Grid Theme (here 'alpine dark') -->
    <div id="grid" class="ag-theme-alpine-dark"></div>
    </body>
    tip

    Use either ag-theme-alpine or ag-theme-balham (as they are the only themes with a dark variant)

    note

    AdapTable will detect this theme, and apply the corresponding dark theme.

  • The useVendorFilterFormStyle in Filter Options is only applied (or required) for the 'Balham' theme, as the Alpine theme looks very similar to our default theme

  • The useDefaultVendorGridThemes property in User Interface Options was removed.

Layout Changes

In Version 7 Layouts have had a major conceptual and UI makeover.

The primary changes are:

  • Instead of simply storing the internal layout-related logic of the underlying grid in Layout state, AdapTable will now save all the constitudent part as 'first-class' properties. This means that Layouts can include elements that were not previously possible.

  • All layouts get automatically updated whenever a relevant change made

    caution

    The exception to this rule is when the autoSaveLayouts property in Layout Options is set to true; in this case AdapTable displays a 'Save' button for the user explicitly to click to persist any changes.

  • If no Layouts are provided in Layout Predefined Config a Default Layout will be created by AdapTable using the column settings in GridOptions; this too will be saved automatically as changes are made.

    tip

    Set the createDefaultLayout property to true in Layout Options, for AdapTable to provide a default layout even if other layouts exist.

  • This means that there must always be at least one Layout at any time - AdapTable will prevent the last layout from being deleted.

  • The previous (confusing) multi-step Layout wizard has been replaced by a single Edit Layout screen which allows the User to set column visibility, order sorting, grouping, aggregation and pivoting.

  • The Layout object in AdapTable State has been enhanced to include the ability to set column widths and aggregation properties.

  • The restoreLayout and clearLayout methods in Layout Api have been removed.

Layout Migration

caution

Due to the new way Layouts work, not everything currently persisted in v.6 Layout State will be migrated.

The contents of the initial Layout definition - provided either through Predefined Config or in the Layout creation UI - will be automatically migrated by AdapTable (in versions 7.0.2 and later).

However, any subsequent changes to that Layout as the result of user actions in the grid (e.g. widening or grouping columns) will be lost.

Layout Updated Event

The new LayoutUpdatedEvent is fired by AdapTable whenever a Layout is added, updated or deleted.

It provides details of the current Layout and what triggered the change.

important

This replaces the ColumnStateChangedEvent which has been completely removed.

For more information see Layout Function

New Calculated Column Expression Syntax and UI

Previously Calculated Column Expressions were created using an external library (math.js).

Now AdapTable uses an internally-built parser to create the Expression which bring many advantages and improvements:

  • The Expression is far more powerful than before e.g. by allowing for multiple columns, enabling mixing columns and static values and (coming soon) by allowing users to add their own custom functions.

  • A much more usable UI for creating Expressions has been introduced with drag and drop features, multiple functions, dummy data and provision of help-based information about each of the available functions.

  • Formatting has been decoupled from the Calculated Column Expression (which is just a parsed function) and instead this can be done through the improved Format Column Function - exactly the same way as it is for other columns.

warning

This is a breaking change: the required syntax is similar to the previous version so in most cases existing Calculated Columns will run normally; however this cannot be guaranteed, particularly if some of the more estoric features of math.js or its formatting were being used.

note

One effect of this change is that the download size of AdapTable has been greatly reduced as the math.js folder was the single largest element in the downloaded package.

For more information see Calculated Column Function and Adaptable Expression.

Queries

Version 7 introduces the Query Function. It wraps the very powerful new Expression object introduced by AdapTable, but is constrained only to return a boolean (true/false) value.

caution

The AdvancedSearch function was replaced by Query which will run (and save) any query as a search.

Queries have a number of important features:

  • They can be written by hand as the syntax is very succint and easy to learn

  • Alternatively they can be created by using the Expression Editor - the same as used for Calculated Column (as they both use the same underlying parser).

  • They can be shared (via the SharedQueries property in Query State).

    tip

    This enables the same Query to be the CurrentQuery (for Search), to be used in a report or to form part of a Conditional Style.

Filter

Filtering has had a huge makeover in Version 7 including:

  • A new Filter Function replaces (and merges) the 4 previous filter-relaed functions (System, User, Column and Named).

  • The Filter Dropdown and Quick Filter UI have been heavily updated and are both now fully in sync - so the same Filter can be entered (and be reflected) in each.

  • Both will create a Column Filter. This now contains only a single Predicate (see below for more details) - though that can include the 'IN' predicate to filter on multiple values.

  • Developers can easily provide their own Custom Filters at design-time through a much improved syntax - this replaces the previous Named Filters

  • Wildcards can still be used in the Quick Filter bar (but are now less needed due to the improved UI).

warning

This is a breaking change: the Expression object used previously for Filtering has been replaced.

Unfortunately, due to the almost unlimited possibilities the old Expressions offered it has not been possible to provide an automated upgrade path as has been done for Layouts, Export and other Functions.

Predicates and Scope

2 important new types have been introduced to promote object re-use and provide greater flexibility:

Predicate

A Predicate is a type that returns a boolean value.

tip

At its heart, it incudes a (boolean) handler function that will run each time the predicate is required.

Developers can create their own Predicates at DesignTime via the Custom Predicate Defs property of Adaptable Options.

Each predicate can be used in the following functions:

const adaptableOptions: AdaptableOptions = {
...
customPredicateDefs: [
{
id: 'high_invoice',
label: 'High Invoice',
columnScope: {
ColumnIds: ['OrderId'],
},
functionScope: ['filter', 'conditionalstyle', 'alert', 'cellvalidation'],
handler(params: PredicateDefHandlerParams) {
const invoiced: number = params.node.data.InvoicedCost;
const itemCount: number = params.node.data.ItemCount;
return invoiced > 100 && itemCount > 10 ? true : false;
},
}
],
};

Scope

Scope specifies where an object or function can be applied. It has 3 main values:

  • All (i.e. everywhere)
  • Column(s)
  • DataType(s) - e.g. string, number, date etc

The Scope object has been included in a number of functions including:

This means that it is now possible to create a Conditional Style for all Numeric columns (e.g. Green Font for Positive values) with a single step.

Percent Bar Improvements

Percent Bars have been redesigned with the following changes:

  • They now include either a Range or a Column Comparison

  • A Range is a set of values with an associated colour (e.g. 1 - 50, Blue).

    note

    Multiple Ranges are permitted, allowing, for example, the creation of a traffic light effect (e.g. 1-30: Red, 31-60: Amber, 61-100: Green).

    info

    AdapTable will automatically update any existing Percent Bars; if there are only positive or negative numbers then it will create one range, if there are both then it will create a range for each.

  • A Column Comparison paints the Percent Bar based on the cell value compared to another Column

    tip

    This is very useful if, for example, you want to display the contents of a Fill column compared to a Quantity column elsewhere in the row.

  • New properties have been introduced including (optional) back colour, show column value, show value as percentage and to manage tooltips.

New Partner plugins

The transfer of 'non-core functionality' out of the main package and into Plugins contains in Version 7.

This enables a reduction in the size of the core package and allows users to select just those plugins which meet their requirements.

4 new plugins have been created which contain bespoke functionality for specific AdapTable partners:

In each case any configuration that was previously stored in the relevant partner's section of AdapTable State is now provided through an xxxPluginOptions object injected into the Plugin.

For example to use the ipushpull plugin something like this might be provided:

import ipp from '@adaptabletools/adaptable-plugin-ipushpull';
const adaptableOptions: AdaptableOptions = {
primaryKey: 'tradeId',
userName: 'Demo User',
adaptableId: 'ipushpull Demo',
plugins: [
ipp({
username: process.env.IPUSHPULL_USERNAME,
password: process.env.IPUSHPULL_PASSWORD,
throttleTime: 5000,
includeSystemReports: true,
ippConfig: {
api_url: 'https://www.ipushpull.com/api/1.0',
ws_url: 'https://www.ipushpull.com',
web_url: 'https://www.ipushpull.com',
docs_url: 'https://docs.ipushpull.com',
storage_prefix: 'ipp_local',
transport: 'polling',
hsts: false, // strict cors policy
},
}),
],
predefinedConfig: demoConfig,
vendorGrid: { ...gridOptions, modules: AllEnterpriseModules },
};

Support for Master Detail grids

Version 7 of AdapTable provides support for Master / Detail grids in ag-Grid.

Users are able to create Predefined Config not only for the Master Grid but also for the Detail Grids (there is one Adaptable Options which is shared by all the grids).

This also enables run-time users to create searches, alerts, conditional styles etc that will automatially be shared by all 'Detail' grids.

To use this functionality you need to use the new Master Detail Plugin

React Wrapper Changes

In order to work seamlessly with agGrid 23, the React Wrapper was updated.

Below is a quick summary of the changes - for fuller information see the React Wrapper Read Me

  • The <AgGridReact> component now needs to be rendered explicitly.

  • Although most ag-grid properties can be passed into the component via props, you have to make sure you pass the gridOptions object as a prop to the <AgGridReact> component

    caution

    The same gridOptions object must be passed to the <AdaptableReactAggrid> component

    note

    In this way, both <AdaptableReactAggrid> and <AgGridReact> are guaranteed to be connected to the same agGrid instance.

  • You should also pass any ag-Grid Enterprise modules as an input to the <AgGridReact> component.

    caution

    The same modules object must also be passed into the <AdaptableReactAggrid> component

  • Theming now needs to be set expliclity (and not via a prop to <AdaptableReactAggrid> as before). This will typically be done by wrapping the <AgGridReact> component in a div element with the class set to that of the required ag-Grid theme (e.g. 'ag-theme-apline').

React Wrapper Example

<div
style={{
height: '100vh',
display: 'flex',
flexFlow: 'column',
}}
>
<AdaptableReactAggrid
adaptableOptions={adaptableOptions}
gridOptions={gridOptions}
modules={agGridModules}
onAdaptableReady={({ adaptableApi, vendorGrid}) => { ... }}
>
</AdaptableReactAggrid>
<div className="ag-theme-alpine" style={{ flex: 1 }>
<AgGridReact
gridOptions={gridOptions}
modules={agGridModules}
/>
</div>
</div>

AdapTable Tool Panel Component in React

One consequence of the new ag-Grid version is that if you want to use the AdapTable Tool Panel while using the React Wrapper, it needs to be explicitly imported in your code, e.g.:

import { AdaptableToolPanelAgGridComponent } from '@adaptabletools/adaptable/src/AdaptableComponents';

and then explicitly referenced:

const options: GridOptions = {
....
sideBar: true,
components: {
AdaptableToolPanel: AdaptableToolPanelAgGridComponent,
},
....
}

Deprecated props

  • agGridTheme - no longer supported - see above example for how to specify the ag-Grid theme by adding the corresponding className prop on the 'div' wrapping <AgGridReact />
  • modules - now specify agGrid modules directly on the <AgGridReact /> component.
  • render fn - place the <AdaptableReactAggrid /> and <AgGridReact /> components in your jsx wherever you want - they will be connected

Angular Wrapper Changes

In order to work seamlessly with ag-Grid 23, the Angular Wrapper was also updated.

Below is a quick summary of the changes (for full information see the Angular Wrapper)

  • The <ag-grid-angular> component needs to be provided explicitly.

  • Although most ag-grid properties can be passed into the component via inputs, you have to make sure you pass the "gridOptions" object as an input to the <ag-grid-angular> component. The ag-Grid theme is set via the class property.

    caution

    The same gridOptions object must also be passed into the <adaptable-angular-aggrid> component

    note

    In this way, both <adaptable-angular-aggrid> and <ag-grid-angular> are guaranteed to be connected to the same agGrid instance.

  • You should also pass any ag-Grid Enterprise modules as an input to the <ag-grid-angular> component.

    caution

    The same modules object must also be passed into the <adaptable-angular-aggrid> component

  • The onAdaptableReady input is removed from the <adaptable-angular-aggrid> component; instead this functionality is exposed as an AdaptableReady event.

Angular Wrapper Example

<!-- component.html >
<adaptable-angular-aggrid
[adaptableOptions]="adaptableOptions"
[gridOptions]="gridOptions"
(adaptableReady)="onAdaptableReady($event)"
[modules]="agGridModules"
>
</adaptable-angular-aggrid>
<ag-grid-angular
[gridOptions]="gridOptions"
[modules]="agGridModules"
style="height: 90vh"
class="ag-theme-alpine"
>
</ag-grid-angular>
// component.ts
onAdaptableReady({
adaptableApi,
vendorGrid,
}: {
adaptableApi: AdaptableApi;
vendorGrid: GridOptions;
}) {
adaptableApi.eventApi.on('SelectionChanged', selection => {
console.warn('selection changed', selection);
});
}

AdapTable Tool Panel Component in Angular

One consequence of the new ag-Grid version is that if you want to use the AdapTable Tool Panel while using the Angular Wrapper, it needs to be explicitly imported e.g.:

import { AdaptableToolPanelAgGridComponent } from '@adaptabletools/adaptable/src/AdaptableComponents';

Async Static Constructor

The static constructor used for instantiating AdapTable 'core' (i.e. outside of a Wrapper) has become asynchronous.

It still returns an Adaptable Api object but now does so via a Promise.

So instead of:

const api: AdaptableApi = Adaptable.init(adaptableOptions)

This is now required:

const api: AdaptableApi = await Adaptable.init(adaptableOptions)

Schedule State Consolidation

In previous versions of AdapTable, each Function that had a Schedule persisted details of the Schedule in its own section of Adaptable State (e.g. Export, Reminder, ipushpull etc).

This has been changed, and now there is a dedicated Schedule section of AdapTable State which contains all the Schedules i.e. for Export, Reminder, ipushpull etc.

note

One consequence is that the Reminder section of AdapTable State was removed as it is no longer required.

For more information see the Schedule Function ReadMe

Export and Report Changes

Improvements and additions to Exporting and running reports, including:

  • The 'BespokeColumns' value in ReportColumnScope has been changed to ScopeColumns

    tip

    When this value is selected, the new Scope property in the Report object should be used.

  • CustomReports can now be created. These are reports which are sourced entirely by the users and can contain any column or row data that is required.

    note

    An implementation of CustomReportFunction provided by the user is invoked when the Report is run.

  • Additional report destinations can be selected by using the CustomDestinations property in Export Config.

    note

    When used a CustomExportDestinationFunction implementation must be supplied in User Functions section of Adaptable Options.

Other Changes

A number of small changes have been made to AdapTable State and Adaptable functionaliy other than those listed above. These include:

  • Config Server - which has long been deprecated - has finally been removed. The only way to manage state remotely is via the State Options functions in Adaptable Options.

  • As a result of the Layout improvements, the Column Chooser and Column Category functions have been rendered redundant and have both been removed.

  • As a result of the Filter and Query updates, Quick Search has been reduced in scope. It is a pure 'contains' text search (i.e. it no longer supports wildcards) and only highlights matching cells (it no longer has a filtering option)

  • Another consequence is serverSearchOption in Search Options has been renamed to serverSearchOptions and become an array (which can take 'Query', 'Filter' or 'Sort')

  • Alert, Cell Validation and Conditional Style now require a Predicate and include Scope (see above)

  • The previously deprecated VisibleToolbars property in Dashboard State has been removed.

    caution

    This means that if you do not provide a Tab in your Predefined Config (and our advice is that you should) - AdapTable will create a default Tab called 'Toolbars' using it's default set: 'Query', 'Layout', 'Export', 'Filter'.

  • The showAdaptableToolPanel property in User Interface Options now defaults to true

    tip

    Explicitly set this property to false if you do not want the Adaptable Tool Panel to appear.

  • The --ab-cmp-field-wrap__border-radius css variable has been added to the CSS variables

  • All UI elements now include semantic class names to provide easier custom styling

Reduced Package Size

The size of the AdapTable download has decreased by 30%.

This is caused primarily due to the removal of some big packages (notably math.js and moment.js), but also to better tree-shaking and image management so that only imports actually used in AdapTable are included in the download.