Remove creations (#1414)

Signed-off-by: Denis Bykhov <80476319+BykhovDenis@users.noreply.github.com>
This commit is contained in:
Denis Bykhov 2022-04-16 08:59:50 +06:00 committed by GitHub
parent 6ccb343bac
commit 5f374c293b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 586 additions and 706 deletions

View File

@ -1,5 +1,5 @@
//
// Copyright © 2020 Anticrm Platform Contributors.
// 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
@ -15,7 +15,7 @@
import { createClient, Client } from '@anticrm/core'
import { getMetadata, getResource } from '@anticrm/platform'
import { createDeps } from '@anticrm/model-all'
import { migrateOperations } from '@anticrm/model-all'
import { connect } from './connection'
import clientPlugin from '@anticrm/client'
@ -32,7 +32,9 @@ export default async () => {
GetClient: async (): Promise<Client> => {
if (client === undefined) {
client = await createClient(connect)
await createDeps(client)
for (const op of migrateOperations) {
await op.upgrade(client)
}
}
// Check if we had dev hook for client.
const hook = getMetadata(clientPlugin.metadata.ClientHook)

View File

@ -1,31 +0,0 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
//
// 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 { createDeps as createTaskDeps } from '@anticrm/model-task'
import { createDeps as createLeadDeps } from '@anticrm/model-lead'
import { createDeps as createRecruitDeps } from '@anticrm/model-recruit'
import { createDeps as createDemoDeps } from '@anticrm/model-demo'
import { createDeps as createTrackerDeps } from '@anticrm/model-tracker'
import { createDeps as createBoardDeps } from '@anticrm/model-board'
export async function createDeps (client: Client): Promise<void> {
await createTaskDeps(client)
await createLeadDeps(client)
await createRecruitDeps(client)
await createDemoDeps(client)
await createTrackerDeps(client)
await createBoardDeps(client)
}

View File

@ -22,7 +22,6 @@ import { createModel as attachmentModel } from '@anticrm/model-attachment'
import { createModel as chunterModel } from '@anticrm/model-chunter'
import { createModel as contactModel } from '@anticrm/model-contact'
import { createModel as coreModel } from '@anticrm/model-core'
import { createDemo } from '@anticrm/model-demo'
import { createModel as gmailModel } from '@anticrm/model-gmail'
import { createModel as inventoryModel } from '@anticrm/model-inventory'
import { createModel as leadModel } from '@anticrm/model-lead'
@ -98,7 +97,6 @@ const builders: [(b: Builder) => void, string][] = [
[serverGmailModel, 'server-gmail'],
[serverTelegramModel, 'server-telegram'],
[trackerModel, 'tracker'],
[createDemo, 'demo'],
[boardModel, 'board']
]
@ -124,5 +122,4 @@ builder.createDoc(core.class.Version, core.space.Model, version, core.version.Mo
export default builder
// Export upgrade procedures
export { createDeps } from './creation'
export { migrateOperations } from './migration'

View File

@ -31,10 +31,12 @@ import { templatesOperation } from '@anticrm/model-templates'
import { viewOperation } from '@anticrm/model-view'
import { trackerOperation } from '@anticrm/model-tracker'
import { boardOperation } from '@anticrm/model-board'
import { demoOperation } from '@anticrm/model-demo'
export const migrateOperations: MigrateOperation[] = [
coreOperation,
chunterOperation,
demoOperation,
gmailOperation,
templatesOperation,
telegramOperation,

View File

@ -1,63 +0,0 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
//
// 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, { Doc, Space, TxOperations } from '@anticrm/core'
import type { Client, Ref } from '@anticrm/core'
import task, { createKanban } from '@anticrm/task'
import type { KanbanTemplate } from '@anticrm/task'
import { createKanbanTemplate } from '@anticrm/model-task'
import board from './plugin'
export async function createDeps (client: Client): Promise<void> {
const tx = new TxOperations(client, core.account.System)
if ((await tx.findOne(task.class.Sequence, { _id: board.ids.Sequence })) === undefined) {
await tx.createDoc(
task.class.Sequence,
task.space.Sequence,
{
attachedTo: board.class.Card,
sequence: 0
},
board.ids.Sequence
)
}
if ((await tx.findOne(task.class.KanbanTemplate, { _id: board.template.DefaultBoard })) === undefined) {
const defaultTmpl = await createDefaultKanbanTemplate(tx)
await createKanban(tx, board.space.DefaultBoard, defaultTmpl)
}
}
const defaultKanban = {
states: [
{ color: 9, title: 'To do' },
{ color: 9, title: 'Done' }
],
doneStates: [
{ isWon: true, title: 'Won' },
{ isWon: false, title: 'Lost' }
]
}
async function createDefaultKanbanTemplate (client: TxOperations): Promise<Ref<KanbanTemplate>> {
return await createKanbanTemplate(client, {
kanbanId: board.template.DefaultBoard,
space: board.space.BoardTemplates as Ref<Doc> as Ref<Space>,
title: 'Default board',
states: defaultKanban.states,
doneStates: defaultKanban.doneStates
})
}

View File

@ -1,6 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
// 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
@ -18,7 +17,18 @@
import type { Board, Card, CardAction, CardDate, CardLabel } from '@anticrm/board'
import type { Employee } from '@anticrm/contact'
import { TxOperations as Client, Doc, DOMAIN_MODEL, FindOptions, IndexKind, Ref } from '@anticrm/core'
import { Builder, Collection, Index, Model, Prop, TypeBoolean, TypeMarkup, TypeRef, TypeString, UX } from '@anticrm/model'
import {
Builder,
Collection,
Index,
Model,
Prop,
TypeBoolean,
TypeMarkup,
TypeRef,
TypeString,
UX
} from '@anticrm/model'
import attachment from '@anticrm/model-attachment'
import chunter from '@anticrm/model-chunter'
import contact from '@anticrm/model-contact'
@ -435,6 +445,5 @@ export function createModel (builder: Builder): void {
)
}
export { createDeps } from './creation'
export { boardOperation } from './migration'
export { default } from './plugin'

View File

@ -1,6 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
// 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
@ -14,10 +13,11 @@
// limitations under the License.
//
import { TxOperations } from '@anticrm/core'
import { Doc, Ref, Space, TxOperations } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import core from '@anticrm/model-core'
import { createDeps } from './creation'
import { createKanbanTemplate, createSequence } from '@anticrm/model-task'
import task, { createKanban, KanbanTemplate } from '@anticrm/task'
import board from './plugin'
async function createSpace (tx: TxOperations): Promise<void> {
@ -40,11 +40,46 @@ async function createSpace (tx: TxOperations): Promise<void> {
}
}
async function createDefaultKanbanTemplate (tx: TxOperations): Promise<Ref<KanbanTemplate>> {
const defaultKanban = {
states: [
{ color: 9, title: 'To do' },
{ color: 9, title: 'Done' }
],
doneStates: [
{ isWon: true, title: 'Won' },
{ isWon: false, title: 'Lost' }
]
}
return await createKanbanTemplate(tx, {
kanbanId: board.template.DefaultBoard,
space: board.space.BoardTemplates as Ref<Doc> as Ref<Space>,
title: 'Default board',
states: defaultKanban.states,
doneStates: defaultKanban.doneStates
})
}
async function createDefaultKanban (tx: TxOperations): Promise<void> {
const current = await tx.findOne(task.class.Kanban, {
attachedTo: board.space.DefaultBoard
})
if (current !== undefined) return
const defaultTmpl = await createDefaultKanbanTemplate(tx)
await createKanban(tx, board.space.DefaultBoard, defaultTmpl)
}
async function createDefaults (tx: TxOperations): Promise<void> {
await createSpace(tx)
await createSequence(tx, board.class.Card)
await createDefaultKanban(tx)
}
export const boardOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const ops = new TxOperations(client, core.account.System)
await createSpace(ops)
await createDeps(ops)
await createDefaults(ops)
}
}

View File

@ -14,31 +14,29 @@
//
import { Comment, Message, ThreadMessage } from '@anticrm/chunter'
import core, { Client, Doc, DOMAIN_TX, Ref, TxCreateDoc, TxOperations } from '@anticrm/core'
import core, { Doc, DOMAIN_TX, Ref, TxCreateDoc, TxOperations } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import { DOMAIN_CHUNTER, DOMAIN_COMMENT } from './index'
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',
topic: 'General Channel',
private: false,
archived: false,
members: []
}, chunter.space.General)
await tx.createDoc(
chunter.class.Channel,
core.space.Space,
{
name: 'general',
description: 'General Channel',
topic: 'General Channel',
private: false,
archived: false,
members: []
},
chunter.space.General
)
}
}
@ -47,19 +45,26 @@ export async function createRandom (tx: TxOperations): Promise<void> {
objectId: chunter.space.Random
})
if (createTx === undefined) {
await tx.createDoc(chunter.class.Channel, core.space.Space, {
name: 'random',
description: 'Random Talks',
topic: 'Random Talks',
private: false,
archived: false,
members: []
}, chunter.space.Random)
await tx.createDoc(
chunter.class.Channel,
core.space.Space,
{
name: 'random',
description: 'Random Talks',
topic: 'Random Talks',
private: false,
archived: false,
members: []
},
chunter.space.Random
)
}
}
export async function setCreate (client: TxOperations): Promise<void> {
const messages = (await client.findAll(chunter.class.Message, { })).filter((m) => m.createBy === undefined).map((m) => m._id)
const messages = (await client.findAll(chunter.class.Message, {}))
.filter((m) => m.createBy === undefined)
.map((m) => m._id)
if (messages.length === 0) return
const txes = await client.findAll(core.class.TxCreateDoc, { objectId: { $in: messages } })
const promises = txes.map(async (tx) => {
@ -77,13 +82,17 @@ export async function migrateMessages (client: MigrationClient): Promise<void> {
attachedTo: { $exists: false }
})
for (const message of messages) {
await client.update(DOMAIN_CHUNTER, {
_id: message._id
}, {
attachedTo: message.space,
attachedToClass: chunter.class.Channel,
collection: 'messages'
})
await client.update(
DOMAIN_CHUNTER,
{
_id: message._id
},
{
attachedTo: message.space,
attachedToClass: chunter.class.Channel,
collection: 'messages'
}
)
}
const txes = await client.find<TxCreateDoc<Doc>>(DOMAIN_TX, {
@ -91,13 +100,17 @@ export async function migrateMessages (client: MigrationClient): Promise<void> {
objectClass: chunter.class.Message
})
for (const tx of txes) {
await client.update(DOMAIN_TX, {
_id: tx._id
}, {
'attributes.attachedTo': tx.objectSpace,
'attributes.attachedToClass': chunter.class.Channel,
'attributes.collection': 'messages'
})
await client.update(
DOMAIN_TX,
{
_id: tx._id
},
{
'attributes.attachedTo': tx.objectSpace,
'attributes.attachedToClass': chunter.class.Channel,
'attributes.collection': 'messages'
}
)
}
}
@ -130,14 +143,18 @@ export async function migrateThreadMessages (client: MigrationClient): Promise<v
'attributes.attachedToClass': chunter.class.Message
})
for (const tx of txes) {
await client.update(DOMAIN_TX, {
_id: tx._id
}, {
objectClass: chunter.class.ThreadMessage,
'attributes.createBy': tx.modifiedBy,
'attributes.createOn': tx.modifiedOn,
'attributes.content': tx.attributes.message
})
await client.update(
DOMAIN_TX,
{
_id: tx._id
},
{
objectClass: chunter.class.ThreadMessage,
'attributes.createBy': tx.modifiedBy,
'attributes.createOn': tx.modifiedOn,
'attributes.content': tx.attributes.message
}
)
}
}

