Skip to content

Commit

Permalink
inprogress
Browse files Browse the repository at this point in the history
  • Loading branch information
pomahtri committed Dec 7, 2024
1 parent 06250e1 commit 525c4fd
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { DataRow } from '@ts/grids/new/grid_core/columns_controller/types';
import { PureComponent } from '@ts/grids/new/grid_core/core/pure_component';
import type { DataObject } from '@ts/grids/new/grid_core/data_controller/types';
import { CollectionController } from '@ts/grids/new/grid_core/keyboard_navigation/collection_controller';
import type { InfernoNode, RefObject } from 'inferno';
import { createRef } from 'inferno';
Expand Down Expand Up @@ -34,9 +35,9 @@ export interface CardProps {
row: DataRow;

cover?: {
imageExpr?: string;
imageExpr?: (data: DataObject) => string;

altExpr?: string;
altExpr?: (data: DataObject) => string;
};

elementRef?: RefObject<HTMLDivElement>;
Expand Down Expand Up @@ -99,8 +100,8 @@ export class Card extends PureComponent<CardProps> {
hoverStateEnabled ? CLASSES.cardHover : '',
].filter(Boolean).join(' ');

const imageSrc = cover?.imageExpr && this.props.row.data[cover.imageExpr] as string;
const alt = cover?.altExpr && this.props.row.data[cover.altExpr] as string;
const imageSrc = cover?.imageExpr?.(this.props.row.data);
const alt = cover?.altExpr?.(this.props.row.data);

return (
<div
Expand All @@ -118,10 +119,12 @@ export class Card extends PureComponent<CardProps> {
<CardHeader
items={this.props.toolbar || []}
/>
{imageSrc && (
<Cover
imageSrc={imageSrc}
alt={alt}
/>
)}
{this.props.row.cells.map((cell, index) => (
<FieldTemplate
elementRef={this.fieldRefs[index]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import messageLocalization from '@js/localization/message';
import type { Properties as LoadPanelProps } from '@js/ui/load_panel';
import type { Template } from '@ts/grids/new/grid_core/types';

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

export interface Options {
cardsPerRow?: number | 'auto';
cardMinWidth?: number;
Expand All @@ -17,6 +19,11 @@ export interface Options {
noDataText?: string;

noDataTemplate?: Template<{ text: string }>;

cardCover?: {
imageExpr: string | ((data: DataObject) => string);
altExpr: string | ((data: DataObject) => string);
};
}

export const defaultOptions = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable spellcheck/spell-checker */
import { compileGetter } from '@js/core/utils/data';
import { isDefined } from '@js/core/utils/type';
import type dxScrollable from '@js/ui/scroll_view/ui.scrollable';
import type { ScrollEventInfo } from '@js/ui/scroll_view/ui.scrollable';
import { combined, computed, state } from '@ts/core/reactive/index';
Expand All @@ -12,6 +14,7 @@ import { DataController } from '@ts/grids/new/grid_core/data_controller';
import { ErrorController } from '@ts/grids/new/grid_core/error_controller/error_controller';
import { createRef } from 'inferno';

import type { DataObject } from '../../grid_core/data_controller/types';
import type { ContentViewProps } from './content_view';
import { ContentView as ContentViewComponent } from './content_view';

Expand Down Expand Up @@ -144,7 +147,16 @@ export class ContentView extends View<ContentViewProps> {
onDblClick: this.options.action('onCardDblClick'),
onHoverChanged: this.options.action('onCardHoverChanged'),
onPrepared: this.options.action('onCardPrepared'),
cover: this.options.oneWay('cardCover'),
cover: combined({
imageExpr: computed(
(imageExpr) => this.processExpr(imageExpr),
[this.options.oneWay('cardCover.imageExpr')],
),
altExpr: computed(
(altExpr) => this.processExpr(altExpr),
[this.options.oneWay('cardCover.altExpr')],
),
}),
// eslint-disable-next-line @typescript-eslint/no-explicit-any
toolbar: this.options.oneWay('cardHeader.items') as any,
}),
Expand Down Expand Up @@ -173,6 +185,16 @@ export class ContentView extends View<ContentViewProps> {
});
}

private processExpr<T>(
expr: T | ((data: DataObject) => T) | undefined,
): ((data: DataObject) => T) | undefined {
if (!isDefined(expr)) {
return undefined;
}
// @ts-expect-error
return compileGetter(expr);
}

private onScroll(e: ScrollEventInfo<unknown>): void {
this.scrollTop.update(e.scrollOffset.top);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
// import type { Change } from '../editing/types';
import { OptionsController } from '../options_controller/options_controller';
import type { DataObject } from './types';
import { normalizeDataSource } from './utils';
import { normalizeDataSource, updateItemsImmutable } from './utils';

export class DataController {
private readonly dataSourceConfiguration = this.options.oneWay('dataSource');
Expand Down Expand Up @@ -61,8 +61,15 @@ export class DataController {
) {
effect(
(dataSource) => {
const changedCallback = (): void => {
this._items.update(dataSource.items());
const changedCallback = (e?): void => {
let items = dataSource.items() as DataObject[];

if (e?.changes) {
items = this._items.unreactive_get();
items = updateItemsImmutable(items, e.changes, dataSource.store());
}

this._items.update(items);
this.pageIndex.update(dataSource.pageIndex());
this.pageSize.update(dataSource.pageSize());
this._totalCount.update(dataSource.totalCount());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { DataSourceLike } from '@js/data/data_source';
import DataSource from '@js/data/data_source';
import { normalizeDataSourceOptions } from '@js/data/data_source/utils';
import { applyBatch } from '@ts/data/m_array_utils';

import type { DataObject } from './types';

export function normalizeDataSource(
dataSourceLike: DataSourceLike<unknown, unknown> | null | undefined,
Expand All @@ -24,3 +30,17 @@ export function normalizeDataSource(
// TODO: research making second param not required
return new DataSource(normalizeDataSourceOptions(dataSourceLike, undefined));
}

export function updateItemsImmutable(
data: DataObject[],
changes: any[],
keyInfo: any,
): DataObject[] {
// @ts-expect-error
return applyBatch({
keyInfo,
data,
changes,
immutable: true,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,12 @@ export class OptionsController<TProps, TDefaultProps extends TProps = TProps> {
const obs = computed(
(props) => {
const value = getValue(props, name);
// NOTE: it is better not to use '??' operator,
// because result will be different if value is 'null'.
// Some code works differently if undefined is passed instead of null,
// for example dataSource getter-setter .filter()
/*
NOTE: it is better not to use '??' operator,
because result will be different if value is 'null'.
Some code works differently if undefined is passed instead of null,
for example dataSource's getter-setter `.filter()`
*/
return value !== undefined ? value : getValue(this.defaults, name);
},
[this.props],
Expand All @@ -125,7 +127,6 @@ export class OptionsController<TProps, TDefaultProps extends TProps = TProps> {

public twoWay<TProp extends string>(
name: TProp,
// eslint-disable-next-line max-len
): SubsGetsUpd<PropertyWithDefaults<TProps, TDefaultProps, TProp>> {
const obs = state(this.component.option(name));
this.oneWay(name).subscribe(obs.update.bind(obs) as any);
Expand Down
Loading

0 comments on commit 525c4fd

Please sign in to comment.