Skip to content
Open
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
22 changes: 17 additions & 5 deletions apps/docs/src/app/components/stackblitz/stackblitz-writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,34 @@ const TEMPLATE_PATH = 'assets/stackblitz/';
*/
const OPTIONAL_PACKAGE_JSON_DEPENDENCIES = {
'country-flag-icons': {
'country-flag-icons': '^1.6.20'
'country-flag-icons': '^1'
},
'@koobiq/components/markdown': {
marked: '^17.0.3'
marked: '^17'
},
'@koobiq/components/input': {
'@maskito/angular': '^5.0.1',
'@maskito/kit': '^5.0.1'
'@maskito/angular': '^5',
'@maskito/kit': '^5'
},
'@koobiq/components/code-block': {
'highlight.js': '^11.11.1'
'highlight.js': '^11'
},
'@koobiq/ag-grid-angular-theme': {
'@koobiq/ag-grid-angular-theme': '^34',
'ag-grid-angular': '^34',
'ag-grid-community': '^34'
},
// Used by packages/docs-examples/components/ag-grid/ag-grid-export/ag-grid-export-example.ts
jspdf: {
jspdf: '^4'
},
// Used by packages/docs-examples/components/ag-grid/ag-grid-export/ag-grid-export-example.ts
'jspdf-autotable': {
'jspdf-autotable': '^5'
},
// Used by packages/docs-examples/components/ag-grid/ag-grid-export/ag-grid-export-example.ts
xlsx: {
xlsx: '^0.18'
}
} as const;

Expand Down
26 changes: 26 additions & 0 deletions docs/data-grid/ag-grid/ag-grid.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,26 @@ The `kbqAgGridRowActions` directive adds an action panel that appears when hover

<!-- example(ag-grid-row-actions) -->

### Row grouping

The `kbqAgGridRowGroup` directive implements client-side row grouping. Attach it to `ag-grid-angular`, supply raw data via `[kbqAgGridRowGroupRowData]` instead of `[rowData]`, and set the grouped columns via `[(kbqAgGridRowGroupCols)]`.

Collapsed/expanded group state and row selection can each be persisted independently by setting `kbqAgGridRowGroupCollapsedState` and `kbqAgGridRowGroupSelectionState` to a unique key, connecting store providers via `kbqAgGridRowGroupCollapsedStateStoreProvider` and `kbqAgGridRowGroupSelectionStateStoreProvider`.

<!-- example(ag-grid-row-group) -->

### Copying selected rows

The `kbqAgGridCopyByCtrlC` directive allows you to copy selected rows to the clipboard using the `Ctrl+C` keyboard shortcut.

<!-- example(ag-grid-copy-selected) -->

### Export

