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 @@ -30,6 +30,7 @@ const isEventReadOnlySelector = createSelector(
);

export const selectors = {
ampm: createSelector((state: State) => state.preferences.ampm),
visibleDate: createSelector((state: State) => state.visibleDate),
showCurrentTimeIndicator: createSelector((state: State) => state.showCurrentTimeIndicator),
nowUpdatedEveryMinute: createSelector((state: State) => state.nowUpdatedEveryMinute),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export const selectors = {
views: createSelector((state: State) => state.views),
preferences: createSelector((state: State) => state.preferences),
preferencesMenuConfig: createSelector((state: State) => state.preferencesMenuConfig),
ampm: createSelector((state: State) => state.preferences.ampm),
showWeekends: createSelector((state: State) => state.preferences.showWeekends),
showWeekNumber: createSelector((state: State) => state.preferences.showWeekNumber),
showEmptyDaysInAgenda: createSelector((state: State) => state.preferences.showEmptyDaysInAgenda),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,22 @@ import {
EventCalendarPreferencesMenuConfig,
} from '../models';
import { Adapter } from '../use-adapter/useAdapter.types';
import { SchedulerParametersToStateMapper, SchedulerStore } from '../utils/SchedulerStore';
import {
DEFAULT_SCHEDULER_PREFERENCES,
SchedulerParametersToStateMapper,
SchedulerStore,
} from '../utils/SchedulerStore';
import { EventCalendarState, EventCalendarParameters } from './EventCalendarStore.types';

export const DEFAULT_VIEWS: CalendarView[] = ['week', 'day', 'month', 'agenda'];
export const DEFAULT_VIEW: CalendarView = 'week';
export const DEFAULT_PREFERENCES: EventCalendarPreferences = {

export const DEFAULT_EVENT_CALENDAR_PREFERENCES: EventCalendarPreferences = {
...DEFAULT_SCHEDULER_PREFERENCES,
showWeekends: true,
showWeekNumber: false,
showEmptyDaysInAgenda: true,
isSidePanelOpen: true,
ampm: true,
};
export const DEFAULT_PREFERENCES_MENU_CONFIG: EventCalendarPreferencesMenuConfig = {
toggleWeekendVisibility: true,
Expand All @@ -39,7 +44,7 @@ const mapper: SchedulerParametersToStateMapper<
getInitialState: (schedulerInitialState, parameters) => ({
...schedulerInitialState,
...deriveStateFromParameters(parameters),
preferences: { ...DEFAULT_PREFERENCES, ...parameters.preferences },
preferences: { ...DEFAULT_EVENT_CALENDAR_PREFERENCES, ...parameters.preferences },
preferencesMenuConfig:
parameters.preferencesMenuConfig === false
? parameters.preferencesMenuConfig
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { adapter } from 'test/utils/scheduler';
import { createRenderer } from '@mui/internal-test-utils/createRenderer';
import {
DEFAULT_PREFERENCES,
DEFAULT_EVENT_CALENDAR_PREFERENCES,
DEFAULT_PREFERENCES_MENU_CONFIG,
DEFAULT_VIEW,
DEFAULT_VIEWS,
Expand Down Expand Up @@ -41,7 +41,7 @@ describe('Core - EventCalendarStore', () => {
showCurrentTimeIndicator: true,
eventColor: 'jade',
pendingUpdateRecurringEventParameters: null,
preferences: DEFAULT_PREFERENCES,
preferences: DEFAULT_EVENT_CALENDAR_PREFERENCES,
preferencesMenuConfig: DEFAULT_PREFERENCES_MENU_CONFIG,
viewConfig: null,
occurrencePlaceholder: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ export const selectors = {
...schedulerSelectors,
view: createSelector((state: State) => state.view),
views: createSelector((state: State) => state.views),
ampm: createSelector((state: State) => state.preferences.ampm),
};
11 changes: 7 additions & 4 deletions packages/x-scheduler-headless/src/use-timeline/TimelineStore.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { TimelinePreferences, TimelineView } from '../models';
import { Adapter } from '../use-adapter';
import { SchedulerParametersToStateMapper, SchedulerStore } from '../utils/SchedulerStore';
import {
DEFAULT_SCHEDULER_PREFERENCES,
SchedulerParametersToStateMapper,
SchedulerStore,
} from '../utils/SchedulerStore';
import { TimelineState, TimelineParameters } from './TimelineStore.types';

export const DEFAULT_VIEWS: TimelineView[] = ['time', 'days', 'weeks', 'months', 'years'];
Expand All @@ -11,9 +15,8 @@ const deriveStateFromParameters = <TEvent extends object, TResource extends obje
) => ({
views: parameters.views ?? DEFAULT_VIEWS,
});
export const DEFAULT_PREFERENCES: TimelinePreferences = {
ampm: true,
};

export const DEFAULT_PREFERENCES: TimelinePreferences = DEFAULT_SCHEDULER_PREFERENCES;

const mapper: SchedulerParametersToStateMapper<TimelineState, TimelineParameters<any, any>> = {
getInitialState: (schedulerInitialState, parameters) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export interface TimelineState extends SchedulerState {
views: TimelineView[];
/**
* Preferences for the timeline.
*
*/
preferences: TimelinePreferences;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
SchedulerValidDate,
CalendarEventUpdatedProperties,
RecurringEventUpdateScope,
SchedulerPreferences,
} from '../../models';
import {
SchedulerState,
Expand Down Expand Up @@ -47,6 +48,10 @@ export const DEFAULT_IS_MULTI_DAY_EVENT = (event: CalendarEvent | CalendarEventO

const ONE_MINUTE_IN_MS = 60 * 1000;

export const DEFAULT_SCHEDULER_PREFERENCES: SchedulerPreferences = {
ampm: true,
};

/**
* Instance shared by the Event Calendar and the Timeline components.
*/
Expand Down Expand Up @@ -76,6 +81,7 @@ export class SchedulerStore<
...SchedulerStore.deriveStateFromParameters(parameters, adapter),
...buildEventsState(parameters),
...buildResourcesState(parameters),
preferences: DEFAULT_SCHEDULER_PREFERENCES,
adapter,
occurrencePlaceholder: null,
nowUpdatedEveryMinute: adapter.date(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
CalendarEventId,
SchedulerResourceModelStructure,
SchedulerEventModelStructure,
SchedulerPreferences,
} from '../../models';
import { Adapter } from '../../use-adapter/useAdapter.types';

Expand Down Expand Up @@ -113,6 +114,10 @@ export interface SchedulerState<TEvent extends object = any> {
* Pending parameters to use when the user selects the scope of a recurring event update.
*/
pendingUpdateRecurringEventParameters: UpdateRecurringEventParameters | null;
/**
* Preferences for the scheduler.
*/
preferences: SchedulerPreferences;
}

export interface SchedulerParameters<TEvent extends object, TResource extends object> {
Expand Down Expand Up @@ -234,7 +239,7 @@ export interface SchedulerParametersToStateMapper<
* Updates the state based on the new parameters.
*/
updateStateFromParameters: (
newState: Partial<SchedulerState>,
newState: Omit<Partial<SchedulerState>, 'preferences'>,
parameters: Parameters,
updateModel: SchedulerModelUpdater<State, Parameters>,
) => Partial<State>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { EventPopoverProvider } from '../event-popover';
import { TimeGridColumn } from './TimeGridColumn';
import { DayGridCell } from './DayGridCell';
import './DayTimeGrid.css';
import { useFormatTime } from '../../hooks/useFormatTime';

export const DayTimeGrid = React.forwardRef(function DayTimeGrid(
props: DayTimeGridProps,
Expand All @@ -40,7 +41,6 @@ export const DayTimeGrid = React.forwardRef(function DayTimeGrid(
const hasDayView = useStore(store, selectors.hasDayView);
const now = useStore(store, selectors.nowUpdatedEveryMinute);
const isMultiDayEvent = useStore(store, selectors.isMultiDayEvent);
const ampm = useStore(store, selectors.ampm);
const showCurrentTimeIndicator = useStore(store, selectors.showCurrentTimeIndicator);

// Feature hooks
Expand All @@ -51,7 +51,7 @@ export const DayTimeGrid = React.forwardRef(function DayTimeGrid(
shouldAddPosition: isMultiDayEvent,
});

const timeFormat = ampm ? 'hoursMinutes12h' : 'hoursMinutes24h';
const formatTime = useFormatTime();

const { start, end } = React.useMemo(
() => ({
Expand Down Expand Up @@ -171,9 +171,7 @@ export const DayTimeGrid = React.forwardRef(function DayTimeGrid(
shouldHideHour(hour) ? 'HiddenHourLabel' : undefined,
)}
>
{hour === 0
? null
: adapter.format(adapter.setHours(visibleDate, hour), timeFormat)}
{hour === 0 ? null : formatTime(adapter.setHours(visibleDate, hour))}
</time>
</div>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { TimeGridEvent } from '../event/time-grid-event/TimeGridEvent';
import { EventPopoverTrigger } from '../event-popover';
import { useEventPopoverContext } from '../event-popover/EventPopover';
import './DayTimeGrid.css';
import { useFormatTime } from '../../hooks/useFormatTime';

export function TimeGridColumn(props: TimeGridColumnProps) {
const { day, showCurrentTimeIndicator, index } = props;
Expand Down Expand Up @@ -139,16 +140,11 @@ function ColumnInteractiveLayer({
}

function TimeGridCurrentTimeLabel() {
const adapter = useAdapter();
const store = useEventCalendarStoreContext();
const now = useStore(store, selectors.nowUpdatedEveryMinute);
const ampm = useStore(store, selectors.ampm);
const timeFormat = ampm ? 'hoursMinutes12h' : 'hoursMinutes24h';
const formatTime = useFormatTime();

const currentTimeLabel = React.useMemo(
() => adapter.format(now, timeFormat),
[now, timeFormat, adapter],
);
const currentTimeLabel = React.useMemo(() => formatTime(now), [now, formatTime]);

return (
<span className="DayTimeGridCurrentTimeLabel" aria-hidden="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import * as React from 'react';
import clsx from 'clsx';
import { useStore } from '@base-ui-components/utils/store';
import { Repeat } from 'lucide-react';
import { useAdapter } from '@mui/x-scheduler-headless/use-adapter';
import { CalendarGrid } from '@mui/x-scheduler-headless/calendar-grid';
import { selectors } from '@mui/x-scheduler-headless/use-event-calendar';
import { useEventCalendarStoreContext } from '@mui/x-scheduler-headless/use-event-calendar-store-context';
import { DayGridEventProps } from './DayGridEvent.types';
import { getColorClassName } from '../../../utils/color-utils';
import { useTranslations } from '../../../utils/TranslationsContext';
import { EventDragPreview } from '../../event-drag-preview';
import { useFormatTime } from '../../../hooks/useFormatTime';
import './DayGridEvent.css';
// TODO: Create a standalone component for the resource color pin instead of re-using another component's CSS classes
import '../../resource-legend/ResourceLegend.css';
Expand All @@ -30,15 +30,14 @@ export const DayGridEvent = React.forwardRef(function DayGridEvent(
...other
} = props;

const adapter = useAdapter();
const translations = useTranslations();
const store = useEventCalendarStoreContext();
const isDraggable = useStore(store, selectors.isEventDraggable, occurrence.id);
const isResizable = useStore(store, selectors.isEventResizable, occurrence.id, 'day-grid');
const ampm = useStore(store, selectors.ampm);
const resource = useStore(store, selectors.resource, occurrence.resource);
const color = useStore(store, selectors.eventColor, occurrence.id);
const isRecurring = Boolean(occurrence.rrule);
const formatTime = useFormatTime();

const content = React.useMemo(() => {
switch (variant) {
Expand Down Expand Up @@ -85,13 +84,8 @@ export const DayGridEvent = React.forwardRef(function DayGridEvent(
<span className="DayGridEventTime">{translations.allDay}</span>
) : (
<time className="DayGridEventTime">
<span>
{adapter.format(occurrence.start, ampm ? 'hoursMinutes12h' : 'hoursMinutes24h')}
</span>
<span>
{' '}
- {adapter.format(occurrence.end, ampm ? 'hoursMinutes12h' : 'hoursMinutes24h')}
</span>
<span>{formatTime(occurrence.start)}</span>
<span> - {formatTime(occurrence.end)}</span>
</time>
)}

Expand All @@ -109,7 +103,7 @@ export const DayGridEvent = React.forwardRef(function DayGridEvent(
);
}
}, [
adapter,
formatTime,
variant,
occurrence.title,
occurrence?.allDay,
Expand All @@ -118,7 +112,6 @@ export const DayGridEvent = React.forwardRef(function DayGridEvent(
isRecurring,
resource?.title,
translations,
ampm,
]);

const sharedProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import clsx from 'clsx';
import { useId } from '@base-ui-components/utils/useId';
import { useStore } from '@base-ui-components/utils/store';
import { Repeat } from 'lucide-react';
import { useAdapter } from '@mui/x-scheduler-headless/use-adapter';
import { selectors } from '@mui/x-scheduler-headless/use-event-calendar';
import { useEventCalendarStoreContext } from '@mui/x-scheduler-headless/use-event-calendar-store-context';
import { EventItemProps } from './EventItem.types';
import { getColorClassName } from '../../../utils/color-utils';
import { useTranslations } from '../../../utils/TranslationsContext';
import { useFormatTime } from '../../../hooks/useFormatTime';
import './EventItem.css';
// TODO: Create a standalone component for the resource color pin instead of re-using another component's CSS classes
import '../../resource-legend/ResourceLegend.css';
Expand All @@ -36,17 +36,16 @@ export const EventItem = React.forwardRef(function EventItem(

// Context hooks
const translations = useTranslations();
const adapter = useAdapter();
const store = useEventCalendarStoreContext();

// State hooks
const id = useId(idProp);

// Selector hooks
const ampm = useStore(store, selectors.ampm);
const resource = useStore(store, selectors.resource, occurrence.resource);
const color = useStore(store, selectors.eventColor, occurrence.id);

const formatTime = useFormatTime();
const isRecurring = Boolean(occurrence.rrule);

const content = React.useMemo(() => {
Expand All @@ -68,9 +67,7 @@ export const EventItem = React.forwardRef(function EventItem(
style={{ '--number-of-lines': 1 } as React.CSSProperties}
>
<time className="EventItemTime EventItemTime--compact">
<span>
{adapter.format(occurrence.start, ampm ? 'hoursMinutes12h' : 'hoursMinutes24h')}
</span>
<span>{formatTime(occurrence.start)}</span>
</time>

<span className="EventItemTitle">{occurrence.title}</span>
Expand Down Expand Up @@ -126,13 +123,8 @@ export const EventItem = React.forwardRef(function EventItem(
<span className="EventItemTime">{translations.allDay}</span>
) : (
<time className="EventItemTime">
<span>
{adapter.format(occurrence.start, ampm ? 'hoursMinutes12h' : 'hoursMinutes24h')}
</span>
<span>
{' '}
- {adapter.format(occurrence.end, ampm ? 'hoursMinutes12h' : 'hoursMinutes24h')}
</span>
<span>{formatTime(occurrence.start)}</span>
<span> - {formatTime(occurrence.end)}</span>
</time>
)}

Expand All @@ -150,7 +142,6 @@ export const EventItem = React.forwardRef(function EventItem(
);
}
}, [
adapter,
variant,
occurrence.title,
occurrence?.allDay,
Expand All @@ -159,7 +150,7 @@ export const EventItem = React.forwardRef(function EventItem(
isRecurring,
resource?.title,
translations,
ampm,
formatTime,
]);

return (
Expand Down
Loading
Loading