View File

@ -1,89 +0,0 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
//
// 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 { TxOperations } from '@anticrm/core'
import type { Client } from '@anticrm/core'
import contact from '@anticrm/model-contact'
import recruit from '@anticrm/model-recruit'
export async function createDeps (client: Client): Promise<void> {
const account = await client.findOne(contact.class.EmployeeAccount, { email: 'rosamund@hc.engineering' })
if (account === undefined) {
throw Error('Failed to find EmployeeAccount')
}
const tx = new TxOperations(client, account._id)
// Create missing Employee
await tx.createDoc(
contact.class.Employee,
contact.space.Employee,
{
name: 'Chen,Rosamund',
city: 'Mountain View'
},
account.employee
)
const u1 = await tx.createDoc(
contact.class.Person,
recruit.space.CandidatesPublic,
{
name: 'P.,Andrey',
city: 'Monte Carlo'
}
)
await tx.addCollection(contact.class.Channel, recruit.space.CandidatesPublic, u1, contact.class.Person, 'channels', {
provider: contact.channelProvider.Email,
value: 'andrey@hc.engineering'
})
await tx.createMixin(u1, contact.class.Person, recruit.space.CandidatesPublic, recruit.mixin.Candidate, {
title: 'Chief Architect'
})
const u2 = await tx.createDoc(
contact.class.Person,
recruit.space.CandidatesPublic,
{
name: 'M.,Marina',
city: 'Los Angeles'
}
)
await tx.addCollection(contact.class.Channel, recruit.space.CandidatesPublic, u2, contact.class.Person, 'channels', {
provider: contact.channelProvider.Email,
value: 'marina@hc.engineering'
})
await tx.createMixin(u2, contact.class.Person, recruit.space.CandidatesPublic, recruit.mixin.Candidate, {
title: 'Chief Designer'
})
const u3 = await tx.createDoc(
contact.class.Person,
recruit.space.CandidatesPublic,
{
name: 'P.,Alex',
city: 'Krasnodar, Russia'
}
)
await tx.addCollection(contact.class.Channel, recruit.space.CandidatesPublic, u3, contact.class.Person, 'channels', {
provider: contact.channelProvider.Email,
value: 'alex@hc.engineering'
})
await tx.createMixin(u3, contact.class.Person, recruit.space.CandidatesPublic, recruit.mixin.Candidate, {
title: 'Frontend Engineer'
})
}

