Skip to content

beta grouping feature #108

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion packages/core/README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# Data Den Core
# Data Den Core
12 changes: 6 additions & 6 deletions packages/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ const options2: DataDenOptions = {
caseSensitive: false,
},
resize: true,
width: 260,
width: 150,
cellRenderer: DataDenDefaultCellRenderer,
},
{
Expand All @@ -220,7 +220,7 @@ const options2: DataDenOptions = {
caseSensitive: false,
},
resize: true,
width: 200,
width: 150,
cellRenderer: DataDenDefaultCellRenderer,
editable: true,
},
Expand All @@ -241,7 +241,7 @@ const options2: DataDenOptions = {
},
},
resize: true,
width: 210,
width: 150,
cellRenderer: DataDenDefaultCellRenderer,
editable: true,
},
Expand All @@ -253,7 +253,7 @@ const options2: DataDenOptions = {
debounceTime: 500,
},
resize: false,
width: 180,
width: 150,
cellRenderer: DataDenDefaultCellRenderer,
editable: true,
},
Expand All @@ -272,7 +272,7 @@ const options2: DataDenOptions = {
caseSensitive: false,
},
resize: true,
width: 220,
width: 150,
cellRenderer: DataDenDefaultCellRenderer,
editable: true,
},
Expand All @@ -291,7 +291,7 @@ const options2: DataDenOptions = {
caseSensitive: false,
},
resize: true,
width: 180,
width: 150,
cellRenderer: DataDenDefaultCellRenderer,
editable: true,
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/data-den-options.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface DataDenColDef {
editable?: boolean | ((...args: any[]) => boolean);
defaultSort?: 'asc' | 'desc' | null;
sortOrder?: ('asc' | 'desc' | null)[];
grouped?: boolean;
}

