mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 11:01:54 +03:00
Remove duplicated directs (#6516)
This commit is contained in:
parent
1daec4def4
commit
42abc31ab4
@ -74,7 +74,10 @@ export { chunterOperation } from './migration'
|
||||
export const DOMAIN_CHUNTER = 'chunter' as Domain
|
||||
|
||||
@Model(chunter.class.ChunterSpace, core.class.Space)
|
||||
export class TChunterSpace extends TSpace implements ChunterSpace {}
|
||||
export class TChunterSpace extends TSpace implements ChunterSpace {
|
||||
@Prop(PropCollection(activity.class.ActivityMessage), chunter.string.Messages)
|
||||
messages?: number
|
||||
}
|
||||
|
||||
@Model(chunter.class.Channel, chunter.class.ChunterSpace)
|
||||
@UX(chunter.string.Channel, chunter.icon.Hashtag, undefined, undefined, undefined, chunter.string.Channels)
|
||||
|
@ -13,7 +13,7 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { chunterId, type ThreadMessage } from '@hcengineering/chunter'
|
||||
import { chunterId, type DirectMessage, type ThreadMessage } from '@hcengineering/chunter'
|
||||
import core, {
|
||||
type Account,
|
||||
TxOperations,
|
||||
@ -33,12 +33,13 @@ import {
|
||||
} from '@hcengineering/model'
|
||||
import activity, { migrateMessagesSpace, DOMAIN_ACTIVITY } from '@hcengineering/model-activity'
|
||||
import notification from '@hcengineering/notification'
|
||||
import contactPlugin, { type PersonAccount } from '@hcengineering/contact'
|
||||
import { DOMAIN_NOTIFICATION } from '@hcengineering/model-notification'
|
||||
import contactPlugin, { type Person, type PersonAccount } from '@hcengineering/contact'
|
||||
import { DOMAIN_DOC_NOTIFY, DOMAIN_NOTIFICATION } from '@hcengineering/model-notification'
|
||||
import { type DocUpdateMessage } from '@hcengineering/activity'
|
||||
import { DOMAIN_SPACE } from '@hcengineering/model-core'
|
||||
|
||||
import chunter from './plugin'
|
||||
import { DOMAIN_CHUNTER } from './index'
|
||||
import { type DocUpdateMessage } from '@hcengineering/activity'
|
||||
|
||||
export const DOMAIN_COMMENT = 'comment' as Domain
|
||||
|
||||
@ -239,6 +240,53 @@ async function removeWrongActivity (client: MigrationClient): Promise<void> {
|
||||
})
|
||||
}
|
||||
|
||||
async function removeDuplicatedDirects (client: MigrationClient): Promise<void> {
|
||||
const directs = await client.find<DirectMessage>(DOMAIN_SPACE, { _class: chunter.class.DirectMessage })
|
||||
const personAccounts = await client.model.findAll<PersonAccount>(contactPlugin.class.PersonAccount, {})
|
||||
const personByAccount = new Map(personAccounts.map((it) => [it._id, it.person]))
|
||||
|
||||
const accountsToPersons = (members: Ref<Account>[]): Ref<Person>[] => {
|
||||
const personsSet = new Set(
|
||||
members
|
||||
.map((it) => personByAccount.get(it as Ref<PersonAccount>))
|
||||
.filter((it): it is Ref<Person> => it !== undefined)
|
||||
)
|
||||
return Array.from(personsSet)
|
||||
}
|
||||
|
||||
const map: Map<string, DirectMessage[]> = new Map<string, DirectMessage[]>()
|
||||
const toRemove: Ref<DirectMessage>[] = []
|
||||
|
||||
for (const direct of directs) {
|
||||
const persons = accountsToPersons(direct.members)
|
||||
|
||||
if (persons.length === 0) {
|
||||
toRemove.push(direct._id)
|
||||
continue
|
||||
}
|
||||
|
||||
const key = persons.sort().join(',')
|
||||
|
||||
if (!map.has(key)) {
|
||||
map.set(key, [direct])
|
||||
} else {
|
||||
map.get(key)?.push(direct)
|
||||
}
|
||||
}
|
||||
|
||||
for (const [, directs] of map) {
|
||||
if (directs.length === 1) continue
|
||||
const toSave = directs.reduce((acc, it) => ((it.messages ?? 0) > (acc.messages ?? 0) ? it : acc), directs[0])
|
||||
const rest = directs.filter((it) => it._id !== toSave._id)
|
||||
toRemove.push(...rest.map((it) => it._id))
|
||||
}
|
||||
|
||||
await client.deleteMany(DOMAIN_SPACE, { _id: { $in: toRemove } })
|
||||
await client.deleteMany(DOMAIN_ACTIVITY, { attachedTo: { $in: toRemove } })
|
||||
await client.deleteMany(DOMAIN_ACTIVITY, { objectId: { $in: toRemove } })
|
||||
await client.deleteMany(DOMAIN_DOC_NOTIFY, { objectId: { $in: toRemove } })
|
||||
}
|
||||
|
||||
export const chunterOperation: MigrateOperation = {
|
||||
async migrate (client: MigrationClient): Promise<void> {
|
||||
await tryMigrate(client, chunterId, [
|
||||
@ -283,6 +331,12 @@ export const chunterOperation: MigrateOperation = {
|
||||
func: async (client) => {
|
||||
await removeWrongActivity(client)
|
||||
}
|
||||
},
|
||||
{
|
||||
state: 'remove-duplicated-directs-v1',
|
||||
func: async (client) => {
|
||||
await removeDuplicatedDirects(client)
|
||||
}
|
||||
}
|
||||
])
|
||||
},
|
||||
|
@ -17,9 +17,9 @@
|
||||
import { deepEqual } from 'fast-equals'
|
||||
|
||||
import { DirectMessage } from '@hcengineering/chunter'
|
||||
import contact, { Employee, PersonAccount } from '@hcengineering/contact'
|
||||
import contact, { Employee, Person, PersonAccount } from '@hcengineering/contact'
|
||||
import core, { getCurrentAccount, Ref } from '@hcengineering/core'
|
||||
import { SelectUsersPopup } from '@hcengineering/contact-resources'
|
||||
import { personIdByAccountId, SelectUsersPopup } from '@hcengineering/contact-resources'
|
||||
import notification from '@hcengineering/notification'
|
||||
import presentation, { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { Modal, showPopup } from '@hcengineering/ui'
|
||||
@ -55,15 +55,31 @@
|
||||
const accIds = [myAcc._id, ...employeeAccounts.filter(({ _id }) => _id !== myAcc._id).map(({ _id }) => _id)].sort()
|
||||
|
||||
const existingDms = await client.findAll(chunter.class.DirectMessage, {})
|
||||
const newDirectPersons = Array.from(new Set([...employeeIds, myAcc.person])).sort()
|
||||
|
||||
let direct: DirectMessage | undefined
|
||||
|
||||
for (const dm of existingDms) {
|
||||
if (deepEqual(dm.members.sort(), accIds)) {
|
||||
const existDirectPersons = Array.from(
|
||||
new Set(dm.members.map((id) => $personIdByAccountId.get(id as Ref<PersonAccount>)))
|
||||
)
|
||||
.filter((person): person is Ref<Person> => person !== undefined)
|
||||
.sort()
|
||||
if (deepEqual(existDirectPersons, newDirectPersons)) {
|
||||
direct = dm
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const existingMembers = direct?.members
|
||||
const missingAccounts = existingMembers !== undefined ? accIds.filter((id) => !existingMembers.includes(id)) : []
|
||||
|
||||
if (direct !== undefined && missingAccounts.length > 0) {
|
||||
await client.updateDoc(chunter.class.DirectMessage, direct.space, direct._id, {
|
||||
members: [...direct.members, ...missingAccounts]
|
||||
})
|
||||
}
|
||||
|
||||
const dmId =
|
||||
direct?._id ??
|
||||
(await client.createDoc(chunter.class.DirectMessage, core.space.Space, {
|
||||
@ -75,12 +91,13 @@
|
||||
}))
|
||||
|
||||
const context = await client.findOne(notification.class.DocNotifyContext, {
|
||||
person: myAcc.person,
|
||||
user: myAcc._id,
|
||||
objectId: dmId,
|
||||
objectClass: chunter.class.DirectMessage
|
||||
})
|
||||
|
||||
if (context !== undefined) {
|
||||
dispatch('close')
|
||||
openChannel(dmId, chunter.class.DirectMessage)
|
||||
|
||||
return
|
||||
@ -97,6 +114,7 @@
|
||||
})
|
||||
|
||||
openChannel(dmId, chunter.class.DirectMessage)
|
||||
dispatch('close')
|
||||
}
|
||||
|
||||
function handleCancel (): void {
|
||||
|
@ -25,7 +25,9 @@ import { Person, ChannelProvider as SocialChannelProvider } from '@hcengineering
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface ChunterSpace extends Space {}
|
||||
export interface ChunterSpace extends Space {
|
||||
messages?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
|
@ -16,38 +16,38 @@
|
||||
|
||||
import {
|
||||
AvatarType,
|
||||
type Channel,
|
||||
type ChannelProvider,
|
||||
type Contact,
|
||||
contactId,
|
||||
type Employee,
|
||||
formatName,
|
||||
getFirstName,
|
||||
getLastName,
|
||||
getName,
|
||||
type Channel,
|
||||
type ChannelProvider,
|
||||
type Contact,
|
||||
type Employee,
|
||||
type Person,
|
||||
type PersonAccount
|
||||
} from '@hcengineering/contact'
|
||||
import core, {
|
||||
getCurrentAccount,
|
||||
toIdMap,
|
||||
type Account,
|
||||
AggregateValue,
|
||||
AggregateValueData,
|
||||
type Class,
|
||||
type Client,
|
||||
type Doc,
|
||||
type DocumentQuery,
|
||||
getCurrentAccount,
|
||||
type Hierarchy,
|
||||
type IdMap,
|
||||
matchQuery,
|
||||
type ObjQueryType,
|
||||
type Ref,
|
||||
type Space,
|
||||
type Timestamp,
|
||||
toIdMap,
|
||||
type TxOperations,
|
||||
type UserStatus,
|
||||
type WithLookup,
|
||||
AggregateValue,
|
||||
type Space,
|
||||
type Hierarchy,
|
||||
type DocumentQuery,
|
||||
AggregateValueData,
|
||||
matchQuery
|
||||
type WithLookup
|
||||
} from '@hcengineering/core'
|
||||
import notification, { type DocNotifyContext, type InboxNotification } from '@hcengineering/notification'
|
||||
import { getEmbeddedLabel, getResource, translate } from '@hcengineering/platform'
|
||||
@ -61,8 +61,8 @@ import {
|
||||
type ResolvedLocation,
|
||||
type TabItem
|
||||
} from '@hcengineering/ui'
|
||||
import view, { type GrouppingManager, type Filter } from '@hcengineering/view'
|
||||
import { FilterQuery, accessDeniedStore } from '@hcengineering/view-resources'
|
||||
import view, { type Filter, type GrouppingManager } from '@hcengineering/view'
|
||||
import { accessDeniedStore, FilterQuery } from '@hcengineering/view-resources'
|
||||
import { derived, get, writable } from 'svelte/store'
|
||||
|
||||
import contact from './plugin'
|
||||
@ -305,6 +305,10 @@ export const channelProviders = writable<ChannelProvider[]>([])
|
||||
|
||||
export const personAccountPersonByIdStore = writable<IdMap<WithLookup<Person>>>(new Map())
|
||||
|
||||
export const personIdByAccountId = derived(personAccountByIdStore, (vals) => {
|
||||
return new Map<Ref<PersonAccount>, Ref<Person>>(Array.from(vals.values()).map((it) => [it._id, it.person]))
|
||||
})
|
||||
|
||||
export const statusByUserStore = writable<Map<Ref<Account>, UserStatus>>(new Map())
|
||||
|
||||
export const personByIdStore = derived([personAccountPersonByIdStore, employeeByIdStore], (vals) => {
|
||||
|
Loading…
Reference in New Issue
Block a user