Fix team planning event disappear (#5581)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov 2024-05-11 19:41:00 +05:00 committed by GitHub
parent 7d7e1ef412
commit 75474a6311
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 161 additions and 157 deletions

View File

@ -34,7 +34,6 @@
"@hcengineering/view": "^0.6.9", "@hcengineering/view": "^0.6.9",
"@hcengineering/model-attachment": "^0.6.0", "@hcengineering/model-attachment": "^0.6.0",
"@hcengineering/setting": "^0.6.11", "@hcengineering/setting": "^0.6.11",
"@hcengineering/model-task": "^0.6.0",
"@hcengineering/calendar": "^0.6.17", "@hcengineering/calendar": "^0.6.17",
"@hcengineering/calendar-resources": "^0.6.0", "@hcengineering/calendar-resources": "^0.6.0",
"@hcengineering/platform": "^0.6.9", "@hcengineering/platform": "^0.6.9",

View File

@ -25,10 +25,17 @@ import {
type Visibility type Visibility
} from '@hcengineering/calendar' } from '@hcengineering/calendar'
import { type Contact } from '@hcengineering/contact' import { type Contact } from '@hcengineering/contact'
import { DateRangeMode, type Domain, IndexKind, type Markup, type Ref, type Timestamp } from '@hcengineering/core' import {
DateRangeMode,
IndexKind,
type SystemSpace,
type Domain,
type Markup,
type Ref,
type Timestamp
} from '@hcengineering/core'
import { import {
ArrOf, ArrOf,
type Builder,
Collection, Collection,
Index, Index,
Mixin, Mixin,
@ -41,12 +48,12 @@ import {
TypeRef, TypeRef,
TypeString, TypeString,
TypeTimestamp, TypeTimestamp,
UX UX,
type Builder
} from '@hcengineering/model' } from '@hcengineering/model'
import attachment from '@hcengineering/model-attachment' import attachment from '@hcengineering/model-attachment'
import contact from '@hcengineering/model-contact' import contact from '@hcengineering/model-contact'
import core, { TAttachedDoc, TClass } from '@hcengineering/model-core' import core, { TAttachedDoc, TClass, TDoc } from '@hcengineering/model-core'
import { TProject } from '@hcengineering/model-task'
import view, { createAction } from '@hcengineering/model-view' import view, { createAction } from '@hcengineering/model-view'
import notification from '@hcengineering/notification' import notification from '@hcengineering/notification'
import setting from '@hcengineering/setting' import setting from '@hcengineering/setting'
@ -59,9 +66,11 @@ export { calendarOperation } from './migration'
export const DOMAIN_CALENDAR = 'calendar' as Domain export const DOMAIN_CALENDAR = 'calendar' as Domain
@Model(calendar.class.Calendar, core.class.Space) @Model(calendar.class.Calendar, core.class.Doc, DOMAIN_CALENDAR)
@UX(calendar.string.Calendar, calendar.icon.Calendar) @UX(calendar.string.Calendar, calendar.icon.Calendar)
export class TCalendar extends TProject implements Calendar { export class TCalendar extends TDoc implements Calendar {
name!: string
hidden!: boolean
visibility!: Visibility visibility!: Visibility
} }
@ -76,7 +85,10 @@ export class TExternalCalendar extends TCalendar implements ExternalCalendar {
@Model(calendar.class.Event, core.class.AttachedDoc, DOMAIN_CALENDAR) @Model(calendar.class.Event, core.class.AttachedDoc, DOMAIN_CALENDAR)
@UX(calendar.string.Event, calendar.icon.Calendar) @UX(calendar.string.Event, calendar.icon.Calendar)
export class TEvent extends TAttachedDoc implements Event { export class TEvent extends TAttachedDoc implements Event {
declare space: Ref<Calendar> declare space: Ref<SystemSpace>
@Prop(TypeRef(calendar.class.Calendar), calendar.string.Calendar)
calendar!: Ref<Calendar>
eventId!: string eventId!: string

View File

@ -13,10 +13,10 @@
// limitations under the License. // limitations under the License.
// //
import { calendarId, type Calendar, type Event, type ReccuringEvent } from '@hcengineering/calendar' import { calendarId, type Event, type ReccuringEvent } from '@hcengineering/calendar'
import contact from '@hcengineering/contact' import { type Ref, type Space } from '@hcengineering/core'
import core, { TxOperations, type Ref } from '@hcengineering/core'
import { import {
createDefaultSpace,
tryMigrate, tryMigrate,
tryUpgrade, tryUpgrade,
type MigrateOperation, type MigrateOperation,
@ -24,68 +24,47 @@ import {
type MigrationUpgradeClient type MigrationUpgradeClient
} from '@hcengineering/model' } from '@hcengineering/model'
import { DOMAIN_SPACE } from '@hcengineering/model-core' import { DOMAIN_SPACE } from '@hcengineering/model-core'
import { DOMAIN_SETTING } from '@hcengineering/model-setting'
import { type Integration } from '@hcengineering/setting'
import { DOMAIN_CALENDAR } from '.' import { DOMAIN_CALENDAR } from '.'
import calendar from './plugin' import calendar from './plugin'
async function migrateCalendars (tx: TxOperations): Promise<void> { async function migrateCalendars (client: MigrationClient): Promise<void> {
const existCalendars = new Set((await tx.findAll(calendar.class.Calendar, {})).map((p) => p._id)) await client.move(
const users = await tx.findAll(contact.class.PersonAccount, {}) DOMAIN_SPACE,
for (const user of users) { { _class: { $in: [calendar.class.Calendar, calendar.class.ExternalCalendar] } },
if (!existCalendars.has(`${user._id}_calendar` as Ref<Calendar>)) { DOMAIN_CALENDAR
await tx.createDoc( )
calendar.class.Calendar, await client.update(
core.space.Space, DOMAIN_CALENDAR,
{ { _class: { $in: [calendar.class.Calendar, calendar.class.ExternalCalendar] } },
name: user.email, { space: calendar.space.Calendar }
description: '', )
archived: false, await client.update(
private: false, DOMAIN_CALENDAR,
members: [user._id], { _class: { $in: [calendar.class.Calendar, calendar.class.ExternalCalendar] }, archived: true },
visibility: 'public' { hidden: true }
}, )
`${user._id}_calendar` as Ref<Calendar>, await client.update(
undefined, DOMAIN_CALENDAR,
user._id { _class: { $in: [calendar.class.Calendar, calendar.class.ExternalCalendar] }, archived: false },
) { hidden: false }
} )
} await client.update(
const events = await tx.findAll(calendar.class.Event, { space: calendar.space.PersonalEvents }) DOMAIN_CALENDAR,
for (const event of events) { { _class: { $in: [calendar.class.Calendar, calendar.class.ExternalCalendar] } },
await tx.update(event, { space: (event.createdBy ?? event.modifiedBy) as string as Ref<Calendar> }) { $unset: { type: true, private: true, members: true, archived: true } }
} )
const space = await tx.findOne(calendar.class.Calendar, { _id: calendar.space.PersonalEvents })
if (space !== undefined) {
await tx.remove(space)
}
const calendars = await tx.findAll(calendar.class.Calendar, { visibility: { $exists: false } }) const events = await client.find<Event>(DOMAIN_CALENDAR, {
for (const calendar of calendars) { space: { $ne: calendar.space.Calendar }
await tx.update(calendar, { visibility: 'public' })
}
}
async function migrateExternalCalendars (client: MigrationClient): Promise<void> {
const calendars = await client.find<Calendar>(DOMAIN_SPACE, { _class: calendar.class.Calendar })
const integrations = await client.find<Integration>(DOMAIN_SETTING, {
type: calendar.integrationType.Calendar,
disabled: false,
value: { $ne: '' }
}) })
for (const val of calendars) { const eventByCalendar = new Map<Ref<Space>, Ref<Event>[]>()
if (val._id.endsWith('_calendar')) continue for (const event of events) {
const integration = integrations.find((i) => i.createdBy === val.createdBy) const events = eventByCalendar.get(event.space) ?? []
await client.update( events.push(event._id)
DOMAIN_SPACE, eventByCalendar.set(event.space, events)
{ _id: val._id }, }
{ for (const [_calendar, ids] of eventByCalendar) {
_class: calendar.class.ExternalCalendar, await client.update(DOMAIN_CALENDAR, { _id: { $in: ids } }, { space: calendar.space.Calendar, calendar: _calendar })
externalId: val._id,
externalUser: integration?.value ?? '',
default: val._id === integration?.value
}
)
} }
} }
@ -148,23 +127,23 @@ export const calendarOperation: MigrateOperation = {
await migrateReminders(client) await migrateReminders(client)
await fillOriginalStartTime(client) await fillOriginalStartTime(client)
await migrateSync(client) await migrateSync(client)
await migrateExternalCalendars(client)
} }
}, },
{ {
state: 'timezone', state: 'timezone',
func: migrateTimezone func: migrateTimezone
},
{
state: 'migrate_calendars',
func: migrateCalendars
} }
]) ])
}, },
async upgrade (client: MigrationUpgradeClient): Promise<void> { async upgrade (client: MigrationUpgradeClient): Promise<void> {
await tryUpgrade(client, calendarId, [ await tryUpgrade(client, calendarId, [
{ {
state: 'u-calendar0002', state: 'default-space',
func: async (client) => { func: () => createDefaultSpace(client, calendar.space.Calendar, { name: 'Space for all events and calendars' })
const tx = new TxOperations(client, core.account.System)
await migrateCalendars(tx)
}
} }
]) ])
} }

