Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class DateTable extends InfernoWrapperComponent<DateTableProps> {
dataCellTemplate,
groupOrientation,
addVerticalSizesClassToRows,
rowHeights,
...restProps
} = this.props;
const classes = addDateTableClass ? 'dx-scheduler-date-table' : undefined;
Expand Down Expand Up @@ -67,6 +68,7 @@ export class DateTable extends InfernoWrapperComponent<DateTableProps> {
rightVirtualCellWidth={rightVirtualCellWidth}
groupOrientation={groupOrientation}
addVerticalSizesClassToRows={addVerticalSizesClassToRows}
rowHeights={rowHeights}
topVirtualRowHeight={DateTableBodyDefaultProps.topVirtualRowHeight}
bottomVirtualRowHeight={DateTableBodyDefaultProps.bottomVirtualRowHeight}
addDateTableClass={DateTableBodyDefaultProps.addDateTableClass}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import {
describe, expect, it, jest,
} from '@jest/globals';

import type { CellTemplateProps } from '../types';
import { DateTableBody } from './date_table_body';
import { Row } from './row';

interface RenderUtilsMock {
renderUtils: {
addHeightToStyle: (
height: number | undefined,
styles?: Record<string, unknown>,
) => Record<string, unknown>;
};
}

jest.mock('../../utils/index', (): RenderUtilsMock => ({
renderUtils: {
addHeightToStyle: (
height: number | undefined,
styles: Record<string, unknown> = {},
): Record<string, unknown> => (height === undefined ? styles : { ...styles, height }),
},
}));

const viewContext = {
view: {
type: 'day',
},
crossScrollingEnabled: false,
} as const;

const CellTemplate = (): JSX.Element => <td />;

interface VirtualNodeLike {
type?: unknown;
props?: {
children?: unknown;
styles?: unknown;
};
children?: unknown;
}

const toArray = (value: unknown): unknown[] => {
if (Array.isArray(value)) {
return value;
}

return value === undefined || value === null ? [] : [value];
};

const getRowNodes = (node: unknown): VirtualNodeLike[] => {
if (typeof node !== 'object' || node === null) {
return [];
}

const virtualNode = node as VirtualNodeLike;
const currentNode = virtualNode.type === Row ? [virtualNode] : [];
const children = [
...toArray(virtualNode.children),
...toArray(virtualNode.props?.children),
];

return [
...currentNode,
...children.flatMap(getRowNodes),
];
};

const createCell = (
key: number,
): CellTemplateProps => ({
key,
startDate: new Date(2025, 0, 1),
endDate: new Date(2025, 0, 1, 0, 30),
index: key,
isFirstGroupCell: false,
isLastGroupCell: false,
isSelected: false,
isFocused: false,
});

describe('DateTableBody', () => {
it('should apply row heights', () => {
const component = new DateTableBody({
viewContext,
viewData: {
groupedData: [{
dateTable: [
{ key: 0, cells: [createCell(0)] },
{ key: 1, cells: [createCell(1)] },
],
groupIndex: 0,
key: '0',
}, {
dateTable: [
{ key: 2, cells: [createCell(2)] },
],
groupIndex: 1,
key: '1',
}],
leftVirtualCellCount: 0,
rightVirtualCellCount: 0,
topVirtualRowCount: 0,
bottomVirtualRowCount: 0,
},
cellTemplate: CellTemplate,
leftVirtualCellWidth: 0,
rightVirtualCellWidth: 0,
topVirtualRowHeight: 0,
bottomVirtualRowHeight: 0,
addDateTableClass: true,
addVerticalSizesClassToRows: true,
rowHeights: [120, 80, 160],
});

const rows = getRowNodes(component.render());

expect(rows[0].props?.styles).toEqual({ height: 120 });
expect(rows[1].props?.styles).toEqual({ height: 80 });
expect(rows[2].props?.styles).toEqual({ height: 160 });
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PublicTemplate } from '@ts/scheduler/r1/components/templates/index';
import { Fragment } from 'inferno';

import { combineClasses } from '../../../../core/r1/utils/render_utils';
import { renderUtils } from '../../utils/index';
import { DATE_TABLE_ROW_CLASS } from '../const';
import type { CellTemplateProps, DefaultProps } from '../types';
import { AllDayPanelTableBody, AllDayPanelTableBodyDefaultProps } from './all_day_panel_table_body';
Expand All @@ -29,11 +30,15 @@ export class DateTableBody extends BaseInfernoComponent<DateTableBodyProps> {
addVerticalSizesClassToRows,
cellTemplate,
dataCellTemplate,
rowHeights,
} = this.props;
const rowClasses = combineClasses({
[DATE_TABLE_ROW_CLASS]: true,
'dx-scheduler-cell-sizes-vertical': addVerticalSizesClassToRows,
});
const getGroupRowOffset = (groupIndex: number): number => viewData.groupedData
.slice(0, groupIndex)
.reduce((offset, { dateTable }) => offset + dateTable.length, 0);

return (
<>
Expand All @@ -43,7 +48,7 @@ export class DateTableBody extends BaseInfernoComponent<DateTableBodyProps> {
dateTable,
isGroupedAllDayPanel,
key: fragmentKey,
}) => (
}, groupIndex) => (
<Fragment key={fragmentKey}>
{
isGroupedAllDayPanel && <AllDayPanelTableBody
Expand All @@ -63,10 +68,17 @@ export class DateTableBody extends BaseInfernoComponent<DateTableBodyProps> {
dateTable.map(({
cells,
key: rowKey,
}) => (
}, rowIndex) => {
const rowHeight = rowHeights?.[getGroupRowOffset(groupIndex) + rowIndex];
const rowStyles = rowHeight === undefined
? undefined
: renderUtils.addHeightToStyle(rowHeight);

return (
<Row
key={rowKey}
className={rowClasses}
styles={rowStyles}
leftVirtualCellWidth={viewData.leftVirtualCellWidth
?? RowDefaultProps.leftVirtualCellWidth}
rightVirtualCellWidth={viewData.rightVirtualCellWidth
Expand Down Expand Up @@ -112,7 +124,8 @@ export class DateTableBody extends BaseInfernoComponent<DateTableBodyProps> {
} as CellTemplateProps} />)
}
</Row>
))
);
})
}
</Fragment>
))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class GroupPanel extends InfernoWrapperComponent<GroupPanelProps> {
groupOrientation,
groups,
styles,
rowHeights,
} = this.props;
const isVerticalLayout = isVerticalGroupingApplied(groups.length, groupOrientation);