View File

@ -1,6 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
// 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
@ -14,20 +13,4 @@
// limitations under the License.
//
import { Employee, EmployeeAccount } from '@anticrm/contact'
import core, { generateId } from '@anticrm/core'
import { Builder } from '@anticrm/model'
import contact from '@anticrm/model-contact'
export function createDemo (builder: Builder): void {
const rosamund = generateId<Employee>()
const account = generateId<EmployeeAccount>()
builder.createDoc<EmployeeAccount>(contact.class.EmployeeAccount, core.space.Model, {
email: 'rosamund@hc.engineering',
employee: rosamund,
name: 'Chen,Rosamund'
}, account, account)
}
export { createDeps } from './creation'
export { demoOperation } from './migration'

View File

@ -0,0 +1,71 @@
//
// 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 contact, { EmployeeAccount } from '@anticrm/contact'
import recruit from '@anticrm/model-recruit'
async function createCandidate (
tx: TxOperations,
name: string,
city: string,
email: string,
title: string
): Promise<void> {
const current = await tx.findOne(core.class.TxCreateDoc, {
objectClass: contact.class.Person,
'attributes.name': name
})
if (current !== undefined) return
const u1 = await tx.createDoc(contact.class.Person, recruit.space.CandidatesPublic, {
name,
city
})
await tx.addCollection(contact.class.Channel, recruit.space.CandidatesPublic, u1, contact.class.Person, 'channels', {
provider: contact.channelProvider.Email,
value: email
})
await tx.createMixin(u1, contact.class.Person, recruit.space.CandidatesPublic, recruit.mixin.Candidate, {
title
})
}
export const demoOperation: 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(contact.class.EmployeeAccount, {
email: 'rosamund@hc.engineering'
})
if (current === undefined) {
const employee = await tx.createDoc(contact.class.Employee, contact.space.Employee, {
name: 'Chen,Rosamund',
city: 'Mountain View'
})
await tx.createDoc<EmployeeAccount>(contact.class.EmployeeAccount, core.space.Model, {
email: 'rosamund@hc.engineering',
employee,
name: 'Chen,Rosamund'
})
}
await createCandidate(tx, 'P.,Andrey', 'Monte Carlo', 'andrey@hc.engineering', 'Chief Architect')
await createCandidate(tx, 'M.,Marina', 'Los Angeles', 'marina@hc.engineering', 'Chief Designer')
await createCandidate(tx, 'P.,Alex', 'Krasnodar, Russia', 'alex@hc.engineering', 'Frontend Engineer')
}
}

View File

