Spaces in domain (#1151)

Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
This commit is contained in:
Denis Bykhov 2022-03-17 11:05:30 +06:00 committed by GitHub
parent 45fc18fe31
commit 2612cd5b13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 409 additions and 162 deletions

View File

@ -97,7 +97,7 @@ async function genVacansyApplicants (
// Update or create candidate
await ctx.with('update', {}, (ctx) =>
findOrUpdate(ctx, client, core.space.Model, recruit.class.Vacancy, vacancyId, vacancy)
findOrUpdate(ctx, client, core.space.Space, recruit.class.Vacancy, vacancyId, vacancy)
)
console.log('Vacandy generated', vacancy.name)

View File

@ -246,7 +246,7 @@ async function createUpdateVacancy (client: TxOperations, statuses: any): Promis
console.log('Creating vacancy', vacancy.name)
// Update or create candidate
await findOrUpdate(client, core.space.Model, recruit.class.Vacancy, vacancyId, vacancy)
await findOrUpdate(client, core.space.Space, recruit.class.Vacancy, vacancyId, vacancy)
const states = await createUpdateSpaceKanban(vacancyId, client, statuses)

View File

@ -13,22 +13,29 @@
// limitations under the License.
//
import { MigrateOperation } from '@anticrm/model'
// Import migrate operations.
import { coreOperation } from '@anticrm/model-core'
import { taskOperation } from '@anticrm/model-task'
import { MigrateOperation } from '@anticrm/model'
import { attachmentOperation } from '@anticrm/model-attachment'
import { chunterOperation } from '@anticrm/model-chunter'
import { contactOperation } from '@anticrm/model-contact'
import { coreOperation } from '@anticrm/model-core'
import { gmailOperation } from '@anticrm/model-gmail'
import { leadOperation } from '@anticrm/model-lead'
import { notificationOperation } from '@anticrm/model-notification'
import { settingOperation } from '@anticrm/model-setting'
import { recruitOperation } from '@anticrm/model-recruit'
import { viewOperation } from '@anticrm/model-view'
import { contactOperation } from '@anticrm/model-contact'
import { tagsOperation } from '@anticrm/model-tags'
import { taskOperation } from '@anticrm/model-task'
import { telegramOperation } from '@anticrm/model-telegram'
import { templatesOperation } from '@anticrm/model-templates'
import { viewOperation } from '@anticrm/model-view'
export const migrateOperations: MigrateOperation[] = [
coreOperation,
chunterOperation,
gmailOperation,
templatesOperation,
telegramOperation,
taskOperation,
attachmentOperation,
leadOperation,

View File

@ -99,20 +99,6 @@ export function createModel (builder: Builder): void {
]
}
}, chunter.app.Chunter)
builder.createDoc(chunter.class.Channel, core.space.Model, {
name: 'general',
description: 'General Channel',
private: false,
archived: false,
members: []
}, chunter.space.General)
builder.createDoc(chunter.class.Channel, core.space.Model, {
name: 'random',
description: 'Random Talks',
private: false,
archived: false,
members: []
}, chunter.space.Random)
builder.mixin(chunter.class.Comment, core.class.Class, view.mixin.AttributePresenter, {
presenter: chunter.component.CommentPresenter
@ -164,4 +150,6 @@ export function createModel (builder: Builder): void {
}, chunter.ids.TxBacklinkRemove)
}
export { chunterOperation } from './migration'
export default chunter

View File

@ -0,0 +1,66 @@
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import type { Client } from '@anticrm/core'
import core, { TxOperations } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import chunter from './plugin'
export async function createDeps (client: Client): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createGeneral(tx)
await createRandom(tx)
}
export async function createGeneral (tx: TxOperations): Promise<void> {
const createTx = await tx.findOne(core.class.TxCreateDoc, {
objectId: chunter.space.General
})
if (createTx === undefined) {
await tx.createDoc(chunter.class.Channel, core.space.Space, {
name: 'general',
description: 'General Channel',
private: false,
archived: false,
members: []
}, chunter.space.General)
}
}
export async function createRandom (tx: TxOperations): Promise<void> {
const createTx = await tx.findOne(core.class.TxCreateDoc, {
objectId: chunter.space.Random
})
if (createTx === undefined) {
await tx.createDoc(chunter.class.Channel, core.space.Space, {
name: 'random',
description: 'Random Talks',
private: false,
archived: false,
members: []
}, chunter.space.Random)
}
}
export const chunterOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createGeneral(tx)
await createRandom(tx)
}
}

