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
10 changes: 8 additions & 2 deletions apps/calendar/src/components/timeGrid/gridLines.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { memo } from 'preact/compat';

import { useTheme } from '@src/contexts/themeStore';
import { cls, toPercent } from '@src/helpers/css';
import { getTimeSteps } from '@src/time/datetime';

import type { TimeGridRow } from '@t/grid';
import type { ThemeState } from '@t/theme';
Expand All @@ -19,12 +20,17 @@ export const GridLines = memo(function GridLines({
}: {
timeGridRows: TimeGridRow[];
}) {
const { STEPS } = getTimeSteps(timeGridRows);
const { halfHourLineBorder, hourLineBorder } = useTheme(gridLineBorderSelector);

let count = 1;

return (
<div className={cls('gridlines')}>
{timeGridRows.map((time, index) => {
const isUpperLine = index % 2 === 0;
{timeGridRows.map((time) => {
count = count === STEPS + 1 ? 1 : count;
const isUpperLine = count !== STEPS;
count += 1;

return (
<div
Expand Down
8 changes: 5 additions & 3 deletions apps/calendar/src/components/timeGrid/timeColumn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
import { weekTimeGridLeftSelector } from '@src/selectors/theme';
import { timezonesSelector } from '@src/selectors/timezone';
import TZDate from '@src/time/date';
import { addMinutes, setTimeStrToDate } from '@src/time/datetime';
import { addMinutes, getTimeSteps, setTimeStrToDate } from '@src/time/datetime';
import { isNil, isPresent } from '@src/utils/type';

import type { TimeGridRow } from '@t/grid';
Expand Down Expand Up @@ -119,6 +119,7 @@ interface Props {
}

export const TimeColumn = memo(function TimeColumn({ timeGridRows, nowIndicatorState }: Props) {
const { STEPS } = getTimeSteps(timeGridRows);
const showNowIndicator = useStore(showNowIndicatorOptionSelector);
const timezones = useStore(timezonesSelector);
const timezonesCollapsed = useStore(timezonesCollapsedOptionSelector);
Expand All @@ -127,8 +128,9 @@ export const TimeColumn = memo(function TimeColumn({ timeGridRows, nowIndicatorS
const { width, borderRight } = useTheme(weekTimeGridLeftSelector);

const rowsByHour = useMemo(
() => timeGridRows.filter((_, index) => index % 2 === 0 || index === timeGridRows.length - 1),
[timeGridRows]
() =>
timeGridRows.filter((_, index) => index % STEPS === 0 || index === timeGridRows.length - 1),
[timeGridRows, STEPS]
);
const hourRowsPropsMapper = useCallback(
(row: TimeGridRow, index: number, diffFromPrimaryTimezone?: number) => {
Expand Down
6 changes: 5 additions & 1 deletion apps/calendar/src/components/timeGrid/timeGrid.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe('Showing Current Time Indicator', () => {
const timeGridData = createTimeGridData(weekDatesIncludingBaseDate, {
hourStart: 0,
hourEnd: 24,
timeStep: [0,30]
});

// When
Expand All @@ -50,7 +51,7 @@ describe('Showing Current Time Indicator', () => {
startDayOfWeek: 0,
workweek: false,
});
const timeGridData = createTimeGridData(weekDatesBeforeBaseDate, { hourStart: 0, hourEnd: 24 });
const timeGridData = createTimeGridData(weekDatesBeforeBaseDate, { hourStart: 0, hourEnd: 24, timeStep: [0,30] });

// When
render(<TimeGrid timeGridData={timeGridData} events={[]} />);
Expand All @@ -69,6 +70,7 @@ describe('Showing Current Time Indicator', () => {
const timeGridData = createTimeGridData(weekDatesIncludingBaseDate, {
hourStart: 0,
hourEnd: 24,
timeStep: [0,30]
});

// When
Expand All @@ -88,6 +90,7 @@ describe('Showing Current Time Indicator', () => {
const timeGridData = createTimeGridData(weekDatesIncludingBaseDate, {
hourStart: 0,
hourEnd: 24,
timeStep: [0,30]
});

// When
Expand All @@ -113,6 +116,7 @@ describe('Showing Current Time Indicator', () => {
const timeGridData = createTimeGridData(weekDatesIncludingBaseDate, {
hourStart: 0,
hourEnd: 24,
timeStep: [0,30]
});
const oneHourHeightPercent = timeGridData.rows[0].height * 2;
const initialTop = 50;
Expand Down
15 changes: 12 additions & 3 deletions apps/calendar/src/components/view/day.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,16 @@ export function Day() {
const [timePanel, setTimePanelRef] = useDOMNode<HTMLDivElement>();

const weekOptions = options.week as Required<WeekOptions>;
const { narrowWeekend, startDayOfWeek, workweek, hourStart, hourEnd, eventView, taskView } =
weekOptions;
const {
narrowWeekend,
startDayOfWeek,
workweek,
hourStart,
hourEnd,
eventView,
taskView,
timeStep,
} = weekOptions;
const days = useMemo(() => [renderDate], [renderDate]);
const dayNames = getDayNames(days, options.week?.dayNames ?? []);
const { rowStyleInfo, cellWidthMap } = getRowStyleInfo(
Expand Down Expand Up @@ -95,8 +103,9 @@ export function Day() {
hourStart,
hourEnd,
narrowWeekend,
timeStep,
}),
[days, hourEnd, hourStart, narrowWeekend]
[days, hourEnd, hourStart, narrowWeekend, timeStep]
);
const activePanels = getActivePanels(taskView, eventView);
const gridRows = activePanels.map((key) => {
Expand Down
15 changes: 12 additions & 3 deletions apps/calendar/src/components/view/week.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,16 @@ export function Week() {
const [timePanel, setTimePanelRef] = useDOMNode<HTMLDivElement>();

const weekOptions = options.week as Required<WeekOptions>;
const { narrowWeekend, startDayOfWeek, workweek, hourStart, hourEnd, eventView, taskView } =
weekOptions;
const {
narrowWeekend,
startDayOfWeek,
workweek,
hourStart,
hourEnd,
eventView,
taskView,
timeStep,
} = weekOptions;
const weekDates = useMemo(() => getWeekDates(renderDate, weekOptions), [renderDate, weekOptions]);
const dayNames = getDayNames(weekDates, options.week?.dayNames ?? []);
const { rowStyleInfo, cellWidthMap } = getRowStyleInfo(
Expand Down Expand Up @@ -96,8 +104,9 @@ export function Week() {
hourStart,
hourEnd,
narrowWeekend,
timeStep,
}),
[hourEnd, hourStart, narrowWeekend, weekDates]
[hourEnd, hourStart, narrowWeekend, weekDates, timeStep]
);

const activePanels = getActivePanels(taskView, eventView);
Expand Down
1 change: 1 addition & 0 deletions apps/calendar/src/css/events/time.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
position: absolute;
overflow: hidden;
cursor: pointer;
min-height: 17px;
}

.event-time .travel-time,
Expand Down
1 change: 1 addition & 0 deletions apps/calendar/src/css/timegrid/column.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
right: 10px;
left: 1px;
padding: 3px;
min-height: 26px;
}

.column .grid-selection .grid-selection-label {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ Object {
"showTimezoneCollapseButton": false,
"startDayOfWeek": 0,
"taskView": true,
"timeStep": Array [
0,
30,
],
"timezonesCollapsed": false,
"workweek": false,
},
Expand Down
23 changes: 13 additions & 10 deletions apps/calendar/src/helpers/grid.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -502,22 +502,25 @@ describe('getColumnStyles', () => {
describe('createTimeGridData', () => {
function assertTimeGridDataRows(
expectedRows: TimeGridRow[],
options: { hourStart: number; hourEnd: number }
options: { hourStart: number; hourEnd: number, timeStep: number[] }
) {
const steps = (options.hourEnd - options.hourStart) * 2;
const timeStep = options.timeStep;
const steps = (options.hourEnd - options.hourStart) * timeStep.length;
const expectedRowHeight = 100 / steps;
let count = 0;

expect(expectedRows).toHaveLength(steps);
range(steps).forEach((step, index) => {
const isOdd = index % 2 === 1;
const hour = options.hourStart + Math.floor(step / 2);
count = count === timeStep.length ? 0 : count;
const hour = options.hourStart + Math.floor(step / timeStep.length);

expect(expectedRows[index]).toEqual({
top: expectedRowHeight * index,
height: expectedRowHeight,
startTime: `${hour}:${isOdd ? '30' : '00'}`.padStart(5, '0'),
endTime: (isOdd ? `${hour + 1}:00` : `${hour}:30`).padStart(5, '0'),
startTime: `${hour}:${timeStep[count] != 0 ? timeStep[count] : '00'}`.padStart(5, '0'),
endTime: (count === (timeStep.length - 1) ? `${hour + 1}:00` : `${hour}:` + timeStep[count+1]).padStart(5, '0'),
});
count++;
});
}

Expand All @@ -526,7 +529,7 @@ describe('createTimeGridData', () => {
const rows = getWeekDates(new TZDate('2021-01-28T00:00:00'), {
startDayOfWeek: Day.SUN,
});
const options = { hourStart: 0, hourEnd: 24 };
const options = { hourStart: 0, hourEnd: 24, timeStep: [0,30] };

// When
const result = createTimeGridData(rows, options);
Expand All @@ -541,7 +544,7 @@ describe('createTimeGridData', () => {
const rows = getWeekDates(new TZDate('2021-01-28T00:00:00'), {
startDayOfWeek: Day.SUN,
});
const options = { hourStart: 0, hourEnd: 12 };
const options = { hourStart: 0, hourEnd: 12, timeStep: [0,30] };

// When
const result = createTimeGridData(rows, options);
Expand All @@ -556,7 +559,7 @@ describe('createTimeGridData', () => {
const rows = getWeekDates(new TZDate('2021-01-28T00:00:00'), {
startDayOfWeek: Day.SUN,
});
const options = { hourStart: 12, hourEnd: 24 };
const options = { hourStart: 12, hourEnd: 24, timeStep: [0,30] };

// When
const result = createTimeGridData(rows, options);
Expand All @@ -572,7 +575,7 @@ describe('createTimeGridData', () => {
const rows = getWeekDates(new TZDate('2021-01-28T00:00:00'), {
startDayOfWeek: Day.SUN,
});
const options = { hourStart: 0, hourEnd: 24, narrowWeekend };
const options = { hourStart: 0, hourEnd: 24, narrowWeekend, timeStep: [0,30] };

// When
const result = createTimeGridData(rows, options);
Expand Down
17 changes: 11 additions & 6 deletions apps/calendar/src/helpers/grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,20 +422,25 @@ export function createTimeGridData(
hourStart: number;
hourEnd: number;
narrowWeekend?: boolean;
timeStep: number[];
}
): TimeGridData {
const columns = getColumnsData(datesOfWeek, options.narrowWeekend ?? false);

const steps = (options.hourEnd - options.hourStart) * 2;
const { timeStep } = options;
const steps = (options.hourEnd - options.hourStart) * timeStep.length;
const baseHeight = 100 / steps;
let count = 0;
const rows = range(steps).map((step, index) => {
const isOdd = index % 2 === 1;
const hour = options.hourStart + Math.floor(step / 2);
const startTime = `${hour}:${isOdd ? '30' : '00'}`.padStart(5, '0') as FormattedTimeString;
const endTime = (isOdd ? `${hour + 1}:00` : `${hour}:30`).padStart(
count = count === timeStep.length ? 0 : count;
const hour = options.hourStart + Math.floor(step / timeStep.length);
const startTime = `${hour}:${timeStep[count] !== 0 ? timeStep[count] : '00'}`.padStart(
5,
'0'
) as FormattedTimeString;
const endTime = (
count === timeStep.length - 1 ? `${hour + 1}:00` : `${hour}:${timeStep[count + 1]}`
).padStart(5, '0') as FormattedTimeString;
count += 1;

return {
top: baseHeight * index,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ describe('useGridSelection', () => {
workweek: false,
});

const timeGridData = createTimeGridData(weekDates, { hourStart: 0, hourEnd: 24 });
const timeGridData = createTimeGridData(weekDates, { hourStart: 0, hourEnd: 24, timeStep: [0,30] });

describe('Opening popup', () => {
it('should open event form popup after dragging when the `useFormPopup` option is enabled', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('useTimeGridEventMove', () => {
const rows = getWeekDates(createDate(2021, 2, 14), {
startDayOfWeek: Day.SUN,
});
const timeGridData = createTimeGridData(rows, { hourStart: 0, hourEnd: 24 });
const timeGridData = createTimeGridData(rows, { hourStart: 0, hourEnd: 24, timeStep: [0,30] });
const DEFAULT_CONTAINER_WIDTH = 70;
const DEFAULT_CONTAINER_HEIGHT = 480;

Expand Down
23 changes: 13 additions & 10 deletions apps/calendar/src/hooks/timeGrid/useTimeGridEventMove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,17 @@ import { useCurrentPointerPositionInGrid } from '@src/hooks/event/useCurrentPoin
import { useDraggingEvent } from '@src/hooks/event/useDraggingEvent';
import type EventUIModel from '@src/model/eventUIModel';
import type TZDate from '@src/time/date';
import { addMilliseconds, addMinutes, MS_PER_DAY, MS_PER_THIRTY_MINUTES } from '@src/time/datetime';
import { addMilliseconds, addMinutes, getTimeSteps, MS_PER_DAY } from '@src/time/datetime';
import { isNil, isPresent } from '@src/utils/type';

import type { GridPosition, GridPositionFinder, TimeGridData } from '@t/grid';
import type { CalendarState } from '@t/store';

const THIRTY_MINUTES = 30;

function getCurrentIndexByTime(time: TZDate, hourStart: number) {
function getCurrentIndexByTime(time: TZDate, hourStart: number, STEP_MINUTES: number) {
const hour = time.getHours() - hourStart;
const minutes = time.getMinutes();

return hour * 2 + Math.floor(minutes / THIRTY_MINUTES);
return hour * (60 / STEP_MINUTES) + Math.floor(minutes / STEP_MINUTES);
}

function getMovingEventPosition({
Expand All @@ -35,18 +33,22 @@ function getMovingEventPosition({
timeGridDataRows: TimeGridData['rows'];
currentDate: TZDate;
}) {
const { STEP_MINUTES, MS_PER_STEP_MINUTES } = getTimeSteps(timeGridDataRows);
const rowHeight = timeGridDataRows[0].height;
const maxHeight = rowHeight * timeGridDataRows.length;
const millisecondsDiff = rowDiff * MS_PER_THIRTY_MINUTES + columnDiff * MS_PER_DAY;
const millisecondsDiff = rowDiff * MS_PER_STEP_MINUTES + columnDiff * MS_PER_DAY;
const hourStart = Number(timeGridDataRows[0].startTime.split(':')[0]);

const { goingDuration = 0, comingDuration = 0 } = draggingEvent.model;
const goingStart = addMinutes(draggingEvent.getStarts(), -goingDuration);
const comingEnd = addMinutes(draggingEvent.getEnds(), comingDuration);
const nextStart = addMilliseconds(goingStart, millisecondsDiff);
const nextEnd = addMilliseconds(comingEnd, millisecondsDiff);
const startIndex = Math.max(getCurrentIndexByTime(nextStart, hourStart), 0);
const endIndex = Math.min(getCurrentIndexByTime(nextEnd, hourStart), timeGridDataRows.length - 1);
const startIndex = Math.max(getCurrentIndexByTime(nextStart, hourStart, STEP_MINUTES), 0);
const endIndex = Math.min(
getCurrentIndexByTime(nextEnd, hourStart, STEP_MINUTES),
timeGridDataRows.length - 1
);

const isStartAtPrevDate =
nextStart.getFullYear() < currentDate.getFullYear() ||
Expand Down Expand Up @@ -74,6 +76,7 @@ export function useTimeGridEventMove({
gridPositionFinder: GridPositionFinder;
timeGridData: TimeGridData;
}) {
const { MS_PER_STEP_MINUTES } = getTimeSteps(timeGridData.rows);
const initX = useStore(initXSelector);
const initY = useStore(initYSelector);

Expand Down Expand Up @@ -126,9 +129,9 @@ export function useTimeGridEventMove({

return addMilliseconds(
startDateTime,
gridDiff.rowDiff * MS_PER_THIRTY_MINUTES + gridDiff.columnDiff * MS_PER_DAY
gridDiff.rowDiff * MS_PER_STEP_MINUTES + gridDiff.columnDiff * MS_PER_DAY
);
}, [gridDiff, startDateTime]);
}, [gridDiff, startDateTime, MS_PER_STEP_MINUTES]);

const movingEvent = useMemo(() => {
if (isNil(draggingEvent) || isNil(currentGridPos) || isNil(gridDiff)) {
Expand Down
5 changes: 3 additions & 2 deletions apps/calendar/src/hooks/timeGrid/useTimeGridEventResize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useCurrentPointerPositionInGrid } from '@src/hooks/event/useCurrentPoin
import { useDraggingEvent } from '@src/hooks/event/useDraggingEvent';
import type EventUIModel from '@src/model/eventUIModel';
import type TZDate from '@src/time/date';
import { addMinutes, max, setTimeStrToDate } from '@src/time/datetime';
import { addMinutes, getTimeSteps, max, setTimeStrToDate } from '@src/time/datetime';
import { findLastIndex } from '@src/utils/array';
import { isNil, isPresent } from '@src/utils/type';

Expand Down Expand Up @@ -198,7 +198,8 @@ export function useTimeGridEventResize({
),
-comingDuration
);
const minEndDate = addMinutes(resizingStartUIModel.getStarts(), 30);
const { STEP_MINUTES } = getTimeSteps(timeGridData.rows);
const minEndDate = addMinutes(resizingStartUIModel.getStarts(), STEP_MINUTES);

eventBus.fire('beforeUpdateEvent', {
event: resizingStartUIModel.model.toEventObject(),
Expand Down
1 change: 1 addition & 0 deletions apps/calendar/src/slices/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ function initializeWeekOptions(weekOptions: Options['week'] = {}): CalendarWeekO
eventView: true,
taskView: true,
collapseDuplicateEvents: false,
timeStep: [0, 30],
...weekOptions,
};

Expand Down
Loading