Calendar: resize and move event (#3750)

Signed-off-by: Alexander Platov <sas_lord@mail.ru>
This commit is contained in:
Alexander Platov 2023-09-28 07:56:20 +03:00 committed by GitHub
parent 75b71e9b1a
commit a3fd97e3b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 343 additions and 225 deletions

View File

@ -793,6 +793,7 @@ a.no-line {
.cursor-pointer { cursor: pointer; }
.cursor-default { cursor: default; }
.cursor-inherit { cursor: inherit; }
.cursor-row-resize { cursor: row-resize; }
.pointer-events-none { pointer-events: none; }
.content-pointer-events-none > * { pointer-events: none; }

View File

@ -13,8 +13,9 @@
// limitations under the License.
-->
<script lang="ts">
import { Event } from '@hcengineering/calendar'
import { Timestamp } from '@hcengineering/core'
import { Event, ReccuringInstance } from '@hcengineering/calendar'
import { Timestamp, Ref, DocumentUpdate } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation'
import ui, {
ActionIcon,
CalendarItem,
@ -25,14 +26,19 @@
Scroller,
addZero,
areDatesEqual,
closeTooltip,
deviceOptionsStore as deviceInfo,
day as getDay,
getMonday,
getWeekDayName,
resizeObserver
resizeObserver,
showPopup,
getEventPositionElement
} from '@hcengineering/ui'
import { Menu } from '@hcengineering/view-resources'
import { createEventDispatcher, onDestroy, onMount } from 'svelte'
import calendar from '../plugin'
import { updateReccuringInstance, isReadOnly } from '../utils'
import EventElement from './EventElement.svelte'
export let events: Event[]
@ -47,6 +53,7 @@
export let showHeader: boolean = true
export let clearCells: boolean = false
const client = getClient()
const dispatch = createEventDispatcher()
const todayDate = new Date()
@ -132,6 +139,16 @@
dueDate: Timestamp
cols: number
}
interface CalendarElementRect {
top: number
bottom: number
left: number
right: number
width: number
height: number
fit: boolean
visibility: number
}
interface CalendarColumn {
elements: CalendarElement[]
}
@ -169,6 +186,7 @@
let adMaxRow: number = 1
let adRows: CalendarADRows[]
const cellBorder: number = 1
const stepsPerHour: number = 4
const heightAD: number = 2
const minAD: number = 2
const maxAD: number = 3
@ -178,6 +196,16 @@
let shownAD: boolean = false
let shortAlldays: { id: string; day: number; fixRow?: boolean }[] = []
let moreCounts: number[] = Array<number>(displayedDaysCount)
const nullCalendarElement: CalendarElementRect = {
top: 0,
bottom: 0,
left: 0,
right: 0,
width: 0,
height: rem(heightAD),
fit: true,
visibility: 1
}
$: if (newEvents !== calendarEvents) {
newEvents = calendarEvents
@ -340,14 +368,12 @@
return mins < 2 ? (end ? 1 : 2) : mins >= 57 ? (end ? 1 + cellBorder : 1) : 1
}
const getRect = (
event: CalendarItem
): { top: number; bottom: number; left: number; right: number; width: number; visibility: number } => {
const result = { top: 0, bottom: 0, left: 0, right: 0, width: 0, visibility: 1 }
const getRect = (event: CalendarItem): CalendarElementRect => {
const result = { ...nullCalendarElement }
const checkDate = new Date(weekMonday.getTime() + MILLISECONDS_IN_DAY * event.day)
const startDay = checkDate.setHours(startHour, 0, 0, 0)
const endDay = checkDate.setHours(displayedHours - 1, 59, 59, 999)
const startTime = event.date < startDay ? { hours: 0, mins: 0 } : convertToTime(event.date)
const startTime = event.date <= startDay ? { hours: startHour, mins: 0 } : convertToTime(event.date)
const endTime =
event.dueDate > endDay ? { hours: displayedHours - startHour, mins: 0 } : convertToTime(event.dueDate)
if (getDay(weekMonday, event.day).setHours(endTime.hours, endTime.mins, 0, 0) <= todayDate.getTime()) {
@ -383,12 +409,8 @@
(cols - index - 1) * rem(0.125)
return result
}
const getADRect = (
id: string,
day?: number,
fixRow?: boolean
): { top: number; left: number; width: number; height: number; fit: boolean; visibility: number } => {
const result = { top: 0, left: 0, width: 0, height: rem(heightAD), fit: true, visibility: 1 }
const getADRect = (id: string, day?: number, fixRow?: boolean): CalendarElementRect => {
const result = { ...nullCalendarElement }
const index = adRows.findIndex((ev) => ev.id === id)
const checkTime = new Date().setHours(0, 0, 0, 0)
@ -516,10 +538,116 @@
: rem((heightAD + 0.125) * (adMaxRow <= maxAD ? adMaxRow : maxAD) + 0.25)
$: showArrowAD = (!minimizedAD && adMaxRow > maxAD) || (minimizedAD && adMaxRow > minAD)
let dragOnOld: CalendarCell | null = null
const getMinutes = (e: MouseEvent): number => {
let mins: number = 0
for (let i = 0; i < stepsPerHour; i++) {
if (e.offsetY >= (i * cellHeight) / stepsPerHour && e.offsetY < ((i + 1) * cellHeight) / stepsPerHour) {
mins = (i * 60) / stepsPerHour
}
}
return mins
}
const getMinutes = (e: MouseEvent): number => (e.offsetY >= cellHeight / 2 ? 30 : 0)
const dragOver = (e: DragEvent & { currentTarget: EventTarget & HTMLDivElement }, day: Date, hourOfDay: number) => {
let dragOnOld: CalendarCell | null = null
let dragId: Ref<Event> | null = null
let resizeId: Ref<Event> | null = null
let directionResize: 'top' | 'bottom' | null
let oldMins: number = 0
let oldTime: number = -1
let originDate: Timestamp = 0
let originDueDate: Timestamp = 0
async function updateHandler (event: Event) {
const update: DocumentUpdate<Event> = {}
if (originDate !== event.date) update.date = event.date
if (originDueDate !== event.dueDate) update.dueDate = event.dueDate
if (Object.keys(update).length > 0) {
if (event._class === calendar.class.ReccuringInstance) {
await updateReccuringInstance(update, event as ReccuringInstance)
} else {
await client.update(event, update)
}
}
}
async function mouseUpElement (e: MouseEvent) {
window.removeEventListener('mouseup', mouseUpElement)
const event = events.find((ev) => ev._id === resizeId)
if (event !== undefined) await updateHandler(event)
resizeId = directionResize = null
}
function mouseDownElement (e: MouseEvent, event: Event, direction: 'top' | 'bottom'): void {
if (e.buttons !== 1) return
e.stopPropagation()
resizeId = event._id
directionResize = direction
originDate = event.date
originDueDate = event.dueDate
window.addEventListener('mouseup', mouseUpElement)
}
function mouseMoveElement (
e: MouseEvent & { currentTarget: EventTarget & HTMLDivElement },
day: Date,
hour: number
): void {
if (resizeId == null && directionResize == null) return
let mins: number = 0
for (let i = 0; i < stepsPerHour; i++) {
if (e.offsetY >= (i * cellHeight) / stepsPerHour && e.offsetY < ((i + 1) * cellHeight) / stepsPerHour) mins = i
}
if (oldMins === mins) return
oldMins = mins
const newDate = new Date(day).setHours(
hour + startHour,
(mins * 60) / stepsPerHour + (directionResize === 'top' ? 0 : 60 / stepsPerHour),
0,
0
)
const index = events.findIndex((ev) => ev._id === resizeId)
if (index === -1) return
if (directionResize === 'top') {
if (events[index].dueDate - newDate >= 15 * 60000) events[index].date = newDate
} else {
if (newDate - events[index].date >= 15 * 60000) events[index].dueDate = newDate
}
events = events
}
function dragStartElement (e: DragEvent & { currentTarget: EventTarget & HTMLDivElement }, event: Event): void {
if (isReadOnly(event) || event.allDay) return
if (e.dataTransfer) e.dataTransfer.effectAllowed = 'all'
originDate = event.date
originDueDate = event.dueDate
dragOnOld = null
oldTime = -1
closeTooltip()
setTimeout(() => (dragId = event._id), 50)
}
async function dragEndElement (e: DragEvent) {
const event = events.find((ev) => ev._id === dragId)
if (event !== undefined) await updateHandler(event)
dragId = null
}
function dragDrop (e: DragEvent, day: Date, hourOfDay: number): void {
const newTime = new Date(day).setHours(hourOfDay + startHour, getMinutes(e), 0, 0)
if (dragId) {
const index = events.findIndex((ev) => ev._id === dragId)
const diff = newTime - oldTime
if (diff && index !== -1 && oldTime !== -1) {
events[index].date = originDate + diff
events[index].dueDate = originDueDate + diff
events = events
}
} else {
dispatch('dragDrop', {
day,
hour: hourOfDay + startHour,
date: new Date(newTime)
})
}
dragOnOld = null
}
function dragOver (e: DragEvent, day: Date, hourOfDay: number): void {
if (e.dataTransfer) e.dataTransfer.dropEffect = 'move'
e.preventDefault()
const dragOn: CalendarCell = {
day,
hourOfDay,
@ -527,20 +655,31 @@
}
if (
dragOnOld !== null &&
dragOn.day === dragOnOld.day &&
areDatesEqual(dragOn.day, dragOnOld.day) &&
dragOn.hourOfDay === dragOnOld.hourOfDay &&
dragOn.minutes === dragOnOld.minutes
) {
return
}
dragOnOld = dragOn
dispatch('dragenter', {
date: new Date(day.setHours(hourOfDay + startHour, dragOn.minutes, 0, 0))
})
e.preventDefault()
const newTime = new Date(day).setHours(hourOfDay + startHour, dragOn.minutes, 0, 0)
if (dragId) {
if (oldTime === -1) oldTime = newTime
const index = events.findIndex((ev) => ev._id === dragId)
const diff = newTime - oldTime
if (diff && index !== -1) {
events[index].date = originDate + diff
events[index].dueDate = originDueDate + diff
}
events = events
} else dispatch('dragEnter', { date: new Date(newTime) })
}
const dragOn = (e: DragEvent) => e.preventDefault()
function showMenu (ev: MouseEvent, event: Event) {
ev.preventDefault()
closeTooltip()
showPopup(Menu, { object: event }, getEventPositionElement(ev))
}
</script>
<Scroller
@ -550,9 +689,9 @@
<div
bind:this={container}
on:dragleave
on:dragover={dragOn}
class="calendar-container"
class:clearCells
class:clearCells={clearCells || resizeId !== null || dragId !== null}
class:cursor-row-resize={resizeId !== null && directionResize !== null}
style:--calendar-ad-height={styleAD + 'px'}
style:grid={`${showHeader ? '[header] 3.5rem ' : ''}[all-day] ${styleAD}px repeat(${
(displayedHours - startHour) * 2
@ -706,14 +845,9 @@
style:width={`${colWidth}px`}
style:grid-column={`col-start ${dayOfWeek + 1} / ${dayOfWeek + 2}`}
style:grid-row={`row-start ${hourOfDay * 2 + 1} / row-start ${hourOfDay * 2 + 3}`}
on:mousemove={(e) => mouseMoveElement(e, day, hourOfDay)}
on:dragover={(e) => dragOver(e, day, hourOfDay)}
on:drop|preventDefault={(e) => {
dispatch('drop', {
day,
hour: hourOfDay + startHour,
date: new Date(day.setHours(hourOfDay + startHour, getMinutes(e), 0, 0))
})
}}
on:drop|preventDefault={(e) => dragDrop(e, day, hourOfDay)}
on:click|stopPropagation={() => {
dispatch('create', {
date: new Date(day.setHours(hourOfDay + startHour, 0, 0, 0)),
@ -733,14 +867,31 @@
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
<div
class="calendar-element"
class:past={rect.visibility === 0}
style:top={`${rect.top}px`}
style:bottom={`${rect.bottom}px`}
style:left={`${rect.left}px`}
style:right={`${rect.right}px`}
style:opacity={rect.visibility === 0 ? 0.4 : 1}
style:--mask-image={'none'}
draggable={!ev.allDay && !resizeId}
tabindex={1000 + i}
on:dragstart={(e) => dragStartElement(e, ev)}
on:dragend={dragEndElement}
>
<div
class="calendar-element-start"
class:allowed={!resizeId && !dragId && !clearCells}
class:hovered={resizeId === ev._id && directionResize === 'top'}
on:mousedown={(e) => mouseDownElement(e, ev, 'top')}
on:contextmenu={(e) => showMenu(e, ev)}
/>
<div
class="calendar-element-end"
class:allowed={!resizeId && !dragId && !clearCells}
class:hovered={resizeId === ev._id && directionResize === 'bottom'}
on:mousedown={(e) => mouseDownElement(e, ev, 'bottom')}
on:contextmenu={(e) => showMenu(e, ev)}
/>
<EventElement
event={ev}
hourHeight={cellHeight}
@ -748,12 +899,6 @@
width: rect.width,
height: (calendarRect?.height ?? rect.top + rect.bottom) - rect.top - rect.bottom
}}
on:drop={(e) => {
dispatch('drop', {
date: new Date(event.date)
})
}}
on:resize={() => (events = events)}
/>
</div>
{/if}
@ -778,7 +923,7 @@
&::after {
position: absolute;
content: '';
inset: 0;
inset: -1px;
z-index: 5;
}
}
@ -847,7 +992,61 @@
&:not(.withPointer) {
pointer-events: none;
}
&-start,
&-end {
position: absolute;
left: 0;
right: 0;
height: 0.5rem;
border-radius: 0.5rem;
&::after {
position: absolute;
content: '';
left: -0.25rem;
right: -0.25rem;
height: 1rem;
border: 1px solid transparent;
border-radius: 0.5rem;
transition-property: opacity, border-width, transform;
transition-duration: 0.15s;
transition-timing-function: var(--timing-main);
transform: scale(0.9);
opacity: 0;
cursor: row-resize;
filter: drop-shadow(0 0 2px var(--primary-edit-border-color));
pointer-events: none;
}
&.allowed::after {
pointer-events: all;
z-index: 10;
}
&.allowed:hover::after,
&.hovered::after {
border-width: 1px;
transform: scale(1);
opacity: 1;
}
}
&-start {
top: 0;
&::after {
top: -0.25rem;
border-top-color: var(--primary-edit-border-color);
}
}
&-end {
bottom: 0;
&::after {
bottom: -0.25rem;
border-bottom-color: var(--primary-edit-border-color);
}
}
}
:global(.calendar-element.past .event-container) {
opacity: 0.4;
}
.sticky-header {
position: sticky;
background-color: var(--theme-comp-header-color);

View File

@ -13,22 +13,21 @@
// limitations under the License.
-->
<script lang="ts">
import { Event, ReccuringEvent, ReccuringInstance, RecurringRule, generateEventId } from '@hcengineering/calendar'
import { Event, ReccuringEvent, ReccuringInstance, RecurringRule } from '@hcengineering/calendar'
import { Person } from '@hcengineering/contact'
import { DocumentUpdate, Ref } from '@hcengineering/core'
import presentation, { getClient } from '@hcengineering/presentation'
import { StyledTextBox } from '@hcengineering/text-editor'
import { Button, DAY, EditBox, Icon, IconClose, closePopup, showPopup } from '@hcengineering/ui'
import { Button, EditBox, Icon, IconClose, showPopup } from '@hcengineering/ui'
import { deepEqual } from 'fast-equals'
import { createEventDispatcher } from 'svelte'
import calendar from '../plugin'
import { isReadOnly, saveUTC } from '../utils'
import { isReadOnly, saveUTC, updateReccuringInstance } from '../utils'
import EventParticipants from './EventParticipants.svelte'
import EventReminders from './EventReminders.svelte'
import EventTimeEditor from './EventTimeEditor.svelte'
import EventTimeExtraButton from './EventTimeExtraButton.svelte'
import ReccurancePopup from './ReccurancePopup.svelte'
import UpdateRecInstancePopup from './UpdateRecInstancePopup.svelte'
export let object: Event
$: readOnly = isReadOnly(object)
@ -96,7 +95,7 @@
if (Object.keys(update).length > 0) {
if (object._class === calendar.class.ReccuringInstance) {
await updateHandler(update)
await updateReccuringInstance(update, object as ReccuringInstance)
} else {
await client.update(object, update)
}
@ -124,94 +123,6 @@
}
})
}
async function updatePast (ops: DocumentUpdate<Event>) {
const obj = object as ReccuringInstance
const origin = await client.findOne(calendar.class.ReccuringEvent, {
eventId: obj.recurringEventId,
space: obj.space
})
if (origin !== undefined) {
await client.addCollection(
calendar.class.ReccuringEvent,
origin.space,
origin.attachedTo,
origin.attachedToClass,
origin.collection,
{
...origin,
date: obj.date,
dueDate: obj.dueDate,
...ops,
eventId: generateEventId()
}
)
const targetDate = ops.date ?? obj.date
await client.update(origin, {
rules: [{ ...origin.rules[0], endDate: targetDate - DAY }],
rdate: origin.rdate.filter((p) => p < targetDate)
})
const instances = await client.findAll(calendar.class.ReccuringInstance, {
recurringEventId: origin.eventId,
date: { $gte: targetDate }
})
for (const instance of instances) {
await client.remove(instance)
}
}
}
async function updateHandler (ops: DocumentUpdate<ReccuringEvent>) {
const obj = object as ReccuringInstance
if (obj.virtual !== true) {
await client.update(object, ops)
} else {
showPopup(UpdateRecInstancePopup, { currentAvailable: ops.rules === undefined }, undefined, async (res) => {
if (res !== null) {
if (res.mode === 'current') {
await client.addCollection(
obj._class,
obj.space,
obj.attachedTo,
obj.attachedToClass,
obj.collection,
{
title: obj.title,
description: obj.description,
date: obj.date,
dueDate: obj.dueDate,
allDay: obj.allDay,
participants: obj.participants,
externalParticipants: obj.externalParticipants,
originalStartTime: obj.originalStartTime,
recurringEventId: obj.recurringEventId,
reminders: obj.reminders,
location: obj.location,
eventId: obj.eventId,
access: 'owner',
rules: obj.rules,
exdate: obj.exdate,
rdate: obj.rdate,
...ops
},
obj._id
)
} else if (res.mode === 'all') {
const base = await client.findOne(calendar.class.ReccuringEvent, {
space: obj.space,
eventId: obj.recurringEventId
})
if (base !== undefined) {
await client.update(base, ops)
}
} else if (res.mode === 'next') {
await updatePast(ops)
}
}
closePopup()
})
}
}
</script>
<div class="eventPopup-container">

View File

@ -14,20 +14,19 @@
-->
<script lang="ts">
import calendar, { CalendarEventPresenter, Event } from '@hcengineering/calendar'
import { Doc, DocumentUpdate } from '@hcengineering/core'
import { Doc } from '@hcengineering/core'
import { getClient } from '@hcengineering/presentation'
import {
Component,
MILLISECONDS_IN_MINUTE,
deviceOptionsStore,
closeTooltip,
getEventPositionElement,
showPopup,
tooltip
} from '@hcengineering/ui'
import view, { ObjectEditor } from '@hcengineering/view'
import { Menu } from '@hcengineering/view-resources'
import { createEventDispatcher } from 'svelte'
import { calendarStore, isReadOnly, isVisible } from '../utils'
import { calendarStore, isVisible } from '../utils'
import EventPresenter from './EventPresenter.svelte'
export let event: Event
@ -56,93 +55,13 @@
let div: HTMLDivElement
const dispatch = createEventDispatcher()
$: fontSize = $deviceOptionsStore.fontSize
function dragStart (e: DragEvent) {
if (readOnly) return
if (event.allDay) return
originDate = event.date
originDueDate = event.dueDate
const rect = div.getBoundingClientRect()
const topThreshold = rect.y + fontSize / 2
if (e.dataTransfer) {
e.dataTransfer.effectAllowed = 'move'
e.dataTransfer.dropEffect = 'move'
}
dragInitY = e.y
if (e.y < topThreshold) {
dragDirection = 'top'
} else {
const bottomThreshold = rect.y + rect.height - fontSize / 2
if (e.y > bottomThreshold) {
dragDirection = 'bottom'
} else {
dragDirection = 'mid'
}
}
}
let originDate = event.date
let originDueDate = event.dueDate
$: pixelPer15Min = hourHeight / 4
let dragInitY: number | undefined
let dragDirection: 'bottom' | 'mid' | 'top' | undefined
function drag (e: DragEvent) {
if (readOnly) return
if (event.allDay) return
if (dragInitY !== undefined) {
const diff = Math.floor((e.y - dragInitY) / pixelPer15Min)
if (diff) {
if (dragDirection !== 'bottom') {
const newValue = new Date(originDate).setMinutes(new Date(originDate).getMinutes() + 15 * diff)
if (dragDirection === 'top') {
if (newValue < event.dueDate) {
event.date = newValue
dispatch('resize')
}
} else {
const newDue = new Date(originDueDate).setMinutes(new Date(originDueDate).getMinutes() + 15 * diff)
event.date = newValue
event.dueDate = newDue
dispatch('resize')
}
} else {
const newDue = new Date(originDueDate).setMinutes(new Date(originDueDate).getMinutes() + 15 * diff)
if (newDue > event.date) {
event.dueDate = newDue
dispatch('resize')
}
}
}
}
}
async function drop () {
const update: DocumentUpdate<Event> = {}
if (originDate !== event.date) {
update.date = event.date
}
if (originDueDate !== event.dueDate) {
update.dueDate = event.dueDate
}
if (Object.keys(update).length > 0) {
await client.update(event, {
dueDate: event.dueDate,
date: event.date
})
}
}
function showMenu (ev: MouseEvent) {
ev.preventDefault()
closeTooltip()
showPopup(Menu, { object: event }, getEventPositionElement(ev))
}
$: visible = isVisible(event, $calendarStore)
$: readOnly = isReadOnly(event)
</script>
{#if event}
@ -152,14 +71,9 @@
class="event-container"
class:oneRow
class:empty
draggable={!event.allDay}
use:tooltip={{ component: EventPresenter, props: { value: event, hideDetails: !visible } }}
on:click|stopPropagation={click}
on:contextmenu={showMenu}
on:dragstart={dragStart}
on:drag={drag}
on:dragend={drop}
on:drop
>
{#if !empty && presenter?.presenter}
<Component is={presenter.presenter} props={{ event, narrow, oneRow, hideDetails: !visible }} />

View File

@ -1,8 +1,10 @@
import { Calendar, Event } from '@hcengineering/calendar'
import { IdMap, Timestamp, getCurrentAccount, toIdMap } from '@hcengineering/core'
import { Calendar, Event, ReccuringEvent, ReccuringInstance, generateEventId } from '@hcengineering/calendar'
import { IdMap, Timestamp, getCurrentAccount, toIdMap, DocumentUpdate } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation'
import { showPopup, closePopup, DAY } from '@hcengineering/ui'
import { writable } from 'svelte/store'
import calendar from './plugin'
import UpdateRecInstancePopup from './components/UpdateRecInstancePopup.svelte'
export function saveUTC (date: Timestamp): Timestamp {
const utcdate = new Date(date)
@ -76,3 +78,94 @@ function fillStores (): void {
}
fillStores()
export async function updatePast (ops: DocumentUpdate<Event>, object: ReccuringInstance): Promise<void> {
const client = getClient()
const origin = await client.findOne(calendar.class.ReccuringEvent, {
eventId: object.recurringEventId,
space: object.space
})
if (origin !== undefined) {
await client.addCollection(
calendar.class.ReccuringEvent,
origin.space,
origin.attachedTo,
origin.attachedToClass,
origin.collection,
{
...origin,
date: object.date,
dueDate: object.dueDate,
...ops,
eventId: generateEventId()
}
)
const targetDate = ops.date ?? object.date
await client.update(origin, {
rules: [{ ...origin.rules[0], endDate: targetDate - DAY }],
rdate: origin.rdate.filter((p) => p < targetDate)
})
const instances = await client.findAll(calendar.class.ReccuringInstance, {
recurringEventId: origin.eventId,
date: { $gte: targetDate }
})
for (const instance of instances) {
await client.remove(instance)
}
}
}
export async function updateReccuringInstance (
ops: DocumentUpdate<ReccuringEvent>,
object: ReccuringInstance
): Promise<void> {
const client = getClient()
if (object.virtual !== true) {
await client.update(object, ops)
} else {
showPopup(UpdateRecInstancePopup, { currentAvailable: ops.rules === undefined }, undefined, async (res) => {
if (res !== null) {
if (res.mode === 'current') {
await client.addCollection(
object._class,
object.space,
object.attachedTo,
object.attachedToClass,
object.collection,
{
title: object.title,
description: object.description,
date: object.date,
dueDate: object.dueDate,
allDay: object.allDay,
participants: object.participants,
externalParticipants: object.externalParticipants,
originalStartTime: object.originalStartTime,
recurringEventId: object.recurringEventId,
reminders: object.reminders,
location: object.location,
eventId: object.eventId,
access: 'owner',
rules: object.rules,
exdate: object.exdate,
rdate: object.rdate,
...ops
},
object._id
)
} else if (res.mode === 'all') {
const base = await client.findOne(calendar.class.ReccuringEvent, {
space: object.space,
eventId: object.recurringEventId
})
if (base !== undefined) {
await client.update(base, ops)
}
} else if (res.mode === 'next') {
await updatePast(ops, object)
}
}
closePopup()
})
}
}