@ -1,61 +0,0 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
//
// 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, { Doc, Space, TxOperations } from '@anticrm/core'
import type { Client, Ref } from '@anticrm/core'
import task, { createKanban } from '@anticrm/task'
import type { KanbanTemplate } from '@anticrm/task'
import { createKanbanTemplate } from '@anticrm/model-task'
import lead from './plugin'
export async function createDeps (client: Client): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await tx.createDoc(
task.class.Sequence,
task.space.Sequence,
{
attachedTo: lead.class.Lead,
sequence: 0
}
)
const defaultTmpl = await createDefaultKanbanTemplate(tx)
await createKanban(tx, lead.space.DefaultFunnel, defaultTmpl)
}
const defaultKanban = {
states: [
{ color: 9, title: 'Incoming' },
{ color: 10, title: 'Negotation' },
{ color: 1, title: 'Offer preparing' },
{ color: 0, title: 'Make a decision' },
{ color: 11, title: 'Contract conclusion' },
{ color: 9, title: 'Done' }
],
doneStates: [
{ isWon: true, title: 'Won' },
{ isWon: false, title: 'Lost' }
]
}
const createDefaultKanbanTemplate = async (client: TxOperations): Promise<Ref<KanbanTemplate>> =>
await createKanbanTemplate(client, {
kanbanId: lead.template.DefaultFunnel,
space: lead.space.FunnelTemplates as Ref<Doc> as Ref<Space>,
title: 'Default funnel',
states: defaultKanban.states,
doneStates: defaultKanban.doneStates
})

View File

@ -1,6 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
// 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
@ -26,7 +25,7 @@ import core from '@anticrm/model-core'
import task, { TSpaceWithStates, TTask } from '@anticrm/model-task'
import view from '@anticrm/model-view'
import workbench from '@anticrm/model-workbench'
import type { } from '@anticrm/view'
import type {} from '@anticrm/view'
import lead from './plugin'
@Model(lead.class.Funnel, task.class.SpaceWithStates)
@ -120,8 +119,7 @@ export function createModel (builder: Builder): void {
]
})
const leadLookup: Lookup<Lead> =
{
const leadLookup: Lookup<Lead> = {
attachedTo: [lead.mixin.Customer, { _id: { channels: contact.class.Channel } }],
state: task.class.State,
doneState: task.class.DoneState
@ -139,7 +137,11 @@ export function createModel (builder: Builder): void {
'$lookup.attachedTo',
'$lookup.state',
'$lookup.doneState',
{ presenter: attachment.component.AttachmentsPresenter, label: attachment.string.Files, sortingKey: 'attachments' },
{
presenter: attachment.component.AttachmentsPresenter,
label: attachment.string.Files,
sortingKey: 'attachments'
},
{ presenter: chunter.component.CommentsPresenter, label: chunter.string.Comments, sortingKey: 'comments' },
'modifiedOn',
'$lookup.attachedTo.$lookup.channels'
@ -186,6 +188,5 @@ export function createModel (builder: Builder): void {
)
}
export { createDeps } from './creation'
export { leadOperation } from './migration'
export { default } from './plugin'

View File

@ -1,6 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering Inc.
// 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
@ -14,9 +13,11 @@
// limitations under the License.
//
import { TxOperations } from '@anticrm/core'
import { Doc, Ref, Space, TxOperations } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import core from '@anticrm/model-core'
import { createKanbanTemplate, createSequence } from '@anticrm/model-task'
import task, { KanbanTemplate, createKanban } from '@anticrm/task'
import lead from './plugin'
async function createSpace (tx: TxOperations): Promise<void> {
@ -39,11 +40,50 @@ async function createSpace (tx: TxOperations): Promise<void> {
}
}
async function createDefaultKanbanTemplate (tx: TxOperations): Promise<Ref<KanbanTemplate>> {
const defaultKanban = {
states: [
{ color: 9, title: 'Incoming' },
{ color: 10, title: 'Negotation' },
{ color: 1, title: 'Offer preparing' },
{ color: 0, title: 'Make a decision' },
{ color: 11, title: 'Contract conclusion' },
{ color: 9, title: 'Done' }
],
doneStates: [
{ isWon: true, title: 'Won' },
{ isWon: false, title: 'Lost' }
]
}
return await createKanbanTemplate(tx, {
kanbanId: lead.template.DefaultFunnel,
space: lead.space.FunnelTemplates as Ref<Doc> as Ref<Space>,
title: 'Default funnel',
states: defaultKanban.states,
doneStates: defaultKanban.doneStates
})
}
async function createDefaultKanban (tx: TxOperations): Promise<void> {
const current = await tx.findOne(task.class.Kanban, {
attachedTo: lead.space.DefaultFunnel
})
if (current !== undefined) return
const defaultTmpl = await createDefaultKanbanTemplate(tx)
await createKanban(tx, lead.space.DefaultFunnel, defaultTmpl)
}
async function createDefaults (tx: TxOperations): Promise<void> {
await createSpace(tx)
await createSequence(tx, lead.class.Lead)
await createDefaultKanban(tx)
}
export const leadOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
},
async migrate (client: MigrationClient): Promise<void> {},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const ops = new TxOperations(client, core.account.System)
await createSpace(ops)
await createDefaults(ops)
}
}

View File

