mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-24 17:30:03 +00:00
Fix team planning event disappear (#5581)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
parent
7d7e1ef412
commit
75474a6311
@ -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",
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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 />
|
||||||
|
@ -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,
|
||||||
|
@ -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} />
|
||||||
|
@ -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>
|
||||||
|
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
@ -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>
|
||||||
|
@ -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(),
|
||||||
|
@ -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} />
|
||||||
|
@ -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,
|
||||||
|
@ -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(),
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
})
|
})
|
||||||
|
@ -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: [],
|
||||||
|
@ -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>,
|
||||||
|
Loading…
Reference in New Issue
Block a user