The grid's own API can be used to export the currently displayed data (respecting active filters, sorting, and formatters). `api.exportDataAsCsv()` downloads a CSV file with no additional dependencies. Other formats can be built on top of the grid's cell values using third-party libraries — for example, XLSX via [`xlsx`](https://www.npmjs.com/package/xlsx), and PDF via [`jspdf`](https://www.npmjs.com/package/jspdf) with [`jspdf-autotable`](https://www.npmjs.com/package/jspdf-autotable).

<!-- example(ag-grid-export) -->

### Status bar

The `kbqAgGridStatusBar` directive adds a customizable panel below the table.
Expand Down Expand Up @@ -96,6 +110,18 @@ The `kbqAgGridExternalFilterState` directive saves the external filter value. Ad

<!-- example(ag-grid-external-filter-state) -->

#### Rows

The `kbqAgGridRowSelectionState` directive saves row selection. Add it with a unique key, connect the store provider via `kbqAgGridRowSelectionStateStoreProvider`, and set `getRowId`.

<!-- example(ag-grid-row-selection-state) -->

#### Focus

The `kbqAgGridRowFocusState` directive saves the focused cell. Add it with a unique key, connect the store provider via `kbqAgGridRowFocusStateStoreProvider`, and set `getRowId`.

<!-- example(ag-grid-row-focus-state) -->

### Column menu

The `kbqAgGridColumnMenu` directive adds a button in the top-right corner of the grid that opens a column management menu. The menu allows showing and hiding columns, reordering them via drag-and-drop, pinning them to the left or right, and searching for a column by name. The reset button restores columns to their initial state.
Expand Down
26 changes: 26 additions & 0 deletions docs/data-grid/ag-grid/ag-grid.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,26 @@ import { AgGridModule } from 'ag-grid-angular';

<!-- example(ag-grid-row-actions) -->

### Группировка строк

Директива `kbqAgGridRowGroup` реализует группировку строк на стороне клиента. Подключите её к `ag-grid-angular`, передайте исходные данные через `[kbqAgGridRowGroupRowData]` вместо `[rowData]` и укажите колонки группировки через `[(kbqAgGridRowGroupCols)]`.

Состояние свёрнутых/развёрнутых групп и выделение строк можно сохранять независимо друг от друга: укажите уникальный ключ в `kbqAgGridRowGroupCollapsedState` и `kbqAgGridRowGroupSelectionState`, подключив провайдеры хранилища через `kbqAgGridRowGroupCollapsedStateStoreProvider` и `kbqAgGridRowGroupSelectionStateStoreProvider`.

<!-- example(ag-grid-row-group) -->

### Копирование выделенных строк

Директива `kbqAgGridCopyByCtrlC` позволяет копировать выделенные строки в буфер обмена при помощи комбинации клавиш `Ctrl+C`.

<!-- example(ag-grid-copy-selected) -->

### Экспорт

Для экспорта отображаемых данных (с учётом активных фильтров, сортировки и форматирования) можно использовать собственный API таблицы. Метод `api.exportDataAsCsv()` позволяет скачать CSV-файл без дополнительных зависимостей. Другие форматы можно получить на основе значений ячеек таблицы с помощью сторонних библиотек — например, XLSX с помощью [`xlsx`](https://www.npmjs.com/package/xlsx), а PDF — с помощью [`jspdf`](https://www.npmjs.com/package/jspdf) и [`jspdf-autotable`](https://www.npmjs.com/package/jspdf-autotable).

<!-- example(ag-grid-export) -->

### Панель статуса

Директива `kbqAgGridStatusBar` добавляет настраиваемую панель под таблицей.
Expand Down Expand Up @@ -96,6 +110,18 @@ import { AgGridModule } from 'ag-grid-angular';

<!-- example(ag-grid-external-filter-state) -->

#### Строки

Директива `kbqAgGridRowSelectionState` сохраняет выделение строк. Добавьте её с уникальным ключом, подключите провайдер хранилища через `kbqAgGridRowSelectionStateStoreProvider` и укажите `getRowId`.

<!-- example(ag-grid-row-selection-state) -->

#### Фокус

Директива `kbqAgGridRowFocusState` сохраняет сфокусированную ячейку. Добавьте её с уникальным ключом, подключите провайдер хранилища через `kbqAgGridRowFocusStateStoreProvider` и укажите `getRowId`.

<!-- example(ag-grid-row-focus-state) -->

### Меню колонок

Директива `kbqAgGridColumnMenu` добавляет в правый верхний угол таблицы кнопку, которая открывает меню управления колонками. В меню можно показывать и скрывать колонки, менять их порядок перетаскиванием, закреплять слева или справа и находить колонку по названию. Кнопка сброса возвращает колонки к исходному состоянию.
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"@docsearch/js": "^4.6.3",
"@fontsource/inter": "^5.2.8",
"@fontsource/jetbrains-mono": "^5.2.6",
"@koobiq/ag-grid-angular-theme": "^34.4.0",
"@koobiq/ag-grid-angular-theme": "^34.5.1",
"@koobiq/date-adapter": "^3.5.1",
"@koobiq/date-formatter": "^3.5.1",
"@koobiq/icons": "^11.7.1",
Expand All @@ -39,10 +39,13 @@
"ag-grid-angular": "^34.3.1",
"ag-grid-community": "^34.3.1",
"highlight.js": "^11.11.1",
"jspdf": "^4.2.1",
"jspdf-autotable": "^5.0.8",
"marked": "^17.0.3",
"overlayscrollbars": "2.7.3",
"rxjs": "^7.8.2",
"tslib": "^2.8.1",
"xlsx": "^0.18.5",
"zone.js": "~0.16.2"
},
"devDependencies": {
Expand Down
16 changes: 16 additions & 0 deletions packages/components-dev/ag-grid/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
AgGridColumnMenuExample,
AgGridColumnStateExample,
AgGridCopySelectedExample,
AgGridExportExample,
AgGridExternalFilterStateExample,
AgGridFilterStateExample,
AgGridInfiniteSelectionExample,
Expand All @@ -11,6 +12,9 @@ import {
AgGridQuickFilterStateExample,
AgGridRowActionsExample,
AgGridRowDraggingExample,
AgGridRowFocusStateExample,
AgGridRowGroupExample,
AgGridRowSelectionStateExample,
AgGridSkeletonCellRendererExample,
AgGridStatusBarExample
} from 'packages/docs-examples/components/ag-grid';
Expand All @@ -22,13 +26,17 @@ import { DevThemeToggle } from '../theme-toggle';
AgGridColumnMenuExample,
AgGridOverviewExample,
AgGridRowDraggingExample,
AgGridRowGroupExample,
AgGridCopySelectedExample,
AgGridExportExample,
AgGridStatusBarExample,
AgGridRowActionsExample,
AgGridColumnStateExample,
AgGridFilterStateExample,
AgGridQuickFilterStateExample,
AgGridExternalFilterStateExample,
AgGridRowSelectionStateExample,
AgGridRowFocusStateExample,
AgGridLoadingOverlayExample,
AgGridSkeletonCellRendererExample,
AgGridInfiniteSelectionExample
Expand All @@ -50,12 +58,20 @@ import { DevThemeToggle } from '../theme-toggle';
<hr />
<ag-grid-column-state-example />
<hr />
<ag-grid-row-selection-state-example />
<hr />
<ag-grid-row-focus-state-example />
<hr />
<ag-grid-overview-example />
<hr />
<ag-grid-row-dragging-example />
<hr />
<ag-grid-row-group-example />
<hr />
<ag-grid-copy-selected-example />
<hr />
<ag-grid-export-example />
<hr />
<ag-grid-status-bar-example />
<hr />
<ag-grid-row-actions-example />
Expand Down
1 change: 1 addition & 0 deletions packages/components-dev/ag-grid/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
dev-app {
display: block;
max-width: 608px;
padding: var(--kbq-size-s);
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ export class ExampleGrid {
node.setSelected(true);
}
});
api.setColumnWidths([{ key: 'ag-Grid-SelectionColumn', newWidth: 36 }]);

this.api = api;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ ModuleRegistry.registerModules([AllCommunityModule]);
selector: 'ag-grid-column-state-example',
imports: [AgGridModule, KbqAgGridThemeModule, KbqButtonModule],
template: `
<button type="button" kbq-button (click)="columnState.reset()">Reset state</button>
<button type="button" kbq-button (click)="columnState.reset()">Reset column state</button>
<ag-grid-angular
#columnState="kbqAgGridColumnState"
kbqAgGridTheme
kbqAgGridThemeDisableCellFocusStyles
kbqAgGridColumnState="dev-ag-grid-column-state"
kbqAgGridColumnState="example-ag-grid-column-state"
[alwaysMultiSort]="true"
[rowData]="rowData"
[columnDefs]="columnDefs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,6 @@ export class AgGridCopySelectedExample {
node.setSelected(true);
}
});

api.setColumnWidths([{ key: 'ag-Grid-SelectionColumn', newWidth: 36 }]);
}

protected onCopyDone({ success }: KbqAgGridCopyEvent): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { KbqAgGridThemeModule } from '@koobiq/ag-grid-angular-theme';
import { KbqButtonModule } from '@koobiq/components/button';
import { AgGridModule } from 'ag-grid-angular';
import { AllCommunityModule, ColDef, GridApi, GridReadyEvent, ModuleRegistry } from 'ag-grid-community';
import { jsPDF } from 'jspdf';
import { autoTable } from 'jspdf-autotable';
import { utils, writeFile } from 'xlsx';

ModuleRegistry.registerModules([AllCommunityModule]);

type ExportTable = {
headers: string[];
rows: string[][];
};

/**
* @title AG Grid with CSV, XLSX and PDF export
*/
@Component({
selector: 'ag-grid-export-example',
imports: [AgGridModule, KbqAgGridThemeModule, KbqButtonModule],
template: `
<div class="ag-grid-export-example-actions">
<button type="button" kbq-button (click)="downloadCsv()">Download CSV</button>
<button type="button" kbq-button (click)="downloadXlsx()">Download XLSX</button>
<button type="button" kbq-button (click)="downloadPdf()">Download PDF</button>
</div>

<ag-grid-angular
kbqAgGridTheme
kbqAgGridThemeDisableCellFocusStyles
[alwaysMultiSort]="true"
[rowData]="rowData"
[columnDefs]="columnDefs"
[defaultColDef]="defaultColDef"
[style.height.px]="300"
[style.width.%]="100"
(gridReady)="onGridReady($event)"
/>
`,
styles: `
:host {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--kbq-size-m);
}