View File

@ -224,19 +224,6 @@ export function createModel (builder: Builder): void {
contact.channelProvider.Facebook
)
builder.createDoc(
core.class.Space,
core.space.Model,
{
name: 'Employees',
description: 'Employees',
private: false,
archived: false,
members: []
},
contact.space.Employee
)
builder.mixin(contact.class.Person, core.class.Class, view.mixin.AttributePresenter, {
presenter: contact.component.PersonPresenter
})

View File

@ -15,7 +15,7 @@
//
import { Channel, ChannelProvider, Contact } from '@anticrm/contact'
import { Class, DOMAIN_TX, generateId, Ref, SortingOrder, TxCreateDoc, TxCUD, TxRemoveDoc, TxUpdateDoc } from '@anticrm/core'
import { Class, DOMAIN_TX, generateId, Ref, SortingOrder, TxCreateDoc, TxCUD, TxOperations, TxRemoveDoc, TxUpdateDoc } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import core from '@anticrm/model-core'
import contact, { DOMAIN_CHANNEL, DOMAIN_CONTACT } from './index'
@ -207,6 +207,26 @@ async function migrateChannelsDomain (client: MigrationClient): Promise<void> {
await client.move(DOMAIN_CONTACT, { _class: contact.class.Channel }, DOMAIN_CHANNEL)
}
async function createSpace (tx: TxOperations): Promise<void> {
const current = await tx.findOne(core.class.Space, {
_id: contact.space.Employee
})
if (current === undefined) {
await tx.createDoc(
core.class.Space,
core.space.Space,
{
name: 'Employees',
description: 'Employees',
private: false,
archived: false,
members: []
},
contact.space.Employee
)
}
}
export const contactOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
const classes = [contact.class.Contact, contact.class.Person, contact.class.Employee, contact.class.Organization]
@ -214,5 +234,7 @@ export const contactOperation: MigrateOperation = {
await migrateChannelsDomain(client)
},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createSpace(tx)
}
}

View File

@ -13,17 +13,58 @@
// limitations under the License.
//
import { TxOperations } from '@anticrm/core'
import { DOMAIN_TX, TxOperations } from '@anticrm/core'
import {
MigrateOperation,
MigrationClient,
MigrationUpgradeClient
} from '@anticrm/model'
import core from './component'
async function migrateSpaces (client: MigrationUpgradeClient): Promise<void> {
const currentSpaces = (await client.findAll(core.class.Space, {})).map((s) => s._id)
const descendants = client.getHierarchy().getDescendants(core.class.Space)
const removedSpaces = (await client.findAll(core.class.TxRemoveDoc, { objectClass: { $in: descendants } })).map((s) => s.objectId)
let createTxes = await client.findAll(core.class.TxCreateDoc, {
objectClass: { $in: descendants },
objectId: { $nin: [...currentSpaces, ...removedSpaces] }
})
// TXes already stored, avoid dublicate id error
createTxes = createTxes.map((p) => {
return {
...p,
space: core.space.DerivedTx
}
})
await Promise.all(createTxes.map(async (tx) => await client.tx(tx)))
let updateTxes = await client.findAll(core.class.TxUpdateDoc, {
objectClass: { $in: descendants },
objectId: { $nin: [...currentSpaces, ...removedSpaces] }
})
// TXes already stored, avoid dublicate id error
updateTxes = updateTxes.map((p) => {
return {
...p,
space: core.space.DerivedTx
}
})
await Promise.all(updateTxes.map(async (tx) => await client.tx(tx)))
}
export const coreOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {},
async migrate (client: MigrationClient): Promise<void> {
await client.update(DOMAIN_TX, {
objectSpace: core.space.Model,
objectClass: {
$in: ['core:class:Space', 'contact:class:Organizations', 'contact:class:Persons',
'chunter:class:Channel', 'task:class:SpaceWithStates', 'task:class:Project', 'recruit:class:ReviewCategory',
'recruit:class:Candidates', 'recruit:class:Vacancy', 'lead:class:Funnel']
}
}, {
objectSpace: core.space.Space
})
},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const targetSpaces = (await client.findAll(core.class.Space, {}))
.filter((space) => space.archived == null)
@ -32,5 +73,7 @@ export const coreOperation: MigrateOperation = {
await Promise.all(targetSpaces.map(
(space) => new TxOperations(client, space.modifiedBy).updateDoc(space._class, space.space, space._id, { archived: false })
)).catch((e) => console.error(e))
await migrateSpaces(client)
}
}

