diff --git a/plugins/calendar-resources/src/components/DayCalendar.svelte b/plugins/calendar-resources/src/components/DayCalendar.svelte index 3284c62105..4bb6d0f977 100644 --- a/plugins/calendar-resources/src/components/DayCalendar.svelte +++ b/plugins/calendar-resources/src/components/DayCalendar.svelte @@ -29,11 +29,11 @@ closeTooltip, deviceOptionsStore as deviceInfo, day as getDay, - getWeekStart, getWeekDayName, + getWeekStart, + isWeekend, resizeObserver, - ticker, - isWeekend + ticker } from '@hcengineering/ui' import { showMenu } from '@hcengineering/view-resources' import { createEventDispatcher, onDestroy, onMount } from 'svelte' @@ -48,6 +48,7 @@ import calendar from '../plugin' import { isReadOnly, updateReccuringInstance } from '../utils' import EventElement from './EventElement.svelte' + import TimeDuration from './TimeDuration.svelte' export let events: Event[] export let selectedDate: Date = new Date() @@ -342,6 +343,40 @@ } } + const calcTime = (events: CalendarItem[]): number => { + if (events.length === 0) return 0 + + // Extract and sort intervals by start time + const intervals = events.map((it) => [it.date, it.dueDate]).sort((a, b) => a[0] - b[0]) + + // Merge overlapping intervals + const mergedIntervals = [] + let currentStart = intervals[0][0] + let currentEnd = intervals[0][1] + + for (let i = 1; i < intervals.length; i++) { + const [nextStart, nextEnd] = intervals[i] + + // If intervals overlap, extend the current end if needed + if (nextStart <= currentEnd) { + currentEnd = Math.max(currentEnd, nextEnd) + } else { + // No overlap, add current interval to merged list and start a new one + mergedIntervals.push([currentStart, currentEnd]) + currentStart = nextStart + currentEnd = nextEnd + } + } + + // Add the last interval + mergedIntervals.push([currentStart, currentEnd]) + + // Calculate total duration in hours + const totalHours = mergedIntervals.reduce((sum, [start, end]) => sum + (end - start) / (1000 * 60 * 60), 0) + + return totalHours * 1000 * 60 * 60 + } + const checkIntersect = (date1: CalendarItem | CalendarElement, date2: CalendarItem | CalendarElement): boolean => { return ( (date2.date <= date1.date && date2.dueDate > date1.date) || @@ -818,6 +853,7 @@ {#each [...Array(displayedDaysCount).keys()] as dayOfWeek} {@const day = getDay(weekStart, dayOfWeek)} {@const tday = areDatesEqual(todayDate, day)} + {@const tEvents = calcTime(toCalendar(events, day))} {/each} {/if} diff --git a/plugins/calendar-resources/src/components/TimeDuration.svelte b/plugins/calendar-resources/src/components/TimeDuration.svelte new file mode 100644 index 0000000000..46c1855aac --- /dev/null +++ b/plugins/calendar-resources/src/components/TimeDuration.svelte @@ -0,0 +1,12 @@ + + +{duration} diff --git a/plugins/client-resources/src/connection.ts b/plugins/client-resources/src/connection.ts index e111185fed..889392e316 100644 --- a/plugins/client-resources/src/connection.ts +++ b/plugins/client-resources/src/connection.ts @@ -298,7 +298,7 @@ class Connection implements ClientConnection { return } - if (resp.rateLimit !== undefined && resp.rateLimit.remaining < 10) { + if (resp.rateLimit !== undefined && resp.rateLimit.remaining < 50) { console.log( 'Rate limits:', resp.rateLimit.remaining, diff --git a/plugins/time-resources/src/components/team/agenda/Agenda.svelte b/plugins/time-resources/src/components/team/agenda/Agenda.svelte index a6e0809d31..74d17ac31c 100644 --- a/plugins/time-resources/src/components/team/agenda/Agenda.svelte +++ b/plugins/time-resources/src/components/team/agenda/Agenda.svelte @@ -8,6 +8,7 @@ import WithTeamData from '../WithTeamData.svelte' import { toSlots } from '../utils' import DayPlan from './DayPlan.svelte' + import { personRefByAccountUuidStore } from '@hcengineering/contact-resources' export let space: Ref export let currentDate: Date @@ -36,9 +37,22 @@ todayFrom, todayTo ) + + $: persons = (project?.members ?? []) + .map((it) => $personRefByAccountUuidStore.get(it)) + .filter((it) => it !== undefined) - +
{#if project} diff --git a/plugins/time-resources/src/components/team/agenda/PlanPerson.svelte b/plugins/time-resources/src/components/team/agenda/PlanPerson.svelte index 9444863f84..72e09452bd 100644 --- a/plugins/time-resources/src/components/team/agenda/PlanPerson.svelte +++ b/plugins/time-resources/src/components/team/agenda/PlanPerson.svelte @@ -43,7 +43,9 @@ {/each} {#each gitem.events as event} - + {#if event.overlap === 0} + + {/if} {/each} {#if gitem.busy.slots.length > 0} diff --git a/plugins/time-resources/src/components/team/calendar/TeamCalendar.svelte b/plugins/time-resources/src/components/team/calendar/TeamCalendar.svelte index f5827634d7..adb64b3622 100644 --- a/plugins/time-resources/src/components/team/calendar/TeamCalendar.svelte +++ b/plugins/time-resources/src/components/team/calendar/TeamCalendar.svelte @@ -16,8 +16,12 @@ import calendar, { Event, getAllEvents } from '@hcengineering/calendar' import { calendarByIdStore } from '@hcengineering/calendar-resources' import { getCurrentEmployee, Person } from '@hcengineering/contact' - import { socialIdsByPersonRefStore, personRefByPersonIdStore } from '@hcengineering/contact-resources' - import core, { Doc, IdMap, Ref, Timestamp, Tx, TxCUD, TxCreateDoc, TxUpdateDoc } from '@hcengineering/core' + import { + personRefByAccountUuidStore, + personRefByPersonIdStore, + socialIdsByPersonRefStore + } from '@hcengineering/contact-resources' + import core, { Doc, IdMap, Ref, Timestamp, Tx, TxCreateDoc, TxCUD, TxUpdateDoc } from '@hcengineering/core' import { Asset } from '@hcengineering/platform' import { createQuery, getClient } from '@hcengineering/presentation' import { Project } from '@hcengineering/task' @@ -43,7 +47,10 @@ let slots: WorkSlot[] = [] let events: Event[] = [] let todos: IdMap = new Map() - let persons: Ref[] = [] + + $: persons = (project?.members ?? []) + .map((it) => $personRefByAccountUuidStore.get(it)) + .filter((it) => it !== undefined) const txCreateQuery = createQuery() diff --git a/plugins/time-resources/src/components/team/calendar/TeamCalendarDay.svelte b/plugins/time-resources/src/components/team/calendar/TeamCalendarDay.svelte index 9e4e0a272b..97d391ada0 100644 --- a/plugins/time-resources/src/components/team/calendar/TeamCalendarDay.svelte +++ b/plugins/time-resources/src/components/team/calendar/TeamCalendarDay.svelte @@ -23,6 +23,7 @@ import { groupTeamData, toSlots } from '../utils' import EventElement from './EventElement.svelte' import PersonCalendar from './PersonCalendar.svelte' + import { personRefByAccountUuidStore } from '@hcengineering/contact-resources' export let space: Ref export let currentDate: Date @@ -37,7 +38,10 @@ let slots: WorkSlot[] = [] let events: Event[] = [] let todos: IdMap = new Map() - let persons: Ref[] = [] + + $: persons = (project?.members ?? []) + .map((it) => $personRefByAccountUuidStore.get(it)) + .filter((it) => it !== undefined) function calcHourWidth (events: Event[], totalWidth: number): number[] { const hours = new Map() diff --git a/plugins/time-resources/src/components/team/utils.ts b/plugins/time-resources/src/components/team/utils.ts index 31b210139c..f084714aa2 100644 --- a/plugins/time-resources/src/components/team/utils.ts +++ b/plugins/time-resources/src/components/team/utils.ts @@ -173,10 +173,10 @@ function crossWith (a: EventVars, b: EventVars): EventVars[] { /** * * @param events - without overlaps - * @param event - + * @param event - any object with date and dueDate properties * @returns */ -function calcOverlap (events: EventVars[], event: Event): { events: EventVars[], total: number } { +function calcOverlap (events: EventVars[], event: EventVars): { events: EventVars[], total: number } { let tmp: EventVars[] = [{ date: event.date, dueDate: event.dueDate }] for (const a of events) { const newTmp: EventVars[] = []