@ -1,106 +0,0 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
//
// 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 { Class, Client } from '@anticrm/core'
import core, { Doc, Ref, Space, TxOperations } from '@anticrm/core'
import { createKanbanTemplate } from '@anticrm/model-task'
import task, { KanbanTemplate } from '@anticrm/task'
import recruit from './plugin'
export async function createDeps (client: Client): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createSequence(tx, recruit.class.Applicant)
await createSequence(tx, recruit.class.Review)
await createSequence(tx, recruit.class.Opinion)
await createDefaultKanbanTemplate(tx)
await createReviewTemplates(tx)
}
export async function createSequence (tx: TxOperations, _class: Ref<Class<Doc>>): Promise<void> {
if (await tx.findOne(task.class.Sequence, { attachedTo: _class }) === undefined) {
await tx.createDoc(
task.class.Sequence,
task.space.Sequence,
{
attachedTo: _class,
sequence: 0
}
)
}
}
const defaultKanban = {
states: [
{ color: 9, title: 'HR Interview' },
{ color: 10, title: 'Technical Interview' },
{ color: 1, title: 'Test task' },
{ color: 0, title: 'Offer' }
],
doneStates: [
{ isWon: true, title: 'Won' },
{ isWon: false, title: 'Lost' }
]
}
/**
* @public
*/
export const createDefaultKanbanTemplate = async (client: TxOperations): Promise<Ref<KanbanTemplate>> =>
await createKanbanTemplate(client, {
kanbanId: recruit.template.DefaultVacancy,
space: recruit.space.VacancyTemplates as Ref<Doc> as Ref<Space>,
title: 'Default vacancy',
states: defaultKanban.states,
doneStates: defaultKanban.doneStates
})
export async function createReviewTemplates (tx: TxOperations): Promise<void> {
if (await tx.findOne(core.class.TxCreateDoc, { objectId: recruit.template.Interview }) === undefined) {
await createKanbanTemplate(tx, {
kanbanId: recruit.template.Interview,
space: recruit.space.ReviewTemplates as Ref<Doc> as Ref<Space>,
title: 'Interview',
states: [
{ color: 9, title: 'Prepare' },
{ color: 10, title: 'Appointment' },
{ color: 1, title: 'Opinions' }
],
doneStates: [
{ isWon: true, title: 'Pass' },
{ isWon: false, title: 'Failed' }
]
})
}
if (await tx.findOne(core.class.TxCreateDoc, { objectId: recruit.template.Task }) === undefined) {
await createKanbanTemplate(tx, {
kanbanId: recruit.template.Task,
space: recruit.space.ReviewTemplates as Ref<Doc> as Ref<Space>,
title: 'Test task',
states: [
{ color: 9, title: 'Prepare' },
{ color: 10, title: 'Assigned' },
{ color: 1, title: 'Review' },
{ color: 4, title: 'Opinions' }
],
doneStates: [
{ isWon: true, title: 'Pass' },
{ isWon: false, title: 'Failed' }
]
})
}
}

View File

@ -1,5 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// 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
@ -438,6 +438,5 @@ export function createModel (builder: Builder): void {
createReviewModel(builder)
}
export { createDeps } from './creation'
export { recruitOperation } from './migration'
export { default } from './plugin'

View File