export interface DataDenDefaultColDef {
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/data-den-pub-sub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export class DataDenPubSub {
'info:fetch:done': [],
'command:pin-column:start': [],
'command:rerendering:done': [],
'command:group-column:start': [],
'command:ungroup-column:start': [],
'command:group:update': []
};

publish(name: string, data: DataDenPublishedEvent) {
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/data-den.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export class DataDen {
if (this.#dataLoaderStrategy) {
this.#fetch = new DataDenFetchService(this.#dataLoaderStrategy, this.PubSub);
}

this.#rendering = new DataDenRenderingService(container, gridOptions, this.PubSub);
this.#sorting = new DataDenSortingService(gridOptions, this.PubSub);
this.#filtering = new DataDenFilteringService(gridOptions, this.PubSub);
Expand Down
95 changes: 65 additions & 30 deletions packages/core/src/modules/dragging/data-den-dragging-service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DataDenInternalOptions } from '../../data-den-options.interface';
import { DataDenColDef, DataDenInternalOptions } from '../../data-den-options.interface';
import { DataDenPubSub } from '../../data-den-pub-sub';
import { Context } from '../../context';
import { getMainColumnsOrder } from '../../utils/columns-order';
import { DataDenEvent } from '../../data-den-event';

export class DataDenDraggingService {
#container: HTMLElement;
Expand All @@ -20,6 +20,9 @@ export class DataDenDraggingService {
#mainColumnsOrder: number[];
#defaultGridOffsetLeft: number;
#cssPrefix: string;
#groupedColumns: string[] = [];
#mainOrderedColumns: DataDenColDef[];
#columnsOrder: number[] = [];

#handleGridMouseMove: (e: MouseEvent) => void;
#handleDocumentMouseUp: (e: MouseEvent) => void;
Expand All @@ -40,15 +43,18 @@ export class DataDenDraggingService {
this.#columnPositions = [];
this.#breakpoints = [];
this.#mainColumnsOrder = [];
this.#groupedColumns = [];
this.#defaultGridOffsetLeft = 0;
this.#cssPrefix = options.cssPrefix;
this.#mainOrderedColumns = options.columns;

this.#handleGridMouseMove = () => {};
this.#handleDocumentMouseUp = () => {};
this.#handleHeaderMouseDown = () => {};
this.#handleGridMouseMove = () => { };
this.#handleDocumentMouseUp = () => { };
this.#handleHeaderMouseDown = () => { };

this.#subscribeFetchDone();
this.#subscribeRerenderingDone();
this.#subscribeGroupUpdate();
}

init() {
Expand All @@ -69,7 +75,9 @@ export class DataDenDraggingService {

update() {
const tempColumns = [...this.#getAllColumnElements()];
this.#columns = this.#mainColumnsOrder.map((columnIndex) => tempColumns[columnIndex]);
this.#columns = this.#mainColumnsOrder.map((columnIndex) => {
return tempColumns[columnIndex]
});
}

#subscribeFetchDone() {
Expand Down Expand Up @@ -102,7 +110,7 @@ export class DataDenDraggingService {
}

#setColumnParams() {
this.#columnPositions = [...this.#getAllColumnPositions()];
this.#columnPositions = this.#columnPositions.length === 0 ? [...this.#getAllColumnPositions()] : this.#columnPositions;
this.#setBreakpoints();
this.#defaultGridOffsetLeft =
this.#gridMain!.getBoundingClientRect().left + parseFloat(this.#headerMainCellsWrapper!.style.left);
Expand Down Expand Up @@ -139,7 +147,7 @@ export class DataDenDraggingService {
const colHeader = this.#headers[index];
const rows = this.#container.querySelectorAll('[ref="row"]');
const cells = Array.from(rows).map(
(row) => row.querySelectorAll('.data-den-main-cells-wrapper [ref="cell"]')[index] as HTMLElement
(row) => row.querySelectorAll('.data-den-main-cells-wrapper [ref="cell"]')[this.#mainColumnsOrder[index]] as HTMLElement
);

return [colHeader, ...cells];
Expand All @@ -156,7 +164,7 @@ export class DataDenDraggingService {
}

#setDefaultColumnsOrder() {
this.#mainColumnsOrder = getMainColumnsOrder(this.#options.columns);
this.#mainColumnsOrder = this.#mainColumnsOrder.length ? this.#mainColumnsOrder : getMainColumnsOrder(this.#mainOrderedColumns);
}

#subscribeResizingDone() {
Expand Down Expand Up @@ -205,7 +213,7 @@ export class DataDenDraggingService {
this.#targetIndex = this.#getMinBreakpointIndex(this.#breakpoints, offsetX);

const currentColumnWidth = this.#columnPositions[this.#currentIndex].width;
const gap = this.#getColumnsGap(this.#currentIndex);
const gap = this.#getColumnsGap(this.#currentIndex, this.#targetIndex);

// prevent swapping if there is no space for it (current column is wider than target column)
if (
Expand Down Expand Up @@ -271,14 +279,50 @@ export class DataDenDraggingService {
return array.length - 1;
}

#subscribeGroupUpdate() {
this.PubSub.subscribe('command:group:update', (event: DataDenEvent) => {
this.#currentIndex = this.#getMinBreakpointIndex(this.#breakpoints, event.data.pageX);
const len = event.data.groupedColumns.length;

// handle main columns order
const columnPositionsBefore = this.#mainColumnsOrder.splice(len - 1, this.#currentIndex - len + 1);
this.#mainColumnsOrder.splice(len, 0, ...columnPositionsBefore)
// handle main columns order

// handle column positions
const colsBefore = this.#columnPositions.splice(len - 1, this.#currentIndex - len + 1);
this.#columnPositions.splice(len, 0, ...colsBefore);
// handle column positions


// @TODO update columns

setTimeout(() => {
console.log(this.#columns);

const columnsBefore = this.#columns.splice(len - 1, this.#currentIndex - len + 1);
this.#columns.splice(len, 0, ...columnsBefore);
console.log(this.#columns);
}, 0);

// setTimeout(() => {
// console.log(this.#columns);
// }, 0);

// @TODO update breakpoints positions

});
}

#updateColumnPositions() {
if (this.#currentIndex === this.#targetIndex && this.#prevTargetIndex === -1) {
return;
}

const direction = this.#getDirection();
const currentOrderedIndex = direction === 'right' ? this.#targetIndex - 1 : this.#targetIndex + 1;
const gap = this.#getColumnsGap(currentOrderedIndex);

const gap = this.#getColumnsGap(currentOrderedIndex, this.#targetIndex);

if (direction === 'right') {
this.#breakpoints[this.#targetIndex] = this.#breakpoints[this.#targetIndex] + gap;
Expand All @@ -295,18 +339,6 @@ export class DataDenDraggingService {
cell.style.left = `${this.#breakpoints[index]}px`;
});
});

this.#publishColumnsOrder();
}

#getDirection() {
return this.#prevTargetIndex > this.#targetIndex ? 'left' : 'right';
}

#getColumnsGap(sourceIndex: number) {
const sourceColumnWidth = this.#columnPositions[sourceIndex].width;
const targetColumnWidth = this.#columnPositions[this.#targetIndex].width;
return targetColumnWidth - sourceColumnWidth;
}

#swapArrayElements(array: HTMLElement[][] | any[], sourceIndex: number, targetIndex: number) {
Expand All @@ -319,6 +351,16 @@ export class DataDenDraggingService {
array[targetIndex] = temp;
}

#getDirection() {
return this.#prevTargetIndex > this.#targetIndex ? 'left' : 'right';
}

#getColumnsGap(sourceIndex: number, targetIndex: number) {
const sourceColumnWidth = this.#columnPositions[sourceIndex].width;
const targetColumnWidth = this.#columnPositions[targetIndex].width;
return targetColumnWidth - sourceColumnWidth;
}

#finalizeDragging() {
this.#isDragging = false;
this.#disableTransition();
Expand All @@ -343,11 +385,4 @@ export class DataDenDraggingService {
this.#container.removeEventListener('mousemove', this.#handleGridMouseMove);
document.removeEventListener('mouseup', this.#handleDocumentMouseUp);
}

#publishColumnsOrder() {
this.PubSub.publish('info:dragging:columns-reorder:done', {
columnsOrder: this.#mainColumnsOrder,
context: new Context('info:dragging:columns-reorder:done'),
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,14 @@ export interface DataDenPaginationOptions {
lastRowIndex: number;
}

export interface DataDenGroupedOptions {
groupedColumns?: any[];
}

export interface DataDenFetchOptions {
sortingOptions?: DataDenSortOptions;
quickFilterOptions?: DataDenQuickFilterOptions;
filtersOptions?: DataDenFiltersOptions;
paginationOptions?: DataDenPaginationOptions;
groupedOptions?: DataDenGroupedOptions;
}
13 changes: 13 additions & 0 deletions packages/core/src/modules/fetch/data-den-fetch-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class DataDenFetchService {
this.#subscribeQuickFilterChanged();
this.#subscribeFilterChange();
this.#subscribePaginationChange();
this.#subscribeGroupChange();
}

#getData(fetchOptions: DataDenFetchOptions): Promise<any[]> {
Expand Down Expand Up @@ -92,4 +93,16 @@ export class DataDenFetchService {
});
});
}

#subscribeGroupChange(): void {
this.PubSub.subscribe('command:group:update', (event: DataDenEvent) => {
this.#fetchOptions.groupedOptions = event.data.groupedColumns.length === 0 ? undefined : {
groupedColumns: event.data.groupedColumns,
};

this.#getData({ groupedOptions: this.#fetchOptions.groupedOptions }).then((data: any[]) => {
this.#publishFetchDone(event.context, data);
});
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { DataDenDataLoaderStrategy } from './data-den-data-loader-strategy';
import {
DataDenFetchOptions,
DataDenFiltersOptions,
DataDenGroupedOptions,
DataDenPaginationOptions,
DataDenQuickFilterOptions,
DataDenSortOptions,
} from '../data-den-fetch-options.interface';
import { deepCopy } from '../../../utils';
import { deepCopy, groupRows } from '../../../utils';

