Skip to content

Commit

Permalink
inprogress
Browse files Browse the repository at this point in the history
  • Loading branch information
pomahtri committed Dec 10, 2024
1 parent 579ec0e commit 0ea1132
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class Card extends PureComponent<CardProps> {
// eslint-disable-next-line max-len, @typescript-eslint/explicit-function-return-type
alignment={cell.column.alignment}
title={cell.column.caption || cell.column.name}
value={cell.value}
value={cell.text}
/>
))}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
/* eslint-disable spellcheck/spell-checker */
import { computed } from '@ts/core/reactive/index';
import type { Subscribable } from '@ts/core/reactive/index';
import { combined } from '@ts/core/reactive/index';
import { ColumnsController } from '@ts/grids/new/grid_core/columns_controller/columns_controller';
import { View } from '@ts/grids/new/grid_core/core/view_old';
import { View } from '@ts/grids/new/grid_core/core/view';

import type { Props } from './resizable_header_panel';
import { ResizableHeaderPanel } from './resizable_header_panel';

export class HeaderPanelView extends View {
public vdom = computed(
(columns, allowColumnReordering) => (
<ResizableHeaderPanel
columns={columns}
onReorder={this.onReorder.bind(this)}
onAdd={this.onAdd.bind(this)}
onRemove={this.onRemove.bind(this)}
allowColumnReordering={allowColumnReordering}
/>
),
[
this.columnsController.visibleColumns,
this.columnsController.allowColumnReordering,
],
);
export class HeaderPanelView extends View<Props> {
protected component = ResizableHeaderPanel;

public static dependencies = [ColumnsController] as const;

Expand All @@ -30,6 +18,16 @@ export class HeaderPanelView extends View {
super();
}

protected override getProps(): Subscribable<Props> {
return combined({
columns: this.columnsController.visibleColumns,
onReorder: this.onReorder.bind(this),
onAdd: this.onAdd.bind(this),
onRemove: this.onRemove.bind(this),
allowColumnReordering: this.columnsController.allowColumnReordering,
});
}

public onRemove(name: string): void {
this.columnsController.columnOption(name, 'visible', false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { OptionsController } from './options_controller';
export class CardViewBase extends GridCoreNew {
contentView!: ContentViewModule.View;

headerPanel!: HeaderPanelView;

protected _registerDIContext(): void {
super._registerDIContext();
this.diContext.register(HeaderPanelView);
Expand All @@ -37,6 +39,7 @@ export class CardViewBase extends GridCoreNew {
protected _initDIContext(): void {
super._initDIContext();
this.contentView = this.diContext.get(ContentViewModule.View);
this.headerPanel = this.diContext.get(HeaderPanelView);
}

// eslint-disable-next-line max-len
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
/* eslint-disable @typescript-eslint/no-shadow */
/* eslint-disable spellcheck/spell-checker */
import formatHelper from '@js/format_helper';
import type { Subscribable, SubsGets, SubsGetsUpd } from '@ts/core/reactive/index';
import { computed, iif, interruptableComputed } from '@ts/core/reactive/index';
import {
computed, iif, interruptableComputed,
} from '@ts/core/reactive/index';

import { DataController } from '../data_controller/index';
import type { DataObject } from '../data_controller/types';
import { OptionsController } from '../options_controller/options_controller';
import type { ColumnProperties, PreNormalizedColumn } from './options';
import type { Column, DataRow, VisibleColumn } from './types';
import { getColumnIndexByName, normalizeColumns, normalizeVisibleIndexes } from './utils';
import {
getColumnIndexByName, normalizeColumns, normalizeVisibleIndexes, preNormalizeColumns,
} from './utils';

export class ColumnsController {
public readonly columns: SubsGetsUpd<Column[]>;
private readonly columnsConfiguration: Subscribable<ColumnProperties[] | undefined>;
private readonly columnsSettings: SubsGetsUpd<PreNormalizedColumn[]>;

public readonly columns: SubsGets<Column[]>;

public readonly visibleColumns: SubsGets<Column[]>;

Expand All @@ -24,7 +33,7 @@ export class ColumnsController {
private readonly options: OptionsController,
private readonly dataController: DataController,
) {
const columnsConfiguration = this.options.oneWay('columns');
this.columnsConfiguration = this.options.oneWay('columns');

const columnsFromDataSource = computed(
(items: unknown[]) => {
Expand All @@ -38,17 +47,24 @@ export class ColumnsController {
[this.dataController.items],
);

this.columns = interruptableComputed(
(columnsConfiguration) => normalizeColumns(columnsConfiguration ?? []),
this.columnsSettings = interruptableComputed(
(columnsConfiguration) => preNormalizeColumns(columnsConfiguration ?? []),
[
iif(
computed((columnsConfiguration) => !!columnsConfiguration, [columnsConfiguration]),
columnsConfiguration,
computed((columnsConfiguration) => !!columnsConfiguration, [this.columnsConfiguration]),
this.columnsConfiguration,
columnsFromDataSource,
),
],
);

this.columns = computed(
(columnsSettings) => normalizeColumns(columnsSettings ?? []),
[
this.columnsSettings,
],
);

this.visibleColumns = computed(
(columns) => columns
.filter((column): column is VisibleColumn => column.visible)
Expand All @@ -66,10 +82,25 @@ export class ColumnsController {

public createDataRow(data: DataObject, columns: Column[]): DataRow {
return {
cells: columns.map((c) => ({
column: c,
value: c.calculateCellValue(data),
})),
cells: columns.map((c) => {
const displayValue = c.calculateDisplayValue(data);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let text = formatHelper.format(displayValue as any, c.format);

if (c.customizeText) {
text = c.customizeText({
value: displayValue,
valueText: text,
});
}

return {
column: c,
value: c.calculateCellValue(data),
displayValue,
text,
};
}),
key: this.dataController.getDataKey(data),
data,
};
Expand All @@ -80,7 +111,7 @@ export class ColumnsController {
option: TProp,
value: Column[TProp],
): void {
this.columns.updateFunc((columns) => {
this.columnsSettings.updateFunc((columns) => {
const index = getColumnIndexByName(columns, name);
const newColumns = [...columns];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { DataType } from '@js/common';
import messageLocalization from '@js/localization/message';

import type { DataObject } from '../data_controller/types';
import type { WithRequired } from '../types';
import type { Column } from './types';

export type ColumnProperties = Partial<Column> | string;
export type ColumnSettings = Partial<Omit<Column, 'calculateDisplayValue'> & {
calculateDisplayValue: string | ((this: Column, data: DataObject) => unknown);
}>;

export type PreNormalizedColumn = WithRequired<ColumnSettings, 'name' | 'visibleIndex'>;

export type ColumnProperties = ColumnSettings | string;

export const defaultColumnProperties = {
dataType: 'string',
calculateCellValue(data): unknown {
// @ts-expect-error
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return data[this.dataField!];
},
calculateDisplayValue(data): unknown {
return data[this.dataField!];
},
alignment: 'left',
visible: true,
allowReordering: true,
trueText: messageLocalization.format('dxDataGrid-trueText'),
falseText: messageLocalization.format('dxDataGrid-falseText'),
} satisfies Partial<Column>;

export const defaultColumnPropertiesByDataType: Record<
Expand All @@ -23,6 +35,11 @@ Exclude<ColumnProperties, string>
> = {
boolean: {
alignment: 'center',
customizeText({ value }): string {
return value
? this.trueText
: this.falseText;
},
},
string: {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Format } from '@js/common';
import type { ColumnBase } from '@js/common/grids';

import type { DataObject, Key } from '../data_controller/types';
Expand All @@ -8,14 +9,25 @@ type InheritedColumnProps =
| 'visible'
| 'visibleIndex'
| 'allowReordering'
| 'trueText'
| 'falseText'
| 'caption';

export type Column = Pick<Required<ColumnBase>, InheritedColumnProps> & {
dataField?: string;

name: string;

calculateCellValue: (this: Column, data: unknown) => unknown | Promise<unknown>;
calculateCellValue: (this: Column, data: DataObject) => unknown;

calculateDisplayValue: (this: Column, data: DataObject) => unknown;

format?: Format;

customizeText?: (this: Column, info: {
value: unknown;
valueText: string;
}) => string;

editorTemplate?: unknown;

Expand All @@ -26,6 +38,11 @@ export type VisibleColumn = Column & { visible: true };

export interface Cell {
value: unknown;

displayValue: unknown;

text: string;

column: Column;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
import { compileGetter } from '@js/core/utils/data';
import { captionize } from '@js/core/utils/inflector';
import { isDefined } from '@js/core/utils/type';
import { isDefined, isString } from '@js/core/utils/type';

import type { WithOptional } from '../types';
import { type ColumnProperties, defaultColumnProperties, defaultColumnPropertiesByDataType } from './options';
import type { DataObject } from '../data_controller/types';
import type { ColumnProperties, ColumnSettings, PreNormalizedColumn } from './options';
import { defaultColumnProperties, defaultColumnPropertiesByDataType } from './options';
import type { Column } from './types';

function normalizeColumn(column: ColumnProperties, index: number): WithOptional<Column, 'visibleIndex'> {
let col = column;

if (typeof col === 'string') {
col = { dataField: col };
}

function normalizeColumn(column: PreNormalizedColumn): Column {
const dataTypeDefault = defaultColumnPropertiesByDataType[
col.dataType ?? defaultColumnProperties.dataType
column.dataType ?? defaultColumnProperties.dataType
];

const name = col.name ?? col.dataField ?? `column${index}`;
const caption = captionize(name);
const caption = captionize(column.name);

return {
const colWithDefaults = {
...defaultColumnProperties,
...dataTypeDefault,
name,
caption,
...col,
...column,
};

return {
...colWithDefaults,
calculateDisplayValue: isString(colWithDefaults.calculateDisplayValue)
? compileGetter(colWithDefaults.calculateDisplayValue) as (data: DataObject) => string
: colWithDefaults.calculateDisplayValue,
};
}

Expand Down Expand Up @@ -81,8 +82,26 @@ export function normalizeVisibleIndexes(
return returnIndexes;
}

export function normalizeColumns(columns: ColumnProperties[]): Column[] {
const normalizedColumns = columns.map((c, i) => normalizeColumn(c, i));
export function normalizeColumns(columns: PreNormalizedColumn[]): Column[] {
const normalizedColumns = columns.map((c) => normalizeColumn(c));
return normalizedColumns;
}

export function preNormalizeColumns(columns: ColumnProperties[]): PreNormalizedColumn[] {
const normalizedColumns = columns
.map((column): ColumnSettings => {
if (typeof column === 'string') {
return {
dataField: column,
};
}

return column;
})
.map((column, index) => ({
...column,
name: column.name ?? column.dataField ?? `column-${index}`,
}));

const visibleIndexes = getVisibleIndexes(
normalizedColumns.map((c) => c.visibleIndex),
Expand All @@ -92,9 +111,17 @@ export function normalizeColumns(columns: ColumnProperties[]): Column[] {
normalizedColumns[i].visibleIndex = visibleIndexes[i];
});

return normalizedColumns as Column[];
return normalizedColumns as PreNormalizedColumn[];
}

export function normalizeStringColumn(column: ColumnProperties): ColumnSettings {
if (typeof column === 'string') {
return { dataField: column };
}

return column;
}

export function getColumnIndexByName(columns: Column[], name: string): number {
export function getColumnIndexByName(columns: PreNormalizedColumn[], name: string): number {
return columns.findIndex((c) => c.name === name);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,16 @@ import { Component, type ComponentType, render } from 'inferno';
export abstract class View<T extends {}> {
private inferno: undefined | ComponentType;

private props?: T;

protected abstract component: ComponentType<T>;

protected abstract getProps(): Subscribable<T>;

public render(root: Element): Subscription {
const ViewComponent = this.component;
return toSubscribable(this.getProps()).subscribe((props: T) => {
this.props = props;
// @ts-expect-error
render(<ViewComponent {...props}/>, root);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export interface WithDIContext {
export type Template<T> = (props: T) => HTMLDivElement | template;

export type WithOptional<T, TProp extends keyof T> = Omit<T, TProp> & Partial<Pick<T, TProp>>;
export type WithRequired<T, TProp extends keyof T> = Omit<T, TProp> & Required<Pick<T, TProp>>;

0 comments on commit 0ea1132

Please sign in to comment.