View File

@ -16,7 +16,7 @@
let calendars: ExternalCalendar[] = [] let calendars: ExternalCalendar[] = []
const me = getCurrentAccount() const me = getCurrentAccount()
const q = createQuery() const q = createQuery()
q.query(calendarPlugin.class.ExternalCalendar, { members: me._id, archived: false }, (res) => { q.query(calendarPlugin.class.ExternalCalendar, { members: me._id, hidden: false }, (res) => {
calendars = res calendars = res
}) })

View File

@ -118,7 +118,7 @@
let calendars: Calendar[] = [] let calendars: Calendar[] = []
calendarsQuery.query(calendar.class.Calendar, { members: me._id }, (res) => { calendarsQuery.query(calendar.class.Calendar, { createdBy: me._id, hidden: false }, (res) => {
calendars = res calendars = res
}) })
@ -132,7 +132,7 @@
): void { ): void {
q.query<Event>( q.query<Event>(
_class, _class,
query ?? { space: { $in: calendars.map((p) => p._id) } }, query ?? { calendar: { $in: calendars.map((p) => p._id) } },
(result) => { (result) => {
raw = result raw = result
}, },
@ -257,11 +257,12 @@
attachedToClass: dragItem._class, attachedToClass: dragItem._class,
_class: dragEventClass, _class: dragEventClass,
collection: 'events', collection: 'events',
space: `${me._id}_calendar` as Ref<Calendar>, calendar: `${me._id}_calendar` as Ref<Calendar>,
modifiedBy: me._id, modifiedBy: me._id,
participants: [me.person], participants: [me.person],
modifiedOn: Date.now(), modifiedOn: Date.now(),
date: e.detail.date.getTime(), date: e.detail.date.getTime(),
space: calendar.space.Calendar,
dueDate: new Date(e.detail.date).setMinutes(new Date(e.detail.date).getMinutes() + 30) dueDate: new Date(e.detail.date).setMinutes(new Date(e.detail.date).getMinutes() + 30)
} }
raw.push(temp) raw.push(temp)

View File

@ -65,12 +65,12 @@
let description: Markup = EmptyMarkup let description: Markup = EmptyMarkup
let visibility: Visibility = 'private' let visibility: Visibility = 'private'
const me = getCurrentAccount() const me = getCurrentAccount()
let space: Ref<Calendar> = `${me._id}_calendar` as Ref<Calendar> let _calendar: Ref<Calendar> = `${me._id}_calendar` as Ref<Calendar>
const q = createQuery() const q = createQuery()
q.query(calendar.class.ExternalCalendar, { default: true, members: me._id, archived: false }, (res) => { q.query(calendar.class.ExternalCalendar, { default: true, members: me._id, hidden: false }, (res) => {
if (res.length > 0) { if (res.length > 0) {
space = res[0]._id _calendar = res[0]._id
} }
}) })
@ -93,27 +93,36 @@
if (date === undefined) return if (date === undefined) return
if (title === '') return if (title === '') return
if (rules.length > 0) { if (rules.length > 0) {
await client.addCollection(calendar.class.ReccuringEvent, space, attachedTo, attachedToClass, 'events', { await client.addCollection(
eventId: generateEventId(), calendar.class.ReccuringEvent,
date: allDay ? saveUTC(date) : date, calendar.space.Calendar,
dueDate: allDay ? saveUTC(dueDate) : dueDate, attachedTo,
externalParticipants, attachedToClass,
rdate: [], 'events',
exdate: [], {
rules, calendar: _calendar,
reminders, eventId: generateEventId(),
description, date: allDay ? saveUTC(date) : date,
participants, dueDate: allDay ? saveUTC(dueDate) : dueDate,
visibility, externalParticipants,
title, rdate: [],
location, exdate: [],
allDay, rules,
access: 'owner', reminders,
originalStartTime: allDay ? saveUTC(date) : date, description,
timeZone participants,
}) visibility,
title,
location,
allDay,
access: 'owner',
originalStartTime: allDay ? saveUTC(date) : date,
timeZone
}
)
} else { } else {
await client.addCollection(calendar.class.Event, space, attachedTo, attachedToClass, 'events', { await client.addCollection(calendar.class.Event, calendar.space.Calendar, attachedTo, attachedToClass, 'events', {
calendar: _calendar,
eventId: generateEventId(), eventId: generateEventId(),
date: allDay ? saveUTC(date) : date, date: allDay ? saveUTC(date) : date,
dueDate: allDay ? saveUTC(dueDate) : dueDate, dueDate: allDay ? saveUTC(dueDate) : dueDate,
@ -210,7 +219,7 @@
/> />
</div> </div>
<div class="block rightCropPadding"> <div class="block rightCropPadding">
<CalendarSelector bind:value={space} focusIndex={10101} /> <CalendarSelector bind:value={_calendar} focusIndex={10101} />
<div class="flex-row-center flex-gap-1"> <div class="flex-row-center flex-gap-1">
<Icon icon={calendar.icon.Hidden} size={'small'} /> <Icon icon={calendar.icon.Hidden} size={'small'} />
<VisibilityEditor bind:value={visibility} kind={'tertiary'} focusIndex={10102} withoutIcon /> <VisibilityEditor bind:value={visibility} kind={'tertiary'} focusIndex={10102} withoutIcon />

View File

@ -44,8 +44,9 @@
let date: number | undefined let date: number | undefined
if (value != null) date = value if (value != null) date = value
if (date === undefined) return if (date === undefined) return
const space = `${getCurrentAccount()._id}_calendar` as Ref<Calendar> const _calendar = `${getCurrentAccount()._id}_calendar` as Ref<Calendar>
await client.addCollection(calendar.class.Event, space, attachedTo, attachedToClass, 'events', { await client.addCollection(calendar.class.Event, calendar.space.Calendar, attachedTo, attachedToClass, 'events', {
calendar: _calendar,
eventId: generateEventId(), eventId: generateEventId(),
date, date,
dueDate: date + defaultDuration, dueDate: date + defaultDuration,

View File

@ -56,7 +56,7 @@
let allDay = object.allDay let allDay = object.allDay
let visibility = object.visibility ?? 'public' let visibility = object.visibility ?? 'public'
let reminders = [...(object.reminders ?? [])] let reminders = [...(object.reminders ?? [])]
let space = object.space let _calendar = object.calendar
let timeZone: string = object.timeZone ?? getUserTimezone() let timeZone: string = object.timeZone ?? getUserTimezone()
let description = object.description let description = object.description
@ -88,8 +88,8 @@
if (object.visibility !== visibility) { if (object.visibility !== visibility) {
update.visibility = visibility update.visibility = visibility
} }
if (object.space !== space) { if (object.calendar !== _calendar) {
update.space = space update.calendar = _calendar
} }
if (object.location !== location) { if (object.location !== location) {
update.location = location update.location = location
@ -216,7 +216,7 @@
</div> </div>
<div class="divider" /> <div class="divider" />
<div class="block rightCropPadding"> <div class="block rightCropPadding">
<CalendarSelector bind:value={space} focusIndex={10008} /> <CalendarSelector bind:value={_calendar} focusIndex={10008} />
<div class="flex-row-center flex-gap-1"> <div class="flex-row-center flex-gap-1">
<Icon icon={calendar.icon.Hidden} size={'small'} /> <Icon icon={calendar.icon.Hidden} size={'small'} />
<VisibilityEditor bind:value={visibility} kind={'tertiary'} withoutIcon focusIndex={10009} /> <VisibilityEditor bind:value={visibility} kind={'tertiary'} withoutIcon focusIndex={10009} />

View File

@ -40,7 +40,7 @@
async function update (calendar: Calendar, value: boolean) { async function update (calendar: Calendar, value: boolean) {
await client.update(calendar, { await client.update(calendar, {
archived: !value hidden: !value
}) })
} }
@ -69,7 +69,7 @@
{#each calendars as calendar} {#each calendars as calendar}
<div>{calendar.name}</div> <div>{calendar.name}</div>
<div> <div>
<Toggle on={!calendar.archived} on:change={(res) => update(calendar, res.detail)} /> <Toggle on={!calendar.hidden} on:change={(res) => update(calendar, res.detail)} />
</div> </div>
{/each} {/each}
</Grid> </Grid>

View File

@ -90,6 +90,7 @@ async function deleteRecHandler (res: any, object: ReccuringInstance): Promise<v
description: object.description, description: object.description,
date: object.date, date: object.date,
dueDate: object.dueDate, dueDate: object.dueDate,
calendar: object.calendar,
allDay: object.allDay, allDay: object.allDay,
participants: object.participants, participants: object.participants,
externalParticipants: object.externalParticipants, externalParticipants: object.externalParticipants,

View File

@ -37,8 +37,8 @@ export function hidePrivateEvents (events: Event[], calendars: IdMap<Calendar>,
res.push(event) res.push(event)
} }
} else { } else {
const space = calendars.get(event.space) const calendar = calendars.get(event.calendar)
if (space != null && space.visibility !== 'private') { if (calendar != null && calendar.visibility !== 'private') {
res.push(event) res.push(event)
} }
} }
@ -62,11 +62,11 @@ export function isVisible (value: Event, calendars: IdMap<Calendar>): boolean {
} else if (value.visibility === 'public') { } else if (value.visibility === 'public') {
return true return true
} }
const space = calendars.get(value.space) const calendar = calendars.get(value.calendar)
if (space == null) { if (calendar == null) {
return true return true
} else { } else {
return space.visibility === 'public' return calendar.visibility === 'public'
} }
} }
@ -93,7 +93,7 @@ export async function updatePast (ops: DocumentUpdate<Event>, object: ReccuringI
const client = getClient() const client = getClient()
const origin = await client.findOne(calendar.class.ReccuringEvent, { const origin = await client.findOne(calendar.class.ReccuringEvent, {
eventId: object.recurringEventId, eventId: object.recurringEventId,
space: object.space calendar: object.calendar
}) })
if (origin !== undefined) { if (origin !== undefined) {
await client.addCollection( await client.addCollection(
@ -158,6 +158,7 @@ export async function updateReccuringInstance (
reminders: object.reminders, reminders: object.reminders,
location: object.location, location: object.location,
eventId: object.eventId, eventId: object.eventId,
calendar: object.calendar,
access: 'owner', access: 'owner',
rules: object.rules, rules: object.rules,
exdate: object.exdate, exdate: object.exdate,
@ -170,7 +171,7 @@ export async function updateReccuringInstance (
resolve(true) resolve(true)
} else if (res.mode === 'all') { } else if (res.mode === 'all') {
const base = await client.findOne(calendar.class.ReccuringEvent, { const base = await client.findOne(calendar.class.ReccuringEvent, {
space: object.space, calendar: object.calendar,
eventId: object.recurringEventId eventId: object.recurringEventId
}) })
if (base !== undefined) { if (base !== undefined) {

View File

@ -12,7 +12,7 @@
// limitations under the License. // limitations under the License.
import { Contact } from '@hcengineering/contact' import { Contact } from '@hcengineering/contact'
import type { AttachedDoc, Class, Doc, Markup, Mixin, Ref, Space, Timestamp } from '@hcengineering/core' import type { AttachedDoc, Class, Doc, Markup, Mixin, Ref, SystemSpace, Timestamp } from '@hcengineering/core'
import { NotificationType } from '@hcengineering/notification' import { NotificationType } from '@hcengineering/notification'
import type { Asset, IntlString, Metadata, Plugin } from '@hcengineering/platform' import type { Asset, IntlString, Metadata, Plugin } from '@hcengineering/platform'
import { plugin } from '@hcengineering/platform' import { plugin } from '@hcengineering/platform'
@ -27,7 +27,9 @@ export type Visibility = 'public' | 'freeBusy' | 'private'
/** /**
* @public * @public
*/ */
export interface Calendar extends Space { export interface Calendar extends Doc {
name: string
hidden: boolean
visibility: Visibility visibility: Visibility
} }
@ -76,11 +78,13 @@ export interface ReccuringEvent extends Event {
* @public * @public
*/ */
export interface Event extends AttachedDoc { export interface Event extends AttachedDoc {
space: Ref<Calendar> space: Ref<SystemSpace>
eventId: string eventId: string
title: string title: string
description: Markup description: Markup
calendar: Ref<Calendar>
location?: string location?: string
allDay: boolean allDay: boolean
@ -161,8 +165,7 @@ const calendarPlugin = plugin(calendarId, {
Permissions: '' as Asset Permissions: '' as Asset
}, },
space: { space: {
// deprecated Calendar: '' as Ref<SystemSpace>
PersonalEvents: '' as Ref<Calendar>
}, },
app: { app: {
Calendar: '' as Ref<Doc> Calendar: '' as Ref<Doc>

View File

@ -84,14 +84,15 @@
rank: makeRank(undefined, latestTodo?.rank) rank: makeRank(undefined, latestTodo?.rank)
} }
) )
const space = `${acc._id}_calendar` as Ref<Calendar> const _calendar = `${acc._id}_calendar` as Ref<Calendar>
for (const slot of slots) { for (const slot of slots) {
await ops.addCollection(time.class.WorkSlot, space, id, time.class.ToDo, 'workslots', { await ops.addCollection(time.class.WorkSlot, calendar.space.Calendar, id, time.class.ToDo, 'workslots', {
eventId: generateEventId(), eventId: generateEventId(),
date: slot.date, date: slot.date,
dueDate: slot.dueDate, dueDate: slot.dueDate,
description: todo.description, description: todo.description,
participants: [acc.person], participants: [acc.person],
calendar: _calendar,
title: todo.title, title: todo.title,
allDay: false, allDay: false,
access: 'owner', access: 'owner',
@ -107,12 +108,12 @@
} }
const currentUser = getCurrentAccount() as PersonAccount const currentUser = getCurrentAccount() as PersonAccount
let space: Ref<Calendar> = `${currentUser._id}_calendar` as Ref<Calendar> let _calendar: Ref<Calendar> = `${currentUser._id}_calendar` as Ref<Calendar>
const q = createQuery() const q = createQuery()
q.query(calendar.class.ExternalCalendar, { default: true, members: currentUser._id }, (res) => { q.query(calendar.class.ExternalCalendar, { default: true, members: currentUser._id }, (res) => {
if (res.length > 0) { if (res.length > 0) {
space = res[0]._id _calendar = res[0]._id
} }
}) })
@ -142,7 +143,8 @@
access: 'owner', access: 'owner',
visibility: todo.visibility, visibility: todo.visibility,
reminders: [], reminders: [],
space, calendar: _calendar,
space: calendar.space.Calendar,
_id: generateId(), _id: generateId(),
_class: time.class.WorkSlot, _class: time.class.WorkSlot,
attachedTo: generateId(), attachedTo: generateId(),

View File

@ -45,7 +45,7 @@
let description = object.description let description = object.description
let visibility = object.visibility ?? 'public' let visibility = object.visibility ?? 'public'
let space = object.space let _calendar = object.calendar
let _doc: ToDo | undefined let _doc: ToDo | undefined
@ -84,8 +84,8 @@
if (object.visibility !== visibility) { if (object.visibility !== visibility) {
update.visibility = visibility update.visibility = visibility
} }
if (object.space !== space) { if (object.calendar !== _calendar) {
update.space = space update.calendar = _calendar
} }
if (!deepEqual(object.reminders, reminders)) { if (!deepEqual(object.reminders, reminders)) {
update.reminders = reminders update.reminders = reminders
@ -137,7 +137,7 @@
<TaskSelector bind:value={_doc} focusIndex={10006} /> <TaskSelector bind:value={_doc} focusIndex={10006} />
</div> </div>
<div class="block rightCropPadding"> <div class="block rightCropPadding">
<CalendarSelector bind:value={space} disabled={readOnly} focusIndex={10007} /> <CalendarSelector bind:value={_calendar} disabled={readOnly} focusIndex={10007} />
<div class="flex-row-center flex-gap-1"> <div class="flex-row-center flex-gap-1">
<Icon icon={calendar.icon.Hidden} size={'small'} /> <Icon icon={calendar.icon.Hidden} size={'small'} />
<VisibilityEditor bind:value={visibility} kind={'tertiary'} withoutIcon disabled={readOnly} focusIndex={10008} /> <VisibilityEditor bind:value={visibility} kind={'tertiary'} withoutIcon disabled={readOnly} focusIndex={10008} />

View File

@ -53,12 +53,13 @@
const currentUser = getCurrentAccount() as PersonAccount const currentUser = getCurrentAccount() as PersonAccount
const extCalendar = await client.findOne(calendar.class.ExternalCalendar, { const extCalendar = await client.findOne(calendar.class.ExternalCalendar, {
members: currentUser._id, members: currentUser._id,
archived: false, hidden: false,
default: true default: true
}) })
const space = extCalendar ? extCalendar._id : (`${currentUser._id}_calendar` as Ref<Calendar>) const _calendar = extCalendar ? extCalendar._id : (`${currentUser._id}_calendar` as Ref<Calendar>)
const dueDate = date + defaultDuration const dueDate = date + defaultDuration
await client.addCollection(time.class.WorkSlot, space, doc._id, doc._class, 'workslots', { await client.addCollection(time.class.WorkSlot, calendar.space.Calendar, doc._id, doc._class, 'workslots', {
calendar: _calendar,
eventId: generateEventId(), eventId: generateEventId(),
date, date,
dueDate, dueDate,

View File

@ -55,7 +55,7 @@
let calendars: Calendar[] = [] let calendars: Calendar[] = []
let todayDate = new Date() let todayDate = new Date()
$: calendarsQ.query(calendar.class.Calendar, { members: acc, archived: false }, (res) => { $: calendarsQ.query(calendar.class.Calendar, { createdBy: acc, hidden: false }, (res) => {
calendars = res calendars = res
}) })
@ -65,7 +65,7 @@
function update (calendars: Calendar[]): void { function update (calendars: Calendar[]): void {
q.query<Event>( q.query<Event>(
calendar.class.Event, calendar.class.Event,
{ space: { $in: calendars.map((p) => p._id) } }, { calendar: { $in: calendars.map((p) => p._id) } },
(result) => { (result) => {
raw = result raw = result
}, },
@ -115,7 +115,7 @@
current.dueDate = new Date(e.detail.date).setMinutes(new Date(e.detail.date).getMinutes() + 30) current.dueDate = new Date(e.detail.date).setMinutes(new Date(e.detail.date).getMinutes() + 30)
} else { } else {
const me = getCurrentAccount() as PersonAccount const me = getCurrentAccount() as PersonAccount
const space = `${me._id}_calendar` as Ref<Calendar> const _calendar = `${me._id}_calendar` as Ref<Calendar>
const ev: WorkSlot = { const ev: WorkSlot = {
_id: dragItemId, _id: dragItemId,
allDay: false, allDay: false,
@ -128,7 +128,8 @@
_class: time.class.WorkSlot, _class: time.class.WorkSlot,
collection: 'events', collection: 'events',
visibility: 'public', visibility: 'public',
space, calendar: _calendar,
space: calendar.space.Calendar,
modifiedBy: me._id, modifiedBy: me._id,
participants: [me.person], participants: [me.person],
modifiedOn: Date.now(), modifiedOn: Date.now(),

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
--> -->
<script lang="ts"> <script lang="ts">
import { Calendar, generateEventId } from '@hcengineering/calendar' import calendar, { Calendar, generateEventId } from '@hcengineering/calendar'
import contact, { PersonAccount } from '@hcengineering/contact' import contact, { PersonAccount } from '@hcengineering/contact'
import { Ref, getCurrentAccount } from '@hcengineering/core' import { Ref, getCurrentAccount } from '@hcengineering/core'
import { createQuery, getClient } from '@hcengineering/presentation' import { createQuery, getClient } from '@hcengineering/presentation'
@ -55,12 +55,13 @@
const now = Date.now() const now = Date.now()
const date = Math.ceil(now / (30 * 60 * 1000)) * (30 * 60 * 1000) const date = Math.ceil(now / (30 * 60 * 1000)) * (30 * 60 * 1000)
const currentUser = getCurrentAccount() as PersonAccount const currentUser = getCurrentAccount() as PersonAccount
const space = `${currentUser._id}_calendar` as Ref<Calendar> const _calendar = `${currentUser._id}_calendar` as Ref<Calendar>
const dueDate = date + defaultDuration const dueDate = date + defaultDuration
await client.addCollection(time.class.WorkSlot, space, todo._id, todo._class, 'workslots', { await client.addCollection(time.class.WorkSlot, calendar.space.Calendar, todo._id, todo._class, 'workslots', {
eventId: generateEventId(), eventId: generateEventId(),
date, date,
dueDate, dueDate,
calendar: _calendar,
description: todo.description, description: todo.description,
participants: [currentUser.person], participants: [currentUser.person],
title: todo.title, title: todo.title,

View File

@ -60,7 +60,7 @@
calendar.class.Event, calendar.class.Event,
{ {
_class: { $nin: [calendar.class.ReccuringEvent] }, _class: { $nin: [calendar.class.ReccuringEvent] },
space: { $in: calendarIds }, calendar: { $in: calendarIds },
date: { $lte: toDate }, date: { $lte: toDate },
dueDate: { $gte: fromDate }, dueDate: { $gte: fromDate },
participants: { $in: persons } as any participants: { $in: persons } as any
@ -72,7 +72,7 @@
$: queryR.query( $: queryR.query(
calendar.class.ReccuringEvent, calendar.class.ReccuringEvent,
{ space: { $in: calendarIds }, participants: { $in: persons } as any }, { calendar: { $in: calendarIds }, participants: { $in: persons } as any },
(res) => { (res) => {
rawReq = res rawReq = res
} }
@ -98,7 +98,7 @@
) )
const calendarQuery = createQuery() const calendarQuery = createQuery()
$: calendarQuery.query(calendar.class.Calendar, { archived: false }, (res) => { $: calendarQuery.query(calendar.class.Calendar, { hidden: false }, (res) => {
calendarIds = res.map((p) => p._id) calendarIds = res.map((p) => p._id)
calendars = toIdMap(res) calendars = toIdMap(res)
}) })

View File

@ -91,15 +91,11 @@ export function groupTeamData (
} }
for (const event of events) { for (const event of events) {
const space = calendars.get(event.space) const _calendar = calendars.get(event.calendar)
if (space === undefined) { if (_calendar === undefined) {
continue continue
} }
for (const p of event.participants) { for (const p of event.participants) {
const accounts = personAccounts.filter((it) => it.person === p)
if (!accounts.some((it) => space.members.includes(it._id))) {
continue
}
const mapping: EventPersonMapping = result.get(p) ?? { const mapping: EventPersonMapping = result.get(p) ?? {
busy: { busy: {
slots: [], slots: [],

View File

@ -15,7 +15,7 @@
import calendar, { Calendar, Event } from '@hcengineering/calendar' import calendar, { Calendar, Event } from '@hcengineering/calendar'
import { PersonAccount } from '@hcengineering/contact' import { PersonAccount } from '@hcengineering/contact'
import core, { import {
Class, Class,
Doc, Doc,
DocumentQuery, DocumentQuery,
@ -85,13 +85,10 @@ export async function OnPersonAccountCreate (tx: Tx, control: TriggerControl): P
const res: TxCreateDoc<Calendar> = control.txFactory.createTxCreateDoc( const res: TxCreateDoc<Calendar> = control.txFactory.createTxCreateDoc(
calendar.class.Calendar, calendar.class.Calendar,
core.space.Space, calendar.space.Calendar,
{ {
name: user.email, name: user.email,
description: '', hidden: false,
archived: false,
private: false,
members: [user._id],
visibility: 'public' visibility: 'public'
}, },
`${user._id}_calendar` as Ref<Calendar>, `${user._id}_calendar` as Ref<Calendar>,