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
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,117 @@
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',
}],
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],
});

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

expect(rows[0].props?.styles).toEqual({ height: 120 });
expect(rows[1].props?.styles).toEqual({ height: 80 });
});
});
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,7 +30,9 @@ export class DateTableBody extends BaseInfernoComponent<DateTableBodyProps> {
addVerticalSizesClassToRows,
cellTemplate,
dataCellTemplate,
rowHeights,
} = this.props;
let rowIndex = 0;
const rowClasses = combineClasses({
[DATE_TABLE_ROW_CLASS]: true,
'dx-scheduler-cell-sizes-vertical': addVerticalSizesClassToRows,
Expand Down Expand Up @@ -63,10 +66,18 @@ export class DateTableBody extends BaseInfernoComponent<DateTableBodyProps> {
dateTable.map(({
cells,
key: rowKey,
}) => (
}) => {
const rowHeight = rowHeights?.[rowIndex];
const rowStyles = rowHeight === undefined
? undefined
: renderUtils.addHeightToStyle(rowHeight);
rowIndex += 1;

return (
<Row
key={rowKey}
className={rowClasses}
styles={rowStyles}
leftVirtualCellWidth={viewData.leftVirtualCellWidth
?? RowDefaultProps.leftVirtualCellWidth}
rightVirtualCellWidth={viewData.rightVirtualCellWidth
Expand Down Expand Up @@ -112,7 +123,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
Expand Up @@ -25,34 +25,47 @@ class VerticalCurrentTimeShader extends CurrentTimeShader {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
renderShader(isHorizontalGroupedWorkSpace: boolean, groupCount: number, cellCount: number): void {
let shaderHeight = this.getShaderHeight();
const maxHeight = this.getShaderMaxHeight();
const isSolidShader = shaderHeight > maxHeight;

if (shaderHeight > maxHeight) {
shaderHeight = maxHeight;
}
if (this.workSpace.isGroupedByDate()) {
const maxHeight = this.getShaderMaxHeight();
const isSolidShader = shaderHeight > maxHeight;

setHeight(this.$shader, shaderHeight);
if (shaderHeight > maxHeight) {
shaderHeight = maxHeight;
}

if (this.workSpace.isGroupedByDate()) {
setHeight(this.$shader, shaderHeight);
this.renderGroupedByDateShaderParts(groupCount, shaderHeight, maxHeight, isSolidShader);
} else {
this.renderShaderParts(groupCount, shaderHeight, maxHeight, isSolidShader);
setHeight(this.$shader, Math.min(shaderHeight, this.getMaxShaderHeight(groupCount)));
this.renderShaderParts(groupCount, shaderHeight);
}
}

private getMaxShaderHeight(groupCount: number): number {
const effectiveGroupCount = groupCount || 1;
let maxHeight = 0;

for (let i = 0; i < effectiveGroupCount; i += 1) {
maxHeight = Math.max(maxHeight, this.getShaderMaxHeight(i));
}

return maxHeight;
}

private renderShaderParts(
groupCount: number,
shaderHeight: number,
maxHeight: number,
isSolidShader: boolean,
): void {
for (let i = 0; i < groupCount; i += 1) {
const maxHeight = this.getShaderMaxHeight(i);
const isSolidShader = shaderHeight > maxHeight;
const normalizedShaderHeight = isSolidShader ? maxHeight : shaderHeight;
const shaderWidth = this.getShaderWidth();
this.renderTopShader(this.$shader, shaderHeight, shaderWidth, i);
this.renderTopShader(this.$shader, normalizedShaderHeight, shaderWidth, i);

if (!isSolidShader) {
this.renderBottomShader(this.$shader, maxHeight, shaderHeight, shaderWidth, i);
this.renderBottomShader(this.$shader, maxHeight, normalizedShaderHeight, shaderWidth, i);
}

this.renderAllDayShader(shaderWidth, i);
Expand Down Expand Up @@ -152,8 +165,8 @@ class VerticalCurrentTimeShader extends CurrentTimeShader {
return this.workSpace.getGroupedStrategy().getShaderHeight();
}

private getShaderMaxHeight(): number {
return this.workSpace.getGroupedStrategy().getShaderMaxHeight();
private getShaderMaxHeight(groupIndex?: number): number {
return this.workSpace.getGroupedStrategy().getShaderMaxHeight(groupIndex);
}

private getShaderWidth(): number {
Expand Down
Loading
Loading