Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
feat(table): Added experimental export as CSV functionality.
Browse files Browse the repository at this point in the history
This can be used by providing the `showExportButton` input on the table
component itself.
  • Loading branch information
LucasHocker authored and tomheller committed Dec 20, 2021
1 parent ac5320f commit 9034a8b
Show file tree
Hide file tree
Showing 19 changed files with 719 additions and 13 deletions.
10 changes: 10 additions & 0 deletions apps/demos/src/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ import {
DtExampleTableDynamicColumns,
DtExampleTableEmptyState,
DtExampleTableExpandableRows,
DtExampleTableExport,
DtExampleTableExportSelection,
DtExampleTableFavoriteColumn,
DtExampleTableFavoriteColumnNoHeader,
DtExampleTableInteractiveRows,
Expand Down Expand Up @@ -1101,6 +1103,14 @@ const ROUTES: Routes = [
path: 'table-expandable-rows-example',
component: DtExampleTableExpandableRows,
},
{
path: 'table-export-example',
component: DtExampleTableExport,
},
{
path: 'table-export-selection-example',
component: DtExampleTableExportSelection,
},
{
path: 'table-favorite-column-example',
component: DtExampleTableFavoriteColumn,
Expand Down
8 changes: 8 additions & 0 deletions apps/demos/src/nav-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,14 @@ export const DT_DEMOS_EXAMPLE_NAV_ITEMS = [
name: 'table-expandable-rows-example',
route: '/table-expandable-rows-example',
},
{
name: 'table-export-example',
route: '/table-export-example',
},
{
name: 'table-export-selection-example',
route: '/table-export-selection-example',
},
{
name: 'table-favorite-column-example',
route: '/table-favorite-column-example',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@ describe('DtDrawerTable', () => {
});

it('should show the selected row in drawer', () => {
const lastRow =
fixture.debugElement.nativeElement.querySelector('dt-row:last-child');
const lastRow = fixture.debugElement.nativeElement.querySelector(
'dt-row:last-of-type',
);
lastRow.click();
fixture.detectChanges();
expect(component.drawerTable.isOpen).toBe(true);
Expand Down
36 changes: 31 additions & 5 deletions libs/barista-components/table/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ class MyModule {}
The `DtTable` component supports the following inputs. Find details about the
usage of each input below.

| Name | Type | Default | Description |
| ------------- | -------------------------------------- | ------- | -------------------------------------------------------------------- |
| `dataSource` | `object[] \| Observable \| DataSource` | | Data to be shown in the table. |
| `loading` | `boolean` | `false` | Whether the table is [loading](#loading) or not. |
| `multiExpand` | `boolean` | `false` | Whether the table allows [multiple rows to be expanded]() at a time. |
| Name | Type | Default | Description |
| -------------- | -------------------------------------- | ------- | -------------------------------------------------------------------- |
| `dataSource` | `object[] \| Observable \| DataSource` | | Data to be shown in the table. |
| `loading` | `boolean` | `false` | Whether the table is [loading](#loading) or not. |
| `multiExpand` | `boolean` | `false` | Whether the table allows [multiple rows to be expanded]() at a time. |
| `exportButton` | `boolean` | `false` | Whether the table includes an export button. |

## Simple columns for basic use cases

Expand Down Expand Up @@ -675,3 +676,28 @@ simpleColumn could look like this (example from the `dt-simple-number-column`).
```

<ba-ux-snippet name="table-in-use"></ba-ux-snippet>

## Exporting

### Simple

By setting the `showExportButton` input to `true`, an `dtContextDialog` button
is added just below the table, or in line with pagination if present. This
dialog contains at least 2 buttons:

- **Export table data** which triggers a download of the currently filtered data
as shown, without regard for pagination.
- **Export visible data** which triggers a download of the filtered data from
the datasource and does not use a displayAccessor.

<ba-live-example name="DtExampleTableExport" fullwidth></ba-live-example>

### Selection

If `dtTableSelection` is enabled and you have connected `dtTableSelection` to
`dtTableDataSource` (similar to `dtSort`), you also will have a third button:

- **Export selected rows** which triggers a download of the display data, but
just for selected rows.

<ba-live-example name="DtExampleTableExportSelection" fullwidth></ba-live-example>
24 changes: 24 additions & 0 deletions libs/barista-components/table/src/table-data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
DtSimpleColumnSortAccessorFunction,
} from './simple-columns';
import { DtSort, DtSortEvent } from './sort/sort';
import { DtTableSelection } from './selection/selection';
import { DtTable } from './table';

export type DtSortAccessorFunction<T> = (data: T) => any; // tslint:disable-line:no-any
Expand All @@ -55,6 +56,17 @@ export class DtTableDataSource<T> extends DataSource<T> {
*/
filteredData: T[];

/**
* Data structure to expose exportable data to the table.
*/
exporter: {
filteredData: T[];
selection: DtTableSelection<T> | null;
} = {
filteredData: [],
selection: null,
};

/** @internal DisplayAccessorMap for SimpleColumn displayAccessor functions. */
_displayAccessorMap: Map<string, DtSimpleColumnDisplayAccessorFunction<T>> =
new Map();
Expand Down Expand Up @@ -135,6 +147,16 @@ export class DtTableDataSource<T> extends DataSource<T> {
}
private _sort: DtSort | null;

/**
* Instance of the DtTableSelection directive used by the table to provide selected data.
*/
get selection(): DtTableSelection<T> | null {
return this.exporter.selection;
}
set selection(selection: DtTableSelection<T> | null) {
this.exporter.selection = selection;
}

/**
* Instance of the DtTableSearch directive used by the table to control which
* rows are displayed. Search changes emitted by the DtTableSearch will
Expand Down Expand Up @@ -453,6 +475,8 @@ export class DtTableDataSource<T> extends DataSource<T> {
this._simpleComparatorMap = comparatorMap;
this._updateChangeSubscription();
});
_table._filteredData = this.filteredData;
_table._exporter = this.exporter;
return this._renderData;
}

Expand Down
2 changes: 2 additions & 0 deletions libs/barista-components/table/src/table-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { DtFormattersModule } from '@dynatrace/barista-components/formatters';
import { DtIconModule } from '@dynatrace/barista-components/icon';
import { DtInputModule } from '@dynatrace/barista-components/input';
import { DtCheckboxModule } from '@dynatrace/barista-components/checkbox';
import { DtContextDialogModule } from '@dynatrace/barista-components/context-dialog';

import { DtCell, DtCellDef, DtColumnDef } from './cell';
import {
Expand Down Expand Up @@ -106,6 +107,7 @@ const EXPORTED_DECLARATIONS = [
DtEmptyStateModule,
ReactiveFormsModule,
DtCheckboxModule,
DtContextDialogModule,
],
exports: [...EXPORTED_DECLARATIONS, DtIndicatorModule],
declarations: [...EXPORTED_DECLARATIONS],
Expand Down
25 changes: 24 additions & 1 deletion libs/barista-components/table/src/table.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
<ng-container headerRowOutlet></ng-container>
<ng-container rowOutlet></ng-container>
<ng-container noDataRowOutlet></ng-container>
<dt-context-dialog
*ngIf="showExportButton && !isEmptyDataSource"
aria-label="Show export menu"
ariaLabelClose="Close export menu"
overlayPanelClass="dt-exportMenu"
>
<button dt-button variant="secondary" (click)="_exportDisplayData()">
Export table data
</button>
<button dt-button variant="secondary" (click)="_exportFilteredData()">
Export visible data
</button>
<button
*ngIf="_selectionEnabledAndConnected"
[disabled]="!numSelectedRows"
dt-button
variant="secondary"
(click)="_exportSelection()"
>
Export {{ numSelectedRows }} rows
</button>
</dt-context-dialog>
<ng-container footerRowOutlet></ng-container>

<ng-template #emptyStateTemplate>
<ng-content
*ngIf="!loading"
select="[dtTableEmptyState], dt-empty-state, [dtCustomEmptyState]"
></ng-content>
>
</ng-content>
</ng-template>

<ng-container cdkPortalOutlet></ng-container>
Expand Down
18 changes: 18 additions & 0 deletions libs/barista-components/table/src/table.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,21 @@
.dt-table-search + :host {
margin-top: 8px;
}

.dt-context-dialog {
position: relative;
margin-top: 14px;
margin-bottom: -46px;
display: flex;
justify-content: flex-end;
flex-direction: row;
}

::ng-deep .dt-exportMenu {
display: flex;
flex-direction: column;
}

::ng-deep .dt-exportMenu button {
margin-bottom: 8px;
}
Loading

0 comments on commit 9034a8b

Please sign in to comment.