Expand All @@ -53,6 +54,7 @@ export class GroupPanel extends InfernoWrapperComponent<GroupPanelProps> {
groupPanelData={groupPanelData}
elementRef={elementRef}
styles={styles}
rowHeights={rowHeights}
groups={GroupPanelDefaultProps.groups}
groupOrientation={GroupPanelDefaultProps.groupOrientation}
groupByDate={GroupPanelDefaultProps.groupByDate}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface GroupPanelBaseProps extends
groupPanelData: GroupPanelData;
groupByDate: boolean;
height?: number;
rowHeights?: number[];
resourceCellTemplate?: JSXTemplate<ResourceCellTemplateProps>;
}

Expand Down Expand Up @@ -43,6 +44,7 @@ export const GroupPanelCellDefaultProps = {

export interface GroupPanelRowProps extends PropsWithClassName {
groupItems: GroupRenderItem[];
height?: number;
cellTemplate?: JSXTemplate<ResourceCellTemplateProps>;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export class GroupPanelVertical extends BaseInfernoComponent<GroupPanelProps> {
resourceCellTemplate,
height,
styles,
rowHeights,
} = this.props;
const style = normalizeStyles(renderUtils.addHeightToStyle(height, styles));

Expand All @@ -26,9 +27,10 @@ export class GroupPanelVertical extends BaseInfernoComponent<GroupPanelProps> {
<div className="dx-scheduler-group-flex-container">
{
groupPanelData.groupPanelItems
.map((group) => <GroupPanelVerticalRow
.map((group, index) => <GroupPanelVerticalRow
key={group[0].key}
groupItems={group}
height={rowHeights?.[index]}
cellTemplate={resourceCellTemplate}
/>)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
describe, expect, it, jest,
} from '@jest/globals';

import { GroupPanelVerticalRow } from './group_panel_vertical_row';

interface RenderUtilsMock {
renderUtils: {
addHeightToStyle: (
height: number | undefined,
styles?: Record<string, unknown>,
) => Record<string, unknown>;
};
}

jest.mock('../../utils/index', (): RenderUtilsMock => ({
renderUtils: {
addHeightToStyle: (
height: number | undefined,
styles: Record<string, unknown> = {},
): Record<string, unknown> => (height === undefined ? styles : { ...styles, height }),
},
}));

interface VirtualNodeLike {
props?: {
style?: unknown;
};
}

describe('GroupPanelVerticalRow', () => {
it('should apply row height', () => {
const component = new GroupPanelVerticalRow({
groupItems: [{
key: '0',
id: 0,
text: 'Group 0',
data: { id: 0 },
resourceName: 'ownerId',
}],
height: 140,
className: '',
});
const result = component.render() as VirtualNodeLike;

expect(result.props?.style).toEqual({ height: '140px' });
});
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BaseInfernoComponent } from '@ts/core/r1/runtime/inferno/index';
import { BaseInfernoComponent, normalizeStyles } from '@ts/core/r1/runtime/inferno/index';

import { renderUtils } from '../../utils/index';
import type { GroupPanelRowProps } from './group_panel_props';
import { GroupPanelRowDefaultProps } from './group_panel_props';
import { GroupPanelVerticalCell } from './group_panel_vertical_cell';
Expand All @@ -9,11 +10,18 @@ export class GroupPanelVerticalRow extends BaseInfernoComponent<GroupPanelRowPro
const {
className,
groupItems,
height,
cellTemplate,
} = this.props;
const styles = height === undefined
? undefined
: normalizeStyles(renderUtils.addHeightToStyle(height));

return (
<div className={`dx-scheduler-group-row ${className}`}>
<div
className={`dx-scheduler-group-row ${className}`}
style={styles}
>
{
groupItems.map(({
color,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface LayoutProps extends PropsWithViewContext {
addDateTableClass: boolean;
addVerticalSizesClassToRows: boolean;
width?: number;
rowHeights?: number[];
dataCellTemplate?: JSXTemplate<DataCellTemplateProps>;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
describe, expect, it, jest,
} from '@jest/globals';
import $ from '@js/core/renderer';

import VerticalCurrentTimeShader from './current_time_shader_vertical';

const DATE_TIME_SHADER_CLASS = 'dx-scheduler-date-time-shader';
const DATE_TIME_SHADER_TOP_CLASS = 'dx-scheduler-date-time-shader-top';
const DATE_TIME_SHADER_BOTTOM_CLASS = 'dx-scheduler-date-time-shader-bottom';

describe('VerticalCurrentTimeShader', () => {
it('should use group max height for each shader part', () => {
const $container = $('<div>');
const getShaderMaxHeight = jest.fn((groupIndex?: number): number => (
groupIndex === 0 ? 100 : 200
));
const workSpace = {
getScrollable: () => ({ $content: () => $container }),
isGroupedByDate: () => false,
getGroupedStrategy: () => ({
getShaderHeight: () => 150,
getShaderMaxHeight,
getShaderWidth: () => 50,
getShaderTopOffset: () => 0,
getShaderOffset: () => 0,
}),
getCellWidth: () => 10,
option: () => false,
$element: () => $('<div>'),
} as any;
const shader = new VerticalCurrentTimeShader(workSpace);

shader.render(false, 2, 0);

expect(getShaderMaxHeight).toHaveBeenCalledWith(0);
expect(getShaderMaxHeight).toHaveBeenCalledWith(1);
expect($container.find(`.${DATE_TIME_SHADER_CLASS}`).css('height')).toBe('150px');
expect($container.find(`.${DATE_TIME_SHADER_TOP_CLASS}`).eq(0).css('height')).toBe('100px');
expect($container.find(`.${DATE_TIME_SHADER_TOP_CLASS}`).eq(1).css('height')).toBe('150px');
expect($container.find(`.${DATE_TIME_SHADER_BOTTOM_CLASS}`).length).toBe(1);
});
});
Loading
Loading