@ -1,5 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// 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
@ -13,55 +13,120 @@
// limitations under the License.
//
import core, { Ref, TxOperations } from '@anticrm/core'
import core, { Doc, Ref, Space, TxOperations } from '@anticrm/core'
import { createOrUpdate, MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import tags, { TagCategory } from '@anticrm/model-tags'
import { createKanbanTemplate, createSequence } from '@anticrm/model-task'
import { getCategories } from '@anticrm/skillset'
import { createReviewTemplates, createSequence } from './creation'
import { KanbanTemplate } from '@anticrm/task'
import recruit from './plugin'
export const recruitOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
},
async migrate (client: MigrationClient): Promise<void> {},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createDefaults(tx)
}
}
await createSpace(tx)
async function createDefaults (tx: TxOperations): Promise<void> {
await createSpace(tx)
await createOrUpdate(
tx,
tags.class.TagCategory,
tags.space.Tags,
{
icon: tags.icon.Tags,
label: 'Other',
targetClass: recruit.mixin.Candidate,
tags: [],
default: true
},
recruit.category.Other
)
for (const c of getCategories()) {
await createOrUpdate(
tx,
tags.class.TagCategory,
tags.space.Tags,
{
icon: tags.icon.Tags,
label: 'Other',
label: c.label,
targetClass: recruit.mixin.Candidate,
tags: [],
default: true
tags: c.skills,
default: false
},
recruit.category.Other
(recruit.category.Category + '.' + c.id) as Ref<TagCategory>
)
for (const c of getCategories()) {
await createOrUpdate(
tx,
tags.class.TagCategory,
tags.space.Tags,
{
icon: tags.icon.Tags,
label: c.label,
targetClass: recruit.mixin.Candidate,
tags: c.skills,
default: false
},
(recruit.category.Category + '.' + c.id) as Ref<TagCategory>
)
}
await createReviewTemplates(tx)
await createSequence(tx, recruit.class.Review)
await createSequence(tx, recruit.class.Opinion)
}
await createSequence(tx, recruit.class.Review)
await createSequence(tx, recruit.class.Opinion)
await createSequence(tx, recruit.class.Applicant)
await createDefaultKanbanTemplate(tx)
await createReviewTemplates(tx)
}
async function createReviewTemplates (tx: TxOperations): Promise<void> {
if ((await tx.findOne(core.class.TxCreateDoc, { objectId: recruit.template.Interview })) === undefined) {
await createKanbanTemplate(tx, {
kanbanId: recruit.template.Interview,
space: recruit.space.ReviewTemplates as Ref<Doc> as Ref<Space>,
title: 'Interview',
states: [
{ color: 9, title: 'Prepare' },
{ color: 10, title: 'Appointment' },
{ color: 1, title: 'Opinions' }
],
doneStates: [
{ isWon: true, title: 'Pass' },
{ isWon: false, title: 'Failed' }
]
})
}
if ((await tx.findOne(core.class.TxCreateDoc, { objectId: recruit.template.Task })) === undefined) {
await createKanbanTemplate(tx, {
kanbanId: recruit.template.Task,
space: recruit.space.ReviewTemplates as Ref<Doc> as Ref<Space>,
title: 'Test task',
states: [
{ color: 9, title: 'Prepare' },
{ color: 10, title: 'Assigned' },
{ color: 1, title: 'Review' },
{ color: 4, title: 'Opinions' }
],
doneStates: [
{ isWon: true, title: 'Pass' },
{ isWon: false, title: 'Failed' }
]
})
}
}
async function createDefaultKanbanTemplate (tx: TxOperations): Promise<Ref<KanbanTemplate>> {
const defaultKanban = {
states: [
{ color: 9, title: 'HR Interview' },
{ color: 10, title: 'Technical Interview' },
{ color: 1, title: 'Test task' },
{ color: 0, title: 'Offer' }
],
doneStates: [
{ isWon: true, title: 'Won' },
{ isWon: false, title: 'Lost' }
]
}
return await createKanbanTemplate(tx, {
kanbanId: recruit.template.DefaultVacancy,
space: recruit.space.VacancyTemplates as Ref<Doc> as Ref<Space>,
title: 'Default vacancy',
states: defaultKanban.states,
doneStates: defaultKanban.doneStates
})
}
async function createSpace (tx: TxOperations): Promise<void> {

View File

@ -1,117 +0,0 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
//
// 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, { Doc, TxOperations } from '@anticrm/core'
import type { Client, Ref, Space } from '@anticrm/core'
import { createKanban, genRanks } from '@anticrm/task'
import type { DoneStateTemplate, KanbanTemplate, StateTemplate } from '@anticrm/task'
import task from './plugin'
export async function createDeps (client: Client): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await tx.createDoc(
task.class.Sequence,
task.space.Sequence,
{
attachedTo: task.class.Issue,
sequence: 0
}
)
const defaultTmpl = await createDefaultKanbanTemplate(tx)
await createKanban(tx, task.space.TasksPublic, defaultTmpl)
}
const defaultKanban = {
states: [
{ color: 9, title: 'Open' },
{ color: 10, title: 'In Progress' },
{ color: 1, title: 'Under review' },
{ color: 0, title: 'Done' },
{ color: 11, title: 'Invalid' }
],
doneStates: [
{ isWon: true, title: 'Won' },
{ isWon: false, title: 'Lost' }
]
}
/**
* @public
*/
export interface KanbanTemplateData {
kanbanId: Ref<KanbanTemplate>
space: Ref<Space>
title: KanbanTemplate['title']
states: Pick<StateTemplate, 'title' | 'color'>[]
doneStates: (Pick<DoneStateTemplate, 'title'> & { isWon: boolean })[]
}
/**
* @public
*/
export async function createKanbanTemplate (client: TxOperations, data: KanbanTemplateData): Promise<Ref<KanbanTemplate>> {
const tmpl = await client.createDoc(
task.class.KanbanTemplate,
data.space,
{
doneStatesC: 0,
statesC: 0,
title: data.title
},
data.kanbanId
)
const doneStateRanks = [...genRanks(data.doneStates.length)]
await Promise.all(
data.doneStates.map((st, i) => client.addCollection(
st.isWon ? task.class.WonStateTemplate : task.class.LostStateTemplate,
data.space,
data.kanbanId,
task.class.KanbanTemplate,
'doneStatesC',
{
rank: doneStateRanks[i],
title: st.title
}))
)
const stateRanks = [...genRanks(data.states.length)]
await Promise.all(
data.states.map((st, i) => client.addCollection(
task.class.StateTemplate,
data.space,
data.kanbanId,
task.class.KanbanTemplate,
'statesC',
{
rank: stateRanks[i],
title: st.title,
color: st.color
}))
)
return tmpl
}
const createDefaultKanbanTemplate = async (client: TxOperations): Promise<Ref<KanbanTemplate>> =>
await createKanbanTemplate(client, {
kanbanId: task.template.DefaultProject,
space: task.space.ProjectTemplates as Ref<Doc> as Ref<Space>,
title: 'Default project',
states: defaultKanban.states,
doneStates: defaultKanban.doneStates
})

View File