.ag-grid-export-example-actions {
display: flex;
gap: var(--kbq-size-m);
}
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AgGridExportExample {
private readonly api = signal<GridApi | null>(null);
private readonly filename = 'example-export';
protected readonly defaultColDef: ColDef = {
sortable: true,
resizable: true,
filter: true,
floatingFilter: true
};
protected readonly columnDefs: ColDef[] = [
{ field: 'column0', headerName: 'Project name', width: 130 },
{ field: 'column1', headerName: 'Column 1', width: 130 },
{ field: 'column2', headerName: 'Column 2', width: 130 },
{ field: 'column3', headerName: 'Column 3', width: 130 },
{ field: 'column4', headerName: 'Column 4', width: 130 }
];
protected readonly rowData = Array.from({ length: 20 }, (_, index) => ({
column0: 'Project name ' + index,
column1: 'Text ' + index,
column2: 'Text ' + index,
column3: 'Text ' + index,
column4: 'Text ' + index
}));

/** Stores the grid API once the grid finishes initializing. */
protected onGridReady({ api }: GridReadyEvent): void {
this.api.set(api);
}

/** Downloads the grid data as a .csv file. */
protected downloadCsv(): void {
this.api()?.exportDataAsCsv({ fileName: `${this.filename}.csv` });
}

/** Downloads the grid data as an .xlsx file. */
protected downloadXlsx(): void {
const table = this.getExportTable();

if (!table) return;

const worksheet = utils.aoa_to_sheet([table.headers, ...table.rows]);
const workbook = utils.book_new();

utils.book_append_sheet(workbook, worksheet, 'Export');
writeFile(workbook, `${this.filename}.xlsx`);
}

/** Downloads the grid data as a .pdf file. */
protected downloadPdf(): void {
const table = this.getExportTable();

if (!table) return;

const pdf = new jsPDF({ orientation: 'landscape' });

autoTable(pdf, { head: [table.headers], body: table.rows, theme: 'plain' });
pdf.save(`${this.filename}.pdf`);
}

/** Reads the currently displayed columns and rows (respecting filter, sort and formatters). */
private getExportTable(): ExportTable | null {
const api = this.api();

if (!api) return null;

const columns = api.getAllDisplayedColumns();
const headers = columns.map((column) => column.getColDef().headerName ?? column.getColId());
const rows: string[][] = [];

api.forEachNodeAfterFilterAndSort((node) => {
if (!node.data) return;

rows.push(
columns.map((column) => api.getCellValue({ rowNode: node, colKey: column, useFormatter: true }) ?? '')
);
});

return { headers, rows };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ ModuleRegistry.registerModules([AllCommunityModule]);
<ag-grid-angular
#externalFilterState="kbqAgGridExternalFilterState"
kbqAgGridTheme
kbqAgGridExternalFilterState="dev-ag-grid-external-filter-state"
kbqAgGridExternalFilterState="example-ag-grid-external-filter-state"
[alwaysMultiSort]="true"
[rowData]="rowData"
[columnDefs]="columnDefs"
Expand Down
Loading