export class DataDenClientDataLoaderStrategy extends DataDenDataLoaderStrategy {
#data: any[];
Expand All @@ -18,10 +19,24 @@ export class DataDenClientDataLoaderStrategy extends DataDenDataLoaderStrategy {
}

getData(options: DataDenFetchOptions): Promise<any[]> {

return this.filterData(deepCopy(this.#data), options.filtersOptions)
.then((filtered) => this.quickFilterData(filtered, options.quickFilterOptions))
.then((quickFiltered) => this.sortData(quickFiltered, options.sortingOptions))
.then((sorted) => this.paginateData(sorted, options.paginationOptions));
.then((sorted) => this.groupData(sorted, options.groupedOptions))
.then((grouped) => this.paginateData(grouped, options.paginationOptions, options.groupedOptions))
}

groupData(rows: any[], groupedOptions: DataDenGroupedOptions | undefined): Promise<any[]> {
if (!groupedOptions) {
return Promise.resolve(rows);
}

const groups = groupedOptions.groupedColumns.map((column) => column.group);

const grouped = groupRows(rows, groups);

return Promise.resolve(grouped);
}

filterData(rows: any[], filtersOptions: DataDenFiltersOptions | undefined): Promise<any[]> {
Expand All @@ -43,14 +58,16 @@ export class DataDenClientDataLoaderStrategy extends DataDenDataLoaderStrategy {
return Promise.resolve(filtered);
}

paginateData(rows: any[], paginationOptions: DataDenPaginationOptions | undefined): Promise<any[]> {
paginateData(rows: any[], paginationOptions: DataDenPaginationOptions | undefined, groupedOptions: DataDenGroupedOptions | undefined): Promise<any> {
if (!paginationOptions) {
return Promise.resolve(rows);
}

const { firstRowIndex, lastRowIndex } = paginationOptions;

const paginated = rows.slice(firstRowIndex, lastRowIndex);
const paginated = (groupedOptions ? Object.fromEntries(
Object.entries(rows).slice(firstRowIndex, lastRowIndex)
) : rows.slice(firstRowIndex, lastRowIndex));

return Promise.resolve(paginated);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
DataDenFetchOptions,
DataDenFiltersOptions,
DataDenGroupedOptions,
DataDenPaginationOptions,
DataDenQuickFilterOptions,
DataDenSortOptions,
Expand All @@ -11,5 +12,5 @@ export abstract class DataDenDataLoaderStrategy {
abstract filterData(data: any[], params: DataDenFiltersOptions): Promise<any[]>;
abstract sortData(data: any[], params: DataDenSortOptions): Promise<any[]>;
abstract quickFilterData(data: any[], params: DataDenQuickFilterOptions): Promise<any[]>;
abstract paginateData(data: any[], params: DataDenPaginationOptions): Promise<any[]>;
abstract paginateData(data: any[], params: DataDenPaginationOptions, groupedOptions: DataDenGroupedOptions): Promise<any[]>;
}
Loading