View File

@ -13,14 +13,16 @@
// limitations under the License.
//
import { Account, Arr, DOMAIN_MODEL, IndexKind, Ref, Space } from '@anticrm/core'
import { Account, Arr, Domain, DOMAIN_MODEL, IndexKind, Ref, Space } from '@anticrm/core'
import { Index, Model, Prop, TypeBoolean, TypeString } from '@anticrm/model'
import core from './component'
import { TDoc } from './core'
export const DOMAIN_SPACE = 'space' as Domain
// S P A C E
@Model(core.class.Space, core.class.Doc, DOMAIN_MODEL)
@Model(core.class.Space, core.class.Doc, DOMAIN_SPACE)
export class TSpace extends TDoc implements Space {
@Prop(TypeString(), core.string.Name)
@Index(IndexKind.FullText)

View File

@ -132,19 +132,6 @@ export function createModel (builder: Builder): void {
gmail.integrationType.Gmail
)
builder.createDoc(
core.class.Space,
core.space.Model,
{
name: 'Gmail',
description: 'Space for all gmail messages',
private: false,
archived: false,
members: []
},
gmail.space.Gmail
)
builder.createDoc(
activity.class.TxViewlet,
core.space.Model,
@ -159,3 +146,5 @@ export function createModel (builder: Builder): void {
gmail.ids.TxSharedCreate
)
}
export { gmailOperation } from './migration'

View File

@ -0,0 +1,43 @@
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import core, { TxOperations } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import gmail from './plugin'
export const gmailOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
const current = await tx.findOne(core.class.Space, {
_id: gmail.space.Gmail
})
if (current === undefined) {
await tx.createDoc(
core.class.Space,
core.space.Space,
{
name: 'Gmail',
description: 'Space for all gmail messages',
private: false,
archived: false,
members: []
},
gmail.space.Gmail
)
}
}
}

View File