@ -1,5 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// 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
@ -18,11 +18,14 @@ import contact from '@anticrm/contact'
import { Arr, Class, Doc, Domain, DOMAIN_MODEL, FindOptions, IndexKind, Ref, Space, Timestamp } from '@anticrm/core'
import {
Builder,
Collection, Hidden, Implements,
Collection,
Hidden,
Implements,
Index,
Mixin,
Model,
Prop, TypeBoolean,
Prop,
TypeBoolean,
TypeDate,
TypeMarkup,
TypeRef,
@ -37,16 +40,29 @@ import view from '@anticrm/model-view'
import workbench from '@anticrm/model-workbench'
import { IntlString } from '@anticrm/platform'
import type {
DoneState, DoneStateTemplate, Issue, Kanban,
KanbanCard, KanbanTemplate, KanbanTemplateSpace, LostState, LostStateTemplate, Project, Sequence, State, StateTemplate, Task,
TodoItem, WonState, WonStateTemplate
DoneState,
DoneStateTemplate,
Issue,
Kanban,
KanbanCard,
KanbanTemplate,
KanbanTemplateSpace,
LostState,
LostStateTemplate,
Project,
Sequence,
State,
StateTemplate,
Task,
TodoItem,
WonState,
WonStateTemplate
} from '@anticrm/task'
import { AnyComponent } from '@anticrm/ui'
import type { ActionTarget } from '@anticrm/view'
import task from './plugin'
export { createDeps, createKanbanTemplate } from './creation'
export { taskOperation } from './migration'
export { taskOperation, createKanbanTemplate, createSequence } from './migration'
export { default } from './plugin'
export const DOMAIN_TASK = 'task' as Domain
@ -312,7 +328,11 @@ export function createModel (builder: Builder): void {
'$lookup.assignee',
'$lookup.state',
'$lookup.doneState',
{ presenter: attachment.component.AttachmentsPresenter, label: attachment.string.Files, sortingKey: 'attachments' },
{
presenter: attachment.component.AttachmentsPresenter,
label: attachment.string.Files,
sortingKey: 'attachments'
},
{ presenter: chunter.component.CommentsPresenter, label: chunter.string.Comments, sortingKey: 'comments' },
'modifiedOn'
]
@ -492,11 +512,16 @@ export function createModel (builder: Builder): void {
}
})
builder.createDoc(presentation.class.ObjectSearchCategory, core.space.Model, {
icon: task.icon.Task,
label: task.string.SearchTask,
query: task.completion.IssueQuery
}, task.completion.IssueCategory)
builder.createDoc(
presentation.class.ObjectSearchCategory,
core.space.Model,
{
icon: task.icon.Task,
label: task.string.SearchTask,
query: task.completion.IssueQuery
},
task.completion.IssueCategory
)
builder.createDoc(view.class.ActionTarget, core.space.Model, {
target: task.class.Task,

View File

@ -1,5 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// 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
@ -13,13 +13,89 @@
// limitations under the License.
//
import { TxOperations } from '@anticrm/core'
import {
MigrateOperation, MigrationClient, MigrationUpgradeClient
} from '@anticrm/model'
import { Class, Doc, Ref, Space, TxOperations } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import core from '@anticrm/model-core'
import { KanbanTemplate, StateTemplate, DoneStateTemplate, genRanks, createKanban } from '@anticrm/task'
import task from './plugin'
/**
* @public
*/
export interface KanbanTemplateData {
kanbanId: Ref<KanbanTemplate>
space: Ref<Space>
title: KanbanTemplate['title']
states: Pick<StateTemplate, 'title' | 'color'>[]
doneStates: (Pick<DoneStateTemplate, 'title'> & { isWon: boolean })[]
}
/**
* @public
*/
export async function createSequence (tx: TxOperations, _class: Ref<Class<Doc>>): Promise<void> {
if ((await tx.findOne(task.class.Sequence, { attachedTo: _class })) === undefined) {
await tx.createDoc(task.class.Sequence, task.space.Sequence, {
attachedTo: _class,
sequence: 0
})
}
}
/**
* @public
*/
export async function createKanbanTemplate (
client: TxOperations,
data: KanbanTemplateData
): Promise<Ref<KanbanTemplate>> {
const current = await client.findOne(task.class.KanbanTemplate, { _id: data.kanbanId })
if (current !== undefined) {
return current._id
}
const tmpl = await client.createDoc(
task.class.KanbanTemplate,
data.space,
{
doneStatesC: 0,
statesC: 0,
title: data.title
},
data.kanbanId
)
const doneStateRanks = [...genRanks(data.doneStates.length)]
await Promise.all(
data.doneStates.map((st, i) =>
client.addCollection(
st.isWon ? task.class.WonStateTemplate : task.class.LostStateTemplate,
data.space,
data.kanbanId,
task.class.KanbanTemplate,
'doneStatesC',
{
rank: doneStateRanks[i],
title: st.title
}
)
)
)
const stateRanks = [...genRanks(data.states.length)]
await Promise.all(
data.states.map((st, i) =>
client.addCollection(task.class.StateTemplate, data.space, data.kanbanId, task.class.KanbanTemplate, 'statesC', {
rank: stateRanks[i],
title: st.title,
color: st.color
})
)
)
return tmpl
}
async function createDefaultProject (tx: TxOperations): Promise<void> {
const createTx = await tx.findOne(core.class.TxCreateDoc, {
objectId: task.space.TasksPublic
@ -60,12 +136,50 @@ async function createDefaultSequence (tx: TxOperations): Promise<void> {
}
}
async function createDefaultKanbanTemplate (tx: TxOperations): Promise<Ref<KanbanTemplate>> {
const defaultKanban = {
states: [
{ color: 9, title: 'Open' },
{ color: 10, title: 'In Progress' },
{ color: 1, title: 'Under review' },
{ color: 0, title: 'Done' },
{ color: 11, title: 'Invalid' }
],
doneStates: [
{ isWon: true, title: 'Won' },
{ isWon: false, title: 'Lost' }
]
}
return await createKanbanTemplate(tx, {
kanbanId: task.template.DefaultProject,
space: task.space.ProjectTemplates as Ref<Doc> as Ref<Space>,
title: 'Default project',
states: defaultKanban.states,
doneStates: defaultKanban.doneStates
})
}
async function createDefaultKanban (tx: TxOperations): Promise<void> {
const current = await tx.findOne(task.class.Kanban, {
attachedTo: task.space.TasksPublic
})
if (current !== undefined) return
const defaultTmpl = await createDefaultKanbanTemplate(tx)
await createKanban(tx, task.space.TasksPublic, defaultTmpl)
}
async function createDefaults (tx: TxOperations): Promise<void> {
await createDefaultSequence(tx)
await createDefaultProject(tx)
await createSequence(tx, task.class.Issue)
await createDefaultKanban(tx)
}
export const taskOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
},
async migrate (client: MigrationClient): Promise<void> {},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createDefaultSequence(tx)
await createDefaultProject(tx)
await createDefaults(tx)
}
}

View File

@ -1,48 +0,0 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
//
// 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, { Client, TxOperations } from '@anticrm/core'
import { Team } from '@anticrm/tracker'
import tracker from './plugin'
export async function createDeps (client: Client): Promise<void> {
const tx = new TxOperations(client, core.account.System)
const current = await tx.findOne(tracker.class.Team, {
_id: tracker.team.DefaultTeam
})
const currentDeleted = await tx.findOne(core.class.TxRemoveDoc, {
objectId: tracker.team.DefaultTeam
})
// Create new if not deleted by customers.
if (current === undefined && currentDeleted === undefined) {
await tx.createDoc<Team>(
tracker.class.Team,
core.space.Space,
{
name: 'Default',
description: 'Default team',
private: false,
members: [],
archived: false,
identifier: 'TSK',
sequence: 0
},
tracker.team.DefaultTeam
)
}
}

View File

@ -1,5 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// 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
@ -18,8 +18,12 @@ import contact from '@anticrm/contact'
import { Domain, IndexKind, Markup, Ref, Timestamp } from '@anticrm/core'
import {
Builder,
Collection, Hidden, Index, Model,
Prop, TypeDate,
Collection,
Hidden,
Index,
Model,
Prop,
TypeDate,
TypeMarkup,
TypeNumber,
TypeRef,
@ -35,7 +39,6 @@ import tracker from './plugin'
import workbench from '@anticrm/model-workbench'
export { createDeps } from './creation'
export { trackerOperation } from './migration'
export { default } from './plugin'
@ -47,17 +50,17 @@ export const DOMAIN_TRACKER = 'tracker' as Domain
@Model(tracker.class.Team, core.class.Space, DOMAIN_SPACE)
@UX(tracker.string.Team, tracker.icon.Team, tracker.string.Team)
export class TTeam extends TSpace implements Team {
@Prop(TypeString(), tracker.string.Title)
@Index(IndexKind.FullText)
reamLogo!: IntlString
@Prop(TypeString(), tracker.string.Title)
@Index(IndexKind.FullText)
reamLogo!: IntlString
@Prop(TypeString(), tracker.string.Identifier)
@Index(IndexKind.FullText)
identifier!: IntlString
@Prop(TypeString(), tracker.string.Identifier)
@Index(IndexKind.FullText)
identifier!: IntlString
@Prop(TypeNumber(), tracker.string.Number)
@Hidden()
sequence!: number
@Prop(TypeNumber(), tracker.string.Number)
@Hidden()
sequence!: number
}
/**
@ -120,28 +123,25 @@ export class TIssue extends TDoc implements Issue {
@Model(tracker.class.Document, core.class.Doc, DOMAIN_TRACKER)
@UX(tracker.string.Document, tracker.icon.Document, tracker.string.Document)
export class TDocument extends TDoc implements Document {
@Prop(TypeString(), tracker.string.Title)
@Index(IndexKind.FullText)
title!: string
@Prop(TypeString(), tracker.string.Title)
@Index(IndexKind.FullText)
title!: string
@Prop(TypeString(), tracker.string.DocumentIcon)
icon!: string | null
@Prop(TypeString(), tracker.string.DocumentIcon)
icon!: string | null
@Prop(TypeString(), tracker.string.DocumentColor)
color!: number
@Prop(TypeString(), tracker.string.DocumentColor)
color!: number
@Prop(TypeMarkup(), tracker.string.Description)
@Index(IndexKind.FullText)
content!: Markup
@Prop(TypeMarkup(), tracker.string.Description)
@Index(IndexKind.FullText)
content!: Markup
declare space: Ref<Team>
declare space: Ref<Team>
}
export function createModel (builder: Builder): void {
builder.createModel(
TTeam,
TIssue
)
builder.createModel(TTeam, TIssue)
builder.createDoc(
workbench.class.Application,
@ -213,7 +213,8 @@ export function createModel (builder: Builder): void {
component: tracker.component.Projects
}
]
}]
}
]
},
navHeaderComponent: tracker.component.NewIssueHeader
},

View File

@ -1,5 +1,5 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// 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
@ -13,15 +13,47 @@
// limitations under the License.
//
import {
MigrateOperation, MigrationClient, MigrationUpgradeClient
} from '@anticrm/model'
import { createDeps } from './creation'
import core, { TxOperations } from '@anticrm/core'
import { MigrateOperation, MigrationClient, MigrationUpgradeClient } from '@anticrm/model'
import { Team } from '@anticrm/tracker'
import tracker from './plugin'
export const trackerOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {
},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
await createDeps(client)
async function createDefaultTeam (tx: TxOperations): Promise<void> {
const current = await tx.findOne(tracker.class.Team, {
_id: tracker.team.DefaultTeam
})
const currentDeleted = await tx.findOne(core.class.TxRemoveDoc, {
objectId: tracker.team.DefaultTeam
})
// Create new if not deleted by customers.
if (current === undefined && currentDeleted === undefined) {
await tx.createDoc<Team>(
tracker.class.Team,
core.space.Space,
{
name: 'Default',
description: 'Default team',
private: false,
members: [],
archived: false,
identifier: 'TSK',
sequence: 0
},
tracker.team.DefaultTeam
)
}
}
async function createDefaults (tx: TxOperations): Promise<void> {
await createDefaultTeam(tx)
}
export const trackerOperation: MigrateOperation = {
async migrate (client: MigrationClient): Promise<void> {},
async upgrade (client: MigrationUpgradeClient): Promise<void> {
const tx = new TxOperations(client, core.account.System)
await createDefaults(tx)
}
}

View File

@ -15,7 +15,7 @@
import contact from '@anticrm/contact'
import core, { DOMAIN_TX, Tx, Client as CoreClient, Domain, IndexKind, DOMAIN_MODEL } from '@anticrm/core'
import builder, { createDeps, migrateOperations } from '@anticrm/model-all'
import builder, { migrateOperations } from '@anticrm/model-all'
import { Client } from 'minio'
import { Db, Document, MongoClient } from 'mongodb'
import { connect } from './connect'
@ -99,7 +99,9 @@ export async function initModel (transactorUrl: string, dbName: string): Promise
console.log('creating data...')
const connection = await connect(transactorUrl, dbName, true)
try {
await createDeps(connection)
for (const op of migrateOperations) {
await op.upgrade(connection)
}
} catch (e) {
console.log(e)
} finally {