@ -104,18 +104,6 @@ export function createModel (builder: Builder): void {
},
lead.app.Lead
)
builder.createDoc(
lead.class.Funnel,
core.space.Model,
{
name: 'Funnel',
description: 'Default funnel',
private: false,
archived: false,
members: []
},
lead.space.DefaultFunnel
)
builder.createDoc(view.class.Viewlet, core.space.Model, {
attachTo: lead.mixin.Customer,

View File

@ -29,6 +29,26 @@ function logInfo (msg: string, result: MigrationResult): void {
}
}
async function createSpace (tx: TxOperations): Promise<void> {
const current = await tx.findOne(core.class.Space, {
_id: lead.space.DefaultFunnel
})
if (current === undefined) {
await tx.createDoc(
lead.class.Funnel,
core.space.Space,
{
name: 'Funnel',
description: 'Default funnel',
private: false,
archived: false,
members: []
},
lead.space.DefaultFunnel
)
}
}
export const leadOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
// Update done states for tasks
@ -52,6 +72,7 @@ export const leadOperation: MigrateOperation = {
console.log('Lead: Performing model upgrades')
const ops = new TxOperations(client, core.account.System)
await createSpace(ops)
const leads = await client.findAll(lead.class.Lead, {})
for (const lead of leads) {

View File

@ -191,18 +191,6 @@ export function createModel (builder: Builder): void {
},
recruit.app.Recruit
)
builder.createDoc(
recruit.class.Candidates,
core.space.Model,
{
name: 'public',
description: 'Public Candidates',
private: false,
members: [],
archived: false
},
recruit.space.CandidatesPublic
)
builder.createDoc(view.class.Viewlet, core.space.Model, {
attachTo: recruit.mixin.Candidate,

View File

@ -161,6 +161,8 @@ export const recruitOperation: MigrateOperation = {
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createSpace(tx)
await createOrUpdate(
tx,
tags.class.TagCategory,
@ -206,6 +208,27 @@ export const recruitOperation: MigrateOperation = {
await createSequence(tx, recruit.class.Opinion)
}
}
async function createSpace (tx: TxOperations): Promise<void> {
const current = await tx.findOne(core.class.Space, {
_id: recruit.space.CandidatesPublic
})
if (current === undefined) {
await tx.createDoc(
recruit.class.Candidates,
core.space.Space,
{
name: 'public',
description: 'Public Candidates',
private: false,
members: [],
archived: false
},
recruit.space.CandidatesPublic
)
}
}
async function migrateUpdateCandidateToPersonAndMixin (client: MigrationClient): Promise<void> {
const updateCandidates = await client.find(DOMAIN_TX, {
_class: core.class.TxUpdateDoc,

View File

@ -84,19 +84,6 @@ export class TTagCategory extends TDoc implements TagCategory {
export function createModel (builder: Builder): void {
builder.createModel(TTagElement, TTagReference, TTagCategory)
builder.createDoc(
core.class.Space,
core.space.Model,
{
name: 'Tags',
description: 'Space for all tags',
private: true,
archived: false,
members: []
},
tags.space.Tags
)
builder.mixin(tags.class.TagReference, core.class.Class, view.mixin.AttributeEditor, {
editor: tags.component.Tags
})

View File

@ -1,7 +1,27 @@
import core, { TxOperations } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import tags from './plugin'
export const tagsOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
const current = await tx.findOne(core.class.Space, {
_id: tags.space.Tags
})
if (current === undefined) {
await tx.createDoc(
core.class.Space,
core.space.Space,
{
name: 'Tags',
description: 'Space for all tags',
private: true,
archived: false,
members: []
},
tags.space.Tags
)
}
}
}

View File

@ -330,19 +330,6 @@ export function createModel (builder: Builder): void {
card: task.component.KanbanCard
})
builder.createDoc(
task.class.Project,
core.space.Model,
{
name: 'public',
description: 'Public tasks',
private: false,
archived: false,
members: []
},
task.space.TasksPublic
)
builder.createDoc(
task.class.KanbanTemplateSpace,
core.space.Model,
@ -433,19 +420,6 @@ export function createModel (builder: Builder): void {
task.viewlet.Kanban
)
builder.createDoc(
core.class.Space,
core.space.Model,
{
name: 'Sequences',
description: 'Internal space to store sequence numbers',
members: [],
private: false,
archived: false
},
task.space.Sequence
)
builder.mixin(task.class.DoneState, core.class.Class, view.mixin.AttributePresenter, {
presenter: task.component.DoneStatePresenter
})

View File

@ -52,6 +52,46 @@ async function migrateClass<T extends Doc> (
)
}
async function createDefaultProject (tx: TxOperations): Promise<void> {
const createTx = await tx.findOne(core.class.TxCreateDoc, {
objectId: task.space.TasksPublic
})
if (createTx === undefined) {
await tx.createDoc(
task.class.Project,
core.space.Space,
{
name: 'public',
description: 'Public tasks',
private: false,
archived: false,
members: []
},
task.space.TasksPublic
)
}
}
async function createDefaultSequence (tx: TxOperations): Promise<void> {
const current = await tx.findOne(core.class.Space, {
_id: task.space.Sequence
})
if (current === undefined) {
await tx.createDoc(
core.class.Space,
core.space.Space,
{
name: 'Sequences',
description: 'Internal space to store sequence numbers',
members: [],
private: false,
archived: false
},
task.space.Sequence
)
}
}
export const taskOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
// Since we should not have Task class instances, we convert them all to Issue.
@ -138,6 +178,8 @@ export const taskOperation: MigrateOperation = {
}
const tx = new TxOperations(client, core.account.System)
await createDefaultSequence(tx)
await createDefaultProject(tx)
// To not depend on ui package let's use inlined ones one time
const colors = new Map([

View File

@ -97,19 +97,6 @@ export function createModel (builder: Builder): void {
telegram.integrationType.Telegram
)
builder.createDoc(
core.class.Space,
core.space.Model,
{
name: 'Telegram',
description: 'Space for all telegram messages',
private: false,
archived: false,
members: []
},
telegram.space.Telegram
)
builder.createDoc(
activity.class.TxViewlet,
core.space.Model,
@ -124,3 +111,5 @@ export function createModel (builder: Builder): void {
telegram.ids.TxSharedCreate
)
}
export { telegramOperation } from './migration'

View File

@ -0,0 +1,42 @@
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import core, { TxOperations } from '@anticrm/core'
import telegram from './plugin'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
export const telegramOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
const current = await tx.findOne(core.class.Space, {
_id: telegram.space.Telegram
})
if (current === undefined) {
await tx.createDoc(
core.class.Space,
core.space.Space,
{
name: 'Telegram',
description: 'Space for all telegram messages',
private: false,
archived: false,
members: []
},
telegram.space.Telegram
)
}
}
}

View File

@ -38,19 +38,6 @@ export class TMessageTemplate extends TDoc implements MessageTemplate {
export function createModel (builder: Builder): void {
builder.createModel(TMessageTemplate)
builder.createDoc(
core.class.Space,
core.space.Model,
{
name: 'Templates',
description: 'Space for all templates',
private: true,
archived: false,
members: []
},
templates.space.Templates
)
builder.createDoc(setting.class.SettingsCategory, core.space.Model, {
name: 'message-templates',
label: templates.string.Templates,
@ -66,3 +53,5 @@ export function createModel (builder: Builder): void {
order: 1500
}, templates.ids.TemplatePopupAction)
}
export { templatesOperation } from './migration'

View File

@ -0,0 +1,42 @@
//
// Copyright © 2022 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import core, { TxOperations } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import templates from './plugin'
export const templatesOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
const current = await tx.findOne(core.class.Space, {
_id: templates.space.Templates
})
if (current === undefined) {
await tx.createDoc(
core.class.Space,
core.space.Space,
{
name: 'Templates',
description: 'Space for all templates',
private: true,
archived: false,
members: []
},
templates.space.Templates
)
}
}
}

View File

@ -58,7 +58,8 @@ export default plugin(coreId, {
space: {
Tx: '' as Ref<Space>,
DerivedTx: '' as Ref<Space>,
Model: '' as Ref<Space>
Model: '' as Ref<Space>,
Space: '' as Ref<Space>
},
account: {
System: '' as Ref<Account>

View File

@ -32,7 +32,7 @@
const client = getClient()
function createChannel() {
client.createDoc(chunter.class.Channel, core.space.Model, {
client.createDoc(chunter.class.Channel, core.space.Space, {
name,
description,
private: false,

View File

@ -32,7 +32,7 @@
const client = getClient()
function createChannel () {
client.createDoc(contact.class.Organizations, core.space.Model, {
client.createDoc(contact.class.Organizations, core.space.Space, {
name,
description,
private: false,

View File

@ -32,7 +32,7 @@
const client = getClient()
function createChannel () {
client.createDoc(contact.class.Persons, core.space.Model, {
client.createDoc(contact.class.Persons, core.space.Space, {
name,
description,
private: false,

View File

@ -40,7 +40,7 @@
const id = await client.createDoc(
lead.class.Funnel,
core.space.Model,
core.space.Space,
{
name,
description,

View File

@ -40,7 +40,7 @@
throw Error(`Failed to find target kanban template: ${templateId}`)
}
const id = await client.createDoc(recruit.class.Vacancy, core.space.Model, {
const id = await client.createDoc(recruit.class.Vacancy, core.space.Space, {
name,
description,
private: false,

View File

@ -40,7 +40,7 @@
throw Error(`Failed to find target kanban template: ${templateId}`)
}
const id = await client.createDoc(recruit.class.ReviewCategory, core.space.Model, {
const id = await client.createDoc(recruit.class.ReviewCategory, core.space.Space, {
name,
description,
private: false,

View File

@ -40,7 +40,7 @@
const id = await client.createDoc(
task.class.Project,
core.space.Model,
core.space.Space,
{
name,
description,

View File

@ -199,16 +199,9 @@ async function getEmailTx (ptx: TxCollectionCUD<Doc, Backlink>, control: Trigger
}
const receiver = attached.email
let doc: Doc | undefined
if (hierarchy.isDerived(backlink.backlinkClass, core.class.Space)) {
doc = (await control.modelDb.findAll(backlink.backlinkClass, {
_id: backlink.backlinkId
}, { limit: 1 }))[0]
} else {
doc = (await control.findAll(backlink.backlinkClass, {
_id: backlink.backlinkId
}, { limit: 1 }))[0]
}
const doc = (await control.findAll(backlink.backlinkClass, {
_id: backlink.backlinkId
}, { limit: 1 }))[0]
if (doc === undefined) return undefined
const TextPresenter = getTextPresenter(doc._class, hierarchy)

View File

@ -11,7 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
// limitations under the f.
//
import contact, { combineName } from '@anticrm/contact'

View File

@ -126,6 +126,7 @@ export async function upgradeModel (
dbName: string
): Promise<void> {
const { mongodbUri, txes } = prepareTools()
if (txes.some((tx) => tx.objectSpace !== core.space.Model)) {
throw Error('Model txes must target only core.space.Model')
}